v3.3.2 9697f9d

auth.md RawHistoryFolder

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).

Configuration

Gordon uses token-only authentication. All registry and Admin API access is controlled through JWT tokens.

[auth]
secrets_backend = "pass"
token_secret = "gordon/auth/token_secret"
token_expiry = "30d"
access_token_ttl = "15m"

Options

Option Type Default Description
enabled bool true Authentication toggle. false enables local-only mode (see below)
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)
access_token_ttl string "15m" Lifetime of ephemeral access tokens issued by /auth/token

Secrets Backends

token_secret is 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

# 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

Remote CLI Tokens

Store a token for remote CLI access:

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:apps:read Read-only apps access (list, show, diff, status)
admin:apps:write App mutations (apply, deploy, lifecycle, secrets)
admin:config:read Read-only config access
admin:config:write Config write access
admin:status:read Read-only status/health
admin:logs:read Read-only logs access
admin:volumes:read List Docker volumes
admin:volumes:write Prune eligible Gordon-managed volumes

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

Access Token TTL

The access_token_ttl setting controls the lifetime of ephemeral access tokens issued by the /auth/token endpoint. These short-lived tokens are used internally for registry operations and Admin API sessions.

Value Meaning
"15m" 15 minutes (default)
"30m" 30 minutes
"1h" 1 hour (maximum before store validation applies)

Tokens with a lifetime of 1 hour or less skip store validation for performance. Longer-lived tokens (generated via gordon auth token generate) are always validated against the token store.

[auth]
access_token_ttl = "30m"

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

Local-only Mode

Authentication is enabled by default. If you set auth.enabled=false, Gordon switches to local-only mode:

  • /admin/* endpoints are not registered on the TCP listener.
  • /v2/* registry endpoints are restricted to loopback (127.0.0.1 / ::1).
  • Remote registry and remote admin access are disabled.

Local gordon apps commands keep working through an owner-only administration socket:

  • When XDG_RUNTIME_DIR is set, the daemon uses $XDG_RUNTIME_DIR/gordon/admin.sock; an invalid or unsafe preferred path fails closed and never falls back. When XDG_RUNTIME_DIR is unset, the daemon uses ~/.gordon/run/admin.sock. The CLI probes $XDG_RUNTIME_DIR/gordon/admin.sock when set, then /run/user/<uid>/gordon/admin.sock, then ~/.gordon/run/admin.sock, accepting only a safe owner-owned socket.
  • The runtime directory is 0700 and the socket 0600, both owned by the effective user. A foreign owner, group/other permission bits, or a symlink makes the daemon refuse to start and the CLI refuse to connect; an existing live listener is never replaced.
  • The socket exposes only app administration and app log reads. The implicit local-owner principal receives exactly admin:apps:read, admin:apps:write, and admin:logs:read; configuration, auth, prune, route, backup, and volume routes are denied.
  • Unix platforms only. Never share, mount, or forward the socket: filesystem access to it is the credential.

With neither a running daemon nor an explicit remote, app commands fail with daemon-unavailable. An explicit --remote/GORDON_REMOTE is authoritative and never falls back to the local socket.

Use this only when Gordon is intended for local machine usage.

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## Configuration
8
9Gordon uses token-only authentication. All registry and Admin API access is controlled through JWT tokens.
10
11```toml
12[auth]
13secrets_backend = "pass"
14token_secret = "gordon/auth/token_secret"
15token_expiry = "30d"
16access_token_ttl = "15m"
17```
18
19## Options
20
21| Option | Type | Default | Description |
22|--------|------|---------|-------------|
23| `enabled` | bool | `true` | Authentication toggle. `false` enables local-only mode (see below) |
24| `secrets_backend` | string | `"unsafe"` | Secrets backend: `"pass"`, `"sops"`, or `"unsafe"` |
25| `token_secret` | string | - | **Required.** Path to JWT signing secret in secrets backend |
26| `token_expiry` | string | `"30d"` | Token validity duration (0 = never expires) |
27| `access_token_ttl` | string | `"15m"` | Lifetime of ephemeral access tokens issued by `/auth/token` |
28
29## Secrets Backends
30
31`token_secret` is read through the configured backend:
32
33| Backend | Description |
34| --------- | ------------- |
35| `pass` | Unix password manager (GPG-encrypted) |
36| `sops` | Mozilla SOPS encrypted files |
37| `unsafe` | Plain text files (development only) |
38
39See [Secret Providers](./secrets.md) for setup details.
40
41## Environment Variable
42
43`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`).
44
45```bash
46export GORDON_AUTH_TOKEN_SECRET="your-32-character-secret-here"
47gordon serve
48```
49
50## Setup
51
52```bash
53# Create token secret (random 32+ characters)
54pass insert gordon/auth/token_secret
55
56# Generate a token
57gordon auth token generate --subject ci-bot --scopes push,pull --expiry 0
58```
59
60```bash
61# Docker login with token
62docker login -u ci-bot -p <token> registry.mydomain.com
63```
64
65## Remote CLI Tokens
66
67Store a token for remote CLI access:
68
69```bash
70gordon auth login --token <token>
71# or
72gordon remotes set-token prod <token>
73```
74
75## Token Scopes
76
77Registry scopes:
78
79| Scope | Permission |
80| ------- | ------------ |
81| `push` | Push images to registry |
82| `pull` | Pull images from registry |
83| `push,pull` | Both push and pull (default) |
84
85Admin scopes (for remote CLI):
86
87| Scope | Permission |
88|-------|------------|
89| `admin:*:*` | Full admin access |
90| `admin:apps:read` | Read-only apps access (list, show, diff, status) |
91| `admin:apps:write` | App mutations (apply, deploy, lifecycle, secrets) |
92| `admin:config:read` | Read-only config access |
93| `admin:config:write` | Config write access |
94| `admin:status:read` | Read-only status/health |
95| `admin:logs:read` | Read-only logs access |
96| `admin:volumes:read` | List Docker volumes |
97| `admin:volumes:write` | Prune eligible Gordon-managed volumes |
98
99Examples:
100
101```bash
102gordon auth token generate --subject reader --scopes pull --expiry 30d
103gordon auth token generate --subject builder --scopes push --expiry 0
104gordon auth token generate --subject admin --scopes "push,pull,admin:*:*" --expiry 0
105```
106
107## Access Token TTL
108
109The `access_token_ttl` setting controls the lifetime of ephemeral access tokens issued by the `/auth/token` endpoint. These short-lived tokens are used internally for registry operations and Admin API sessions.
110
111| Value | Meaning |
112|-------|---------|
113| `"15m"` | 15 minutes (default) |
114| `"30m"` | 30 minutes |
115| `"1h"` | 1 hour (maximum before store validation applies) |
116
117Tokens with a lifetime of 1 hour or less skip store validation for performance. Longer-lived tokens (generated via `gordon auth token generate`) are always validated against the token store.
118
119```toml
120[auth]
121access_token_ttl = "30m"
122```
123
124## Token Expiry
125
126Durations support `d`, `w`, `M`, `y` and combinations like `1y6M` or `2w3d`.
127
128```bash
129gordon auth token generate --subject ci --expiry 0
130gordon auth token generate --subject deploy --expiry 1y
131gordon auth token generate --subject temp --expiry 30d
132```
133
134## Instance-specific Tokens
135
136- Tokens are signed with `token_secret`
137- Tokens from one Gordon instance won't work on another
138- Changing `token_secret` invalidates all existing tokens
139
140## Local-only Mode
141
142Authentication is enabled by default. If you set `auth.enabled=false`, Gordon switches to local-only mode:
143
144- `/admin/*` endpoints are not registered on the TCP listener.
145- `/v2/*` registry endpoints are restricted to loopback (`127.0.0.1` / `::1`).
146- Remote registry and remote admin access are disabled.
147
148Local `gordon apps` commands keep working through an owner-only administration socket:
149
150- When `XDG_RUNTIME_DIR` is set, the daemon uses `$XDG_RUNTIME_DIR/gordon/admin.sock`; an invalid or unsafe preferred path fails closed and never falls back. When `XDG_RUNTIME_DIR` is unset, the daemon uses `~/.gordon/run/admin.sock`. The CLI probes `$XDG_RUNTIME_DIR/gordon/admin.sock` when set, then `/run/user/<uid>/gordon/admin.sock`, then `~/.gordon/run/admin.sock`, accepting only a safe owner-owned socket.
151- The runtime directory is `0700` and the socket `0600`, both owned by the effective user. A foreign owner, group/other permission bits, or a symlink makes the daemon refuse to start and the CLI refuse to connect; an existing live listener is never replaced.
152- The socket exposes only app administration and app log reads. The implicit `local-owner` principal receives exactly `admin:apps:read`, `admin:apps:write`, and `admin:logs:read`; configuration, auth, prune, route, backup, and volume routes are denied.
153- Unix platforms only. Never share, mount, or forward the socket: filesystem access to it is the credential.
154
155With neither a running daemon nor an explicit remote, app commands fail with `daemon-unavailable`. An explicit `--remote`/`GORDON_REMOTE` is authoritative and never falls back to the local socket.
156
157Use this only when Gordon is intended for local machine usage.
158
159## Internal Registry Auth
160
161Gordon generates internal credentials when auth is enabled. These are used for loopback pulls during deploys and are regenerated on each restart.
162
163Gordon 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.
164
165To view internal credentials (for troubleshooting):
166
167```bash
168gordon auth internal
169```
170
171> **Note:** Internal credentials are stored with restrictive permissions (0600) in secure runtime directories (XDG_RUNTIME_DIR or ~/.gordon/run) and cleaned up on shutdown.
172
173## Related
174
175- [Secret Providers](./secrets.md)
176- [CLI Commands](../cli/index.md)
177- [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