Skip to main content

Configuration Reference

Both the STS (Security Token Service) and Auth Bridge services are configured through application.yml files, with all custom properties nested under the sphereon.app.* prefix. Environment variables can be interpolated into the configuration using the ${env:VARIABLE_NAME:default_value} syntax, where the portion after the colon is the fallback value used when the environment variable is not set. Secrets are referenced via indirect references (*-ref.key) that resolve to environment variables at runtime, ensuring no plaintext secrets ever appear in configuration files.

This page provides a comprehensive reference for all configuration properties, organized by service and by functional section within each service.

Configuration Structure

The general structure of an application.yml file follows this pattern:

sphereon:
app:
section:
property: value
nested-section:
property: "${env:ENV_VAR:default_value}"

Environment variable interpolation is resolved at application startup. This approach allows the same configuration file to be used across environments (development, staging, production) by varying only the environment variables.

Configuration Precedence

Configuration values are resolved in the following order of precedence (highest to lowest):

  1. Environment variables set on the process or container
  2. System properties passed via -D JVM flags
  3. application.yml values in the working directory
  4. application.yml values bundled in the JAR
  5. Default values specified in the ${env:VAR:default} syntax

STS Configuration

The STS service handles OAuth2 authorization server functionality, token issuance, and federation with upstream identity providers. Its configuration is organized into the following sections.

OAuth2 Server Settings

These properties control the behavior of the OAuth2 authorization server built into the STS.

sphereon:
app:
oauth2:
servers:
primary:
mode: "HOSTED"
issuer: "${env:STS_ISSUER_URL:http://localhost:8092}"
access-token-lifetime-seconds: 3600 # 1 hour
refresh-token-lifetime-seconds: 86400 # 24 hours
id-token-lifetime-seconds: 3600 # 1 hour
pkce-mode: "REQUIRED" # Always require PKCE
dpop-mode: "DISABLED" # Disabled for PoC
token-exchange-mode: "SUPPORTED" # RFC 8693
introspection-mode: "SUPPORTED" # RFC 7662
PropertyDefaultDescription
modeHOSTEDServer mode. HOSTED means the STS operates as a full OAuth2 authorization server capable of issuing tokens.
issuerhttp://localhost:8092The issuer URL included in all issued tokens. Must match the externally reachable URL of the STS. This value appears in the iss claim of JWT tokens and must be consistent with the OIDC discovery document at /.well-known/openid-configuration.
access-token-lifetime-seconds3600Lifetime of access tokens in seconds (1 hour). After this period, clients must use a refresh token or re-authenticate.
refresh-token-lifetime-seconds86400Lifetime of refresh tokens in seconds (24 hours).
id-token-lifetime-seconds3600Lifetime of ID tokens in seconds (1 hour).
pkce-modeREQUIREDPKCE (Proof Key for Code Exchange) enforcement level. Valid values: REQUIRED (all clients must use PKCE), SUPPORTED (PKCE accepted but not mandatory), DISABLED. Should always be REQUIRED in production to prevent authorization code interception attacks.
dpop-modeDISABLEDDPoP (Demonstrating Proof of Possession) enforcement. REQUIRED provides sender-constrained tokens that cannot be replayed by an attacker who intercepts them. Recommended for production but disabled in the proof-of-concept configuration.
token-exchange-modeSUPPORTEDRFC 8693 token exchange support. Allows clients to exchange one token type for another.
introspection-modeSUPPORTEDRFC 7662 token introspection support. Allows resource servers to validate tokens by calling the STS.

STS Client Registrations

Each registered OAuth2 client is configured under oauth2.servers.clients. Client registrations define which applications are permitted to request tokens from the STS and under what conditions.

          clients:
- client-id: "portal"
client-secret-ref:
key: "STS_CLIENT_SECRET"
redirect-uris:
- "${env:FRONTEND_URL:http://localhost:3000}/api/auth/callback/sts"
- "${env:FRONTEND_URL:http://localhost:3000}/api/auth/callback/sts-wallet"
scopes: ["openid", "profile", "email"]
grant-types: ["authorization_code", "refresh_token"]
PropertyDescription
client-idUnique identifier for the client application. Used in authorization requests and token exchanges.
client-secret-ref.keyEnvironment variable name containing the client secret. The STS reads the value from this environment variable at runtime. Never hardcode the secret in the YAML file.
redirect-urisList of allowed redirect URIs for the authorization code flow. The STS rejects authorization requests with redirect URIs not in this list. Supports environment variable interpolation for the base URL.
scopesAllowed scopes that this client may request. Requests for scopes not in this list are rejected.
grant-typesAllowed OAuth2 grant types. Common values are authorization_code (for interactive browser flows) and refresh_token (for silent token renewal).

Federation Providers

Federation providers are upstream identity providers that the STS delegates authentication to. When a user chooses to authenticate via SURF or Keycloak, the STS acts as an OIDC relying party to the selected upstream provider.

    federation:
providers:
surf:
issuer-url: "${env:SURF_ISSUER_URL:https://connect.test.surfconext.nl}"
client-id-ref:
key: "FEDERATION_CLIENT_ID"
client-secret-ref:
key: "FEDERATION_CLIENT_SECRET"
provider-id: "env"
scopes: ["openid", "profile", "email", "eduid"]
user-info-enabled: true
state-mode: "JWT"

keycloak:
enabled: "${env:KEYCLOAK_ENABLED:false}"
issuer-url: "${env:KEYCLOAK_ISSUER_URL:http://localhost:8083/realms/portal}"
client-id-ref:
key: "KEYCLOAK_CLIENT_ID"
client-secret-ref:
key: "KEYCLOAK_CLIENT_SECRET"
provider-id: "env"
scopes: ["openid", "profile", "email"]
PropertyDefaultDescription
issuer-url--OIDC issuer URL of the upstream provider. The STS appends /.well-known/openid-configuration to discover endpoints.
client-id-ref.key--Environment variable containing the OIDC client ID registered with this provider.
client-secret-ref.key--Environment variable containing the OIDC client secret.
client-secret-ref.provider-idenvSecret provider type. env reads from an environment variable.
scopes["openid"]Scopes to request from the upstream provider. SURF supports the eduid scope for eduID-specific claims.
user-info-enabledfalseWhether to call the provider's UserInfo endpoint after token exchange to obtain additional claims.
state-modeRANDOMHow to generate the OIDC state parameter. JWT encodes session metadata in the state as a signed JWT; RANDOM uses a random opaque string.
enabledtrueWhether this provider is active. Set to false to disable without removing the configuration.

STS Auth Bridge Delegation

The STS delegates wallet-based authentication (OID4VP flows) to the Auth Bridge service. When a user presents a verifiable credential from their wallet, the STS forwards the presentation to the Auth Bridge for verification and identity matching.

    oid4vp:
auth-bridge:
base-url: "${env:AUTH_BRIDGE_URL:http://localhost:8090}"
default-query-id: "portal-eduid-vc"
PropertyDefaultDescription
oid4vp.auth-bridge.base-urlhttp://localhost:8090Internal base URL of the Auth Bridge service. Used for service-to-service communication.
oid4vp.auth-bridge.default-query-idportal-eduid-vcThe default DCQL query identifier to use when initiating OID4VP sessions. References a query defined in the Auth Bridge configuration.

Identity Reconciliation Attribute Rules (STS)

The STS includes attribute rules that control how claims from different sources are assembled into tokens. These rules determine which claims appear in ID tokens and access tokens issued to clients.

See the Canonical Attribute Rules section below for the full definition and attribute table.


Auth Bridge Configuration

The Auth Bridge service is the core of the identity matching and reconciliation system. Its configuration is more extensive than the STS, covering OID4VP session management, cryptographic key management, reconciliation provider setup, database access, external API security, and data lifecycle management.

OID4VP Settings

These settings control how the Auth Bridge handles verifiable presentation sessions initiated by wallets.

sphereon:
app:
oid4vp:
universal:
external-base-url: "${env:AUTH_BRIDGE_EXTERNAL_URL:http://localhost:8090}"
auth-bridge:
session-ttl-seconds: 300 # 5-minute session timeout
require-reconciliation: true
PropertyDefaultDescription
oid4vp.universal.external-base-urlhttp://localhost:8090The externally reachable base URL of the Auth Bridge. Used to construct authorization request URLs that are sent to wallets. Must be publicly accessible when wallets are external devices.
oid4vp.auth-bridge.session-ttl-seconds300Lifetime in seconds of an OID4VP presentation session. After this period, the session expires and cannot be completed. The wallet holder must start a new session.
oid4vp.auth-bridge.require-reconciliationtrueWhether identity reconciliation is mandatory. When true, wallet holders must complete the reconciliation flow (linking to an institutional identity) before a binding is created. When false, bindings are created from wallet data alone.

DCQL Queries

DCQL (Digital Credentials Query Language) queries define what credential types and claims the Auth Bridge requests from wallets during OID4VP sessions.

    oid4vp:
dcql-queries:
portal-eduid-vc:
credential-type: "eu.europa.ec.eudi.pid.1"
claims:
- "family_name"
- "given_name"
- "birth_date"
- "issuance_date"

Each query is identified by a unique ID (e.g., portal-eduid-vc) and specifies the credential type to request and the list of claims that should be included in the presentation. The STS references these query IDs when delegating OID4VP flows to the Auth Bridge.

KMS (Key Management Service)

The KMS configuration determines where cryptographic keys are stored and how the Auth Bridge accesses them. The system supports multiple KMS providers, allowing development environments to use a software-based keystore while production environments use a hardware-backed cloud KMS.

Software Provider (Development)

    kms:
providers:
- id: "software"
type: "SOFTWARE"
config:
keystore-path: "data/keystore/auth-bridge.p12"
keystore-password-ref:
key: "KMS_KEYSTORE_PASSWORD"

The software provider stores keys in a PKCS#12 keystore file on the local filesystem. This is convenient for development but provides no hardware protection for key material and should never be used in production.

Azure Key Vault Provider (Production)

    kms:
providers:
- id: "azure"
type: "AZURE_KEY_VAULT"
config:
vault-url: "https://your-vault.vault.azure.net"
tenant-id: "${env:AZURE_TENANT_ID}"
client-id: "${env:AZURE_CLIENT_ID}"
client-secret-ref:
key: "AZURE_CLIENT_SECRET"
PropertyDescription
vault-urlAzure Key Vault URL.
tenant-idAzure AD tenant ID for authentication.
client-idAzure AD application (service principal) client ID.
client-secret-ref.keyEnvironment variable containing the Azure AD client secret.

Azure Key Vault provides HSM-backed key storage, ensuring that key material never leaves the hardware security module boundary. Cryptographic operations (HMAC, encrypt, decrypt) are performed within the HSM.

Cryptographic Key Configuration

Three domain-separated keys are used throughout the system. Each key is referenced by an alias (its name in the KMS) and a version number that tracks key rotation.

    identity:
reconciliation:
crypto:
holder-hmac-key-alias: "reconciliation:holder"
holder-hmac-key-version: 1
institution-hmac-key-alias: "reconciliation:institution"
institution-hmac-key-version: 1
encryption-key-alias: "reconciliation:encryption"
encryption-key-version: 1
# Uncomment during key rotation:
# previous-holder-hmac-key-alias: "reconciliation:holder-v1"
# previous-holder-hmac-key-version: 1
PropertyDefaultDescription
crypto.holder-hmac-key-alias--KMS key alias for Key A. Used for HMAC-SHA256 hashing of wallet/holder identifiers.
crypto.holder-hmac-key-version1Current version of Key A. Stored on records so the system knows which version to use for verification.
crypto.institution-hmac-key-alias--KMS key alias for Key B. Used for HMAC-SHA256 hashing of institution identifiers.
crypto.institution-hmac-key-version1Current version of Key B.
crypto.encryption-key-alias--KMS key alias for Key C. Used for AES-256-GCM encryption of sensitive data.
crypto.encryption-key-version1Current version of Key C.
crypto.previous-holder-hmac-key-alias--Previous Key A alias, used during key rotation. The system will attempt to verify hashes against both the current and previous key.
crypto.previous-holder-hmac-key-version--Previous Key A version.

Reconciliation Rules

The rule version is a date-stamped identifier that tracks when the reconciliation rules were last updated. This version is stored on each binding so that operators can determine which rule set was in effect when the binding was created.

        rule-version: "2026-03-24"
selector-rules:
- id: "default-surf"
enabled: true
priority: 0
plan:
type: "RUN_IDV"
provider-id: "surf"
material-profile-id: "holder-only-v1"

Selector Rules

Selector rules determine which reconciliation provider is used for a given identity match. Rules are evaluated in priority order (lowest number = highest priority), and the first matching enabled rule is selected.

PropertyDescription
selector-rules[].idUnique identifier for the rule.
selector-rules[].enabledWhether this rule is active.
selector-rules[].priorityEvaluation order (0 = highest priority).
selector-rules[].plan.typeAction type. RUN_IDV initiates identity verification with an upstream provider.
selector-rules[].plan.provider-idWhich reconciliation provider to use (must match a provider ID in the providers list).
selector-rules[].plan.material-profile-idWhich material profile to apply for determining binding staleness.

Material Profiles

Material profiles define which attributes are considered "material" -- that is, which attributes are significant enough that a change in their values should trigger re-reconciliation of the binding.

        material-profiles:
- id: "holder-only-v1"
version: "1"
materials:
- type: "holder_key_fp"
hmac-domain: "holder"
PropertyDescription
material-profiles[].idUnique identifier for the profile.
material-profiles[].versionVersion of this profile. Stored on bindings for traceability.
material-profiles[].materialsList of material definitions. Each material specifies a type and the HMAC domain used for fingerprinting.

Reconciliation Providers

Each reconciliation provider represents an upstream identity verification source (such as SURF) that users authenticate with to link their wallet identity to an institutional identity.

        oidc-clients:
surf-oidc:
discovery-url: "https://connect.test.surfconext.nl/.well-known/openid-configuration"
client-id-ref:
key: "IDENTITY_RECONCILIATION_PROVIDERS_SURF_CLIENT_ID"
client-secret-ref:
key: "IDENTITY_RECONCILIATION_PROVIDERS_SURF_CLIENT_SECRET"
provider-id: "env"
scopes: ["openid", "profile", "email", "eduid"]
user-info-enabled: true

providers:
- id: "surf"
name: "SURFconext"
oidc-client-id: "surf-oidc"
identifier-attribute-name: "sub"
enabled: true

The configuration separates OIDC client settings (oidc-clients) from provider definitions (providers). This allows multiple providers to share the same OIDC client if needed, or for a provider to be reconfigured to use a different OIDC client without changing its identity.

PropertyDefaultDescription
oidc-clients[].discovery-url--OIDC discovery endpoint URL for automatic endpoint discovery.
oidc-clients[].client-id-ref.key--Environment variable containing the OIDC client ID.
oidc-clients[].client-secret-ref.key--Environment variable containing the OIDC client secret.
oidc-clients[].scopes["openid"]Scopes to request during reconciliation.
oidc-clients[].user-info-enabledfalseWhether to call UserInfo for additional claims.
providers[].id--Unique provider identifier. Referenced by selector rules and stored on bindings.
providers[].name--Display name shown to users during the reconciliation flow.
providers[].oidc-client-id--References an OIDC client definition from the oidc-clients section.
providers[].identifier-attribute-namesubThe claim name to use as the institution identifier. The value of this claim is HMAC-hashed with Key B and stored as institution_identifier_hash.
providers[].enabledtrueWhether this provider is currently active.

Database

    database:
url: "${env:DATABASE_URL:jdbc:postgresql://localhost:5432/authbridge}"
username: "${env:DATABASE_USERNAME:postgres}"
password-ref:
key: "DATABASE_PASSWORD"
max-pool-size: 5
PropertyDefaultDescription
database.urljdbc:postgresql://localhost:5432/authbridgeJDBC connection URL for the Auth Bridge database.
database.usernamepostgresDatabase username.
database.password-ref.key--Environment variable containing the database password.
database.max-pool-size5Maximum number of connections in the connection pool. Tune based on expected concurrency.

External API

The external API allows authorized third-party systems to look up identity information. Access is controlled through JWT bearer tokens and client-specific attribute projections.

    external-api:
enabled: true
jwt:
issuer: "${env:EXTERNAL_API_JWT_ISSUER:http://keycloak:8080/realms/portal}"
jwks-uri: "${env:EXTERNAL_API_JWT_JWKS_URI}"
clients:
api:
scopes: ["reconciliation:read"]
projected-claims: ["eduid", "eduperson_principal_name", "email"]
auxiliary-categories: ["enrollment", "role"]
PropertyDefaultDescription
external-api.enabledtrueWhether the external API is active.
external-api.jwt.issuer--Expected iss claim in JWT bearer tokens. Tokens from other issuers are rejected.
external-api.jwt.jwks-uri--JWKS endpoint URL for validating JWT signatures. The Auth Bridge fetches the signing keys from this endpoint.
external-api.clients[].scopes--Required scopes in the JWT token for this client.
external-api.clients[].projected-claims--List of canonical attribute names this client is allowed to receive in identity lookup responses. Claims not in this list are filtered out even if they exist on the binding.
external-api.clients[].auxiliary-categories--List of auxiliary data categories this client may access. Requests for categories not in this list are denied.

Client projections implement the principle of least privilege at the data level. Each API consumer sees only the attributes they need, even though the system may have more data available for the identity.

Retention and Cleanup

        retention:
inactive-days: 730 # 2-year inactivity threshold
soft-delete-days: 30 # 30-day soft-delete retention
cleanup-interval-minutes: 60 # Inactivity check frequency

session-cleanup:
interval-minutes: 5 # Expired session cleanup frequency

session-ttl-seconds: 300 # Reconciliation session timeout
PropertyDefaultDescription
retention.inactive-days730Number of days of inactivity after which a binding is soft-deleted. Based on the last_used_at timestamp.
retention.soft-delete-days30Number of days a soft-deleted record is retained before permanent hard deletion.
retention.cleanup-interval-minutes60How often (in minutes) the background job checks for inactive bindings.
session-cleanup.interval-minutes5How often (in minutes) the background job cleans up expired reconciliation sessions.
session-ttl-seconds300Default lifetime of a reconciliation session in seconds.

Canonical Attribute Rules

Attribute rules control how claims from different sources (wallet credentials and OIDC providers) are merged, which claims are persisted in the encrypted binding envelope, and which claims are projected into STS tokens and API responses. Both the STS and Auth Bridge have attribute rules: the Auth Bridge rules govern persistence, while the STS rules govern token projection.

Merge Modes

ModeBehavior
OIDC_WINSUse the OIDC provider's value if available; fall back to the wallet credential value if the OIDC provider does not supply this claim. This is the default for most attributes, reflecting the higher assurance of institutionally verified data.
WALLET_ONLYOnly use values from the wallet credential. OIDC provider values for this claim are ignored. Appropriate for claims that are inherent to the wallet identity itself.
OIDC_ONLYOnly use values from the OIDC provider. Wallet credential values for this claim are ignored. Used for claims like eduid and sub that are definitionally tied to the institution.

Auth Bridge Attribute Rules (Persistence)

The following table shows the complete set of canonical attributes as configured for the Auth Bridge. The persist column determines whether the attribute is stored (encrypted) in the binding's persisted_attributes_envelope. The project column determines whether the attribute is included in API responses and STS token assembly.

Canonical NameMerge ModePersistProjectSource Aliases
eduidOIDC_ONLYtruetrueeduid
eduperson_principal_nameOIDC_WINStruetrueeduperson_principal_name, urn:mace:dir:attribute-def:eduPersonPrincipalName
emailOIDC_WINStruetrueemail
given_nameOIDC_WINSfalsetruegiven_name
family_nameOIDC_WINSfalsetruefamily_name
subOIDC_ONLYtruetruesub
schac_home_organizationOIDC_ONLYtruetrueschac_home_organization
eduperson_affiliationOIDC_WINStruetrueeduperson_affiliation
eduperson_scoped_affiliationOIDC_WINStruetrueeduperson_scoped_affiliation

The data minimization principle is visible in the persist column: given_name and family_name have persist: false. These personally identifiable information (PII) fields are available during the active session -- they flow through the system and may appear in tokens issued by the STS -- but they are never written to the database. If the database is compromised, an attacker will find no names or other directly identifying PII, only encrypted institutional identifiers and affiliation data.

Source Aliases

The Source Aliases column lists all claim names that map to a given canonical attribute. Different OIDC providers may use different claim names for the same concept (e.g., eduperson_principal_name vs. the URN-based urn:mace:dir:attribute-def:eduPersonPrincipalName). The attribute mapping normalizes these into a single canonical name.


Secret References

Secrets are never stored in configuration files. Instead, they use indirect references that are resolved at runtime from environment variables:

# Reference an environment variable
client-secret-ref:
key: "ENVIRONMENT_VARIABLE_NAME"
provider-id: "env" # Optional, defaults to env

# The service reads the secret at runtime:
# System.getenv("ENVIRONMENT_VARIABLE_NAME")

This indirection pattern ensures that application.yml files can be safely committed to version control without exposing credentials. The actual secret values live exclusively in the runtime environment.

Production Secret Management

For production deployments, populate the environment variables from a dedicated secrets manager:

  • Azure Key Vault: Use the Azure Key Vault CSI driver (Kubernetes) or Azure App Service key references to inject secrets as environment variables.
  • AWS Secrets Manager: Use the AWS Secrets and Config Provider for Kubernetes, or ECS task definition secrets.
  • HashiCorp Vault: Use the Vault Agent sidecar or CSI provider to inject secrets.
  • Kubernetes Secrets: As a baseline, create Kubernetes Secret objects and reference them in pod specifications:
# In Kubernetes, the environment variable is populated from a Secret:
# envFrom:
# - secretRef:
# name: portal-secrets

Never commit .env files, .pem files, .key files, or any other files containing plaintext secrets to version control. The repository's .gitignore should include entries for all such file patterns.