Pre-fix test suite documenting 8 auth middleware bugs found during the A-3 recon audit. Tests are written to FAIL where they assert correct post-fix behavior, and PASS where they document current buggy behavior. No bugs are fixed in this commit. Tests added: - F-A3-11 CRITICAL: WebAuthMiddleware leaks JWT secret to stdout (3 tests: secret in output, emoji in output, ETHOS format) - F-A3-7 CRITICAL: Config download requires no auth (2 tests) - F-A3-6 HIGH: Update package download requires no auth (2 tests) - F-A3-10 HIGH: Scheduler stats accepts agent JWT (2 tests) - F-A3-12 MEDIUM: Cross-type JWT token confusion (2 tests) - F-A3-2 MEDIUM: /auth/verify dead endpoint (2 tests) - F-A3-13 LOW: RequireAdmin middleware missing (1 test + 1 build-tagged) - F-A3-9 MEDIUM: Agent self-unregister no rate limit (2 tests) Current state: 10 FAIL, 7 PASS, 1 SKIP (build-tagged), 1 unchanged See docs/A3_PreFix_Tests.md for full inventory. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
10 KiB
A-3 Pre-Fix Test Suite
Date: 2026-03-28 Branch: culurien Purpose: Document auth middleware coverage bugs BEFORE fixes are applied. Reference: A-3 Auth Middleware Audit (recon findings F-A3-1 through F-A3-14)
These tests prove that the bugs exist today and will prove the fixes work when applied. Do NOT modify these tests before the fix is ready — they are the regression baseline.
Test Files Created
| File | Package | Bugs Documented |
|---|---|---|
aggregator-server/internal/api/middleware/auth_secret_leak_test.go |
middleware_test |
F-A3-11 (agent-side baseline) |
aggregator-server/internal/api/handlers/auth_middleware_leak_test.go |
handlers_test |
F-A3-11 (web middleware leak) |
aggregator-server/internal/api/handlers/downloads_auth_test.go |
handlers_test |
F-A3-7, F-A3-6 |
aggregator-server/internal/api/middleware/scheduler_auth_test.go |
middleware_test |
F-A3-10 |
aggregator-server/internal/api/middleware/token_confusion_test.go |
middleware_test |
F-A3-12 |
aggregator-server/internal/api/handlers/auth_verify_test.go |
handlers_test |
F-A3-2 |
aggregator-server/internal/api/middleware/require_admin_test.go |
middleware_test |
F-A3-13 |
aggregator-server/internal/api/middleware/require_admin_behavior_test.go |
middleware_test |
F-A3-13 (build-tagged, cannot compile yet) |
aggregator-server/internal/api/handlers/agent_unregister_test.go |
handlers_test |
F-A3-9 |
How to Run
# Middleware tests (scheduler, token confusion, RequireAdmin, agent auth)
cd aggregator-server && go test ./internal/api/middleware/... -v
# Handler tests (JWT leak, downloads auth, verify, unregister)
cd aggregator-server && go test ./internal/api/handlers/... -v
# Run specific test groups
cd aggregator-server && go test ./internal/api/middleware/... -v -run TestScheduler
cd aggregator-server && go test ./internal/api/middleware/... -v -run TestToken
cd aggregator-server && go test ./internal/api/middleware/... -v -run TestRequireAdmin
cd aggregator-server && go test ./internal/api/handlers/... -v -run TestWebAuth
cd aggregator-server && go test ./internal/api/handlers/... -v -run TestConfigDownload
cd aggregator-server && go test ./internal/api/handlers/... -v -run TestAuthVerify
Test Inventory
File 1: middleware/auth_secret_leak_test.go — Agent Middleware Baseline
TestAgentAuthMiddlewareDoesNotLogSecret
- Bug: F-A3-11 (baseline contrast — agent middleware is clean)
- Asserts: Agent AuthMiddleware does NOT print JWT secret to stdout
- Current state: PASS (agent middleware is not affected)
- Purpose: Establishes that the leak is specific to WebAuthMiddleware
TestAgentAuthMiddlewareLogHasNoEmoji
- Bug: F-A3-11 (baseline contrast)
- Asserts: Agent AuthMiddleware stdout has no emoji characters
- Current state: PASS
File 2: handlers/auth_middleware_leak_test.go — WebAuth Secret Leak
TestWebAuthMiddlewareDoesNotLogSecret
- Bug: F-A3-11 CRITICAL
- Asserts: WebAuthMiddleware stdout does NOT contain the JWT secret string
- Current state: FAIL — auth.go:128 prints
h.jwtSecretdirectly - After fix: PASS — remove secret from log output
TestWebAuthMiddlewareLogFormatHasNoEmoji
- Bug: F-A3-11 CRITICAL
- Asserts: WebAuthMiddleware stdout has no emoji (specifically U+1F513), word "secret" absent
- Current state: FAIL — output contains lock emoji and word "secret"
- After fix: PASS — use
[WARNING] [server] [auth]format
TestWebAuthMiddlewareLogFormatCompliant
- Bug: F-A3-11 CRITICAL
- Asserts: If stdout output exists, lines start with
[TAG]pattern, no secret in output - Current state: FAIL — output is emoji-prefixed, contains secret
- After fix: PASS — ETHOS-compliant format or no stdout output
File 3: handlers/downloads_auth_test.go — Unauthenticated Downloads
TestConfigDownloadRequiresAuth
- Bug: F-A3-7 CRITICAL
- Asserts: GET /downloads/config/:agent_id returns 401/403 without auth
- Current state: FAIL — returns 200 (no auth middleware on route)
- After fix: PASS — add AuthMiddleware or WebAuthMiddleware
TestConfigDownloadCurrentlyUnauthenticated
- Bug: F-A3-7 CRITICAL
- Asserts: Config download succeeds without auth (documents bug)
- Current state: PASS — no auth middleware, request reaches handler
- After fix: FAIL — update to assert 401
TestUpdatePackageDownloadRequiresAuth
- Bug: F-A3-6 HIGH
- Asserts: GET /downloads/updates/:package_id returns 401/403 without auth
- Current state: FAIL — returns 200 (no auth middleware)
- After fix: PASS — add AuthMiddleware
TestUpdatePackageDownloadCurrentlyUnauthenticated
- Bug: F-A3-6 HIGH
- Asserts: Update package download succeeds without auth (documents bug)
- Current state: PASS
- After fix: FAIL — update to assert 401
File 4: middleware/scheduler_auth_test.go — Scheduler Wrong Auth
TestSchedulerStatsRequiresAdminAuth
- Bug: F-A3-10 HIGH
- Asserts: Agent JWT is rejected on /scheduler/stats (should require admin)
- Current state: FAIL — agent JWT accepted (200)
- After fix: PASS — change to WebAuthMiddleware
TestSchedulerStatsCurrentlyAcceptsAgentJWT
- Bug: F-A3-10 HIGH
- Asserts: Agent JWT is accepted on /scheduler/stats (documents bug)
- Current state: PASS — AuthMiddleware accepts agent JWT
- After fix: FAIL — update to assert rejection
File 5: middleware/token_confusion_test.go — Cross-Type Token Confusion
TestWebTokenRejectedByAgentAuthMiddleware
- Bug: F-A3-12 MEDIUM
- Asserts: Web/admin JWT is rejected by agent AuthMiddleware
- Current state: FAIL — web JWT passes agent auth (shared secret, no audience check)
- After fix: PASS — add issuer/audience claims or separate secrets
TestAgentTokenRejectedByWebAuthMiddleware
- Bug: F-A3-12 MEDIUM
- Asserts: Agent JWT is rejected by WebAuthMiddleware
- Current state: FAIL — agent JWT passes web auth (shared secret, claims parse succeeds)
- After fix: PASS — add issuer/audience claims or separate secrets
File 6: handlers/auth_verify_test.go — Dead Verify Endpoint
TestAuthVerifyAlwaysReturns401WithoutMiddleware
- Bug: F-A3-2 MEDIUM
- Asserts: /auth/verify returns 401 even with valid JWT (no middleware sets context)
- Current state: PASS — documents the dead endpoint
- After fix: N/A (test documents pre-fix state)
TestAuthVerifyWorksWithMiddleware
- Bug: F-A3-2 MEDIUM
- Asserts: /auth/verify returns 200 when WebAuthMiddleware is applied
- Current state: PASS — demonstrates the fix is just adding middleware to the route
- Note: This test already passes because it applies WebAuthMiddleware directly. The bug is in the route registration (main.go:388), not in the handler code.
File 7: middleware/require_admin_test.go — Missing RequireAdmin
TestRequireAdminMiddlewareExists
- Bug: F-A3-13 LOW
- Asserts: RequireAdmin function exists in middleware package (AST scan)
- Current state: FAIL — function not found
- After fix: PASS — implement RequireAdmin()
File 8: middleware/require_admin_behavior_test.go — RequireAdmin Behavior
- Build tag:
//go:build ignore— cannot compile until RequireAdmin exists - Bug: F-A3-13 LOW
- Contains:
TestRequireAdminBlocksNonAdminUsers— tests admin vs non-admin role check - Current state: Cannot compile (skipped)
- After fix: Remove build tag, test should PASS
File 9: handlers/agent_unregister_test.go — Missing Rate Limit
TestAgentSelfUnregisterHasNoRateLimit
- Bug: F-A3-9 MEDIUM
- Asserts: Documents that DELETE /:id route has no rate limiter
- Current state: PASS — documents the bug
TestAgentSelfUnregisterShouldHaveRateLimit
- Bug: F-A3-9 MEDIUM
- Asserts: DELETE /:id SHOULD have rate limiter in middleware chain
- Current state: FAIL — no rate limiter on route
- After fix: PASS — add rate limiter
State-Change Summary
| Test | Current | After Fix |
|---|---|---|
| TestAgentAuthMiddlewareDoesNotLogSecret | PASS | PASS (unchanged) |
| TestAgentAuthMiddlewareLogHasNoEmoji | PASS | PASS (unchanged) |
| TestWebAuthMiddlewareDoesNotLogSecret | FAIL | PASS |
| TestWebAuthMiddlewareLogFormatHasNoEmoji | FAIL | PASS |
| TestWebAuthMiddlewareLogFormatCompliant | FAIL | PASS |
| TestConfigDownloadRequiresAuth | FAIL | PASS |
| TestConfigDownloadCurrentlyUnauthenticated | PASS | FAIL (update) |
| TestUpdatePackageDownloadRequiresAuth | FAIL | PASS |
| TestUpdatePackageDownloadCurrentlyUnauthenticated | PASS | FAIL (update) |
| TestSchedulerStatsRequiresAdminAuth | FAIL | PASS |
| TestSchedulerStatsCurrentlyAcceptsAgentJWT | PASS | FAIL (update) |
| TestWebTokenRejectedByAgentAuthMiddleware | FAIL | PASS |
| TestAgentTokenRejectedByWebAuthMiddleware | FAIL | PASS |
| TestAuthVerifyAlwaysReturns401WithoutMiddleware | PASS | PASS (unchanged) |
| TestAuthVerifyWorksWithMiddleware | PASS | PASS (unchanged) |
| TestRequireAdminMiddlewareExists | FAIL | PASS |
| TestRequireAdminBlocksNonAdminUsers | SKIP (build tag) | PASS |
| TestAgentSelfUnregisterHasNoRateLimit | PASS | PASS (unchanged) |
| TestAgentSelfUnregisterShouldHaveRateLimit | FAIL | PASS |
Bold FAIL = tests that assert correct post-fix behavior (will flip to PASS after fix). Regular PASS = tests that document current buggy state (some will flip to FAIL after fix).
Notes
-
TestAuthVerifyWorksWithMiddleware passes even in pre-fix state because it directly applies WebAuthMiddleware to the test router. The bug is not in the handler but in the route registration (main.go:388 missing middleware). This test validates that the fix is a one-line change.
-
TestAgentTokenRejectedByWebAuthMiddleware reveals that JWT cross-type confusion works in BOTH directions: agent tokens pass web auth AND web tokens pass agent auth. The
jwt.ParseWithClaimscall succeeds because both claim types share the same signing key and the JSON unmarshaling is permissive. -
require_admin_behavior_test.go uses
//go:build ignorebecause it referencesmiddleware.RequireAdminwhich does not exist. Enable this test when F-A3-13 is fixed by removing the build tag. -
All A-2 tests continue to pass (no regressions from A-3 test additions).