authzserver

package
v0.6.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 27, 2026 License: MIT Imports: 14 Imported by: 0

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

View Source
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.

View Source
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

View Source
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.

View Source
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.

func (*MultiIssuerVerifier) Verify

func (v *MultiIssuerVerifier) Verify(ctx context.Context, tokenString string) (*idjag.Assertion, error)

Verify validates the JWT signature and claims. It first extracts the issuer from the token, then uses the appropriate JWKS verifier for that 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 WithLogger

func WithLogger(logger *slog.Logger) Option

WithLogger sets the logger.

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

func WithPersonServerURL(url string) Option

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 WithTokenTTL

func WithTokenTTL(ttl time.Duration) Option

WithTokenTTL sets the token TTL.

func WithVerifier

func WithVerifier(v idjag.Verifier) Option

WithVerifier sets the ID-JAG verifier.

func WithVerifierChain

func WithVerifierChain(verifiers ...idjag.Verifier) Option

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

func (s *Server) Handler() http.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) Issuer

func (s *Server) Issuer() string

Issuer returns the token issuer URL.

func (*Server) KeyID

func (s *Server) KeyID() string

KeyID returns the key identifier.

func (*Server) PublicKey

func (s *Server) PublicKey() crypto.PublicKey

PublicKey returns the server's public key.

func (*Server) RegisterHandlers

func (s *Server) RegisterHandlers(mux *http.ServeMux)

RegisterHandlers registers all Authorization Server handlers on the given mux. This is a convenience method for registering all handlers at once.

func (*Server) Store

func (s *Server) Store() Store

Store returns the underlying store.

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.

func (*Token) IsValid

func (t *Token) IsValid() bool

IsValid returns true if the token is still valid.

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.

func (*VerifierChain) Verify

func (c *VerifierChain) Verify(ctx context.Context, tokenString string) (*idjag.Assertion, error)

Verify tries each verifier in order until one succeeds.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL