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)The @Microsoft.KeyVault(...) reference is resolved by Azure App Service and Azure Functions when you set it as an application setting — Chronicle does not resolve it. On any other platform the literal text would be used as the value, so inject the resolved secret through that platform’s secret mechanism instead, as in the Kubernetes example below.
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