v2.8.0 6aced72

auth.md RawHistoryFolder

Authentication

Configure authentication for the Gordon registry and Admin API.

Quick Start

Authentication is enabled by default for security. Gordon will not start without authentication configured.

Option 1: Password Authentication (simplest)

# 1. Generate password hash
gordon auth password hash
# Enter your password, copy the bcrypt hash

# 2. Save hash to secrets file
mkdir -p ~/.gordon/secrets
echo '$2a$10$...' > ~/.gordon/secrets/password_hash

# 3. Add to config.toml
cat >> ~/.gordon/config.toml << 'EOF'
[auth]
password_hash = "password_hash"
EOF

Option 2: Disable Authentication (development only)

[auth]
enabled = false

Configuration

[auth]
enabled = true
secrets_backend = "pass"
token_secret = "gordon/auth/token_secret"
token_expiry = "30d"

# Optional: enable password authentication
username = "deploy"
password_hash = "gordon/auth/password_hash"

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)

Authentication Modes

Gordon infers the authentication mode from your configuration:

Config Mode Description
Only token_secret Token-only JWT tokens for all access
token_secret + username + password_hash Password + Token Password for interactive login, tokens for CI/CD

Tokens always work regardless of mode. The difference is whether password authentication is available.

Environment Variables

Gordon supports environment variables for sensitive configuration:

Variable Description
GORDON_AUTH_TOKEN_SECRET JWT signing secret (takes priority over config file)

Using environment variables is recommended for production as it avoids storing secrets on disk:

export GORDON_AUTH_TOKEN_SECRET="your-32-character-secret-here"
gordon serve

Secrets Backend

The secrets_backend option determines how Gordon retrieves sensitive values like token_secret and password_hash:

Backend Description
pass Unix password manager (GPG-encrypted)
sops Mozilla SOPS encrypted files
unsafe Plain text files (development only)

See Secret Providers for detailed configuration of each backend.

Authentication Types

Token-Only Mode

JWT-based authentication, ideal for CI/CD pipelines when you don't need interactive login:

[auth]
enabled = true
secrets_backend = "pass"
token_secret = "gordon/auth/token_secret"
token_expiry = "30d"

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

Usage:

# Docker login with token
docker login -u ci-bot -p <token> registry.mydomain.com

Token Management:

# List all tokens
gordon auth token list

# Revoke a specific token
gordon auth token revoke <token-id>

# Revoke all tokens
gordon auth token revoke --all

Password + Token Mode

Password authentication for interactive login, plus tokens for CI/CD:

[auth]
enabled = true
secrets_backend = "pass"
username = "deploy"
password_hash = "gordon/auth/password_hash"
token_secret = "gordon/auth/token_secret"

When username and password_hash are configured, both password and token authentication work.

Setup:

# Generate bcrypt hash
gordon auth password hash
# Enter password when prompted

# Store hash in secrets backend
pass insert gordon/auth/password_hash
# Paste the bcrypt hash

# Create token secret (for CI/CD token generation)
pass insert gordon/auth/token_secret
# Enter a random 32+ character string

Usage:

# Docker registry access
docker login -u deploy -p <password> registry.mydomain.com

# Remote CLI authentication
gordon auth login --remote prod
# Enter username and password when prompted

Remote CLI Authentication:

With password authentication enabled, you can use gordon auth login to obtain a token for remote CLI operations:

gordon auth login --remote prod
# Username: deploy
# Password: ********
# ✓ Authentication successful!
# Token stored for remote 'prod'

The returned token is stored automatically and used for subsequent CLI commands.

Token Scopes

Tokens can have different permission levels:

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 access via the Admin API:

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:

# Pull-only token (for read-only access)
gordon auth token generate --subject reader --scopes pull --expiry 30d

# Push-only token (for CI builds)
gordon auth token generate --subject builder --scopes push --expiry 0

# Full admin access (for remote CLI)
gordon auth token generate --subject admin --scopes "push,pull,admin:*:*" --expiry 0

Token Expiry

Control how long tokens remain valid. Supports human-friendly units:

Unit Description
d days (24 hours)
w weeks (7 days)
M months (30 days)
y years (365 days)

Compound durations work too: 1y6M, 2w3d

# Never expires (for CI/CD)
gordon auth token generate --subject ci --expiry 0

# Expires in 1 year
gordon auth token generate --subject deploy --expiry 1y

# Expires in 30 days
gordon auth token generate --subject temp --expiry 30d

Instance-Specific Tokens

Tokens are signed with the token_secret, which is unique to each Gordon instance:

  • Tokens from one Gordon instance won't work on another
  • Changing the token_secret invalidates all existing tokens
  • Each environment (dev, staging, prod) should have different secrets

Development Setup

For local development without authentication:

[auth]
enabled = false

Examples

CI/CD Setup (Token-Only)

[auth]
enabled = true
secrets_backend = "pass"
token_secret = "gordon/auth/token_secret"
# Generate CI token
gordon auth token generate --subject github-actions --scopes push,pull --expiry 0

In GitHub Actions:

- name: Login to Gordon Registry
  run: docker login -u github-actions -p ${{ secrets.GORDON_TOKEN }} ${{ secrets.GORDON_REGISTRY }}

Production with Password + Token

[auth]
enabled = true
secrets_backend = "pass"
username = "deploy"
password_hash = "gordon/auth/password_hash"
token_secret = "gordon/auth/token_secret"

Enterprise with SOPS

[auth]
enabled = true
secrets_backend = "sops"
token_secret = "gordon/auth/token_secret"

Internal Registry Auth

Gordon generates internal credentials automatically when auth is enabled. These are used for loopback pulls when deploying containers and are regenerated on each restart.

To view internal credentials (for troubleshooting):

gordon auth internal
source
1# Authentication
2
3Configure authentication for the Gordon registry and Admin API.
4
5## Quick Start
6
7Authentication is **enabled by default** for security. Gordon will not start without authentication configured.
8
9**Option 1: Password Authentication (simplest)**
10```bash
11# 1. Generate password hash
12gordon auth password hash
13# Enter your password, copy the bcrypt hash
14
15# 2. Save hash to secrets file
16mkdir -p ~/.gordon/secrets
17echo '$2a$10$...' > ~/.gordon/secrets/password_hash
18
19# 3. Add to config.toml
20cat >> ~/.gordon/config.toml << 'EOF'
21[auth]
22password_hash = "password_hash"
23EOF
24```
25
26**Option 2: Disable Authentication (development only)**
27```toml
28[auth]
29enabled = false
30```
31
32## Configuration
33
34```toml
35[auth]
36enabled = true
37secrets_backend = "pass"
38token_secret = "gordon/auth/token_secret"
39token_expiry = "30d"
40
41# Optional: enable password authentication
42username = "deploy"
43password_hash = "gordon/auth/password_hash"
44```
45
46## Options
47
48| Option | Type | Default | Description |
49|--------|------|---------|-------------|
50| `enabled` | bool | `true` | Enable authentication |
51| `secrets_backend` | string | `"unsafe"` | Secrets backend: `"pass"`, `"sops"`, or `"unsafe"` |
52| `token_secret` | string | - | **Required.** Path to JWT signing secret in secrets backend |
53| `token_expiry` | string | `"30d"` | Token validity duration (0 = never expires) |
54| `username` | string | - | Username for password auth (optional) |
55| `password_hash` | string | - | Path to bcrypt hash in secrets backend (optional) |
56
57## Authentication Modes
58
59Gordon infers the authentication mode from your configuration:
60
61| Config | Mode | Description |
62|--------|------|-------------|
63| Only `token_secret` | Token-only | JWT tokens for all access |
64| `token_secret` + `username` + `password_hash` | Password + Token | Password for interactive login, tokens for CI/CD |
65
66Tokens always work regardless of mode. The difference is whether password authentication is available.
67
68## Environment Variables
69
70Gordon supports environment variables for sensitive configuration:
71
72| Variable | Description |
73|----------|-------------|
74| `GORDON_AUTH_TOKEN_SECRET` | JWT signing secret (takes priority over config file) |
75
76Using environment variables is recommended for production as it avoids storing secrets on disk:
77
78```bash
79export GORDON_AUTH_TOKEN_SECRET="your-32-character-secret-here"
80gordon serve
81```
82
83## Secrets Backend
84
85The `secrets_backend` option determines how Gordon retrieves sensitive values like `token_secret` and `password_hash`:
86
87| Backend | Description |
88|---------|-------------|
89| `pass` | Unix password manager (GPG-encrypted) |
90| `sops` | Mozilla SOPS encrypted files |
91| `unsafe` | Plain text files (development only) |
92
93See [Secret Providers](./secrets.md) for detailed configuration of each backend.
94
95## Authentication Types
96
97### Token-Only Mode
98
99JWT-based authentication, ideal for CI/CD pipelines when you don't need interactive login:
100
101```toml
102[auth]
103enabled = true
104secrets_backend = "pass"
105token_secret = "gordon/auth/token_secret"
106token_expiry = "30d"
107```
108
109**Setup:**
110```bash
111# Create token secret (random 32+ characters)
112pass insert gordon/auth/token_secret
113
114# Generate a token
115gordon auth token generate --subject ci-bot --scopes push,pull --expiry 0
116```
117
118**Usage:**
119```bash
120# Docker login with token
121docker login -u ci-bot -p <token> registry.mydomain.com
122```
123
124**Token Management:**
125```bash
126# List all tokens
127gordon auth token list
128
129# Revoke a specific token
130gordon auth token revoke <token-id>
131
132# Revoke all tokens
133gordon auth token revoke --all
134```
135
136### Password + Token Mode
137
138Password authentication for interactive login, plus tokens for CI/CD:
139
140```toml
141[auth]
142enabled = true
143secrets_backend = "pass"
144username = "deploy"
145password_hash = "gordon/auth/password_hash"
146token_secret = "gordon/auth/token_secret"
147```
148
149When `username` and `password_hash` are configured, both password and token authentication work.
150
151**Setup:**
152```bash
153# Generate bcrypt hash
154gordon auth password hash
155# Enter password when prompted
156
157# Store hash in secrets backend
158pass insert gordon/auth/password_hash
159# Paste the bcrypt hash
160
161# Create token secret (for CI/CD token generation)
162pass insert gordon/auth/token_secret
163# Enter a random 32+ character string
164```
165
166**Usage:**
167```bash
168# Docker registry access
169docker login -u deploy -p <password> registry.mydomain.com
170
171# Remote CLI authentication
172gordon auth login --remote prod
173# Enter username and password when prompted
174```
175
176**Remote CLI Authentication:**
177
178With password authentication enabled, you can use `gordon auth login` to obtain a token for remote CLI operations:
179
180```bash
181gordon auth login --remote prod
182# Username: deploy
183# Password: ********
184# ✓ Authentication successful!
185# Token stored for remote 'prod'
186```
187
188The returned token is stored automatically and used for subsequent CLI commands.
189
190## Token Scopes
191
192Tokens can have different permission levels:
193
194### Registry Scopes
195
196| Scope | Permission |
197|-------|------------|
198| `push` | Push images to registry |
199| `pull` | Pull images from registry |
200| `push,pull` | Both push and pull (default) |
201
202### Admin Scopes
203
204For remote CLI access via the Admin API:
205
206| Scope | Permission |
207|-------|------------|
208| `admin:*:*` | Full admin access |
209| `admin:routes:read` | Read-only routes access |
210| `admin:routes:write` | Routes write access |
211| `admin:config:read` | Read-only config access |
212| `admin:config:write` | Config write access |
213| `admin:status:read` | Read-only status/health |
214| `admin:secrets:read` | List secret keys |
215| `admin:secrets:write` | Set/delete secrets |
216
217**Examples:**
218```bash
219# Pull-only token (for read-only access)
220gordon auth token generate --subject reader --scopes pull --expiry 30d
221
222# Push-only token (for CI builds)
223gordon auth token generate --subject builder --scopes push --expiry 0
224
225# Full admin access (for remote CLI)
226gordon auth token generate --subject admin --scopes "push,pull,admin:*:*" --expiry 0
227```
228
229## Token Expiry
230
231Control how long tokens remain valid. Supports human-friendly units:
232
233| Unit | Description |
234|------|-------------|
235| `d` | days (24 hours) |
236| `w` | weeks (7 days) |
237| `M` | months (30 days) |
238| `y` | years (365 days) |
239
240Compound durations work too: `1y6M`, `2w3d`
241
242```bash
243# Never expires (for CI/CD)
244gordon auth token generate --subject ci --expiry 0
245
246# Expires in 1 year
247gordon auth token generate --subject deploy --expiry 1y
248
249# Expires in 30 days
250gordon auth token generate --subject temp --expiry 30d
251```
252
253## Instance-Specific Tokens
254
255Tokens are signed with the `token_secret`, which is unique to each Gordon instance:
256
257- Tokens from one Gordon instance won't work on another
258- Changing the `token_secret` invalidates all existing tokens
259- Each environment (dev, staging, prod) should have different secrets
260
261## Development Setup
262
263For local development without authentication:
264
265```toml
266[auth]
267enabled = false
268```
269
270## Examples
271
272### CI/CD Setup (Token-Only)
273
274```toml
275[auth]
276enabled = true
277secrets_backend = "pass"
278token_secret = "gordon/auth/token_secret"
279```
280
281```bash
282# Generate CI token
283gordon auth token generate --subject github-actions --scopes push,pull --expiry 0
284```
285
286In GitHub Actions:
287```yaml
288- name: Login to Gordon Registry
289  run: docker login -u github-actions -p ${{ secrets.GORDON_TOKEN }} ${{ secrets.GORDON_REGISTRY }}
290```
291
292### Production with Password + Token
293
294```toml
295[auth]
296enabled = true
297secrets_backend = "pass"
298username = "deploy"
299password_hash = "gordon/auth/password_hash"
300token_secret = "gordon/auth/token_secret"
301```
302
303### Enterprise with SOPS
304
305```toml
306[auth]
307enabled = true
308secrets_backend = "sops"
309token_secret = "gordon/auth/token_secret"
310```
311
312## Internal Registry Auth
313
314Gordon generates internal credentials automatically when auth is enabled. These are used for loopback pulls when deploying containers and are regenerated on each restart.
315
316To view internal credentials (for troubleshooting):
317```bash
318gordon auth internal
319```
320
321## Related
322
323- [Secret Providers](./secrets.md)
324- [CLI Commands](../cli/index.md)
325- [GitHub Actions Deployment](../deployment/github-actions.md)

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 7

Tags 106

↑↓ moveenter openesc close