Skip to content

test(auth): add a SAML lane to the mock-IdP stack to reproduce #263 - #595

Draft
ian-flores wants to merge 5 commits into
mainfrom
saml-lane-mock-idp
Draft

test(auth): add a SAML lane to the mock-IdP stack to reproduce #263#595
ian-flores wants to merge 5 commits into
mainfrom
saml-lane-mock-idp

Conversation

@ian-flores

Copy link
Copy Markdown
Collaborator

This does not fix #263. It builds the thing that lets us find out what #263 actually is.

Why

#263 says interactive-auth storage state captured for Connect does not authenticate Workbench on a separate ALB under SAML/Okta. But the mock-idp-e2e stack already runs Connect on connect.vip.test:3939 and Workbench on workbench.vip.test:8787 — separate hostnames — and it is green every day. So separate hostnames alone do not break us, and the issue's framing ("storage state does not carry over") is a customer's inference, not an observation we have reproduced.

The one variable #263 has that the green stack does not is SAML. That matches samcofer's own note on the call that the problem may be SAML rather than OIDC handling.

What this adds

A second Workbench lane speaking SAML against the same Keycloak realm, changing exactly one variable:

  • a saml client in the realm import, SP entity ID https://workbench-saml.vip.test:8788/saml/metadata, ACS /saml/acs, and a Username attribute mapper
  • entrypoint-saml.sh / Dockerfile.saml setting auth-saml, auth-saml-metadata-url and auth-saml-sp-attribute-username
  • a workbench-saml compose service behind a saml profile, on its own hostname and port 8788, with a cert from cert-init
  • just mock-idp-saml-up

The endpoints and the Username attribute name are taken from the SAML SSO admin guide, not inferred. SP request signing is left off, per that guide: "In most situations, SAML authentication request signing is not required or even supported."

SAML is exclusive of PAM/OIDC on a single instance, which is why this is a separate container rather than a toggle. The OIDC lane is untouched — it is the control in this experiment.

The diagnostic job

mock-idp-e2e-saml-diagnostic runs vip verify against the SAML lane twice: Workbench-only, then Connect + Workbench (the actual #263 topology). Both logs are uploaded regardless of where it breaks.

This job is expected to be red. That is the point — it reproduces a bug. So it is workflow_dispatch-only, continue-on-error: true, and excluded from the status gate, so it cannot block a merge. It should be promoted to a normal gated lane once the fix makes it green.

Known limit

This probes --headless-auth only. #263 was reported under --interactive-auth, which CI cannot run (it opens a headed browser and blocks). Both modes share _authenticate_workbench, where the leading hypothesis sits, so a red result here is real evidence — but a green result would not exonerate the interactive-only prompt path.

Next

Dispatch the job. If the OIDC lane stays green and the SAML lane fails, #263 is cornered and the fix gets written against the trace. If both pass, the SAML hypothesis is wrong and we go back to the customer for a verbose trace rather than inventing a fix.

Refs #263

The mock-IdP stack runs Connect and Workbench on separate hostnames behind a real Keycloak and is green daily, which shows the cross-hostname piggyback works for OIDC. The one variable #263 has that the stack does not is SAML.

Add a second Workbench lane configured for SAML against the same Keycloak realm: a SAML client in the realm import, a Workbench image whose entrypoint sets auth-saml, a compose service behind a "saml" profile on its own hostname and port, and a certificate for it. SAML cannot run alongside PAM or OIDC on one instance, so it needs its own container rather than a toggle. The OIDC lane is untouched and remains the control.

Add a workflow_dispatch-only diagnostic job that runs vip verify against the SAML lane, both Workbench-only and alongside Connect, and uploads both logs. The job is expected to fail, since it reproduces a bug, so it is continue-on-error and excluded from the status gate. Promote it to a normal lane once the fix makes it green.

Refs #263
Copilot AI lite review requested due to automatic review settings August 18, 2026 00:56

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds an opt-in SAML “lane” to the existing mock-IdP E2E stack so VIP can reproduce and diagnose issue #263 (suspected Workbench auth sharing failure under SAML/Okta with separate hostnames), while keeping the existing OIDC lane unchanged as a control.

Changes:

  • Adds a second Workbench container configured for SAML against the same Keycloak realm (new Keycloak SAML client + Workbench SAML entrypoint/Dockerfile + new compose service behind a saml profile).
  • Extends the TLS cert generation to include workbench-saml.vip.test, plus a new just mock-idp-saml-up helper target.
  • Adds a workflow_dispatch-only GitHub Actions diagnostic job that runs VIP against the SAML lane (Workbench-only, then Connect+Workbench) and uploads logs/artifacts regardless of failures.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
justfile Adds mock-idp-saml-up to start the stack with the SAML Workbench profile enabled.
docker/workbench/entrypoint-saml.sh New entrypoint to configure Workbench SAML settings and trust the stack CA before starting supervisord.
docker/workbench/Dockerfile.saml New thin wrapper image that installs the SAML entrypoint.
docker/tls/gen-certs.sh Adds generation of workbench-saml leaf cert/key for the new hostname.
docker/keycloak/realm-vip.json Adds a SAML client + mapper for the Workbench-SAML lane in the mock realm import.
compose.mock-idp.yml Adds workbench-saml service under a saml profile and its volume/hostname wiring.
.github/workflows/mock-idp-e2e.yml Adds a dispatch-only diagnostic job that runs VIP against the SAML lane twice and uploads artifacts/logs.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread docker/tls/gen-certs.sh Outdated
Comment thread compose.mock-idp.yml
Comment on lines +15 to +17
# A fourth hostname, workbench-saml.vip.test, is a second Workbench lane
# configured for SAML instead of OIDC against the same Keycloak realm. It
# exists to reproduce issue #263 (Workbench behind SAML on a separate
…anly

A SAML diagnostic run timed out after the IdP accepted credentials and MFA, and the error said only that login "did not complete" — not where the browser had ended up. That single missing fact is the difference between the IdP rejecting our request, the product rejecting the assertion, and a misconfigured test fixture, which are three different problems with three different fixes.

Report the browser's final URL, the page title and the expected product origin at all three authentication timeout sites, guarding those reads so a crashed page cannot turn a timeout into a different error.

Name the protocol actually in use rather than hardcoding OIDC, since the message appeared verbatim during a SAML flow. Derive the stated duration from the real deadline, which is scaled: under VIP_TIMEOUT_SCALE=2 the tool waited ten minutes and reported five.

Raise AuthTimeoutError, a subclass of AuthConfigError, instead of a bare RuntimeError, and wrap the interactive-auth call site the way the headless one already was. Both modes previously escaped as a pytest INTERNALERROR with a traceback; the interactive path is the one issue #263 was reported on.

Use one timeout constant for the IdP round trip. Workbench's wait was 2 minutes against the primary path's 5, which made it skip spuriously (#596).

Refs #263
@github-actions

Copy link
Copy Markdown
Contributor

ian-flores and others added 3 commits August 18, 2026 09:58
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
The lane could not support its own conclusion. Workbench had no local Unix account for the realm's test user, so rserver refused every sign-in before any SAML-specific path ran; the run reported "OIDC login did not complete" because cli.py hardcodes oidc whenever --idp is set with no vip.toml; and a genuine auth failure became a pytest skip, so the step reporting the #263 topology exited 0 while the login test never ran.

Provision the account from entrypoint-saml.sh, add a --provider flag so the lane can declare saml, thread provider into _authenticate_workbench so its timeout names the protocol that actually ran, and assert in the workflow that the login tests executed rather than trusting the exit code. The workflow guard is temporary and cites #596, which fixes the exit-code contract properly.

Also fixes gen-certs.sh regenerating only when the CA is missing, which left a volume warmed before workbench-saml was added without its leaf cert.
The stock Workbench image already ships /usr/local/bin/startup.sh, and its supervisord "rstudio-workbench" program runs it to create the rstudio user and exec rserver. Copying VIP's startup.sh over that path meant supervisord ran the user-creation script instead, which exits 0, so rserver never started and the container died after three retries.
@ian-flores

Copy link
Copy Markdown
Collaborator Author

Dispatching the mock-IdP lane on #601 turned up something that affects this PR's premise directly.

test_workbench_login cannot run under SSO at all. src/vip_tests/workbench/test_auth.py:90, inside the @given("Workbench is accessible at the configured URL") step, skips whenever auth_provider != "password". Both diagnostic steps here filter to that test, so with --provider saml it will skip at setup before any SAML behaviour is exercised — the lane cannot reproduce #263 through it, with or without a working test user. Filed as #602.

Separately, the missing local Unix account is confirmed as the cause of the SSO timeout, and #601 fixes it: in run 32172732884 >>> Workbench authenticated. appears on all three legs, where it appeared in no earlier run. The provisioning commit here does the same thing for workbench-saml, so once #601 merges this branch needs a small rebase in compose.mock-idp.yml.

The skip-guard added in this PR behaves correctly and would have caught the above immediately — it fails the step when the named login test does not execute. It will now fire every run until #602 is resolved, which is the guard doing its job rather than a fault in it.

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.

fix(workbench): session launch tests fail with SAML/Okta auth — login not shared from interactive auth

2 participants