Documentation
¶
Overview ¶
Package bridge provides cross-protocol bridging for agent-protocols.
The bridge package enables interoperability between the three authentication protocols (ID-JAG, AIMS, AAuth) by providing:
- Canonical identity representation shared across all protocols
- Token converters for translating between protocol-specific formats
- Multi-protocol middleware for accepting any protocol token
Canonical Identity ¶
All three protocols share a common set of identity fields that form the "canonical identity":
- Issuer (iss): Entity that issued the token
- Subject (sub): Primary identity being asserted
- Audience (aud): Intended recipient(s)
- IssuedAt (iat): Token creation time
- ExpiresAt (exp): Token validity end
- JWTID (jti): Unique identifier for replay prevention
The Identity type captures these common fields, allowing application code to work with a unified identity regardless of which protocol was used.
Token Conversion ¶
Convert between protocol token types:
// Extract canonical identity from any token identity, err := bridge.FromIDJAG(assertion) identity, err := bridge.FromWIT(wit) identity, err := bridge.FromAAuth(agentToken) // Convert to a different protocol assertion, err := identity.ToIDJAG(clientID) wit, err := identity.ToWIT(spiffeID) agentToken, err := identity.ToAAuth(cnf)
Multi-Protocol Middleware ¶
Accept any protocol token in HTTP requests:
handler := bridge.MultiProtocolMiddleware( bridge.WithIDJAGVerifier(idjagVerifier), bridge.WithWITVerifier(witVerifier), bridge.WithAAuthVerifier(aauthorizer), )(protectedHandler)
The middleware detects the protocol from request headers and extracts the canonical identity into the request context.
Protocol Detection ¶
Protocols are detected by examining:
- JWT typ header: oauth-id-jag+jwt, wimse-id+jwt, aa-agent+jwt
- HTTP headers: Authorization Bearer, Workload-Identity-Token, Signature-Key
Use Cases ¶
Common bridging scenarios:
- Gateway accepting multiple protocols from different clients
- Migration from one protocol to another
- Hybrid environments with mixed protocol usage
- Protocol translation for legacy system integration
Index ¶
- Constants
- Variables
- func IsAAuth(tokenString string) bool
- func IsIDJAG(tokenString string) bool
- func IsWIT(tokenString string) bool
- func MultiProtocolMiddleware(opts ...MiddlewareOption) func(http.Handler) http.Handler
- type AAuthVerifier
- type Actor
- type IDJAGVerifier
- type Identity
- func (i *Identity) HasDelegation() bool
- func (i *Identity) HasKeyBinding() bool
- func (i *Identity) IsExpired() bool
- func (i *Identity) SignAAuth(cnf *aauth.CNF, signer crypto.Signer, keyID string) (string, error)
- func (i *Identity) SignIDJAG(clientID string, signer crypto.Signer, keyID string) (string, error)
- func (i *Identity) SignWIT(signer crypto.Signer, keyID string) (string, error)
- func (i *Identity) ToAAuth(cnf *aauth.CNF) (*aauth.AgentToken, error)
- func (i *Identity) ToIDJAG(clientID string) (*idjag.Assertion, error)
- func (i *Identity) ToWIT() (*aims.WorkloadIdentityToken, error)
- type KeyBinding
- type MiddlewareConfig
- type MiddlewareOption
- func WithAAuthVerifier(v AAuthVerifier) MiddlewareOption
- func WithAllowedProtocols(protocols ...Protocol) MiddlewareOption
- func WithErrorHandler(handler func(w http.ResponseWriter, r *http.Request, err error)) MiddlewareOption
- func WithIDJAGVerifier(v IDJAGVerifier) MiddlewareOption
- func WithRequireKeyBinding() MiddlewareOption
- func WithWITVerifier(v WITVerifier) MiddlewareOption
- type ParseResult
- type Protocol
- type WITVerifier
Constants ¶
const ( // IdentityContextKey is the context key for the canonical identity. IdentityContextKey contextKey = "bridge.identity" // ProtocolContextKey is the context key for the detected protocol. ProtocolContextKey contextKey = "bridge.protocol" )
const ( TypIDJAG = "oauth-id-jag+jwt" TypWIT = "wimse-id+jwt" TypWPT = "wimse-proof+jwt" TypAAuth = "aa-agent+jwt" )
JWT typ header values for protocol detection.
Variables ¶
var ( ErrUnsupportedProtocol = errors.New("unsupported protocol") ErrMissingRequiredField = errors.New("missing required field") ErrInvalidIdentity = errors.New("invalid identity") )
Common errors for bridge operations.
var ( ErrNoToken = errors.New("no authentication token found") ErrVerificationFailed = errors.New("token verification failed") ErrNoVerifier = errors.New("no verifier configured for protocol") )
Common middleware errors.
var ( ErrInvalidJWT = errors.New("invalid JWT format") ErrUnknownProtocol = errors.New("unknown protocol") ErrParsingFailed = errors.New("token parsing failed") )
Parser errors.
Functions ¶
func MultiProtocolMiddleware ¶
func MultiProtocolMiddleware(opts ...MiddlewareOption) func(http.Handler) http.Handler
MultiProtocolMiddleware creates HTTP middleware that accepts any configured protocol.
The middleware detects the protocol from request headers:
- Authorization: Bearer <token> with typ=oauth-id-jag+jwt → ID-JAG
- Workload-Identity-Token header → AIMS
- Signature-Key header → AAuth
On success, the canonical Identity is stored in the request context.
Types ¶
type AAuthVerifier ¶
type AAuthVerifier interface {
VerifyAgentToken(ctx context.Context, tokenString string) (*aauth.AgentToken, error)
}
AAuthVerifier verifies AAuth agent tokens.
type Actor ¶
type Actor struct {
// Subject is the actor's identity.
Subject string
// Issuer is the actor's issuer (optional).
Issuer string
// Actor is the nested actor for multi-level delegation.
Actor *Actor
}
Actor represents an actor in a delegation chain (RFC 8693 act claim).
type IDJAGVerifier ¶
type IDJAGVerifier interface {
Verify(ctx context.Context, tokenString string) (*idjag.Assertion, error)
}
IDJAGVerifier verifies ID-JAG assertions.
type Identity ¶
type Identity struct {
// Protocol indicates which protocol this identity was extracted from.
Protocol Protocol
// Issuer is the entity that issued the token (iss claim).
Issuer string
// Subject is the primary identity being asserted (sub claim).
Subject string
// Audience is the intended recipient(s) of the token (aud claim).
Audience []string
// IssuedAt is when the token was created (iat claim).
IssuedAt time.Time
// ExpiresAt is when the token expires (exp claim).
ExpiresAt time.Time
// JWTID is the unique token identifier (jti claim).
JWTID string
// KeyBinding contains proof-of-possession key information if present.
// This is extracted from CNF claims in AIMS and AAuth.
KeyBinding *KeyBinding
// Actor contains delegation chain information if present.
// This is extracted from act claims in ID-JAG and AAuth.
Actor *Actor
// OriginalClaims preserves protocol-specific claims for reference.
OriginalClaims map[string]any
}
Identity represents the canonical identity extracted from any protocol. This is the common representation that enables cross-protocol bridging.
func FromAAuth ¶
func FromAAuth(token *aauth.AgentToken) (*Identity, error)
FromAAuth extracts a canonical identity from an AAuth agent token.
func FromWIT ¶
func FromWIT(wit *aims.WorkloadIdentityToken) (*Identity, error)
FromWIT extracts a canonical identity from an AIMS Workload Identity Token.
func IdentityFromContext ¶
IdentityFromContext retrieves the canonical identity from context.
func (*Identity) HasDelegation ¶
HasDelegation returns true if the identity has a delegation chain.
func (*Identity) HasKeyBinding ¶
HasKeyBinding returns true if the identity has proof-of-possession binding.
func (*Identity) ToAAuth ¶
ToAAuth converts the canonical identity to an AAuth agent token. The cnf parameter provides the required proof-of-possession binding.
type KeyBinding ¶
type KeyBinding struct {
// Kid is the key identifier.
Kid string
// JWK is the embedded public key in JWK format.
JWK []byte
// JKU is the URL to fetch the JWK Set.
JKU string
// X5T is the X.509 certificate SHA-256 thumbprint.
X5T string
}
KeyBinding represents proof-of-possession key binding information.
type MiddlewareConfig ¶
type MiddlewareConfig struct {
// IDJAGVerifier verifies ID-JAG assertions.
IDJAGVerifier IDJAGVerifier
// WITVerifier verifies AIMS WITs.
WITVerifier WITVerifier
// AAuthVerifier verifies AAuth agent tokens.
AAuthVerifier AAuthVerifier
// OnError is called when verification fails.
// If nil, a 401 response is returned.
OnError func(w http.ResponseWriter, r *http.Request, err error)
// RequireKeyBinding requires proof-of-possession for all protocols.
RequireKeyBinding bool
// AllowedProtocols limits which protocols are accepted.
// If empty, all configured protocols are allowed.
AllowedProtocols []Protocol
}
MiddlewareConfig holds configuration for multi-protocol middleware.
type MiddlewareOption ¶
type MiddlewareOption func(*MiddlewareConfig)
MiddlewareOption configures the middleware.
func WithAAuthVerifier ¶
func WithAAuthVerifier(v AAuthVerifier) MiddlewareOption
WithAAuthVerifier sets the AAuth verifier.
func WithAllowedProtocols ¶
func WithAllowedProtocols(protocols ...Protocol) MiddlewareOption
WithAllowedProtocols limits which protocols are accepted.
func WithErrorHandler ¶
func WithErrorHandler(handler func(w http.ResponseWriter, r *http.Request, err error)) MiddlewareOption
WithErrorHandler sets a custom error handler.
func WithIDJAGVerifier ¶
func WithIDJAGVerifier(v IDJAGVerifier) MiddlewareOption
WithIDJAGVerifier sets the ID-JAG verifier.
func WithRequireKeyBinding ¶
func WithRequireKeyBinding() MiddlewareOption
WithRequireKeyBinding requires proof-of-possession binding.
func WithWITVerifier ¶
func WithWITVerifier(v WITVerifier) MiddlewareOption
WithWITVerifier sets the AIMS WIT verifier.
type ParseResult ¶
type ParseResult struct {
// Protocol is the detected protocol.
Protocol Protocol
// Identity is the canonical identity extracted from the token.
Identity *Identity
// IDJAGAssertion is the parsed ID-JAG assertion (if Protocol == ProtocolIDJAG).
IDJAGAssertion *idjag.Assertion
// WIT is the parsed AIMS WIT (if Protocol == ProtocolAIMS).
WIT *aims.WorkloadIdentityToken
// AAuthToken is the parsed AAuth agent token (if Protocol == ProtocolAAuth).
AAuthToken *aauth.AgentToken
}
ParseResult contains the result of parsing a token.
func MustParse ¶
func MustParse(tokenString string) *ParseResult
MustParse is like Parse but panics on error. Use only in tests or when the token is known to be valid.
func Parse ¶
func Parse(tokenString string) (*ParseResult, error)
Parse attempts to parse a JWT token and detect its protocol. This parses without verification - use Verify methods for secure validation.
type Protocol ¶
type Protocol string
Protocol represents the source protocol of an identity.
const ( // ProtocolIDJAG indicates the identity came from an ID-JAG assertion. ProtocolIDJAG Protocol = "id-jag" // ProtocolAIMS indicates the identity came from an AIMS WIT. ProtocolAIMS Protocol = "aims" // ProtocolAAuth indicates the identity came from an AAuth agent token. ProtocolAAuth Protocol = "aauth" // ProtocolUnknown indicates the protocol could not be determined. ProtocolUnknown Protocol = "unknown" )
func DetectProtocol ¶
DetectProtocol examines a JWT token and returns its protocol.
func ProtocolFromContext ¶
ProtocolFromContext retrieves the detected protocol from context.
type WITVerifier ¶
type WITVerifier interface {
Verify(tokenString string) (*aims.WorkloadIdentityToken, error)
}
WITVerifier verifies AIMS Workload Identity Tokens.