test: cover the Keycloak issuer migration and cross-app token handoff - #10
Merged
Conversation
The session-expiry guards in test_add_model_flow.py matched on `"opub-kc" in page.url or "auth/realms" in page.url`. Both halves are now dead: opub-kc.civicdatalab.in is decommissioned, and Keycloak moved from /auth to the domain root, so the live redirect is auth.civicdatalab.in/realms/... and neither substring appears. A bounce to login therefore stopped being detected and the test failed with a confusing locator timeout instead of skipping cleanly. Match host-agnostically on /realms/ plus login keywords, so the guard works against either Keycloak server.
Three regression tests for the auth.civicdatalab.in migration:
- sign-in redirects to the migrated issuer (api, regression)
- sign-in never touches the decommissioned opub-kc host (api, regression)
- a live ParakhAI token is accepted by CivicDataSpace (api, regression,
auth)
The third is the one that matters. ParakhAI's DataSpaceAuthMiddleware
forwards user tokens to the CivicDataSpace backend, so a cross-issuer
mismatch degrades every authenticated request to anonymous rather than
erroring - the exact silent failure in ParakhAI-Backend#107. It logs in
for real and POSTs the resulting token to the CDS token-exchange
endpoint.
Deliberately not asserted via GraphQL: verified on dev that
`{ myAssignments { id } }` returns an identical empty result
authenticated and unauthenticated, so such an assertion would pass
whether or not the handoff works.
Proven non-vacuous: tampering the token makes the test fail with the
production symptom (401 "Invalid or expired token").
The handoff test asserted `status_code != 401`. A 5xx satisfies that too, so it passed while the CivicDataSpace token-exchange endpoint was timing out entirely - proving nothing about whether the token is accepted. Found by running the CivicDataSpace API suite against dev, where the same endpoint returned 504. Now asserts == 200, and separates the two failure modes: - 401/403 -> the token was rejected. That is the ParakhAI-Backend#107 issuer mismatch and still fails the test. - 502/503/504 or a client timeout -> the endpoint could not answer, so acceptance cannot be evaluated. Retried three times with a 90s timeout (longer than nginx's own 60s, so slowness arrives as a status code rather than a ReadTimeout), then skipped with a message naming the defect. Skipping there is deliberate. Failing would report an issuer mismatch that has not been shown, and retrying harder would dress a broken endpoint up as a passing test. The endpoint is genuinely degraded on dev: measured 504, 200 in 7s, 200 in 42s, 504 across four consecutive calls, while Keycloak itself answers in 0.13s and the backend's own /health/ in 0.2s - so the latency is inside the exchange handler, not the Keycloak migration. Verified: 3 consecutive runs green, the skip path exercised live, and a tampered token still fails with HTTP 401.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Repairs two guards the Keycloak migration silently broke, and adds the regression test that would have caught ParakhAI-Backend#107.
Broken guards
tests/e2e/test_add_model_flow.pydetected a bounce to login with:Both halves are now dead.
opub-kc.civicdatalab.inis decommissioned, and Keycloak moved from/authto the domain root, so the live redirect isauth.civicdatalab.in/realms/...and neither substring appears. A session expiry stopped being detected and the test failed with a confusing locator timeout instead of skipping cleanly.Now matched host-agnostically on
/realms/plus login keywords, so it works against either server.New coverage
opub-kchostThe third one is the point
ParakhAI's
DataSpaceAuthMiddlewareforwards user tokens to the CivicDataSpace backend. A cross-issuer mismatch degrades every authenticated request to anonymous rather than erroring — the exact silent failure in ParakhAI-Backend#107. The test logs in for real and POSTs the resulting token to the CDS token-exchange endpoint.Deliberately not asserted via GraphQL. I verified on dev that
{ myAssignments { id } }returns an identical empty result authenticated and unauthenticated —auditsandauditorAssignmentslikewise. Any assertion built on those would have passed whether or not the handoff worked, which is worse than no test.Verification
All 3 pass against dev. Proven non-vacuous: tampering the token makes the handoff test fail with the production symptom,
401 {"error":"Invalid or expired token"}.ruff checkclean.