AWS Bedrock Attribution and Cloud Access Roles

Follow

User Guide: AWS Bedrock Cost Attribution with Kion Cloud Access Roles and Session Tags

This guide walks through using Kion Cloud Access Roles (CARs) with AWS session tags to enable **IAM principal attribution** for AWS Bedrock — giving you per-user, per-team, and per-cost-center visibility into Bedrock inference costs in AWS Cost Explorer and Cost and Usage Reports (CUR 2.0).

How It Works

Amazon Bedrock automatically records the IAM principal (role) identity for every inference request made through the bedrock-runtime APIs (InvokeModel, Converse, Chat Completions). When users access AWS through a Kion Cloud Access Role, every session Kion brokers carries:

  1. The caller identity ARN — Kion sets the STS role session name to the user’s Kion username, so the identity ARN looks like arn:aws:sts::123456789012:assumed-role/<car-role-name>/<kion-username>. Bedrock captures this automatically; no tags required.
  2. Session tags — key/value pairs Kion passes on sts:AssumeRole when generating federated console access or short-term access keys. These come from two sources:
    • CAR-level session tags — defined on the Cloud Access Role itself; applied to every user of that role. Good for static dimensions like Team, Department, or Environment.
    • User-level session tags — captured from your SAML identity provider at login (any SAML attribute whose name contains PrincipalTag:, e.g. https://aws.amazon.com/SAML/Attributes/PrincipalTag:CostCenter). Good for dynamic, per-user dimensions like User or CostCenter. If a user-level tag and a CAR-level tag share a key, the user-level value wins.

Kion marks all session tags as transitive, so they survive role chaining. After you activate these tag keys as cost allocation tags in AWS Billing, Bedrock spend can be filtered and grouped by them in Cost Explorer and CUR 2.0.

Note: For per-prompt detail, see Bedrock’s per-request metadata tagging or model invocation logging.

Prerequisites

  • A Kion-managed AWS account where Bedrock will be used, with the Kion service role trust policy allowing sts:TagSession (Kion’s standard trust policy template includes both sts:AssumeRole and sts:TagSession; verify under Settings → AWS Access if your roles were provisioned with a customized policy).
  • Access to the AWS Billing and Cost Management console in the payer account (for cost allocation tag activation and the CUR 2.0 Data Export).
  • (Optional, for per-user tags) A SAML IDMS configured in Kion whose assertions include PrincipalTag: attributes. Note: per-user session tags are currently supported for SAML only, not OIDC.

Part 1: Create a Cloud Access Role with Session Tags

Step 1 — Navigate to the CAR creation form

For a Project-scoped role:

  1. In Kion, open the Project where Bedrock will be used.
  2. Go to the Identity tab → Cloud Access Roles.
  3. Click Add / Create Cloud Access Role.

(The same flow exists at the OU level under OU → Identity → Cloud Access Roles if you want the role inherited by all child projects.)

Step 2 — Configure the role basics

  • Name: e.g. bedrock-user
  • AWS IAM Role Name: e.g. kion-bedrock-user
  • Access types: enable Web Access (federated console) and/or Short-Term Access Keys depending on how users will call Bedrock. Short-term access keys are what most users will use for programmatic/SDK access to Bedrock.

Learn more about creating and applying cloud access roles.

Step 3 — Attach Bedrock IAM permissions

Attach an IAM policy granting the Bedrock access your users need. A minimal inference-only example:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "bedrock:InvokeModel",
        "bedrock:InvokeModelWithResponseStream",
        "bedrock:Converse",
        "bedrock:ConverseStream",
        "bedrock:ListFoundationModels",
        "bedrock:GetFoundationModel"
      ],
      "Resource": "*"
    }
  ]
}

Create this as a managed IAM policy in Kion (Cloud Management → IAM Policies) and attach it to the CAR, or attach an existing policy.

Step 4 — Add AWS Session Tags

In the CAR form, find the AWS Session Tags (Optional) section:

  1. Click Add Key/Value Pair.
  2. Enter a tag key and value. Recommended dimensions (aligned with the Bedrock attribution doc):
Tag Key Example Value
Team DataScience
Department Engineering
CostCenter
CC-1001
Environment
Production

        3. Add as many pairs as needed (AWS allows up to 50 session tags per role session) and save the role.

Kion will provision the IAM role in the account(s) and pass these tags on every `AssumeRole` it performs for this CAR.

Step 5 (Optional) — Per-user tags from your SAML IdP

Static CAR tags answer “which team/project spent this,” but for **per-user** Bedrock attribution through a shared role you want a `User` tag that varies by person. Configure your SAML IdP (Okta, Entra ID, Ping, etc.) to emit attributes in this form:

https://aws.amazon.com/SAML/Attributes/PrincipalTag:User      → jane@example.com
https://aws.amazon.com/SAML/Attributes/PrincipalTag:CostCenter → CC-1001

Kion parses any assertion attribute containing PrincipalTag: at login, stores the key/value against the user, and merges those tags into every session that user starts — overriding CAR-level tags on key conflicts. Tags refresh on each SAML login.

Even without aUsertag, you still get per-user identity attribution from the caller identity ARN, since Kion sets the role session name to the Kion username. TheUsersession tag is what lets you group by user in Cost Explorer, though.

Part 2: Using the Cloud Access Role

Users on the project (added directly or via user groups on the CAR) access Bedrock through Kion as usual:

  • Federated console access: from the project’s Cloud Access menu, select the account and the CAR → Kion generates a console sign-in link. Sessions opened this way carry the session tags; anything the user does in the Bedrock console (playground, etc.) is attributed.
  • Short-term access keys: select Short-Term Access Keys for the account/CAR → Kion calls sts:AssumeRole with the merged session tags and returns temporary credentials. Export them and call Bedrock normally:
export AWS_ACCESS_KEY_ID=...
export AWS_SECRET_ACCESS_KEY=...
export AWS_SESSION_TOKEN=...

aws bedrock-runtime converse \
  --model-id anthropic.claude-sonnet-4-6 \
  --messages '[{"role":"user","content":[{"text":"Hello"}]}]'

Every call made with those credentials is attributed in AWS billing to the session’s identity ARN and session tags. No application code changes are needed — attribution is based on who made the call.

Using the Kion CLI

The Kion CLI is the most convenient way to use a CAR for programmatic Bedrock access. It authenticates against your Kion instance and obtains short-term keys through the same Kion API as the web UI — so every credential it hands out carries the same identity ARN and session tags, and Bedrock attribution works identically.

Install and configure:

brew install kionsoftware/tap/kion-cli

Create ~/.kion.yml:

kion:
  url: https://kion.example.com
  api_key: <your-kion-api-key>   # or omit to authenticate with username/password or SAML
  default_region: us-east-1
favorites:
  - name: bedrock
    account:"111122223333"
    cloud_access_role: bedrock-user

Ad-hoc credentials and console access:

# Export short-term keys into your current shell
kion stak --account 111122223333 --car bedrock-user

# Run a single command with temporary credentials
kion run --favorite bedrock -- aws bedrock-runtime converse \
  --model-id anthropic.claude-sonnet-4-6 \
  --messages '[{"role":"user","content":[{"text":"Hello"}]}]'

# Open the federated console in a browser
kion console --account 111122223333 --car bedrock-user

AWS SDK credentials provider (credential_process):

For applications, notebooks, and scripts using any AWS SDK, configure the Kion CLI as a credential process in ~/.aws/config. The SDK’s default credential chain invokes the Kion CLI on demand, which returns fresh session-tagged credentials — nothing long-lived is stored on disk:

[profile bedrock]
credential_process= kion stak --credential-process --account 111122223333 --car bedrock-user
region= us-east-1

# Or reference a favorite from ~/.kion.yml
[profile bedrock-fav]
credential_process= kion favorite --credential-process bedrock
region= us-east-1

Then every SDK picks it up automatically via the profile — for example with boto3:

import boto3

session = boto3.Session(profile_name="bedrock")
client = session.client("bedrock-runtime")

response = client.converse(
    modelId="anthropic.claude-sonnet-4-6",
    messages=[{"role": "user", "content": [{"text": "Hello"}]}],
)

Or with the AWS CLI / any SDK that honors AWS_PROFILE:

AWS_PROFILE=bedrock aws bedrock-runtime converse --model-id anthropic.claude-sonnet-4-6 \
  --messages '[{"role":"user","content":[{"text":"Hello"}]}]'

Because the credentials come from Kion’s

AssumeRole

(CAR tags + the user’s SAML-derived tags, session name = Kion username), all Bedrock usage from these SDK calls is attributed per user in Cost Explorer and CUR 2.0 — even when many developers share the same CAR. This is the same pattern the Bedrock doc describes for LLM gateways, with Kion acting as the credential broker.

Note: Bedrock IAM principal attribution applies tobedrock-runtimeAPIs (InvokeModel / Converse / Chat Completions). Long-term access keys on a CAR (if enabled) authenticate as an IAM user rather than an assumed-role session and will not carry session tags — prefer web access and short-term keys for attributed Bedrock usage.

Part 3: Enable Cost Allocation in AWS Billing

The identity and tags are now flowing on every request; two one-time steps in the payer account make them usable for cost reporting.

Step 1 — Create a CUR 2.0 Data Export with caller identity

  1. In Billing and Cost Management, choose Data Exports.
  2. Choose Create and select a CUR 2.0 export.
  3. In the export configuration, enable all facets.
  4. Choose the destination S3 bucket and complete the export setup.

Step 2 — Activate the IAM principal cost allocation tags

  1. Open the AWS Billing and Cost Management console.
  2. Choose Cost allocation tags in the navigation pane.
  3. Filter by type IAM principal to find your tag keys (Team, CostCenter, User, etc.).
  4. Select them and choose Activate.

Notes:

  • Tag keys only appear in this list after at least one Bedrock API call has been made with them — use the CAR first, then activate.
  • Activation is not retroactive: only costs incurred after activation are tagged.
  • Activated tags can take up to 24 hours to start appearing.
  • Activated principal/session tags appear in CUR 2.0 with the iamPrincipal/ column prefix.

Important: If you already have a CUR 2.0 export that was created before enabling this, you must create a new export with the caller identity option selected — existing exports do not retroactively include identity data.

 


Limitations and Gotchas

  • Aggregation, not per-request: attribution is per usage type per day, per identity/tag. Session tags are fixed at AssumeRole time and constant for the session’s lifetime.
  • bedrock-runtime APIs only (InvokeModel / Converse / Chat Completions) today; bedrock-mantle API support is coming from AWS.
  • Tag precedence: user-level (SAML) session tags override CAR-level tags on the same key; session tags override any static principal tags on the IAM role itself.
  • sts:TagSession is required in the IAM role’s trust policy. Kion’s standard generated trust policy includes it, but verify on custom-trust-policy CARs.
  • OIDC IDMS users currently get CAR-level tags only — per-user session tags from the IdP are SAML-only in Kion today.
  • Not retroactive: cost allocation tags only apply to spend after activation, and new CUR 2.0 exports only include identity data going forward.
  • Up to 24-hour delay for data to appear in Cost Explorer and CUR after requests are made.

Bonus: Contextual Claude Code Configuration and Kion CLI

Claude Code can be configured to use project-level settings for Bedrock access:

.claude/settings.local.json

  {
    "env": {
      "CLAUDE_CODE_USE_BEDROCK": "1",
      "AWS_PROFILE": "bedrock-cc-project-2",
      "AWS_REGION": "us-east-1",
      "ANTHROPIC_MODEL": "global.anthropic.claude-opus-4-6-v1",
      "ANTHROPIC_SMALL_FAST_MODEL": "global.anthropic.claude-sonnet-4-6"
    }
  }

The AWS_PROFILE ensures that claude code in this project will utilize a profile configured for the Kion CLI credentials provider. You can utilize different CARs to attribute spend to different projects.