Skip to content

fix(router): OptionalAuthStrict on /stacks/new + DELETE /stacks/:slug + presign#205

Merged
mastermanas805 merged 2 commits into
masterfrom
fix/api-stacks-optional-auth-strict
May 30, 2026
Merged

fix(router): OptionalAuthStrict on /stacks/new + DELETE /stacks/:slug + presign#205
mastermanas805 merged 2 commits into
masterfrom
fix/api-stacks-optional-auth-strict

Conversation

@mastermanas805

Copy link
Copy Markdown
Member

Summary

T19 P1-7 (2026-05-20) migrated the seven anonymous-capable mutating provisioning endpoints from bare OptionalAuth to OptionalAuthStrict so an agent presenting a malformed/expired bearer header gets a 401 instead of silently downgrading to anonymous-tier provisioning. Three sites were missed in that wave:

  1. POST /stacks/new — multi-service anonymous-capable provision.
  2. DELETE /stacks/:slug — mutating, anonymous-capable.
  3. POST /storage/:token/presign — H46 F1 (2026-05-21) landed the strict-mode intent in the source comment but the chain itself was still bare OptionalAuth. Code now matches the comment.

GET /stacks/:slug and GET /stacks/:slug/logs/:svc intentionally stay non-strict: a logged-out tab reading an anonymous slug must not 401.

Rule-18 registry test: TestRouter_AnonymousMutatingRoutes_StrictBearer iterates the live route registry and probes each anonymous-capable mutating endpoint with a malformed bearer. Asserts 401 (strict) and asserts no-bearer is not-401 (still anonymous-capable). A future drop-back to bare OptionalAuth on any of the 10 registered routes fails this test loudly.

Coverage block (rule 17)

Symptom:        agent with bad bearer silently gets anonymous-tier
                resource + 24h TTL, no signal.
Enumeration:    rg -n 'middleware.OptionalAuth\(' internal/router/router.go
                (only mutating, anonymous-capable routes in scope).
Sites found:    3 — /stacks/new, DELETE /stacks/:slug, /storage/:token/presign.
Sites touched:  3 — all swapped to OptionalAuthStrict.
Coverage test:  TestRouter_AnonymousMutatingRoutes_StrictBearer (router_test)
                iterates the live route registry, asserts each route
                401s on a malformed bearer + does not 401 on no bearer.
Live verified:  awaiting user verification on prod after deploy
                (curl /stacks/new with `Bearer not-a-jwt` → expect 401
                instead of 503/4xx anonymous fallthrough).

Test plan

  • go test ./internal/router/ -run TestRouter_AnonymousMutatingRoutes_StrictBearer -count=1 -short — PASS (10 sub-tests).
  • go test ./internal/router/ -count=1 -short — PASS.
  • go test ./internal/middleware/ -count=1 -short — PASS.
  • go test ./internal/handlers/ -run TestPresign -count=1 -short — PASS.
  • Post-deploy curl https://api.instanode.dev/stacks/new -H 'Authorization: Bearer not-a-jwt' -X POST → expect 401 (was: 4xx anonymous-tier fall-through).
  • Post-deploy curl https://api.instanode.dev/storage/some-token/presign -H 'Authorization: Bearer not-a-jwt' -X POST → expect 401.

🤖 Generated with Claude Code

mastermanas805 and others added 2 commits May 30, 2026 21:16
… + presign

T19 P1-7 (2026-05-20) migrated /db, /vector, /cache, /nosql, /queue,
/storage, /webhook /new endpoints from bare OptionalAuth to
OptionalAuthStrict so an agent presenting a malformed/expired bearer
header gets a 401 instead of silently downgrading to anonymous-tier
provisioning. Three sites were missed in that wave (rule 17 surface
miss / MR-P1-38 follow-up):

  1. POST /stacks/new — multi-service anonymous-capable provision.
  2. DELETE /stacks/:slug — mutating, anonymous-capable.
  3. POST /storage/:token/presign — H46 F1 (2026-05-21) landed the
     OptionalAuthStrict intent in the source comment but the chain
     itself was still bare OptionalAuth. Code now matches the comment.

GET /stacks/:slug and GET /stacks/:slug/logs/:svc intentionally stay
non-strict: a logged-out tab reading an anonymous slug must not 401.

Coverage block (rule 17):

  Symptom:        agent with bad bearer silently gets anonymous-tier
                  resource + 24h TTL, no signal.
  Enumeration:    rg -n 'middleware.OptionalAuth\(' internal/router/
                  router.go (only mutating, anonymous-capable routes
                  in scope).
  Sites found:    3 — /stacks/new, DELETE /stacks/:slug,
                  /storage/:token/presign.
  Sites touched:  3 — all three swapped to OptionalAuthStrict.
  Coverage test:  TestRouter_AnonymousMutatingRoutes_StrictBearer in
                  internal/router/optional_auth_strict_coverage_test.go
                  iterates the live route registry and probes each
                  anonymous-capable mutating endpoint with a malformed
                  bearer. Asserts 401 (strict) and also asserts no-
                  bearer is not-401 (still anonymous-capable). A future
                  drop-back to bare OptionalAuth on any of the 10
                  registered routes fails this test loudly.
  Live verified:  awaiting user verification on prod after deploy
                  (curl /stacks/new with Bearer not-a-jwt → expect
                   401 instead of 503/4xx anonymous fallthrough).

Also updated the existing TestPresign_RegistryHasMiddleware +
TestPresign_TestHelpersMirrorMiddleware needles + the testhelpers
mirror so the strict variant is the asserted-required wiring (the
old needle matched both variants by prefix; pinning strict catches
regressions explicitly).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@mastermanas805 mastermanas805 merged commit 243e10b into master May 30, 2026
15 checks passed
@mastermanas805 mastermanas805 deleted the fix/api-stacks-optional-auth-strict branch May 30, 2026 16:06
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