hub v0.152.0: operator access tokens with scopes (09 §3 decision 251, operator 2026-10-15 11:38)
gates / gates (push) Successful in 6m44s
gates / gates (push) Successful in 6m44s
- Configuration → Access tokens: named, scoped (group read/write), expiring (≤365 d), shown once, stored SHA-256 only, every use logged by name. Bearer fhp_… on the web surface only; /api/v1 refuses it. - Route table = the code's single source (web/routes.go), pinned to ServeHTTP's switch; session-only: secrets shown/minted, deletes/resets, password, tokens. - R-952 closed: /api/v1 route table names each caller, pinned to the switch; no-credential refusal test. - Fail-open fixed: an empty operator password served the UI open (main skipped RequireAuth). Live hub never open. - 05 §17, 04 §6.2, 13, 09 §3 251; register 155→157 (+R-1054, R-1055, R-1056, −R-952); STATUS. - website: prowlarr-logo.svg (byte copy from felhom.eu-media) — the site gate refused every push. Not deployed — waits for the operator's yes. Claude-Session: https://claude.ai/code/session_012qRErfCoiTkvDK9N5XHbzb
This commit is contained in:
@@ -245,6 +245,15 @@ func (h *Handler) requireGlobalKey(w http.ResponseWriter, r *http.Request) bool
|
||||
func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
path := strings.TrimPrefix(r.URL.Path, "/api/v1")
|
||||
|
||||
// An operator access token (`05` §17, prefix fhp_) never reaches the box API: not a box route, not a global-key
|
||||
// route. Refused here, before any handler, so no route can accept one by accident. Pinned by
|
||||
// TestAPI_AccessTokenIsRefusedEverywhere.
|
||||
if auth := r.Header.Get("Authorization"); strings.HasPrefix(strings.TrimSpace(strings.TrimPrefix(auth, "Bearer ")), store.APITokenPrefix) {
|
||||
h.logger.Printf("[WARN] access token refused on the box API: %s %s", r.Method, r.URL.Path)
|
||||
http.Error(w, "Forbidden: access tokens are not accepted on /api/v1", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
switch {
|
||||
case r.Method == http.MethodPost && path == "/report":
|
||||
h.handleReport(w, r)
|
||||
|
||||
Reference in New Issue
Block a user