Skip to main content

Secrets and Keys

Every installation from the Full Stack Quick Start starts with the same tokens, keys, and passwords. Anyone with access to the quick start files knows them. Replace them before you store real data or expose your installation to a network.

This page lists every secret in the starter setup, what it protects, and what happens when you change it. Some secrets are replaced as part of another step, such as connecting your own identity provider or database. Those are listed here and covered in detail on their own pages.

Overview​

SecretServiceEffect of changing it
Key storage encryption keyCoreSet once. Keys stored before the change can no longer be read.
OpenID4VCI encryption keysCoreHeld credentials can no longer be refreshed or reissued.
OpenID4VCI nonce signing keysCoreIn-progress issuance flows fail. Safe to change any time.
STS signing keyBFFOperator sessions and service tokens are invalidated.
WRPR signing keyWRPRPublic API responses are signed with the new key.
Static tokensCore, Bridge, WRPRCallers fail until updated with the new token.
Session cookie secretoauth2-proxyOperators are signed out.
Identity provider credentialsKeycloak, all servicesSign-in and technical user tokens fail until updated.
Database and cache credentialsDatabases, RedisServices cannot connect until updated.

Generating values​

Generate a new value for every secret. Do not reuse values across secrets or across environments.

KindCommand
32-byte hex key or tokenopenssl rand -hex 32
Ed25519 private key, PKCS #8, one lineopenssl genpkey -algorithm ed25519 | tr '\n' ' '
oauth2-proxy cookie secretopenssl rand -base64 32 | tr -- '+/' '-_'
Passwordopenssl rand -base64 24

Write private keys on a single line, as the command above produces:

sts.token.privateKey="-----BEGIN PRIVATE KEY----- MC4CAQAwBQYDK2VwBCIEI... -----END PRIVATE KEY-----"

Core encryption keys​

Core encrypts sensitive data with keys from its configuration. Core does not start if a required key is missing.

Key storage encryption key​

Encrypts private keys held in INTERNAL key storage.

ONE_keyStorage__INTERNAL__params__private__encryption="<32-byte hex>"
danger

Set this key before you create any keys, and do not change it afterwards. Keys stored before a change can no longer be read, and there is currently no procedure for re-encrypting them.

Store this key in a secure location outside your installation. If it is lost, keys in INTERNAL storage cannot be recovered.

OpenID4VCI encryption keys​

When Core holds credentials, these keys encrypt the access and refresh tokens it receives from issuers. Each OpenID4VCI issuance protocol instance requires its own key:

ONE_issuanceProtocol__OPENID4VCI_FINAL1__params__private__encryption="<32-byte hex>"
ONE_issuanceProtocol__OPENID4VCI_FINAL1_SWIYU__params__private__encryption="<32-byte hex>"
ONE_issuanceProtocol__OPENID4VCI_FINAL1_HAIP__params__private__encryption="<32-byte hex>"

If you change a key, stored tokens can no longer be used. Credentials already held continue to work, but they can no longer be refreshed and new batches cannot be requested.

OpenID4VCI nonce signing keys​

Sign the nonces used during issuance. Each OpenID4VCI issuance protocol instance requires its own key:

ONE_issuanceProtocol__OPENID4VCI_FINAL1__params__private__nonce__signingKey="<32-byte hex>"
ONE_issuanceProtocol__OPENID4VCI_FINAL1_SWIYU__params__private__nonce__signingKey="<32-byte hex>"
ONE_issuanceProtocol__OPENID4VCI_FINAL1_HAIP__params__private__nonce__signingKey="<32-byte hex>"

Changing a key only affects issuance flows in progress at the time of the change.

Signing keys​

The BFF and WRPR sign tokens and responses with Ed25519 private keys in PKCS #8 format.

STS signing key​

The BFF signs the tokens issued by its Secure Token Service (STS) with this key:

sts.token.privateKey="<Ed25519 private key, one line>"

Changing the key invalidates all operator sessions and issued STS tokens. Services that validate STS tokens cache the BFF's public keys, so tokens signed with the previous key may be accepted for a short time after the change.

WRPR signing key​

WRPR signs its public API responses with this key:

public.api.signing.privateKey="<Ed25519 private key, one line>"

After a change, WRPR signs all new responses with the new key.

Static tokens​

In the starter setup, Core, Bridge, and WRPR accept requests authenticated with a static token. Each token appears in the receiving service's configuration and in the configuration of every service that calls it. Change all occurrences together:

TokenSet in the serviceSet in each caller
CoreONE_app__auth__staticToken (.core.env)core.api.staticToken (.bff.env, .bridge.env, .wrpr.env)
Bridgeauth.staticToken (.bridge.env)bridge.api.staticToken (.bff.env)
WRPRauth.staticToken (.wrpr.env)wrpr.api.staticToken (.bff.env)

Static tokens are for development and testing. For production, replace them with STS authentication.

oauth2-proxy encrypts operator session cookies with cookie_secret in oauth2-proxy.cfg. Changing it signs out all operators.

Identity provider credentials​

The services authenticate to the identity provider with client secrets:

ClientWhere the secret is set
Login client, used by oauth2-proxyclientSecret (alpha-config.yml)
Technical client, used by BFF, Bridge, and WRPRauth.technicalUserCredentials.clientSecret (.bff.env); spring.security.oauth2.client.registration.keycloakClient.client-secret (.bridge.env, .wrpr.env)

When you connect your own identity provider, it issues new client secrets.

Starter Keycloak​

If you keep the starter Keycloak running while you test, change its shared defaults in the Keycloak admin console:

  1. Change the admin password. The default is admin / admin.

  2. Change the password of example_user, or delete the user.

  3. Regenerate the secrets of login-client and one-bff, then update the files listed above.

Database and cache credentials​

Each database has a user password and a root password. The user password appears in both the database's configuration and the service's configuration:

DatabaseDatabase configurationService configuration
Core.core_mariadb.envONE_app__databaseUrl (.core.env)
BFF.bff_mariadb.envMYSQL_PASSWORD (.bff.env)
Bridge.bridge_mariadb.envMYSQL_PASSWORD (.bridge.env)
WRPR.wrpr_mariadb.envMYSQL_PASSWORD (.wrpr.env)
Keycloak.keycloak_postgres.envKEYCLOAK_DATABASE_PASSWORD (.keycloak.env)

Redis runs without a password in the starter setup.

The database images set passwords only when the database is first created. To change passwords on an existing database, change them in the database as well. See Databases.

Feature-specific secrets​

Some features require credentials for external services. They are empty in the starter setup and only needed if you enable the feature:

  • Remote key storage (keyStorage, for example Azure Key Vault): client credentials for the vault.
  • QES document signing (documentSignerProvider): client credentials for the signing provider. See Wallet-Centric Approach.
  • Email (spring.mail.username, spring.mail.password in .bff.env): SMTP credentials.

Where to keep secrets​

The quick start stores secrets in plain text in configuration and environment files. For any shared or long-running installation:

  • Do not commit files that contain real secrets to version control.
  • Supply secrets from your platform's secret store, such as Docker secrets, Kubernetes secrets, or a vault.
  • Keep secrets separate from other configuration, so the rest of your configuration can be shared and versioned.

For Core, one way to keep secrets separate is a dedicated configuration file passed as the last --config. Core merges it like any other layer. See Configuring Your Installation.