feat: manage automatic key rotation as code (key_rotation.yaml) - #52
Draft
piotrek-janus wants to merge 5 commits into
Draft
piotrek-janus wants to merge 5 commits into
piotrek-janus wants to merge 5 commits into
Conversation
Introduces the cac-owned schema for workspaces/<wid>/key_rotation.yaml
({sig,enc} -> {enabled, cron, starting_from}) and the helpers the rest of
the pipeline uses to carry it in a patch under the key_rotation key:
Pop/Get (strict decode, unknown fields rejected), Validate (cron required
for every present use and parsed with gorhill/cronexpr, the same library
and version the server uses), and conversions to and from the admin
AutomaticKeyRotation model. The read-only scheduled_at and the
never-echoed starting_from are dropped when converting from the server.
Adds utils.AsPatch for the recurring any -> patch map conversion.
Key rotation is not part of TreeServer, so ServerStorage pops it from the patch before the strict model conversion and writes it to its own file, and reads it back under the key_rotation key so filters, diff and merged sources see it like any other workspace resource. TenantStorage does the same per workspace. The file is optional on read.
Client.Read fetches use=sig and use=enc from the admin keys endpoint and adds them to the patch, omitting a use the server reports as never configured (empty cron). Client.Write pops key_rotation before the hub import or patch call, skips that call when nothing else remains (push --filter key_rotation), and PUTs each present use afterwards. TenantClient does the same for every workspace in sorted order.
Validators strict-decode and validate key_rotation, then run the tree validation on a copy of the patch without it. The caller's patch is still cleaned of id and tenant_id so push sends the same body as before. The server never returns starting_from, so diff ignores key_rotation.<use>.starting_from unconditionally; otherwise every diff would report it as an addition.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Workspace signing and encryption key rotation can now be managed as code through a new optional per-workspace file,
workspaces/<workspace-id>/key_rotation.yaml:pullreads thesigandencrotation settings and writes the file. The read-onlyscheduled_atis dropped, and a use that was never configured is omitted.push(both--method patchand--method import) updates each use present in the file. A missing file or a missing use means no change, so existing repositories are unaffected.diffandpush --dry-runinclude rotation changes in their output.Design notes
key_rotationkey and is popped out right before every strict model conversion. That keepsdiff,--dry-run,--filter key_rotation, merged sources and tenant mode working without extra plumbing.--filter rootexcludes it, like the other resources that live in their own file.enabledisfalse, so a disabled entry still needs a valid cron. Local validation mirrors that with a clear message instead of a 400 from the server.starting_fromis write-only: the server never returns it, sopullnever writes it anddiffignores that one field. It is honored only when it is in the future.gorhill/cronexpr, pinned to the same version the server uses, so what passes locally is what the server accepts.push --filter key_rotationskips the workspace config call when nothing else remains in the patch.Verification
make lint: only the three pre-existing findings.go test ./...: all packages pass, 155 tests (18 new test functions and table cases covering the new package, storage round trips, client GET/PUT against the mock server, validators, diff filtering and dry-run).Not yet exercised against a live tenant.