carlos / platform Public

infra: read-only inventory grant for the architecture page

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Paul Campbell pushed by paul@keymail.dev f64f7fcc91fda57c298cd436b757c2ef29f19d09 parent 7dc9b80
2 files changed, +40 −0
  • docs/superpowers/specs/2026-08-19-fleet-architecture-diagram-design.md +6 −0
  • infra/modules/region-host/main.tf +34 −0
diff --git a/docs/superpowers/specs/2026-08-19-fleet-architecture-diagram-design.md b/docs/superpowers/specs/2026-08-19-fleet-architecture-diagram-design.md
index 0db071256..eabe177ae 100644
--- a/docs/superpowers/specs/2026-08-19-fleet-architecture-diagram-design.md
+++ b/docs/superpowers/specs/2026-08-19-fleet-architecture-diagram-design.md
@@ -324,6 +324,12 @@ inventory is not granted. **The page must be built and merged without
depending on the grant existing** — the ungranted state is a first-class
rendering, not a broken one.
+**Status (2026-08-19):** the module statement is in this repo as of this
+branch. The flagship box runs a role provisioned from pinfra, so the grant
+reaches production only when the matching pinfra change is applied — until
+then `/fleet/architecture` renders the CARLOS half and reports the estate
+as ungranted, which is the designed state and not a fault.
+
## 9. Testing
- `internal/infraview`: shape round-trip, and the additive rule — an
diff --git a/infra/modules/region-host/main.tf b/infra/modules/region-host/main.tf
index c145aac8f..407565c29 100644
--- a/infra/modules/region-host/main.tf
+++ b/infra/modules/region-host/main.tf
@@ -97,6 +97,40 @@ resource "aws_iam_role_policy" "host_buckets" {
Action = ["ssm:GetParameter"]
Resource = var.ssm_parameter_arn
},
+ # Infrastructure inventory (2026-08-19-fleet-architecture-diagram-design.md
+ # §8): what the console's hourly infra pass needs to draw
+ # /fleet/architecture. Read-only in the strictest sense — every action
+ # here is a List/Describe/Get of a resource's SHAPE. No write action,
+ # no s3:GetObject, and deliberately no iam:GetPolicyVersion: the page
+ # shows that a role exists and how many policies are attached to it,
+ # never what those policies say.
+ {
+ Effect = "Allow"
+ Action = [
+ "ec2:DescribeInstances",
+ "ec2:DescribeVolumes",
+ "ec2:DescribeAddresses",
+ "ec2:DescribeSecurityGroups",
+ "ec2:DescribeVpcs",
+ "ec2:DescribeSubnets",
+ "ec2:DescribeRegions",
+ "tag:GetResources",
+ "s3:ListAllMyBuckets",
+ "s3:GetBucketLocation",
+ "s3:GetBucketVersioning",
+ "s3:GetEncryptionConfiguration",
+ "s3:GetBucketPublicAccessBlock",
+ "route53:ListHostedZones",
+ "route53:ListResourceRecordSets",
+ "iam:ListRoles",
+ "iam:ListUsers",
+ "iam:ListAttachedRolePolicies",
+ "cloudwatch:DescribeAlarms",
+ "acm:ListCertificates",
+ "sts:GetCallerIdentity",
+ ]
+ Resource = "*"
+ },
]
})
}