oid4vci

package module
v0.44.0 Latest Latest
Warning

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

Go to latest
Published: Oct 16, 2026 License: MIT Imports: 11 Imported by: 0

README

OID4VCgo

Release CI OID4VCI Conformance OID4VP Conformance Polaris interop OpenSSF Scorecard Go Reference

Quality Gate Coverage Lines of Code Security Rating Maintainability Rating Reliability Rating Vulnerabilities Code Smells Technical Debt

OpenID Certified™ OpenID4VCI 1.0 + OpenID4VP 1.0, under the HAIP 1.0 profile, for Go.

OID4VCgo is a sister library to FAPIgo, targeting the full OpenID4VC High Assurance Interoperability Profile (HAIP) 1.0 — the OpenID Foundation's interoperability profile for digital credential issuance and presentation where a high level of security and privacy is required (e.g. mobile driving licences and other government-grade digital identity credentials). HAIP profiles two base specifications — OpenID for Verifiable Credential Issuance 1.0 and OpenID for Verifiable Presentations 1.0 — and requires compliance with the applicable provisions of FAPI 2.0 Security Profile Final, the same security profile FAPIgo implements and is OpenID Certified™ against.

This isn't a generic, profile-agnostic OID4VCI/OID4VP implementation with HAIP as an optional layer on top: HAIP's overrides — DPoP mandatory, Wallet Attestation in place of private_key_jwt/mTLS, HAIP's own algorithm requirements — are unconditional in the issuer/wallet/ verifier packages themselves. See ARCHITECTURE.md's "Relationship to FAPIgo" section for the specific list.

OpenID Certified

OpenID Certified™ by Oscar Sanderson for all four HAIP roles, as tested for OID4VCgo 0.12.0: OID4VCI 1.0 + HAIP 1.0 Issuer and Wallet, and OID4VP 1.0 + HAIP 1.0 Verifier and Wallet, each for both SD-JWT VC and mdoc credentials. This is a result submitted to and published by the OpenID Foundation, not merely a self-run pass against the live suite. It is a statement of tested conformance, not an OIDF endorsement of OID4VCgo generally. See conformance/README.md#oidf-certification for every certified profile.

⚠ Pre-1.0, APIs may still change. Every package — issuer, wallet, verifier, walletflow, credential/sdjwtvc, credential/mdoc, statuslist, attestation, dcql, oid4vpmdoc, mdocdcapi, proximity, registration, haip, storage — and the separate mobile module are implemented and tested. All four roles were OpenID Certified as 0.12.0 (see above), and every later release is checked against the same OIDF test plans by the daily conformance workflows. The OpenID4VP wallet harness is also run on each pull request, daily, and on each release, against polaris-oid4vp, an independent verifier, with negative controls the OIDF suite lacks. Those certified profiles are the redirect flows: the Digital Credentials API (OpenID4VP's dc_api.jwt and mdocdcapi's org-iso-mdoc) and in-person presentation (proximity) aren't certified. org-iso-mdoc has run in Safari on an iPhone, with the demo iOS wallet as its document provider, and OpenID4VP over the DC API in Chrome on the Android emulator, with the demo Android wallet as its Credential Manager provider; proximity is tested against ISO/IEC 18013-5 Annex D, not yet between two devices. See ARCHITECTURE.md for the full package-by-package status and what, if anything, remains.

See SPECIFICATIONS.md for the exact specification and Internet-Draft versions this project targets — every one of them was verified against the spec's own published/status text and, for drafts, the exact draft-…-NN a Final OIDF spec pins, rather than assumed.

go get github.com/idfoundry/oid4vcgo

(Go module paths are lowercased; the GitHub repository itself is IDFoundry/OID4VCgo.)

Usage

Each role package's own doc comment (go doc github.com/idfoundry/oid4vcgo/issuer, .../wallet, .../verifier, or pkg.go.dev) is the primary API reference — it documents what's implemented, what's deliberately out of scope, and the boundary with fapigo/server/fapigo/client for everything OAuth 2.0/FAPI 2.0-level. Runnable Example functions (e.g. wallet.ExampleWallet_FetchAuthorizationRequest) cover specific gaps between packages — like fetching a Verifier's request_uri before handing it to wallet.ParseAuthorizationRequest — that aren't obvious from either package's own doc comment alone; go test runs and checks these automatically, so they can't silently drift from the real API.

Where to start, by role:

  • Verifier — verifier.Transactions runs a presentation session end to end (request object, direct_post.jwt response, same-device response_code bound to the browser), with its RequestObjectHandler and ResponseHandler as ready http.Handlers over a verifier.TransactionStore (storage.NewVerifierTransactionStore for development). VerifiedCredential.StatusListRef plus statuslist.Checker check revocation.
  • Wallet — wallet.EncryptionFromMetadata picks credential request/response encryption from the Issuer's metadata; wallet.Respond answers a verified Authorization Request in one call (after showing the holder wallet.PreviewPresentation).
  • Issuer — haip.RecommendedAuthorizationServerConfig and haip.RecommendedWalletClient set up FAPIgo's Authorization Server for HAIP; issuer.CredentialHandler serves the Credential Endpoint (with issuer/fapiresource checking access tokens), asking you only what to issue — or to defer (CredentialRequest.Defer, resolved later with IssueDeferredCredential) — and DeferredCredentialHandler/NotificationEndpointHandler serve the other two protected endpoints; issuer.NewError builds an OID4VCI error response (e.g. credential_request_denied); statuslist.Publisher serves a signed Status List Token.
  • A browser's Digital Credentials API — the Verifier builds an OpenID4VP request with Verifier.BuildDCAPIAuthorizationRequest and checks the answer with Verifier.VerifyResponse, setting VerifyResponseRequest.Origin to its page's origin and ExpectedOrigins to the request's. A wallet parses the request with wallet.ParseDCAPIRequestData (unsigned, signed or multi-signed). Safari's org-iso-mdoc protocol is package mdocdcapi, both sides: BuildRequest and VerifyResponse for the page, ParseRequest and Incoming.Respond for the wallet.
  • In person — package proximity is ISO/IEC 18013-5 over BLE: NewDeviceSession for the holder, NewReaderSession for the reader. The app carries the BLE messages; the package does everything else.
  • A wallet app — package walletflow runs issuance and presentation as sessions over keys and stores the app supplies, and a Wallet Provider for issuers that ask for attestations (HAIP 1.0, an opt-in profile): StartIssuance, StartPresentation, StartDCAPIPresentation (OpenID4VP over the DC API), StartMdocPresentation (org-iso-mdoc) and StartProximityPresentation. The separate mobile module binds it for iOS (the OID4VCWallet Swift package) and Android (a Kotlin library), each with its documentation: Swift and Kotlin (guides). See also mobile/MOBILE.md and mobile/.
  • Your own stores and resolvers — issuer/issuertest and verifier/verifiertest hold contract tests to run against them.

For a complete, real integration, see the four cmd/conformance-* binaries under conformance/: each pairs this library's own role package (issuer, wallet, verifier) with real HTTP and, where applicable, a real fapigo/server/fapigo/client, and each is the binary that produced its role's OIDF certification results (see ARCHITECTURE.md and each binary's own conformance/<role>/README.md for what was verified). They're a better model for a real deployment's wiring than the package tests alone, which exercise each function in isolation rather than a full request/response cycle over the network. For an end-to-end application — a gmrtd passport turned into both credential formats, a browser and a command-line wallet, and a verifier with revocation — see examples/passport-vdc.

Relevant specifications

See SPECIFICATIONS.md for the complete list, including the pinned credential-format, attestation, and status-list Internet-Drafts.

Contributing

See CONTRIBUTING.md for the conformance-first development philosophy and pre-PR checklist, and SECURITY.md to report a vulnerability.

License

MIT — see LICENSE.

OpenID®, OpenID Connect™, and OpenID Certified™ are trademarks or registered trademarks of the OpenID Foundation in the United States and other countries. Use of these marks here is limited to the certified conformance statement above, per Section 3(d) of the OpenID Certification Terms and Conditions.

Documentation

Overview

Package oid4vci holds value types shared across the issuer, wallet, and verifier packages, the way FAPIgo's root fapi package holds identifiers, algorithm enums and other data with a single, stable meaning on the wire regardless of role — see that package's own doc comment and ARCHITECTURE.md's "Shared public value types only where semantics match" rule.

CredentialOffer (and Grants/GrantAuthorizationCode/ GrantPreAuthorizedCode/TxCode), IssuedCredential/CredentialResponse, and ProofTypeJWT/ProofTypeAttestation moved here from issuer once wallet needed the exact same wire semantics for each — see issuer's own git history for why each one was originally issuer-scoped and what changed. Each type's own Validate method (where it has one) checks only §4/§8's own structural requirements; a role package's additional, role-specific constraints (e.g. issuer's own check that credential_configuration_ids are actually known to it) stay in that role package as a free function over these types, not a method here — Go methods can only be defined where a type is declared, and a role-specific rule doesn't belong in a package every role imports.

Don't add a type here speculatively — move one in only once a second role package needs the exact same semantics, not before.

Index

Constants

View Source
const (
	// A128GCM and A256GCM are AES-GCM with 128- and 256-bit keys (RFC
	// 7518 §5.3) — the values HAIP 1.0 §5.1 requires for OpenID4VP
	// response encryption.
	A128GCM JWEEnc = jwe.A128GCM
	A256GCM JWEEnc = jwe.A256GCM

	// ZipDEF is DEFLATE compression before encryption (RFC 7516 §4.1.3).
	ZipDEF JWEZip = jwe.DEF
)

JWE "enc" and "zip" values internal/jwe supports.

View Source
const (
	// ProofTypeJWT is the "jwt" proof type (Appendix F.1): a JWT proves
	// possession of the key the issued Credential is bound to.
	ProofTypeJWT = "jwt"

	// ProofTypeAttestation is the "attestation" proof type (Appendix
	// F.3): a Key Attestation JWT conveys attested keys without itself
	// proving possession of any one of them.
	ProofTypeAttestation = "attestation"
)

Proof type identifiers (Appendix F). Only the two OID4VCgo's credential formats actually use are defined here — di_vp (W3C VCDM) is out of scope; see SPECIFICATIONS.md.

View Source
const (
	// ES256 is ECDSA using P-256 and SHA-256 (RFC 7518 §3.4) — HAIP
	// 1.0's own minimum signing algorithm requirement.
	ES256 = "ES256"

	// EdDSA is pure EdDSA over Ed25519 (RFC 8037 §3.1).
	EdDSA = "EdDSA"
)

JOSE signature algorithm identifiers accepted by every jose.Alg-typed configuration field across this module — verifier.Config.SigningAlg, wallet.Config.ProofSigningAlg, issuer's SDJWTSigner/MdocSigner Alg fields, and haip's WalletConfig/VerifierConfig equivalents. jose.Alg itself is defined in internal/jose, which (like every internal package) an external caller of this module cannot import — so without a named constant here, an external config literal has to spell the algorithm as a bare, unchecked string ("ES256") with no compile-time typo protection. These are untyped string constants, each directly assignable to any JOSEAlg-typed field or parameter without an explicit conversion. Only the two algorithms internal/jose actually supports are defined here; see that package's own doc comment before adding a third.

View Source
const AuthorizationDetailsTypeOpenIDCredential = "openid_credential" //nolint:gosec // an RFC 9396 authorization details type value, not a credential

AuthorizationDetailsTypeOpenIDCredential is RFC 9396 §5.1.1's own authorization details type this specification defines for requesting Credential issuance.

Variables

View Source
var IssuerStateExtension = extension.Definition[string]{
	Name:           "issuer_state",
	Cardinality:    extension.Single,
	AllowedSources: extension.SourcePlainParameter | extension.SourceRequestObject,
	MaxBytes:       2048,
	Sensitivity:    extension.Sensitive,
}

IssuerStateExtension declares the issuer_state authorization parameter (OID4VCI 1.0 §4.1.1) to fapigo's own extension.Definition mechanism — a plain opaque string neither role here interprets, only passes through, so there is no Validate beyond the wire-shape/size checks extension.Set/a Registry already apply. 2048 bytes is generous headroom for a value the spec places no length limit on.

This lives here, not in wallet or issuer, because both sides of the Authorization Code Flow need the exact same extension.Definition[string] value: wallet's own BuildAuthorizationRequest attaches it to an outbound client.BeginAuthorizationRequest via extension.Set, and a deployment pairing issuer with a real fapigo/server.Server registers it in that Server's own Config.Extensions so a Pushed Authorization Request carrying issuer_state isn't rejected as an unregistered parameter. Two independently-declared copies of this Definition would risk drifting apart (a different Cardinality or MaxBytes on each side is a real interop bug, not a cosmetic one) — the same "shared public value types only where semantics match" reasoning that moved CredentialOffer and friends here.

It's Sensitive: an issuer can use issuer_state as the handle on a pending issuance (the passport-vdc example's unguessable transaction ID), and it decides whose Credential is issued, so it's kept out of log lines and error messages.

View Source
var ResourceExtension = extension.Definition[string]{
	Name:           "resource",
	Cardinality:    extension.Single,
	AllowedSources: extension.SourcePlainParameter | extension.SourceRequestObject,
	MaxBytes:       2048,
}

ResourceExtension declares the resource authorization parameter (RFC 8707 §2): the Credential Issuer's identifier, which OpenID4VCI §5.1.2 has a Wallet send so an Authorization Server serving more than one Credential Issuer can tell them apart, and restrict the token to the one it's for.

Deprecated: set fapigo/client's BeginAuthorizationRequest.Resource instead, as wallet.BuildAuthorizationRequest does: an extension reaches only the pushed request, not the code exchange or a refresh, which RFC 8707 §2.2 has name it again, and fapigo/client refuses a request that sets both.

Functions

This section is empty.

Types

type AuthorizationDetail

type AuthorizationDetail struct {
	// Type is REQUIRED (§5.1.1). This specification's own use of
	// authorization_details always sets it to
	// AuthorizationDetailsTypeOpenIDCredential; an entry with any other
	// Type is a coexisting authorization details type neither role here
	// interprets (§5.1.1's own "Additional authorization_details data
	// fields MAY be defined and used... never considered invalid due to
	// unknown fields") and should simply be skipped.
	Type string `json:"type"`

	// CredentialConfigurationID is REQUIRED (§5.1.1): which Credential
	// Configuration this authorization detail authorizes.
	CredentialConfigurationID string `json:"credential_configuration_id"`

	// CredentialIdentifiers is REQUIRED once an authorization detail is
	// echoed back in a Token Response (§6.2): every credential_identifier
	// value a Credential Request may later present against it. Absent
	// on the Authorization/Token Request's own outbound copy of this
	// same type — a Wallet never sets this itself, only an Authorization
	// Server does, once it decides to support this optional mechanism
	// at all (§6.2's own "MAY do so").
	CredentialIdentifiers []string `json:"credential_identifiers,omitempty"`
}

AuthorizationDetail is one entry of an "authorization_details" array (RFC 9396 §2), for the "openid_credential" type this specification defines: §5.1.1's own Authorization/Token Request parameters, echoed back with CredentialIdentifiers added per §6.2's own Token Response parameter. This is the same wire shape both issuer (resolving credential_identifier-based Credential Requests against it, and minting fresh entries for ExchangePreAuthorizedCode's own Token Response) and wallet (parsing entries out of a Token Response, and presenting one of a matched entry's own CredentialIdentifiers values in a later Credential Request) need identically — the same "shared value types only where semantics match" split CredentialOffer and friends already live here for.

type BackgroundImage

type BackgroundImage struct {
	// URI is REQUIRED: where the Wallet can obtain the background
	// image.
	URI string `json:"uri"`
}

BackgroundImage is CredentialDisplay's own "background_image" object (Appendix A).

type BatchCredentialIssuance

type BatchCredentialIssuance struct {
	// BatchSize is REQUIRED: the maximum array size for a Credential
	// Request's own "proofs" parameter an issuer advertising this
	// supports. Must be 2 or greater.
	BatchSize int `json:"batch_size"`
}

BatchCredentialIssuance is Metadata's own optional "batch_credential_issuance" (§12.2.4): an issuer's own advertised support for more than one key proof per Credential Request.

func (BatchCredentialIssuance) Validate

func (b BatchCredentialIssuance) Validate() error

Validate checks b's own structural requirements (§12.2.4).

type COSEAlg added in v0.21.0

type COSEAlg = cose.Alg

JOSEAlg and COSEAlg name internal/jose's and internal/cose's signature algorithm types, which an external caller of this module can't import. Public interfaces return them — verifier.SDJWTVCIssuerKeyResolver, verifier.MdocIssuerKeyResolver, issuer.AttestationVerifier, issuer.ProofBindingKeyResolver — so an implementation outside this module declares its method with these names:

func (r MyResolver) ResolveIssuerKey(ctx context.Context, header, payload map[string]any) (crypto.PublicKey, oid4vci.JOSEAlg, error)
const (
	// COSEES256 is ECDSA using P-256 and SHA-256 (COSE algorithm -7).
	COSEES256 COSEAlg = cose.ES256

	// COSEEdDSA is EdDSA (COSE algorithm -8).
	COSEEdDSA COSEAlg = cose.EdDSA
)

COSE signature algorithm identifiers (RFC 9053) accepted by every cose.Alg-typed parameter and field — mdoc.Issue, mdoc.Verify, statuslist.IssueTokenCWTX5Chain, issuer.MdocSigner.Alg — the COSE counterparts of ES256 and EdDSA below.

type ClaimDisplay

type ClaimDisplay struct {
	// Name and Locale are both OPTIONAL.
	Name   string `json:"name,omitempty"`
	Locale string `json:"locale,omitempty"`
}

ClaimDisplay is one entry in a ClaimsDescription's own "display" array (Appendix B.2).

type ClaimsDescription

type ClaimsDescription struct {
	// Path is REQUIRED: each element a string, nil (wire null, "select
	// every array element"), or non-negative int.
	Path []any `json:"path"`

	// Mandatory is OPTIONAL, default false — use IsMandatory to read
	// the effective value.
	Mandatory *bool `json:"mandatory,omitempty"`

	// Display is OPTIONAL.
	Display []ClaimDisplay `json:"display,omitempty"`
}

ClaimsDescription is one entry in CredentialMetadata's own "claims" array (Appendix B.2): how one claim in the issued Credential is displayed to the End-User. Path is a Claims Path Pointer (Appendix C) — the exact same wire shape OID4VP's own dcql.Path implements (§7.1 there: a non-empty array of strings, nulls, and non-negative integers), kept here as a plain []any rather than importing that OID4VP-specific package: describing display metadata never needs dcql.Path's own Select/evaluation behavior, only its wire shape, and this OID4VCI-side type has no reason to depend on an OID4VP one for that.

func (ClaimsDescription) IsMandatory

func (c ClaimsDescription) IsMandatory() bool

IsMandatory reports c's own effective value — false unless Mandatory was explicitly set to true (Appendix B.2's own default).

func (ClaimsDescription) Validate

func (c ClaimsDescription) Validate() error

Validate checks c's own structural requirements (Appendix B.2).

type CredentialConfigurationMetadata

type CredentialConfigurationMetadata struct {
	// Format is REQUIRED — a Credential Format Identifier such as
	// credential/sdjwtvc.CredentialFormat ("dc+sd-jwt").
	Format string `json:"format"`

	// Scope is OPTIONAL: the Authorization Request scope value that
	// selects this Credential.
	Scope string `json:"scope,omitempty"`

	// CryptographicBindingMethodsSupported is REQUIRED when
	// Cryptographic Key Binding applies to this Credential; omitted
	// otherwise.
	CryptographicBindingMethodsSupported []string `json:"cryptographic_binding_methods_supported,omitempty"`

	// CredentialSigningAlgValuesSupported is OPTIONAL: either a
	// []string of JOSE alg values or a []int/[]float64 of COSE alg
	// numbers (Appendix A.2.2), depending on Format — decode into the
	// shape Format implies, or inspect it with a type switch.
	CredentialSigningAlgValuesSupported any `json:"credential_signing_alg_values_supported,omitempty"`

	// ProofTypesSupported is REQUIRED exactly when
	// CryptographicBindingMethodsSupported is present, keyed by proof
	// type identifier (ProofTypeJWT, ProofTypeAttestation).
	ProofTypesSupported map[string]ProofTypeConfiguration `json:"proof_types_supported,omitempty"`

	// VCT is credential/sdjwtvc's own format-specific metadata
	// parameter (Appendix A.3.2): present when Format is
	// credential/sdjwtvc.CredentialFormat, meaningless otherwise.
	VCT string `json:"vct,omitempty"`

	// DocType is credential/mdoc's own format-specific metadata
	// parameter (Appendix A.2.2): present when Format is
	// credential/mdoc.CredentialFormat, meaningless otherwise.
	DocType string `json:"doctype,omitempty"`

	// CredentialMetadata is OPTIONAL (Appendix A).
	CredentialMetadata *CredentialMetadata `json:"credential_metadata,omitempty"`
}

CredentialConfigurationMetadata is one entry in Metadata's own "credential_configurations_supported" (§12.2.4) — the wire shape of one Credential an issuer publishes support for. Distinct from issuer.CredentialConfiguration (that package's own Go-ergonomic *input* shape, which a Credential Issuer builds one of these from): CredentialSigningAlgValuesSupported is untyped here because the wire carries either JOSE alg strings or COSE alg numbers depending on Format, where issuer.CredentialConfiguration instead exposes two separate typed fields for the same reason RequestCredential wants (build-time type safety) that a wire decoder doesn't.

type CredentialDisplay

type CredentialDisplay struct {
	// Name is REQUIRED: a display name for the Credential.
	Name string `json:"name"`

	Locale          string           `json:"locale,omitempty"`
	Description     string           `json:"description,omitempty"`
	BackgroundColor string           `json:"background_color,omitempty"`
	BackgroundImage *BackgroundImage `json:"background_image,omitempty"`
	TextColor       string           `json:"text_color,omitempty"`
}

CredentialDisplay is one entry in CredentialMetadata's own "display" array (Appendix A) — a Credential Configuration's own display properties for one language. Distinct from Display (the Credential *Issuer*-level display type): Name is REQUIRED here, unlike there.

func (CredentialDisplay) Validate

func (cd CredentialDisplay) Validate() error

Validate checks cd's own structural requirements (Appendix A).

type CredentialMetadata

type CredentialMetadata struct {
	// Display and Claims are both OPTIONAL; non-empty if present.
	Display []CredentialDisplay `json:"display,omitempty"`
	Claims  []ClaimsDescription `json:"claims,omitempty"`
}

CredentialMetadata is a CredentialConfigurationMetadata's own optional "credential_metadata" object (Appendix A): display/claims metadata for the issued Credential. Format-specific mechanisms (e.g. SD-JWT VC's own type metadata) are always preferred by the Wallet over this, which serves only as a fallback default (Appendix A's own text) — this type makes no attempt to keep the two in sync.

func (CredentialMetadata) Validate

func (cm CredentialMetadata) Validate() error

Validate checks cm's own structural requirements (Appendix A/B.2).

type CredentialOffer

type CredentialOffer struct {
	// CredentialIssuer is REQUIRED: the Credential Issuer's identifier.
	CredentialIssuer string `json:"credential_issuer"`

	// CredentialConfigurationIDs is REQUIRED: a non-empty list of
	// unique keys into the Credential Issuer's own
	// credential_configurations_supported metadata.
	CredentialConfigurationIDs []string `json:"credential_configuration_ids"`

	// Grants is OPTIONAL — see Grants' own doc comment.
	Grants *Grants `json:"grants,omitempty"`
}

CredentialOffer is the Credential Offer object (§4.1.1) — what a Wallet receives either by value (the credential_offer URI query parameter) or by reference (fetched from a credential_offer_uri).

A Wallet MUST treat a Credential Offer's contents as untrustworthy: its origin is not authenticated and its integrity is not protected (§13.5). Validate does not, and cannot, change that — it only checks structural well-formedness.

func (CredentialOffer) AppendToURL added in v0.10.0

func (o CredentialOffer) AppendToURL(base string) (string, error)

AppendToURL appends o, JSON-encoded, as a by-value "credential_offer" query parameter (§4.1.2) to base — the transport-agnostic half of a Credential Offer deep link. issuer.Issuer.CreateCredentialOffer already builds one flavor of this (the "openid-credential-offer://" custom scheme a real Wallet registers to handle), but a caller without a live *Issuer to hand — delivering an offer to a fixed test endpoint, or one round-tripped through storage rather than freshly built — needs the same transform against a base of its own choosing, which may already carry a query string. base is used as-is, otherwise; this does no scheme/URL validation of its own.

func (CredentialOffer) Validate

func (o CredentialOffer) Validate() error

Validate checks o against §4.1.1's own structural requirements: credential_issuer and credential_configuration_ids are non-empty, every ID in credential_configuration_ids is unique, and Grants, if present, itself validates. It does not check credential_configuration_ids against any actual Issuer Metadata — that's the caller's own job.

type CredentialResponse

type CredentialResponse struct {
	Credentials []IssuedCredential `json:"credentials,omitempty"`

	// TransactionID identifies a deferred issuance, in place of
	// Credentials; Interval is the minimum number of seconds the
	// Wallet waits before polling for it (REQUIRED with TransactionID).
	TransactionID string `json:"transaction_id,omitempty"`
	Interval      int64  `json:"interval,omitempty"`

	// NotificationID is OPTIONAL: identifies this issuance flow for a
	// later Notification Request (§11.1). Absent unless the Credential
	// Issuer actually supports the Notification Endpoint.
	NotificationID string `json:"notification_id,omitempty"`
}

CredentialResponse is a Credential Response (§8.3): either the issued Credentials, or — when the Credential Issuer defers issuance — a TransactionID and Interval for the Wallet to poll the Deferred Credential Endpoint with (§9), sent as HTTP 202.

type Display

type Display struct {
	// Name is OPTIONAL: a display name for the Credential Issuer.
	Name string `json:"name,omitempty"`

	// Locale is OPTIONAL: a BCP47 language tag.
	Locale string `json:"locale,omitempty"`

	Logo *Logo `json:"logo,omitempty"`
}

Display is one entry in Metadata's own top-level "display" (§12.2.4) — a Credential Issuer's own display properties for one language. At most one Display per distinct Locale (including "") is meaningful; this type doesn't reject a duplicate itself (§12.2.4 doesn't make it a MUST either) — describing, not policing, every SHOULD.

func (Display) Validate

func (d Display) Validate() error

Validate checks d's own structural requirements (§12.2.4).

type GrantAuthorizationCode

type GrantAuthorizationCode struct {
	// IssuerState is OPTIONAL: an opaque value the Wallet echoes back
	// as the issuer_state Authorization Request parameter if it uses
	// this grant.
	IssuerState string `json:"issuer_state,omitempty"`

	// AuthorizationServer is OPTIONAL, and only meaningful when the
	// Credential Issuer's own Metadata advertises more than one entry
	// in authorization_servers, in which case it must be one of them
	// (§4.1.1). That depends on the issuer's metadata, not on anything
	// this type can check on its own — issuer.CreateCredentialOffer
	// enforces it against issuer.Config.AuthorizationServers.
	AuthorizationServer string `json:"authorization_server,omitempty"`
}

GrantAuthorizationCode is the "authorization_code" grant a Credential Offer's own Grants may declare (§4.1.1).

type GrantPreAuthorizedCode

type GrantPreAuthorizedCode struct {
	// PreAuthorizedCode is REQUIRED: a short-lived, single-use code the
	// Wallet presents at the Token Endpoint's Pre-Authorized Code Flow.
	PreAuthorizedCode string `json:"pre-authorized_code"`

	// TxCode is OPTIONAL: present (possibly empty) when the Authorization
	// Server expects a Transaction Code alongside the Token Request.
	TxCode *TxCode `json:"tx_code,omitempty"`

	// AuthorizationServer is OPTIONAL — see
	// GrantAuthorizationCode.AuthorizationServer's own doc comment; the
	// same caveat applies here.
	AuthorizationServer string `json:"authorization_server,omitempty"`
}

GrantPreAuthorizedCode is the "urn:ietf:params:oauth:grant-type:pre-authorized_code" grant a Credential Offer's own Grants may declare (§4.1.1).

func (GrantPreAuthorizedCode) Validate

func (g GrantPreAuthorizedCode) Validate() error

Validate checks g against §4.1.1's own structural requirements: pre-authorized_code is REQUIRED, and TxCode, if present, must itself validate. It does not check AuthorizationServer — see its own doc comment for why that's a runtime policy question, not a structural one.

type Grants

type Grants struct {
	AuthorizationCode *GrantAuthorizationCode `json:"authorization_code,omitempty"`

	// PreAuthorizedCode's JSON key is OID4VCI's own Grant Type
	// identifier URN, not a conventional short name.
	PreAuthorizedCode *GrantPreAuthorizedCode `json:"urn:ietf:params:oauth:grant-type:pre-authorized_code,omitempty"`
}

Grants indicates which Grant Types the Wallet may use for a Credential Offer (§4.1.1) — nil on CredentialOffer means the Wallet must instead determine available grants from the Credential Issuer's Metadata. Only the two Grant Types this specification defines are supported; one with neither, empty or holding only grant types this package doesn't know, is treated as absent (§4.1.1: "If grants is not present or is empty, the Wallet MUST determine the Grant Types ... using the respective metadata").

func (Grants) Validate

func (g Grants) Validate() error

Validate checks g against §4.1.1's own structural requirements: PreAuthorizedCode, if present, must itself validate. Empty grants are valid: a Wallet then determines the grant from the metadata.

type IssuedCredential

type IssuedCredential struct {
	// Credential is the issued Credential, encoded per its format's own
	// Credential Format Profile (Appendix A): the compact SD-JWT VC
	// string for credential/sdjwtvc's own CredentialFormat, or the
	// base64url-encoded CBOR IssuerSigned structure for
	// credential/mdoc's own CredentialFormat.
	Credential string `json:"credential"`
}

IssuedCredential is one element of a Credential Response's "credentials" array (§8.3).

type JOSEAlg added in v0.21.0

type JOSEAlg = jose.Alg

JOSEAlg and COSEAlg name internal/jose's and internal/cose's signature algorithm types, which an external caller of this module can't import. Public interfaces return them — verifier.SDJWTVCIssuerKeyResolver, verifier.MdocIssuerKeyResolver, issuer.AttestationVerifier, issuer.ProofBindingKeyResolver — so an implementation outside this module declares its method with these names:

func (r MyResolver) ResolveIssuerKey(ctx context.Context, header, payload map[string]any) (crypto.PublicKey, oid4vci.JOSEAlg, error)

type JWEAlg added in v0.31.0

type JWEAlg = jwe.Alg

JWEAlg, JWEEnc and JWEZip name internal/jwe's key-management, content-encryption and compression types, which an external caller of this module can't import — like signing_algorithms.go's constants, so a configuration that takes a list of them (issuer.RequestEncryptionSupport, issuer.ResponseEncryptionSupport, verifier.Config.EncValuesSupported) can be written outside this module: []oid4vci.JWEEnc{oid4vci.A256GCM}.

const ECDHES JWEAlg = jwe.ECDHES

ECDHES is ECDH-ES Direct Key Agreement (RFC 7518 §4.6), the one JWE "alg" internal/jwe supports.

type JWEEnc added in v0.18.0

type JWEEnc = jwe.Enc

JWEAlg, JWEEnc and JWEZip name internal/jwe's key-management, content-encryption and compression types, which an external caller of this module can't import — like signing_algorithms.go's constants, so a configuration that takes a list of them (issuer.RequestEncryptionSupport, issuer.ResponseEncryptionSupport, verifier.Config.EncValuesSupported) can be written outside this module: []oid4vci.JWEEnc{oid4vci.A256GCM}.

type JWEZip added in v0.18.0

type JWEZip = jwe.Zip

JWEAlg, JWEEnc and JWEZip name internal/jwe's key-management, content-encryption and compression types, which an external caller of this module can't import — like signing_algorithms.go's constants, so a configuration that takes a list of them (issuer.RequestEncryptionSupport, issuer.ResponseEncryptionSupport, verifier.Config.EncValuesSupported) can be written outside this module: []oid4vci.JWEEnc{oid4vci.A256GCM}.

type JWK

type JWK struct {
	jwk.JWK
	Kid string `json:"kid"`
	Alg JWEAlg `json:"alg"`

	// Use is the key's intended use (RFC 7517 §4.2): "enc" for an
	// encryption key, "sig" for a signing one. OPTIONAL.
	Use string `json:"use,omitempty"`

	// KeyOps is the operations the key is for (RFC 7517 §4.3), e.g.
	// "deriveKey" for an ECDH-ES encryption key. OPTIONAL.
	KeyOps []string `json:"key_ops,omitempty"`
}

JWK is a JSON Web Key (RFC 7517) plus the "kid"/"alg" every entry in an encryption jwks needs — internal/jwk.JWK itself has neither field, since both are contextual to where a key is published, not part of the key material Marshal encodes. §10's own "The alg parameter MUST be present. The JWE alg algorithm used MUST be equal to the alg value of the chosen JWK" makes Alg REQUIRED here, not optional metadata — confirmed live: the OIDF suite's own VCICheckCredentialRequestEncryptionSupported check rejects a published key with no "alg" member outright ("expected at least one key with... an asymmetric JWE alg").

The embedded internal/jwk.JWK's own PublicKey() method promotes onto this type (json.Unmarshal into a JWK, then call .PublicKey()) — a caller outside this module that only needs to decode a fetched JWK back into a crypto.PublicKey (e.g. to build its own verifier.SDJWTVCIssuerKeyResolver against a pinned Issuer key) can use this exported type for that, without needing internal/jwk itself. Alg here is specifically the JWE encryption algorithm (§10's own contract above); a signing-algorithm use case needs its own alg field alongside this type, the same way this repo's own cmd/conformance-verifier does.

type JWKSet

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

JWKSet is a JSON Web Key Set (RFC 7517 §5) — §12.2.4's own "jwks" member is REQUIRED to be one (a {"keys": [...]} object, not a bare JSON array of keys).

type KeyAttestationRequirement

type KeyAttestationRequirement struct {
	// KeyStorage/UserAuthentication constrain which
	// attestation.AttackPotentialResistance values (Appendix D.2) an
	// issuer accepts, mirroring the Key Attestation claims of the same
	// name. Both OPTIONAL; non-empty if present.
	KeyStorage         []string `json:"key_storage,omitempty"`
	UserAuthentication []string `json:"user_authentication,omitempty"`
}

KeyAttestationRequirement is a proof type's key_attestations_required object (§12.2.4): "the Credential Issuer expects the Wallet to send" a Key Attestation meeting these constraints. A present-but-empty value (both fields nil) means a key attestation is required with no further constraint — a Credential Issuer sets ProofTypeConfiguration's own KeyAttestationsRequired to a non-nil *KeyAttestationRequirement to require one at all, nil to not require one.

type Logo struct {
	// URI is REQUIRED: where the Wallet can obtain the logo — any
	// scheme ("https:", "data:", ...); this package never fetches it.
	URI string `json:"uri"`

	// AltText is OPTIONAL: alternative text for the logo image.
	AltText string `json:"alt_text,omitempty"`
}

Logo is a "logo" object (§12.2.4/Appendix A) — the shared shape both Display's own Logo and CredentialDisplay's own Logo use.

func (Logo) Validate

func (l Logo) Validate() error

Validate checks l's own structural requirements (§12.2.4/Appendix A).

type Metadata

type Metadata struct {
	CredentialIssuer fapi.URL `json:"credential_issuer"`
	// AuthorizationServers are the OAuth 2.0 Authorization Servers
	// (their issuer identifiers) this Credential Issuer relies on
	// (§12.2.4). OPTIONAL: when absent, the Credential Issuer is its
	// own Authorization Server. With more than one, a Credential Offer
	// grant's authorization_server says which one to use.
	AuthorizationServers              []fapi.URL                                 `json:"authorization_servers,omitempty"`
	CredentialEndpoint                fapi.URL                                   `json:"credential_endpoint"`
	NonceEndpoint                     *fapi.URL                                  `json:"nonce_endpoint,omitempty"`
	DeferredCredentialEndpoint        *fapi.URL                                  `json:"deferred_credential_endpoint,omitempty"`
	NotificationEndpoint              *fapi.URL                                  `json:"notification_endpoint,omitempty"`
	CredentialConfigurationsSupported map[string]CredentialConfigurationMetadata `json:"credential_configurations_supported"`
	CredentialRequestEncryption       *RequestEncryptionMetadata                 `json:"credential_request_encryption,omitempty"`
	CredentialResponseEncryption      *ResponseEncryptionMetadata                `json:"credential_response_encryption,omitempty"`
	BatchCredentialIssuance           *BatchCredentialIssuance                   `json:"batch_credential_issuance,omitempty"`
	Display                           []Display                                  `json:"display,omitempty"`
}

Metadata is a Credential Issuer's own Credential Issuer Metadata document (§12.2.4) — issuer.Issuer.Metadata() builds one to serve at GET /.well-known/openid-credential-issuer, and wallet.FetchCredentialIssuerMetadata decodes one fetched from there.

func DecodeMetadata added in v0.15.0

func DecodeMetadata(data []byte, opts ...fapi.URLOption) (Metadata, error)

DecodeMetadata decodes a Credential Issuer Metadata document, parsing its URL members with opts — for example fapi.AllowLoopbackHTTP() to accept a local development issuer at http://127.0.0.1. With no opts it is exactly Metadata's UnmarshalJSON.

func (*Metadata) UnmarshalJSON

func (m *Metadata) UnmarshalJSON(data []byte) error

UnmarshalJSON decodes m per §12.2.4 — see wireMetadata's own doc comment for why this is a custom implementation, not the default struct decode. It is DecodeMetadata with no URL options: every URL must be https.

type NotificationEvent

type NotificationEvent string

NotificationEvent is a Notification Request's own "event" parameter (§11.1) — the closed set of outcomes a Wallet reports for a previously issued Credential (or batch thereof).

const (
	// NotificationEventCredentialAccepted means the Credential(s) were
	// successfully stored in the Wallet, with or without user action.
	NotificationEventCredentialAccepted NotificationEvent = "credential_accepted" //nolint:gosec // an OID4VCI event name, not a credential

	// NotificationEventCredentialDeleted means the unsuccessful
	// Credential issuance was caused by a user action.
	NotificationEventCredentialDeleted NotificationEvent = "credential_deleted" //nolint:gosec // an OID4VCI event name, not a credential

	// NotificationEventCredentialFailure covers every other
	// unsuccessful case.
	NotificationEventCredentialFailure NotificationEvent = "credential_failure" //nolint:gosec // an OID4VCI event name, not a credential
)

type ProofTypeConfiguration

type ProofTypeConfiguration struct {
	// ProofSigningAlgValuesSupported is REQUIRED: the algorithms an
	// issuer accepts a proof of this type to be signed with.
	ProofSigningAlgValuesSupported []string `json:"proof_signing_alg_values_supported"`

	// KeyAttestationsRequired, if non-nil, requires every proof of this
	// type to carry a Key Attestation — see the type's own doc comment.
	KeyAttestationsRequired *KeyAttestationRequirement `json:"key_attestations_required,omitempty"`
}

ProofTypeConfiguration is one entry in a CredentialConfigurationMetadata's own ProofTypesSupported (§12.2.4).

func (ProofTypeConfiguration) Validate

func (p ProofTypeConfiguration) Validate() error

Validate checks p's own structural requirements (§12.2.4) — not whether an issuer actually accepts a proof meeting them, that's the caller's own role-specific decision.

type RequestEncryptionMetadata

type RequestEncryptionMetadata struct {
	JWKS               JWKSet   `json:"jwks"`
	EncValuesSupported []JWEEnc `json:"enc_values_supported"`
	ZipValuesSupported []JWEZip `json:"zip_values_supported,omitempty"`
	EncryptionRequired bool     `json:"encryption_required"`
}

RequestEncryptionMetadata is Metadata's own "credential_request_encryption" (§12.2.4) — the wire shape of an issuer's own advertised support for §10 Credential Request encryption. Distinct from issuer.RequestEncryptionSupport (that package's own input shape, which holds private decryption keys, not the public JWKS this publishes).

type ResponseEncryptionMetadata

type ResponseEncryptionMetadata struct {
	AlgValuesSupported []JWEAlg `json:"alg_values_supported"`
	EncValuesSupported []JWEEnc `json:"enc_values_supported"`
	ZipValuesSupported []JWEZip `json:"zip_values_supported,omitempty"`
	EncryptionRequired bool     `json:"encryption_required"`
}

ResponseEncryptionMetadata is Metadata's own "credential_response_encryption" (§12.2.4) — the wire shape of an issuer's own advertised support for §10 Credential Response encryption. AlgValuesSupported is always exactly ["ECDH-ES"] for every issuer this repo builds (see issuer.ResponseEncryptionSupport's own doc comment for why).

type TxCode

type TxCode struct {
	// InputMode is OPTIONAL; "" means TxCodeInputModeNumeric.
	InputMode TxCodeInputMode `json:"input_mode,omitempty"`

	// Length is OPTIONAL: the expected Transaction Code length, purely
	// to help the Wallet render an input screen. 0 means unspecified.
	Length int `json:"length,omitempty"`

	// Description is OPTIONAL guidance for the End-User on how to
	// obtain the Transaction Code. Must not exceed 300 characters.
	Description string `json:"description,omitempty"`
}

TxCode describes the Transaction Code the Authorization Server expects alongside a pre-authorized_code Token Request (§4.1.1's tx_code) — present (even as an empty object) only when a Transaction Code is actually required.

func (TxCode) Validate

func (t TxCode) Validate() error

Validate checks t against §4.1.1's own structural requirements.

type TxCodeInputMode

type TxCodeInputMode string

TxCodeInputMode is a Transaction Code's expected character set (§4.1.1's tx_code.input_mode).

const (
	// TxCodeInputModeNumeric restricts a Transaction Code to digits —
	// the default when input_mode is absent.
	TxCodeInputModeNumeric TxCodeInputMode = "numeric"

	// TxCodeInputModeText allows any characters in a Transaction Code.
	TxCodeInputModeText TxCodeInputMode = "text"
)

Directories

Path Synopsis
Package attestation implements OID4VCI 1.0's two attestation mechanisms:
Package attestation implements OID4VCI 1.0's two attestation mechanisms:
cmd
conformance-issuer command
Command conformance-issuer pairs a real fapigo/server.Server (FAPI 2.0 Security Profile Final, Wallet Attestation client authentication, DPoP) with a real oid4vcgo/issuer.Issuer behind real HTTP, for the OIDF conformance suite's own "oid4vci-1_0-issuer-haip-test-plan" ("OpenID for Verifiable Credential Issuance 1.0 Final/HAIP: Test an issuer").
Command conformance-issuer pairs a real fapigo/server.Server (FAPI 2.0 Security Profile Final, Wallet Attestation client authentication, DPoP) with a real oid4vcgo/issuer.Issuer behind real HTTP, for the OIDF conformance suite's own "oid4vci-1_0-issuer-haip-test-plan" ("OpenID for Verifiable Credential Issuance 1.0 Final/HAIP: Test an issuer").
conformance-verifier command
Command conformance-verifier stands up verifier.Verifier behind real HTTP for the OIDF conformance suite's own "oid4vp-1final-verifier-haip-test-plan" ("OpenID for Verifiable Presentations 1.0 Final/HAIP: Test a verifier") — the suite plays Wallet, driving this binary's real Authorization Request construction, request_uri hosting, and direct_post.jwt response verification.
Command conformance-verifier stands up verifier.Verifier behind real HTTP for the OIDF conformance suite's own "oid4vp-1final-verifier-haip-test-plan" ("OpenID for Verifiable Presentations 1.0 Final/HAIP: Test a verifier") — the suite plays Wallet, driving this binary's real Authorization Request construction, request_uri hosting, and direct_post.jwt response verification.
conformance-wallet command
Command conformance-wallet drives oid4vcgo/wallet and fapigo/client headlessly through the OIDF conformance suite's own "oid4vci-1_0-wallet-haip-test-plan" ("OpenID for Verifiable Credential Issuance 1.0 Final/HAIP: Test a wallet") — specifically the wallet_initiated flow variant's 4 non-battery modules (VCIWalletTestCredentialIssuance, VCIWalletTestCredentialIssuanceWithNotification, VCIWalletTestBatchCredentialIssuance, VCIWalletTestClientAttestationChallenge), crossed with all 3 of the plan's own issuance-mode/encryption variants (immediate+plain, deferred+plain, immediate+encrypted), plus the plan's 4th module-list entry — the generic FAPI2SP client conformance battery, always at the fixed immediate+plain crossing.
Command conformance-wallet drives oid4vcgo/wallet and fapigo/client headlessly through the OIDF conformance suite's own "oid4vci-1_0-wallet-haip-test-plan" ("OpenID for Verifiable Credential Issuance 1.0 Final/HAIP: Test a wallet") — specifically the wallet_initiated flow variant's 4 non-battery modules (VCIWalletTestCredentialIssuance, VCIWalletTestCredentialIssuanceWithNotification, VCIWalletTestBatchCredentialIssuance, VCIWalletTestClientAttestationChallenge), crossed with all 3 of the plan's own issuance-mode/encryption variants (immediate+plain, deferred+plain, immediate+encrypted), plus the plan's 4th module-list entry — the generic FAPI2SP client conformance battery, always at the fixed immediate+plain crossing.
conformance-wallet-vp command
Command conformance-wallet-vp stands up wallet's own OID4VP presentation half behind real HTTP for the OIDF conformance suite's own "oid4vp-1final-wallet-haip-test-plan" ("OpenID for Verifiable Presentations 1.0 Final/HAIP: Test a wallet") — specifically its direct_post.jwt + x509_hash + request_uri_signed module list (the suite plays Verifier, driving this binary's real Authorization Request resolution and credential presentation over the redirect flow), under either credential format the plan's own VP1FinalWalletCredentialFormat variant offers (sd_jwt_vc, the default, or iso_mdl — see Config.CredentialFormat/credential.go's own issueFixtureMdocCredential) — and its three dc_api.jwt module lists, through POST /dcapi (dcapi.go), with the driver standing in for the browser — see conformance/wallet-vp/README.md.
Command conformance-wallet-vp stands up wallet's own OID4VP presentation half behind real HTTP for the OIDF conformance suite's own "oid4vp-1final-wallet-haip-test-plan" ("OpenID for Verifiable Presentations 1.0 Final/HAIP: Test a wallet") — specifically its direct_post.jwt + x509_hash + request_uri_signed module list (the suite plays Verifier, driving this binary's real Authorization Request resolution and credential presentation over the redirect flow), under either credential format the plan's own VP1FinalWalletCredentialFormat variant offers (sd_jwt_vc, the default, or iso_mdl — see Config.CredentialFormat/credential.go's own issueFixtureMdocCredential) — and its three dc_api.jwt module lists, through POST /dcapi (dcapi.go), with the driver standing in for the browser — see conformance/wallet-vp/README.md.
conformance
issuer/scripts/generate-config command
Command generate-config writes a throwaway conformance-issuer config.json: a fresh self-signed TLS listener cert and a fresh EC P-256 credential-issuer signing key plus a leaf certificate wrapping it issued under a fresh throwaway CA (the CA's own PEM is what to paste into the OIDF suite's own "credential.trust_anchor_pem" test configuration — confirmed live: the suite's own SD-JWT VC x5c check rejects a self-signed leaf outright, "Leaf certificate in x5c chain must not be self-signed", the same finding conformance/wallet-vp/README.md documents first).
Command generate-config writes a throwaway conformance-issuer config.json: a fresh self-signed TLS listener cert and a fresh EC P-256 credential-issuer signing key plus a leaf certificate wrapping it issued under a fresh throwaway CA (the CA's own PEM is what to paste into the OIDF suite's own "credential.trust_anchor_pem" test configuration — confirmed live: the suite's own SD-JWT VC x5c check rejects a self-signed leaf outright, "Leaf certificate in x5c chain must not be self-signed", the same finding conformance/wallet-vp/README.md documents first).
issuer/scripts/run-fapi2sp-battery command
Command run-fapi2sp-battery drives the HAIP issuer test plan's own full module list — every VCI-specific happy-flow/negative-test/ metadata module, its own Discovery module (a separate ModuleListEntry), and its generic FAPI2SP client conformance battery (VCIIssuerTestPlanHaip.vciFapi2SPFinalTestModules(), 39 modules) — against a real, locally-run OIDF conformance suite instance and a real cmd/conformance-issuer — the suite plays the FAPI2 client/wallet, this binary's job is entirely config generation and result polling, not driving any flow itself (see the package doc comment below for why).
Command run-fapi2sp-battery drives the HAIP issuer test plan's own full module list — every VCI-specific happy-flow/negative-test/ metadata module, its own Discovery module (a separate ModuleListEntry), and its generic FAPI2SP client conformance battery (VCIIssuerTestPlanHaip.vciFapi2SPFinalTestModules(), 39 modules) — against a real, locally-run OIDF conformance suite instance and a real cmd/conformance-issuer — the suite plays the FAPI2 client/wallet, this binary's job is entirely config generation and result polling, not driving any flow itself (see the package doc comment below for why).
verifier/scripts/generate-config command
Command generate-config writes a throwaway conformance-verifier config.json: a fresh self-signed TLS listener cert, a fresh OID4VP Client Identifier leaf certificate (its SHA-256 hash becomes the x509_hash Client ID) issued under a fresh throwaway CA — not self-signed; confirmed live: the suite's own ValidateRequestObjectSignatureAgainstX5cHeader check rejects a self-signed leaf outright ("Leaf certificate in x5c chain must not be self-signed"), the exact same finding conformance/wallet-vp/scripts/generate-config and conformance/issuer/scripts/generate-config already worked around for their own leaf certs — and a fresh EC P-256 keypair for the "credential issuer" — paste that keypair's public JWK into the OIDF suite's own test-configuration UI under "Credential Issuer" > "Signing JWK" (matching AbstractCreateSdJwtCredential.createSdJwt's own createSdJwt in the suite's source, confirmed against gitlab.com/openid/conformance-suite) so the suite signs its emulated test credentials with the same key this binary is told to trust.
Command generate-config writes a throwaway conformance-verifier config.json: a fresh self-signed TLS listener cert, a fresh OID4VP Client Identifier leaf certificate (its SHA-256 hash becomes the x509_hash Client ID) issued under a fresh throwaway CA — not self-signed; confirmed live: the suite's own ValidateRequestObjectSignatureAgainstX5cHeader check rejects a self-signed leaf outright ("Leaf certificate in x5c chain must not be self-signed"), the exact same finding conformance/wallet-vp/scripts/generate-config and conformance/issuer/scripts/generate-config already worked around for their own leaf certs — and a fresh EC P-256 keypair for the "credential issuer" — paste that keypair's public JWK into the OIDF suite's own test-configuration UI under "Credential Issuer" > "Signing JWK" (matching AbstractCreateSdJwtCredential.createSdJwt's own createSdJwt in the suite's source, confirmed against gitlab.com/openid/conformance-suite) so the suite signs its emulated test credentials with the same key this binary is told to trust.
verifier/scripts/run-mdoc-module command
Command run-mdoc-module closes this repo's own remaining OIDF Verifier-role certification gap: the "iso_mdl direct_post.jwt" certification profile's own 4 applicable modules of `oid4vp-1final-verifier-haip-test-plan` — happy-flow, request-uri-method-post, request-uri-fetched-twice, and invalid-session-transcript (confirmed against the suite's own Java source, VP1FinalVerifierTestPlan's own 12-module testModules list minus the 8 SD-JWT-VC-only modules — 7 KB-JWT-specific negative tests plus minimal-cnf-jwk, each carrying its own @VariantNotApplicable(credential_format=iso_mdl); minimal-cnf-jwk's own doc comment says so directly: "This test is only applicable for the SD-JWT VC credential format" — invalid-session-transcript carries the mirror-image @VariantNotApplicable(sd_jwt_vc) instead, the only one of the 12 that's iso_mdl-only rather than sd_jwt_vc-only or format-agnostic).
Command run-mdoc-module closes this repo's own remaining OIDF Verifier-role certification gap: the "iso_mdl direct_post.jwt" certification profile's own 4 applicable modules of `oid4vp-1final-verifier-haip-test-plan` — happy-flow, request-uri-method-post, request-uri-fetched-twice, and invalid-session-transcript (confirmed against the suite's own Java source, VP1FinalVerifierTestPlan's own 12-module testModules list minus the 8 SD-JWT-VC-only modules — 7 KB-JWT-specific negative tests plus minimal-cnf-jwk, each carrying its own @VariantNotApplicable(credential_format=iso_mdl); minimal-cnf-jwk's own doc comment says so directly: "This test is only applicable for the SD-JWT VC credential format" — invalid-session-transcript carries the mirror-image @VariantNotApplicable(sd_jwt_vc) instead, the only one of the 12 that's iso_mdl-only rather than sd_jwt_vc-only or format-agnostic).
verifier/scripts/run-sdjwt-modules command
Command run-sdjwt-modules closes conformance-verifier's own last "driven by hand" gap: `oid4vp-1final-verifier-haip-test-plan`'s 11 `direct_post.jwt` + `x509_hash` + `request_uri_signed` + `credential_format=sd_jwt_vc` modules (confirmed against a real historical plan document, GET /api/plan/{id}, fetched from this repo's own already-passing run — not guessed) were originally run live one at a time by hand (see conformance/verifier/README.md's own "Interaction model, confirmed live" section), never as a committed, repeatable tool.
Command run-sdjwt-modules closes conformance-verifier's own last "driven by hand" gap: `oid4vp-1final-verifier-haip-test-plan`'s 11 `direct_post.jwt` + `x509_hash` + `request_uri_signed` + `credential_format=sd_jwt_vc` modules (confirmed against a real historical plan document, GET /api/plan/{id}, fetched from this repo's own already-passing run — not guessed) were originally run live one at a time by hand (see conformance/verifier/README.md's own "Interaction model, confirmed live" section), never as a committed, repeatable tool.
wallet-vp/scripts/generate-config command
Command generate-config writes a throwaway conformance-wallet-vp config.json: a fresh self-signed TLS listener cert, a fresh EC P-256 credential-issuer key plus a leaf certificate wrapping it issued under a fresh throwaway CA (the CA's own PEM is what to paste into the OIDF suite's own credential-trust test configuration, "credential.trust_anchor_pem" — confirmed live: the suite's own SD- JWT VC x5c check rejects a self-signed leaf outright, "Leaf certificate in x5c chain must not be self-signed"), and a fresh EC P-256 Holder Binding key.
Command generate-config writes a throwaway conformance-wallet-vp config.json: a fresh self-signed TLS listener cert, a fresh EC P-256 credential-issuer key plus a leaf certificate wrapping it issued under a fresh throwaway CA (the CA's own PEM is what to paste into the OIDF suite's own credential-trust test configuration, "credential.trust_anchor_pem" — confirmed live: the suite's own SD- JWT VC x5c check rejects a self-signed leaf outright, "Leaf certificate in x5c chain must not be self-signed"), and a fresh EC P-256 Holder Binding key.
wallet-vp/scripts/run-modules command
Command run-modules closes conformance-wallet-vp's own "driven by hand" gap: 13 of `oid4vp-1final-wallet-haip-test-plan`'s 14 `direct_post.jwt` + `x509_hash` + `request_uri_signed` modules (confirmed against a real historical plan document, GET /api/plan/{id} — not guessed) were originally run live one at a time by hand, never as a committed, repeatable tool.
Command run-modules closes conformance-wallet-vp's own "driven by hand" gap: 13 of `oid4vp-1final-wallet-haip-test-plan`'s 14 `direct_post.jwt` + `x509_hash` + `request_uri_signed` modules (confirmed against a real historical plan document, GET /api/plan/{id} — not guessed) were originally run live one at a time by hand, never as a committed, repeatable tool.
credential
mdoc
Package mdoc implements ISO/IEC 18013-5 mdoc credential's data structures for both roles: IssuerSigned (the namespace/data-element digest-and-salt selective-disclosure mechanism, §10.3.3), the Mobile Security Object (MSO, §12.3.4), and IssuerAuth on the issuer side; DeviceSigned and mdoc authentication (§10.3.3, §12.4) on the Holder/presentation side.
Package mdoc implements ISO/IEC 18013-5 mdoc credential's data structures for both roles: IssuerSigned (the namespace/data-element digest-and-salt selective-disclosure mechanism, §10.3.3), the Mobile Security Object (MSO, §12.3.4), and IssuerAuth on the issuer side; DeviceSigned and mdoc authentication (§10.3.3, §12.4) on the Holder/presentation side.
sdjwtvc
Package sdjwtvc implements SD-JWT-based Verifiable Credentials (draft-ietf-oauth-sd-jwt-vc-13), built on the base SD-JWT selective disclosure mechanism (RFC 9901, "Selective Disclosure for JSON Web Tokens") — see SPECIFICATIONS.md for exactly which draft/RFC each requirement below traces to.
Package sdjwtvc implements SD-JWT-based Verifiable Credentials (draft-ietf-oauth-sd-jwt-vc-13), built on the base SD-JWT selective disclosure mechanism (RFC 9901, "Selective Disclosure for JSON Web Tokens") — see SPECIFICATIONS.md for exactly which draft/RFC each requirement below traces to.
Package dcql implements the Digital Credentials Query Language (OID4VP 1.0 §6/§7) — the query object an OID4VP Authorization Request's own "dcql_query" parameter carries to describe which Credentials, and which claims within them, a Verifier is requesting, plus the Claims Path Pointer (§7) addressing scheme a Claims Query's own "path" uses.
Package dcql implements the Digital Credentials Query Language (OID4VP 1.0 §6/§7) — the query object an OID4VP Authorization Request's own "dcql_query" parameter carries to describe which Credentials, and which claims within them, a Verifier is requesting, plus the Claims Path Pointer (§7) addressing scheme a Claims Query's own "path" uses.
Package haip is the OpenID4VC High Assurance Interoperability Profile (HAIP) 1.0 profile layer: recommendations that wire HAIP's own specific overrides on top of the protocol-generic role packages (issuer, wallet and verifier), mirroring FAPIgo's own server.RecommendedLimits/RecommendedAlgorithms pattern.
Package haip is the OpenID4VC High Assurance Interoperability Profile (HAIP) 1.0 profile layer: recommendations that wire HAIP's own specific overrides on top of the protocol-generic role packages (issuer, wallet and verifier), mirroring FAPIgo's own server.RecommendedLimits/RecommendedAlgorithms pattern.
internal
certchain
Package certchain implements the one certificate-chain-trust primitive shared by every X5C/X5C-chain-shaped resolver this repo ships (verifier.X5CIssuerKeyResolver, verifier.X5ChainIssuerKeyResolver, issuer.X5CAttestationVerifier, issuer.X5CProofBindingKeyResolver): parse a leaf-first chain and verify it against a trust anchor set, rejecting a self-signed leaf even when that leaf is itself a configured root.
Package certchain implements the one certificate-chain-trust primitive shared by every X5C/X5C-chain-shaped resolver this repo ships (verifier.X5CIssuerKeyResolver, verifier.X5ChainIssuerKeyResolver, issuer.X5CAttestationVerifier, issuer.X5CProofBindingKeyResolver): parse a leaf-first chain and verify it against a trust anchor set, rejecting a self-signed leaf even when that leaf is itself a configured root.
conformancecert
Package conformancecert builds throwaway self-signed key material for the conformance/*/scripts/generate-config generators — never for production use, and deliberately not internal/testcert (that one builds a *x509.Certificate for tests to hold in memory; these generators need PEM text to write into a JSON config file).
Package conformancecert builds throwaway self-signed key material for the conformance/*/scripts/generate-config generators — never for production use, and deliberately not internal/testcert (that one builds a *x509.Certificate for tests to hold in memory; these generators need PEM text to write into a JSON config file).
conformanceconfig
Package conformanceconfig holds JSON-shape types shared between a conformance/*/scripts/*/config.go generator and the cmd/conformance-*/config.go binary that parses what it writes — both package main, so neither can import the other, the same constraint internal/conformancecert already exists to work around for key material.
Package conformanceconfig holds JSON-shape types shared between a conformance/*/scripts/*/config.go generator and the cmd/conformance-*/config.go binary that parses what it writes — both package main, so neither can import the other, the same constraint internal/conformancecert already exists to work around for key material.
conformancesuite
Package conformancesuite drives the OpenID Foundation conformance suite's own REST API (POST /api/plan, POST /api/runner, GET /api/info/{id}) — generic to the suite itself, with no OID4VCI- or FAPI-specific content.
Package conformancesuite drives the OpenID Foundation conformance suite's own REST API (POST /api/plan, POST /api/runner, GET /api/info/{id}) — generic to the suite itself, with no OID4VCI- or FAPI-specific content.
conformanceverifier
Package conformanceverifier holds the pieces conformance/verifier/scripts/run-mdoc-module and conformance/verifier/scripts/run-sdjwt-modules both need — generating fresh key material, writing/restarting cmd/conformance-verifier's own config, building the suite's own plan-configuration body, and driving one module via the documented two-request interaction model — factored out once both scripts turned out to duplicate all of it near-verbatim (confirmed live by SonarCloud's own duplication gate on the PR that added the second script).
Package conformanceverifier holds the pieces conformance/verifier/scripts/run-mdoc-module and conformance/verifier/scripts/run-sdjwt-modules both need — generating fresh key material, writing/restarting cmd/conformance-verifier's own config, building the suite's own plan-configuration body, and driving one module via the documented two-request interaction model — factored out once both scripts turned out to duplicate all of it near-verbatim (confirmed live by SonarCloud's own duplication gate on the PR that added the second script).
cose
Package cose implements small, self-contained COSE_Sign1 (RFC 9052 §4.2) and COSE_Mac0 (RFC 9052 §6.2) signers/verifiers, used internally by credential/mdoc (IssuerAuth, DeviceSignature, DeviceMac — ISO/IEC 18013-5) and statuslist (CWT-encoded Status List Tokens).
Package cose implements small, self-contained COSE_Sign1 (RFC 9052 §4.2) and COSE_Mac0 (RFC 9052 §6.2) signers/verifiers, used internally by credential/mdoc (IssuerAuth, DeviceSignature, DeviceMac — ISO/IEC 18013-5) and statuslist (CWT-encoded Status List Tokens).
dpop
Package dpop verifies an RFC 9449 DPoP proof JWT — the server-side counterpart to wallet's own GenerateDPoPProof, which builds one.
Package dpop verifies an RFC 9449 DPoP proof JWT — the server-side counterpart to wallet's own GenerateDPoPProof, which builds one.
ecdsafixed
Package ecdsafixed converts between the ASN.1 DER ECDSA signature encoding Go's crypto.Signer produces (SEC1 / RFC 3279 §2.2.3) and the fixed-width big-endian R||S encoding both JWS (RFC 7518 §3.4) and COSE (RFC 9053 §2.1) require instead — the one piece of signature-envelope logic internal/jose and internal/cose need identically, since both specs made the same encoding choice for ECDSA.
Package ecdsafixed converts between the ASN.1 DER ECDSA signature encoding Go's crypto.Signer produces (SEC1 / RFC 3279 §2.2.3) and the fixed-width big-endian R||S encoding both JWS (RFC 7518 §3.4) and COSE (RFC 9053 §2.1) require instead — the one piece of signature-envelope logic internal/jose and internal/cose need identically, since both specs made the same encoding choice for ECDSA.
hkdf
Package hkdf implements HKDF (RFC 5869) using SHA-256, the key derivation function ISO/IEC 18013-5 §12.4.5 uses to derive mdoc's ephemeral MAC key (EMacKey) from an ECDH shared secret — the one piece of key-agreement machinery credential/mdoc's DeviceMac needs that internal/cose deliberately doesn't own (see that package's doc comment).
Package hkdf implements HKDF (RFC 5869) using SHA-256, the key derivation function ISO/IEC 18013-5 §12.4.5 uses to derive mdoc's ephemeral MAC key (EMacKey) from an ECDH shared secret — the one piece of key-agreement machinery credential/mdoc's DeviceMac needs that internal/cose deliberately doesn't own (see that package's doc comment).
jose
Package jose implements a small, self-contained JWS compact serialization signer/verifier (RFC 7515), used internally by credential/sdjwtvc (and, in time, attestation and statuslist) for the Issuer-signed JWT and Key Binding JWT that SD-JWT VC needs.
Package jose implements a small, self-contained JWS compact serialization signer/verifier (RFC 7515), used internally by credential/sdjwtvc (and, in time, attestation and statuslist) for the Issuer-signed JWT and Key Binding JWT that SD-JWT VC needs.
jwe
Package jwe implements a small, self-contained JWE Compact Serialization encryptor/decryptor (RFC 7516), for OID4VCI 1.0 §10's Encrypted Credential Requests and Responses.
Package jwe implements a small, self-contained JWE Compact Serialization encryptor/decryptor (RFC 7516), for OID4VCI 1.0 §10's Encrypted Credential Requests and Responses.
jwk
Package jwk implements a small, self-contained JWK (RFC 7517) marshaler/parser for the two key types internal/jose signs with: P-256 EC keys and Ed25519 OKP keys.
Package jwk implements a small, self-contained JWK (RFC 7517) marshaler/parser for the two key types internal/jose signs with: P-256 EC keys and Ed25519 OKP keys.
jwtdate
Package jwtdate converts JWT NumericDates (RFC 7519 §2) to times, refusing the values time.Unix and Duration arithmetic can't hold: a date near int64's maximum wraps into the far past, and the age of one far in the future saturates, so an iat or nbf there would pass a freshness check.
Package jwtdate converts JWT NumericDates (RFC 7519 §2) to times, refusing the values time.Unix and Duration arithmetic can't hold: a date near int64's maximum wraps into the far past, and the age of one far in the future saturates, so an iat or nbf there would pass a freshness check.
readerauth
Package readerauth signs and verifies ISO/IEC 18013-5 mdoc reader authentication (§9.1.4): a COSE_Sign1 with a null payload over a detached ReaderAuthenticationBytes, the reader's certificate chain in its unprotected x5chain header.
Package readerauth signs and verifies ISO/IEC 18013-5 mdoc reader authentication (§9.1.4): a COSE_Sign1 with a null payload over a detached ReaderAuthenticationBytes, the reader's certificate chain in its unprotected x5chain header.
testcert
Package testcert builds throwaway self-signed X.509 certificates for tests that need a *x509.Certificate (e.g.
Package testcert builds throwaway self-signed X.509 certificates for tests that need a *x509.Certificate (e.g.
testmdoc
Package testmdoc provides shared "mso_mdoc" test fixtures for OID4VP presentation tests across packages (verifier, wallet) — never for production use.
Package testmdoc provides shared "mso_mdoc" test fixtures for OID4VP presentation tests across packages (verifier, wallet) — never for production use.
testverifier
Package testverifier builds a ready-to-use *verifier.Verifier for tests (and fuzz targets, which build their own seed corpus outside any *testing.T-scoped test function) that need one — never for production use.
Package testverifier builds a ready-to-use *verifier.Verifier for tests (and fuzz targets, which build their own seed corpus outside any *testing.T-scoped test function) that need one — never for production use.
testverify
Package testverify holds small shared assertion helpers and query fixtures for verifier.VerifyResponse tests across packages (verifier, wallet) — never for production use.
Package testverify holds small shared assertion helpers and query fixtures for verifier.VerifyResponse tests across packages (verifier, wallet) — never for production use.
Package issuer implements the OID4VCI 1.0 Credential Issuer role (the server side): the Nonce Endpoint (§7), Credential Issuer Metadata (§12.2), the Credential Endpoint (§8), the Credential Offer (§4), the Deferred Credential Endpoint (§9), the Notification Endpoint (§11), and the Pre-Authorized Code Flow's own Token Request/Response (§6.1/§6.2).
Package issuer implements the OID4VCI 1.0 Credential Issuer role (the server side): the Nonce Endpoint (§7), Credential Issuer Metadata (§12.2), the Credential Endpoint (§8), the Credential Offer (§4), the Deferred Credential Endpoint (§9), the Notification Endpoint (§11), and the Pre-Authorized Code Flow's own Token Request/Response (§6.1/§6.2).
fapiresource
Package fapiresource adapts a fapigo/resource.Verifier to issuer.AccessTokenVerifier, for an Issuer whose access tokens come from a fapigo/server Authorization Server (or its own ExchangePreAuthorizedCode).
Package fapiresource adapts a fapigo/resource.Verifier to issuer.AccessTokenVerifier, for an Issuer whose access tokens come from a fapigo/server Authorization Server (or its own ExchangePreAuthorizedCode).
issuertest
Package issuertest holds reusable contract tests for issuer's store interfaces, for a caller testing its own store implementation.
Package issuertest holds reusable contract tests for issuer's store interfaces, for a caller testing its own store implementation.
Package mdocdcapi implements both sides of "org-iso-mdoc": the presentation of an mdoc over the W3C Digital Credentials API, as ISO/IEC TS 18013-7:2025 Annex C defines it — the one protocol Safari supports, answered by Apple Wallet or an iOS document provider app.
Package mdocdcapi implements both sides of "org-iso-mdoc": the presentation of an mdoc over the W3C Digital Credentials API, as ISO/IEC TS 18013-7:2025 Annex C defines it — the one protocol Safari supports, answered by Apple Wallet or an iOS document provider app.
Package oid4vpmdoc implements the OID4VP-specific wire structures the "mso_mdoc" Credential Format's own Presentation needs on top of credential/mdoc's own ISO/IEC 18013-5 primitives: DeviceResponse (ISO/IEC 18013-5 §10.3.2/§10.3.3, OID4VP Appendix B.2.5 — the VP Token array entry's own base64url-encoded wire shape), and SessionTranscriptBytes built per either of OID4VP's own two Handover structures — OpenID4VPHandover (Appendix B.2.6.1, redirect flow) or OpenID4VPDCAPIHandover (Appendix B.2.6.2, the DC API flow) — see below.
Package oid4vpmdoc implements the OID4VP-specific wire structures the "mso_mdoc" Credential Format's own Presentation needs on top of credential/mdoc's own ISO/IEC 18013-5 primitives: DeviceResponse (ISO/IEC 18013-5 §10.3.2/§10.3.3, OID4VP Appendix B.2.5 — the VP Token array entry's own base64url-encoded wire shape), and SessionTranscriptBytes built per either of OID4VP's own two Handover structures — OpenID4VPHandover (Appendix B.2.6.1, redirect flow) or OpenID4VPDCAPIHandover (Appendix B.2.6.2, the DC API flow) — see below.
Package proximity implements ISO/IEC 18013-5 in-person (proximity) presentation over BLE, both roles, as bytes in and bytes out: the mdoc (holder) side is DeviceSession, the mdoc reader (verifier) side is ReaderSession.
Package proximity implements ISO/IEC 18013-5 in-person (proximity) presentation over BLE, both roles, as bytes in and bytes out: the mdoc (holder) side is DeviceSession, the mdoc reader (verifier) side is ReaderSession.
Package registration is OID4VCgo's verifier registration attestation: a JWT a registrar issues for a relying party, saying who it is, why it asks, and which claims it's registered to request.
Package registration is OID4VCgo's verifier registration attestation: a JWT a registrar issues for a relying party, saying who it is, why it asks, and which claims it's registered to request.
Package statuslist implements Token Status List (draft-ietf-oauth-status-list-14): a bit-packed, DEFLATE/ZLIB- compressed array of Referenced Token statuses, published as a signed Status List Token, plus the "status" claim a Referenced Token (such as an SD-JWT VC — see credential/sdjwtvc's Claims.Status, or an mdoc — see credential/mdoc's package doc comment) uses to point at one.
Package statuslist implements Token Status List (draft-ietf-oauth-status-list-14): a bit-packed, DEFLATE/ZLIB- compressed array of Referenced Token statuses, published as a signed Status List Token, plus the "status" claim a Referenced Token (such as an SD-JWT VC — see credential/sdjwtvc's Claims.Status, or an mdoc — see credential/mdoc's package doc comment) uses to point at one.
Package storage provides in-memory implementations of every store interface the issuer package defines (NonceStore, CredentialOfferStore, DeferredTransactionStore, NotificationStore, PreAuthorizedCodeStore, DPoPNonceStore, DPoPReplayChecker) and the verifier package's TransactionStore — for local development and testing only.
Package storage provides in-memory implementations of every store interface the issuer package defines (NonceStore, CredentialOfferStore, DeferredTransactionStore, NotificationStore, PreAuthorizedCodeStore, DPoPNonceStore, DPoPReplayChecker) and the verifier package's TransactionStore — for local development and testing only.
Package verifier implements the OID4VP 1.0 Verifier (Relying Party) role, profiled by HAIP 1.0 §5 — the presentation half of HAIP, as issuer/wallet implement OID4VCI's own issuance half.
Package verifier implements the OID4VP 1.0 Verifier (Relying Party) role, profiled by HAIP 1.0 §5 — the presentation half of HAIP, as issuer/wallet implement OID4VCI's own issuance half.
verifiertest
Package verifiertest holds reusable contract tests for verifier's issuer key resolvers, and the certificate helpers they need, for a caller testing its own resolver.
Package verifiertest holds reusable contract tests for verifier's issuer key resolvers, and the certificate helpers they need, for a caller testing its own resolver.
Package wallet implements the OID4VCI 1.0 Wallet role (the client side): resolving a Credential Offer (§4), generating jwt-type and attestation-type key proofs (Appendix F.1/F.3), and driving the Credential Endpoint (§8), Nonce Endpoint (§7), Deferred Credential Endpoint (§9) and Notification Endpoint (§11).
Package wallet implements the OID4VCI 1.0 Wallet role (the client side): resolving a Credential Offer (§4), generating jwt-type and attestation-type key proofs (Appendix F.1/F.3), and driving the Credential Endpoint (§8), Nonce Endpoint (§7), Deferred Credential Endpoint (§9) and Notification Endpoint (§11).
Package walletflow is a holder's wallet as a set of sessions: it receives credentials from a Credential Offer (OpenID4VCI 1.0, and optionally only from issuers following HAIP 1.0 §4) and presents them in answer to an Authorization Request (OpenID4VP 1.0, HAIP 1.0 §5), orchestrating the wallet package and fapigo/client step by step so an app can stop at each point that needs the holder: to show an offer, open the issuer's authorization page, ask for a PIN, or choose what to disclose.
Package walletflow is a holder's wallet as a set of sessions: it receives credentials from a Credential Offer (OpenID4VCI 1.0, and optionally only from issuers following HAIP 1.0 §4) and presents them in answer to an Authorization Request (OpenID4VP 1.0, HAIP 1.0 §5), orchestrating the wallet package and fapigo/client step by step so an app can stop at each point that needs the holder: to show an offer, open the issuer's authorization page, ask for a PIN, or choose what to disclose.
walletflowtest
Package walletflowtest runs a complete HAIP 1.0 Credential Issuer in process — or, with Options, one outside HAIP that OpenID4VCI 1.0 allows (Anonymous) — for tests that drive a wallet built on walletflow end to end (walletflow's own, and the mobile module's): a fapigo/server Authorization Server authenticating wallets by Wallet Attestation, an issuer.Issuer taking Key Attestations (the attestation proof type), with the authorization code grant (consent approved automatically), the pre-authorized code grant with a PIN, deferred issuance and notifications, plus the Wallet Provider that attests the wallet and its keys, and an OpenID4VP Verifier (StartVerifier).
Package walletflowtest runs a complete HAIP 1.0 Credential Issuer in process — or, with Options, one outside HAIP that OpenID4VCI 1.0 allows (Anonymous) — for tests that drive a wallet built on walletflow end to end (walletflow's own, and the mobile module's): a fapigo/server Authorization Server authenticating wallets by Wallet Attestation, an issuer.Issuer taking Key Attestations (the attestation proof type), with the authorization code grant (consent approved automatically), the pre-authorized code grant with a PIN, deferred issuance and notifications, plus the Wallet Provider that attests the wallet and its keys, and an OpenID4VP Verifier (StartVerifier).

Jump to

Keyboard shortcuts

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