Skip to content

Add SSO cookie vendor endpoint for native apps behind auth proxies - #7127

Open
nathanmoreton wants to merge 10 commits into
dani-garcia:mainfrom
nathanmoreton:feat/sso-cookie-vendor
Open

Add SSO cookie vendor endpoint for native apps behind auth proxies#7127
nathanmoreton wants to merge 10 commits into
dani-garcia:mainfrom
nathanmoreton:feat/sso-cookie-vendor

Conversation

@nathanmoreton

Copy link
Copy Markdown

Native Bitwarden apps cannot complete login when Vaultwarden sits behind an authenticating reverse proxy (Cloudflare Access, Authentik, Authelia, oauth2-proxy). The proxy redirects API requests to a browser-based IdP flow, which the apps' HTTP clients cannot follow.

Bitwarden addressed this upstream in February 2026 with a flow called SSO cookie vending. The server publishes, through /api/config, a communication.bootstrap block naming the IdP login URL and the cookie the proxy sets. The app opens a system browser for the IdP step, the browser hits /api/sso-cookie-vendor, and the server 302-redirects to bitwarden://sso-cookie-vendor?<name>=<value>&d=1. The app captures the cookie from the deep link and attaches it to every future API request.

Vaultwarden v2026.2.0 shipped the web-vault connector page from clients#18476, but the server side has not landed. This PR adds it.

Changes

  • New config section sso_cookie_vendor through the existing make_config! macro: SSO_COOKIE_VENDOR_ENABLED, SSO_COOKIE_VENDOR_IDP_LOGIN_URL, SSO_COOKIE_VENDOR_COOKIE_NAME, SSO_COOKIE_VENDOR_COOKIE_DOMAIN. Startup validation refuses to run when the flag is on but the three string fields are empty.
  • GET /api/sso-cookie-vendor reads the proxy auth cookie from the request jar and 302-redirects to the bitwarden:// deep link. Handles sharded cookies (<name>-0 through <name>-19, which Cloudflare Access uses when the JWT exceeds single-cookie size limits), with a non-sharded cookie taking precedence. Missing cookie returns the upstream 404 HTML page; URIs over 8192 bytes return 400. Registered only when the flag is on.
  • communication.bootstrap object added to /api/config, matching the shape from upstream PR apply policies only to confirmed members #6892 so clients pick it up unpatched.
  • Unit tests cover single-cookie, sharded-cookie, precedence, URL-encoding, oversize URI, missing-cookie 404, and error HTML format.
  • docs/sso-cookie-vendor.md covers the end-to-end flow, security notes, and per-proxy configuration.

Default behavior

SSO_COOKIE_VENDOR_ENABLED defaults to false. Installs without the four env vars set are byte-identical to current behavior.

Upstream references

Test plan

  • cargo fmt --check
  • cargo clippy --features sqlite -- -D warnings
  • cargo test --features sqlite -- sso_cookie_vendor
  • Manual: running behind Cloudflare Access with the four env vars set; web vault and native iOS/Android/desktop apps all complete login.

…proxies

Implements the server-side pieces of Bitwarden's SSO cookie vending flow
(upstream PRs bitwarden/server#6880, dani-garcia#6892, dani-garcia#6903) so the native Bitwarden
mobile and desktop apps work when Vaultwarden sits behind an authenticating
reverse proxy such as Cloudflare Access, Authentik, Authelia, or
oauth2-proxy.

Without this, users behind such a proxy can authenticate the web vault in
a browser but the native apps 404 on /api/sso-cookie-vendor after the
browser-assisted IdP step, leaving the app unable to acquire the proxy's
auth cookie.

What's added:

  * New config section `sso_cookie_vendor` (4 fields, default-off) driving
    both env-var and admin-UI configuration via the existing make_config!
    macro, with startup validation.
  * GET /api/sso-cookie-vendor — reads the proxy auth cookie from the
    request (including sharded variants CF_Authorization-0..19) and
    302-redirects to bitwarden://sso-cookie-vendor?<cookie>=<value>&d=1
    so the native app can capture and reuse the cookie. Upstream-compatible
    404/400/500 HTML error pages; 8192-byte URI cap.
  * communication.bootstrap block in /api/config matching the shape from
    bitwarden/server#6892 so clients discover the flow without modification.
  * Unit tests covering single/sharded cookies, precedence, missing-cookie
    404, URL-encoding, oversize URI, and error HTML format.

See docs/sso-cookie-vendor.md for the full writeup (background, security
considerations, end-to-end flow, and per-proxy configuration notes).
@mohouse1985

Copy link
Copy Markdown

Thx for this work ! Can't wait to see it arrive.

The rebase onto upstream main bumped rust-toolchain to 1.95, which
flagged two things the 1.94 compiler didn't catch:

- rustfmt collapses build_redirect_uri's signature onto one line
- clippy's collapsible_if catches the nested if in validate_config

Style only, no behavior change.
@nathanmoreton

Copy link
Copy Markdown
Author

@dani-garcia What is needed to get this reviewed and approved?

@MartinK99

Copy link
Copy Markdown

Highly interested in getting this merged as well, since without it it does feel a tad more insecure with just Bitwarden itself, and I'd love to enable Cloudflare Access after all. Any way the merge could be facilitated?

@yannou38

Copy link
Copy Markdown

Please focus on this PR, I don't feel super great at having vaultwarden exposed without a SSO on the reverse proxy, but having it currently break the android app so i need vualtwarden with a less restricted access ...

Resolve conflict in src/api/core/mod.rs: upstream grouped `pub mod`
declarations at the top (moving `pub mod two_factor;`), so keep only the
new `mod sso_cookie_vendor;` declaration among the private modules.

Reformat the SSO code for the Edition 2024 / Rust 1.96 rustfmt rules
introduced upstream (dani-garcia#7200): import ordering in sso_cookie_vendor.rs and
the multi-line err!() in config.rs validation.
@ssbat

ssbat commented Aug 5, 2026

Copy link
Copy Markdown

Please we need this PR to be merged, it is not ideal to keep the app exposed to public access

@zero-noise-dev

Copy link
Copy Markdown

Can we please get an update on how far away this is?

@BlackChimera47

Copy link
Copy Markdown

Would you be kind enough to please review and merge this PR.
I do not want to expose the keys to my kingdom to the internet.
Thank you for all the hard work BTW!

Upstream added a "communication": null placeholder for bitwarden/server#6892
after this branch last merged main. Combined with this PR's populated
"communication" key, serde_json's json! macro keeps the last duplicate key,
so the null silently overwrote the ssoCookieVendor bootstrap block and native
clients never saw it. Keep only the populated key.
@forkrails

Copy link
Copy Markdown

Does this also apply to the extension? Or does the extension already share the browser cookie store?

@nathanmoreton

Copy link
Copy Markdown
Author

Does this also apply to the extension? Or does the extension already share the browser cookie store?

I am self-hosting and my extension is working. I believe the extension shares the browser cookie, so I think it works without this update as well, but I'm not entirely sure. If your extension isn't working, go to your vault url in a new tab and go through the zero trust auth so your browser grabs a new cookie and it may start working.

@nathanmoreton

Copy link
Copy Markdown
Author

@dani-garcia @BlackDex can we get someone to look at this request? I have been using it behind cloudflare zero trust for months with no problems syncing the mobile app. This solved a problem a lot of people have.

@forkrails

Copy link
Copy Markdown

@nathanmoreton how do the clients handle cf access session expiry/revocation in your experience? Do they prompt you to sign in again?

@nathanmoreton

Copy link
Copy Markdown
Author

@nathanmoreton how do the clients handle cf access session expiry/revocation in your experience? Do they prompt you to sign in again?

Yes, the mobile app already did that. It prompts for you to launch a browser and sign in when your cookie expires. This bug fix is to allow vaultwarden to properly route the cookie back to the app when it detects the request comes from a mobile app.

@forkrails

Copy link
Copy Markdown

Good info, thanks.

@BlackDex this seems simple enough, what's with the 4 month delay for review? This is the single best improvement, security wise.

@LordBouldermort

Copy link
Copy Markdown

@BlackDex Can you look at this soon? It would be awesome for security and ease of setup.

developerxpe pushed a commit to developerxpe/vaultwarden that referenced this pull request Aug 29, 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.

9 participants