Skip to main content
LLM gateways typically share a single IAM role across all tenants. Without per-request tagging, every Bedrock call attributes to the same identity in AWS Cost Explorer — making cost breakdowns impossible. Portkey solves this by forwarding the x-portkey-metadata header as AWS STS session tags during AssumeRole. Each unique tag set produces a distinct STS session, so AWS records cost and usage per application, team, or environment — no extra IAM roles required.
This feature is available exclusively for Enterprise self-hosted gateway customers. It is not available on the Portkey managed cloud.

How It Works

  1. Client sends x-portkey-metadata with key-value pairs on each request.
  2. Gateway parses the metadata, sanitises it (drops reserved aws: prefixes, enforces AWS limits), and passes the pairs as Tags.member.N.Key / Tags.member.N.Value in the STS AssumeRole POST.
  3. AWS STS issues temporary credentials tagged with those values.
  4. Gateway uses those credentials to call Bedrock InvokeModel.
  5. Tags appear in CUR 2.0 (iamPrincipal/ prefix), CloudTrail, and Cost Explorer.

Prerequisites


Step 1: Configure IAM Permissions on AWS

Session tags require sts:TagSession in two places: the caller’s IAM policy and the target role’s trust policy. Missing either one causes an AccessDenied error. Complete this setup before enabling the feature on the gateway.

1a. Caller principal (the gateway’s execution role)

The IAM role the gateway runs under (e.g. an ECS task role, an EC2 instance profile, or a Kubernetes service account role) must be allowed to both assume and tag the target Bedrock role. Add or update the policy attached to the caller role:
Replace <TARGET_ACCOUNT_ID> and <BEDROCK_ROLE_NAME> with the actual values for the role Portkey assumes to invoke Bedrock.
Cross-account setups: When the gateway and the Bedrock role live in different AWS accounts, both the caller permissions (in the gateway account) and the target trust policy (in the Bedrock account) must allow sts:TagSession. This is the most common source of AccessDenied errors.

1b. Target role trust policy (the Bedrock invocation role)

Open the target role in IAM, go to Trust relationships → Edit trust policy, and ensure the Action includes both sts:AssumeRole and sts:TagSession:
The Condition block is optional but recommended. If you configured an external ID when setting up the assumed role in Portkey, include it here.

1c. Bedrock invocation permissions (no change needed)

The existing permission policy on the target role (bedrock:InvokeModel, bedrock:InvokeModelWithResponseStream) does not need modification. Session tags only affect the AssumeRole call, not the Bedrock API calls themselves.

Step 2: Enable Session Tags on the Gateway

Once IAM permissions are in place, enable the feature by setting the environment variable on the gateway container:
Enable this flag only after completing the IAM setup in Step 1. If sts:TagSession is not permitted on both the caller and target roles, all Bedrock requests through assumed roles will fail with AccessDenied once the flag is enabled.
Restart or redeploy the gateway after adding the variable.

Step 3: Send Metadata with Requests

Pass key-value pairs in the x-portkey-metadata header (or the SDK metadata option). Every key-value pair becomes an STS session tag.

Step 4: Verify Tags in CloudTrail

After sending a tagged request, confirm the tags appear in the AssumeRole CloudTrail event:
A successful tagged request shows a tags array in requestParameters:
If the tags field is absent, double-check:
  • Gateway version is ≥ 2.19.0
  • AWS_BEDROCK_STS_SESSION_TAGS_ENABLED=true is set
  • The gateway was restarted after adding the variable

Step 5: View Costs in AWS Cost Explorer

Session tags flow into AWS Cost and Usage Reports (CUR 2.0) with the iamPrincipal/ prefix. To view them in Cost Explorer:
  1. Open Billing and Cost Management → Cost Allocation Tags.
  2. Filter for User-defined cost allocation tags.
  3. Locate your tag keys (e.g. app, team, env) and click Activate.
Tags take up to 24 hours to appear after the first tagged API call, and a further 24 hours to activate in Cost Explorer.
  1. In Cost Explorer, group or filter by Tag → select your activated tag key.
This breaks down Bedrock spend by application, team, environment, or any other dimension passed in metadata — all through a single shared IAM role.

Tag Constraints and Sanitisation

The gateway automatically sanitises metadata before passing it to AWS STS. Understanding the constraints helps avoid silent tag drops. Source: AWS STS session tag limits, AssumeRole API reference

Credential Caching

The gateway caches STS temporary credentials to minimize AssumeRole API calls. No custom cache configuration is needed — caching works out of the box.

Cache key composition

Each cached credential is keyed by the combination of: Parameters not in the cache key: model name, Portkey API key, virtual key slug, request body. These do not affect the STS call and are irrelevant to credential identity.

TTL and reuse

When does a new AssumeRole call happen?

A new STS AssumeRole call is made only when no cached credential exists for the computed cache key. In practice:
  • Same metadata, same role — Reuses cached credentials for up to 5 minutes. One STS call per 5-minute window.
  • Different metadata, same role — Each unique metadata set triggers its own STS call and produces a separate cached entry. For example, 3 distinct team values means 3 STS calls (then cached for 5 min each).
  • Gateway restart — Clears the in-memory cache. Redis cache (if configured) survives restarts.
  • Source credential rotation — When the gateway’s own credentials change (e.g. ECS task role refresh), the sourceCredentialHash changes and new STS calls are made.

Estimating STS call volume

For a gateway serving 3 teams (ai-platform, mobile, backend) through 1 Bedrock role in 1 region, expect ~3 STS calls every 5 minutes — regardless of request volume.
AWS STS has no hard per-second rate limit, but sustained high call rates may trigger throttling. The 5-minute cache keeps call volume well within safe bounds for typical deployments. If you have hundreds of unique metadata combinations, consider limiting the metadata keys sent as session tags to a small set of high-cardinality dimensions (e.g. team and env, not per-request IDs).

Troubleshooting

This is the most common error. The full message looks like:
Fix: Add sts:TagSession to both the caller’s IAM policy (Step 1a) and the target role’s trust policy (Step 1b). In cross-account setups, both accounts must allow the action.
Possible causes:
  1. Gateway version too old — Confirm >= 2.19.0 by calling GET /health.
  2. Feature flag not set — Verify AWS_BEDROCK_STS_SESSION_TAGS_ENABLED=true is in the container environment (Step 2).
  3. Gateway not restarted — Environment variables are read at startup. Redeploy after adding the variable.
  4. Metadata not sent — Confirm the x-portkey-metadata header is present in Portkey’s request inspector.
  5. Cached credentials — Previously cached (untagged) credentials may still be in use. Wait for the credential TTL to expire or restart the gateway to clear the cache.
  1. Tags must be activated as cost allocation tags in the Billing console (Step 5).
  2. Activation takes up to 24 hours after the first tagged Bedrock call.
  3. Cost Explorer data may lag an additional 24 hours.
  4. Ensure you are looking under User-defined cost allocation tags, not IAM principal type tags.
If Bedrock requests fail immediately after enabling AWS_BEDROCK_STS_SESSION_TAGS_ENABLED, the most likely cause is missing sts:TagSession permissions. As a quick mitigation:
  1. Disable the feature flag: set AWS_BEDROCK_STS_SESSION_TAGS_ENABLED to false (or remove it).
  2. Restart the gateway.
  3. Complete the IAM setup in Step 1, then re-enable.
STS session tags do not survive role chaining by default. If the gateway performs a two-hop assumption (source role → target role), tags passed on the first hop are dropped on the second unless marked as transitive. The gateway does not currently set TransitiveTagKeys.

Reference


Portkey is now PRISMA AIRS AI Gateway. See it in action.

Contact Us
Last modified on September 9, 2026