Documentation
¶
Overview ¶
Package softwarestatement provides helpers for working with OAuth 2.0 Dynamic Client Registration software statements as described in RFC 7591 Section 2.3. It offers utilities to parse, validate, and create JWT-based statements that convey OAuth client metadata, including experimental trusted issuer tokens backed by Verifiable Credentials and SPIFFE JWT-SVIDs.
The package wraps github.com/golang-jwt/jwt/v5 so callers can parse or create a statement with familiar JWT primitives:
signed, err := softwarestatement.Create(claims, signingKey)
parsed, err := softwarestatement.ParseWithOptions(
signed,
keyFunc,
jwt.WithAudience("https://as.example.org/register"),
)
For deployments adopting the OAuth 2.0 Dynamic Client Registration with Trusted Issuer Credentials draft, helper types such as SPIFFEValidationOptions and RequireMetadata enforce draft-kasselman-oauth-dcr-trusted-issuer-token requirements, including SPIFFE trust domain checks and mandatory client metadata.
References:
- RFC 7591 (OAuth 2.0 Dynamic Client Registration Protocol): https://datatracker.ietf.org/doc/html/rfc7591
- OAuth 2.0 Dynamic Client Registration with Trusted Issuer Credentials (IETF draft): https://www.ietf.org/archive/id/draft-kasselman-oauth-dcr-trusted-issuer-token-01.html
- SPIFFE Workload API / JWT-SVIDs: https://spiffe.io/docs/latest/spiffe-about/spiffe-concepts/#jwt-svid
Index ¶
- func Create(claims *Claims, signingKey any) (string, error)
- func IssueSPIFFESoftwareStatement(signingKey any, opts SPIFFEIssueOptions) (string, error)
- func IssueVerifiableCredentialSoftwareStatement(signingKey any, opts VerifiableCredentialIssueOptions) (string, error)
- type Claims
- func Parse(statementJWT string, keyFunc jwt.Keyfunc) (*Claims, error)
- func ParseUnverified(statementJWT string) (*Claims, error)
- func ParseWithOptions(statementJWT string, keyFunc jwt.Keyfunc, opts ...jwt.ParserOption) (*Claims, error)
- func ValidateSPIFFE(statementJWT string, keyFunc jwt.Keyfunc, opts SPIFFEValidationOptions) (*Claims, error)
- func ValidateVerifiableCredential(statementJWT string, keyFunc jwt.Keyfunc, opts VCValidationOptions) (*Claims, error)
- func ValidateVerifiableCredentialSoftwareStatement(statementJWT string, keyFunc jwt.Keyfunc, opts VCValidationOptions) (*Claims, error)
- type MetadataField
- type MetadataValidator
- type SPIFFEIssueOptions
- type SPIFFEValidationOptions
- type VCStatusValidator
- type VCValidationOptions
- type VerifiableCredentialIssueOptions
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Create ¶
Create creates a signed software statement JWT from the provided claims and signing key. The signing method is automatically determined from the key type.
func IssueSPIFFESoftwareStatement ¶
func IssueSPIFFESoftwareStatement(signingKey any, opts SPIFFEIssueOptions) (string, error)
IssueSPIFFESoftwareStatement creates and signs a SPIFFE-based trusted issuer token that satisfies the requirements from Section 5.1 of the trusted issuer credential draft. It validates the trust domain, subject, TTL, and audiences before delegating to Create.
func IssueVerifiableCredentialSoftwareStatement ¶
func IssueVerifiableCredentialSoftwareStatement(signingKey any, opts VerifiableCredentialIssueOptions) (string, error)
IssueVerifiableCredentialSoftwareStatement creates a VC-backed trusted issuer token, validating issuer/subject/audience inputs and ensuring a vc payload is embedded before signing the JWT.
Types ¶
type Claims ¶
type Claims struct {
jwt.RegisteredClaims
authlib.ClientRegistrationRequest
// VC holds an optional Verifiable Credential payload when the software statement
// is implemented as a VC-JWT according to the trusted issuer token draft.
//
// [Trusted Issuer Token Draft]: https://www.ietf.org/archive/id/draft-kasselman-oauth-dcr-trusted-issuer-token-01.html
VC json.RawMessage `json:"vc,omitempty"`
}
Claims represents the claims in a software statement JWT. Software statements are JWTs that contain metadata about client software, signed by the software publisher. It embeds the standard ClientRegistrationRequest to inherit all client metadata fields.
func Parse ¶
Parse parses and validates a software statement JWT string using default validation behavior from jwt.ParseWithClaims. Use ParseWithOptions when you need to pass custom parser or claims validation options such as audience, issuer, or leeway requirements. The keyFunc is called to provide the verification key for the JWT signature. Returns the parsed claims if validation succeeds.
func ParseUnverified ¶
ParseUnverified parses a software statement JWT without verifying the signature. This should only be used when signature verification is not required or will be performed separately.
WARNING: This does not validate the JWT signature. Use Parse for signature verification.
func ParseWithOptions ¶
func ParseWithOptions(statementJWT string, keyFunc jwt.Keyfunc, opts ...jwt.ParserOption) (*Claims, error)
ParseWithOptions parses and validates a software statement JWT string while honoring the supplied jwt.ParserOption set. This allows callers to rely on the upstream validator for standard checks like issuer, subject, audience, temporal leeway, and optional JSON decoding behavior. The keyFunc is called to provide the verification key for the JWT signature. Returns the parsed claims if validation succeeds.
func ValidateSPIFFE ¶
func ValidateSPIFFE(statementJWT string, keyFunc jwt.Keyfunc, opts SPIFFEValidationOptions) (*Claims, error)
ValidateSPIFFE parses the JWT-SVID, verifies its signature, and enforces the SPIFFE requirements described in Section 5.1 of the trusted issuer token draft. Callers should supply a jwt.Keyfunc that is anchored to the OAuth Client Registration Endpoint's trust store (for example, the SPIFFE control plane or JWKS published by an approved trust domain) so that only issuers that are in a trust relationship with the registration endpoint can register new clients. In addition to signature verification, the helper asserts that iss/sub share the same trust domain, that the configured registration endpoint audience is present, and that any metadata validators succeed. This mirrors the draft's recommendation for verifying trusted issuer credentials before accepting the software statement contents.
func ValidateVerifiableCredential ¶
func ValidateVerifiableCredential(statementJWT string, keyFunc jwt.Keyfunc, opts VCValidationOptions) (*Claims, error)
ValidateVerifiableCredential validates a VC-JWT based trusted issuer token, enforcing the processing guidance from Section 5.2 of the trusted issuer token draft. The supplied jwt.Keyfunc must be derived from the OAuth Client Registration Endpoint's set of trusted issuers so that only mutually trusted credential issuers can influence client onboarding. Beyond signature checks, the helper verifies iss/aud/sub as requested, ensures the credentialStatus block (when present) passes caller-provided status validation, and exposes the parsed Claims so the registration endpoint can inspect credentialSubject or embedded OAuth client metadata before provisioning the client.
func ValidateVerifiableCredentialSoftwareStatement ¶
func ValidateVerifiableCredentialSoftwareStatement(statementJWT string, keyFunc jwt.Keyfunc, opts VCValidationOptions) (*Claims, error)
ValidateVerifiableCredentialSoftwareStatement is a convenience wrapper for ValidateVerifiableCredential. It exists to make the intent explicit when processing trusted issuer tokens.
func (*Claims) UnmarshalVC ¶
UnmarshalVC decodes the embedded Verifiable Credential payload (vc claim) into dst. This helper is useful when processing trusted issuer tokens where OAuth client metadata is conveyed in the VC structure.
type MetadataField ¶
type MetadataField string
MetadataField represents a single OAuth client metadata attribute that can be required when validating trusted issuer tokens.
const ( MetadataClientName MetadataField = "client_name" MetadataClientURI MetadataField = "client_uri" MetadataLogoURI MetadataField = "logo_uri" MetadataRedirectURIs MetadataField = "redirect_uris" MetadataGrantTypes MetadataField = "grant_types" MetadataResponseTypes MetadataField = "response_types" MetadataScope MetadataField = "scope" MetadataContacts MetadataField = "contacts" MetadataTOSURI MetadataField = "tos_uri" MetadataPolicyURI MetadataField = "policy_uri" MetadataJWKSURI MetadataField = "jwks_uri" MetadataJWKS MetadataField = "jwks" MetadataTokenEndpointAuthMethod MetadataField = "token_endpoint_auth_method" MetadataSoftwareID MetadataField = "software_id" MetadataSoftwareVersion MetadataField = "software_version" )
type MetadataValidator ¶
MetadataValidator allows callers to assert requirements on metadata extracted from a software statement.
func RequireMetadata ¶
func RequireMetadata(fields ...MetadataField) MetadataValidator
RequireMetadata returns a MetadataValidator that ensures the provided metadata fields are populated.
type SPIFFEIssueOptions ¶
type SPIFFEIssueOptions struct {
// TrustDomain identifies the SPIFFE trust domain (for example "spiffe://example.org").
// Required.
TrustDomain string
// Subject contains the SPIFFE ID of the workload that is registering a client. Either Subject or
// WorkloadPath must be provided. When WorkloadPath is supplied, the function assembles the subject
// from TrustDomain + WorkloadPath.
Subject string
// WorkloadPath is the SPIFFE workload path (for example "/workload/123"). Ignored if Subject is set.
WorkloadPath string
// Audience entries populate the aud claim targeting registration endpoints.
// At least one value is required.
Audience []string
// TTL controls the lifetime of the JWT (exp = iat + TTL). Must be positive.
TTL time.Duration
// Metadata optionally carries OAuth client metadata copied into the resulting claims.
Metadata *authlib.ClientRegistrationRequest
// VC allows embedding a Verifiable Credential payload (vc claim) so SPIFFE issuers can supply
// additional metadata through a VC structure. When nil, the vc claim is omitted.
VC any
// JWTID, when set, populates the jti claim.
JWTID string
// Now overrides the clock used for iat/exp. Defaults to time.Now.
Now func() time.Time
}
SPIFFEIssueOptions configures how IssueSPIFFESoftwareStatement constructs a trusted issuer token. It mirrors the SPIFFE JWT-SVID requirements from Section 5.1 of the trusted issuer token draft.
type SPIFFEValidationOptions ¶
type SPIFFEValidationOptions struct {
// TrustDomain identifies the SPIFFE trust domain that is allowed to issue the JWT-SVID.
// Example: "spiffe://example.org". If empty, the iss claim is only required to be non-empty.
TrustDomain string
// Audience must be present in the aud claim. When empty, the aud claim is only
// verified to be non-empty.
Audience string
// ClockSkew defines an allowed clock skew when validating temporal claims. Defaults to 1 minute.
ClockSkew time.Duration
// Now allows injecting a custom time source (useful for tests). Defaults to time.Now.
Now func() time.Time
// MetadataValidators contains additional validation hooks for OAuth client metadata.
MetadataValidators []MetadataValidator
}
SPIFFEValidationOptions configures validation for SPIFFE JWT-SVID based software statements.
Reference: Section 5.1 of the OAuth 2.0 Dynamic Client Registration with Trusted Issuer Credentials draft.
type VCStatusValidator ¶
VCStatusValidator allows callers to plug in revocation/status verification for VC-based software statements.
type VCValidationOptions ¶
type VCValidationOptions struct {
// TrustedIssuer, when set, must match the iss claim of the VC-JWT.
TrustedIssuer string
// Audience, when set, must be included in the aud claim.
Audience string
// Subject, when set, must match the sub claim.
Subject string
// ClockSkew defines an allowed clock skew when validating exp/iat. Defaults to 1 minute.
ClockSkew time.Duration
// Now allows overriding the current time source (useful for tests).
Now func() time.Time
// MetadataValidators contains additional validation hooks for OAuth client metadata.
MetadataValidators []MetadataValidator
// StatusValidator optionally validates the credentialStatus entry inside the VC payload.
StatusValidator VCStatusValidator
}
VCValidationOptions configures validation for Verifiable Credential JWT software statements as described in Section 5.2 of the trusted issuer token draft.
type VerifiableCredentialIssueOptions ¶
type VerifiableCredentialIssueOptions struct {
// Issuer is the VC Issuer identifier (iss claim). Required.
Issuer string
// Subject identifies the credential holder / client (sub claim). Required.
Subject string
// Audience entries populate the aud claim. At least one value is required.
Audience []string
// TTL controls exp relative to iat. Must be positive.
TTL time.Duration
// Metadata copies OAuth client metadata into the software statement.
Metadata *authlib.ClientRegistrationRequest
// VC contains the Verifiable Credential payload that will be embedded in the vc claim.
// Required.
VC any
// JWTID, when set, populates the jti claim.
JWTID string
// Now overrides the clock used for iat/exp. Defaults to time.Now.
Now func() time.Time
}
VerifiableCredentialIssueOptions configures IssueVerifiableCredentialSoftwareStatement to mint a VC-backed trusted issuer token (Section 5.2 of the draft).