Repository navigation
feat(s3/bucket): allow s3:BypassGovernanceRetention in policies - #88
Merged
Merged
Conversation
A principal may be granted the right to delete or shorten a governance-locked version, as S3 allows in a bucket policy. Hilt prices the bypass header on the delete and retention operations against it. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
alanshaw
added a commit
to fil-forge/hilt
that referenced
this pull request
Oct 22, 2026
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
alanshaw
added a commit
to fil-forge/hilt
that referenced
this pull request
Oct 22, 2026
A delete or a retention write that asks to bypass governance retention, with `x-amz-bypass-governance-retention: true`, needs `s3:BypassGovernanceRetention` in S3. Hilt had no such permission, so the header carried no decision here. This is the Hilt half of governance bypass; the gateway half stays as it is. ### What changes `s3:BypassGovernanceRetention` joins the vocabulary as a policy action, added by fil-forge/libforge#88 and now on libforge main, which this pins, and as a service-key permission. It maps to no Forge commands of its own, since the delete or retention write it rides on carries them. The header is priced like the other header-added permissions: on DeleteObject, DeleteObjectVersion, DeleteObjects and PutObjectRetention, read on its first value case-insensitively as the gateway reads it, and only when the signature covers it. A service key must hold the permission and a principal's effective set must grant it. ### What does not change Ingot's gateway layer decides the bypass itself against the bucket's lock state, and today refuses it whatever the key holds, since it looks for the grant in a bucket policy document Ingot does not serve internally. So the permission has no effect on the wire yet: a request carrying the header is refused by Hilt without the permission, and by the gateway with it. The gateway hook that would honour Hilt's answer is the parked other half. ### Behaviour changes to know about - A request carrying the bypass header from a key or principal without the permission is now refused by Hilt as not permitted, where before it reached the gateway and was refused there. The outcome is the same; the refusing side moves. - A bypass header the signature does not cover is refused as `UnsignedHeader`, like the lock headers. - Keys issued with explicit permission lists, and policies that list actions, can now name `s3:BypassGovernanceRetention`. 馃 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
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.
S3 lets a bucket policy grant
s3:BypassGovernanceRetention, the right to delete or shorten a governance-locked version with thex-amz-bypass-governance-retentionheader. This adds it to the policy action allowlist so a principal can hold it.Hilt's follow-up prices that header on DeleteObject, DeleteObjects and PutObjectRetention against the permission, for both key kinds. Ingot's gateway layer keeps refusing governance bypass for now, whatever the key holds, so the permission has no effect on the wire until that side is done; this and the Hilt change settle the vocabulary and the authorization decision ahead of it.
馃 Generated with Claude Code