Conversation
🤖 Bitwarden Claude Code ReviewOverall Assessment: APPROVE Reviewed the Two things worth noting outside the finding list: the Lint check is currently red, and the only net change this PR now makes to |
| if (_featureService.IsEnabled(FeatureFlagKeys.Sm2093MachineAccountTokenPrefix)) | ||
| { | ||
| clientSecret = _clientSecretPrefix + clientSecret; | ||
| } |
There was a problem hiding this comment.
❓ QUESTION: Have the token consumers been verified against the prefixed secret, not just server-side validation?
Why this is separate from the backward-compatibility argument
The PR description covers the inbound path correctly: SecretsManagerApiKeyProvider hands Duende a Secret(apiKey.ClientSecretHash) and the stock HashedSharedSecretValidator does a shape-agnostic hash comparison, so previously issued tokens keep working and the SHA-256 hash length is unchanged.
What that argument does not cover is the outbound path. This endpoint returns the bare ClientSecret (AccessTokenCreationResponseModel), and the user-facing access token is assembled outside this repo as 0.<accessTokenId>.<clientSecret>:<encryptionKey>, then parsed back apart by bws / the SDK before the client-credentials call is made. A parser that splits on . and : is unaffected, but one that constrains the secret segment by charset or length would reject bw_… — _ is outside the base64 alphabet, and the segment grows from 30 to 33 characters.
Worth confirming against the SDK/CLI access-token parser before the flag is turned on for anyone, since a failure there would surface as newly created machine accounts being unable to authenticate at all. If that has already been checked on the clients/SDK side, disregard.
There was a problem hiding this comment.
@maxkpower The change from 30 to 33 characters from adding the "bw_" prefix, does not impact value-based masking which is the approach used by nearly everyone.
The residual risk is limited to customer-defined regex patterns that explicitly assume a 30-character token. Those patterns could fail silently, but the likelihood and impact appear low enough that clearly documenting the change in the release notes is a proportionate mitigation.
- We should also update documentation to reflect this new formatting in the examples we show and a note about how users may see both variations as we are not changing legacy access tokens.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## sm-2093-machine-account-token-prefix-flag #8369 +/- ##
==========================================================================
Coverage 64.49% 64.49%
==========================================================================
Files 2480 2480
Lines 106110 106115 +5
Branches 9627 9628 +1
==========================================================================
+ Hits 68435 68441 +6
+ Misses 35337 35336 -1
Partials 2338 2338 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Exercises the real HTTP + OAuth pipeline via the in-process
ApiApplicationFactory/IdentityApplicationFactory test harness (SQLite,
no docker):
- POST /service-accounts/{id}/access-tokens respects the feature flag:
prefixed when enabled, unchanged when disabled.
- A bw_-prefixed access token completes a real client_credentials grant
and successfully calls an authenticated Secrets Manager endpoint.
- A token issued before the flag was enabled keeps authenticating and
revoking normally after the flag goes live for new tokens, proving
the non-breaking-change guarantee end-to-end rather than by
inspection of the hash-comparison code alone.
…ddress DEBT finding)
… review feedback)
🎟️ Tracking
SM-2093, SM-2094
📔 Objective
Stacked on #8368. When the
Sm2093MachineAccountTokenPrefixfeature flag is enabled,CreateAccessTokenCommandprepends the literalbw_to newly generated Secrets Manager machine account (service account) access token client secrets, before hashing. Behavior is unchanged when the flag is disabled.This is backward compatible: token validation (
SecretsManagerApiKeyProvider→ Duende's stockHashedSharedSecretValidator) is a generic hash comparison with no assumption about secret shape, so already-issued unprefixed tokens continue to authenticate with no database or migration changes needed.Adds test coverage for both flag states in
CreateAccessTokenCommandTests.