docs(review): 008 — HTTP-door consumer evidence (LFS Basic auth, route-fallback constraint)
Report-only from alkgit's LFS POC: AH-1 the shared bearer middleware is Bearer-only while real git-lfs authenticates Basic on the batch; AH-2 extras doors cannot carry a second route fallback (docs-only record). No mechanism change fixed here; dispositions session-owned.
This commit is contained in:
1 parent
449661eb87
commit
1cac63fdba
1 file changed
+94
@@ -0,0 +1,94 @@
|
||||
# Review 008 — First HTTP-door consumer evidence: shared auth vs LFS Basic, and the extras route-fallback constraint
|
||||
|
||||
## Status
|
||||
|
||||
Open — filed 2026-10-17. Report-only consumer input from alkgit's LFS
|
||||
POC (POC-L, 2026-10-16; findings at
|
||||
`/workspace/@alkdev/alkgit/docs/research/pocl-findings.md`; the POC
|
||||
crate is `/workspace/lfs-poc`, which served a real `git-lfs` 3.7.0
|
||||
client through `with_extra_routes` doors). Ask ledger source: alkgit's
|
||||
`docs/research/substrate-recomposition.md` §Upstream-push
|
||||
candidates #6/#9 (the alkhttp-named items; the gateway-dispatch half
|
||||
of #6 is filed where it belongs — alkcall review 012).
|
||||
|
||||
## Scope
|
||||
|
||||
Two findings, both from the same consumption round (an LFS batch-API
|
||||
door on the extras router). Neither was discovered by a source sweep;
|
||||
both anchors were re-verified by targeted read this session. Severity
|
||||
and shape are the consumer seat's; the disposition belongs to this
|
||||
crate's own session.
|
||||
|
||||
## AH-1 [small, contract-visible] — The shared bearer middleware is Bearer-only; LFS clients authenticate with Basic on the batch
|
||||
|
||||
**Anchor.** `src/server/auth.rs` — the shared identity middleware
|
||||
(`bearer_auth_middleware`); the module doc states the semantics
|
||||
explicitly: *"Malformed `Authorization` header (not `Bearer <token>`)
|
||||
→ `None` (treated as no-token, not an error — Bearer-only is the auth
|
||||
mechanism)"* (lines 1–20, verified this session).
|
||||
|
||||
**Evidence.** Real `git-lfs` 3.7.0 authenticates the batch endpoint
|
||||
with **Basic** credentials (URL userinfo — the spec-shape behavior of
|
||||
the official client; its config is `http://user:pass@host/repo`). An
|
||||
extras door mounted on the shared middleware therefore receives the
|
||||
batch request with the middleware already having resolved `None`
|
||||
(the Basic header is not `Bearer`) — the door had to parse the
|
||||
Authorization header a second time (Basic *or* Bearer) to get any
|
||||
identity at all. The POC's door resolved both schemes locally and
|
||||
passed the real client; the shared middleware contributed nothing on
|
||||
this request shape.
|
||||
|
||||
**Why it matters beyond LFS.** The middleware is shared by gateway
|
||||
endpoints and `to_mcp`; any HTTP-door surface whose
|
||||
real-world client authenticates with Basic (LFS today; git's
|
||||
smart-HTTP transport's basic auth is tomorrow's `git` door) silently
|
||||
loses identity resolution at the middleware and every door
|
||||
re-implements the fallback — the exact quiet-bypass shape review 012
|
||||
(alkcall) records for the ownership seam, one layer up in the same
|
||||
stack.
|
||||
|
||||
**Recommended shape (own session, to be re-derived)**: tolerate Basic
|
||||
userinfo in the shared middleware — parse `Basic base64(user:pass)`
|
||||
into the identity provider's resolve path (or expose a documented
|
||||
per-door hook that receives the raw header before the None fold-in),
|
||||
keeping the current "resolve fails → None" fallback semantics. The
|
||||
doc line "Bearer-only is the auth mechanism" should flip to match
|
||||
whatever lands. Small surface; the decision is whether Basic
|
||||
resolution belongs in the shared middleware (uniform) or stays a
|
||||
door concern (explicit).
|
||||
|
||||
**Verification status**: middleware semantics re-read this session;
|
||||
the client behavior is POC-L's recorded route-shape fact (real
|
||||
client, live). Re-verify by pointing a stock `git-lfs` at a
|
||||
shared-middleware door during resolution.
|
||||
|
||||
## AH-2 [recorded constraint, no ask yet] — Extras doors cannot carry a route fallback; door route tables must be static shapes
|
||||
|
||||
**Anchor/evidence.** POC-L, live: the merged extras router already
|
||||
owns a fallback route (the decoy), and axum refuses a second merge —
|
||||
a door attempting `fallback_layer`/merge fallback on the merged
|
||||
router panics **at construction**. Consequence: door route tables
|
||||
must be statically enumerated; multi-segment repo namespaces
|
||||
(`/user/repo/objects/batch` style) need enumerated pattern routes
|
||||
(`/{user}/{repo}/...` shape), not a dynamic-fallback match. The POC
|
||||
door's static shapes worked for every e2e case.
|
||||
|
||||
**Disposition space.** This is a structural fact of the current
|
||||
router assembly, currently undocumented on the door-facing surface —
|
||||
worth one doc line in the extras/hooks documentation ("route tables
|
||||
are static; no second fallback; enumerate multi-segment patterns
|
||||
explicitly") regardless of whether any mechanism change is ever
|
||||
wanted. Not a mechanism ask today; recorded so the next door author
|
||||
does not rediscover the construction panic.
|
||||
|
||||
## What this review asks for
|
||||
|
||||
| # | Item | Class |
|
||||
|---|---|---|
|
||||
| AH-1 | Basic tolerance (or a documented pre-resolution hook) in the shared identity middleware | small change + doc flip, own session |
|
||||
| AH-2 | doc line: extras route tables are static; no second fallback | docs-only, ride-along |
|
||||
|
||||
Nothing here blocks any door surface that resolves identity
|
||||
door-side (the proven compensation), but the shared-middleware trap
|
||||
(AH-1) compounds alkcall review 012's gateway trap for every future
|
||||
External-facing door — the two are worth one resolution round each.
|
||||
Reference in new issue
Block a user