Skip to content

feat(monsoon-openstack-auth): add browser-side mTLS SSO login via JS#2055

Draft
bbobrov wants to merge 3 commits into
masterfrom
option-1-fetch-based-auth
Draft

feat(monsoon-openstack-auth): add browser-side mTLS SSO login via JS#2055
bbobrov wants to merge 3 commits into
masterfrom
option-1-fetch-based-auth

Conversation

@bbobrov
Copy link
Copy Markdown
Contributor

@bbobrov bbobrov commented May 19, 2026

Implement a new authentication flow where the browser directly authenticates with Keystone using the cc_x509 external plugin via mTLS (client certificate presented through the upstream ingress), then posts the resulting token to Elektra's consume-auth-token endpoint to establish a Rails session.

Changes:

  • Add sso_login.ts module that auto-fires on the login page, performing a cross-origin fetch to Keystone with X-User-Domain-Name header and methods=['external'], then posting the X-Subject-Token back to Elektra same-origin with CSRF protection
  • Add esbuild entry point (app/javascript/sso_login.ts)
  • Add meta tags to the login view for keystone-url, domain, and consume-path (only rendered when MONSOON_OPENSTACK_AUTH_API_ENDPOINT is configured)
  • Extend SessionsController#consume_auth_token to return JSON for raw=1 POST requests (the browser SSO path) while preserving existing redirect behaviour for legacy flows

The legacy server-side validate_sso_certificate path is preserved unchanged as a fallback.

The template below is left empty on purpose, nothing from it was done.

Summary

Changes Made

  • Change 1
  • Change 2
  • Change 3

Related Issues

  • Issue 1: #ISSUE_ID

Screenshots (if applicable)

Checklist

  • I have performed a self-review of my code.
  • I have commented my code, particularly in hard-to-understand areas.
  • I have added tests that prove my fix is effective or that my feature works.
  • New and existing unit tests pass locally with my changes.
  • I have made corresponding changes to the documentation (if applicable).
  • My changes generate no new warnings or errors.

bbobrov added 3 commits May 19, 2026 10:57
…fetch to Keystone

Implement a new authentication flow where the browser directly
authenticates with Keystone using the cc_x509 external plugin via
mTLS (client certificate presented through the upstream ingress),
then posts the resulting token to Elektra's consume-auth-token
endpoint to establish a Rails session.

Changes:
- Add sso_login.ts module that auto-fires on the login page,
  performing a cross-origin fetch to Keystone with X-User-Domain-Name
  header and methods=['external'], then posting the X-Subject-Token
  back to Elektra same-origin with CSRF protection
- Add esbuild entry point (app/javascript/sso_login.ts)
- Add meta tags to the login view for keystone-url, domain, and
  consume-path (only rendered when MONSOON_OPENSTACK_AUTH_API_ENDPOINT
  is configured)
- Extend SessionsController#consume_auth_token to return JSON for
  raw=1 POST requests (the browser SSO path) while preserving
  existing redirect behaviour for legacy flows
- Add comprehensive Vitest tests (12) and RSpec tests (8) covering
  the new path and backward compatibility

The legacy server-side validate_sso_certificate path is preserved
unchanged as a fallback.
…in Keystone fetch

With Keystone returning Access-Control-Allow-Origin: * (the chart
default when cors.allowed_origin is not set), the browser refuses
to use the response when credentials mode is 'include'. Client
certificate presentation is hostname-based at the TLS layer and
is not affected by this option, so the mTLS flow keeps working.

The same-origin fetch to /auth/sessions/consume_auth_token retains
credentials:'same-origin' since it must carry the Rails session
cookie.
…y-auth-token

Replace the bespoke raw=1 path through SessionsController#consume_auth_token
with a form POST to the existing /verify-auth-token endpoint, which already
handles externally-obtained Keystone tokens for federated SSO (WebSSO,
OIDC, SAML).

Benefits:
- No new server-side code in SessionsController; the rails-side flow is
  now identical to federation handover.
- /verify-auth-token re-validates the token at Keystone and reads the
  user domain from the authoritative response.
- ~180 lines of controller and spec code removed.

Changes:
- sso_login.ts: replace step-2 fetch+redirect with a hidden form
  submission to /verify-auth-token (token + authenticity_token).
- sso_login.test.ts: rewrite step-2 tests to assert form construction
  and submission (9 tests, all passing).
- sessions/new.html.erb: drop the sso-consume-path meta tag.
- sessions_controller.rb: revert raw_sso_request?/consume_auth_token
  changes from the initial feat commit.
- sessions_controller_spec.rb: revert the 8 SSO-specific tests from
  the initial feat commit.
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