aws-samples / aws-samples/sample-kiro-cost-analyzer

Ingest Amazon Bedrock (Claude Code) invocation logs as a new clientType

Open
#56 0 comments 0 reactions 0 assignees View on GitHub
enhancement
Dominant language
Python
Stars
11
Forks
3
Avg merge
3h 11m
Merged PRs (30d)
36

Description

## Problem

Organizations running Kiro Enterprise often also have developers using **Claude Code pointed at Amazon Bedrock** in the same AWS account. That consumption is invisible to this tool today, fragmenting the org's view of AI-assisted development cost. The analysis (`docs/evolution-analysis.md`, Parte B) concludes ingestion is viable and the architecture supports it well — but it is **not "just read another CSV"**; there are three real design frictions.

> **Depends on #55 (ETL source-adapter seam).** This feature is implemented as one new adapter on that seam plus the identity/pricing machinery below.

## Data source

**Bedrock model invocation logging → S3** (one opt-in Bedrock setting). One JSON record per `InvokeModel`/`Converse`: timestamp, model id, token counts (incl. cache read/write), caller IAM identity ARN, and optionally request/response bodies. Structural analog of the Kiro prompt logs the ETL already ingests. (OTel productivity metrics and CUR reconciliation are explicitly out of scope.)

## The three frictions

1. **Credits vs tokens** — cost model diverges. `CLAUDE_CODE` records carry token/USD, never credit fields. The tier-recommendation engine does not apply and the UI must exclude these users from it.
2. **Identity attribution (hardest)** — the log carries an IAM ARN, which may be a shared assumed role. Per-user attribution requires individual credentials (IDC federation carrying the user in the session name, or per-dev inference profiles). `IDENTMAP#` items (mirroring the `GITMAP#` precedent) resolve ARN+session → session-name mode → static mode → `UNMAPPED#{role-name}` (visible, never dropped).
3. **Self-invocation filtering** — the log records all Bedrock use in the account, including this stack's own categorization/correlation calls. An exclusion list (seeded with the stack's own role ARNs) drops+counts them.

## Tasks (by checkpoint)

- [ ] **Adapter core** — `etl/sources/bedrock_invocation_log.py`: `claim` on the Bedrock log key layout, `parse` (JSON-lines, token/identity/body extraction, `skippedRecords`), `normalize` (`clientType=CLAUDE_CODE`, activity + prompt records); register only when the feature param is set
- [ ] **Pricing** — `PRICING#BEDROCK` config item (admin-editable, tier-pricing pattern), `estimatedCostUsd` with `Decimal`, `unpricedInvocations` counter (never silent-zero)
- [ ] **Identity** — `IDENTMAP#` accessors + resolution; `Admins`-guarded `GET/PUT/DELETE /api/settings/identity-mappings`
- [ ] **Self-invocation exclusion** — SSM param seeded in `template.yaml`; drop+count before normalize
- [ ] **Coexistence** — tier engine excludes exclusively-`CLAUDE_CODE` users; engagement/funnel/dormant/client-type include them; frontend USD-estimate labels + unmapped-row labeling; catalog keys in both locales
- [ ] **Infra/docs/ship** — optional `BedrockInvocationLogLocation` SAM param + scoped S3 read policy; `docs/deploy.md` (enabling logging + attribution prerequisite); `docs/architecture.md`; full gates + `docs/changelog.md`

Effort comparable to the `gitlab-provider-support` spec (the internal precedent for "add a second provider to a system designed for one").

Full spec: `.kiro/specs/bedrock-claude-code-ingestion/` on the analysis branch.

Contributor guide

Open the contributing guide

Research direction

Start with dependency #55 and the full spec in .kiro/specs/bedrock-claude-code-ingestion/, then inspect etl/sources/bedrock_invocation_log.py, template.yaml, the settings API, and the referenced docs. Done means all listed checkpoints pass, including adapter registration, pricing and identity handling, exclusion and coexistence behavior, infrastructure and documentation updates, and the full project gates.

Written by the indexing model from the issue text.

Assessment

Tech stack
aws, python
Domain
backend, cloud, data-engineering
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.