Skip to content

Secrets

Kod supports per-repository encrypted secrets. Secrets are stored encrypted at rest using AES-256-GCM and automatically injected as environment variables when workflows run.

To use secrets, you must provide an encryption key when starting the server:

Terminal window
# Generate a key
openssl rand -base64 32
# Start the server with the key
KOD_ENCRYPTION_KEY=your-generated-key kod serve
# Or via CLI flag
kod serve --encryption-key your-generated-key

Secrets are managed through the HTTP API. You need a token with secrets:write permission (or admin).

Terminal window
curl -X PUT http://localhost:3000/repos/my-project/secrets/DEPLOY_TOKEN \
-H "Authorization: Bearer kod_your_token" \
-H "Content-Type: application/json" \
-d '{"value": "my-secret-deploy-token"}'

Secret names must be valid environment variable names: letters, digits, and underscores, starting with a letter or underscore.

Terminal window
curl http://localhost:3000/repos/my-project/secrets \
-H "Authorization: Bearer kod_your_token"

This returns secret names and metadata only — values are never exposed through the API.

[
{
"name": "DEPLOY_TOKEN",
"repoName": "my-project",
"createdAt": 1706234567890,
"updatedAt": 1706234567890
}
]
Terminal window
curl -X DELETE http://localhost:3000/repos/my-project/secrets/DEPLOY_TOKEN \
-H "Authorization: Bearer kod_your_token"

Secrets are automatically injected into the workflow environment. Reference them like regular environment variables:

[step:deploy]
if: "branch == 'main'"
run: curl -H "Authorization: Bearer $DEPLOY_TOKEN" https://api.example.com/deploy
[step:notify]
run: |
curl -X POST $SLACK_WEBHOOK \
-H "Content-Type: application/json" \
-d '{"text":"Deployment complete"}'

No special syntax or declaration needed. If a secret named DEPLOY_TOKEN exists for the repository, $DEPLOY_TOKEN is available in every step.

PermissionWhat it allows
secrets:readList secret names and metadata (no values)
secrets:writeCreate, update, and delete secrets
adminFull access (includes secrets)

Create a token with secrets access:

Terminal window
kod token create ci-manager \
--permissions repo:read,repo:write,workflow:trigger,secrets:write
  • Encryption: AES-256-GCM with per-value random IVs
  • Key derivation: User-provided key is processed through scrypt for consistent key length
  • Storage: Encrypted values stored in PikoDB; never written to disk in plaintext
  • API: Secret values are never returned by any API endpoint
  • Logging: Decrypted values are never written to logs
  • Workflow isolation: Each workflow run gets a fresh clone with secrets injected only into the process environment