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.
Configuration
Section titled “Configuration”Configuration file
Section titled “Configuration file”{ "clients": [ { "clientId": "my-service", "clientSecret": "a-strong-secret-value" }, { "clientId": "another-service", "clientSecret": "another-secret-value" } ]}Environment variables
Section titled “Environment variables”Cratis__Chronicle__Clients__0__ClientId=my-serviceCratis__Chronicle__Clients__0__ClientSecret=a-strong-secret-valueCratis__Chronicle__Clients__1__ClientId=another-serviceCratis__Chronicle__Clients__1__ClientSecret=another-secret-valueProperties
Section titled “Properties”| Property | Type | Required | Description |
|---|---|---|---|
| clientId | string | Yes | The client identifier used for authentication |
| clientSecret | string | Yes | The client secret in plaintext. Hashed internally on load |
How it works
Section titled “How it works”- On startup, Chronicle reads the
clientsarray from configuration - For each client, the secret is hashed using ASP.NET Core’s
PasswordHasher - The raw secret is never retained in memory beyond the bootstrap phase
- If a client with the same
clientIdalready exists, it is skipped (not overwritten) - Bootstrap clients are visible in the Workbench UI alongside manually created clients
- The Workbench UI continues to support adding and revoking clients at runtime
Secret management
Section titled “Secret management”The clientSecret is provided as plaintext in configuration. In production, use a proper secrets management solution:
Azure Key Vault
Section titled “Azure Key Vault”# Store secret in Key Vaultaz keyvault secret set --vault-name my-vault --name chronicle-client-secret --value "strong-secret"
# Reference in environment variableCratis__Chronicle__Clients__0__ClientId=my-serviceCratis__Chronicle__Clients__0__ClientSecret=@Microsoft.KeyVault(SecretUri=https://my-vault.vault.azure.net/secrets/chronicle-client-secret)Kubernetes Secrets
Section titled “Kubernetes Secrets”apiVersion: v1kind: Secretmetadata: name: chronicle-clientstype: OpaquestringData: client-secret: "strong-secret-value"---apiVersion: apps/v1kind: Deploymentspec: 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-secretDocker Compose with secrets
Section titled “Docker Compose with secrets”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