Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 11 additions & 6 deletions charts/workspace/templates/ingress-claude-api.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,17 @@ spec:
http:
paths:
# The capture group is re-applied by rewrite-target (/$1), so the path
# reaches BrowserHandler unchanged. Covers the task API, memory store,
# the metrics/health probes the mobile client polls, and the Applications
# surface (list + reverse proxy + the WebView session bootstrap under
# api/claude/) — the app proxy accepts a Bearer token or the scoped
# kc_app_session cookie it mints (see server.py check_app_proxy_auth).
- path: /(api/claude/.*|api/memory.*|api/apps|api/app-proxy/.*|api/desktop.*|api/terminal-proxy.*|api/missioncontrol/.*|metrics|health)
# reaches BrowserHandler unchanged. The whole API surface routes here
# deliberately (issue #428): auth is enforced server-side, per endpoint —
# the /bearer-api/ marker makes check_claude_auth demand the Bearer token
# and distrust identity headers (#161), so an enumerated whitelist added
# no security boundary while silently 404ing every API added after #174
# for the mobile app (hypervisor, files, skills, gateway, …). The only
# /api endpoint that skips check_claude_auth is the WhatsApp webhook
# verify, which is provider-signature-gated and already public via its
# own ingress. /metrics is token-checked; /health is a plain liveness
# probe and intentionally open.
- path: /(api/.*|metrics|health)
pathType: ImplementationSpecific
backend:
service:
Expand Down
32 changes: 32 additions & 0 deletions charts/workspace/tests/bearer_api_ingress_test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
suite: Bearer-token API ingress path coverage (issue #428)
templates:
- templates/ingress-claude-api.yaml
values:
- test-values.yaml
set:
ingress.auth.type: oauth2
oauth2.cookieSecret: dGVzdGNvb2tpZXNlY3JldDEyMzQ1Njc4OTAxMjM0NTY=
oauth2.clientId: test-client
oauth2.clientSecret: test-secret
tests:
- it: routes the whole /api surface so new endpoints can never silently miss the mobile path
asserts:
- equal:
path: spec.rules[0].http.paths[0].path
value: /(api/.*|metrics|health)
- equal:
path: spec.rules[0].http.paths[0].backend.service.port.number
value: 6080

- it: keeps the /bearer-api marker rewrite that pins server-side Bearer-only auth (#161)
asserts:
- equal:
path: metadata.annotations["nginx.ingress.kubernetes.io/rewrite-target"]
value: /bearer-api/$1

- it: is absent outside oauth2 auth mode (basic ingress catch-all covers the API)
set:
ingress.auth.type: basic
asserts:
- hasDocuments:
count: 0