Add route authorization manifest and CI check (#598) - #1208
Open
ptone wants to merge 5 commits into
Open
Conversation
added 5 commits
August 22, 2026 13:07
Every route registered in registerRoutes() must now appear in pkg/hub/route_authz_manifest.go declaring its authorization posture (public, auth-flow, authenticated, admin, workstation, broker-hmac, webhook, agent-token, oidc-public). This closes the gap identified in the authz-guards check (hack/check-authz-guards.sh lines 55-63): a handler with no authorization at all was invisible to any lexical rule. Deliverables: - pkg/hub/route_authz_manifest.go: manifest covering all 147 routes - hack/check-route-authz-manifest.sh: security-grade lint with --self-test - Makefile: check-route-authz-manifest target, added to check-custom - CI: dedicated workflow step with distinct error annotations - hack/check-project-compat-literals.sh: allowlist entry for manifest file Closes #598. Part of #1193 (CI custom linter framework).
- CI step: match authz-guards precedent with explanatory comment and detailed NOTHING WAS ANALYSED annotation for the * case - Replace grep -P (GNU Perl regex) with POSIX sed in all 4 extraction sites (self-test and main script) for macOS compatibility - Add lint-only artifact comment to routeAuthzManifest var declaration
Add nolint:unused directive to routeAuthzManifest var in route_authz_manifest.go — the var is a lint-only artifact consumed by hack/check-route-authz-manifest.sh, not Go code. Add shellcheck disable=SC2001 before two sed 's/^/ /' lines in check-route-authz-manifest.sh — prepending to each line of a multiline string requires sed; bash parameter expansion cannot do this.
gofmt requires an empty comment line between a doc comment block and a //nolint directive. Without it, gofmt treats the nolint line as part of the doc comment and reformats it, causing CI to fail.
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.
Summary
Closes #598. Part of #1193 (CI custom linter framework, Phase 3).
Every route registered in
registerRoutes()must now appear in a manifest declaring its authorization posture. This closes the gap identified in the authz-guards check (hack/check-authz-guards.shlines 55-63): a handler with no authorization at all was invisible to any lexical rule because there was no guard to key on.Deliverables
pkg/hub/route_authz_manifest.go— Go map covering all 147 routes with their verified authorization posture (public,auth-flow,authenticated,admin,workstation,broker-hmac,webhook,agent-token,oidc-public)hack/check-route-authz-manifest.sh— security-grade lint script (exit 3 on missing tools, not exit 0) with--self-testmodecheck-route-authz-manifesttarget added as dependency ofcheck-custom::error title=annotationhack/check-project-compat-literals.sh— allowlist entry for manifest file (references/api/v1/groves/*paths as registered routes)Authorization posture verification
Each route's posture was verified by reading the handler implementation, not just the registration pattern:
isUnauthenticatedEndpoint()(auth.go:426) confirmed asauth-flow/public/webhookuser.Role() != "admin"requireWorkstation()middlewareGetBrokerIdentityFromContext()GetAgentFromContext()/metrics,/api/v1/settings/public,/api/v1/auth/me,/api/v1/auth/tokens[/],/api/v1/auth/invite/redeemrequire auth despite names/comments suggesting otherwise — classified asauthenticated/api/v1/metrics/and/api/v1/admin/metrics-dashboardintentionally open to all authenticated users (not admin-only)Test plan
./hack/check-route-authz-manifest.sh --self-testpasses./hack/check-route-authz-manifest.shreports 0 violations (all 147 routes covered)make check-custompassesmake cipasses