Configure Secrets
Learn how to securely configure and use secrets in Kestra.
Configure Secrets
Secrets are sensitive values that should not be exposed in plain text, such as passwords, API tokens, access keys, or other confidential information. For a detailed overview, see the Secrets documentation.
This guide demonstrates how to add secrets to your Kestra server using an environment file (.env).
If you prefer a simpler, UI-based experience, check out the Enterprise Edition, which allows managing secrets per namespace directly from the web interface — without modifying server configuration files.
Using secrets in Kestra
Step 1: Create a .env file
Start by defining your secrets in a standard environment file:
POSTGRES_PASSWORD=actual_postgres_passwordOPENAI_KEY=actual_openai_keyAWS_ACCESS_KEY=actual_aws_access_keyAWS_SECRET_KEY=actual_aws_secret_keyStep 2: Encode and prefix your secrets
Kestra expects all secret keys to be prefixed with SECRET_ and their values base64-encoded.
The resulting .env_encoded file should look like this:
SECRET_POSTGRES_PASSWORD=base64_encoded_postgres_passwordSECRET_OPENAI_KEY=base64_encoded_openai_keySECRET_AWS_ACCESS_KEY=base64_encoded_aws_access_keySECRET_AWS_SECRET_KEY=base64_encoded_aws_secret_keyTo generate this file automatically, use the following Bash script:
while IFS='=' read -r key value; do echo "SECRET_$key=$(echo -n "$value" | base64)";done < .env > .env_encodedThis script:
- Base64-encodes all values.
- Adds the
SECRET_prefix to all variable names. - Saves the result as
.env_encoded.
You can verify the output by opening .env_encoded — it should look like the example above.
Alternatively, you can manually write the file using macros to encode secrets dynamically:
SECRET_POSTGRES_PASSWORD={{ "actual_postgres_password" | base64encode }}SECRET_OPENAI_KEY={{ "actual_openai_key" | base64encode }}SECRET_AWS_ACCESS_KEY={{ "actual_aws_access_key" | base64encode }}SECRET_AWS_SECRET_KEY={{ "actual_aws_secret_key" | base64encode }}Step 3: Point Docker to the encoded file
Update your docker-compose.yaml to use the .env_encoded file:
kestra: image: kestra/kestra:latest env_file: - .env_encodedThis ensures your secrets are loaded when Kestra starts.
Step 4: Use secrets in a flow
Once your secrets are loaded, reference them in your flows using the secret() function — without including the SECRET_ prefix.
For example, this flow connects to PostgreSQL using SECRET_POSTGRES_PASSWORD and uploads query results to AWS S3 using SECRET_AWS_ACCESS_KEY and SECRET_AWS_SECRET_KEY.
id: postgres_to_s3namespace: company.team
tasks: - id: fetch type: io.kestra.plugin.jdbc.postgresql.Query url: jdbc:postgresql://127.0.0.1:56982/ username: pg_user password: "{{ secret('POSTGRES_PASSWORD') }}" sql: select id, first_name, last_name, city from users fetchType: STORE
- id: write_to_s3 type: io.kestra.plugin.aws.s3.Upload accessKeyId: "{{ secret('AWS_ACCESS_KEY') }}" secretKeyId: "{{ secret('AWS_SECRET_KEY') }}" region: "eu-central-1" from: "{{ outputs.fetch.uri }}" bucket: "kestra-bucket" key: "data/users.csv"How secrets are resolved
When you reference a secret using {{ secret('POSTGRES_PASSWORD') }}, Kestra automatically:
- Finds the corresponding environment variable (e.g.,
SECRET_POSTGRES_PASSWORD). - Base64-decodes its value.
- Injects it securely into the execution context.
This ensures your sensitive data stays encrypted at rest and never appears in logs or flow definitions.
Was this page helpful?