Files
alkgit/docs/architecture/decisions/007-acl-before-advertisement.md
T
glm-5.3-flash 8f73da5d12 docs(architecture): phase 1 bootstrap — specs, 9 ADRs, OQ tracker
Architecture documentation structure per sdd_process phase 1:

- README index (doc table, ADR table, lifecycle), overview with crate
  map, dependency rules, and security invariants
- Component specs: storage, transport, http, ssh, alkgitd (all draft)
- ADRs 001-009: crate decomposition, front-door-blind core, V2-first
  protocol, pack pipeline (data::output generation / data::input
  ingestion), session substrate types, http adapter composition
  (proposed, OQ-01), ACL-before-advertisement, registry-resolved repo
  identity, bounded-resources budgets
- open-questions.md: OQ-01..08 with two deferred(scope), one
  deferred(unclear), door-type definitions, blocker tracker tasks in
  tasks/architecture/
- v1 ssh-door decision recorded: russh terminates wire SSH in alkgitd;
  alkcall channels stay the internal substrate (OQ-03 partially
  resolved)

Two review rounds (fresh-context subagent): 4 critical + 17 warnings
fixed in round one; zero critical + 4 warnings + 5 suggestions fixed in
round two. All ADR/OQ cross-references verified resolving.
2026-09-21 03:55:33 +00:00

64 lines
3.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ADR-007: ACL runs before any advertisement or ref line
## Status
Accepted
## Context
Ref names leak repository existence (and structure). The advertisement is
the first thing a client sees; if ACL runs after advertisement begins, a
denied caller has already learned that a repo (or a ref within it) exists.
The vision's visible-surface = authorized-surface invariant requires the
check to run before the first byte of git protocol content.
POC-1 observed the natural enforcement point on the git:// path: the repo
name arrives in-band in the first request line, *before* any ref data — so
the resolve-then-authorize step sits structurally ahead of the first
emitted line. POC-3 noted the http extra-routes are registered permissive
by default (the gateway bearer layer does not cover them) — making the
http-side check an explicit alkgit-http responsibility, not an inherited
one.
## Decision
Every session/request performs, in order, before any protocol output:
1. Extract the wire repo name (git:// first-request line; ssh exec command
string; http path segment).
2. Resolve it against the registry to (repo id, storage root) — reject
unknown repos with the same error as unauthorized ones (no existence
oracle) (ADR-008).
3. Run alkcall `AccessControl::check(peer_identity)` against the repo's
required access. Read access covers the *whole fetch surface*:
advertisement, ref listing, and pack transfer alike — anonymous access
on explicitly-public repos grants the same full read path
(vision §"Primary deployment target" makes anonymous clone first-class;
the "advertisement is the only anonymous surface" line in the same
doc's principle 1 is read as the *minimum* boundary, and this decision
sets the operative rule).
4. Only then hand the session to transport.
Adapters embed this sequence; transport asserts it (the session entry
points take an authorized-repo marker — a type the adapter constructs only
after step 3 passes — so skipping the check is a type error, not a runtime
log) but does not re-check — authorization evaluation lives in one place,
alkcall, and invocation/wiring lives in one place, the adapter.
Push is always authenticated on every repo, no exceptions (vision §
"Primary deployment target").
## Consequences
- No ref/capability line is ever emitted for a repo a caller cannot see;
the gitea-class "enforcement elsewhere" bug is structurally excluded.
- Unknown-repo and unauthorized errors are indistinguishable to callers.
- The check is cheap (registry lookup + ACL check) and runs before any
expensive protocol work.
- http adapters must wire ACL explicitly for their routes (POC-3 showed
alkhttp extra routes default permissive) — http.md encodes this.
## References
- `docs/research/vision.md` §"Guiding principles" 1–2, §"Immediate threat-model notes"
- `docs/research/poc-1-findings.md` follow-up 4; `docs/research/poc3-findings.md` §"does NOT settle" (auth)
- alkcall ADR-017 (privilege model)
- ADR-008 (repo identity), http.md §auth, ssh.md §auth