Skip to content

fix(policy): reject concurrent and non-active key rotations - #4200

Open
c-r33d wants to merge 5 commits into
mainfrom
codex/cks-rotation-active-guard
Open

c-r33d wants to merge 5 commits into
mainfrom
codex/cks-rotation-active-guard

Conversation

@c-r33d

@c-r33d c-r33d commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

Proposed Changes

Require an ACTIVE source before key rotation, returning a logged FailedPrecondition error (key must be ACTIVE). Atomically enforce that status when updating the source so concurrent requests produce one successor; a stale request returns the existing NotFound error. Preserve key metadata and mapping/base-key transfers.

Checklist

  • I have added or updated unit tests
  • I have added or updated integration tests (if appropriate)
  • I have added or updated documentation

Testing Instructions

Race-enabled tests verify non-base-key rotation, rejection of a rotated source, and a single concurrent successor with no loser record. All 13 CLI rotation BATS cases pass, including the early error and backend logging. Focused unit tests and diff lint pass. Full checks encounter existing lint/vulnerability findings and a round-trip suite requiring a separately provisioned platform.

Summary by CodeRabbit

  • Bug Fixes
    • Key rotation now proceeds only when the key is active. Attempts to rotate an inactive key return a clear error.
    • Concurrent rotation requests no longer create multiple successor keys; only one request succeeds.
    • Rotation now preserves the selection of an unrelated base key and avoids changing a key’s status when it is no longer active.

Signed-off-by: Chris Reed <creed@virtru.com>
@github-actions github-actions Bot added comp:db DB component comp:policy Policy Configuration ( attributes, subject mappings, resource mappings, kas registry) labels Oct 8, 2026
@coderabbitai

coderabbitai Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository UI
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: 48ac5f92-51dd-4686-8670-f1200a02165a
📥 Commits

Reviewing files that changed from the base of the PR and between 6d3a01a and 28221af.

📒 Files selected for processing (7)
  • otdfctl/e2e/kas-keys.bats
  • service/integration/kas_registry_key_test.go
  • service/pkg/db/errors.go
  • service/policy/db/key_access_server_registry.go
  • service/policy/db/key_access_server_registry.sql.go
  • service/policy/db/queries/key_access_server_registry.sql
  • service/policy/kasregistry/key_access_server_registry.go

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

Key rotation now rejects keys that are not ACTIVE and updates a key only when its persisted status is ACTIVE. Tests cover repeated, stale-state, and concurrent rotation attempts, along with base-key selection.

Changes

Key rotation

Layer / File(s) Summary
ACTIVE status guard
service/pkg/db/errors.go, service/policy/kasregistry/key_access_server_registry.go
RotateKey rejects a retrieved key whose status is not KEY_STATUS_ACTIVE. The error maps to Connect CodeFailedPrecondition with the message “key must be ACTIVE.”
Conditional status update
service/policy/db/queries/key_access_server_registry.sql, service/policy/db/key_access_server_registry.sql.go, service/policy/db/key_access_server_registry.go
The rotateActiveKey query changes status only when the ID matches and the current status is ACTIVE. RotateKey returns db.ErrNotFound when no row changes and reloads the rotated key after a successful update.
Rotation behavior tests
service/integration/kas_registry_key_test.go, otdfctl/e2e/kas-keys.bats
Tests check base-key preservation, stale persisted status, and concurrent rotation outcomes. The end-to-end test checks the failed-precondition response for a repeated rotation attempt.

Priority: ➖ Normal

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Bug fix

Suggested reviewers: jakedoublev

Merge Risk: ⚪ Minimal · up to 28221

Key rotation now rejects non-ACTIVE keys and updates a key's status only while it is ACTIVE. Concurrent requests therefore produce a single successor. No concrete merge-blocking risk remains in the supplied evidence.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 1 functions across 6 files. (1 skipped: 1 … Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the two main changes: rejecting non-active key rotations and handling concurrent rotations.
Full details: Docstring Coverage

Explanation

Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 1 functions across 6 files. (1 skipped: 1 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

A rabbit checks the key status right,
ACTIVE keys rotate in the night.
One winner updates the row,
The others learn they cannot go.
The base key stays in sight.

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added the size/s label Oct 8, 2026
@github-actions

github-actions Bot commented Oct 8, 2026

Copy link
Copy Markdown
Contributor
Benchmark results, click to expand

Bulk Benchmark Results

Metric Value
Total Decrypts 100
Successful Decrypts 100
Failed Decrypts 0
Total Time 218.398465ms
Throughput 457.88 requests/second

TDF3 Benchmark Results

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 23.973842991s
Average Latency 239.32009ms
Throughput 208.56 requests/second

Comment thread service/policy/db/key_access_server_registry.go
Signed-off-by: Chris Reed <creed@virtru.com>
@c-r33d c-r33d changed the title fix(policy): serialize key rotation and record successor fix(policy): reject concurrent and non-active key rotations Oct 8, 2026
@github-actions

github-actions Bot commented Oct 8, 2026

Copy link
Copy Markdown
Contributor
Benchmark results, click to expand

Bulk Benchmark Results

Metric Value
Total Decrypts 100
Successful Decrypts 100
Failed Decrypts 0
Total Time 344.201401ms
Throughput 290.53 requests/second

TDF3 Benchmark Results

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 33.943314409s
Average Latency 338.557516ms
Throughput 147.30 requests/second

Signed-off-by: Chris Reed <creed@virtru.com>
@github-actions

github-actions Bot commented Oct 8, 2026

Copy link
Copy Markdown
Contributor
Benchmark results, click to expand

Bulk Benchmark Results

Metric Value
Total Decrypts 100
Successful Decrypts 100
Failed Decrypts 0
Total Time 400.382412ms
Throughput 249.76 requests/second

TDF3 Benchmark Results

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 45.28702015s
Average Latency 451.468928ms
Throughput 110.41 requests/second

Signed-off-by: Chris Reed <creed@virtru.com>
@github-actions

github-actions Bot commented Oct 8, 2026

Copy link
Copy Markdown
Contributor
Benchmark results, click to expand

Bulk Benchmark Results

Metric Value
Total Decrypts 100
Successful Decrypts 100
Failed Decrypts 0
Total Time 346.823592ms
Throughput 288.33 requests/second

TDF3 Benchmark Results

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 35.426474324s
Average Latency 353.404507ms
Throughput 141.14 requests/second

Signed-off-by: Chris Reed <creed@virtru.com>
@c-r33d
c-r33d marked this pull request as ready for review October 8, 2026 19:41
@c-r33d
c-r33d requested review from a team as code owners October 8, 2026 19:41
@github-actions

github-actions Bot commented Oct 8, 2026

Copy link
Copy Markdown
Contributor
Benchmark results, click to expand

Bulk Benchmark Results

Metric Value
Total Decrypts 100
Successful Decrypts 100
Failed Decrypts 0
Total Time 277.694119ms
Throughput 360.11 requests/second

TDF3 Benchmark Results

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 30.08556217s
Average Latency 300.270328ms
Throughput 166.19 requests/second

@github-actions

github-actions Bot commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

⚠️ Govulncheck found vulnerabilities ⚠️

The following modules have known vulnerabilities:

  • otdfctl
  • service
  • tests-bdd

See the workflow run for details.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp:db DB component comp:policy Policy Configuration ( attributes, subject mappings, resource mappings, kas registry) size/s

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant