feat(binjovi): route the staging dashboard on binjovi.dev through Oathkeeper #116

Merged
binjovi-bot merged 1 commit from feat/binjovi-dev-dashboard-routes into trunk 2026-09-13 12:42:48 +00:00
Owner

Second of three pull requests that make the staging dashboard at https://binjovi.dev/ open in a normal browser. The client registration is seanfarm #703; the proxy Deployment, the route split and the origin allow-list follow in binjovi.

Kratos pins its session cookie to sean.farm, so a browser on binjovi.dev never carries a session, and the app answers 401 invalid_identity to every operator. The design keeps Oathkeeper as the first hop for binjovi.dev, exactly as for production, so the availability gate keeps the 401 it expects from an anonymous request. What changes is where the session comes from.

  • Every browser rule on binjovi.sean.farm (dashboard, services page, assets, api reads, and the two /api/v1/ui/ command routes) gains a binjovi-dev-* twin with the same route and methods.
  • Each twin's cookie_session authenticator asks the login proxy on the host, binjovi-staging-login.binjovi-staging.svc:4180/oauth2/userinfo, instead of Kratos, with subject_from: email and extra_from: '@this'. The jwt authenticator stays as the fallback.
  • The id_token mutator's claims template reads email from .Extra.email, which is where the proxy's user info carries it, so the app receives the same identity token shape it already verifies (iss https://auth.sean.farm/oathkeeper, aud binjovi). No change to the app's auth config.
  • Per-rule errors: an HTML request with no session is redirected to https://binjovi.dev/oauth2/start?rd=<url>; anything else keeps the JSON 401. Oathkeeper is v0.40.9, which supports per-rule handler config and per-rule errors.
  • Upstream is binjovi-staging.binjovi-staging.svc:80, never the production Service.
  • A ReferenceGrant lets the HTTPRoute in binjovi-staging reach Service/oathkeeper-proxy, as binjovi-to-oathkeeper does for production.

tests/binjovi-dev-route-contract.sh, wired into tests/check.sh, proves each twin carries its production route and method set, the proxy user info, the claims template, the redirect, the staging upstream, that exactly six rules reach staging, that no binjovi-dev-* rule reaches the production app, and that the grant names the staging namespace. It was red before the rules and is green after; tests/check.sh passes in full; the rule list parses as one YAML sequence of 49 unique ids.

https://claude.ai/code/session_01XdBRc9CHgFhAxCyHbdVtt6

Second of three pull requests that make the staging dashboard at `https://binjovi.dev/` open in a normal browser. The client registration is seanfarm #703; the proxy Deployment, the route split and the origin allow-list follow in binjovi. Kratos pins its session cookie to `sean.farm`, so a browser on `binjovi.dev` never carries a session, and the app answers `401 invalid_identity` to every operator. The design keeps Oathkeeper as the first hop for `binjovi.dev`, exactly as for production, so the availability gate keeps the 401 it expects from an anonymous request. What changes is where the session comes from. - Every browser rule on `binjovi.sean.farm` (dashboard, services page, assets, `api` reads, and the two `/api/v1/ui/` command routes) gains a `binjovi-dev-*` twin with the same route and methods. - Each twin's `cookie_session` authenticator asks the login proxy on the host, `binjovi-staging-login.binjovi-staging.svc:4180/oauth2/userinfo`, instead of Kratos, with `subject_from: email` and `extra_from: '@this'`. The `jwt` authenticator stays as the fallback. - The `id_token` mutator's claims template reads `email` from `.Extra.email`, which is where the proxy's user info carries it, so the app receives the same identity token shape it already verifies (`iss https://auth.sean.farm/oathkeeper`, `aud binjovi`). No change to the app's auth config. - Per-rule `errors`: an HTML request with no session is redirected to `https://binjovi.dev/oauth2/start?rd=<url>`; anything else keeps the JSON 401. Oathkeeper is v0.40.9, which supports per-rule handler config and per-rule errors. - Upstream is `binjovi-staging.binjovi-staging.svc:80`, never the production Service. - A `ReferenceGrant` lets the `HTTPRoute` in `binjovi-staging` reach `Service/oathkeeper-proxy`, as `binjovi-to-oathkeeper` does for production. `tests/binjovi-dev-route-contract.sh`, wired into `tests/check.sh`, proves each twin carries its production route and method set, the proxy user info, the claims template, the redirect, the staging upstream, that exactly six rules reach staging, that no `binjovi-dev-*` rule reaches the production app, and that the grant names the staging namespace. It was red before the rules and is green after; `tests/check.sh` passes in full; the rule list parses as one YAML sequence of 49 unique ids. https://claude.ai/code/session_01XdBRc9CHgFhAxCyHbdVtt6
feat(binjovi): route the staging dashboard on binjovi.dev through Oathkeeper
All checks were successful
binjovi/ci Binjovi completed the frozen plan
540fc9884b
The staging dashboard answers 401 to every browser. Kratos pins its session
cookie to sean.farm, so a browser on binjovi.dev never carries a session.

Every browser rule on binjovi.sean.farm gains a twin on binjovi.dev. Each
twin asks the login proxy on that host for the session, mints the identity
token the app already verifies with the email from the proxy's user info,
and sends an HTML request with no session to the proxy's sign-in. A request
that is not HTML keeps its 401, which the availability gate expects. A
ReferenceGrant lets the route in binjovi-staging reach the Oathkeeper
Service.

A contract proves each twin carries the production route and methods, the
proxy's user info, the claims template, the redirect, and the staging
upstream, and that no staging rule reaches the production app.

Claude-Session: https://claude.ai/code/session_01XdBRc9CHgFhAxCyHbdVtt6
binjovi-bot deleted branch feat/binjovi-dev-dashboard-routes 2026-09-13 12:42:48 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
sean/ory!116
No description provided.