Skip to content

Task-role scoped read permissions for runtime self-introspection (logs, ECS state, CloudWatch/CloudTrail) #36

Description

@BoldBlackBot

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:

  1. ssmmessages:* — the four channel actions, for ECS Exec.
  2. 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):

{
  "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 stay Resource: *" precedent as #35.

Open questions for the RFC

  1. 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.
  2. 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.
  3. CloudWatch metrics/alarms — TaskRole or deployer-only? Metrics are account-wide; a task with GetMetricData reads 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).
  4. CloudTrail — recommend no. cloudtrail:LookupEvents exposes 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

  • 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.
  • Complementary to Scoped CloudWatch + CloudTrail read grants for the deployer policy so the agent can self-diagnose #35, does not subsume it: the deployer key keeps its grants for teardown and not-yet-deployed scenarios.
  • 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).

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