Documentation
¶
Overview ¶
Package aims implements the Agent Identity Management System (AIMS) framework based on draft-klrc-aiagent-auth-00.
AIMS provides a comprehensive framework for AI agent authentication by composing multiple identity and security standards:
- SPIFFE (Secure Production Identity Framework For Everyone) for workload identity
- WIMSE (Workload Identity in Multi-System Environments) for token-based auth
- OAuth 2.0 for authorization delegation
EXPERIMENTAL ¶
This package implements a draft specification that is subject to change. The API may change in backwards-incompatible ways as the specification evolves.
Framework Overview ¶
Unlike specific protocols (like ID-JAG), AIMS is a layered framework that defines nine architectural layers for agent identity management:
- Identifiers - SPIFFE IDs as canonical workload identifiers
- Credentials - X.509 SVIDs, JWT-SVIDs, WITs
- Attestation - TPM, SGX, SEV-SNP, cloud attestation
- Provisioning - SPIRE, cloud-native credential issuance
- Authentication - mTLS, WIT/WPT token flows
- Authorization - Policy-based access control
- Monitoring - Audit logging and telemetry
- Policy - Centralized policy management
- Compliance - Regulatory and audit requirements
Key Components ¶
SPIFFE ID is the canonical identifier format:
spiffe://trust-domain/path
Workload Identity Token (WIT) is a JWT representing workload identity:
{
"iss": "https://spire.example.com",
"sub": "spiffe://example.com/agent/calendar-bot",
"aud": ["https://api.example.com"],
"exp": 1234567890,
"cnf": { "jwk": {...} }
}
WIMSE Proof Token (WPT) binds authentication to specific requests:
{
"iss": "spiffe://example.com/agent/calendar-bot",
"aud": "https://api.example.com",
"htm": "POST",
"htu": "/api/v1/events"
}
References ¶
- IETF Draft: https://datatracker.ietf.org/doc/html/draft-klrc-aiagent-auth-00
- SPIFFE: https://spiffe.io/
- WIMSE: https://datatracker.ietf.org/doc/draft-ietf-wimse-s2s-protocol/
- RFC 8693 (Token Exchange): https://tools.ietf.org/html/rfc8693
Index ¶
- Constants
- Variables
- func GenerateJTI() string
- func WPTFromHeader(r *http.Request) string
- type AgentIdentity
- type Attestation
- type AttestationOption
- type AttestationType
- type CNF
- type Credential
- type CredentialType
- type IdentityOption
- type JWTSVID
- type Layer
- type SPIFFEID
- func (s *SPIFFEID) Equal(other *SPIFFEID) bool
- func (s *SPIFFEID) InTrustDomain(domain string) bool
- func (s *SPIFFEID) IsAgent() bool
- func (s *SPIFFEID) IsService() bool
- func (s *SPIFFEID) IsUser() bool
- func (s *SPIFFEID) IsWorkload() bool
- func (s *SPIFFEID) MemberOf(pathPrefix string) bool
- func (s *SPIFFEID) Name() string
- func (s *SPIFFEID) String() string
- func (s *SPIFFEID) URI() *url.URL
- type WIMSEProofToken
- func (p *WIMSEProofToken) BindToRequest(r *http.Request, signer crypto.Signer, keyID string) error
- func (p *WIMSEProofToken) IsExpired() bool
- func (p *WIMSEProofToken) MatchesRequest(r *http.Request) bool
- func (p *WIMSEProofToken) Sign(signer crypto.Signer, keyID string) (string, error)
- func (p *WIMSEProofToken) Validate() error
- type WITOption
- type WPTOption
- type WorkloadIdentityToken
- func (w *WorkloadIdentityToken) ExpiresAt() time.Time
- func (w *WorkloadIdentityToken) IsExpired() bool
- func (w *WorkloadIdentityToken) SPIFFEID() (*SPIFFEID, error)
- func (w *WorkloadIdentityToken) Sign(signer crypto.Signer, keyID string) (string, error)
- func (w *WorkloadIdentityToken) TimeToExpiry() time.Duration
- func (w *WorkloadIdentityToken) Type() CredentialType
- func (w *WorkloadIdentityToken) Validate() error
- type X509SVID
Constants ¶
const ( // AttrInstanceID is the cloud instance ID. AttrInstanceID = "instance-id" // AttrRegion is the cloud region. AttrRegion = "region" // AttrAccountID is the cloud account/project ID. AttrAccountID = "account-id" // AttrNamespace is the Kubernetes namespace. AttrNamespace = "namespace" // AttrServiceAccount is the Kubernetes service account name. AttrServiceAccount = "service-account" // AttrPodName is the Kubernetes pod name. AttrPodName = "pod-name" // AttrContainerID is the container ID (Docker, containerd). AttrContainerID = "container-id" // AttrImageDigest is the container image digest. AttrImageDigest = "image-digest" // AttrPCR0 is the TPM PCR[0] value (BIOS/firmware). AttrPCR0 = "pcr0" // AttrMRENCLAVE is the SGX enclave measurement. AttrMRENCLAVE = "mrenclave" // AttrMRSIGNER is the SGX signer measurement. AttrMRSIGNER = "mrsigner" )
Common attestation attribute keys.
const ( PathPrefixAgent = "/agent/" PathPrefixWorkload = "/workload/" PathPrefixService = "/service/" PathPrefixUser = "/user/" )
Common path prefixes for SPIFFE IDs.
const ( // HeaderWPT is the HTTP header for the WIMSE Proof Token. HeaderWPT = "Workload-Identity-Token" // HeaderDPoP is an alternative header used in some DPoP-style deployments. HeaderDPoP = "DPoP" )
WPT header name per draft-ietf-wimse-s2s-protocol.
const SPIFFEScheme = "spiffe"
SPIFFEScheme is the URI scheme for SPIFFE IDs.
Variables ¶
var ( ErrInvalidSPIFFEID = errors.New("invalid SPIFFE ID") ErrEmptyTrustDomain = errors.New("trust domain cannot be empty") ErrInvalidScheme = errors.New("SPIFFE ID must use 'spiffe' scheme") ErrPathContainsQuery = errors.New("SPIFFE ID path cannot contain query parameters") ErrPathContainsFragment = errors.New("SPIFFE ID path cannot contain fragments") ErrTrustDomainHasPort = errors.New("trust domain cannot contain port") ErrTrustDomainHasUserInfo = errors.New("trust domain cannot contain user info") )
SPIFFE ID errors.
var ( ErrWITMissingSubject = errors.New("WIT must have a subject (SPIFFE ID)") ErrWITMissingIssuer = errors.New("WIT must have an issuer") ErrWITMissingAudience = errors.New("WIT must have at least one audience") ErrWITExpired = errors.New("WIT has expired") ErrWITNotYetValid = errors.New("WIT is not yet valid") )
WIT (Workload Identity Token) errors.
var ( ErrWPTMissingIssuer = errors.New("WPT must have an issuer (must match WIT subject)") ErrWPTMissingAudience = errors.New("WPT must have an audience") ErrWPTMissingHTM = errors.New("WPT must have HTTP method (htm)") ErrWPTMissingHTU = errors.New("WPT must have HTTP URI (htu)") ErrWPTExpired = errors.New("WPT has expired") )
WPT (WIMSE Proof Token) errors.
Functions ¶
func WPTFromHeader ¶
WPTFromHeader extracts a WPT JWT from an HTTP header.
Types ¶
type AgentIdentity ¶
type AgentIdentity struct {
// SPIFFEID is the canonical identifier for this agent.
SPIFFEID *SPIFFEID
// Credential is the authentication credential (X.509 SVID, JWT-SVID, or WIT).
Credential Credential
// Attestation contains attestation evidence for the agent's runtime environment.
Attestation *Attestation
// Metadata contains additional key-value pairs about the agent.
Metadata map[string]string
// CreatedAt is when this identity was created.
CreatedAt time.Time
}
AgentIdentity represents a fully-attested agent identity. It combines a SPIFFE ID, credentials, attestation evidence, and metadata.
func NewAgentIdentity ¶
func NewAgentIdentity(spiffeID *SPIFFEID, cred Credential, opts ...IdentityOption) *AgentIdentity
NewAgentIdentity creates an agent identity from a SPIFFE ID and credential.
func (*AgentIdentity) ExpiresAt ¶
func (ai *AgentIdentity) ExpiresAt() time.Time
ExpiresAt returns when this identity expires. Returns the credential's expiration time if available.
func (*AgentIdentity) IsValid ¶
func (ai *AgentIdentity) IsValid() bool
IsValid checks if the identity is currently valid. An identity is valid if:
- It has a SPIFFE ID
- It has a credential that is not expired
func (*AgentIdentity) TimeToExpiry ¶
func (ai *AgentIdentity) TimeToExpiry() time.Duration
TimeToExpiry returns the duration until this identity expires. Returns 0 if already expired.
type Attestation ¶
type Attestation struct {
// Type identifies the attestation mechanism.
Type AttestationType
// Evidence is the raw attestation evidence (format depends on Type).
// For TPM: TPM quote and PCR values
// For SGX: SGX report/quote
// For cloud: signed instance identity document
Evidence []byte
// Timestamp is when the attestation was generated.
Timestamp time.Time
// Attributes contains parsed attestation attributes.
// Keys and values depend on the attestation type.
Attributes map[string]string
}
Attestation represents attestation evidence for an agent's runtime environment. Attestation proves the agent is running in a trusted context.
func NewAttestation ¶
func NewAttestation(attestType AttestationType, evidence []byte) *Attestation
NewAttestation creates a new attestation with the given type and evidence.
func NewAttestationWithOptions ¶
func NewAttestationWithOptions(attestType AttestationType, evidence []byte, opts ...AttestationOption) *Attestation
NewAttestationWithOptions creates an attestation with options.
func (*Attestation) Age ¶
func (a *Attestation) Age() time.Duration
Age returns how old the attestation is.
func (*Attestation) GetAttribute ¶
func (a *Attestation) GetAttribute(key string) (string, bool)
GetAttribute returns an attestation attribute value.
type AttestationOption ¶
type AttestationOption func(*Attestation)
AttestationOption configures an Attestation.
func WithAttestationTimestamp ¶
func WithAttestationTimestamp(t time.Time) AttestationOption
WithAttestationTimestamp sets a custom timestamp for the attestation.
func WithAttribute ¶
func WithAttribute(key, value string) AttestationOption
WithAttribute adds an attribute to the attestation.
type AttestationType ¶
type AttestationType string
AttestationType identifies the attestation mechanism used.
const ( // AttestationTPM uses TPM-based hardware attestation. AttestationTPM AttestationType = "tpm" // AttestationSGX uses Intel SGX enclave attestation. AttestationSGX AttestationType = "sgx" // AttestationSEVSNP uses AMD SEV-SNP attestation. AttestationSEVSNP AttestationType = "sev-snp" // AttestationTDX uses Intel TDX attestation. AttestationTDX AttestationType = "tdx" // AttestationKubernetes uses Kubernetes service account attestation. AttestationKubernetes AttestationType = "kubernetes" // AttestationAWS uses AWS instance identity document attestation. AttestationAWS AttestationType = "aws" // AttestationGCP uses GCP instance identity token attestation. AttestationGCP AttestationType = "gcp" // AttestationAzure uses Azure managed identity attestation. AttestationAzure AttestationType = "azure" // AttestationGitHub uses GitHub Actions OIDC token attestation. AttestationGitHub AttestationType = "github" // AttestationUnix uses Unix domain socket attestation (PID, UID, GID). AttestationUnix AttestationType = "unix" // AttestationDocker uses Docker container attestation. AttestationDocker AttestationType = "docker" )
func (AttestationType) Description ¶
func (at AttestationType) Description() string
Description returns a human-readable description of the attestation type.
func (AttestationType) IsCloud ¶
func (at AttestationType) IsCloud() bool
IsCloud returns true if this is a cloud provider attestation type.
func (AttestationType) IsHardware ¶
func (at AttestationType) IsHardware() bool
IsHardware returns true if this is a hardware-based attestation type.
func (AttestationType) String ¶
func (at AttestationType) String() string
String returns the attestation type as a string.
type CNF ¶
type CNF struct {
// JWK is an embedded JSON Web Key.
JWK json.RawMessage `json:"jwk,omitempty"`
// Kid is a key ID reference (when key is retrieved separately).
Kid string `json:"kid,omitempty"`
// X5T is the X.509 certificate SHA-256 thumbprint.
X5T string `json:"x5t#S256,omitempty"`
}
CNF contains the confirmation key binding for a WIT. This proves possession of the key material.
type Credential ¶
type Credential interface {
// Type returns the credential type.
Type() CredentialType
// SPIFFEID returns the SPIFFE ID embedded in this credential.
SPIFFEID() *SPIFFEID
// IsExpired returns true if the credential has expired.
IsExpired() bool
// ExpiresAt returns when the credential expires.
ExpiresAt() time.Time
}
Credential is the interface for agent authentication credentials. All credential types (X.509 SVID, JWT-SVID, WIT) implement this interface.
type CredentialType ¶
type CredentialType string
CredentialType identifies the format of an agent credential.
const ( // CredentialX509SVID is an X.509 certificate-based SPIFFE Verifiable Identity Document. CredentialX509SVID CredentialType = "x509-svid" // CredentialJWTSVID is a JWT-based SPIFFE Verifiable Identity Document. CredentialJWTSVID CredentialType = "jwt-svid" // CredentialWIT is a WIMSE Workload Identity Token. CredentialWIT CredentialType = "wit" )
func (CredentialType) String ¶
func (ct CredentialType) String() string
String returns the credential type as a string.
type IdentityOption ¶
type IdentityOption func(*AgentIdentity)
IdentityOption configures an AgentIdentity.
func WithAttestation ¶
func WithAttestation(att *Attestation) IdentityOption
WithAttestation adds attestation evidence to the identity.
func WithMetadata ¶
func WithMetadata(key, value string) IdentityOption
WithMetadata adds metadata to the identity.
type JWTSVID ¶
type JWTSVID struct {
// Token is the raw JWT token string.
Token string
// contains filtered or unexported fields
}
JWTSVID represents a JWT SPIFFE Verifiable Identity Document. This is a JWT token that encodes the SPIFFE ID and can be used for non-mTLS authentication scenarios.
func NewJWTSVID ¶
NewJWTSVID creates a JWTSVID from its components.
type Layer ¶
type Layer int
Layer represents one of the 9 AIMS architectural layers. Each layer addresses a specific aspect of agent identity management.
const ( // LayerIdentifiers defines canonical workload identifiers (SPIFFE IDs). LayerIdentifiers Layer = iota + 1 // LayerCredentials defines credential formats (X.509 SVIDs, JWT-SVIDs, WITs). LayerCredentials // LayerAttestation defines attestation mechanisms (TPM, SGX, cloud). LayerAttestation // LayerProvisioning defines credential issuance (SPIRE, cloud-native). LayerProvisioning // LayerAuthentication defines authentication methods (mTLS, WIT/WPT). LayerAuthentication // LayerAuthorization defines access control policies. LayerAuthorization // LayerMonitoring defines audit logging and telemetry. LayerMonitoring // LayerPolicy defines centralized policy management. LayerPolicy // LayerCompliance defines regulatory and audit requirements. LayerCompliance )
func (Layer) Description ¶
Description returns a brief description of the layer's purpose.
type SPIFFEID ¶
type SPIFFEID struct {
// TrustDomain is the identity's trust domain (e.g., "example.com").
TrustDomain string
// Path is the workload path (e.g., "/agent/calendar-bot").
// It must start with "/" if non-empty.
Path string
}
SPIFFEID represents a SPIFFE identity URI. Format: spiffe://<trust-domain>/<path>
The trust domain identifies the trust root (e.g., "example.com"). The path identifies the specific workload within that domain.
func MustParseSPIFFEID ¶
MustParseSPIFFEID parses a SPIFFE ID string, panicking on error. Use only when the input is known to be valid (e.g., constants).
func NewSPIFFEID ¶
NewSPIFFEID creates a SPIFFE ID from trust domain and path components. The path must start with "/" if non-empty.
func ParseSPIFFEID ¶
ParseSPIFFEID parses a SPIFFE ID string into its components. The input must be a valid SPIFFE ID URI per the SPIFFE specification.
Valid examples:
spiffe://example.com spiffe://example.com/agent/calendar-bot spiffe://prod.example.com/workload/api-server
func (*SPIFFEID) InTrustDomain ¶
InTrustDomain returns true if this SPIFFE ID belongs to the given trust domain.
func (*SPIFFEID) IsAgent ¶
IsAgent returns true if the path indicates this is an agent identity. Agent identities typically have paths starting with "/agent/".
func (*SPIFFEID) IsService ¶
IsService returns true if the path indicates this is a service identity. Service identities typically have paths starting with "/service/".
func (*SPIFFEID) IsUser ¶
IsUser returns true if the path indicates this is a user identity. User identities typically have paths starting with "/user/".
func (*SPIFFEID) IsWorkload ¶
IsWorkload returns true if the path indicates this is a workload identity. Workload identities typically have paths starting with "/workload/".
func (*SPIFFEID) MemberOf ¶
MemberOf returns true if this SPIFFE ID's path starts with the given prefix.
func (*SPIFFEID) Name ¶
Name returns the final component of the path (the workload name). For example, "/agent/calendar-bot" returns "calendar-bot".
type WIMSEProofToken ¶
type WIMSEProofToken struct {
// Issuer must match the WIT's subject (the calling workload's SPIFFE ID).
Issuer string `json:"iss"`
// Audience is the target service (the recipient of the request).
Audience string `json:"aud"`
// IssuedAt is when this proof was created.
IssuedAt time.Time `json:"iat"`
// Expiry is when this proof expires (typically very short-lived).
Expiry time.Time `json:"exp,omitempty"`
// JWTID is a unique identifier for replay prevention.
JWTID string `json:"jti,omitempty"`
// Nonce for additional replay protection (if provided by server).
Nonce string `json:"nonce,omitempty"`
// HTM is the HTTP method (GET, POST, etc.).
HTM string `json:"htm"`
// HTU is the HTTP URI (typically the path and query).
HTU string `json:"htu"`
// ATH is the access token hash (if binding to an access token).
ATH string `json:"ath,omitempty"`
}
WIMSEProofToken (WPT) binds authentication to a specific HTTP request. Per draft-ietf-wimse-s2s-protocol, a WPT proves possession of the key that was bound to the WIT, and binds that proof to a specific request.
func NewWPT ¶
func NewWPT(issuer, audience, method, uri string, opts ...WPTOption) *WIMSEProofToken
NewWPT creates a new WIMSE Proof Token for an HTTP request. The issuer should be the SPIFFE ID of the calling workload (matching the WIT subject).
func NewWPTForRequest ¶
func NewWPTForRequest(issuer, audience string, r *http.Request, opts ...WPTOption) *WIMSEProofToken
NewWPTForRequest creates a WPT bound to an http.Request.
func NewWPTFromWIT ¶
func NewWPTFromWIT(wit *WorkloadIdentityToken, audience, method, uri string, opts ...WPTOption) *WIMSEProofToken
NewWPTFromWIT creates a WPT bound to a WIT for an HTTP request.
func (*WIMSEProofToken) BindToRequest ¶
BindToRequest adds the WPT to an HTTP request. The WPT is added as a signed JWT in the Workload-Identity-Token header.
func (*WIMSEProofToken) IsExpired ¶
func (p *WIMSEProofToken) IsExpired() bool
IsExpired returns true if the proof token has expired.
func (*WIMSEProofToken) MatchesRequest ¶
func (p *WIMSEProofToken) MatchesRequest(r *http.Request) bool
MatchesRequest checks if this WPT matches the given HTTP request.
func (*WIMSEProofToken) Validate ¶
func (p *WIMSEProofToken) Validate() error
Validate checks if the WPT has all required fields.
type WITOption ¶
type WITOption func(*WorkloadIdentityToken)
WITOption configures a WorkloadIdentityToken.
func WithWITNotBefore ¶
WithWITNotBefore sets the not-before time.
type WPTOption ¶
type WPTOption func(*WIMSEProofToken)
WPTOption configures a WIMSEProofToken.
func WithWPTAccessToken ¶
WithWPTAccessToken binds the WPT to an access token via ATH claim.
func WithWPTExpiry ¶
WithWPTExpiry sets a custom expiry time.
func WithWPTJTI ¶
WithWPTJTI sets the JWT ID for replay prevention.
func WithWPTNonce ¶
WithWPTNonce sets the nonce for replay protection.
type WorkloadIdentityToken ¶
type WorkloadIdentityToken struct {
// Issuer identifies the SPIFFE trust domain that issued this token.
Issuer string `json:"iss"`
// Subject is the SPIFFE ID of the workload.
Subject string `json:"sub"`
// Audience contains the intended recipients of this token.
Audience []string `json:"aud"`
// Expiry is when this token expires.
Expiry time.Time `json:"exp"`
// IssuedAt is when this token was issued.
IssuedAt time.Time `json:"iat"`
// NotBefore is the earliest time the token is valid (optional).
NotBefore time.Time `json:"nbf,omitempty"`
// JWTID is a unique identifier for this token.
JWTID string `json:"jti,omitempty"`
// CNF contains the confirmation key binding (key proof).
CNF *CNF `json:"cnf,omitempty"`
}
WorkloadIdentityToken (WIT) is a JWT representing workload identity. Per draft-ietf-wimse-s2s-protocol, a WIT is bound to a specific key and can be used to authenticate workload-to-workload communication.
func NewWIT ¶
func NewWIT(spiffeID *SPIFFEID, audience []string, ttl time.Duration, opts ...WITOption) *WorkloadIdentityToken
NewWIT creates a new Workload Identity Token. The SPIFFE ID's trust domain is used as the issuer.
func (*WorkloadIdentityToken) ExpiresAt ¶
func (w *WorkloadIdentityToken) ExpiresAt() time.Time
ExpiresAt returns the token's expiration time.
func (*WorkloadIdentityToken) IsExpired ¶
func (w *WorkloadIdentityToken) IsExpired() bool
IsExpired returns true if the token has expired.
func (*WorkloadIdentityToken) SPIFFEID ¶
func (w *WorkloadIdentityToken) SPIFFEID() (*SPIFFEID, error)
SPIFFEID returns the SPIFFE ID from the subject claim.
func (*WorkloadIdentityToken) TimeToExpiry ¶
func (w *WorkloadIdentityToken) TimeToExpiry() time.Duration
TimeToExpiry returns the duration until this token expires.
func (*WorkloadIdentityToken) Type ¶
func (w *WorkloadIdentityToken) Type() CredentialType
Type returns CredentialWIT.
func (*WorkloadIdentityToken) Validate ¶
func (w *WorkloadIdentityToken) Validate() error
Validate checks if the WIT has all required fields and is temporally valid.
type X509SVID ¶
type X509SVID struct {
// Certificates is the certificate chain, with the leaf certificate first.
Certificates []*x509.Certificate
// PrivateKey is the private key for the leaf certificate.
PrivateKey crypto.PrivateKey
// contains filtered or unexported fields
}
X509SVID represents an X.509 SPIFFE Verifiable Identity Document. It contains a certificate chain and private key for mTLS authentication.
func NewX509SVID ¶
func NewX509SVID(certs []*x509.Certificate, key crypto.PrivateKey) (*X509SVID, error)
NewX509SVID creates an X509SVID from a certificate chain and private key. The leaf certificate must contain a SPIFFE ID in its URI SAN.
func (*X509SVID) LeafCertificate ¶
func (s *X509SVID) LeafCertificate() *x509.Certificate
LeafCertificate returns the leaf (end-entity) certificate.
Directories
¶
| Path | Synopsis |
|---|---|
|
examples
|
|
|
mtls
command
Package main demonstrates AIMS agent authentication using mTLS with X.509 SVID.
|
Package main demonstrates AIMS agent authentication using mTLS with X.509 SVID. |
|
simple
command
Package main demonstrates basic AIMS agent authentication with SPIFFE ID.
|
Package main demonstrates basic AIMS agent authentication with SPIFFE ID. |