README: operator notes for the mail user boundary
What to set (CARLOS_MAIL_USER_BOUNDARY), the IAM the console role needs (iam:PutUserPermissionsBoundary on user/carlos-mail/*, conditioned on the boundary ARN), that the backfill is lazy, and when to condition CreateUser and PutUserPolicy on iam:PermissionsBoundary.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 file changed,
+9
−0
README.md+9 −0
diff --git a/README.md b/README.md| index 7a4b80895..940768627 100644 |
| --- a/README.md |
| +++ b/README.md |
| @@ -496,6 +496,15 @@ This release stops every box and the console from reading the whole deployment b |
| - customer fleet boxes keep reading the way they do today. |
| - to see the effect, look at daily S3 ListBucket and GetObject requests for the deployment bucket in Cost Explorer. they should fall within a day of arming. |
| +### Email sending users get a permissions boundary (2026-10-23) |
| + |
| +This release creates every email sending user (IAM path `/carlos-mail/`) under a permissions boundary, the way store users already are. Without one, anything that can act as the console's role can create a user on that path, give it an administrator policy and mint it a key. |
| + |
| +- a console with `CARLOS_MAIL_REGION` set now refuses to start without `CARLOS_MAIL_USER_BOUNDARY`. set it to the ARN of an IAM managed policy that allows `ses:SendRawEmail` and nothing else. |
| +- create that policy and give the console role `iam:PutUserPermissionsBoundary` on `user/carlos-mail/*` before this rolls. condition it on `iam:PermissionsBoundary` equal to the boundary ARN, or the role can set any boundary it likes. never grant `iam:DeleteUserPermissionsBoundary`. nothing calls it. |
| +- existing users are fixed lazily. a user without the boundary, or with a different one, gets the configured one the next time the console ensures it: `carlos email enable` for the app, a new standalone credential, or a domain change that refreshes the app's policies. until then it stays unbounded. list the ones still missing it with `aws iam get-user` over `aws iam list-users --path-prefix /carlos-mail/`. |
| +- once every console runs this release and every existing user carries the boundary, condition the role's `iam:CreateUser` and `iam:PutUserPolicy` on `iam:PermissionsBoundary` too. the console sets the boundary before it writes the policy, so the condition does not block the backfill. |
| + |
| ## App config & secrets |
| Per-app config lives in the deployment bucket |