Skip to content

fix(api): authenticate reflector endpoints + pin govulncheck (security P0) - #398

Merged
krisarmstrong merged 1 commit into
mainfrom
harden/stem-phase0-security
Jun 7, 2026
Merged

fix(api): authenticate reflector endpoints + pin govulncheck (security P0)#398
krisarmstrong merged 1 commit into
mainfrom
harden/stem-phase0-security

Conversation

@krisarmstrong

Copy link
Copy Markdown
Collaborator

Phase 0 — stem security P0 (per the stem/niac remediation plan).

What

  1. Authenticate the reflector endpoints. POST/GET /api/v1/reflector/{config,stats} were registered with raw mux.Handle + only a rate limiter — no authentication. Any network client could reconfigure or inspect the dataplane. Now routed through handleAuthRateLimited (auth + rate limit), matching every other mutating route.
  2. Pin govulncheck @latest -> @v1.3.0 (CLAUDE.md: never @latest).

Tests

Updated the reflector tests to authenticate (the suite previously encoded the insecure assumption that these endpoints were open). Added/inverted TestReflectorEndpointsRequireAuth to assert unauthenticated access now returns 401. Full internal/api package passes.

Scope note

This is the bounded, high-impact slice. CSRF rekey to sha256(session) + fail-closed, and the CORS operator-allowlist (Config.Validate()), follow as separate Phase-0 changes (they need care not to break the setup/recovery flow and LAN-appliance access).

POST/GET /api/v1/reflector/{config,stats} were registered with only a rate
limiter (no auth) — any client on the network could reconfigure or inspect the
dataplane. Route them through handleAuthRateLimited so a valid token is
required; update the reflector tests to the authenticated behavior (and invert
the old 'endpoints don't require auth' test).

Also pin govulncheck @latest -> @v1.3.0 per CLAUDE.md (never @latest).

Phase 0 of the stem security hardening. CSRF rekey + CORS allowlist follow.
@github-actions

github-actions Bot commented Jun 7, 2026

Copy link
Copy Markdown
Contributor

License Compliance Report

All dependencies pass license compliance checks

Go Dependencies

  • Unknown: 31 package(s)
  • MIT: 26 package(s)
  • BSD-3-Clause: 16 package(s)
  • Apache-2.0: 11 package(s)
  • BSD-2-Clause: 1 package(s)

npm Dependencies

See full report in workflow artifacts

Allowed Licenses: MIT, Apache-2.0, BSD-*, ISC, CC0-1.0, MPL-2.0
Forbidden: GPL, AGPL, SSPL (strong copyleft)

@krisarmstrong
krisarmstrong enabled auto-merge (squash) June 7, 2026 04:47
@krisarmstrong
krisarmstrong merged commit 7d9a4e3 into main Jun 7, 2026
28 checks passed
@krisarmstrong
krisarmstrong deleted the harden/stem-phase0-security branch June 7, 2026 04:52
krisarmstrong added a commit that referenced this pull request Jun 8, 2026
#401)

Routes are now declared as data and a single register()/registerAll() composes
their per-route policy — rate limit, authentication — in one canonical order, so
a route cannot ship without its policy. This replaces the scattered imperative
handleAuthRateLimited/handleRateLimited/mux.Handle calls where the wrapper
nesting could be forgotten — the regression class that left
POST /api/v1/reflector/config unauthenticated (#398).

- internal/api/route.go: route{} + register()/registerAll() + methodGate, a
  routeManifest, and the /__capabilities introspection endpoint.
- setupRoutes: all ~40 API routes converted to declarative route{} entries,
  preserving each route's exact auth flag + rate limiter. Removed the now-unused
  handleAuthRateLimited/handleRateLimited helpers.
- scripts/check-route-policy.sh: CI gate failing if any /api route is registered
  directly instead of via register(). Wired into ci.yml.
- route_test.go: asserts /__capabilities records policy (reflector=auth,
  login=no-auth).

Enforcement by construction (Phase 3). Full internal/api suite green; golangci
golden config 0 issues. niac registry follows.

Co-authored-by: Kris Armstrong <kris.armstrong@icloud.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant