README: fail-open no longer covers a 4xx; registration tokens are single-use

14fe8cf · Gabriel Morell · 2026-10-20 18:38

1 files +2 -1

Files changed

modified README.md
+2 −1
@@ -252,7 +252,7 @@ These all live in `config/*.exs`. Key ones:
252 252 | `GitGudWeb.PackagesWebhookController` `shared_secret` | Bearer-token gate on the zot webhook (env: `ZOT_WEBHOOK_SECRET`). **Required**: without it `/_webhooks/zot` refuses every request (fail closed), logged once at boot | `nil` (webhook refuses everything) |
253 253 | `GITGUD_HOOK_SECRET` (env) | Shared secret the git hooks and the SSH shim send (`x-gitgud-hook-token`) to `/_hooks/*` and `/_ssh/resolve`; anything else gets a 403. The node mints one at boot and hands it to every `git` it spawns, so the embedded SSH daemon and smart HTTP need nothing. **Set it, to the same value for both, when using the OpenSSH `authorized_keys` shim** (`gitgud-ssh`, from `mix gitgud.ssh.authorized_keys`), which runs under sshd rather than the node | random per boot |
254 254 | `GITGUD_HOOK_URL` / `GITGUD_PREHOOK_URL` / `GITGUD_AUTH_URL` (env, hook side) | Where `gitgud-hook`, `gitgud-prereceive` and `gitgud-ssh` reach the node | `http://127.0.0.1:4000/_hooks/post-receive` / `…/_hooks/pre-receive` / `…/_ssh/resolve` |
255 −| `GITGUD_PREHOOK_FAIL_OPEN` (env, hook side) | `1` lets a push through when the pre-receive (branch protection) backend is unreachable or answers with an error — a 403 from a missing or wrong hook secret included, so on an OpenSSH-shim install without `GITGUD_HOOK_SECRET` it bypasses branch protection. Off means fail closed | unset (fail closed) |
255 +| `GITGUD_PREHOOK_FAIL_OPEN` (env, hook side) | `1` lets a push through when the pre-receive (branch protection) backend is unreachable — curl missing, connection refused or timed out — or answers 5xx. Never on a 4xx such as a 403 from a missing or wrong hook secret, and never when `GITGUD_HOOK_SECRET` is unset. The node logs a warning at boot while it is set | unset (fail closed) |
256 256 | `GITGUD_IMPORT_ALLOW_PRIVATE` (env) | `1`/`true`/`yes` lets imports, mirrors and upstream sync reach private, loopback and link-local addresses (`GitGud.OutboundUrl` `allow_private: [:import]`). The scheme rule and the no-local-paths rule still apply | unset (public addresses only) |
257 257 | `GITGUD_WEBHOOK_ALLOW_PRIVATE` (env) | The same for webhook delivery (`:webhook`). Webhooks pointing at a LAN host stop delivering until this is set | unset |
258 258 | `GITGUD_FEDERATION_ALLOW_PRIVATE` (env) | The same for ActivityPub actor fetches and inbox delivery (`:federation`) | unset |
@@ -298,6 +298,7 @@ addresses, follows no redirects and pins the address it checked.
298 298 Behaviour that changed under an existing install, as of the October
299 299 2026 hardening (slice 78):
300 300
301 +- **Runner registration tokens are single-use and expire.** A repository or organization registration token now registers one runner and lapses after 24 hours (`registration_token_ttl_seconds`); tokens minted before the upgrade lapse a day after its migration. The instance-wide `GITGUD_RUNNER_REG_TOKEN` stays reusable, for pools.
301 302 - **Only writers' reviews count.** Approvals and "changes requested"
302 303 from someone without write access to the target no longer count
303 304 toward the per-repo merge rules or a protected branch's required

Parents: 77def2d