Security Considerations
The sections below describe how the Issuer Service protects its API, the credentials it issues, and the signing keys it manages.
API Authentication and Authorization:
OIDC JWT Bearer tokens: Every non-public endpoint requires an OIDC-issued JWT presented as
Authorization: Bearer <token>. Tokens are validated against the JWKS endpoint configured inOIDC_JWKS_URL: the signature is verified withRS256, the signing key is selected by matching the token'skidagainst the JWKS, and expiration is enforced. Fetched signing keys are cached for roughly 10 minutes (with a request limit of 10 JWKS fetches per minute) to limit round-trips to the identity provider. A request with a missing, malformed, or expired token is rejected with401 Unauthorized.Role-based access: The
adminrole is additionally enforced on agent management routes (/agent/*— DID, issuer, verifier and holder management) and on cloud-wallet routes (/holders/:holderId/*). For these routes, the service inspects the token's realm roles (realm_access.roles) and client roles (resource_access) and rejects any caller without theadminrole with403 Forbidden. Cloud-wallet routes additionally enforce ownership, so a caller can only access the holders they created. The remaining Issuer endpoints (schema management, credential offers, issuance sessions and direct signing) and the Verifier endpoints require only a valid token — they carry no role requirement. Restrict who can obtain tokens carrying theadminrole in your identity provider.Development bypass: Setting
AUTH_DISABLED=truedisables token validation and treats every request as an authenticatedadminuser. This is a local-development convenience only and must never be enabled in production.
Public Endpoints: A number of endpoints are intentionally unauthenticated:
GET /(hello),GET /version, and the hosted DID document routes (GET /:uuid/did.jsonandGET /:uuid/.well-known/did.json). These expose only public information — a service identifier, a version string, and DID documents that are meant to be world-readable so that verifiers can resolve issuer keys. Also public are the Swagger docs (GET /api-docs,GET /api-docs-json) and the wallet-facing OpenID4VCI/OpenID4VP protocol endpoints mounted under theISSUER_BASE_URL/VERIFIER_BASE_URLpaths (credential-issuer metadata, token, credential, and authorization-request/response endpoints), which are public by protocol design.Transport Security: Always use HTTPS to protect tokens and credentials in transit. The OpenID4VCI issuance flow requires HTTPS in production. The
ALLOW_INSECURE_HTTP=trueflag permits plain HTTP for local development only and must be left unset (orfalse) in any deployed environment.Credential Integrity: Issued credentials are cryptographically signed with the issuer's
Ed25519key using theEdDSAalgorithm. The signature binds the claims to the issuing DID, so any tampering with a credential — for example with an[email protected]:sd-jwtcredential — invalidates the signature and causes verification to fail. For SD-JWT VC credentials, selective disclosure lets a holder reveal only chosen claims while the issuer signature still covers the full set.Rate Limiting: A global throttle of 60 requests per 60 seconds is applied to guard against brute-force and abuse. DID document serving is exempt so that verifiers can always resolve issuer keys. Requests exceeding the limit receive
429 Too Many Requests.Access Controls and Monitoring: In addition to the built-in token validation and role-based access control, operators should apply standard hardening at the network layer: IP allow-listing, firewalls, and audit logging to track sensitive operations and surface suspicious activity.
Key Management: Issuer signing keys are
Ed25519keys held in an internal, database-backed key-management system; private key material is never exposed through the API. Automated key rotation is not available today; it is a planned future capability (see Future Enhancements).
Last updated