Skip to main content

Deployment Modes

The mwen.io issuer supports two operating modes: self-hosted and SaaS. The mode you choose determines how tenants, signing keys, and routing are managed. You select the mode at startup via an environment variable; the application behaviour changes accordingly.


Comparison

Self-HostedSaaS
Number of tenantsOneMany
Tenant routingSingle-tenant (no slug in URL)Slug-based (/your-org/admin)
Signing keyYou supply ISSUER_SIGNING_KEY (BYOK)Derived per-tenant from ISSUER_MASTER_KEY via HKDF
Key storageYour infrastructurePlatform secrets manager
Database isolationNot requiredPostgreSQL Row-Level Security (RLS)
Platform-admin APINot availableAvailable at /api/platform-admin/tenants
Operator registrationFirst operator auto-promotedFirst PLATFORM_ADMIN registers via browser extension
Typical deployerOne organisation running their own instanceA platform onboarding multiple issuing organisations

Self-hosted mode

Self-hosted mode is controlled by setting SAAS_MODE=false (the default when the variable is unset).

In this mode the issuer operates as a single-tenant application. There is one organisation, one signing key, and one set of credential schemas. Tenant routing middleware is inactive — all requests are handled by the single-tenant fallback.

Best suited for:

  • A government agency deploying a national ID issuer
  • A university deploying a diploma credential service
  • An enterprise deploying employee credential infrastructure
  • Any organisation that runs its own infrastructure and wants to bring its own signing key

What you manage:

  • The ISSUER_SIGNING_KEY (a 32-byte hex secret). Generate it once; store it in your secrets manager. All credentials are signed with this key.
  • The PostgreSQL database. No RLS configuration required.
  • The NEXTAUTH_SECRET for admin portal sessions.
  • Your ISSUER_DID (a did:web pointing to your domain, e.g. did:web:issuer.yourorg.com).

What mwen.io provides:

  • The OID4VCI protocol implementation
  • The schema templates
  • The revocation infrastructure (BitstringStatusList)
  • The admin portal UI

SaaS mode

SaaS mode is enabled by setting SAAS_MODE=true.

In this mode the issuer is a multi-tenant application. Multiple organisations are each assigned a slug (e.g. acme-corp). Their admin portal is at /acme-corp/admin. Their OID4VCI credential issuance endpoints are namespaced to their tenant. Database rows are isolated by PostgreSQL Row-Level Security — one tenant cannot read another's data, even if both share the same database.

Best suited for:

  • A platform that wants to offer credential issuance as a service to multiple organisations
  • A government platform serving multiple agencies under one deployment
  • A SaaS operator who manages the infrastructure on behalf of clients

What you manage:

  • The ISSUER_MASTER_KEY (a 32-byte hex secret stored in a secrets manager). Per-tenant signing keys are derived from this using HKDF — you never store individual tenant keys.
  • The PostgreSQL database with RLS policies (applied automatically by the migration runner).
  • The NEXTAUTH_SECRET for admin portal sessions.
  • The platform-admin API for creating and managing tenants.

What mwen.io provides:

  • All of the above plus multi-tenant routing, RLS enforcement, per-tenant HKDF key derivation, and the platform-admin API.

Security note: Rotating ISSUER_MASTER_KEY invalidates the signatures on all previously issued credentials across all tenants. Plan key rotation carefully and communicate with tenants before rotating.


Switching modes

Use the npm scripts to switch between modes in development. Each script copies the appropriate environment file to .env.local before starting the server.

# Switch to self-hosted mode
npm run dev:self-hosted

# Switch to SaaS mode
npm run dev:saas

The active mode is determined by the .env.local file. Switching modes overwrites this file.

For production deployments, set SAAS_MODE=true (or leave it unset for self-hosted) directly in your environment or secrets manager. Do not use the dev scripts in production.