-
Notifications
You must be signed in to change notification settings - Fork 2
docs: define env key rotation, recovery, and lost-key handling flows #28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -285,6 +285,17 @@ Behavior: | |
| - require explicit regeneration of all active key-share records | ||
| - keep prior project-key lineage in audit metadata | ||
|
|
||
| ### Operator decision matrix | ||
|
|
||
| The CLI and broker should treat these as different intents, not synonyms: | ||
|
|
||
| | Situation | Correct action | Why | | ||
| | --- | --- | --- | | ||
| | The underlying secret changed | Value rotation | The trust anchor can stay the same while publishing a new immutable value snapshot | | ||
| | A teammate left or a new teammate joined | Share rotation | Membership changed, but the current project key may still be trusted | | ||
| | A device was stolen, an owner key may be compromised, or the operator wants a hard trust reset | Project-key rotation | The trust anchor itself must change | | ||
| | A user lost local key material but another valid recovery path remains | Recovery / share reissue | Access must be restored without forcing unnecessary secret churn | | ||
|
|
||
| ### Recovery policy | ||
|
|
||
| Hack should not silently escrow plaintext secrets. Recovery must be explicit. | ||
|
|
@@ -305,6 +316,67 @@ Unsafe behavior to reject: | |
| - rotating the project key while leaving no valid recipient or backup | ||
| - revoking the last usable recovery share without an explicit forced override | ||
|
|
||
| ### Lost-key handling flows | ||
|
|
||
| The design needs to distinguish between `lost access` and `compromised access`. | ||
|
|
||
| #### Case 1: Lost local machine, trusted recovery still exists | ||
|
|
||
| Expected flow: | ||
|
|
||
| 1. authenticate as an authorized owner or designated recovery recipient | ||
| 2. unwrap the current project key through the remaining recovery path | ||
| 3. re-apply the latest active portable bundle to new local compatibility storage | ||
| 4. reissue recipient shares for replacement devices as needed | ||
|
Comment on lines
+327
to
+330
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When the surviving authority is a designated recovery recipient, this Case 1 flow lets that backup-only identity complete step 4 and mint fresh recipient shares. That effectively promotes recovery holders into share administrators, even though manual sharing is described as the trust boundary earlier in this doc ( Useful? React with 👍 / 👎. |
||
|
|
||
| This should be logged as recovery, not as key compromise. Values and bundle history stay intact. | ||
|
|
||
| #### Case 2: Recipient lost local key material | ||
|
|
||
| Expected flow: | ||
|
|
||
| 1. verify that the recipient is still entitled to access | ||
| 2. mint a fresh wrapped project-key share for that recipient | ||
| 3. preserve existing bundle versions and project-key lineage | ||
|
Comment on lines
+338
to
+340
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Case 2 assumes we can "mint a fresh wrapped project-key share for that recipient", but the only key-share schema defined here records Useful? React with 👍 / 👎. |
||
|
|
||
| This is basically share repair. It should not force value rotation or project-key rotation on its own. | ||
|
|
||
| #### Case 3: Owner or project key suspected compromised | ||
|
|
||
| Expected flow: | ||
|
|
||
| 1. rotate the project key | ||
| 2. re-wrap the latest active bundle keys to the new project key | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Re-wrapping only the “latest active bundle keys” is not enough for a compromised-project-key scenario, because the design elsewhere keeps bundle versions immutable and fetchable by version ( Useful? React with 👍 / 👎. |
||
| 3. regenerate all active recipient and recovery shares | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This compromise-handling flow rotates the project key and recreates shares, but it never reissues encrypted recovery packages. That breaks the case where a recovery package is the only remaining recovery path, because the new section later ties packages to a specific Useful? React with 👍 / 👎. |
||
| 4. record the superseded key lineage and reason in audit metadata | ||
|
|
||
| If an operator cannot prove which recipient or device was affected, assume compromise and require project-key rotation instead of share repair. | ||
|
|
||
| #### Case 4: No valid recovery path remains | ||
|
|
||
| Expected flow: | ||
|
|
||
| 1. block normal revoke or rotate actions that would strand the project | ||
| 2. require explicit break-glass override semantics for destructive changes | ||
| 3. present a user-facing message that portable recovery is no longer possible without recreating authority | ||
|
|
||
| The system should fail closed here. Hack must not pretend that remote recovery is available when no wrapped recovery authority exists. | ||
|
|
||
| ### Recovery package expectations | ||
|
|
||
| An encrypted recovery package is an allowed recovery path, but it must stay metadata-rich enough to be usable later. | ||
|
|
||
| Minimum metadata: | ||
|
|
||
| - project binding identifier | ||
| - project key identifier | ||
| - creation timestamp | ||
| - creating actor | ||
| - encryption method / wrapping scheme identifier | ||
| - optional human description supplied by the operator | ||
|
|
||
| The package must not be treated as silent escrow. Operators should create it deliberately, store it deliberately, and understand that losing every recovery package plus every valid owner share means portable recovery is no longer possible. | ||
|
|
||
| ## `.env` Compatibility And Backend UX | ||
|
|
||
| Portability should preserve the current local runtime model instead of replacing it. | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the offboarding case where a teammate has already applied the current bundle,
Share rotationis not a sufficient “correct action”: the sharing rules indocs/plans/2026-03-13-env-portability-and-secret-management-design.md:246-249explicitly say revocation only blocks fresh unwraps and does not remove old local materializations. As written, this matrix will push the CLI/broker toward a flow that leaves the departed user with still-valid DB/API credentials until operators also rotate the affected secret values.Useful? React with 👍 / 👎.