Download this file
| 1 | # đŸ¤– Scoped credentials for the Litestream canary — the shape per-instance |
| 2 | # (later per-box) credentials take: confined to one prefix of the instances |
| 3 | # bucket, so a leaked key exposes one instance's ciphertext, not the fleet's. |
| 4 | # No access key is declared here (it would land in state); mint one with |
| 5 | # aws iam create-access-key --user-name litestream-canary |
| 6 | # and store it in 1Password. |
| 7 | |
| 8 | resource "aws_iam_user" "litestream_canary" { |
| 9 | name = "litestream-canary" |
| 10 | } |
| 11 | |
| 12 | data "aws_iam_policy_document" "litestream_canary" { |
| 13 | statement { |
| 14 | sid = "ListCanaryPrefix" |
| 15 | actions = ["s3:ListBucket"] |
| 16 | resources = [aws_s3_bucket.state["instances"].arn] |
| 17 | |
| 18 | condition { |
| 19 | test = "StringLike" |
| 20 | variable = "s3:prefix" |
| 21 | values = ["canary/*", "canary"] |
| 22 | } |
| 23 | } |
| 24 | |
| 25 | statement { |
| 26 | sid = "ReadWriteCanaryObjects" |
| 27 | actions = [ |
| 28 | "s3:GetObject", |
| 29 | "s3:PutObject", |
| 30 | "s3:DeleteObject", |
| 31 | ] |
| 32 | resources = ["${aws_s3_bucket.state["instances"].arn}/canary/*"] |
| 33 | } |
| 34 | } |
| 35 | |
| 36 | resource "aws_iam_user_policy" "litestream_canary" { |
| 37 | name = "litestream-canary-prefix" |
| 38 | user = aws_iam_user.litestream_canary.name |
| 39 | policy = data.aws_iam_policy_document.litestream_canary.json |
| 40 | } |
| 41 | |