Kestra Security and Secrets Configuration

Use this page when you need to protect sensitive values or harden a Kestra deployment.

Encryption

This is the minimum security configuration most self-managed instances should think about early, because it determines whether sensitive flow values can be stored safely at rest.

Kestra supports encryption of sensitive inputs and outputs at rest through kestra.encryption.secret-key.

Example:

kestra:
encryption:
secret-key: BASE64_ENCODED_STRING_OF_32_CHARACTERS

Generate a key with:

openssl rand -base64 32

Without kestra.encryption.secret-key, SECRET inputs and outputs fail at runtime because Kestra cannot encrypt the value at rest.

Example flow using SECRET types:

id: my_secret_flow
namespace: company.team
inputs:
- id: secret
type: SECRET
tasks:
- id: mytask
type: io.kestra.plugin.core.log.Log
message: task that needs the secret to connect to an external system
outputs:
- id: secret_output
type: SECRET
value: "{{ inputs.secret }}"

Secret backends

Choose the backend based on where your organization already stores secrets. In practice, most teams want Kestra to consume an existing cloud or Vault-based secret system rather than create a separate one just for workflows.

Kestra can be configured to use a secrets backend through kestra.secret.*.

This page covers:

  • AWS Secrets Manager
  • Azure Key Vault
  • Google Secret Manager
  • HashiCorp Vault
  • JDBC
  • secret tags
  • secret cache
  • isolation options

Base structure:

kestra:
secret:
type: azure-key-vault
azure-key-vault:
client-secret:
tenant-id: "id"
client-id: "id"
client-secret: "secret"
isolation:
enabled: true
denied-services:
- EXECUTOR

isolation is the key control to understand here: it limits which Kestra services are allowed to resolve secrets, which is useful when you want workers or executors to have narrower access than the whole platform.

Representative backend examples:

kestra:
secret:
type: aws-secret-manager
aws-secret-manager:
access-key-id: mysuperaccesskey
secret-key-id: mysupersecret-key
session-token: mysupersessiontoken
region: us-east-1
kestra:
secret:
type: google-secret-manager
google-secret-manager:
project: gcp-project-id
service-account: |
<service-account JSON>
kestra:
secret:
type: elasticsearch
elasticsearch:
secret: "a-secure-32-character-minimum-key"

Supported Vault auth methods include Userpass, Token, and AppRole. JDBC-backed secrets, secret tags, and secret caching are covered below.

JDBC secret backend

Use JDBC-backed secrets only when secrets must stay inside the same database boundary as Kestra and you do not already have a dedicated secret manager:

kestra:
secret:
type: jdbc
jdbc:
secret: "your-secret-key"

Secret tags

Some backends let you scope lookups with tags so the same secret manager can serve multiple environments:

kestra:
secret:
<secret-type>:
tags:
application: kestra-production

Tags are useful when secrets are selected by metadata rather than by one fixed path convention.

Secret cache

Caching reduces repeated secret-manager calls for frequently used values:

kestra:
secret:
cache:
enabled: true
maximum-size: 1000
expire-after-write: 60s

Use a cache when executions hit the same secret names repeatedly, but keep TTLs conservative if secret rotation happens often.

Secrets UI Configuration

Security settings

This section is about hardening the running platform rather than managing secret values. Reach for it when you are locking down access, controlling invitations and roles, or tuning how the server reacts to component health issues.

This group includes:

  • super-admin behavior
  • default roles
  • invitation expiration
  • password rules
  • server basic auth
  • deletion of configuration files

Server and endpoint hardening examples:

kestra:
server:
basic-auth:
username: admin@kestra.io
password: change-me
open-urls:
- "/api/v1/main/executions/webhook/"
endpoints:
all:
basic-auth:
username: your-user
password: your-password

Super-admin

The super-admin account has the highest level of platform access and should be reserved for break-glass administration:

kestra:
security:
super-admin:
username: your_username
password: ${KESTRA_SUPERADMIN_PASSWORD}
tenant-admin-access:
- <optional>

Default role

Assign a default role to newly created users when you want them to land with a predictable permission set:

kestra:
security:
default-role:
name: default
description: "Default role"
permissions:
FLOW: ["CREATE", "READ", "UPDATE", "DELETE"]

In multi-tenant environments, scope that role to one tenant:

kestra:
security:
default-role:
name: default
description: "Default role"
permissions:
FLOW: ["CREATE", "READ", "UPDATE", "DELETE"]
tenant-id: staging

Invitation expiration and password rules

Invitation links expire after seven days by default. Extend them if user onboarding happens through slower approval processes:

kestra:
security:
invitations:
expire-after: P30D

For username/password auth, enforce password complexity explicitly:

kestra:
security:
basic-auth:
password-regexp: "<regexp-rule>"

Delete configuration files after startup

If the runtime reads secrets from configuration files, delete them after startup so tasks cannot read them later from disk:

kestra:
configurations:
delete-files-on-start: true

Liveness and heartbeat settings also belong here:

kestra:
server:
liveness:
enabled: true
interval: 5s
timeout: 45s
initial-delay: 45s
heartbeat-interval: 3s

Use the OSS-style settings above for JDBC-backed deployments. In Kafka-based EE deployments, timeout and initial-delay are commonly increased to 1m.

Heartbeat and restart behavior also belong here:

  • kestra.heartbeat.frequency controls how often workers emit heartbeats. Default: 10s.
  • kestra.heartbeat.heartbeat-missed controls how many missed heartbeats mark a worker as dead. Default: 3.
  • kestra.server.worker-task-restart-strategy accepts NEVER, IMMEDIATELY, or AFTER_TERMINATION_GRACE_PERIOD and determines what happens to running worker tasks during shutdown.

Set the termination grace period long enough for tasks to exit cleanly:

kestra:
server:
termination-grace-period: 5m

If the deployment regularly creates empty server instances, adjust how often purge runs:

kestra:
server:
service:
purge:
retention: 7d

Was this page helpful?