Skip to content

This guide shows you how to keep secret values in an external store and let Sluice read them when a task starts. You add a provider, create a secret that holds a reference, and check that the reference resolves.

A provider turns a reference into a value. Sluice reads from the store and never writes to it.

Type UI name Configuration Reference Credentials
builtin Builtin None. It always exists. None. Sluice stores the value, encrypted. SLUICE_MASTER_KEYS
env Environment None. It always exists. NAME: Sluice reads SLUICE_SECRET_<NAME>. Default: the secret key. The environment of the server process.
vault HashiCorp Vault mount (default secret), address (optional) path#field in a KV version 2 mount SLUICE_VAULT_TOKEN, or SLUICE_VAULT_K8S_ROLE
azure_key_vault Azure Key Vault vault_url (required, https://) name or name/version DefaultAzureCredential: the AZURE_* variables, workload identity or managed identity.
kubernetes Kubernetes namespace (optional) secret-name/key The service account of the server pod, or SLUICE_K8S_KUBECONFIG.

The configuration of a provider holds no credentials. Sluice accepts only the fields in the table, and it refuses any other field with 422 validation_failed. The credentials come only from the environment of the server.

Set the credentials on every server instance. Any instance can dispatch a task, so any instance can resolve a secret.

You need the admin role. builtin and env always exist, so you add only vault, azure_key_vault and kubernetes.

  1. Set the credentials in the server environment and restart the instances. See the tabs below.

  2. Open Settings → Secret providers and click Add provider.

  3. Type a Name, for example vault-prod. A name has lower-case letters, digits, - and _, and starts with a letter or a digit.

  4. Select the Type and fill in its fields.

  5. Click Add provider.

  6. Click Check in the row of the provider. Type a Reference and click Check. The dialog shows whether the reference resolves, and never the value.

The vault provider reads HashiCorp Vault KV version 2. The reference data/postgres#url reads the field url at the path data/postgres of the mount.

Item Source
Address The provider field Address, else SLUICE_VAULT_ADDR. One of them must be set.
Mount The provider field KV v2 mount. Default secret.
Token auth SLUICE_VAULT_TOKEN. It wins when it is set.
Kubernetes auth SLUICE_VAULT_K8S_ROLE. Sluice logs in at auth/kubernetes/login with the token of the pod service account.

With Kubernetes auth, Sluice logs in again at three quarters of the lease, and once after a 401 or 403 answer. It reads the service account token file at each login, so a rotated token works.

A field that is not a string resolves to its JSON text.

Terminal window
SLUICE_VAULT_ADDR=https://vault.example.com:8200
SLUICE_VAULT_K8S_ROLE=sluice

The API offers the same operations:

Terminal window
curl -X POST "$SLUICE_URL/api/v1/secret-providers" \
-H "Authorization: Bearer $SLUICE_TOKEN" -H "Content-Type: application/json" \
-d '{"name": "vault-prod", "type": "vault", "config": {"mount": "kv"}}'
curl -X POST "$SLUICE_URL/api/v1/secret-providers/vault-prod/check" \
-H "Authorization: Bearer $SLUICE_TOKEN" -H "Content-Type: application/json" \
-d '{"ref": "data/postgres#url"}'

A flow never names a provider. It reads ${{ secret('PG_URL') }}, and the secret PG_URL decides where the value comes from.

  1. Open the Secrets tab of the namespace, or Secrets in the side bar for a global secret.

  2. Click Add secret and type the Key, for example PG_URL.

  3. Select the Provider, for example vault-prod.

  4. Type the Reference, for example data/postgres#url, and save.

  5. Click Check in the row of the secret. The check resolves the secret of exactly that scope.

Terminal window
curl -X PUT "$SLUICE_URL/api/v1/secrets/PG_URL" \
-H "Authorization: Bearer $SLUICE_TOKEN" -H "Content-Type: application/json" \
-d '{"provider": "vault-prod", "ref": "data/postgres#url"}'

An external secret stores only the reference. A request with a value returns 422 validation_failed. A reference has at most 512 characters.

Check on a provider or on a secret returns one status. The message explains a failure and never holds the value.

Status Meaning What to do
ok The reference resolves. Nothing.
not_found The store has no value for the reference. Check the path, the field, the name or the key.
access_denied The store refused access, for example a Vault 403. Give the identity of the server the right to read the value.
provider_error Another error, for example a network error or no Vault address. Check the address and the credentials in the server environment.

A check of an inherited key returns 404 secret_not_found. Check it in its own scope.

At dispatch, not_found fails the task with reason secret_not_found. The other errors fail it with secret_provider_error.

Sluice keeps resolved vault, azure_key_vault and kubernetes values in memory on each instance for SLUICE_SECRET_CACHE_TTL, 60 seconds by default. A change in the store reaches later tasks after at most that time, without a restart. A change of the provider configuration takes effect at once. Sluice does not cache builtin and env values.

Rule Result
A second provider with the same name 409 provider_exists
A change or delete of builtin or env 409 provider_fixed
A delete of a provider that a secret uses 409 provider_in_use. Move or delete those secrets first.