[C-471] Session-policy KMS data-key grant for annotate connections - #219
Merged
Conversation
|
Linked to Plane Work Item(s) References This comment was auto-generated by Plane |
1 similar comment
|
Linked to Plane Work Item(s) References This comment was auto-generated by Plane |
The inline session policy now emits kms:GenerateDataKey (ViaService s3.<region>) for annotate-level connections — annotation sidecar writes to SSE-KMS buckets generate a data key, and the STS inline policy is an intersection filter, so the statement was previously filtered out of the session even where the role permits it. Read-only connections still omit it. The bucket lookup schema gains the optional kmsKeyArn the admin portal reports at bucket registration.
dfrkp
force-pushed
the
feat/c-471-auto-provision-iam-roles
branch
from
September 6, 2026 08:18
de94e48 to
cd20ebc
Compare
…[C-471] The autosuggest effect overwrote the name input while it was focused when the bucket selection resolved asynchronously (catalog arriving mid-fill): React restored the suggested value between the editor's clear and insert, so typed text landed appended to the suggestion. Skip the effect while the name input holds focus.
…ction [C-471] The session policy's kms:ViaService condition and the STS/S3 client construction used the provider connection's region, but the condition must name the bucket's own region (ViaService matches the service that calls KMS on the bucket's behalf) — a bucket registered under a differently-regioned connection got KMS scoping that never matched, failing every SSE-KMS read. Resolve the bucket's region from the bucket catalog (per-bucket rows already carry it), falling back to the connection's region when the registry is unavailable or the build has none (OSS). The browser data-plane provider projection ships the bucket's region too.
The portal provisions exactly one storage role per (bucket, access level), so a grant no longer stores a provider-role id. The connection and share modals' per-grant selector becomes an access-level picker (Read Only / Annotate / Read Write / Admin); the ConnectionGrant column becomes accessLevel. Server-side, each grant's level resolves to the concrete role for the connection's bucket (exact bucket row match when the bucket catalog is available; connection+level otherwise — unambiguous under the one-role-per-(bucket, level) invariant). The id-based resolveConnectionProvider/findProviderRole are dead under the new model and removed; the advisory level filtering keeps the scope-coverage semantics via the backing role's allowedScopes.
Roles are identified by (provider connection, bucket, access level) — exactly one is provisioned per (bucket, level) — and the level-based grants reference only the level, so the payload's id and synthesized display name have no consumer. The browser projection follows; the OSS deploy-time YAML example mirrors the shape.
|
🎉 This PR is included in version 6.15.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
|
🎉 This PR is included in version 6.4.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
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.
Intent
The cytario-web tail of C-471/C-461. The admin portal (cytario/admin-portal#35) now grants
kms:GenerateDataKey+kms:Decrypt(key-ARN-scoped) on annotate-and-above roles for SSE-KMS buckets — but the browser data plane mints credentials viaAssumeRoleWithWebIdentitywith an inline session policy, and STS applies that policy as an intersection filter, so a role-side Allow alone would still be filtered out of the session. This PR adds the matchingkms:GenerateDataKeystatement for annotate-level connections, so annotation sidecar writes (*.annotations.*.jsonPUTs) to SSE-KMS buckets can generate data keys. Spec: cytario/cytario-docs#163.Changes
app/.server/auth/sessionPolicy.ts—KmsGenerateDataKeyViaS3is now emitted for every level that permits sidecar writes (annotate, joining the existing read-write/admin), keyed offpermitsSidecarWriteinstead of the prefix-write block. Statement shape unchanged (Resource: "*"+kms:ViaServicecondition — the intersection with the role's key-ARN-scoped Allow is what bounds it).app/utils/bucketCatalog.schema.ts— bucket lookup row gains optional nullablekmsKeyArn(reported by the portal at bucket registration; optional so OSS YAML catalogs without it still parse).Testing
sessionPolicy.test.ts: the test pinning annotate's omission now asserts presence (shape: Effect/Resource/ViaService); read-only still asserts omission; new size-ceiling regression check (annotate + 64-char prefix + 25-char bucket ≈ 880 chars, well underPOLICY_SIZE_CEILING = 2048).policySeparation.test.ts(ARCH-1 import-disjointness): passes unchanged — no shared imports added.formatHumanReadableDatetimezone test — passes underTZ=Europe/Berlinlike CI.)