You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Follow-up to #35. That issue scoped deployer observability grants (the human-held bclaw-deployer key that runs setup/manage). This issue covers the other identity in the room: the TaskRole — the credentials the claw itself runs with. When the claw's container or agent misbehaves, the running agent has no AWS-side view of itself: it cannot read its own past log events, cannot see the ECS task/service state it runs in, cannot check CloudWatch alarms or metrics, and cannot look up CloudTrail events.
Problem
The TaskRole (stack resource, inline policies ecs-exec + read-ssm-params, see the TaskRole resource in the CFN template) currently holds exactly two grants:
ssmmessages:* — the four channel actions, for ECS Exec.
ssm:GetParameters + kms:Decrypt (scoped to the claw's /bclaw/* namespace + CMK) — for the aws_ssm secret-source plugin at startup.
That is the entire surface. Concretely, from inside the running task the agent cannot:
Read its own logs. CloudWatch Logs reads for /ecs/bclaw* are granted to the deployer (LogsRead in bclaw-deploy-policy.json), not to the task. After a task replacement, the only copy of the previous task's logs is in CloudWatch Logs — the running agent cannot fetch them.
See its own ECS state.ecs:DescribeTasks/DescribeServices/ListTasks are deployer grants. The agent cannot answer "what task definition revision am I running?", "did my service reach steady state?", "did a deployment stall?", or "what did the previous task's stopped-reason say?" without a human running commands outside.
See alarms/metrics. No cloudwatch:* on the TaskRole. When the agent's own instance is degraded (status-check alarms firing, disk pressure on the EBS volume), the agent has no AWS-side view.
Do CloudTrail forensics. No cloudtrail:LookupEvents — cannot see which API calls were made around the time something broke.
The blast-radius argument cuts both ways: a task that cannot read logs/ECS/CloudWatch is also a task that cannot leak them. The question this issue raises is where to draw that line.
Proposal
Extend the TaskRole in template/.agents/skills/setup-bclaw/template.yaml with a read-only inline policy, e.g. self-observe (illustrative — exact action list is for the RFC to settle):
All listed actions are read-only Describe/List/Get; the Resource: "*" entries follow the same README "why some resources stay Resource: *" precedent as #35.
Open questions for the RFC
Log reads — yes. Reading the claw's previous incarnation's logs after a task replacement is the strongest use case: that data exists nowhere else. Scoped to the /ecs/bclaw* log-group prefix, this looks acceptable.
How much ECS read? Describe* is account-wide visibility (every cluster/service in the account, not just this claw's). ECS Describe/List actions mostly do not support resource-level pinning, so it is * or nothing. Worth it for DescribeTasks (stopped-reason) alone.
Lands in template/.agents/skills/setup-bclaw/template.yaml (TaskRole → new inline self-observe policy). The golden test covers the template change automatically.
Needs an RFC in rfcs/ + integration cycle per AGENTS.md.
The generated README.md policy notes and the manage-bclaw skill's diagnostics sections should gain the corresponding runbook steps so the grants actually get used (aws-cli is already a template mise.toml dep, so the running agent has the tooling).
Follow-up to #35. That issue scoped deployer observability grants (the human-held
bclaw-deployerkey that runs setup/manage). This issue covers the other identity in the room: the TaskRole — the credentials the claw itself runs with. When the claw's container or agent misbehaves, the running agent has no AWS-side view of itself: it cannot read its own past log events, cannot see the ECS task/service state it runs in, cannot check CloudWatch alarms or metrics, and cannot look up CloudTrail events.Problem
The TaskRole (stack resource, inline policies
ecs-exec+read-ssm-params, see theTaskRoleresource in the CFN template) currently holds exactly two grants:ssmmessages:*— the four channel actions, for ECS Exec.ssm:GetParameters+kms:Decrypt(scoped to the claw's/bclaw/*namespace + CMK) — for theaws_ssmsecret-source plugin at startup.That is the entire surface. Concretely, from inside the running task the agent cannot:
/ecs/bclaw*are granted to the deployer (LogsReadinbclaw-deploy-policy.json), not to the task. After a task replacement, the only copy of the previous task's logs is in CloudWatch Logs — the running agent cannot fetch them.ecs:DescribeTasks/DescribeServices/ListTasksare deployer grants. The agent cannot answer "what task definition revision am I running?", "did my service reach steady state?", "did a deployment stall?", or "what did the previous task's stopped-reason say?" without a human running commands outside.cloudwatch:*on the TaskRole. When the agent's own instance is degraded (status-check alarms firing, disk pressure on the EBS volume), the agent has no AWS-side view.cloudtrail:LookupEvents— cannot see which API calls were made around the time something broke.The blast-radius argument cuts both ways: a task that cannot read logs/ECS/CloudWatch is also a task that cannot leak them. The question this issue raises is where to draw that line.
Proposal
Extend the TaskRole in
template/.agents/skills/setup-bclaw/template.yamlwith a read-only inline policy, e.g.self-observe(illustrative — exact action list is for the RFC to settle):{ "Sid": "SelfObserveLogs", "Effect": "Allow", "Action": ["logs:DescribeLogGroups", "logs:DescribeLogStreams", "logs:GetLogEvents", "logs:FilterLogEvents"], "Resource": "<the /ecs/bclaw* log-group ARN pattern, same as the deployer's LogsRead>" }, { "Sid": "SelfObserveEcs", "Effect": "Allow", "Action": ["ecs:DescribeClusters", "ecs:DescribeServices", "ecs:DescribeTasks", "ecs:DescribeTaskDefinition", "ecs:ListTasks"], "Resource": "*" }, { "Sid": "SelfObserveCloudWatch", "Effect": "Allow", "Action": ["cloudwatch:DescribeAlarms", "cloudwatch:GetMetricData", "cloudwatch:GetMetricStatistics", "cloudwatch:ListMetrics"], "Resource": "*" }All listed actions are read-only Describe/List/Get; the
Resource: "*"entries follow the same README "why some resources stayResource: *" precedent as #35.Open questions for the RFC
/ecs/bclaw*log-group prefix, this looks acceptable.*or nothing. Worth it forDescribeTasks(stopped-reason) alone.GetMetricDatareads every metric in the account. If that is a concern, keep metrics deployer-only (Scoped CloudWatch + CloudTrail read grants for the deployer policy so the agent can self-diagnose #35).cloudtrail:LookupEventsexposes management-plane API history (which principal called what) to the running workload — a materially bigger info-disclosure surface than log/ECS reads. Recommend it stays deployer-only (Scoped CloudWatch + CloudTrail read grants for the deployer policy so the agent can self-diagnose #35) and off the TaskRole.Implementation notes
template/.agents/skills/setup-bclaw/template.yaml(TaskRole→ new inlineself-observepolicy). The golden test covers the template change automatically.rfcs/+ integration cycle perAGENTS.md.README.mdpolicy notes and themanage-bclawskill's diagnostics sections should gain the corresponding runbook steps so the grants actually get used (aws-cli is already a templatemise.tomldep, so the running agent has the tooling).