tl;dr: AWS Bedrock API keys behave nothing like regular AWS credentials. BKS includes an offline decoder, phantom user discovery, incident response, automated cleanup, preventive SCPs and SIEM-ready detection content.
Contents: Quickstart · Motivation · Installation · Usage · Prevention · Detection · Migration to STS · Talks · Contributing
pip install bedrock-keys-security
bks scan --profile your-aws-profilebks scan discovers every BedrockAPIKey-* phantom user in the account, categorizes risk (AT RISK / ACTIVE / ORPHANED) and prints a summary table.
# Decode a leaked key offline (no AWS credentials needed)
bks decode-key "ABSKQmVkcm9ja..."
# Investigate a phantom user across every region with CloudTrail coverage
bks timeline BedrockAPIKey-xxxx --all-regions --days 30
# Emergency revocation: deny Bedrock + delete API keys + disable AKIA pivots
bks revoke-key BedrockAPIKey-xxxxDetection content (Sigma, CloudTrail Lake, Athena, EventBridge, CloudWatch Insights) lives in detections/. SCP policies and their Terraform / CloudFormation modules live in scps/.
AWS Bedrock API keys behave unlike regular AWS credentials. They authenticate via bearer tokens instead of SigV4, and they embed the AWS account ID and IAM username in plain base64.
The most damaging behavior: when a user creates a long-term Bedrock API key through the AWS Console, AWS silently provisions an IAM user named BedrockAPIKey-xxxx and attaches the AmazonBedrockLimitedAccess managed policy.
Despite its name, the policy is effectively administrative: 48 actions across bedrock:* (44) and bedrock-mantle:* (4) covering create / read / update / delete across all Bedrock resources, plus cross-service reconnaissance (iam:ListRoles, kms:DescribeKey, ec2:Describe{Vpcs,Subnets,SecurityGroups}). Full action list in the AWS doc linked above.
These phantom users are never automatically cleaned up. They accumulate over time, creating an expanding attack surface that most organizations don't know exists.
LLMjacking: An attacker who obtains a leaked key can spin up workers across all AWS regions to consume foundation model capacity. Worst-case exposure depends on the default Bedrock service quota and the model price; for Claude Opus 4.7 at list pricing (May 2026), this works out to roughly $18,000/day per region.
Privilege Escalation: If an attacker creates an IAM access key on the phantom user, or if one already exists, they gain persistent IAM credentials (AKIA...) that extend well beyond Bedrock. From there, they can pivot to S3, Secrets Manager and other services, even after the original Bedrock key expires.
Deep-dive: AWS Bedrock API Keys Security Guide, Part 1: Risks, Vulnerabilities and Attack Techniques on the BeyondTrust Phantom Labs blog.
Install from PyPI:
pip install bedrock-keys-securityOr install from source:
git clone https://github.com/BeyondTrust/bedrock-keys-security.git
cd bedrock-keys-security
pip install .Verify the installation:
bks --versionRequired AWS permissions per command: see docs/permissions.md.
Run a scan to discover all phantom IAM users in your account:
bks scan # scan with default profile
bks scan --profile prod # use a specific AWS profile
bks scan --region eu-west-1 # override the default us-east-1 region
bks scan --json # save JSON to output/
bks scan --csv # save CSV to output/
bks scan --verbose # detailed output
bks --quiet scan --json # SOAR pipelines: only the saved-file path goes to stdoutExample output:
bks v1.1.0 BedrockAPIKey-* phantom user scanner
Account: 123456789012 Region: us-east-1
+--------------------+------------+-------------------+---------------+----------+
| Username | Created | Active API Keys | Access Keys | Status |
+====================+============+===================+===============+==========+
| BedrockAPIKey-h42z | 2026-03-12 | 1 | 2 | AT RISK |
| BedrockAPIKey-x8q1 | 2026-04-22 | 1 | 0 | ACTIVE |
| BedrockAPIKey-aaa1 | 2025-11-08 | 0 | 0 | ORPHANED |
+--------------------+------------+-------------------+---------------+----------+
Summary:
Total phantom users: 3
At Risk: 1 (IAM access keys found)
Active: 1 (live Bedrock API keys)
Orphaned: 1 (safe to cleanup)
⚠ AT RISK · 1 phantom user with persistent IAM credentials
- BedrockAPIKey-h42z (2 access keys)
These keys inherit Bedrock admin + IAM/VPC/KMS reconnaissance from
AmazonBedrockLimitedAccess, and persist after Bedrock key revocation.
→ bks revoke-key <username> emergency containment
→ bks report <username> forensic report
▸ ORPHANED · 1 phantom user with no active credentials
These accumulate over time as privilege-escalation pivots. Cleanup
shrinks the attack surface; no live workflow is affected.
→ bks cleanup --dry-run preview deletions
→ bks cleanup delete with confirmation
Scan complete 127 IAM users · 3 phantoms · 1.4s
JSON / CSV reports are written to output/bks-scan-<account>-<UTC-timestamp>.<ext> (the directory is created automatically). Override the destination with the global --output-dir DIR flag (e.g. bks --output-dir /var/log/bks scan --json). The JSON shape:
{
"scan_metadata": {
"account_id": "123456789012",
"region": "us-east-1",
"scan_time": "2026-05-06T14:30:22+00:00",
"caller_arn": "arn:aws:iam::123456789012:user/security"
},
"summary": { "total": 3, "active": 1, "orphaned": 1, "at_risk": 1 },
"phantom_users": [
{ "username": "BedrockAPIKey-h42z", "status": "AT RISK", "created": "2026-03-12T09:14:08+00:00", "...": "..." }
]
}Each phantom user is categorized by risk level:
- AT RISK: Has IAM access keys with
bedrock:*and recon permissions. Revoking the Bedrock key does not disable them. - ACTIVE: Has valid Bedrock API credentials
- ORPHANED: No active credentials remaining (safe to delete)
Remove orphaned phantom users that no longer have active credentials:
bks cleanup --dry-run # preview what would be deleted
bks cleanup # delete with confirmation prompt
bks cleanup --force # skip confirmation (use with caution)
bks cleanup --json # save cleanup result as JSON to output/Only ORPHANED users are affected. ACTIVE and AT RISK users are never deleted automatically.
When a key is compromised, bks provides emergency response capabilities:
bks revoke-key BedrockAPIKey-xxxx # emergency key revocation
bks revoke-key BedrockAPIKey-xxxx --force # skip confirmation
bks revoke-key BedrockAPIKey-xxxx --json # save revocation result to output/
bks timeline BedrockAPIKey-xxxx # CloudTrail timeline (last 7 days, configured region)
bks timeline BedrockAPIKey-xxxx --days 30 # extended timeline
bks timeline BedrockAPIKey-xxxx --all-regions # fan out across every region with CloudTrail coverage
bks timeline BedrockAPIKey-xxxx --json # save events list as JSON to output/
bks report BedrockAPIKey-xxxx # full incident report
bks report BedrockAPIKey-xxxx --output report.txt # save text report to FILE
bks report BedrockAPIKey-xxxx --json # save report data as JSON to output/revoke-key applies an inline Deny: bedrock:* policy, deletes all Bedrock service-specific credentials and disables IAM access keys (AKIA*) on the phantom user, closing the privilege-escalation pivot in the same operation.
timeline --all-regions is recommended whenever LLMjacking is suspected. Bedrock data-plane events (InvokeModel, Converse, CallWithBearerToken) are recorded in the region they ran, not the home region; a single-region timeline misses cross-region fan-out by design.
Decode leaked Bedrock API keys offline, no AWS credentials required:
bks decode-key "ABSKQmVkcm9ja0FQSUtleS..." # print analysis to terminal
bks decode-key "bedrock-api-key-YmVkcm9ja..." --json # save JSON to output/Extracts the embedded IAM username, AWS account ID, region and key format. Useful for triaging keys found on GitHub, Pastebin or other public sources. With --json, writes output/bks-decode-<account>-<UTC-timestamp>.json.
Four SCPs are provided for organizational enforcement. Apply via AWS Organizations.
| SCP | File | Purpose |
|---|---|---|
| Block all keys (recommended) | scps/1-block-all-keys.json |
Deny creation + usage org-wide |
| Enforce 90-day max | scps/2-enforce-90day-max.json |
Limit damage window |
| Block long-term only | scps/3-block-long-term-only.json |
Allow short-term, block ABSK |
| Block phantom escalation | scps/4-block-phantom-access-keys.json |
Close privesc pivot |
Deploy any SCP via:
aws organizations create-policy \
--name <NAME> \
--type SERVICE_CONTROL_POLICY \
--content file://scps/<FILE>
aws organizations attach-policy \
--policy-id p-xxxxx \
--target-id <ROOT_OR_OU_ID>Note: Always test SCPs on non-production OUs before applying broadly.
The same four SCPs are available as ready-to-deploy modules:
- Terraform:
scps/terraform/wraps the four SCPs asaws_organizations_policyresources with optional OU attachment. - CloudFormation:
scps/cloudformation/scps.yamlis a single template with conditional resources, StackSet-friendly.
Both default to enabling Block-Bedrock-API-Keys plus Block-Phantom-User-Escalation, the recommended baseline pair.
SIEM-ready detection rules for the full attack chain are in detections/: 6 Sigma rules, 2 CloudTrail Lake queries, 2 Athena queries, 5 EventBridge patterns and 1 CloudWatch Insights query. Coverage spans bearer-token usage, key creation, phantom-user creation, AKIA escalation, cross-region fan-out and suspicious user-agents.
Most teams do not need Bedrock API keys. AWS STS temporary credentials are the recommended approach:
- Automatically expire (1 to 12 hours)
- No phantom users created
- Standard AWS SigV4 signing (not bearer tokens)
- No persistent credentials to leak
aws sts assume-role \
--role-arn arn:aws:iam::ACCOUNT:role/BedrockRole \
--role-session-name bedrock-session \
--duration-seconds 3600
export AWS_ACCESS_KEY_ID=ASIA...
export AWS_SECRET_ACCESS_KEY=...
export AWS_SESSION_TOKEN=...
aws bedrock-runtime converse \
--model-id us.anthropic.claude-opus-4-7 \
--messages '[{"role":"user","content":[{"text":"hello"}]}]'API keys may still be necessary for legacy applications hardcoded for bearer tokens, third-party tools without SigV4 support or vendor software lacking STS integration. In those cases, use short-term keys with a maximum 12-hour lifetime and enforce restrictions with the SCPs above.
- Black Hat USA 2026 Arsenal (upcoming, August 2026): Bedrock Keys Security (BKS): Hunting Phantom IAM Users Created by AWS Bedrock API Keys (session)
- BSides Seattle 2026: The Phantom of the Infrastructure: Investigating the Hidden IAM Risks in Bedrock API Keys (slides, video)
- RootedCON Madrid 2026: The Phantom of the Infrastructure: The Invisible Threat in Bedrock API Keys
See CONTRIBUTING.md for development setup, PR workflow and review requirements.
Apache 2.0. See LICENSE.
- Issues and bugs: GitHub Issues
- Twitter: @btphantomlabs
- AWS Bedrock API Keys Security Guide, Part 1: Risks, Vulnerabilities and Attack Techniques (BeyondTrust Phantom Labs)
- AWS Bedrock API Keys User Guide
- AWS Security Blog: Securing Bedrock API Keys
- AWS SCP Examples for Bedrock
- AWS Customer Playbook Framework: Bedrock EventBridge CFN
- CloudTrail Logging for Bedrock





