Documentation
¶
Overview ¶
Package authzserver implements the ID-JAG Authorization Server. It handles token exchange (RFC 8693) and provides policy-based routing between automated (ID-JAG) and human consent (AAuth) flows.
Index ¶
- Constants
- Variables
- type DefaultPolicyEvaluator
- type ErrorResponse
- type IntrospectionResponse
- type MultiIssuerVerifier
- type Option
- func WithJWKSVerifier(jwksURL string, opts idjag.VerifierOptions) Option
- func WithLogger(logger *slog.Logger) Option
- func WithMultiIssuerVerifier(issuers map[string]string, opts idjag.VerifierOptions) Option
- func WithPersonServerURL(url string) Option
- func WithPolicyEvaluator(pe PolicyEvaluator) Option
- func WithSigningMethod(method jwt.SigningMethod) Option
- func WithStaticKeyVerifier(publicKey crypto.PublicKey, keyID string, opts idjag.VerifierOptions) Option
- func WithTokenTTL(ttl time.Duration) Option
- func WithVerifier(v idjag.Verifier) Option
- func WithVerifierChain(verifiers ...idjag.Verifier) Option
- type PolicyDecision
- type PolicyEvaluator
- type ScopePolicy
- type Server
- func (s *Server) HandleCreatePolicy(w http.ResponseWriter, r *http.Request)
- func (s *Server) HandleDeletePolicy(w http.ResponseWriter, r *http.Request)
- func (s *Server) HandleIntrospect(w http.ResponseWriter, r *http.Request)
- func (s *Server) HandleJWKS(w http.ResponseWriter, r *http.Request)
- func (s *Server) HandleListPolicies(w http.ResponseWriter, r *http.Request)
- func (s *Server) HandleListTokens(w http.ResponseWriter, r *http.Request)
- func (s *Server) HandleMetadata(w http.ResponseWriter, r *http.Request)
- func (s *Server) HandlePolicyEvaluate(w http.ResponseWriter, r *http.Request)
- func (s *Server) HandleRevoke(w http.ResponseWriter, r *http.Request)
- func (s *Server) HandleToken(w http.ResponseWriter, r *http.Request)
- func (s *Server) Handler() http.Handler
- func (s *Server) Issuer() string
- func (s *Server) KeyID() string
- func (s *Server) PublicKey() crypto.PublicKey
- func (s *Server) RegisterHandlers(mux *http.ServeMux)
- func (s *Server) Store() Store
- type StaticPolicyEvaluator
- func (pe *StaticPolicyEvaluator) Evaluate(ctx context.Context, agentID string, scopes []string) (*PolicyDecision, error)
- func (pe *StaticPolicyEvaluator) WithAAuthScopes(scopes ...string) *StaticPolicyEvaluator
- func (pe *StaticPolicyEvaluator) WithDefaultProtocol(protocol string) *StaticPolicyEvaluator
- func (pe *StaticPolicyEvaluator) WithIDJAGScopes(scopes ...string) *StaticPolicyEvaluator
- type Store
- type Token
- type TokenExchangeRequest
- type TokenResponse
- type VerifierChain
Constants ¶
const ( GrantTypeTokenExchange = "urn:ietf:params:oauth:grant-type:token-exchange" //nolint:gosec // Not a credential GrantTypeJWTBearer = "urn:ietf:params:oauth:grant-type:jwt-bearer" //nolint:gosec // Not a credential )
OAuth 2.0 grant types.
const ( TokenTypeJWT = "urn:ietf:params:oauth:token-type:jwt" //nolint:gosec // Not a credential TokenTypeIDJAG = "urn:ietf:params:oauth:token-type:id-jag" //nolint:gosec // Not a credential TokenTypeAccessToken = "urn:ietf:params:oauth:token-type:access_token" //nolint:gosec // Not a credential )
Token types.
Variables ¶
var ( // ErrInvalidPrivateKey is returned when the private key is invalid. ErrInvalidPrivateKey = errors.New("private key must implement crypto.Signer") // ErrMissingVerifier is returned when no verifier is configured. ErrMissingVerifier = errors.New("verifier is required") )
Package errors.
var ( // ErrNotFound is returned when a requested resource doesn't exist. ErrNotFound = errors.New("resource not found") // ErrAlreadyExists is returned when trying to create a resource that already exists. ErrAlreadyExists = errors.New("resource already exists") // ErrInvalidInput is returned when input validation fails. ErrInvalidInput = errors.New("invalid input") )
Standard errors for the Store interface.
Functions ¶
This section is empty.
Types ¶
type DefaultPolicyEvaluator ¶
type DefaultPolicyEvaluator struct {
// DefaultProtocol is the protocol to use when no policy matches.
// Default is "aauth" (require human consent for unknown scopes).
DefaultProtocol string
// contains filtered or unexported fields
}
DefaultPolicyEvaluator uses the store's scope policies to route scopes.
func NewDefaultPolicyEvaluator ¶
func NewDefaultPolicyEvaluator(store Store) *DefaultPolicyEvaluator
NewDefaultPolicyEvaluator creates a new policy evaluator backed by the store.
func (*DefaultPolicyEvaluator) Evaluate ¶
func (pe *DefaultPolicyEvaluator) Evaluate(ctx context.Context, agentID string, scopes []string) (*PolicyDecision, error)
Evaluate determines which protocol to use for the requested scopes.
type ErrorResponse ¶
type ErrorResponse struct {
Error string `json:"error"`
Description string `json:"error_description,omitempty"`
}
ErrorResponse represents an OAuth-style error response.
type IntrospectionResponse ¶
type IntrospectionResponse struct {
Active bool `json:"active"`
Scope string `json:"scope,omitempty"`
ClientID string `json:"client_id,omitempty"`
Username string `json:"username,omitempty"`
TokenType string `json:"token_type,omitempty"`
Exp int64 `json:"exp,omitempty"`
Iat int64 `json:"iat,omitempty"`
Sub string `json:"sub,omitempty"`
Aud string `json:"aud,omitempty"`
Iss string `json:"iss,omitempty"`
// Actor chain for delegation tokens
Act map[string]any `json:"act,omitempty"`
}
IntrospectionResponse is returned for token introspection.
type MultiIssuerVerifier ¶
type MultiIssuerVerifier struct {
// contains filtered or unexported fields
}
MultiIssuerVerifier verifies ID-JAG assertions from multiple trusted issuers. Each issuer is mapped to its JWKS URL for key retrieval.
func NewMultiIssuerVerifier ¶
func NewMultiIssuerVerifier(issuers map[string]string, opts idjag.VerifierOptions) *MultiIssuerVerifier
NewMultiIssuerVerifier creates a verifier that accepts tokens from multiple issuers. The issuers map keys are issuer URLs (the "iss" claim value) and values are JWKS URLs.
Example:
issuers := map[string]string{
"https://idp1.example.com": "https://idp1.example.com/.well-known/jwks.json",
"https://idp2.example.com": "https://idp2.example.com/oauth2/jwks",
}
verifier := NewMultiIssuerVerifier(issuers, opts)
func (*MultiIssuerVerifier) AddIssuer ¶
func (v *MultiIssuerVerifier) AddIssuer(issuer, jwksURL string)
AddIssuer adds a new trusted issuer at runtime.
func (*MultiIssuerVerifier) Issuers ¶
func (v *MultiIssuerVerifier) Issuers() []string
Issuers returns the list of trusted issuer URLs.
func (*MultiIssuerVerifier) RemoveIssuer ¶
func (v *MultiIssuerVerifier) RemoveIssuer(issuer string)
RemoveIssuer removes a trusted issuer.
type Option ¶
type Option func(*Server)
Option configures the Server.
func WithJWKSVerifier ¶
func WithJWKSVerifier(jwksURL string, opts idjag.VerifierOptions) Option
WithJWKSVerifier creates and sets a JWKS-based verifier for ID-JAG assertions. The verifier will fetch public keys from the provided JWKS URL.
func WithMultiIssuerVerifier ¶
func WithMultiIssuerVerifier(issuers map[string]string, opts idjag.VerifierOptions) Option
WithMultiIssuerVerifier creates a verifier that accepts tokens from multiple issuers. Each issuer is identified by its issuer URL and verified using its JWKS endpoint.
func WithPersonServerURL ¶
WithPersonServerURL sets the AAuth Person Server URL for consent redirects.
func WithPolicyEvaluator ¶
func WithPolicyEvaluator(pe PolicyEvaluator) Option
WithPolicyEvaluator sets the policy evaluator.
func WithSigningMethod ¶
func WithSigningMethod(method jwt.SigningMethod) Option
WithSigningMethod sets the JWT signing method.
func WithStaticKeyVerifier ¶
func WithStaticKeyVerifier(publicKey crypto.PublicKey, keyID string, opts idjag.VerifierOptions) Option
WithStaticKeyVerifier creates and sets a static key verifier for ID-JAG assertions. Use this when you have a pre-configured public key for a single issuer.
func WithVerifier ¶
WithVerifier sets the ID-JAG verifier.
func WithVerifierChain ¶
WithVerifierChain creates a verifier that tries multiple verifiers in order. This is useful when you need to support multiple verification strategies.
type PolicyDecision ¶
type PolicyDecision struct {
// Protocol indicates which protocol to use: "idjag" for automated, "aauth" for human consent
Protocol string `json:"protocol"`
// InteractionType indicates the required interaction level (for AAuth)
InteractionType string `json:"interaction_type,omitempty"`
// AllowedScopes is the list of scopes that can be automatically approved
AllowedScopes []string `json:"allowed_scopes,omitempty"`
// RequiredConsentScopes are scopes that require human consent
RequiredConsentScopes []string `json:"required_consent_scopes,omitempty"`
// Reason provides context for the decision
Reason string `json:"reason,omitempty"`
}
PolicyDecision represents the result of scope policy evaluation.
type PolicyEvaluator ¶
type PolicyEvaluator interface {
// Evaluate determines the authorization protocol for the requested scopes.
Evaluate(ctx context.Context, agentID string, scopes []string) (*PolicyDecision, error)
}
PolicyEvaluator determines which protocol to use for a given scope.
type ScopePolicy ¶
type ScopePolicy struct {
ID string `json:"id"`
Pattern string `json:"pattern"`
Protocol string `json:"protocol"`
InteractionType string `json:"interaction_type,omitempty"`
Description string `json:"description,omitempty"`
Priority int `json:"priority"`
CreatedAt time.Time `json:"created_at"`
}
ScopePolicy defines the authorization protocol for a scope pattern.
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server is the Authorization Server that handles ID-JAG token exchange and policy-based authorization routing.
func New ¶
func New(store Store, issuer string, privateKey crypto.PrivateKey, keyID string, opts ...Option) (*Server, error)
New creates a new Authorization Server.
func (*Server) HandleCreatePolicy ¶
func (s *Server) HandleCreatePolicy(w http.ResponseWriter, r *http.Request)
HandleCreatePolicy creates a new scope policy (POST /admin/policies).
func (*Server) HandleDeletePolicy ¶
func (s *Server) HandleDeletePolicy(w http.ResponseWriter, r *http.Request)
HandleDeletePolicy deletes a scope policy (DELETE /admin/policies/{id}).
func (*Server) HandleIntrospect ¶
func (s *Server) HandleIntrospect(w http.ResponseWriter, r *http.Request)
HandleIntrospect handles token introspection (POST /introspect).
func (*Server) HandleJWKS ¶
func (s *Server) HandleJWKS(w http.ResponseWriter, r *http.Request)
HandleJWKS returns the public key set (/.well-known/jwks.json).
func (*Server) HandleListPolicies ¶
func (s *Server) HandleListPolicies(w http.ResponseWriter, r *http.Request)
HandleListPolicies lists all scope policies (GET /admin/policies).
func (*Server) HandleListTokens ¶
func (s *Server) HandleListTokens(w http.ResponseWriter, r *http.Request)
HandleListTokens lists issued tokens (GET /admin/tokens).
func (*Server) HandleMetadata ¶
func (s *Server) HandleMetadata(w http.ResponseWriter, r *http.Request)
HandleMetadata returns the server metadata (/.well-known/oauth-authorization-server).
func (*Server) HandlePolicyEvaluate ¶
func (s *Server) HandlePolicyEvaluate(w http.ResponseWriter, r *http.Request)
HandlePolicyEvaluate evaluates policy for given scopes (POST /policy/evaluate).
func (*Server) HandleRevoke ¶
func (s *Server) HandleRevoke(w http.ResponseWriter, r *http.Request)
HandleRevoke handles token revocation (POST /revoke).
func (*Server) HandleToken ¶
func (s *Server) HandleToken(w http.ResponseWriter, r *http.Request)
HandleToken handles token exchange requests (POST /token).
func (*Server) Handler ¶
Handler returns an http.Handler that serves all Authorization Server endpoints. Use this when you want the Authorization Server to handle all routes.
func (*Server) RegisterHandlers ¶
RegisterHandlers registers all Authorization Server handlers on the given mux. This is a convenience method for registering all handlers at once.
type StaticPolicyEvaluator ¶
type StaticPolicyEvaluator struct {
// IDJAGScopes are scopes that can be automatically authorized via ID-JAG.
IDJAGScopes []string
// AAuthScopes are scopes that require human consent via AAuth.
AAuthScopes []string
// DefaultProtocol is used for scopes not in either list.
DefaultProtocol string
}
StaticPolicyEvaluator uses a static list of rules for evaluation. Useful for testing or simple deployments.
func NewStaticPolicyEvaluator ¶
func NewStaticPolicyEvaluator() *StaticPolicyEvaluator
NewStaticPolicyEvaluator creates a new static policy evaluator.
func (*StaticPolicyEvaluator) Evaluate ¶
func (pe *StaticPolicyEvaluator) Evaluate(ctx context.Context, agentID string, scopes []string) (*PolicyDecision, error)
Evaluate determines which protocol to use for the requested scopes.
func (*StaticPolicyEvaluator) WithAAuthScopes ¶
func (pe *StaticPolicyEvaluator) WithAAuthScopes(scopes ...string) *StaticPolicyEvaluator
WithAAuthScopes sets the scopes that require AAuth.
func (*StaticPolicyEvaluator) WithDefaultProtocol ¶
func (pe *StaticPolicyEvaluator) WithDefaultProtocol(protocol string) *StaticPolicyEvaluator
WithDefaultProtocol sets the default protocol.
func (*StaticPolicyEvaluator) WithIDJAGScopes ¶
func (pe *StaticPolicyEvaluator) WithIDJAGScopes(scopes ...string) *StaticPolicyEvaluator
WithIDJAGScopes sets the scopes that can use ID-JAG.
type Store ¶
type Store interface {
// Close closes the store.
Close() error
// CreateToken stores a new token record.
CreateToken(ctx context.Context, token *Token) error
// GetToken retrieves a token by ID.
GetToken(ctx context.Context, id string) (*Token, error)
// RevokeToken marks a token as revoked.
RevokeToken(ctx context.Context, id string) error
// ListTokens returns all tokens (for admin purposes).
ListTokens(ctx context.Context) ([]*Token, error)
// CreateScopePolicy creates a new scope policy.
CreateScopePolicy(ctx context.Context, policy *ScopePolicy) error
// GetScopePolicy retrieves a scope policy by ID.
GetScopePolicy(ctx context.Context, id string) (*ScopePolicy, error)
// ListScopePolicies returns all scope policies ordered by priority.
ListScopePolicies(ctx context.Context) ([]*ScopePolicy, error)
// DeleteScopePolicy removes a scope policy by ID.
DeleteScopePolicy(ctx context.Context, id string) error
}
Store is the interface for authzserver data persistence. Implementations should be thread-safe.
type Token ¶
type Token struct {
ID string `json:"id"`
MissionID string `json:"mission_id,omitempty"`
AgentID string `json:"agent_id"`
UserID string `json:"user_id"`
Scopes string `json:"scopes"`
TokenType string `json:"token_type"`
Protocol string `json:"protocol"`
IssuedAt time.Time `json:"issued_at"`
ExpiresAt time.Time `json:"expires_at"`
RevokedAt *time.Time `json:"revoked_at,omitempty"`
}
Token represents a token record in the store.
type TokenExchangeRequest ¶
type TokenExchangeRequest struct {
GrantType string `json:"grant_type"`
SubjectToken string `json:"subject_token"`
SubjectTokenType string `json:"subject_token_type"`
ActorToken string `json:"actor_token,omitempty"`
ActorTokenType string `json:"actor_token_type,omitempty"`
RequestedTokenType string `json:"requested_token_type,omitempty"`
Audience string `json:"audience,omitempty"`
Scope string `json:"scope,omitempty"`
Resource string `json:"resource,omitempty"`
}
TokenExchangeRequest represents an RFC 8693 token exchange request.
type TokenResponse ¶
type TokenResponse struct {
AccessToken string `json:"access_token"`
IssuedTokenType string `json:"issued_token_type,omitempty"`
TokenType string `json:"token_type"`
ExpiresIn int `json:"expires_in"`
Scope string `json:"scope,omitempty"`
RefreshToken string `json:"refresh_token,omitempty"`
}
TokenResponse is returned when a token is issued.
type VerifierChain ¶
type VerifierChain struct {
// contains filtered or unexported fields
}
VerifierChain chains multiple verifiers together, trying each in order until one succeeds or all fail.
func NewVerifierChain ¶
func NewVerifierChain(verifiers ...idjag.Verifier) *VerifierChain
NewVerifierChain creates a verifier that tries multiple verifiers in order. This is useful when you need different verification strategies for different tokens.
func (*VerifierChain) Add ¶
func (c *VerifierChain) Add(v idjag.Verifier)
Add appends a verifier to the chain.