For the complete documentation index, see llms.txt. This page is also available as Markdown.

Security Considerations

The sections below describe how the Issuer Service protects its API, the credentials it issues, and the signing keys it manages.

  1. 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 in OIDC_JWKS_URL: the signature is verified with RS256, the signing key is selected by matching the token's kid against 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 with 401 Unauthorized.

    • Role-based access: The admin role 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 the admin role with 403 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 the admin role in your identity provider.

    • Development bypass: Setting AUTH_DISABLED=true disables token validation and treats every request as an authenticated admin user. This is a local-development convenience only and must never be enabled in production.

  2. Public Endpoints: A number of endpoints are intentionally unauthenticated: GET / (hello), GET /version, and the hosted DID document routes (GET /:uuid/did.json and GET /: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 the ISSUER_BASE_URL/VERIFIER_BASE_URL paths (credential-issuer metadata, token, credential, and authorization-request/response endpoints), which are public by protocol design.

  3. Transport Security: Always use HTTPS to protect tokens and credentials in transit. The OpenID4VCI issuance flow requires HTTPS in production. The ALLOW_INSECURE_HTTP=true flag permits plain HTTP for local development only and must be left unset (or false) in any deployed environment.

  4. Credential Integrity: Issued credentials are cryptographically signed with the issuer's Ed25519 key using the EdDSA algorithm. The signature binds the claims to the issuing DID, so any tampering with a credential — for example with an [email protected]:sd-jwt credential — 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.

  5. 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.

  6. 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.

  7. Key Management: Issuer signing keys are Ed25519 keys 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