aws-samples / aws-samples/sample-autonomous-cloud-coding-agents

Tighten trace-artifacts bucket IAM: scope runtime s3:PutObject to per-user prefix

Ouverte
#59 0 commentaires 0 réactions 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

infra-cdk security
Langage dominant
TypeScript
Étoiles
146
Forks
46
Merge moyen
3 j 10 h
PR mergées (30 j)
24

Description

> **Follow-up from [PR #52](https://github.com/aws-samples/sample-autonomous-cloud-coding-agents/pull/52)** — security hardening identified during design review; shipped as a pragmatic MVP with a `TODO` pointing at this follow-up.

## Functional description

When a task's `--trace` option is enabled, the agent uploads a detailed execution trace (a JSONL-compressed artifact) to a shared S3 bucket. Per-user isolation is enforced by the agent code convention that each trace goes under `traces//.jsonl.gz`.

**The problem:** that per-user isolation is a **trust boundary**, not an **enforcement boundary**. The runtime's IAM role currently has `s3:PutObject` on the entire bucket (`traceArtifactsBucket/*`) — so a compromised or buggy runtime could overwrite another user's trace artifact. The only thing preventing cross-user writes today is the agent's own code being well-behaved.

**Who cares:** security reviewers, enterprise customers, anyone running this in a regulated environment. Not currently exploitable (our code doesn't have that bug), but it's a defense-in-depth gap that will come up in any security audit.

## Technical context

`cdk/src/stacks/agent.ts` grants the AgentCore runtime `s3:PutObject` on `traceArtifactsBucket/*` via `grantPut(runtime)` — no prefix, no condition. Design §10.1 calls out this loosening as the pragmatic MVP. A `TODO` at the `grantPut` call site points at this issue.

**Why the obvious fix doesn't work today:** PR #52's L4 spike confirmed that Bedrock AgentCore's `InvokeAgentRuntimeCommand` does **NOT** currently expose `sessionTags` or `TransitiveTagKeys`. The originally-envisioned `aws:PrincipalTag/UserId` condition on the bucket resource policy is not viable — the SDK type `InvokeAgentRuntimeRequest` only accepts `runtimeSessionId`, `runtimeUserId`, `traceId`, etc., and `runtimeUserId` is a logical identifier, not an IAM principal tag.

## Proposed options (all require separate design review + PR)

1. **Orchestrator-minted presigned PUT URL (preferred):** the orchestrator signs a one-shot `PutObject` URL scoped to the exact key `traces//.jsonl.gz` and passes it in the AgentCore invocation payload. Drop `grantPut(runtime)` entirely. `upload_trace_to_s3` switches from `boto3.client('s3').put_object` to an HTTPS PUT against the presigned URL.

2. **Dedicated uploader Lambda:** a narrowly-scoped Lambda with an IAM policy conditioned on a caller-supplied `user_id` uploads on behalf of the runtime. Runtime loses `s3:PutObject` entirely and invokes the Lambda instead.

3. **Watch for SessionTags API:** track AWS release notes for `@aws-sdk/client-bedrock-agentcore` updates exposing session tags; revisit this issue when supported. Lowest effort but indefinite timeline.

## Acceptance criteria

- Runtime IAM role has **no** `s3:PutObject` on the trace-artifacts bucket, OR the grant is scoped with a condition whose effective reach is no wider than the user's own `traces//` prefix.
- `upload_trace_to_s3` test coverage unchanged or improved.
- cdk-nag suppression near the grant call in `cdk/src/stacks/agent.ts` is updated to reflect the tightened posture (the current suppression mentions "broad PutObject" and should be narrowed or removed).
- `TODO` comment at the `grantPut` call site is resolved or updated to point at a clearer next step.

## Out of scope

- Changing the trace key layout (`traces//.jsonl.gz` is load-bearing across orchestrator, agent, handler, and CLI — renaming is a separate project).
- Migration to a different storage backend.

## References

- `cdk/src/stacks/agent.ts` — `grantPut(runtime)` call site (has the `TODO` comment)
- `agent/src/telemetry.py` — trace key construction (`traces//.jsonl.gz`)
- `docs/design/ARCHITECTURE.md` §10.1 — design decision and loosening rationale
- `@aws-sdk/client-bedrock-agentcore` `InvokeAgentRuntimeRequest` type (session-tag gap)

Guide de contribution

Ouvrir le guide de contribution

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Piste de recherche

Commencez par le TODO et l’appel à grantPut dans cdk/src/stacks/agent.ts, puis lisez agent/src/telemetry.py et docs/design/ARCHITECTURE.md §10.1. Examinez les tests existants de upload_trace_to_s3 et la PR #52 avant de choisir entre les designs proposés. C’est terminé lorsque les écritures à l’exécution sont limitées au préfixe de l’utilisateur ou supprimées, que le texte de suppression et le texte du TODO sont mis à jour, et que la couverture des traces est préservée.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Évaluation

Stack technique
aws, python, typescript
Domaine
cloud, infrastructure, security
Type d'issue
Bug
Difficulté
5/5
Temps estimé
Plus d'une semaine
Activité
Calme
Clarté
Plutôt claire
Accessibilité débutants
35/100

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.