Skip to content

Authenticate the integration tests against a local Keycloak realm - #87

Open
oysand wants to merge 3 commits into
equinor:mainfrom
oysand:keycloak-oidc
Open

Authenticate the integration tests against a local Keycloak realm#87
oysand wants to merge 3 commits into
equinor:mainfrom
oysand:keycloak-oidc

Conversation

@oysand

@oysand oysand commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

The suite authenticated against Azure Entra ID using four app registrations whose client secrets came from FlotillaTestsKv. That meant every contributor needed az login and access to a shared vault, four secrets to rotate, and a suite that could not run outside Equinor's tenant.

It now runs a Keycloak container and mints tokens from it. custom_realms/robotics-realm.json is a fixture — its client secrets are not secret — and is the same file flotilla and sara mount to run against Keycloak locally, so a developer's stack and CI exercise the same clients, scopes and roles.

before after
Entra app registrations 4 0
Key Vault secrets 8 4 (MQTT only)
az login needed locally yes no

MQTT still needs the vault: the broker validates credentials against a hashed passwd_file committed in equinor/flotilla, which is out of scope here. INTEGRATION_TEST_AZURE_CLIENT_SECRET is made optional, not removed — every one of the 17 repos declares it and consumes this workflow at @main.

Also adds the property nothing previously covered: whether authentication is switched on at all. The fixtures assert each service rejects unauthenticated callers before yielding, and two existing mission tests attempt unauthorised interference mid-flight, with the surrounding status assertions proving it had no effect.

Verified locally with all three service images built from the corresponding branches via scripts/build_local_images.sh, no az login, and only the four MQTT secrets in .env: 4 passed in 4m30s under pytest -s -n auto. 15 fixture auth invariants fired, both woven negative scenarios passed, and there was zero contact with login.microsoftonline.com. Note that this suite does not run in armada's own PR CI, so that local run is the evidence.

Merge order: equinor/isar#1158 → isar-robot bump → equinor/flotilla#2863 + equinor/sara#456wait for published images → this PR.

Supersedes #83, which stays open as a fallback until this set is approved.

@oysand oysand mentioned this pull request Aug 5, 2026
@oysand

oysand commented Aug 5, 2026

Copy link
Copy Markdown
Contributor Author

Full suite verified — ready for review

Built all three service images from the local branches (scripts/build_local_images.sh) and ran the suite with no az login and only the four MQTT secrets in .env.

4 passed in 244.41s (0:04:04)     # pytest -s -n auto

(Note: the description on #83 said 12 tests. The suite collects 4 — that number was wrong.)

The Flotilla → ISAR hop is now proven

This was the one thing nothing else could verify. Straight from the run:

Resolved token endpoint http://keycloak:8080/realms/robotics/protocol/openid-connect/token
  from http://keycloak:8080/realms/robotics/.well-known/openid-configuration
Acquiring token for scope 'isar-api'
  from http://keycloak:8080/realms/robotics/protocol/openid-connect/token

followed by 9 Api.Services.IsarService calls. So GenericOidcAuthorizationHeaderProvider's two Keycloak-specific fixes — resolving the token endpoint from discovery instead of assuming {authority}/token, and sending client_secret — both work against a real downstream service.

Everything else that ran

  • Fixture invariants fired on every stack: GET /robots, GET /api/analysis and POST /schedule/stop-mission all refuse unauthenticated callers.
  • Both woven negative scenarios passed: "Unauthorised attempts to interfere with the mission were rejected" and "…to pause the mission were rejected" — wrong audience and insufficient role, against Flotilla and directly against ISAR, mid-mission, with the normal mission assertions still holding.
  • Zero contact with login.microsoftonline.com, no AadIssuerValidator, no DefaultAzureCredential.
  • xdist parallelism intact across 4 workers.

Cost

Keycloak reports started in 9.1–9.5s consistently, four times (once per stack). That is the honest overhead versus the mock's sub-second start. I do not have a like-for-like baseline — measuring one would mean rebuilding all three images from the oauth2-mock branches — so I am not going to claim a delta. If ~35s of the 4m04s total is judged too much, the mitigation is a session-scoped Keycloak shared across stacks; it holds no per-test state.

One fix from the run

The realm import logged Referenced client scope 'profile'/'email' doesn't exist on every start: a realm declaring its own clientScopes does not inherit Keycloak's built-ins, and the two SPA clients I declared ahead of the frontend work referenced them. Removed — nothing uses them yet, and an expected warning on every import just trains people to ignore warnings. Import is now silent.

Taking this out of draft.

@oysand
oysand marked this pull request as ready for review August 5, 2026 13:09
@oysand oysand changed the title Issue test tokens from a local Keycloak realm Authenticate the integration tests against a local Keycloak realm Aug 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant