License

license.conf configures how the Enterprise API activates its license, where it contacts walt.id's license service, and which seed material to use on first startup.

Licensing is a base feature. The file is required. After the first successful activation, the stack stores the bound credential and installation key in MongoDB. Later restarts reuse that persisted state, so an online credential offer is never redeemed twice.

First startup needs exactly one seed option: seedCredential or seedCredentialFile. Configuring both fails startup.

For the full activation flow, see Licensing.

Example File

license.conf
# URL used for online activation, heartbeat renewal, and usage reporting.
licenseServerUrl = "https://license.walt.id"

# Online first activation — uncomment and paste the offer walt.id provides.
# seedCredential = "openid-credential-offer://..."

# Raw credential seed — recovery or migration when a signed SD-JWT VC is already available.
# Do not set this together with seedCredentialFile.
# seedCredential = "eyJ..."

# Offline or air-gapped activation — mount both files, then uncomment both lines.
# Keep installation-key.json inside your environment; never send it to walt.id.
# seedCredentialFile = "/license/offline-license.waltlicense"
# installationKeyFile = "/license/installation-key.json"

Fields

licenseServerUrl

String — Base URL of walt.id's license service. Used for online activation, heartbeat renewal, and usage reporting.

  • Default"https://license.walt.id"
  • Use the URL walt.id gives you for your environment. Connected deployments need outbound access to this host.

Heartbeat interval and startup refresh timeouts are walt.id policy. They are not configured in this file.

seedCredential

String — First-start license material when you are not mounting a file.

Use one of:

  • OpenID credential offer — e.g. "openid-credential-offer://...": walt.id returns this when they create an online license. The stack redeems it once on first startup, then stores the issued credential.
  • Raw SD-JWT VC — e.g. "eyJ...": a signed license credential you already have. Use this for controlled migrations or recovery, not for a fresh online offer.

Leave the field unset (or commented) after activation if MongoDB already holds the bound credential. A previously redeemed offer cannot be redeemed again — request a fresh offer from walt.id if first activation failed after the offer was consumed.

seedCredentialFile

String (optional) — Path to a raw offline license VC or a checksummed .waltlicense bundle.

  • Use with air-gapped / offline licenses.
  • A path ending in .waltlicense is treated as a bundle. Other files are treated as a raw credential and must be offline licenses.
  • Do not set this together with seedCredential.
  • On later restarts, persisted MongoDB state is used. A mounted bundle with a newer issuedAt is treated as an explicit renewal.

installationKeyFile

String (optional) — Path to the private installation key that matches an offline license.

  • Required for first-start offline activation when walt.id bound the license to a key you generated in your environment.
  • The file must contain a private key.
  • Keep this file inside your environment. Never send it to the license server.
  • After first activation, the fleet key is stored encrypted in MongoDB. All replicas share that stored key. A configured file must match the stored fleet key or startup fails.

Online activations generate the installation key automatically and persist it. You do not set installationKeyFile for a normal online offer.

LICENSE_STATE_ENCRYPTION_KEY

This value is not in license.conf. Supply it as an environment variable or JVM system property on every replica.

The key encrypts the persisted license credential and fleet installation private key in MongoDB.

RequirementDetail
NameLICENSE_STATE_ENCRYPTION_KEY
LengthAt least 32 characters
ScopeSame value on every replica of one deployment
BackupBack it up together with MongoDB

A missing or too-short key fails startup. Changing the key without first re-encrypting the stored rawVc and installationKeyJwk makes existing license state unreadable. Live dual-key rotation is not supported.

Docker

docker run -p 3000:3000 \
  -v $(pwd)/config:/config \
  -e LICENSE_STATE_ENCRYPTION_KEY="{your-32-plus-character-secret}" \
  waltid/waltid-enterprise-api

Docker Compose

Add the variable to the Enterprise API service (or to .env and interpolate it):

waltid-enterprise:
  environment:
    - LICENSE_STATE_ENCRYPTION_KEY={your-32-plus-character-secret}
  volumes:
    - ./config:/config

Kubernetes

Store the key in a Secret and reference it from the Deployment. You can also inject the online offer through the same Secret using HOCON optional substitution in license.conf:

seedCredential = ${?LICENSE_SEED_CREDENTIAL}
seedCredentialFile = ${?LICENSE_SEED_CREDENTIAL_FILE}
installationKeyFile = ${?LICENSE_INSTALLATION_KEY_FILE}
licenseServerUrl = "https://license.walt.id"
apiVersion: v1
kind: Secret
metadata:
  name: waltid-enterprise-license
type: Opaque
stringData:
  state-encryption-key: "{your-32-plus-character-secret}"
  seed-credential: "openid-credential-offer://..."
env:
  - name: LICENSE_STATE_ENCRYPTION_KEY
    valueFrom:
      secretKeyRef:
        name: waltid-enterprise-license
        key: state-encryption-key
  - name: LICENSE_SEED_CREDENTIAL
    valueFrom:
      secretKeyRef:
        name: waltid-enterprise-license
        key: seed-credential
        optional: true

For offline Kubernetes activation, mount the .waltlicense bundle and installation-key.json (for example at /license/offline-license.waltlicense and /license/installation-key.json) and set the matching *-file secret keys to those paths.

  • dev-mode in _features.conf — A development license requires dev-mode to be enabled. A production license refuses to start when dev-mode is enabled.
  • Feature allow-list_features.conf still applies, but a feature must also be allowed by the active license.

See Features and Licensing.

Last updated on August 18, 2026