Repository navigation
Conversation
Proxy mode, imported next, replaces it: walgit takes identity and access from an identity-aware proxy that proves itself with a shared secret, instead of trusting X-Walgit-Principal from anyone that can reach a none-mode listener and making every caller an admin. none mode is loopback-only again. D53 is withdrawn.
…are proxy
Deployments that already authenticate and authorize at a gateway (JWT
verification plus an external authorizer) had one way to hand walgit the
verdict: `mode = "none"` + `X-Walgit-Principal`. That makes everyone admin,
lets any loopback caller name anyone, and gives every forwarded name write.
`server.auth.mode = "proxy"` makes the contract explicit and fail-closed:
- `X-Walgit-Principal` is required (401 without it); there is no anonymous
access (`anonymous_read` must be false).
- `X-Walgit-Access: read | write | admin` is required (missing or unknown:
403). admin implies write, write implies read. Nothing in the config
grants admin; `tokens`, `trusted_forwarders` and `admin_*` are refused.
- Off loopback the proxy proves itself with `X-Walgit-Proxy-Secret`, the
value of `$<proxy_secret_env>` (>= 32 bytes, SHA-256 digests compared in
constant time, checked before any other header is read). `validate`
refuses a non-loopback listen without it; an unresolvable secret fails
startup. Loopback (the sidecar shape) may omit it.
- Repeated identity headers are refused: something appended instead of
replacing.
- Optional `X-Walgit-Owners: <owner>[,<owner>…] | *` narrows what exists
for the caller: owner listings omit the rest, `…/owners/{o}/repos` lists
`[]`, and every route under an out-of-scope owner answers the same 404 as
a missing repository (never 403). Enforced by one `route_layer` over all
matched `{owner}/{repo}` routes plus a check in `dispatch_route` for git
smart HTTP and LFS, so new repository routes inherit it. An
unauthenticated request falls through to its handler's own 401/403.
- None of `X-Walgit-Access`, `X-Walgit-Owners`, `X-Walgit-Proxy-Secret` is
read in any other mode.
The principal name feeds logs, `policy.json` and push attribution as in
every other mode. Documented as D50 and in §1.3 of AGENTS.md, the README
auth table, `walgit.example.toml` and web/API.md.
No round trips added: header parsing only, no store access.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit ebffeb9)
Three review points on proxy mode: - The secret from `proxy_secret_env` is trimmed the way the header value is, so a secret file or Kubernetes Secret ending in a newline no longer fails every request. A blank result is refused at startup; the 32-byte floor counts after trimming. - A missing, wrong or repeated proxy secret (and a repeated X-Walgit-Principal) is a new `AuthError::UntrustedProxy`: 403 with a body naming the misconfigured proxy, no WWW-Authenticate, and an in-band ERR for git clients. Never a 401, which makes git erase the user's stored credential although that credential is not what failed. Not a 5xx either, since a proxy retries 5xx from its upstream and a caller bypassing the proxy is simply refused. - The secret is required in proxy mode on every listen address. The loopback exemption is gone: in the sidecar shape every container of the pod shares loopback, so reaching 127.0.0.1 does not identify the proxy. The sidecar still works; it injects the header from a Secret. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit af56d86)
The workspace forbids string slicing (clippy::string_slice); the test asks for the same truncated secret through str::get.
dumontg
added a commit
that referenced
this pull request
Oct 7, 2026
Owner
Author
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #20.
Removes
server.auth.unauthenticated_public_bind(#4) and imports tobi/walgit#96 by @jonasgrosch with its follow-up. In proxy mode an identity-aware proxy in front asserts the principal and access level in required headers, proves itself with a shared secret off loopback, and can narrow visible owners. Unlikenonebehind a front, callers are not all admins and a header from a client that bypassed the proxy is not trusted.noneis loopback-only again.Conflicts: tobi#96 numbered its decision D50, which tobi#100 already uses here, so it is D55 in this fork (AGENTS.md and code comments); the README row and the API tests from both sides are kept.
Verified on the top of this stack:
cargo clippy --workspace --all-targets -- -D warnings,cargo fmt --check, the crate test suites, and the Azure harness (just test-azure: store contract plus git push, clone, pull and cold restart on Azurite) pass. Known unrelated failures: the runtime stall timing tests ine2e(also intermittent on main) and the web UI asset tests that needpnpm run build.