Skip to main content

Configuration

The mwen.io issuer is configured through a combination of environment variables (for secrets and deployment-specific values) and a YAML file (for non-secret, non-deployment-specific settings). Environment variables always take priority.


Configuration priority

1. Environment variables   — highest priority, always override
2. issuer.config.yaml — operator config file, committed to version control
3. Built-in code defaults — lowest priority

The resolved configuration is cached for the lifetime of the server process.


Environment variables

Required in all modes

VariableDescriptionExample
DATABASE_URLPostgreSQL connection stringpostgresql://user:pass@host:5432/issuer
NEXTAUTH_SECRETSecret for admin portal session cookie signing and encryptionopenssl rand -hex 32
NEXTAUTH_URLCanonical base URL of the issuer — must match the URL the browser navigates tohttps://issuer.yourorg.com

NEXTAUTH_URL must point to the URL users navigate to — i.e. your HTTPS proxy or load balancer URL, not the raw Next.js port (3003). NextAuth uses this for session cookie validation and redirects.


Identity

VariableDescriptionExample
ISSUER_DIDYour issuer's DID. Must start with did:did:web:issuer.yourorg.com
ISSUER_DOMAINDomain used for OID4VCI audience validationissuer.yourorg.com
ISSUER_CATEGORYIssuer vertical categoryemployer

Valid ISSUER_CATEGORY values: government, employer, academic, learning-platform.


Signing keys

Set one of the following depending on your deployment mode:

VariableModeDescription
ISSUER_SIGNING_KEYSelf-hostedHex-encoded 32-byte signing key. All credentials are signed with this key. Generate with openssl rand -hex 32.
ISSUER_MASTER_KEYSaaSHex-encoded 32-byte HKDF master key. Per-tenant signing keys are derived from this. Store in a secrets manager — never commit to version control.

Rotating ISSUER_MASTER_KEY invalidates the signatures on all previously issued credentials across all tenants. Plan rotation carefully.


Mode

VariableDescriptionDefault
SAAS_MODESet to true to enable multi-tenant SaaS modefalse

Identity adapter

VariableDescriptionExample
ADAPTER_TYPEIdentifier for the credential-subject data adaptermock-gov-db
ADAPTER_CONFIGJSON string of adapter-specific non-secret settings{"baseUrl":"https://ldap.yourorg.com"}

Available adapter types: mock-gov-db, ldap, scim, student-registry.


Optional

VariableDescription
ISSUER_CONFIG_PATHAbsolute path to an alternative YAML config file. Useful for Docker volume mounts.
PORTOverride the Next.js listen port (default: 3003).

YAML configuration file

Non-secret settings live in issuer.config.yaml at the root of apps/issuer/. This file is safe to commit. An annotated reference is in issuer.config.example.yaml.

server:
port: 3003
host: 0.0.0.0

identity:
did: did:web:issuer.yourorg.com
domain: issuer.yourorg.com
category: employer

signing:
mode: self-hosted # "self-hosted" | "saas"

adapter:
type: ldap
config:
baseUrl: https://ldap.yourorg.com
baseDN: dc=yourorg,dc=com

YAML field reference

FieldTypeDescription
server.portintegerPort Next.js binds to (not the proxy port)
server.hoststringBind address
identity.didstringIssuer DID — must start with did:
identity.domainstringDomain for OID4VCI audience validation
identity.categorystringIssuer vertical category
signing.mode"self-hosted" | "saas"Signing key strategy
adapter.typestringAdapter identifier
adapter.configobjectAdapter-specific non-secret settings

Any value set in environment variables will override the corresponding YAML field.


Production checklist

Before deploying to production:

  • ISSUER_SIGNING_KEY (self-hosted) or ISSUER_MASTER_KEY (SaaS) — generated fresh, stored in secrets manager
  • NEXTAUTH_SECRET — generated fresh, stored in secrets manager
  • NEXTAUTH_URL — set to your production HTTPS URL (not localhost)
  • ISSUER_DID — set to your production did:web
  • ISSUER_DOMAIN — set to your production domain
  • DATABASE_URL — pointing to your production PostgreSQL instance
  • SAAS_MODE — set correctly (true for SaaS, leave unset for self-hosted)