Authentication
Configure authentication for the Gordon registry and Admin API.
Authentication is enabled by default. Gordon will not start without a valid token_secret (or GORDON_AUTH_TOKEN_SECRET).
Pick a Mode
Token-only (recommended for CI/CD)
[auth]
enabled = true
secrets_backend = "pass"
token_secret = "gordon/auth/token_secret"
token_expiry = "30d"
Password + Token (interactive + CI/CD)
[auth]
enabled = true
secrets_backend = "pass"
username = "deploy"
password_hash = "gordon/auth/password_hash"
token_secret = "gordon/auth/token_secret"
Token auth always works. Adding username + password_hash enables interactive login.
Options
| Option |
Type |
Default |
Description |
enabled |
bool |
true |
Enable authentication |
secrets_backend |
string |
"unsafe" |
Secrets backend: "pass", "sops", or "unsafe" |
token_secret |
string |
- |
Required. Path to JWT signing secret in secrets backend |
token_expiry |
string |
"30d" |
Token validity duration (0 = never expires) |
username |
string |
- |
Username for password auth (optional) |
password_hash |
string |
- |
Path to bcrypt hash in secrets backend (optional) |
Secrets Backends
token_secret and password_hash are read through the configured backend:
| Backend |
Description |
pass |
Unix password manager (GPG-encrypted) |
sops |
Mozilla SOPS encrypted files |
unsafe |
Plain text files (development only) |
See Secret Providers for setup details.
Environment Variable
GORDON_AUTH_TOKEN_SECRET overrides token_secret in the config. If you don’t set the env var, token_secret is loaded from the configured secrets backend (including pass).
export GORDON_AUTH_TOKEN_SECRET="your-32-character-secret-here"
gordon serve
Setup
Token-only setup
# Create token secret (random 32+ characters)
pass insert gordon/auth/token_secret
# Generate a token
gordon auth token generate --subject ci-bot --scopes push,pull --expiry 0
# Docker login with token
docker login -u ci-bot -p <token> registry.mydomain.com
Password + token setup
# Generate bcrypt hash
gordon auth password hash
# Store hash and token secret
pass insert gordon/auth/password_hash
pass insert gordon/auth/token_secret
# Docker registry access
docker login -u deploy -p <password> registry.mydomain.com
# Remote CLI login (stores a token for you)
gordon auth login --remote prod
Remote CLI Tokens
If you already have a token (token-only servers), store it directly:
gordon auth login --token <token>
# or
gordon remotes set-token prod <token>
Token Scopes
Registry scopes:
| Scope |
Permission |
push |
Push images to registry |
pull |
Pull images from registry |
push,pull |
Both push and pull (default) |
Admin scopes (for remote CLI):
| Scope |
Permission |
admin:*:* |
Full admin access |
admin:routes:read |
Read-only routes access |
admin:routes:write |
Routes write access |
admin:config:read |
Read-only config access |
admin:config:write |
Config write access |
admin:status:read |
Read-only status/health |
admin:secrets:read |
List secret keys |
admin:secrets:write |
Set/delete secrets |
Examples:
gordon auth token generate --subject reader --scopes pull --expiry 30d
gordon auth token generate --subject builder --scopes push --expiry 0
gordon auth token generate --subject admin --scopes "push,pull,admin:*:*" --expiry 0
Token Expiry
Durations support d, w, M, y and combinations like 1y6M or 2w3d.
gordon auth token generate --subject ci --expiry 0
gordon auth token generate --subject deploy --expiry 1y
gordon auth token generate --subject temp --expiry 30d
Instance-specific Tokens
- Tokens are signed with
token_secret
- Tokens from one Gordon instance won't work on another
- Changing
token_secret invalidates all existing tokens
Disable Auth (development only)
[auth]
enabled = false
Security Warning: When authentication is disabled, the admin API is fully accessible without credentials. This includes endpoints to deploy containers, manage secrets, modify routes, and reload configuration. Only disable auth for local development where Gordon is not exposed to the internet.
Internal Registry Auth
Gordon generates internal credentials when auth is enabled. These are used for loopback pulls during deploys and are regenerated on each restart.
Gordon also generates a separate service token for its own registry-domain pulls. This token is managed internally and is not exposed via configuration or CLI.
To view internal credentials (for troubleshooting):
gordon auth internal
Note: Internal credentials are stored with restrictive permissions (0600) in secure runtime directories (XDG_RUNTIME_DIR or ~/.gordon/run) and cleaned up on shutdown.
source
1# Authentication
2
3Configure authentication for the Gordon registry and Admin API.
4
5Authentication is enabled by default. Gordon will not start without a valid `token_secret` (or `GORDON_AUTH_TOKEN_SECRET`).
6
7## Pick a Mode
8
9### Token-only (recommended for CI/CD)
10
11```toml
12[auth]
13enabled = true
14secrets_backend = "pass"
15token_secret = "gordon/auth/token_secret"
16token_expiry = "30d"
17```
18
19### Password + Token (interactive + CI/CD)
20
21```toml
22[auth]
23enabled = true
24secrets_backend = "pass"
25username = "deploy"
26password_hash = "gordon/auth/password_hash"
27token_secret = "gordon/auth/token_secret"
28```
29
30Token auth always works. Adding `username` + `password_hash` enables interactive login.
31
32## Options
33
34| Option | Type | Default | Description |
35|--------|------|---------|-------------|
36| `enabled` | bool | `true` | Enable authentication |
37| `secrets_backend` | string | `"unsafe"` | Secrets backend: `"pass"`, `"sops"`, or `"unsafe"` |
38| `token_secret` | string | - | **Required.** Path to JWT signing secret in secrets backend |
39| `token_expiry` | string | `"30d"` | Token validity duration (0 = never expires) |
40| `username` | string | - | Username for password auth (optional) |
41| `password_hash` | string | - | Path to bcrypt hash in secrets backend (optional) |
42
43## Secrets Backends
44
45`token_secret` and `password_hash` are read through the configured backend:
46
47| Backend | Description |
48| --------- | ------------- |
49| `pass` | Unix password manager (GPG-encrypted) |
50| `sops` | Mozilla SOPS encrypted files |
51| `unsafe` | Plain text files (development only) |
52
53See [Secret Providers](./secrets.md) for setup details.
54
55## Environment Variable
56
57`GORDON_AUTH_TOKEN_SECRET` overrides `token_secret` in the config. If you don’t set the env var, `token_secret` is loaded from the configured secrets backend (including `pass`).
58
59```bash
60export GORDON_AUTH_TOKEN_SECRET="your-32-character-secret-here"
61gordon serve
62```
63
64## Setup
65
66### Token-only setup
67
68```bash
69# Create token secret (random 32+ characters)
70pass insert gordon/auth/token_secret
71
72# Generate a token
73gordon auth token generate --subject ci-bot --scopes push,pull --expiry 0
74```
75
76```bash
77# Docker login with token
78docker login -u ci-bot -p <token> registry.mydomain.com
79```
80
81### Password + token setup
82
83```bash
84# Generate bcrypt hash
85gordon auth password hash
86
87# Store hash and token secret
88pass insert gordon/auth/password_hash
89pass insert gordon/auth/token_secret
90```
91
92```bash
93# Docker registry access
94docker login -u deploy -p <password> registry.mydomain.com
95
96# Remote CLI login (stores a token for you)
97gordon auth login --remote prod
98```
99
100## Remote CLI Tokens
101
102If you already have a token (token-only servers), store it directly:
103
104```bash
105gordon auth login --token <token>
106# or
107gordon remotes set-token prod <token>
108```
109
110## Token Scopes
111
112Registry scopes:
113
114| Scope | Permission |
115| ------- | ------------ |
116| `push` | Push images to registry |
117| `pull` | Pull images from registry |
118| `push,pull` | Both push and pull (default) |
119
120Admin scopes (for remote CLI):
121
122| Scope | Permission |
123|-------|------------|
124| `admin:*:*` | Full admin access |
125| `admin:routes:read` | Read-only routes access |
126| `admin:routes:write` | Routes write access |
127| `admin:config:read` | Read-only config access |
128| `admin:config:write` | Config write access |
129| `admin:status:read` | Read-only status/health |
130| `admin:secrets:read` | List secret keys |
131| `admin:secrets:write` | Set/delete secrets |
132
133Examples:
134
135```bash
136gordon auth token generate --subject reader --scopes pull --expiry 30d
137gordon auth token generate --subject builder --scopes push --expiry 0
138gordon auth token generate --subject admin --scopes "push,pull,admin:*:*" --expiry 0
139```
140
141## Token Expiry
142
143Durations support `d`, `w`, `M`, `y` and combinations like `1y6M` or `2w3d`.
144
145```bash
146gordon auth token generate --subject ci --expiry 0
147gordon auth token generate --subject deploy --expiry 1y
148gordon auth token generate --subject temp --expiry 30d
149```
150
151## Instance-specific Tokens
152
153- Tokens are signed with `token_secret`
154- Tokens from one Gordon instance won't work on another
155- Changing `token_secret` invalidates all existing tokens
156
157## Disable Auth (development only)
158
159```toml
160[auth]
161enabled = false
162```
163
164> **Security Warning:** When authentication is disabled, the admin API is fully accessible without credentials. This includes endpoints to deploy containers, manage secrets, modify routes, and reload configuration. Only disable auth for local development where Gordon is not exposed to the internet.
165
166## Internal Registry Auth
167
168Gordon generates internal credentials when auth is enabled. These are used for loopback pulls during deploys and are regenerated on each restart.
169
170Gordon also generates a separate service token for its own registry-domain pulls. This token is managed internally and is not exposed via configuration or CLI.
171
172To view internal credentials (for troubleshooting):
173
174```bash
175gordon auth internal
176```
177
178> **Note:** Internal credentials are stored with restrictive permissions (0600) in secure runtime directories (XDG_RUNTIME_DIR or ~/.gordon/run) and cleaned up on shutdown.
179
180## Related
181
182- [Secret Providers](./secrets.md)
183- [CLI Commands](../cli/index.md)
184- [GitHub Actions Deployment](../deployment/github-actions.md)