Secrets Configuration
Configure how Gordon stores and retrieves sensitive data: auth secrets such as token_secret (this page) and app secret values (managed with gordon apps secrets, values in pass under gordon/apps/<uuid>/<service>/<name>).
Configuration
The secrets backend is configured within the [auth] section:
[auth]
secrets_backend = "pass" # "pass", "sops", or "unsafe"
Options
| Option |
Type |
Default |
Description |
secrets_backend |
string |
"unsafe" |
Secrets storage backend |
Backends
Pass (Recommended for Production)
Uses the Unix password manager (pass) for secure secret storage:
[auth]
secrets_backend = "pass"
Setup:
# Install pass
sudo apt install pass
# Initialize with GPG key
pass init your-gpg-key-id
# Store secrets
pass insert gordon/auth/token_secret
Usage in config:
[auth]
token_secret = "gordon/auth/token_secret" # Path in pass store
Benefits:
- GPG-encrypted storage
- Version control friendly (encrypted files)
- Standard Unix tooling
- Works with team GPG keys
SOPS
Uses Mozilla SOPS for encrypted file-based secrets:
[auth]
secrets_backend = "sops"
Setup:
# Install sops
brew install sops # macOS
# or download from https://github.com/getsops/sops/releases
# Create encrypted secrets file
sops secrets.yaml
Benefits:
- Multiple encryption backends (AWS KMS, GCP KMS, Azure Key Vault, PGP)
- YAML/JSON file encryption
- Git-friendly (encrypted files in repo)
Security:
- Absolute paths are rejected to prevent arbitrary file access
- Path traversal (
..) is blocked
- Only relative paths from your config directory are allowed
Unsafe (Development Only)
Stores secrets as plain text files:
[auth]
secrets_backend = "unsafe"
Storage location:
{data_dir}/secrets/
├── gordon/
│ └── auth/
│ └── token_secret
Usage:
# Create secret
mkdir -p ~/.gordon/secrets/gordon/auth
echo "your-token-secret" > ~/.gordon/secrets/gordon/auth/token_secret
Warning: Only use for local development. Secrets are stored in plain text.
App Secret Values
App secret names are registered in the app manifest ([services.<name>.secrets] maps ENV name to secret name); values are written separately and stay in pass:
gordon apps secrets set blog --service web DATABASE_URL=...
Values affect the next deploy/restart, never running containers. Only key names are ever echoed back, never values. See App Manifest and Apps CLI.
Secret files
A secret declared with as = "file" is delivered as a file instead of an env value:
[services.web.secrets]
DATABASE_URL = { name = "database-url", as = "file" }
- The container sees a read-only file at
/run/secrets/DATABASE_URL and the env var DATABASE_URL_FILE=/run/secrets/DATABASE_URL.
- On the host, Gordon writes one file per secret under
<data_dir>/secrets-run/<app>/<container>/, with directories 0700 and files 0444. The files persist so containers restarted by the runtime or after a reboot still find them.
- Gordon removes a container's files once the container is confirmed gone, and sweeps files of unknown containers at startup.
- Exclude
<data_dir>/secrets-run from host backups: it holds plain secret values.
- Env-delivered secrets stay visible through
docker inspect and /proc/1/environ inside the container. Prefer file delivery for apps that read *_FILE variables.
- An older Gordon v3 binary ignores file delivery and injects those secrets as env vars again. Its leftover
secrets-run directories are harmless and are swept by the next start of a version that supports file delivery.
Examples
Production with Pass
[auth]
enabled = true
secrets_backend = "pass"
token_secret = "gordon/auth/token_secret"
# Setup
pass insert gordon/auth/token_secret
# Enter a random 32+ character string
# Generate tokens
gordon auth token generate --subject deploy --expiry 0
Development with Unsafe
[auth]
enabled = false
secrets_backend = "unsafe"
Security Recommendations
- Production: Always use
pass or sops backend
- Never commit: Don't commit unencrypted secrets to git (app files must never contain secret values)
- Rotate regularly: Regenerate tokens and passwords periodically
- Least privilege: Use separate secrets per environment
- Path validation: SOPS provider rejects absolute paths and path traversal attempts for security
- File delivery: Use
as = "file" for app secrets when the image supports *_FILE variables (see Secret files)
- Hardening: See Security Hardening for the runtime guard, process protection, and credential scoping
source
1# Secrets Configuration
2
3Configure how Gordon stores and retrieves sensitive data: auth secrets such as `token_secret` (this page) and app secret values (managed with `gordon apps secrets`, values in pass under `gordon/apps/<uuid>/<service>/<name>`).
4
5## Configuration
6
7The secrets backend is configured within the `[auth]` section:
8
9```toml
10[auth]
11secrets_backend = "pass" # "pass", "sops", or "unsafe"
12```
13
14## Options
15
16| Option | Type | Default | Description |
17|--------|------|---------|-------------|
18| `secrets_backend` | string | `"unsafe"` | Secrets storage backend |
19
20## Backends
21
22### Pass (Recommended for Production)
23
24Uses the Unix password manager (`pass`) for secure secret storage:
25
26```toml
27[auth]
28secrets_backend = "pass"
29```
30
31**Setup:**
32```bash
33# Install pass
34sudo apt install pass
35
36# Initialize with GPG key
37pass init your-gpg-key-id
38
39# Store secrets
40pass insert gordon/auth/token_secret
41```
42
43**Usage in config:**
44```toml
45[auth]
46token_secret = "gordon/auth/token_secret" # Path in pass store
47```
48
49**Benefits:**
50- GPG-encrypted storage
51- Version control friendly (encrypted files)
52- Standard Unix tooling
53- Works with team GPG keys
54
55### SOPS
56
57Uses Mozilla SOPS for encrypted file-based secrets:
58
59```toml
60[auth]
61secrets_backend = "sops"
62```
63
64**Setup:**
65```bash
66# Install sops
67brew install sops # macOS
68# or download from https://github.com/getsops/sops/releases
69
70# Create encrypted secrets file
71sops secrets.yaml
72```
73
74**Benefits:**
75- Multiple encryption backends (AWS KMS, GCP KMS, Azure Key Vault, PGP)
76- YAML/JSON file encryption
77- Git-friendly (encrypted files in repo)
78
79**Security:**
80- Absolute paths are rejected to prevent arbitrary file access
81- Path traversal (`..`) is blocked
82- Only relative paths from your config directory are allowed
83
84### Unsafe (Development Only)
85
86Stores secrets as plain text files:
87
88```toml
89[auth]
90secrets_backend = "unsafe"
91```
92
93**Storage location:**
94```
95{data_dir}/secrets/
96├── gordon/
97│ └── auth/
98│ └── token_secret
99```
100
101**Usage:**
102```bash
103# Create secret
104mkdir -p ~/.gordon/secrets/gordon/auth
105echo "your-token-secret" > ~/.gordon/secrets/gordon/auth/token_secret
106```
107
108> **Warning:** Only use for local development. Secrets are stored in plain text.
109
110## App Secret Values
111
112App secret names are registered in the app manifest (`[services.<name>.secrets]` maps ENV name to secret name); values are written separately and stay in pass:
113
114```bash
115gordon apps secrets set blog --service web DATABASE_URL=...
116```
117
118Values affect the next deploy/restart, never running containers. Only key names are ever echoed back, never values. See [App Manifest](./apps.md) and [Apps CLI](../cli/apps.md).
119
120### Secret files
121
122A secret declared with `as = "file"` is delivered as a file instead of an env value:
123
124```toml
125[services.web.secrets]
126DATABASE_URL = { name = "database-url", as = "file" }
127```
128
129- The container sees a read-only file at `/run/secrets/DATABASE_URL` and the env var `DATABASE_URL_FILE=/run/secrets/DATABASE_URL`.
130- On the host, Gordon writes one file per secret under `<data_dir>/secrets-run/<app>/<container>/`, with directories `0700` and files `0444`. The files persist so containers restarted by the runtime or after a reboot still find them.
131- Gordon removes a container's files once the container is confirmed gone, and sweeps files of unknown containers at startup.
132- Exclude `<data_dir>/secrets-run` from host backups: it holds plain secret values.
133- Env-delivered secrets stay visible through `docker inspect` and `/proc/1/environ` inside the container. Prefer file delivery for apps that read `*_FILE` variables.
134- An older Gordon v3 binary ignores file delivery and injects those secrets as env vars again. Its leftover `secrets-run` directories are harmless and are swept by the next start of a version that supports file delivery.
135
136## Examples
137
138### Production with Pass
139
140```toml
141[auth]
142enabled = true
143secrets_backend = "pass"
144token_secret = "gordon/auth/token_secret"
145```
146
147```bash
148# Setup
149pass insert gordon/auth/token_secret
150# Enter a random 32+ character string
151
152# Generate tokens
153gordon auth token generate --subject deploy --expiry 0
154```
155
156### Development with Unsafe
157
158```toml
159[auth]
160enabled = false
161secrets_backend = "unsafe"
162```
163
164## Security Recommendations
165
1661. **Production**: Always use `pass` or `sops` backend
1672. **Never commit**: Don't commit unencrypted secrets to git (app files must never contain secret values)
1683. **Rotate regularly**: Regenerate tokens and passwords periodically
1694. **Least privilege**: Use separate secrets per environment
1705. **Path validation**: SOPS provider rejects absolute paths and path traversal attempts for security
1716. **File delivery**: Use `as = "file"` for app secrets when the image supports `*_FILE` variables (see [Secret files](#secret-files))
1727. **Hardening**: See [Security Hardening](./security-hardening.md) for the runtime guard, process protection, and credential scoping
173
174## Related
175
176- [Authentication](./auth.md)
177- [App Manifest](./apps.md)
178- [Security Hardening](./security-hardening.md)
179- [Configuration Overview](./index.md)