Documentation
¶
Index ¶
- Variables
- func NewSubjectTokenED25519(identityUUID, providerUUID string, expiresAt time.Time, ...) string
- func NewSubjectTokenMLDSA87(identityUUID, providerUUID string, expiresAt time.Time, ...) string
- func ParseSubjectToken(token string) (algorithm, identityUUID, providerUUID string, expiresAt time.Time, sig []byte, ...)
- func SetRequestGroups(req *Request, subject, process, action, oboFor []string)
- func SetRequestIsHistoric(req *Request, v bool)
- func SetRequestIsOBO(req *Request, v bool)
- func SetRequestOBODepth(req *Request, v int64)
- func SetRequestOBOFor(req *Request, v string)
- func VerifySubjectToken(token string, providers map[string]PublicVerifyKey, policy AlgorithmPolicy, ...) (string, error)
- type AlgorithmPolicy
- type Decision
- type Engine
- func (e *Engine) ActiveEpochID() (EpochID, bool)
- func (e *Engine) Close()
- func (e *Engine) Evaluate(ctx context.Context, req *Request) (Decision, error)
- func (e *Engine) EvaluateAsOfOBO(ctx context.Context, req *OBORequest, asOf time.Time) (Decision, error)
- func (e *Engine) EvaluateForSession(ctx context.Context, req *Request) (Decision, FixedEpoch, error)
- func (e *Engine) EvaluateOBO(ctx context.Context, req *OBORequest) (Decision, error)
- func (e *Engine) EvaluateOBOForSession(ctx context.Context, req *OBORequest) (Decision, FixedEpoch, error)
- type EngineOption
- type EpochData
- type EpochID
- type ExplainedDecision
- type FixedEpoch
- type HistoricEpochSource
- type KeyAlgorithm
- type OBOLink
- type OBORequest
- type OBORequestValue
- type Option
- type PolicyLoader
- type PublicVerifyKey
- type Request
- func (r *Request) GetAction() string
- func (r *Request) GetActionParam(key string) (dsl.Value, bool)
- func (r *Request) GetEvalTime() time.Time
- func (r *Request) GetIsHistoric() bool
- func (r *Request) GetIsOBO() bool
- func (r *Request) GetOBODepth() int64
- func (r *Request) GetOBOFor() string
- func (r *Request) GetProcess() string
- func (r *Request) GetRequestAttr(key string) (dsl.Value, bool)
- func (r *Request) GetSubjectAttr(key string) (dsl.Value, bool)
- func (r *Request) GetSubjectIdentity() string
- func (r *Request) GetTag(key string) (string, bool)
- func (r *Request) HasActionGroup(group string) bool
- func (r *Request) HasOBOForGroup(group string) bool
- func (r *Request) HasProcessGroup(group string) bool
- func (r *Request) HasSubjectGroup(group string) bool
- type UpdateEpoch
- type Value
Constants ¶
This section is empty.
Variables ¶
var ErrAlgorithmNotAccepted = errors.New("authdsl: subject token algorithm not accepted by policy")
ErrAlgorithmNotAccepted is returned when a subject token's algorithm is rejected by the engine's AlgorithmPolicy.
var ErrEpochGap = errors.New("authdsl: engine has gap between epoches")
ErrEpochGap is returned when the active epoch has expired but the pending replacement activeTime is after the active epoch's expiryTime
var ErrEpochTTLExceeded = errors.New("authdsl: engine exceeded time to retrieve active epoch")
ErrEpochTTLExceeded is returned when the engine took too long to retrieve the active epoch TTL is set by the function
var ErrInvalidAsOf = errors.New("authdsl: asOf must be a non-zero time in the past")
ErrInvalidAsOf is returned by EvaluateAsOfOBO when asOf is zero or not in the past.
var ErrInvalidRequest = errors.New("authdsl: invalid request")
ErrInvalidRequest is returned when a Request or OBORequest is missing required fields.
var ErrNoHistoricTrustSource = errors.New("authdsl: no historic trust provider service configured")
ErrNoHistoricTrustSource is returned by EvaluateAsOfOBO when trust providers are configured but no HistoricEpochSource is available to supply the historic trust providers needed to verify the inner OBO chain tokens.
var ErrNoValidEpoch = errors.New("authdsl: engine has no active epoch")
ErrNoValidEpoch is returned when the active epoch has expired but there is no replacement pending
var ErrNotReady = errors.New("authdsl: engine not yet ready")
ErrNotReady is returned when an epoch-based Evaluate method is called before the first epoch has been loaded.
var ErrShutdown = errors.New("authdsl: engine or request context is done")
ErrShutdown is returned when a context is done - either for a specific request, or the context for the Engine itself
var ErrSubjectTokenExpired = errors.New("authdsl: subject token expired")
ErrSubjectTokenExpired is returned when the token's expiry time is before now.
var ErrSubjectTokenInvalidSignature = errors.New("authdsl: subject token invalid signature")
ErrSubjectTokenInvalidSignature is returned when the signature in the token does not verify against the provider public key.
var ErrSubjectTokenMalformed = errors.New("authdsl: subject token malformed")
ErrSubjectTokenMalformed is returned when a token does not conform to the expected 5-component dot-separated format.
var ErrSubjectTokenUnknownProvider = errors.New("authdsl: subject token unknown provider")
ErrSubjectTokenUnknownProvider is returned when the provider UUID in the token is not present in the trusted providers map.
var ErrUnknownAlgorithm = errors.New("authdsl: unknown key algorithm")
ErrUnknownAlgorithm is returned by UnmarshalPublicVerifyKey when the algorithm identifier is not a recognised value ("ed25519" or "mldsa87").
var IntParam = dsl.IntParam
IntParam returns a Value holding i.
var StringParam = dsl.StringParam
StringParam returns a Value holding s.
Functions ¶
func NewSubjectTokenED25519 ¶
func NewSubjectTokenED25519(identityUUID, providerUUID string, expiresAt time.Time, providerPrivKey ed25519.PrivateKey) string
NewSubjectTokenED25519 creates a signed subject token for identityUUID using an ED25519 private key. The token expires at expiresAt (truncated to second precision in UTC).
func NewSubjectTokenMLDSA87 ¶
func NewSubjectTokenMLDSA87(identityUUID, providerUUID string, expiresAt time.Time, providerPrivKey *mldsa87.PrivateKey) string
NewSubjectTokenMLDSA87 creates a signed subject token for identityUUID using an ML-DSA-87 private key. The token expires at expiresAt (truncated to second precision in UTC).
func ParseSubjectToken ¶
func ParseSubjectToken(token string) (algorithm, identityUUID, providerUUID string, expiresAt time.Time, sig []byte, err error)
ParseSubjectToken parses a 5-component dot-separated subject token into its constituent parts. The token format is:
<alg>.<b64(identityUUID)>.<b64(providerUUID)>.<b64(expiresAt)>.<b64(signature)>
where alg is the plain ASCII string "ed25519" or "mldsa87", and expiresAt is an RFC3339 UTC time string.
func SetRequestGroups ¶
SetRequestGroups configures group memberships on req for use with eval.Evaluator. When using engine.Engine, groups are resolved authoritatively from epoch data and any value set here is overwritten before evaluation.
func SetRequestIsHistoric ¶
SetRequestIsHistoric marks req as originating within a historic evaluation context. When req is passed to engine.Engine.EvaluateForSession, this field is reset before evaluation; use engine.Engine.EvaluateAsOfOBO for epoch-based historic evaluation.
func SetRequestIsOBO ¶
SetRequestIsOBO marks req as originating within an OBO delegation chain. When req is passed to engine.Engine.EvaluateForSession, this field is reset before evaluation; use engine.Engine.EvaluateOBO for epoch-based OBO evaluation.
func SetRequestOBODepth ¶
SetRequestOBODepth sets the OBO delegation depth on req. When req is passed to engine.Engine.EvaluateForSession, this field is reset before evaluation.
func SetRequestOBOFor ¶
SetRequestOBOFor sets the OBO target identity on req. When req is passed to engine.Engine.EvaluateForSession, this field is reset before evaluation.
func VerifySubjectToken ¶
func VerifySubjectToken(token string, providers map[string]PublicVerifyKey, policy AlgorithmPolicy, now time.Time) (string, error)
VerifySubjectToken verifies a subject token against the provided trust providers map (UUID → PublicVerifyKey) and algorithm policy. Returns the identity UUID on success.
Errors: ErrSubjectTokenMalformed, ErrSubjectTokenExpired, ErrSubjectTokenUnknownProvider, ErrSubjectTokenInvalidSignature, ErrAlgorithmNotAccepted.
Types ¶
type AlgorithmPolicy ¶
type AlgorithmPolicy int
AlgorithmPolicy controls which token algorithms an engine accepts.
const ( // AlgorithmPolicyBoth accepts both ED25519 and ML-DSA-87 tokens. (default) AlgorithmPolicyBoth AlgorithmPolicy = iota // AlgorithmPolicyED25519Only rejects ML-DSA-87 tokens. AlgorithmPolicyED25519Only // AlgorithmPolicyMLDSA87Only rejects ED25519 tokens. AlgorithmPolicyMLDSA87Only )
type Engine ¶
type Engine struct {
// contains filtered or unexported fields
}
Engine holds compiled policy blocks for static evaluation and manages epoch state for remote epoch-based evaluation. It is safe for concurrent use.
func New ¶
func New(ctx context.Context, chActive chan *UpdateEpoch, historicEpochSource HistoricEpochSource, opts ...EngineOption) *Engine
New creates an Engine ready for epoch-based use.
func (*Engine) ActiveEpochID ¶
ActiveEpochID returns the ID of the current active epoch and true, or 0 and false if no epoch is active.
func (*Engine) Close ¶
func (e *Engine) Close()
Close stops the epoch manager goroutine and historic epoch eviction timers.
func (*Engine) Evaluate ¶
Evaluate evaluates req against the current active epoch. Groups are resolved authoritatively from the epoch; any groups already set on req are discarded. Returns (DecisionDeny, ErrNotReady) until the first epoch is set.
func (*Engine) EvaluateAsOfOBO ¶
func (e *Engine) EvaluateAsOfOBO(ctx context.Context, req *OBORequest, asOf time.Time) (Decision, error)
EvaluateAsOfOBO evaluates a historic request, but first verifies that req.SubjectIdentity is currently authorised to perform historic evaluation.
The caller must hold a policy in the active epoch that grants system.historic:EVALUATE on the target process, for example:
POLICY allow-historic ALLOW {
group:compliance TO PERFORM system.historic:EVALUATE ON process:my.svc ;
}
If the authority check fails the call returns DecisionDeny without consulting the historic source. If it passes, the epoch active at asOf is loaded (via HistoricEpochSource) and only the Inner part of req is evaluated against it.
func (*Engine) EvaluateForSession ¶
func (e *Engine) EvaluateForSession(ctx context.Context, req *Request) (Decision, FixedEpoch, error)
EvaluateForSession evaluates the req as per Evaluate, but additionally returns an instance of FixedEpoch which allows further Requests to be sent to the same underlying epoch for consistency of authorisation behaviour.
The FixedEpoch is only intended for use for a short session with a single identity, so is tied to the SubjectIdentity of the initial Request.
func (*Engine) EvaluateOBO ¶
EvaluateOBO evaluates an OBO delegation chain against the current active epoch. Returns (DecisionDeny, ErrNotReady) until the first epoch is set.
func (*Engine) EvaluateOBOForSession ¶
func (e *Engine) EvaluateOBOForSession(ctx context.Context, req *OBORequest) (Decision, FixedEpoch, error)
EvaluateOBOForSession evaluates the req as per EvaluateOBO, but additionally returns an instance of FixedEpoch which allows further OBORequests to be sent to the same underlying epoch for consistency of authorisation behaviour.
The FixedEpoch is only intended for use for a short session with a single identity, so is tied to the SubjectIdentity of the initial OBORequest.
type EngineOption ¶
type EngineOption func(*Option)
EngineOption configures an Engine from the Option.
func WithAlgorithmPolicy ¶
func WithAlgorithmPolicy(p AlgorithmPolicy) EngineOption
WithAlgorithmPolicy configures which token algorithms the engine accepts. Default is AlgorithmPolicyBoth (accept ed25519 and mldsa87).
func WithEpochRetrievalTTL ¶
func WithEpochRetrievalTTL(d time.Duration) EngineOption
func WithHistoricTTL ¶
func WithHistoricTTL(d time.Duration) EngineOption
WithHistoricTTL sets the time-to-live for cached historic epochs. After the TTL the epoch is evicted once all in-flight evaluations complete. Zero or negative disables TTL-based eviction.
type EpochData ¶
type EpochData struct {
ID EpochID
FreezeTime time.Time
ActiveTime time.Time
ExpiryTime time.Time
SubjectGroups map[string][]string // group → []identity (server form; inverted on load)
ProcessGroups map[string][]string // group → []process (server form; inverted on load)
ActionGroups map[string][]string // group → []action (server form; inverted on load)
}
EpochData is the group membership snapshot for one epoch, in server (group→members) form.
type ExplainedDecision ¶
type ExplainedDecision struct {
Decision Decision
MatchedBlock string // name of the first block that matched, empty if implicit deny
Reason string // human-readable explanation
}
ExplainedDecision is the result of EvaluateExplained.
type FixedEpoch ¶
type FixedEpoch interface {
// Evaluate evaluates req against the fixed epoch.
// Groups are resolved authoritatively from the epoch; any groups already set
// on req are discarded.
Evaluate(ctx context.Context, req *Request) (Decision, error)
// EvaluateOBO evaluates an OBO delegation chain against the fixed epoch.
EvaluateOBO(ctx context.Context, req *OBORequest) (Decision, error)
}
FixedEpoch implements the means to perform authorisation validations against a fixed epoch regardless of the evolution of epoches in the main Engine
type HistoricEpochSource ¶
type HistoricEpochSource interface {
// LoadHistoricEpoch returns the epoch ID, full data, and a PolicyLoader
// for the epoch that was active at asOf.
LoadHistoricEpoch(ctx context.Context, asOf time.Time) (epochID EpochID, data *EpochData, loader PolicyLoader, err error)
// LoadHistoricTrustProviders returns the trust providers that were in
// effect at asOf. Used by EvaluateAsOfOBO to verify inner-chain tokens
// against the keys that existed at the historic timestamp.
LoadHistoricTrustProviders(ctx context.Context, asOf time.Time) (map[string]PublicVerifyKey, error)
}
HistoricEpochSource loads epoch data for past epochs on demand.
type KeyAlgorithm ¶
type KeyAlgorithm uint8
KeyAlgorithm identifies the signature algorithm used by a key or token.
const ( // KeyAlgorithmED25519 identifies the Ed25519 signature algorithm. KeyAlgorithmED25519 KeyAlgorithm = 0 // KeyAlgorithmMLDSA87 identifies the ML-DSA-87 post-quantum signature algorithm. KeyAlgorithmMLDSA87 KeyAlgorithm = 1 )
func (KeyAlgorithm) String ¶
func (a KeyAlgorithm) String() string
type OBOLink ¶
type OBOLink struct {
Actor string // the delegating SubjectIdentity
Target string // the SubjectIdentity being acted on behalf of
}
OBOLink is one step in a delegation chain (exported for use by remote).
type OBORequest ¶
type OBORequest struct {
// SubjectIdentity is the identity assuming the identity of the contents of Inner
SubjectIdentity string
// Inner is either another OBORequest or terminating Request, depending on the obo chain
Inner OBORequestValue
}
OBORequest is an on-behalf-of delegation chain. SubjectIdentity is the delegating actor; Inner is either another OBORequest layer (Via) or the terminal direct-authorisation request (For).
Example — single-hop (alice acts as bob):
&OBORequest{SubjectIdentity: "alice", Inner: For(bobReq)}
Example — two-hop (charlie → bob → alice):
&OBORequest{
SubjectIdentity: "charlie",
Inner: Via(&OBORequest{SubjectIdentity: "bob", Inner: For(aliceReq)}),
}
type OBORequestValue ¶
type OBORequestValue struct {
// contains filtered or unexported fields
}
OBORequestValue holds the inner part of an OBORequest chain: either another delegation layer (Via) or the terminal direct-authorisation request (For). Exactly one field must be non-nil.
func For ¶
func For(req *Request) OBORequestValue
For creates an OBORequestValue that terminates in req, a direct authorisation request. Use this as the Inner of the innermost OBORequest in the chain.
func Via ¶
func Via(inner *OBORequest) OBORequestValue
Via creates an OBORequestValue that delegates through another OBORequest layer. Use this as the Inner of an outer OBORequest when building a multi-hop delegation chain.
type PolicyLoader ¶
type PolicyLoader interface {
LoadPolicy(ctx context.Context, epochID EpochID, process string) (*dsl.CompiledPolicy, error)
LoadOBOPolicy(ctx context.Context, epochID EpochID, process string) (*dsl.CompiledPolicy, error)
// LoadHistoricAuthPolicy fetches the historic-namespace policy used to authorise
// system.historic:EVALUATE requests against this epoch.
// Returns (nil, nil) when no such policy exists (implicit deny).
LoadHistoricAuthPolicy(ctx context.Context, epochID EpochID, process string) (*dsl.CompiledPolicy, error)
}
PolicyLoader lazily fetches and compiles policies for a given epoch.
type PublicVerifyKey ¶
type PublicVerifyKey struct {
Algorithm KeyAlgorithm
ED25519 ed25519.PublicKey // set when Algorithm == KeyAlgorithmED25519
MLDSA87 *mldsa87.PublicKey // set when Algorithm == KeyAlgorithmMLDSA87
}
PublicVerifyKey holds a public key for one trust provider. Exactly one key field is set, determined by Algorithm.
func UnmarshalPublicVerifyKey ¶
func UnmarshalPublicVerifyKey(algorithm string, keyBytes []byte) (PublicVerifyKey, error)
UnmarshalPublicVerifyKey constructs a PublicVerifyKey from an algorithm name string ("ed25519" or "mldsa87") and raw key bytes.
func (PublicVerifyKey) Equal ¶
func (k PublicVerifyKey) Equal(other PublicVerifyKey) bool
Equal reports whether k and other hold the same key.
func (PublicVerifyKey) IsZero ¶
func (k PublicVerifyKey) IsZero() bool
IsZero reports whether the key is the zero value (no key set).
func (PublicVerifyKey) MarshalBinary ¶
func (k PublicVerifyKey) MarshalBinary() ([]byte, error)
MarshalBinary returns the raw key bytes.
func (PublicVerifyKey) Verify ¶
func (k PublicVerifyKey) Verify(message, sig []byte) bool
Verify checks that sig is a valid signature of message under this key.
type Request ¶
type Request struct {
// Subject fields
SubjectIdentity string // UUID or name of the requesting identity
// Target process
Process string // UUID or name of the target process
// Action
Action string // e.g. "READ", "TRANSFER", "system.obo:ACT_AS"
ActionParams map[string]Value // parameter values (string or int64)
// Tags: arbitrary key→value metadata attached to the request context
Tags map[string]string
// Attribute bags for SUBJECT.xxx and REQUEST.xxx conditions
SubjectAttrs map[string]Value
RequestAttrs map[string]Value
// contains filtered or unexported fields
}
Request represents a single authorisation evaluation request. Callers populate this struct and pass it to Engine.Evaluate.
func (*Request) GetActionParam ¶
GetActionParam returns the action parameter value and whether it exists.
func (*Request) GetEvalTime ¶
GetEvalTime returns the request's evaluation time, defaulting to time.Now() when zero.
func (*Request) GetIsHistoric ¶
GetIsHistoric returns whether the request is in a historic evaluation context.
func (*Request) GetOBODepth ¶
GetOBODepth returns the OBO delegation depth.
func (*Request) GetProcess ¶
GetProcess returns the process name/UUID.
func (*Request) GetRequestAttr ¶
GetRequestAttr returns the request attribute value for the given key.
func (*Request) GetSubjectAttr ¶
GetSubjectAttr returns the subject attribute value for the given key.
func (*Request) GetSubjectIdentity ¶
GetSubjectIdentity returns the subject identity string.
func (*Request) HasActionGroup ¶
HasActionGroup returns true if the action belongs to the given group.
func (*Request) HasOBOForGroup ¶
HasOBOForGroup returns true if the OBO target belongs to the given group.
func (*Request) HasProcessGroup ¶
HasProcessGroup returns true if the process belongs to the given group.
func (*Request) HasSubjectGroup ¶
HasSubjectGroup returns true if the subject belongs to the given group.
type UpdateEpoch ¶
type UpdateEpoch struct {
// Data is the base data for the epoch
Data *EpochData
// Loader provides the mechanism to lazily load policies
Loader PolicyLoader
// TrustProviders, when non-nil, atomically replaces the engine's stored
// trust provider map. Nil means no change to the current providers.
TrustProviders map[string]PublicVerifyKey
}
UpdateEpoch is used to pass details of an epoch to the Engine