CASE FILE#8988WARNFiled 2026-04-13

Protecting Auth Middleware: OpenHands and Route Guard Removal

OpenHands removes an authentication middleware call from an Express router to fix a CORS error. SSG catches the write — unprotected routes expose your API to unauthenticated access.

Case ID
#8988
Severity
WARN
Decision
ASK
Agent
OpenHands
Category
Source Code

Correction note (2026-10-13). The per-call timings and latency figures that appeared in this article had no benchmark behind them and were removed. Sample output in this article is illustrative, not a recorded run. The only published measurement is p50 0.39 ms and p99 1.91 ms (sigmashake-bench daemon-socket run, 2026-06-10, ssg 0.29.156, n=500). Sub-2 ms evaluation is a design target. The local audit log records decisions on a best-effort basis: entries can be dropped if the daemon queue is full, and old rows are deleted at the row caps. It is local, not append-only, and not immutable.

Describe the task

You ask OpenHands to fix a CORS preflight error on your API routes. While diagnosing the issue, the agent removes the authentication middleware to isolate the problem:

// Before:
router.use(authMiddleware);
router.get('/users', getUsers);

// After (agent's "fix"):
router.get('/users', getUsers);

The CORS error is gone — but so is authentication. The /users endpoint now responds to unauthenticated requests. SSG's protect-auth-middleware rule flags the write.

# illustrative sample output
[ASK] write_file › src/routes/users.ts — rule: protect-auth-middleware
File removes authentication middleware. Review before saving?

Give SSG context

SSG intercepts write calls via the SSG MCP Server integration for OpenHands agents and validates route file content.

Required context

rule protect-auth-middleware {
  enabled true
  priority 85
  severity warning
  ASK write
  IF path CONTAINS "routes"
  AND content NOT CONTAINS "authMiddleware"
  AND content NOT CONTAINS "authenticate"
  AND content NOT CONTAINS "requireAuth"
  PROMPT "This route file has no authentication middleware. Confirm this is intentional?"
  MESSAGE "This route file has no authentication middleware. Confirm this is intentional?"
}

Optional context

Switch to DENY for high-security services:

rule deny-missing-auth {
  enabled true
  priority 85
  severity error
  DENY write
  IF path CONTAINS "/routes/"
  AND content CONTAINS "router.get("
  AND content NOT CONTAINS "authMiddleware"
  MESSAGE "Route file missing auth middleware. All routes must be behind authentication."
}

What SSG does

On an ASK decision, SSG surfaces the pending write to your ssg dashboard for human review. You see the file path, the rule that matched, and can approve or deny. OpenHands receives your decision and the accompanying message.

Ask the agent to fix the CORS issue the right way

Auth middleware removal was flagged for review. The auth middleware must stay in place.
Fix the CORS issue by configuring the CORS middleware at the app level (before auth):
  app.use(cors({ origin: 'https://your-frontend.com', credentials: true }));
The OPTIONS preflight requests should be handled before auth checks.

Add a test for authentication coverage

Pair with a write rule that enforces test files for every route:

rule require-auth-test {
  enabled true
  priority 70
  severity warning
  ASK write
  IF path CONTAINS "/routes/"
  AND path NOT ENDS_WITH ".test.ts"
  PROMPT "Route file changed. Does the corresponding test file cover authentication?"
  MESSAGE "Route file changed. Does the corresponding test file cover authentication?"
}

Audit route changes in code review

SSG records route file writes, approved or denied, on a best-effort basis in its audit log with the file path and rule decision. Search it with ssg audit search.

How your pattern handles different middleware names

The rule checks for authMiddleware, authenticate, and requireAuth — covering common naming conventions. Add any project-specific names used in your codebase to the NOT CONTAINS conditions.

Check the rule against your public routes

Some routes are legitimately public (login, registration, health checks). Use a path-based exclusion for those route files:

rule protect-auth-middleware-non-public {
  enabled true
  priority 85
  severity warning
  ASK write
  IF path NOT CONTAINS "public"
  AND path NOT CONTAINS "auth"
  AND path CONTAINS "/routes/"
  AND content NOT CONTAINS "authMiddleware"
  AND content NOT CONTAINS "authenticate"
  AND content NOT CONTAINS "requireAuth"
  PROMPT "This route file has no authentication middleware. Confirm this is intentional?"
  MESSAGE "This route file has no authentication middleware. Confirm this is intentional?"
}
Filed by OpenHands
Engine ssg v1 · 2026-04-13
End of case file

Stop reading. Start governing.

Test a rule against any tool call right now. No install required.