Skip to content

[Sm-1588] secrets versioning - #8307

Open
cd-bitwarden wants to merge 25 commits into
mainfrom
SM-1588-SecretsVersioning
Open

[Sm-1588] secrets versioning#8307
cd-bitwarden wants to merge 25 commits into
mainfrom
SM-1588-SecretsVersioning

Conversation

@cd-bitwarden

@cd-bitwarden cd-bitwarden commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

🎟️ Tracking

https://bitwarden.atlassian.net/jira/software/c/projects/SM/boards/74?assignee=625cb516fd06270069beaf5d&selectedIssue=SM-1588

📔 Objective

  • Fix logic relating to saving an initial version for a secret
  • Implement more test cases related to secrets versioning
  • Create a command to extract and simplify creating a secret version record
  • Adjust logic so that we are saving the user who is modifying the value's information so we can display this in the UI

…at editorName gets returns to clients side properly
SecretUpdateRequestModel.ToSecret mutates the entity in place and returns
the same reference, so originalSecret aliased the already-updated secret
and every version snapshot stored the new value rather than the previous
one. Capture the value and revision date before ToSecret runs.

VersionDate used the secret's CreationDate, which never changes, so every
version for a secret shared one timestamp. That made OrderByDescending a
total tie, leaving history order arbitrary, and let the retention prune in
CreateAsync delete the newest versions instead of the oldest. Use the
revision date of the value being archived. The restore path had the same
problem using DateTime.UtcNow, which collided with the secret's new
revision date, so it now keeps the date the archived value was set.

Drop EditorName from the version response. Machine account names are
encrypted with the organization key, which the server cannot read, so the
field carried ciphertext for service-account editors and plaintext for
user editors. Callers get EditorServiceAccountId and
EditorOrganizationUserId instead and can resolve a display name from data
they have already decrypted. This also removes the per-version editor
lookups along with the IServiceAccountRepository and IUserRepository
dependencies they needed.

Add tests for the update and restore snapshots, the get-by-ids endpoint,
and the ten-version retention cap, none of which were covered.
@cd-bitwarden cd-bitwarden added the t:feature Change Type - Feature Development label Sep 2, 2026
@codecov

codecov Bot commented Sep 3, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 87.15596% with 28 lines in your changes missing coverage. Please review.
✅ Project coverage is 64.00%. Comparing base (6e291ac) to head (84c97b5).

Files with missing lines Patch % Lines
...r/Repositories/Noop/NoopSecretVersionRepository.cs 0.00% 9 Missing ⚠️
...etsManager/Repositories/SecretVersionRepository.cs 84.00% 8 Missing ⚠️
...etsManager/Controllers/SecretVersionsController.cs 84.90% 6 Missing and 2 partials ⚠️
...SecretsManager/Repositories/SecretVersionWriter.cs 91.17% 2 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #8307      +/-   ##
==========================================
+ Coverage   63.97%   64.00%   +0.03%     
==========================================
  Files        2471     2474       +3     
  Lines      105812   105895      +83     
  Branches     9596     9602       +6     
==========================================
+ Hits        67692    67777      +85     
- Misses      35769    35773       +4     
+ Partials     2351     2345       -6     

☔ View full report in Codecov by Harness.
📢 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.

@cd-bitwarden
cd-bitwarden requested a review from r-tome September 3, 2026 19:48
@r-tome r-tome added the ai-review Request a Claude code review label Sep 4, 2026
@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

🤖 Bitwarden Claude Code Review

Overall Assessment: REQUEST CHANGES

This revision moves version writes into ISecretRepository.CreateAsync/UpdateAsync so a snapshot commits in the owning secret's transaction, replaces the controller-side editor resolution with IBuildSecretVersionCommand, and adds a details projection so editor display names are joined in SQL and withheld from service-account and organization API-key callers via CanReadEditorNames. The version model now records the value as of each write rather than the displaced one, with TryBackfillPreviousVersionAsync covering secrets that have no history yet — which resolves the earlier finding about import-created and pre-versioning secrets losing their value on first edit. Access checks, pruning, editor attribution, and the backfill are all covered by new unit and integration tests. One transition case remains: secrets that already carry version rows written under the semantics currently on main.

Code Review Details
  • ⚠️ : Secrets that already have version rows skip the backfill, so their current value is dropped from history on the next edit and is unrecoverable after a restore
    • bitwarden_license/src/Commercial.Infrastructure.EntityFramework/SecretsManager/Repositories/SecretVersionWriter.cs:32

Comment thread src/Api/SecretsManager/Controllers/SecretVersionsController.cs Outdated
Comment thread src/Core/SecretsManager/Models/Data/SecretVersionDetails.cs Outdated
Comment thread test/Api.Test/SecretsManager/Controllers/SecretsControllerTests.cs Outdated
Comment thread src/Api/SecretsManager/Controllers/SecretsController.cs Outdated
Comment thread src/Core/SecretsManager/Models/Data/SecretVersionDetails.cs Outdated
cd-bitwarden and others added 4 commits September 4, 2026 12:22
Co-authored-by: Rui Tomé <108268980+r-tome@users.noreply.github.com>
…'t display. I added a way to look up the actual names.

Member names are stored as plain readable text, but machine-account names are encrypted and the server genuinely cannot read them. So these can't be one combined "name" field — the member name is sent as-is, and the machine-account name is sent still-encrypted for the browser to unscramble.

Saving a secret and saving its version-history entry were two separate operations. If the first succeeded and the second failed, the secret was already permanently saved but the user got an error screen — so they'd try again and end up with two copies of the same secret.

The fix is like a bank transfer: both steps now happen inside a single all-or-nothing operation. If the version entry fails, the secret save is undone too, so the user's retry is safe.
Comment thread src/Api/SecretsManager/Controllers/SecretVersionsController.cs Outdated
Comment thread src/Api/SecretsManager/Controllers/SecretsController.cs
@cd-bitwarden
cd-bitwarden requested a review from r-tome September 9, 2026 22:56
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 t:feature Change Type - Feature Development

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants