Security toolkit for AWS Bedrock API keys — discover phantom IAM users, decode leaked keys, automate cleanup, and enforce preventive controls.
Project description
Bedrock API Keys Security
Security toolkit for AWS Bedrock API keys. Discover phantom IAM users, decode leaked keys, automate cleanup, and enforce preventive controls.
Motivation
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, this policy grants broad permissions:
bedrock:*on all resources (full Bedrock admin)iam:ListRoles(identity enumeration)kms:DescribeKey(encryption key discovery)ec2:Describe*(network reconnaissance)
These phantom users are never automatically cleaned up. They accumulate over time, creating an expanding attack surface that most organizations don't know exists.
Attack Paths
LLMjacking: An attacker who obtains a leaked key can spin up workers across all AWS regions to consume foundation model capacity. Organizations have reported fraudulent charges exceeding $14,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.
Overview
AWS Bedrock API keys (launched July 2025) introduce multiple security risks that organizations must understand before deployment. While designed to simplify authentication, they create permanent attack surfaces through phantom IAM user creation, overprivileged default policies, and bearer token authentication.
Long-term keys automatically provision IAM users (BedrockAPIKey-xxxx) with admin-level Bedrock permissions that persist indefinitely, even after the key is deleted or expires. Within 14 days of launch, keys were already leaking to GitHub. Criminal organizations generate an estimated $1M/year in annualized revenue from stolen keys, with fraudulent charges reaching up to $14,000/day per region.
This toolkit provides:
- Discovery: Scan your account for phantom IAM users and categorize their risk
- Incident Response: Emergency key revocation, CloudTrail timelines, and forensic reports
- Key Decoding: Offline analysis of leaked keys to extract account and identity information
- Prevention: Service Control Policies to block or restrict API key usage at the org level
Installation
Install from PyPI:
pip install bedrock-keys-security
Or install from source:
git clone https://github.com/BeyondTrust/bedrock-keys-security.git
cd bedrock-keys-security
pip install .
Verify the installation:
bks --version
After installation, the bks command is available globally. Requires Python 3.10+ and AWS credentials. Minimum permissions by command:
| Command | IAM Permissions Required |
|---|---|
scan |
iam:ListUsers, iam:ListServiceSpecificCredentials, iam:ListAccessKeys, iam:ListAttachedUserPolicies, iam:ListUserPolicies |
cleanup |
All scan permissions + iam:DeleteAccessKey, iam:DeleteServiceSpecificCredential, iam:DetachUserPolicy, iam:DeleteUserPolicy, iam:DeleteUser |
revoke-key |
iam:PutUserPolicy, iam:ListServiceSpecificCredentials, iam:DeleteServiceSpecificCredential |
timeline |
cloudtrail:LookupEvents |
report |
iam:GetUser, iam:ListServiceSpecificCredentials, iam:ListAccessKeys, iam:ListAttachedUserPolicies, iam:ListUserPolicies |
decode-key |
None (offline) |
Usage
Scanning
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 --json # machine-readable output
bks scan --csv output.csv # export to CSV
bks scan --verbose # detailed output
Each phantom user is categorized by risk level:
- ACTIVE: Has valid Bedrock API credentials
- ORPHANED: No active credentials remaining (safe to delete)
- AT RISK: Has IAM access keys that grant
bedrock:*, recon permissions, and persist independently of the API key
Cleanup
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)
Only ORPHANED users are affected. ACTIVE and AT RISK users are never deleted automatically.
Incident Response
When a key is compromised, bks provides emergency response capabilities:
bks revoke-key BedrockAPIKey-xxxx # emergency key revocation
bks timeline BedrockAPIKey-xxxx # CloudTrail timeline (last 7 days)
bks timeline BedrockAPIKey-xxxx --days 30 # extended timeline
bks report BedrockAPIKey-xxxx # full incident report
bks report BedrockAPIKey-xxxx --output report.txt
The revoke-key command applies an inline deny policy and deletes all Bedrock credentials in a single operation.
Key Decoding
Decode leaked Bedrock API keys offline, no AWS credentials required:
bks decode-key "ABSKQmVkcm9ja0FQSUtleS..."
bks decode-key "bedrock-api-key-YmVkcm9ja..." --json
Extracts the embedded IAM username, AWS account ID, region, and key format. Useful for triaging keys found on GitHub, Pastebin, or other public sources.
Prevention with Service Control Policies
Four SCPs are provided for organizational enforcement. Apply them to OUs via AWS Organizations.
1. Block All API Keys (Recommended)
The simplest approach: block creation and usage of all Bedrock API keys:
aws organizations create-policy \
--name Block-Bedrock-API-Keys \
--type SERVICE_CONTROL_POLICY \
--content file://scps/1-block-all-keys.json
2. Enforce 90-Day Maximum Lifetime
If API keys are required, limit the damage window:
aws organizations create-policy \
--content file://scps/2-enforce-90day-max.json \
--type SERVICE_CONTROL_POLICY
3. Block Long-Term Keys Only
Allow short-term keys while blocking the more dangerous long-term (ABSK) keys:
aws organizations create-policy \
--content file://scps/3-block-long-term-only.json \
--type SERVICE_CONTROL_POLICY
4. Block Phantom Escalation
Prevent IAM access key creation on phantom users. This blocks the privilege escalation path:
aws organizations create-policy \
--content file://scps/4-block-phantom-access-keys.json \
--type SERVICE_CONTROL_POLICY
Note: Always test SCPs on non-production OUs before applying broadly.
Recommended Alternative: STS Temporary Credentials
Most teams do not need Bedrock API keys. AWS STS temporary credentials are the recommended approach:
- Automatically expire (1–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 invoke-model --model-id anthropic.claude-3-sonnet...
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.
Research Findings
- Phantom IAM users are never automatically cleaned up by AWS
AmazonBedrockLimitedAccessgrantsbedrock:*plus reconnaissance permissions- Keys leaked to GitHub within approximately 2 weeks of creation (median)
- Criminal groups generate $1M+/year through LLMjacking operations with leaked keys
Contributing
Contributions are welcome. Useful additions include IaC templates (Terraform/CloudFormation), additional attack scenarios, and GovCloud support.
Standard GitHub workflow: fork, branch, commit, pull request.
License
Apache 2.0. See LICENSE.
Contact
- Issues and bugs: GitHub Issues
- Questions: GitHub Discussions
- Twitter: @btphantomlabs
References
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file bedrock_keys_security-1.0.0.tar.gz.
File metadata
- Download URL: bedrock_keys_security-1.0.0.tar.gz
- Upload date:
- Size: 24.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ac627a5cdaa1d5a6374bff354124daa492fe4fe0444f0e9d85d72a80c63551ec
|
|
| MD5 |
efe68e8be831fa54e7e1bcfca3164bba
|
|
| BLAKE2b-256 |
a4353584909e4fd484e37aac5a42008ec4eda635cf0d94c644bc95b81ba1f441
|
Provenance
The following attestation bundles were made for bedrock_keys_security-1.0.0.tar.gz:
Publisher:
publish.yaml on BeyondTrust/bedrock-keys-security
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
bedrock_keys_security-1.0.0.tar.gz -
Subject digest:
ac627a5cdaa1d5a6374bff354124daa492fe4fe0444f0e9d85d72a80c63551ec - Sigstore transparency entry: 999670774
- Sigstore integration time:
-
Permalink:
BeyondTrust/bedrock-keys-security@11719933a8a749625281914f00bd67f0058be67d -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/BeyondTrust
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yaml@11719933a8a749625281914f00bd67f0058be67d -
Trigger Event:
push
-
Statement type:
File details
Details for the file bedrock_keys_security-1.0.0-py3-none-any.whl.
File metadata
- Download URL: bedrock_keys_security-1.0.0-py3-none-any.whl
- Upload date:
- Size: 25.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
62d977a7d205161370b87bd86364504a13d536e34d687a5b3bf86e13e2368018
|
|
| MD5 |
10fc97316922f01f28e2bd827a23f0b5
|
|
| BLAKE2b-256 |
85a88e98947ef332551b1ce7c1a870e3925846ccbd2a4a882e101e3f9a074283
|
Provenance
The following attestation bundles were made for bedrock_keys_security-1.0.0-py3-none-any.whl:
Publisher:
publish.yaml on BeyondTrust/bedrock-keys-security
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
bedrock_keys_security-1.0.0-py3-none-any.whl -
Subject digest:
62d977a7d205161370b87bd86364504a13d536e34d687a5b3bf86e13e2368018 - Sigstore transparency entry: 999670883
- Sigstore integration time:
-
Permalink:
BeyondTrust/bedrock-keys-security@11719933a8a749625281914f00bd67f0058be67d -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/BeyondTrust
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yaml@11719933a8a749625281914f00bd67f0058be67d -
Trigger Event:
push
-
Statement type: