AWS VDP · Report #3702072
bedrock-mantle.api.aws accepts Bedrock API keys outside the IAM Deny, CloudTrail signal, and invocation logging AWS publishes for Bedrock keys
How it was found
NOTE! Thanks for submitting a report to Amazon Web Services! Please replace all the [square] sections below with the pertinent details. Remember, the more detail you provide, the easier it is for us to triage and respond quickly, so be sure to take your time filling out the report!
Summary
Bedrock API keys (both long-term ABSK* and short-term bedrock-api-key-*) authenticate against bedrock-mantle.{region}.api.aws, a parallel inference plane reachable in 7+ regions with 38 of 39 catalog models billable. Three customer-deployable defensive controls fail to apply to this plane: (1) the AWS-published SCP/IAM Deny: bedrock:CallWithBearerToken does not match mantle's IAM action prefix, (2) the AWS-published CloudTrail filter additionalEventData.callWithBearerToken = true does not match mantle events (the field is at a different JSON path), (3) put-model-invocation-logging-configuration does not capture mantle prompts and there is no equivalent customer-facing API for mantle today, i.e. customers cannot enable mantle prompt/response logging even if they want to. The first two are correctable by a customer once they know mantle exists; the third requires an AWS-side change. Reproduced live on 2026-04-27 against test account ████████. End-to-end repro: bash reproduce.sh "$ABSK" "" "$PHANTOM_USER" (attached).
Description:
AWS publishes guidance for detecting and preventing abuse of Bedrock API keys (long-term ABSK* and short-term bedrock-api-key-* bearer tokens) in two primary places:
- The AWS Security Blog "Securing Amazon Bedrock API Keys" recommends
additionalEventData.callWithBearerToken = trueas the primary CloudTrail detection signal. - The Bedrock CloudTrail user guide describes data event configuration for
AWS::Bedrock::*resource types and referencesaws bedrock put-model-invocation-logging-configurationfor prompt/response capture.
Both pages, plus the AWS-managed policy AmazonBedrockLimitedAccess (which is automatically attached to every IAM user provisioned during long-term API key creation through the AWS Console), grant access to a second Bedrock service plane that the documentation does not mention: bedrock-mantle. The IAM action prefix bedrock-mantle:* (4 actions including CallWithBearerToken, Get*, List*, CreateInference) is listed in AmazonBedrockLimitedAccess v8 but is not described in any customer-facing Bedrock or Bedrock API key documentation.
The mantle plane is publicly callable at https://bedrock-mantle.{region}.api.aws (resolves in 7+ regions; reverse-DNS and WHOIS confirm AWS ownership), serves an OpenAI-compatible surface (/v1/models, /v1/chat/completions) with 38 of 39 catalog models invocable and billable, and authenticates both ABSK* long-term and bedrock-api-key-* short-term tokens that were issued for the standard Bedrock plane. Three customer-facing defenses break against this surface:
| # | Defense AWS publicly recommends | Behavior against bedrock-mantle.api.aws |
|---|---|---|
| A | SCP/IAM Deny: bedrock:CallWithBearerToken | Bypassed. The mantle plane uses IAM action bedrock-mantle:CallWithBearerToken which the policy does not match. |
| B | CloudTrail filter additionalEventData.callWithBearerToken = true | Bypassed. Mantle events place the field at requestParameters.callWithBearerToken instead. |
| C | aws bedrock put-model-invocation-logging-configuration for prompt/response capture | Bypassed. Mantle inference does not appear in the configured BedrockModelInvocationLogs S3 prefix. |
Mantle inference does land in CloudTrail as a data event (eventSource: bedrock-mantle.amazonaws.com, eventName: CreateInference), but on a different field path than the detection signal AWS publishes for Bedrock API keys.
The combined result is that a customer following AWS's published guidance to detect Bedrock API key abuse achieves zero visibility against the bedrock-mantle plane while their leaked API key still authenticates against it and consumes billable inference on premium third-party models.
Steps To Reproduce:
Prerequisites:
- An AWS account with Amazon Bedrock available in the test region (
us-east-1for this report) and at least one foundation model access request approved. The reproduction script invokes the cross-region inference profileus.anthropic.claude-haiku-4-5-20251001-v1:0for the bedrock-standard reference call in step 5; any model accessible via the standardbedrock-runtimeInvokeModelAPI works. - A long-term Bedrock API key generated through the Bedrock Console: navigate to Amazon Bedrock Console → API keys → Generate API key → Long-term (AWS docs). Generating a long-term key auto-provisions a phantom IAM user named
BedrockAPIKey-<4-char-id>with the AWS managed policyAmazonBedrockLimitedAccessattached, and returns a bearer token that begins with the literal stringABSK. Save the token, since AWS does not show it a second time. - AWS CLI authenticated to the same account, with
iam:PutUserPolicyandiam:DeleteUserPolicypermissions on the phantom user (only used in step 3's IAM Deny test). - A CloudTrail trail in the same region with management events enabled (default trail is sufficient) is helpful but not required for the bypass demonstration; it is required to inspect the data event JSON in step 4.
- For step 5 only: Bedrock model invocation logging configured to deliver to an S3 bucket in the same account (AWS docs, or
aws bedrock put-model-invocation-logging-configuration --logging-config 's3Config={bucketName=<bucket>}, textDataDeliveryEnabled=true'). Without this enabled, the bedrock standard reference prompt has nowhere to land, so the contrast against the missing mantle prompt cannot be observed.
Full reproduction in attached reproduce.sh. Run as bash reproduce.sh "$ABSK". The key one-liners and expected results below are the same commands the script issues.
1. Endpoint exists and accepts the API key
$ curl -sS -H "Authorization: Bearer $ABSK" https://bedrock-mantle.us-east-1.api.aws/v1/models | jq '.data | length'
39
DNS resolves in 7+ regions (us-east-1, us-east-2, us-west-2, eu-west-1, ap-northeast-1, ap-south-1, sa-east-1). Reverse-DNS and WHOIS confirm AWS ownership (Amazon Technologies Inc.).
2. Both key types authenticate; auth is enforced
$ curl -sS -o /dev/null -w "%{http_code}\n" https://bedrock-mantle.us-east-1.api.aws/v1/models
401 # no bearer
$ curl -sS -H "Authorization: Bearer ABSKBOGUS" -o /dev/null -w "%{http_code}\n" https://bedrock-mantle.us-east-1.api.aws/v1/models
401 # bogus bearer
$ curl -sS -H "Authorization: Bearer $ABSK" -o /dev/null -w "%{http_code}\n" https://bedrock-mantle.us-east-1.api.aws/v1/models
200 # long-term ABSK
$ curl -sS -H "Authorization: Bearer $SHORT" -o /dev/null -w "%{http_code}\n" https://bedrock-mantle.us-east-1.api.aws/v1/models
200 # short-term bedrock-api-key-*
Both token types return billable inference on POST /v1/chat/completions (e.g. mistral.voxtral-mini-3b-2507 returned usage.total_tokens: 13 for ABSK and 7 for the short-term token in the live run). 38 of 39 catalog models invoke successfully; the only listed-but-not-invocable entry is anthropic.claude-opus-4-7.
3. SCP/IAM Deny: bedrock:CallWithBearerToken does NOT block mantle
$ aws iam put-user-policy --user-name ████████ --policy-name VDPDenyBedrockBearer \
--policy-document '{"Version":"2012-10-17","Statement":[{"Effect":"Deny","Action":"bedrock:CallWithBearerToken","Resource":"*"}]}'
$ sleep 10
$ curl -sS -o /dev/null -w "bedrock std: %{http_code}\n" -H "Authorization: Bearer $ABSK" https://bedrock.us-east-1.amazonaws.com/foundation-models
bedrock std: 403 # explicit deny matches
$ curl -sS -o /dev/null -w "mantle: %{http_code}\n" -H "Authorization: Bearer $ABSK" https://bedrock-mantle.us-east-1.api.aws/v1/models
mantle: 200 # bypass
Replacing bedrock:CallWithBearerToken with bedrock-mantle:CallWithBearerToken in the same policy DOES return 403 on mantle (verified live), confirming the IAM enforcement works once the action is correctly named, and that the documented action prefix is the gap.
4. CloudTrail detection signal does NOT match mantle events
A mantle CloudTrail data event carries the bearer-token attestation at requestParameters.callWithBearerToken: true. The additionalEventData field is absent entirely. A SIEM rule filtering on additionalEventData.callWithBearerToken = true (the example AWS Security Blog publishes) matches zero mantle events. The exact JSON shape is observable on any trail with AWS::BedrockMantle::Project enabled in advanced event selectors, including AWS-internal trails for the test account.
5. put-model-invocation-logging-configuration does NOT capture mantle prompts (and there is no mantle equivalent)
Paired-marker test (live, 2026-04-27 22:41:35Z): one bedrock-runtime InvokeModel (claude-3-haiku) and one bedrock-mantle CreateInference (voxtral-mini), same marker vdp-paired-test-1777329695, fired ~1s apart against the same account whose model invocation logging targets ████████.
22:42:36Z AWSLogs/.../BedrockModelInvocationLogs/.../22/<file>.json.gz delivered
inputBodyJson.messages[0].content == "vdp-paired-test-1777329695 reply OK" # bedrock prompt
grep across every file delivered for the day for the same marker # mantle: 0 hits
Final count across the day's invocation logs: bedrock = 1, mantle = 0. The mantle prompt content is not retrievable from any AWS-managed prompt/response logging surface; there is no aws bedrock-mantle put-model-invocation-logging-configuration (the bedrock-mantle AWS CLI subcommand does not exist as of 2026-04-27, verified with aws bedrock-mantle help).
Verified live 2026-04-27 and 2026-04-28 against test account ████████ and successive phantom users (████████, then ████████ after a key rotation), confirming the bypass survives credential rotation. Attached evidence:
reproduce.sh: end-to-end reproduction script. Run asbash reproduce.sh "$ABSK" "" "$PHANTOM_USER_NAME". Produces the steps 1, 2, 2b, and 3 outputs referenced in this report, plus a one-liner that the operator runs ~10 minutes later to confirm the logging gap.- ████████: terminal capture of the full live reproduction. Top half shows
bash reproduce.sh "$ABSK" "" "$PHANTOM"against the test account: step 2 (bedrock std 403, mantle 200), step 2b (mantle 401with the explicit IAMaccess_deniedbody), and step 3 firing the paired marker againstus.anthropic.claude-haiku-4-5-20251001-v1:0(bedrock standard) andmistral.voxtral-mini-3b-2507(mantle). Bottom half shows the post-run grep across the day'sBedrockModelInvocationLogs/files in the configured S3 bucket, returning exactly one file containing the marker (the bedrock prompt) and zero files containing it from the mantle inference fired with the same marker within the same second.
Impact
Summary:
- SCP gap (high). Customers who deployed the AWS-recommended
Deny: bedrock:CallWithBearerTokenbelieve they have prevented bearer-token abuse. Mantle usesbedrock-mantle:CallWithBearerTokenand is unaffected. - Detection gap (high). SIEM/EventBridge/Athena rules filtering on
additionalEventData.callWithBearerToken = true(the AWS-published example) match zero mantle events. A leaked-key attacker pivoting to mantle is invisible to any detection built per AWS guidance. - Forensic gap (high). Even with
put-model-invocation-logging-configurationenabled, mantle prompts and responses are absent from the configured bucket. There is no AWS-managed prompt/response capture for mantle. - Cost exposure (medium). 38 of 39 catalog models bill, including premium offerings (
mistral.mistral-large-3-675b-instruct,qwen.qwen3-coder-480b-a35b-instruct,openai.gpt-oss-120b,moonshotai.kimi-k2-thinking,deepseek.v3.2, etc.). Streaming and tool/function-calling work, so a leaked key powers full agentic flows. A single leaked key bills against both planes simultaneously, doubling attainable throughput before per-model limits kick in.
The combined effect is that a customer following AWS public guidance end-to-end (recommended SCP, recommended CloudTrail detection, recommended invocation logging) receives zero coverage of the mantle plane while their leaked API key continues to authenticate against it and consume billable inference invisibly.
Root Cause
A second Bedrock-API-key-accepting service plane (bedrock-mantle) was added in a way that the existing customer-side defensive controls do not cover. The gaps are operational, not purely editorial:
- No customer-deployable mantle prompt/response logging exists.
aws bedrock put-model-invocation-logging-configurationonly configures logging forbedrock/bedrock-runtime. There is noaws bedrock-mantle put-model-invocation-logging-configuration(thebedrock-mantleAWS CLI subcommand does not exist), and the existing logging configuration does not extend to mantle inferences. Customers who experience a Bedrock API key compromise have no AWS-managed way to recover what prompts the attacker submitted via the mantle plane or what content the models returned. This cannot be remediated by the customer. - The CloudTrail bearer-token detection signal is on a different JSON path on mantle. Mantle data events carry
requestParameters.callWithBearerToken: true(andrequestParameters.bearerTokenType), whereasbedrock.amazonaws.comevents useadditionalEventData.callWithBearerToken. The example SIEM rule, EventBridge pattern, and CloudWatch Logs Insights query AWS publishes filter on the second path. Already-deployed detections in customer SIEMs do not match mantle until those rules are rewritten by the customer (which requires the customer to know mantle exists). - The IAM action prefix the AWS-recommended SCP denies is the wrong one for mantle. Mantle uses
bedrock-mantle:CallWithBearerToken, notbedrock:CallWithBearerToken. We confirmed this enforcement works correctly when the policy names the right prefix (step 3b in the reproduction), so the IAM enforcement layer itself is intact; the issue is that the AWS-published SCP example points customers at the wrong action.
Contributing to all three: bedrock-mantle is included in the AWS managed policy AmazonBedrockLimitedAccess v8 and in the aws:CalledViaLast condition values for marketplace operations, but is not described in the Bedrock CloudTrail user guide, the AWS Security Blog post on securing Bedrock API keys, the Bedrock API keys user guide (which states API keys are limited to "Amazon Bedrock and Amazon Bedrock Runtime actions"), or the Bedrock model invocation logging documentation. Customers cannot deploy effective controls against a service plane the documentation does not describe.
The result is a plane that is operationally callable, in scope for AmazonBedrockLimitedAccess, generates billable inference on premium third-party models, and is functionally invisible to every Bedrock-API-key-specific defense customers can deploy today.
Recommended Fix
Ordered by control-failure impact, highest first.
-
Logging configuration parity (operational gap, customer cannot remediate). Extend
aws bedrock put-model-invocation-logging-configuration(or introduce an equivalent API) so that a single customer-facing logging configuration captures prompts and responses for bothbedrock/bedrock-runtimeandbedrock-mantleinference. Until this exists, customers responding to a Bedrock API key compromise have no AWS-managed forensic capture for any inference that ran via mantle. -
CloudTrail signal parity. Either emit
additionalEventData.callWithBearerToken = trueon mantle data events (matching the existing detection signal customers built rules on), or publish updated EventBridge / CloudWatch Logs Insights / SIEM templates that OR both JSON paths (additionalEventData.callWithBearerTokenandrequestParameters.callWithBearerToken) and include bothaws.bedrockandaws.bedrock-mantleevent sources. Customer-side rules already deployed against the published example will silently miss mantle until updated. -
SCP / IAM example update. Update the
aws-samplesBedrock SCP examples and the AWS Security Blog SCP examples to deny bothbedrock:CallWithBearerTokenandbedrock-mantle:CallWithBearerToken(and any future bearer-token actions on additional Bedrock service planes). Customers who already deployed the original SCP remain unprotected on mantle until they update; an AWS-side advisory pushing customers to refresh would shorten that window. -
Documentation parity. Update the Bedrock CloudTrail user guide, the AWS Security Blog post on securing Bedrock API keys, the Bedrock API keys user guide (which currently states API keys are limited to "Amazon Bedrock and Amazon Bedrock Runtime actions"), and the Bedrock model invocation logging documentation to describe the
bedrock-mantle.{region}.api.awsendpoint, its IAM action prefixbedrock-mantle:*, and the items in fixes 1-3. Without this, customer security teams cannot know the mantle surface exists or that they need to deploy the corresponding controls.
Disclosure
Coordinated disclosure. This research is part of an ongoing two-part security guide on AWS Bedrock API keys, scheduled for publication on the BeyondTrust Phantom Labs research blog and presentation at Black Hat Arsenal USA 2026. An accompanying open-source detection and incident-response toolkit, BeyondTrust/bedrock-keys-security (bks CLI), is already public; its current main branch deliberately walks back the bedrock-mantle attack-surface claim until AWS has had a chance to remediate, so customers using the tool today are not being primed to exploit the gaps reported here. We are happy to delay further publication until AWS has had time to remediate or respond, and to coordinate on framing. We can share a draft of the planned blog content ahead of publication.