Skip to content

Scoped CloudWatch + CloudTrail read grants for the deployer policy so the agent can self-diagnose #35

Description

@BoldBlackBot

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:

  1. 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.
  2. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions