idjag

package
v0.5.0 Latest Latest
Warning

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

Go to latest
Published: May 25, 2026 License: MIT Imports: 18 Imported by: 0

Documentation

Overview

Package idjag implements Identity Assertion JWT Authorization Grant (ID-JAG) based on draft-ietf-oauth-identity-assertion-authz-grant.

ID-JAG enables secure token exchange where an agent presents a signed JWT assertion to obtain an access token. The assertion can represent:

  • An agent acting on its own behalf (no delegation)
  • An agent acting on behalf of a human (delegation via "act" claim)
  • Nested delegation chains (multiple levels of actors)

EXPERIMENTAL

This package implements a draft specification that is subject to change. The API may change in backwards-incompatible ways as the specification evolves.

Protocol Overview

The ID-JAG flow involves three parties:

  • Assertion Issuer: Creates and signs the identity assertion JWT
  • Authorization Server: Validates assertions and issues access tokens
  • Resource Server: Accepts access tokens to authorize requests

Basic flow:

  1. Agent obtains or creates a signed identity assertion
  2. Agent sends assertion to Authorization Server via token exchange
  3. Authorization Server validates assertion and returns access token
  4. Agent uses access token to call Resource Server

Delegation

When an agent acts on behalf of a human, the assertion includes an "act" (actor) claim identifying the agent:

{
  "iss": "https://issuer.example.com",
  "sub": "user:alice",
  "act": {
    "sub": "agent:calendar-bot"
  }
}

Nested delegation is supported by including nested "act" claims.

References

Index

Constants

View Source
const (
	ClaimIssuer         = "iss"
	ClaimSubject        = "sub"
	ClaimAudience       = "aud"
	ClaimExpirationTime = "exp"
	ClaimNotBefore      = "nbf"
	ClaimIssuedAt       = "iat"
	ClaimJWTID          = "jti"
)

Standard JWT claim names per RFC 7519.

View Source
const (
	// ClaimActor is the "act" claim for delegation per RFC 8693.
	// It contains information about the acting party when delegation is used.
	ClaimActor = "act"

	// ClaimClientID identifies the client making the token exchange request.
	ClaimClientID = "client_id"

	// ClaimScope contains the requested scope for the access token.
	ClaimScope = "scope"
)

ID-JAG specific claim names.

View Source
const (
	// GrantTypeTokenExchange is the grant type for RFC 8693 token exchange.
	GrantTypeTokenExchange = "urn:ietf:params:oauth:grant-type:token-exchange"

	// GrantTypeJWTBearer is the grant type for RFC 7523 JWT bearer assertion.
	GrantTypeJWTBearer = "urn:ietf:params:oauth:grant-type:jwt-bearer"
)

Grant types for token exchange.

View Source
const (
	// TokenTypeAccessToken indicates an OAuth 2.0 access token.
	TokenTypeAccessToken = "urn:ietf:params:oauth:token-type:access_token"

	// TokenTypeRefreshToken indicates an OAuth 2.0 refresh token.
	TokenTypeRefreshToken = "urn:ietf:params:oauth:token-type:refresh_token"

	// TokenTypeIDToken indicates an OpenID Connect ID token.
	TokenTypeIDToken = "urn:ietf:params:oauth:token-type:id_token"

	// TokenTypeJWT indicates a JWT token.
	TokenTypeJWT = "urn:ietf:params:oauth:token-type:jwt"

	// TokenTypeIDJAG indicates an ID-JAG assertion per draft-ietf-oauth-identity-assertion-authz-grant.
	TokenTypeIDJAG = "urn:ietf:params:oauth:token-type:id-jag"

	// TokenTypeSAML1 indicates a SAML 1.1 assertion.
	TokenTypeSAML1 = "urn:ietf:params:oauth:token-type:saml1"

	// TokenTypeSAML2 indicates a SAML 2.0 assertion.
	TokenTypeSAML2 = "urn:ietf:params:oauth:token-type:saml2"
)

Token types for token exchange requests.

View Source
const (
	AlgorithmRS256 = "RS256"
	AlgorithmRS384 = "RS384"
	AlgorithmRS512 = "RS512"
	AlgorithmES256 = "ES256"
	AlgorithmES384 = "ES384"
	AlgorithmES512 = "ES512"
	AlgorithmPS256 = "PS256"
	AlgorithmPS384 = "PS384"
	AlgorithmPS512 = "PS512"
)

Supported JWT signing algorithms.

View Source
const (
	// JWKSPath is the standard path for JWKS endpoint.
	JWKSPath = "/.well-known/jwks.json"

	// OpenIDConfigPath is the standard path for OpenID Connect discovery.
	OpenIDConfigPath = "/.well-known/openid-configuration"
)

JWKS (JSON Web Key Set) constants.

View Source
const (
	HeaderAuthorization = "Authorization"
	HeaderContentType   = "Content-Type"
)

HTTP header names.

View Source
const (
	ContentTypeFormURLEncoded = "application/x-www-form-urlencoded"
	ContentTypeJSON           = "application/json"
)

Content type values.

View Source
const (
	ErrorInvalidRequest       = "invalid_request"
	ErrorInvalidClient        = "invalid_client"
	ErrorInvalidGrant         = "invalid_grant"
	ErrorUnauthorizedClient   = "unauthorized_client"
	ErrorUnsupportedGrantType = "unsupported_grant_type"
	ErrorInvalidScope         = "invalid_scope"
)

Common OAuth 2.0 error codes.

View Source
const (
	// JWTTypeIDJAG is the typ header value for ID-JAG assertions
	// per draft-ietf-oauth-identity-assertion-authz-grant.
	JWTTypeIDJAG = "oauth-id-jag+jwt"
)

JWT header types per IETF specifications.

Variables

View Source
var (
	// ErrInvalidAssertion indicates the assertion JWT is malformed or invalid.
	ErrInvalidAssertion = errors.New("idjag: invalid assertion")

	// ErrExpiredAssertion indicates the assertion has expired (exp claim).
	ErrExpiredAssertion = errors.New("idjag: assertion expired")

	// ErrInvalidIssuer indicates the issuer claim doesn't match expected value.
	ErrInvalidIssuer = errors.New("idjag: invalid issuer")

	// ErrInvalidAudience indicates the audience claim doesn't match expected value.
	ErrInvalidAudience = errors.New("idjag: invalid audience")

	// ErrInvalidSubject indicates the subject claim is missing or invalid.
	ErrInvalidSubject = errors.New("idjag: invalid subject")

	// ErrSignatureInvalid indicates the JWT signature verification failed.
	ErrSignatureInvalid = errors.New("idjag: signature verification failed")

	// ErrKeyNotFound indicates the signing key was not found in JWKS.
	ErrKeyNotFound = errors.New("idjag: signing key not found")

	// ErrTokenExchangeFailed indicates the token exchange request failed.
	ErrTokenExchangeFailed = errors.New("idjag: token exchange failed")

	// ErrUnsupportedAlgorithm indicates the JWT uses an unsupported signing algorithm.
	ErrUnsupportedAlgorithm = errors.New("idjag: unsupported signing algorithm")

	// ErrMissingRequiredClaim indicates a required JWT claim is missing.
	ErrMissingRequiredClaim = errors.New("idjag: missing required claim")
)

Package-level errors for ID-JAG operations.

View Source
var NewIssuerService = NewIdPAuthorizationServer

NewIssuerService is deprecated. Use NewIdPAuthorizationServer instead. Deprecated: This simplified API does not follow the IETF draft OAuth flow.

Functions

func ContextWithAssertion

func ContextWithAssertion(ctx context.Context, assertion *Assertion) context.Context

ContextWithAssertion adds an Assertion to the context.

Types

type Actor

type Actor struct {
	// Subject identifies the actor (sub claim within act).
	Subject string `json:"sub"`

	// Issuer optionally identifies who asserted this actor's identity.
	Issuer string `json:"iss,omitempty"`

	// Actor allows for nested delegation chains.
	// For example, User -> Agent1 -> Agent2.
	Actor *Actor `json:"act,omitempty"`
}

Actor represents the acting party in a delegation chain. Per RFC 8693, this appears in the "act" claim.

type Assertion

type Assertion struct {
	// Issuer identifies the principal that issued the assertion (iss claim).
	// This is the IdP Authorization Server identifier.
	Issuer string `json:"iss"`

	// Subject identifies the principal that is the subject of the assertion (sub claim).
	// For direct agent authentication, this is the agent's identity.
	// For delegation, this is the human/principal identity being delegated.
	Subject string `json:"sub"`

	// Audience identifies the recipients that the assertion is intended for (aud claim).
	// This is the Resource Authorization Server identifier.
	Audience []string `json:"aud"`

	// ClientID identifies the OAuth client at the Resource Authorization Server (client_id claim).
	// This is a required claim per IETF draft.
	ClientID string `json:"client_id"`

	// IssuedAt is the time at which the assertion was issued (iat claim).
	IssuedAt time.Time `json:"iat"`

	// ExpiresAt is the expiration time of the assertion (exp claim).
	ExpiresAt time.Time `json:"exp"`

	// NotBefore is the time before which the assertion is not valid (nbf claim).
	NotBefore time.Time `json:"nbf,omitempty"`

	// JWTID is a unique identifier for the assertion (jti claim).
	// This is a required claim per IETF draft.
	JWTID string `json:"jti,omitempty"`

	// Actor identifies the acting party in delegation scenarios (act claim).
	// When present, Subject identifies the delegating principal and Actor
	// identifies the party acting on their behalf.
	// Note: The IETF draft does not normatively define act claim processing;
	// this implementation follows RFC 8693 for delegation semantics.
	Actor *Actor `json:"act,omitempty"`

	// Claims contains additional custom claims not covered by the standard fields.
	Claims map[string]any `json:"-"`
}

Assertion represents an ID-JAG identity assertion. It contains the standard JWT claims plus the optional "act" claim for delegation. Per draft-ietf-oauth-identity-assertion-authz-grant, required claims are: iss, sub, aud, client_id, jti, exp, iat.

func AssertionFromContext

func AssertionFromContext(ctx context.Context) *Assertion

AssertionFromContext retrieves an Assertion from the context. Returns nil if no assertion is present.

func NewAssertion

func NewAssertion(issuer, subject string, audience []string, ttl time.Duration) *Assertion

NewAssertion creates a new Assertion with common fields populated. A unique jti (JWT ID) is automatically generated per IETF draft requirements.

func NewDelegatedAssertion

func NewDelegatedAssertion(issuer, subject, actorSubject string, audience []string, ttl time.Duration) *Assertion

NewDelegatedAssertion creates an assertion representing delegation. The subject is the delegating principal (e.g., human user), and the actorSubject is the acting party (e.g., agent).

func ParseAssertion

func ParseAssertion(tokenString string) (*Assertion, error)

ParseAssertion parses a JWT string into an Assertion without verification. Use Verifier.Verify for validated parsing.

func (*Assertion) DelegationChain

func (a *Assertion) DelegationChain() []*Actor

DelegationChain returns the full chain of actors from outermost to innermost. For non-delegated assertions, returns nil.

func (*Assertion) IsDelegated

func (a *Assertion) IsDelegated() bool

IsDelegated returns true if the assertion represents delegation (has an actor).

func (*Assertion) IsExpired

func (a *Assertion) IsExpired() bool

IsExpired returns true if the assertion has expired.

func (*Assertion) MarshalJSON

func (a *Assertion) MarshalJSON() ([]byte, error)

MarshalJSON implements custom JSON marshaling for Assertion.

func (*Assertion) Sign

func (a *Assertion) Sign(method jwt.SigningMethod, key crypto.PrivateKey, keyID string) (string, error)

Sign creates a signed JWT string from the assertion. The JWT header includes typ="oauth-id-jag+jwt" per IETF draft.

func (*Assertion) WithActor

func (a *Assertion) WithActor(actor *Actor) *Assertion

WithActor adds an actor to the assertion for delegation.

func (*Assertion) WithClaim

func (a *Assertion) WithClaim(name string, value any) *Assertion

WithClaim adds a custom claim to the assertion.

func (*Assertion) WithClientID added in v0.4.0

func (a *Assertion) WithClientID(clientID string) *Assertion

WithClientID sets the client_id claim (required per IETF draft).

type AuthorizationServer

type AuthorizationServer struct {
	// Verifier validates incoming assertions.
	Verifier Verifier

	// SigningMethod is the JWT signing method for access tokens.
	SigningMethod jwt.SigningMethod

	// SigningKey is the private key for signing access tokens.
	SigningKey crypto.PrivateKey

	// KeyID is the key identifier to include in token headers.
	KeyID string

	// Issuer is the issuer claim for access tokens.
	Issuer string

	// TokenTTL is the lifetime for issued access tokens.
	TokenTTL time.Duration

	// AllowedScopes restricts which scopes can be requested.
	// If empty, all scopes are allowed.
	AllowedScopes []string

	// ScopeValidator is an optional function to validate scope requests.
	// If set, it is called to validate the requested scope against the assertion.
	ScopeValidator func(assertion *Assertion, requestedScope string) error
}

AuthorizationServer is the Resource Authorization Server that exchanges ID-JAG assertions for access tokens. Per draft-ietf-oauth-identity-assertion-authz-grant, the primary grant type is jwt-bearer (RFC 7523), though token-exchange is also supported.

IETF-compliant flow:

  1. Agent obtains ID-JAG from IdP (via IdPAuthorizationServer)
  2. Agent sends ID-JAG to Resource AS using grant_type=jwt-bearer
  3. Resource AS validates ID-JAG and issues access token

func NewAuthorizationServer

func NewAuthorizationServer(verifier Verifier, signingMethod jwt.SigningMethod, signingKey crypto.PrivateKey, keyID, issuer string) *AuthorizationServer

NewAuthorizationServer creates a new authorization server.

func (*AuthorizationServer) ServeHTTP

func (s *AuthorizationServer) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP implements http.Handler for the token endpoint.

type DelegationRequest added in v0.4.0

type DelegationRequest struct {
	Subject           string            `json:"subject"`
	AgentID           string            `json:"agent_id"`
	Audience          []string          `json:"audience"`
	RequestedScopes   []string          `json:"requested_scopes,omitempty"`
	DelegationContext map[string]string `json:"delegation_context,omitempty"`
}

DelegationRequest is deprecated. Use IDJAGRequest instead. Deprecated: This simplified API does not follow the IETF draft OAuth flow.

type DelegationResponse added in v0.4.0

type DelegationResponse struct {
	Assertion string `json:"assertion"`
	ExpiresIn int    `json:"expires_in"`
	Subject   string `json:"subject"`
	Actor     string `json:"actor"`
}

DelegationResponse is deprecated. Use IDJAGResponse instead. Deprecated: This simplified API does not follow the IETF draft OAuth flow.

type IDJAGClient added in v0.4.0

type IDJAGClient struct {
	// TokenURL is the IdP's token endpoint.
	TokenURL string

	// HTTPClient is the HTTP client to use. If nil, http.DefaultClient is used.
	HTTPClient *http.Client

	// ClientID is the OAuth client identifier.
	ClientID string

	// ClientSecret is the OAuth client secret (for confidential clients).
	ClientSecret string
}

IDJAGClient requests ID-JAG assertions from an IdP via OAuth token exchange.

func NewIDJAGClient added in v0.4.0

func NewIDJAGClient(tokenURL string) *IDJAGClient

NewIDJAGClient creates a client for requesting ID-JAG assertions.

func (*IDJAGClient) RequestIDJAG added in v0.4.0

func (c *IDJAGClient) RequestIDJAG(ctx context.Context, req *IDJAGRequest) (*IDJAGResponse, error)

RequestIDJAG requests an ID-JAG from the IdP using OAuth token exchange. Per IETF draft, this uses grant_type=token-exchange with requested_token_type=id-jag.

func (*IDJAGClient) WithCredentials added in v0.4.0

func (c *IDJAGClient) WithCredentials(clientID, clientSecret string) *IDJAGClient

WithCredentials sets client credentials for authentication.

type IDJAGRequest added in v0.4.0

type IDJAGRequest struct {
	// SubjectToken is the security token representing the user's identity.
	// This is typically an ID token, SAML assertion, or refresh token.
	SubjectToken string

	// SubjectTokenType identifies the type of subject token.
	// Common values: TokenTypeIDToken, TokenTypeSAML2, TokenTypeRefreshToken.
	SubjectTokenType string

	// ActorToken optionally identifies the acting party (agent).
	// Per IETF draft, processing of actor_token is not normatively defined.
	ActorToken string

	// ActorTokenType identifies the type of actor token (required if ActorToken set).
	ActorTokenType string

	// Audience is the Resource Authorization Server identifier.
	Audience string

	// ClientID is the OAuth client identifier at the Resource Authorization Server.
	ClientID string

	// Scope is the requested scope (optional).
	Scope string

	// Resource is the resource identifier per RFC 8707 (optional).
	Resource string
}

IDJAGRequest represents an OAuth 2.0 token exchange request for an ID-JAG. Per IETF draft, the request uses grant_type=token-exchange.

type IDJAGResponse added in v0.4.0

type IDJAGResponse struct {
	// AccessToken contains the ID-JAG assertion (named per OAuth convention).
	AccessToken string `json:"access_token"`

	// IssuedTokenType is always TokenTypeIDJAG for ID-JAG responses.
	IssuedTokenType string `json:"issued_token_type"`

	// TokenType is "N_A" per RFC 8693 for non-access-token responses.
	TokenType string `json:"token_type"`

	// ExpiresIn is the assertion lifetime in seconds.
	ExpiresIn int `json:"expires_in"`

	// Scope is the granted scope.
	Scope string `json:"scope,omitempty"`
}

IDJAGResponse is the token exchange response containing the ID-JAG.

type IdPAuthorizationServer added in v0.4.0

type IdPAuthorizationServer struct {
	// Issuer is the issuer identifier (iss claim) for created assertions.
	Issuer string

	// SigningMethod is the JWT signing method (e.g., RS256, ES256).
	SigningMethod jwt.SigningMethod

	// SigningKey is the private key for signing assertions.
	SigningKey crypto.PrivateKey

	// KeyID is the key identifier to include in JWT headers.
	KeyID string

	// AssertionTTL is the lifetime for issued assertions.
	// Default is 5 minutes per IETF draft recommendations.
	AssertionTTL time.Duration

	// SubjectTokenVerifier validates the subject_token (e.g., ID token, refresh token).
	// If nil, subject tokens are not validated (not recommended for production).
	SubjectTokenVerifier Verifier

	// DelegationPolicy is called to validate delegation requests.
	// If nil, all delegation requests are allowed.
	DelegationPolicy func(ctx context.Context, req *IDJAGRequest) error
}

IdPAuthorizationServer issues ID-JAG assertions via OAuth 2.0 token exchange. Per draft-ietf-oauth-identity-assertion-authz-grant, clients request an ID-JAG using grant_type=token-exchange with requested_token_type=id-jag.

func NewIdPAuthorizationServer added in v0.4.0

func NewIdPAuthorizationServer(issuer string, signingMethod jwt.SigningMethod, signingKey crypto.PrivateKey, keyID string) *IdPAuthorizationServer

NewIdPAuthorizationServer creates a new IdP Authorization Server for issuing ID-JAGs.

func (*IdPAuthorizationServer) CreateDelegatedAssertion added in v0.4.0

func (s *IdPAuthorizationServer) CreateDelegatedAssertion(ctx context.Context, req *DelegationRequest) (*DelegationResponse, error)

CreateDelegatedAssertion is deprecated. Use IssueIDJAG instead. Deprecated: This simplified API does not follow the IETF draft OAuth flow.

func (*IdPAuthorizationServer) CreateNestedDelegation added in v0.4.0

func (s *IdPAuthorizationServer) CreateNestedDelegation(ctx context.Context, subject string, actors []string, audience []string) (*DelegationResponse, error)

CreateNestedDelegation creates an assertion with a nested delegation chain.

func (*IdPAuthorizationServer) IssueIDJAG added in v0.4.0

IssueIDJAG creates an ID-JAG assertion from a token exchange request.

func (*IdPAuthorizationServer) ServeHTTP added in v0.4.0

ServeHTTP implements http.Handler for the IdP token endpoint. Handles token exchange requests with requested_token_type=id-jag.

type IssuerClient added in v0.4.0

type IssuerClient struct {
	IssuerURL  string
	HTTPClient *http.Client
}

IssuerClient is deprecated. Use IDJAGClient instead. Deprecated: This simplified API does not follow the IETF draft OAuth flow.

func NewIssuerClient added in v0.4.0

func NewIssuerClient(issuerURL string) *IssuerClient

NewIssuerClient is deprecated. Use NewIDJAGClient instead.

func (*IssuerClient) RequestDelegatedAssertion added in v0.4.0

func (c *IssuerClient) RequestDelegatedAssertion(ctx context.Context, req *DelegationRequest) (*DelegationResponse, error)

RequestDelegatedAssertion is deprecated.

type IssuerHandler added in v0.4.0

type IssuerHandler struct {
	// contains filtered or unexported fields
}

IssuerHandler is deprecated. Use IdPAuthorizationServer.ServeHTTP instead. Deprecated: This simplified API does not follow the IETF draft OAuth flow.

func NewIssuerHandler added in v0.4.0

func NewIssuerHandler(issuer *IdPAuthorizationServer) *IssuerHandler

NewIssuerHandler is deprecated. Deprecated: Use IdPAuthorizationServer directly as an http.Handler.

func (*IssuerHandler) ServeHTTP added in v0.4.0

func (h *IssuerHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP handles legacy delegation requests (JSON body, not OAuth).

type IssuerService added in v0.4.0

type IssuerService = IdPAuthorizationServer

IssuerService is deprecated. Use IdPAuthorizationServer instead. Deprecated: This simplified API does not follow the IETF draft OAuth flow.

type JWK

type JWK struct {
	KeyType   string `json:"kty"`
	KeyID     string `json:"kid"`
	Algorithm string `json:"alg,omitempty"`
	Use       string `json:"use,omitempty"`

	// RSA parameters
	N string `json:"n,omitempty"` // Modulus
	E string `json:"e,omitempty"` // Exponent

	// EC parameters
	Curve string `json:"crv,omitempty"` // Curve name
	X     string `json:"x,omitempty"`   // X coordinate
	Y     string `json:"y,omitempty"`   // Y coordinate
}

JWK represents a JSON Web Key.

func NewJWKFromECPublicKey

func NewJWKFromECPublicKey(pubKey *ecdsa.PublicKey, keyID, algorithm string) JWK

NewJWKFromECPublicKey creates a JWK from an EC public key.

func NewJWKFromRSAPublicKey

func NewJWKFromRSAPublicKey(pubKey *rsa.PublicKey, keyID, algorithm string) JWK

NewJWKFromRSAPublicKey creates a JWK from an RSA public key.

func (*JWK) ToPublicKey

func (k *JWK) ToPublicKey() (crypto.PublicKey, error)

ToPublicKey converts a JWK to a crypto.PublicKey.

type JWKS

type JWKS struct {
	Keys []JWK `json:"keys"`
}

JWKS represents a JSON Web Key Set.

type JWKSHandler

type JWKSHandler struct {
	// contains filtered or unexported fields
}

JWKSHandler serves a JWKS endpoint.

func NewJWKSHandler

func NewJWKSHandler(jwks *JWKS) *JWKSHandler

NewJWKSHandler creates a handler that serves the given JWKS.

func (*JWKSHandler) ServeHTTP

func (h *JWKSHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP implements http.Handler.

type JWKSVerifier

type JWKSVerifier struct {
	// contains filtered or unexported fields
}

JWKSVerifier verifies JWTs using keys fetched from a JWKS endpoint.

func NewJWKSVerifier

func NewJWKSVerifier(jwksURL string, opts VerifierOptions) *JWKSVerifier

NewJWKSVerifier creates a verifier that fetches keys from a JWKS endpoint.

func (*JWKSVerifier) Verify

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

Verify validates the JWT signature and claims using JWKS.

func (*JWKSVerifier) WithCacheTTL

func (v *JWKSVerifier) WithCacheTTL(ttl time.Duration) *JWKSVerifier

WithCacheTTL sets the cache duration for JWKS keys.

func (*JWKSVerifier) WithHTTPClient

func (v *JWKSVerifier) WithHTTPClient(client *http.Client) *JWKSVerifier

WithHTTPClient sets a custom HTTP client for JWKS fetching.

type JWTBearerClient

type JWTBearerClient struct {
	// TokenURL is the authorization server's token endpoint.
	TokenURL string

	// HTTPClient is the HTTP client to use for requests.
	HTTPClient *http.Client

	// ClientID is the OAuth client identifier.
	ClientID string
}

JWTBearerClient handles JWT bearer assertion grants per RFC 7523.

func NewJWTBearerClient

func NewJWTBearerClient(tokenURL string) *JWTBearerClient

NewJWTBearerClient creates a new JWT bearer client.

func (*JWTBearerClient) Exchange

func (c *JWTBearerClient) Exchange(ctx context.Context, assertion, scope string) (*TokenExchangeResponse, error)

Exchange exchanges a JWT assertion for an access token using JWT bearer grant.

type ResourceServer

type ResourceServer struct {
	// Verifier validates incoming access tokens.
	Verifier Verifier
}

ResourceServer provides middleware for validating access tokens.

func NewResourceServer

func NewResourceServer(verifier Verifier) *ResourceServer

NewResourceServer creates a new resource server middleware.

func (*ResourceServer) Middleware

func (rs *ResourceServer) Middleware(next http.Handler) http.Handler

Middleware returns an HTTP middleware that validates Bearer tokens.

type StaticKeyVerifier

type StaticKeyVerifier struct {
	// contains filtered or unexported fields
}

StaticKeyVerifier verifies JWTs using a pre-configured public key.

func NewStaticKeyVerifier

func NewStaticKeyVerifier(publicKey crypto.PublicKey, keyID string, opts VerifierOptions) *StaticKeyVerifier

NewStaticKeyVerifier creates a verifier with a single public key.

func (*StaticKeyVerifier) Verify

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

Verify validates the JWT signature and claims.

type TokenErrorResponse

type TokenErrorResponse struct {
	Error            string `json:"error"`
	ErrorDescription string `json:"error_description,omitempty"`
	ErrorURI         string `json:"error_uri,omitempty"`
}

TokenErrorResponse represents an OAuth 2.0 error response from the authorization server during token exchange.

type TokenExchangeClient

type TokenExchangeClient struct {
	// TokenURL is the authorization server's token endpoint.
	TokenURL string

	// HTTPClient is the HTTP client to use for requests.
	// If nil, http.DefaultClient is used.
	HTTPClient *http.Client

	// ClientID is the OAuth client identifier.
	// If set, it will be included in the request.
	ClientID string

	// ClientSecret is the OAuth client secret.
	// If set, HTTP Basic authentication will be used.
	ClientSecret string
}

TokenExchangeClient handles OAuth 2.0 token exchange requests per RFC 8693.

func NewTokenExchangeClient

func NewTokenExchangeClient(tokenURL string) *TokenExchangeClient

NewTokenExchangeClient creates a new token exchange client.

func (*TokenExchangeClient) Exchange

Exchange performs a token exchange request.

func (*TokenExchangeClient) ExchangeAssertion

func (c *TokenExchangeClient) ExchangeAssertion(ctx context.Context, assertion string, scope string) (*TokenExchangeResponse, error)

ExchangeAssertion is a convenience method for exchanging an ID-JAG assertion. It sets the subject token type to JWT automatically.

func (*TokenExchangeClient) WithCredentials

func (c *TokenExchangeClient) WithCredentials(clientID, clientSecret string) *TokenExchangeClient

WithCredentials sets client credentials for authentication.

func (*TokenExchangeClient) WithHTTPClient

func (c *TokenExchangeClient) WithHTTPClient(client *http.Client) *TokenExchangeClient

WithHTTPClient sets a custom HTTP client.

type TokenExchangeRequest

type TokenExchangeRequest struct {
	// SubjectToken is the security token being exchanged (required).
	// For ID-JAG, this is the signed assertion JWT.
	SubjectToken string

	// SubjectTokenType identifies the type of subject token (required).
	// For ID-JAG assertions, use TokenTypeJWT.
	SubjectTokenType string

	// ActorToken is an optional security token representing the actor.
	ActorToken string

	// ActorTokenType identifies the type of actor token (required if ActorToken is set).
	ActorTokenType string

	// RequestedTokenType identifies the type of token being requested.
	// Defaults to TokenTypeAccessToken if not specified.
	RequestedTokenType string

	// Scope is the requested scope for the issued token.
	Scope string

	// Resource is the target resource for the issued token.
	Resource string

	// Audience is the target audience for the issued token.
	Audience string
}

TokenExchangeRequest represents an RFC 8693 token exchange request.

type TokenExchangeResponse

type TokenExchangeResponse struct {
	// AccessToken is the issued security token.
	AccessToken string `json:"access_token"`

	// IssuedTokenType identifies the type of token issued.
	IssuedTokenType string `json:"issued_token_type"`

	// TokenType is typically "Bearer".
	TokenType string `json:"token_type"`

	// ExpiresIn is the lifetime in seconds of the access token.
	ExpiresIn int `json:"expires_in,omitempty"`

	// Scope is the scope of the access token.
	Scope string `json:"scope,omitempty"`

	// RefreshToken is an optional refresh token.
	RefreshToken string `json:"refresh_token,omitempty"`
}

TokenExchangeResponse represents an RFC 8693 token exchange response.

type Verifier

type Verifier interface {
	// Verify validates the JWT and returns the parsed Assertion.
	Verify(ctx context.Context, tokenString string) (*Assertion, error)
}

Verifier validates ID-JAG assertions.

type VerifierOptions

type VerifierOptions struct {
	// ExpectedIssuer is the required issuer claim value.
	// If empty, issuer is not validated.
	ExpectedIssuer string

	// ExpectedAudience is the required audience claim value.
	// If empty, audience is not validated.
	ExpectedAudience string

	// AllowedAlgorithms restricts which signing algorithms are accepted.
	// If empty, defaults to RS256, RS384, RS512, ES256, ES384, ES512.
	AllowedAlgorithms []string

	// ClockSkew allows for clock differences between systems.
	// Default is 0 (strict timing).
	ClockSkew time.Duration

	// RequireActor requires the assertion to have an actor claim.
	RequireActor bool
}

VerifierOptions configures assertion verification.

Directories

Path Synopsis
examples
delegation command
Package main demonstrates ID-JAG with human-to-agent delegation.
Package main demonstrates ID-JAG with human-to-agent delegation.
simple command
Package main demonstrates a simple ID-JAG token exchange flow without delegation.
Package main demonstrates a simple ID-JAG token exchange flow without delegation.

Jump to

Keyboard shortcuts

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