LLMjacking is the theft of AI model access: attackers use stolen cloud credentials to run large language models and leave the victim to pay the bill. The Sysdig Threat Research Team named it in May 2024, after watching attackers use stolen AWS keys to probe Amazon Bedrock. Their stated goal was to sell LLM access to other cybercriminals while the cloud account owner pays.

Bedrock is an attractive target because model access is billed per token, needs no infrastructure, and turns any key with the right permission into cash. Unlike ransomware, nothing breaks and no data is touched, so the first sign is often the invoice.

This post covers the documented cases, how the attack works step by step, the controls that stop it, and how to test those controls in your own account.

How common is LLMjacking?

LLMjacking has moved from a single observation to a repeated pattern in under two years. The documented cases, newest first:

Date Source What was observed
Sep 2026 FortiGuard Labs, via Hackread A leaked, never-expiring IAM key with AdministratorAccess was used to create a new IAM user, subscribe it to foundation models through AWS Marketplace, and invoke them. FortiGuard says stolen access is resold as cheap AI chatbot subscriptions on Telegram and Discord
Nov 2025 Sysdig An attacker reached admin in about 8 minutes, then checked whether Bedrock logging was on before invoking multiple models and uploaded a Terraform script for a public Lambda backdoor to generate Bedrock credentials
Mar 2025 Entro Labs Real AWS keys deliberately leaked on GitHub, Pastebin and Reddit were probed within 17 minutes on average and 9 minutes at the fastest; attackers then listed available Bedrock models before attempting to invoke them
Sep 2024 Sysdig More than 85,000 Bedrock API requests from attackers, 61,000 of them in a three-hour window on July 11, 2024; attackers were now enabling models with stolen credentials, not just using ones already enabled
May 2024 Sysdig First report: AWS keys stolen through a vulnerable Laravel app (CVE-2021-3129) were used to probe Bedrock, with a tool that checked keys for ten AI services

What it costs. Sysdig’s worst-case estimate for a Claude 2.x model running at quota in four Regions was $46,080 per day. For newer models, it rose to over $100,000 per day, and one victim owed $30,000 after only three hours. Sysdig also noted that attackers maxing out quotas can block the victim from using models for its own business.

The pattern is not unique to AWS. Microsoft dismantled a group that used stolen API keys to abuse Azure OpenAI, which is a reminder that every cloud AI service with key-based billing is a target.

How does an LLMjacking attack work?

Across the published cases, LLMjacking follows the same five steps. Each one leaves a trace in CloudTrail, which matters for detection later.

  1. Steal a key. As in most AWS breaches, it starts with a credential. Sources so far include a vulnerable Laravel app, keys leaked on GitHub, Pastebin and Reddit, and credentials in a public S3 bucket.
  2. Check what the key can do. In Entro’s experiment, attackers called GetCostAndUsage within 9 to 17 minutes to assess the account’s value, then listed available models. Sysdig saw a sneakier probe: an InvokeModel call with max_tokens_to_sample set to -1. A ValidationException reply tells the attacker the key has model access without running a real prompt; an AccessDenied tells them it does not.
  3. Check for logging. Attackers call GetModelInvocationLoggingConfiguration to see whether prompts are recorded. The OAI Reverse Proxy tool used to resell access states it will not use any AWS key that has logging enabled.
  4. Get model access. Early attacks only used models the victim had already enabled; by September 2024 attackers were enabling models themselves. With an admin key, FortiGuard saw the attacker create a new IAM user and subscribe it to models through AWS Marketplace.
  5. Run and resell. Prompts flow through a reverse proxy that lets an attacker manage many stolen accounts without exposing the underlying credentials. The victim pays per token.
LLMjacking in five steps with controls: no static keys prevent step 1, CloudTrail and GuardDuty detect steps 2 and 3, an SCP blocks steps 4 and 5.

Removing static keys stops step 1, CloudTrail and GuardDuty can catch steps 2 and 3, and the SCP below blocks the steps that cost you money.

The hard part for defenders is step 5. FortiGuard’s point is blunt: a Bedrock InvokeModel call from a compromised but valid identity is, at the API level, indistinguishable from legitimate use. That is why prevention has to happen at the identity and policy layer, before the first call.

How to stop LLMjacking with an SCP

First, know that the old speed bump is gone. In 2024, Sysdig described Bedrock’s model-enablement request as a speed bump for attackers rather than a security mechanism. AWS has since removed it entirely: Bedrock now provides automatic access to the serverless models in your Region, and the Model Access page and PutFoundationModelEntitlement permission were retired. AWS’s guidance is that if you relied on the Model Access page to govern access, you should switch to SCP and IAM policies. Models already blocked by IAM or SCPs stay blocked.

The SCP. The policy below combines four patterns from AWS’s documentation into one guardrail. Replace the role names and model list with your own:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "OnlyApprovedRolesInvokeModels",
      "Effect": "Deny",
      "Action": ["bedrock:InvokeModel", "bedrock:InvokeModelWithResponseStream"],
      "Resource": "*",
      "Condition": {
        "ArnNotLike": {"aws:PrincipalArn": "arn:aws:iam::*:role/ai-app-*"}
      }
    },
    {
      "Sid": "OnlyApprovedModels",
      "Effect": "Deny",
      "Action": "bedrock:*",
      "NotResource": [
        "arn:aws:bedrock:*::foundation-model/amazon.nova-*",
        "arn:aws:bedrock:*::inference-profile/us.amazon.nova-*"
      ]
    },
    {
      "Sid": "OnlyPlatformTeamSubscribes",
      "Effect": "Deny",
      "Action": "aws-marketplace:Subscribe",
      "Resource": "*",
      "Condition": {
        "ArnNotLike": {"aws:PrincipalArn": "arn:aws:iam::*:role/ai-platform-admin"}
      }
    },
    {
      "Sid": "NoBedrockApiKeys",
      "Effect": "Deny",
      "Action": [
        "iam:CreateServiceSpecificCredential",
        "bedrock:CallWithBearerToken",
        "bedrock-mantle:CallWithBearerToken"
      ],
      "Resource": "*"
    },
    {
      "Sid": "ProtectInvocationLogging",
      "Effect": "Deny",
      "Action": [
        "bedrock:DeleteModelInvocationLoggingConfiguration",
        "bedrock:PutModelInvocationLoggingConfiguration"
      ],
      "Resource": "*",
      "Condition": {
        "ArnNotLike": {"aws:PrincipalArn": "arn:aws:iam::*:role/security-admin"}
      }
    }
  ]
}

Why each statement is there.

Beyond the SCP. The policy limits damage, but the root cause in every case above was a long-lived credential. Use roles and short-lived credentials for AI workloads, give application roles only bedrock:InvokeModel on the models they call rather than bedrock:*, and never attach AdministratorAccess to an access key. Test the SCP on a sandbox OU before attaching it widely.

How to detect LLMjacking

Prevention can fail, so watch for the reconnaissance steps, which look different from normal application traffic.

Signal Why it matters Where it comes from
InvokeModel failing with ValidationException The probe Sysdig documented; Sysdig published a Falco rule for exactly this event CloudTrail
GetModelInvocationLoggingConfiguration from an unusual identity Attackers check logging before using a key CloudTrail
DeleteModelInvocationLoggingConfiguration A deliberate attempt to hide unauthorized model usage, per Splunk’s detection CloudTrail
GetCostAndUsage or model listing from a new IP or user agent Entro saw this as an early value check CloudTrail
New IAM user followed by Marketplace subscription The FortiGuard attack sequence CloudTrail
Impact:IAMUser/CostHarvesting and Impact:IAMUser/AnomalousModelInvocation GuardDuty AI Protection baselines token volume per identity and flags invocations that exceed it GuardDuty
Sudden Bedrock spend The last line of defense; GuardDuty’s documentation points to AWS Cost Anomaly Detection Billing

Turn on model invocation logging. CloudTrail records that a model was called, but not the prompts and responses. Bedrock invocation logging to S3 or CloudWatch captures those along with token counts. It also acts as a deterrent, since the main resale tool refuses keys that have it enabled.

Respond fast. If you see these signals, deactivate the access key, check for new IAM users, roles and access keys created by that identity, and review Marketplace subscriptions. The FortiGuard case shows why the second step matters: the attacker’s first move was to create a new identity that survives revoking the original key.

How to test it yourself

The probe in step 2 is cheap to reproduce, which makes it a good test of both your detection and your SCP. cloud-firedrill ships a custom:llmjacking-probe technique that sends the same kind of deliberately invalid InvokeModel request LLMjacking tools use. Bedrock rejects it before running the model, so it costs no tokens.

It is used in two scenario files:

Scenario file Account Passes when
guardduty-gaps.yaml Detection sandbox CloudTrail logged the InvokeModel call and a Security Hub finding “Bedrock model access probe” appeared
prevention.yaml Account under your SCPs The call was denied with AccessDeniedException
firedrill run guardduty-gaps --expected-account 111111111111 --confirm
firedrill run prevention --expected-account 222222222222 --confirm

The detection side needs a rule that turns the ValidationException into an alert. GuardDuty AI Protection works on token volume, so a single probe that runs no tokens is unlikely to cross its baseline. cloud-firedrill’s sandbox Terraform includes a small EventBridge and Lambda detector for this probe and for deleted invocation logging, so you can see whether your own setup would have noticed.

Conclusion

LLMjacking turns any AWS key with Bedrock access into a revenue stream for someone else. The published cases show attackers finding leaked keys in minutes, checking whether you log prompts, and reselling access while you pay per token.

Now that Bedrock enables models by default, your own policies are the only gate. Remove long-lived keys, restrict invocation to approved roles and models with an SCP, keep invocation logging on and locked, and turn on GuardDuty AI Protection and cost anomaly alerts. Each of these is cheap compared with a $46,000 day.

Sources

Threat research

AWS documentation and guidance

News coverage and detections