Skip to content

Client Bootstrap Configuration

Chronicle supports declarative client configuration, allowing clients (clientId/clientSecret pairs) to be defined at startup via configuration or secrets management, rather than exclusively through the Workbench UI.

{
"clients": [
{
"clientId": "my-service",
"clientSecret": "a-strong-secret-value"
},
{
"clientId": "another-service",
"clientSecret": "another-secret-value"
}
]
}
Terminal window
Cratis__Chronicle__Clients__0__ClientId=my-service
Cratis__Chronicle__Clients__0__ClientSecret=a-strong-secret-value
Cratis__Chronicle__Clients__1__ClientId=another-service
Cratis__Chronicle__Clients__1__ClientSecret=another-secret-value
PropertyTypeRequiredDescription
clientIdstringYesThe client identifier used for authentication
clientSecretstringYesThe client secret in plaintext. Hashed internally on load
  1. On startup, Chronicle reads the clients array from configuration
  2. For each client, the secret is hashed using ASP.NET Core’s PasswordHasher
  3. The raw secret is never retained in memory beyond the bootstrap phase
  4. If a client with the same clientId already exists, it is skipped (not overwritten)
  5. Bootstrap clients are visible in the Workbench UI alongside manually created clients
  6. The Workbench UI continues to support adding and revoking clients at runtime

The clientSecret is provided as plaintext in configuration. In production, use a proper secrets management solution:

Terminal window
# Store secret in Key Vault
az keyvault secret set --vault-name my-vault --name chronicle-client-secret --value "strong-secret"
# Reference in environment variable
Cratis__Chronicle__Clients__0__ClientId=my-service
Cratis__Chronicle__Clients__0__ClientSecret=@Microsoft.KeyVault(SecretUri=https://my-vault.vault.azure.net/secrets/chronicle-client-secret)
apiVersion: v1
kind: Secret
metadata:
name: chronicle-clients
type: Opaque
stringData:
client-secret: "strong-secret-value"
---
apiVersion: apps/v1
kind: Deployment
spec:
template:
spec:
containers:
- name: chronicle
env:
- name: Cratis__Chronicle__Clients__0__ClientId
value: "my-service"
- name: Cratis__Chronicle__Clients__0__ClientSecret
valueFrom:
secretKeyRef:
name: chronicle-clients
key: client-secret
services:
chronicle:
image: cratis/chronicle:latest
environment:
- Cratis__Chronicle__Clients__0__ClientId=my-service
- Cratis__Chronicle__Clients__0__ClientSecret=${CLIENT_SECRET}

Relationship with Workbench-managed clients

Section titled “Relationship with Workbench-managed clients”
  • Bootstrap clients and Workbench-managed clients coexist
  • Bootstrap clients are registered as regular applications visible in the Workbench
  • If a bootstrap client already exists (matching clientId), it is not re-registered or overwritten
  • Clients created through the Workbench can be revoked through the Workbench; bootstrap clients will be re-created on next restart if removed