Skip to content

refactor(server-communication-config): add vault_url to SsoCookieVendorConfig#832

Merged
coroiu merged 10 commits intomainfrom
PM-33352
Mar 18, 2026
Merged

refactor(server-communication-config): add vault_url to SsoCookieVendorConfig#832
coroiu merged 10 commits intomainfrom
PM-33352

Conversation

@addisonbeck
Copy link
Contributor

@addisonbeck addisonbeck commented Mar 10, 2026

🎟️ Tracking

📔 Objective

Add an explicit vault_url field to SsoCookieVendorConfig to allow more flexibility in what servers are supported by this cookie flow.

The vault_url is extracted from the /api/config response's environment.vault field by clients and provides the explicit full URL (scheme + host + port) for the browser redirect. This replaces implicit URL construction that was failing to preserve ports, handle subdomain variations, etc.

🚨 Breaking Changes

  • SsoCookieVendorConfig struct now requries a new vault_url field

  • The parameter sent into acquireCookies is changed from hostname to vaultUrl. This should be used to construct the browser link: ${vaultUrl}/proxy-cookie-redirect-connector.html instead of relying on EnvironmentService which is prone to edge-case bugs

@github-actions
Copy link
Contributor

github-actions bot commented Mar 10, 2026

Logo
Checkmarx One – Scan Summary & Details88fe368c-22b3-4822-8c70-88b6058049bc


New Issues (4) Checkmarx found the following issues in this Pull Request
# Severity Issue Source File / Package Checkmarx Insight
1 CRITICAL CVE-2026-27699 Npm-basic-ftp-5.0.5
detailsRecommended version: 5.2.0
Description: The `basic-ftp` FTP client library for Node.js contains a Path Traversal vulnerability in versions prior to 5.2.0 in the `downloadToDir()`method. A...
Attack Vector: NETWORK
Attack Complexity: LOW
Vulnerable Package
2 HIGH CVE-2026-27903 Npm-minimatch-10.2.2
detailsRecommended version: 10.2.3
Description: minimatch is a minimal matching utility for converting glob expressions into JavaScript RegExp objects. All versions starting from 3.0.0 and prior ...
Attack Vector: NETWORK
Attack Complexity: LOW
Vulnerable Package
3 HIGH CVE-2026-27904 Npm-minimatch-10.2.2
detailsRecommended version: 10.2.3
Description: minimatch is a minimal matching utility for converting glob expressions into JavaScript RegExp objects. All versions starting from 3.0.0 and prior ...
Attack Vector: NETWORK
Attack Complexity: LOW
Vulnerable Package
4 MEDIUM CVE-2025-13465 Npm-lodash-4.17.21
detailsRecommended version: 4.17.23
Description: Lodash versions from 4.0.0 through 4.17.22 are vulnerable to Prototype Pollution in the "_.unset" and "_.omit" functions. An attacker can pass craf...
Attack Vector: NETWORK
Attack Complexity: LOW
Vulnerable Package

@github-actions
Copy link
Contributor

github-actions bot commented Mar 10, 2026

🔍 SDK Breaking Change Detection Results

SDK Version: PM-33352 (208e5d5)
Completed: 2026-03-13 20:49:59 UTC
Total Time: 245s

Client Status Details
typescript ❌ Breaking changes detected TypeScript compilation failed with new SDK version - View Details

Breaking change detection completed. View SDK workflow

@codecov
Copy link

codecov bot commented Mar 10, 2026

Codecov Report

❌ Patch coverage is 96.73913% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 82.77%. Comparing base (fa86d4d) to head (208e5d5).
⚠️ Report is 28 commits behind head on main.

Files with missing lines Patch % Lines
...r-communication-config/src/wasm/js_platform_api.rs 0.00% 2 Missing ⚠️
...uniffi/src/platform/server_communication_config.rs 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #832      +/-   ##
==========================================
+ Coverage   82.30%   82.77%   +0.46%     
==========================================
  Files         346      351       +5     
  Lines       41401    41970     +569     
==========================================
+ Hits        34075    34739     +664     
+ Misses       7326     7231      -95     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

addisonbeck added a commit that referenced this pull request Mar 10, 2026
Fixes two CI failures identified in SDK PR #832 after adding vault_url
field to SsoCookieVendorConfig struct:

1. Swift demo app build failure: Added missing vault_url parameter to
   SsoCookieVendorConfig test instantiation in ContentView.swift. The
   demo app failed to compile because the struct now requires vault_url
   as a non-optional field.

2. rustfmt style check failure: Split long documentation comment line
   in platform_api.rs to satisfy rustfmt's line length requirements.
   The vault_url parameter documentation exceeded the maximum allowed
   line length.

These corrections complete the vault_url implementation by ensuring all
test code and demo applications are updated to match the new struct
signature, and all code passes style checks.

Refs: PM-33352
@addisonbeck addisonbeck changed the title feat(server-communication-config): add vault_url to SsoCookieVendorConfig refactor(server-communication-config): add vault_url to SsoCookieVendorConfig Mar 12, 2026
…nfig

Adds explicit vault_url field to SsoCookieVendorConfig to fix two critical
issues in SSO cookie acquisition redirect logic:

1. Port preservation: Prevents localhost:8000 being stripped to localhost,
   which breaks local development environments
2. Multi-subdomain routing: Fixes redirects going to api.bitwarden.com
   instead of vault.bitwarden.com when the cookie domain differs from the
   vault hostname

The vault_url is extracted from the /api/config response.environment.vault
field and provides the explicit full URL (scheme + host + port) for the
browser redirect. This replaces implicit URL construction that was failing
to preserve ports and handle subdomain variations correctly.

All test cases updated to include vault_url field.

Refs: PM-33352
…es trait signature

Updates ServerCommunicationConfigPlatformApi trait's acquire_cookies()
method to accept an explicit vault_url parameter alongside the existing
hostname parameter. This enables platform implementations to receive the
full vault URL (scheme + host + port) for SSO cookie acquisition redirects.

This change prepares for fixing two critical issues:
1. Port preservation: Prevents localhost:8000 being stripped to localhost
2. Multi-subdomain routing: Ensures redirects use vault.bitwarden.com
   instead of api.bitwarden.com when domains differ

The vault_url parameter takes priority over hostname-based URL construction
to ensure correct redirect behavior in both local development and multi-
subdomain production environments.

Breaking change: This updates the trait signature. Implementations will be
updated in the next commit to prevent compilation errors.

Refs: PM-33352
…r vault_url

Implements vault_url parameter support in both WASM and UniFFI foreign
function interface bindings to enable client platforms to pass explicit
vault URLs for SSO cookie acquisition.

WASM TypeScript bindings (js_platform_api.rs):
- Added vault_url parameter to TypeScript interface definition
- Updated extern "C" signature to accept vault_url
- Modified trait implementation to forward vault_url through ThreadBoundRunner

UniFFI Swift/Kotlin bindings (server_communication_config.rs):
- Added vault_url parameter to bridge implementation
- Forwards vault_url to underlying platform trait

Both bindings now enable clients to provide the full vault URL (scheme +
host + port) for cookie acquisition redirects, which fixes port preservation
issues in local development (localhost:8000 vs localhost) and multi-subdomain
routing in production (vault.bitwarden.com vs api.bitwarden.com).

Client-side usage in client.rs will be updated in the next commit.

Refs: PM-33352
…uisition

Completes the vault_url implementation in the SDK by updating client-side
cookie acquisition logic and all test infrastructure to use the new field.

Client business logic (client.rs):
- Extracts vault_url from SsoCookieVendorConfig
- Validates vault_url is not empty before cookie acquisition
- Passes vault_url to platform_api.acquire_cookies() alongside hostname
- Returns UnsupportedConfiguration error if vault_url is empty

Test infrastructure updates:
- Updated MockPlatformApi trait impl to accept vault_url parameter
- Updated 14 test fixtures in client.rs to include vault_url field
- Updated 3 test fixtures in repository.rs to include vault_url field
- Updated 1 test fixture in config.rs to include vault_url field

This completes the SDK-side implementation chain started in commits
b8d7fec (struct field), 0245d0c (trait signature), and 392ee2c
(FFI bindings). The SDK now provides full support for explicit vault URLs
in SSO cookie acquisition, enabling clients to fix port preservation issues
(localhost:8000 vs localhost) and multi-subdomain routing (vault vs api
subdomains).

All tests pass (30/30), no compilation warnings. Client implementations
will be updated in subsequent commits.

Refs: PM-33352
Fixes two CI failures identified in SDK PR #832 after adding vault_url
field to SsoCookieVendorConfig struct:

1. Swift demo app build failure: Added missing vault_url parameter to
   SsoCookieVendorConfig test instantiation in ContentView.swift. The
   demo app failed to compile because the struct now requires vault_url
   as a non-optional field.

2. rustfmt style check failure: Split long documentation comment line
   in platform_api.rs to satisfy rustfmt's line length requirements.
   The vault_url parameter documentation exceeded the maximum allowed
   line length.

These corrections complete the vault_url implementation by ensuring all
test code and demo applications are updated to match the new struct
signature, and all code passes style checks.

Refs: PM-33352
CI lint job failed due to bare URLs in rustdoc comments violating
the `-D rustdoc::bare-urls` lint rule. Fixed by wrapping example URLs
in backticks to present them as code literals (non-clickable) rather
than using angle brackets which create clickable hyperlinks.

Example URLs in documentation should appear as inline code, not as
live links, since they demonstrate URL format patterns rather than
pointing to actual resources.

Fixed example URLs in platform_api.rs documentation (lines 74-75).
The vault_url field in SsoCookieVendorConfig was initially added as a
String, but should be Option<String> to match the pattern of other
fields (idp_login_url, cookie_name, cookie_domain) in the same struct.
This ensures consistent optionality semantics across the configuration
structure.

Changes:
- Changed vault_url field type from String to Option<String> in
  SsoCookieVendorConfig struct (config.rs)
- Updated client.rs extraction logic to use
  .as_ref().filter(|s| !s.is_empty()) pattern instead of separate
  empty string validation
- Updated 37 test fixtures across client.rs, config.rs, and
  repository.rs to wrap vault_url values in Some(...)

The trait signature in platform_api.rs correctly remains
vault_url: String as the client validates and extracts the value
before passing to platform implementations.

Refs: PM-33352
@addisonbeck addisonbeck marked this pull request as ready for review March 12, 2026 20:36
@addisonbeck addisonbeck requested a review from a team as a code owner March 12, 2026 20:36
@addisonbeck addisonbeck requested a review from coroiu March 12, 2026 20:36
@addisonbeck addisonbeck added the ai-review Request a Claude code review label Mar 12, 2026
Copy link
Contributor

@coroiu coroiu left a comment

Choose a reason for hiding this comment

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

Just one comment, rest of PR looks good

async fn acquire_cookies(&self, hostname: String) -> Option<Vec<AcquiredCookie>> {
async fn acquire_cookies(
&self,
hostname: String,
Copy link
Contributor

Choose a reason for hiding this comment

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

issue: I was initially positive to keeping this but as I'm reading this PR I think it will just be confusing since it's not clear what this value will actually be set to and how it can bee used. hostname is also a bad name and I have a follow-up PR where I'm renaming it everywhere to domain.

Currently this value is set to whatever domain the API request is trying to access. I could be ok with keeping it if we can make it clear that this is what the value represents.

Copy link
Contributor Author

@addisonbeck addisonbeck Mar 13, 2026

Choose a reason for hiding this comment

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

I went ahead and just removed hostname from the acquire_cookies argument list. I was imagining some scenario where implementations might need both, but thinking about it more now it's clear the platform API layer only ever needs vault_url. domain is really just the storage key now and that's all, as far as the SDK is concerned.

Removed on 232e2b4

addisonbeck added a commit that referenced this pull request Mar 13, 2026
… acquire_cookies

Andreas Coroiu's code review feedback on PR #832 identified the hostname
parameter as confusing and unused. Analysis confirmed platform
implementations don't need it - test mocks prefixed it with underscore,
and documentation explicitly stated to use vault_url for redirect
construction instead.

The SDK layer uses hostname internally as a repository key, but the
platform API interface doesn't need to expose it. Platform implementations
only need vault_url to construct browser redirects for cookie acquisition.
If platforms need domain information for display purposes, they can derive
it from vault_url.

This simplification follows YAGNI principle by removing an unused,
confusing parameter that added no value to the platform API interface.

Changes:
- Removed hostname parameter from
  ServerCommunicationConfigPlatformApi::acquire_cookies() trait method
- Updated trait documentation to reflect single-parameter signature
- Updated caller in ServerCommunicationConfigClient::acquire_cookie() to
  pass only vault_url
- Updated test mock implementation signature
- Updated WASM bindings (TypeScript interface and FFI)
- Updated UniFFI bindings (mobile platforms)

All cargo checks and 30 existing tests pass without modification.

Refs: PM-33352
@claude
Copy link

claude bot commented Mar 13, 2026

Claude finished @addisonbeck's task in 6m 29s —— View job


I'll analyze this and get back to you.

… acquire_cookies

coroiu's code review feedback on PR #832 identified the hostname
parameter as confusing and unused. Analysis confirmed platform
implementations don't need it - test mocks prefixed it with underscore,
and documentation explicitly stated to use vault_url for redirect
construction instead.

The SDK layer uses hostname internally as a repository key, but the
platform API interface doesn't need to expose it. Platform implementations
only need vault_url to construct browser redirects for cookie acquisition.
If platforms need domain information for display purposes, they can derive
it from vault_url.

This simplification follows YAGNI principle by removing an unused,
confusing parameter that added no value to the platform API interface.

Changes:
- Removed hostname parameter from
  ServerCommunicationConfigPlatformApi::acquire_cookies() trait method
- Updated trait documentation to reflect single-parameter signature
- Updated caller in ServerCommunicationConfigClient::acquire_cookie() to
  pass only vault_url
- Updated test mock implementation signature
- Updated WASM bindings (TypeScript interface and FFI)
- Updated UniFFI bindings (mobile platforms)

All cargo checks and 30 existing tests pass without modification.

Refs: PM-33352
@claude
Copy link

claude bot commented Mar 13, 2026

Review: PR #832 — Add vault_url to SsoCookieVendorConfig

  • Gather context and read changed files
  • Review code changes across all layers
  • Post review findings

Overall Assessment: APPROVE

This is an incremental re-review. The previous review identified a single suggestion: missing test coverage for the vault_url validation branch. The new commit (208e5d5) directly addresses that gap by adding two test cases:

  • acquire_cookie_returns_unsupported_when_vault_url_none — verifies UnsupportedConfiguration is returned when vault_url is None
  • acquire_cookie_returns_unsupported_when_vault_url_empty — verifies UnsupportedConfiguration is returned when vault_url is Some empty string

Both tests correctly exercise the validation logic at crates/bitwarden-server-communication-config/src/client.rs:137-142, follow existing test patterns in the module, and verify the platform API is never called when validation fails early. No new findings.

Note: The existing unresolved thread from @coroiu regarding the hostname parameter in the WASM bindings (js_platform_api.rs) remains open — that discussion is about naming conventions and is being tracked for a follow-up PR.


View job run

…rage

AI code review identified missing test coverage for the vault_url validation
branch (lines 137-142 in client.rs). The validation code checks that vault_url
is present and non-empty before calling the platform API, returning
UnsupportedConfiguration error if not. However, no tests covered these error
cases.

Good testing practice requires covering error paths, especially for new
validation logic added in this PR. These tests ensure the validation works
correctly when vault_url is misconfigured (None or empty string), and they
prevent regressions if the validation logic changes in the future.

Added test cases:
- acquire_cookie_returns_unsupported_when_vault_url_none: Tests that
  acquire_cookie returns UnsupportedConfiguration when vault_url is None
- acquire_cookie_returns_unsupported_when_vault_url_empty: Tests that
  acquire_cookie returns UnsupportedConfiguration when vault_url is empty
  string

Both tests follow existing patterns: setup mock repository and platform API,
configure the error condition, verify correct error variant is returned.

Test results:
- 32 tests passing (30 existing + 2 new)
- All validation paths now covered
- Formatting verified with rustfmt

Refs: PM-33352
@sonarqubecloud
Copy link

@addisonbeck addisonbeck requested a review from coroiu March 13, 2026 20:59
Copy link
Contributor

@coroiu coroiu left a comment

Choose a reason for hiding this comment

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

Tested and it works :)

@coroiu coroiu merged commit da6afa8 into main Mar 18, 2026
64 checks passed
@coroiu coroiu deleted the PM-33352 branch March 18, 2026 08:28
bw-ghapp bot pushed a commit to bitwarden/sdk-swift that referenced this pull request Mar 18, 2026
…ommunication-config): add vault_url to SsoCookieVendorConfig (bitwarden/sdk-internal#832)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai-review Request a Claude code review breaking-change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants