Secrets
Client secrets, SMTP passwords and signing keys never sit in an environment file in clear text. Like Pulumi, each environment chooses a secrets provider when it is created.
cratis env init production # passphrase (default)cratis env init production --secrets-provider azurekeyvault://my-vaultcratis env init production --secrets-provider hashivault://vault.example.com:8200/secret/cratisSetting and reading secrets
Section titled “Setting and reading secrets”A secret is never taken from a command-line argument, so it stays out of shell history. Pipe it in, or run the command in a terminal and type it at the hidden prompt.
echo -n "$SMTP_PASSWORD" | cratis config set smtp:password --secretcratis config set smtp:password --secret # prompts, hiddencratis config get smtp:password # [secret]cratis config get smtp:password --show-secret # the valueNo command prints a secret to stdout, stderr, a log or JSON output unless you pass --show-secret.
Passphrase provider
Section titled “Passphrase provider”The default. Secrets are encrypted inline with AES-256-GCM:
- The key is derived from your passphrase and a random per-environment salt (
encryptionSalt) with PBKDF2-SHA256. The algorithm and iteration count (600,000 by default) are recorded in the file, so they can change later. Two environments with the same passphrase get different salts and different ciphertext. - Each value is stored as
secure: <base64>(nonce, tag and ciphertext) and is bound to its key, so moving a ciphertext to another key fails. - A verification value in the file makes a wrong passphrase fail cleanly with exit code
4, before anything is decrypted.
The passphrase is read from, in order, CRATIS_PASSPHRASE, the file named by CRATIS_PASSPHRASE_FILE, or a hidden prompt. It is never written anywhere. A file with only secure: values is safe to commit.
Changing the passphrase
Section titled “Changing the passphrase”cratis env change-passphrase -e productionEvery secret is decrypted with the current passphrase and re-encrypted under the new one with a new salt. The new passphrase comes from CRATIS_NEW_PASSPHRASE, CRATIS_NEW_PASSPHRASE_FILE or a prompt.
Azure Key Vault provider
Section titled “Azure Key Vault provider”azurekeyvault://<vault> - a vault name (my-vault means https://my-vault.vault.azure.net) or a full vault host or URL. Values are stored in the vault as secrets named cratis-<environment>-<key> with a short hash suffix; the file holds the name as ref:. Authentication uses DefaultAzureCredential: Azure CLI login, managed identity or workload identity.
HashiCorp Vault provider
Section titled “HashiCorp Vault provider”hashivault://<address>/<mount>[/<path>] - for example hashivault://vault.example.com:8200/secret/cratis. Secrets are stored in the KV v2 mount at <path>/<environment>/<key> (the path defaults to cratis); the file holds that path as ref:. hashivault+http:// selects plain HTTP for a development server.
Authentication is chosen from the environment:
| Method | Variables |
|---|---|
| Token | VAULT_TOKEN |
| AppRole | VAULT_ROLE_ID, VAULT_SECRET_ID |
| Kubernetes | VAULT_K8S_ROLE, and the service account token from VAULT_K8S_TOKEN_FILE (default /var/run/secrets/kubernetes.io/serviceaccount/token) |
VAULT_AUTH_MOUNT overrides the auth method mount and VAULT_NAMESPACE sets the Vault namespace.
Changing the provider
Section titled “Changing the provider”cratis env change-secrets-provider azurekeyvault://my-vault -e productionEvery secret is read with the current provider, stored with the new one, and the previous material is removed - the file never holds clear text in between, and moving to a vault replaces secure: values with ref: entries. Moving back to passphrase asks for a new passphrase.