Commit b15e44d
committed
fix(runtime): domain claims and the membership skip list stop at a segment boundary
`DomainRoute.match` defaulted to `'prefix'` — a bare `path.startsWith(prefix)`
with no segment boundary — and ten shipped routes carried that implicit
default, so `/datax`, `/metaxyz`, `/uifoo`, `/aixx` and `/packagesomething`
were each claimed by a domain that does not own them. `/auth` was the
eleventh member of the family and was repaired on its own; this closes the
rest at the seam so the next domain added is boundary-correct by default.
The default is `'segment'` now. `match: 'prefix'` still buys the legacy bare
`startsWith` claim for a route that asks for it in writing, and the three
`?`-suffixed routes (`/keys?`, `/mcp?`, `/mcp/skill?`) declare it — a prefix
ending in `'?'` has no `/` after it, so a segment match cannot express the
query-string form at all.
`enforceProjectMembership`'s control-plane skip list carried the same
predicate with a worse consequence: a claim that is too wide sends traffic
somewhere wrong, a skip list that is too wide sends traffic past a check.
`/authentication/foo` satisfied `startsWith('/auth')` and was waved past the
membership check. Its boundary is `'/'`, `'?'` or end-of-string, so
`/auth?redirect=...` keeps the exemption it has today.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015QE8qk46e5CHJxyQEUjbf81 parent 19bf8c0 commit b15e44d
1 file changed
Lines changed: 13 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
0 commit comments