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

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

Aperta
#59 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub
infra-cdk security
Lingua principale
TypeScript
Stelle
143
Fork
46
Merge medio
3g 9h
PR unite (30g)
20

Descrizione

> **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)

Guida per i contributori

Apri la guida per i contributori

Direzione di ricerca

Inizia con il TODO e la chiamata a grantPut in cdk/src/stacks/agent.ts, poi leggi agent/src/telemetry.py e docs/design/ARCHITECTURE.md §10.1. Esamina i test esistenti di upload_trace_to_s3 e la PR #52 prima di scegliere tra i design proposti. Il lavoro è completato quando le scritture a runtime sono limitate al prefisso dell’utente o rimosse, il testo di soppressione e il testo del TODO sono aggiornati e la copertura delle trace è preservata.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
aws, python, typescript
Ambito
cloud, infrastructure, security
Tipo di issue
Bug
Difficoltà
5/5
Tempo stimato
Più di una settimana
Stato di attività
Tranquilla
Chiarezza
Abbastanza chiara
Idoneità per principianti
35/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.