Problem
When a bclaw deployment misbehaves, the managing agent can already see: CloudFormation stack events, ECS task/service state, EC2 instance state, boot console output, and container log events for /ecs/bclaw*. It cannot see:
- CloudWatch alarms and metrics. The stack creates status-check alarms (the recover alarm that triggers ASG instance replacement), but
bclaw-deploy-policy.json grants no cloudwatch:* reads. When the ASG replaces the instance — exactly the failure mode where there is no ECS Exec target and no running agent to ask — the agent cannot tell whether an alarm fired, when, or why, and cannot pull CPU/disk metrics around the incident to reconstruct what happened.
- CloudTrail event history. When an API call fails with an implicit denial or a resource disappears, the agent has no way to see which principal made which management-plane call, short of the human opening the console.
Current policy state: the deployer policy's observability surface is logs:DescribeLogGroups plus log-stream/event reads scoped to the /ecs/bclaw* log-group ARN pattern (see the LogsRead statement in bclaw-deploy-policy.json). No CloudWatch metrics/alarms, no CloudTrail.
Proposal
Extend template/bclaw-deploy-policy.json with two read-only statements:
{
"Sid": "CloudWatchReadOnly",
"Effect": "Allow",
"Action": [
"cloudwatch:DescribeAlarms",
"cloudwatch:DescribeAlarmHistory",
"cloudwatch:DescribeAlarmsForMetric",
"cloudwatch:GetMetricData",
"cloudwatch:GetMetricStatistics",
"cloudwatch:ListMetrics"
],
"Resource": "*"
},
{
"Sid": "CloudTrailLookup",
"Effect": "Allow",
"Action": "cloudtrail:LookupEvents",
"Resource": "*"
}
All of these are read-only Describe/List/Query actions with no resource-level support, so Resource: "*" is AWS-mandated — same precedent as the existing ReadOnlyDescribe bucket documented in the README's "why some resources stay Resource: *" table.
Then teach the manage-bclaw skill the corresponding diagnostic procedures so the grants get used:
- alarm history around an instance replacement ("did the status-check alarm fire, when, what action")
- metric queries around an incident window (CPU, disk, network on the container instance)
LookupEvents for access-denied forensics ("which principal called what right before the resource vanished")
Caveats
cloudtrail:LookupEvents only returns events when a trail exists in the account (single/multi-region or org trail). bclaw does not create one and should not — trail creation is account-level config and explicitly out of scope. The grant means "use it when it's there".
LookupEvents gives the long-lived deployer key visibility into management-plane API history (which principal called what). Read-only, but it is a small information-disclosure surface and the RFC should say so explicitly.
- Out of scope: creating/modifying alarms or trails, CloudWatch Logs Insights (log reads are already covered where scoped), X-Ray.
Implementation notes
- The change lands in
template/bclaw-deploy-policy.json (extend the ReadOnlyDescribe Sid or add siblings); the golden test covers it.
- The README policy table should gain the new rows.
- Per
AGENTS.md, this needs an RFC in rfcs/ plus an integration cycle against a live claw to verify the grants actually let the agent answer the diagnostic questions above, before port-back.
Problem
When a bclaw deployment misbehaves, the managing agent can already see: CloudFormation stack events, ECS task/service state, EC2 instance state, boot console output, and container log events for
/ecs/bclaw*. It cannot see:bclaw-deploy-policy.jsongrants nocloudwatch:*reads. When the ASG replaces the instance — exactly the failure mode where there is no ECS Exec target and no running agent to ask — the agent cannot tell whether an alarm fired, when, or why, and cannot pull CPU/disk metrics around the incident to reconstruct what happened.Current policy state: the deployer policy's observability surface is
logs:DescribeLogGroupsplus log-stream/event reads scoped to the/ecs/bclaw*log-group ARN pattern (see theLogsReadstatement inbclaw-deploy-policy.json). No CloudWatch metrics/alarms, no CloudTrail.Proposal
Extend
template/bclaw-deploy-policy.jsonwith two read-only statements:{ "Sid": "CloudWatchReadOnly", "Effect": "Allow", "Action": [ "cloudwatch:DescribeAlarms", "cloudwatch:DescribeAlarmHistory", "cloudwatch:DescribeAlarmsForMetric", "cloudwatch:GetMetricData", "cloudwatch:GetMetricStatistics", "cloudwatch:ListMetrics" ], "Resource": "*" }, { "Sid": "CloudTrailLookup", "Effect": "Allow", "Action": "cloudtrail:LookupEvents", "Resource": "*" }All of these are read-only Describe/List/Query actions with no resource-level support, so
Resource: "*"is AWS-mandated — same precedent as the existingReadOnlyDescribebucket documented in the README's "why some resources stayResource: *" table.Then teach the
manage-bclawskill the corresponding diagnostic procedures so the grants get used:LookupEventsfor access-denied forensics ("which principal called what right before the resource vanished")Caveats
cloudtrail:LookupEventsonly returns events when a trail exists in the account (single/multi-region or org trail). bclaw does not create one and should not — trail creation is account-level config and explicitly out of scope. The grant means "use it when it's there".LookupEventsgives the long-lived deployer key visibility into management-plane API history (which principal called what). Read-only, but it is a small information-disclosure surface and the RFC should say so explicitly.Implementation notes
template/bclaw-deploy-policy.json(extend theReadOnlyDescribeSid or add siblings); the golden test covers it.AGENTS.md, this needs an RFC inrfcs/plus an integration cycle against a live claw to verify the grants actually let the agent answer the diagnostic questions above, before port-back.