A Stolen API Key, 48 Hours, $82,000: The AI Billing Signature That Standard FinOps Tools Miss

Your Bedrock or Gemini bill is zero one day and $80,000 two days later. No anomaly alert fired. The account had never touched an AI service before. What you're looking at is credential theft β€” and your existing tools are blind to it.

On February 11–12, 2026, a Google Maps API key was used to rack up $82,314.44 in Gemini charges over 48 hours. The key had never had AI service access. It didn't need it. Google had quietly extended unrestricted Maps keys to cover Gemini scope, and neither the key owner nor their FinOps tools knew. Truffle Security's February 2026 research found 2,863 live, valid API keys exposed in Common Crawl web archives β€” every one of them a potential incident of the same shape.

The billing signature of a stolen AI API key is distinctive, but only if you know what to look for: AI service spend appearing on an account with zero prior AI billing history for that service, concentrated in a 24–48 hour window, with no workload attribution tags on any of the rows. No standard FinOps alert covers all three conditions simultaneously. AWS Cost Anomaly Detection requires a baseline β€” an account that has never had AI spend has no baseline. Tag absence alone is a governance finding, not a security signal. The 48-hour burst-and-stop pattern looks like a misconfigured test run, not credential theft.

The three-condition join is the detection. Each condition alone is noise. Together, they form a signal class that has no false positive path from legitimate workloads: legitimate teams starting Bedrock today tag their workloads from application context. An attacker calling a stolen API key with curl or a Python script carries none of those headers.

Google closes the Maps→Gemini unrestricted key vector on June 19, 2026. The structural risk on AWS Bedrock API keys — bearer token authentication, launched July 2025 — remains open and is architecturally identical.

The Mechanism: Why Stolen Keys Produce This Specific Billing Shape

API key theft for AI service abuse has three phases, each leaving a distinct billing trace.

Phase 1 β€” Discovery (hours to days before the first charge). Attackers scrape public repositories, Common Crawl archives, and exposed CI/CD artifacts for API key patterns. The Prowler, Entro, and Sonrai research published December 2025–January 2026 documented attackers validating stolen AWS Bedrock API keys with a single curl command before beginning abuse. A key that validates is immediately monetized β€” either by the attacker directly or sold on access broker markets.

Phase 2 β€” Exploitation (24–48 hours). The attack window is deliberately compressed. Attackers are aware that key rotation is the remediation. They maximize throughput: high-volume token calls to the most expensive available models, running continuously until the key is rotated or the account's spending limit (if any) is hit. This produces the burst-then-stop billing profile β€” the opposite of runaway inference (QB15), which drifts upward over days from an existing baseline. An attack produces a vertical spike from zero. The Google AI Developers Forum thread from April 2026 documented a case where spend dropped 99.85% the moment the Gemini API was disabled on the affected project.

Phase 3 β€” Propagation delay (up to 23 minutes after key rotation). Aikido Security reported β€” and The Register confirmed on May 21, 2026 β€” that Google API keys remain functional for up to 23 minutes after deletion due to infrastructure propagation delay. Google closed the issue as "Won't Fix (Infeasible)." This means rotating a compromised key does not immediately stop the bleeding. Billing rows can continue to arrive for nearly half an hour post-rotation. This detail is relevant to incident response: disabling the API entirely (not just rotating the key) is the faster remediation path.

The tag asymmetry. Legitimate AI API calls originate from deployed applications with workload attribution context β€” Environment, Team, Application, and WorkloadId tags propagated from IAM role context or application-level tagging middleware. An attacker calling a stolen API key directly carries none of these. The billing rows arrive in FOCUS data with tags = NULL. This is inferred from the attack vector rather than directly observed in billing records from public incidents β€” but the inference is structurally sound: no application context, no tags.

Real Incidents

These incidents are sourced from public post-mortems, practitioner reports, and security research. None are fabricated.

$82,314.44 in 48 hours via Google Maps API key (The Register, March 2026 / Truffle Security, February 2026): A Google Maps API key gained unrestricted access to Gemini 3 Pro Image and Text generation models without the key owner's knowledge. Attackers exploiting the key on February 11–12, 2026 ran up $82,314.44 in Gemini charges. The account's existing Gemini baseline was approximately $180/month β€” the attack spend represented roughly 38 months of normal usage in two days. Truffle Security's concurrent research in the same period found 2,863 live, valid API keys exposed in Common Crawl web archives that could be exploited identically.

β‚Ή7,83,722 (~$9,500) in 24 hours via Firebase key (Google AI Developers Forum, April 2026): A Firebase API key with Gemini access was exposed and abused on April 28, 2026. The attack consumed 79 distinct Gemini SKUs β€” text, image, video, and audio generation β€” across a 24-hour window on an account with near-zero prior Gemini history. The Google AI Developers Forum thread documented the incident in detail, including the 99.85% spend drop when the API was disabled.

~$9,500 abuse resumed 3 days after rotation (Google AI Developers Forum, April 2026): A separate incident in the same forum thread documented a Gemini API key compromise where the attacker resumed abuse three days after the original key was rotated β€” either the attacker had obtained a replacement key through the same exposure vector, or a second key from the same project was also compromised. Rotating a single key without auditing the full key inventory did not remediate the incident.

$8,341 in a single day β€” Gemini account compromise (Google AI Developers Forum, April 2026): A Gemini account compromise on unclear prior history produced $8,341 in charges in a single day. The per-day spend rate exceeded the typical monthly budget for the affected project by multiple orders of magnitude.

$2,200 in a single day via Firebase key (Google AI Developers Forum, April 2026): A Firebase key with zero prior AI spend history was used to generate $2,200 in unauthorized Gemini charges in one day. This incident, smaller than the others in absolute terms, demonstrates that the attack pattern fires reliably below the threshold of what most general anomaly monitors would flag.

$10,138 in hours via compromised Maps key — Veo 3 + Imagen (The Register, May 2026): A second Maps→Gemini key abuse incident, documented in May 2026, produced $10,138 in charges across Veo 3 video generation and Imagen image generation SKUs. The account had no prior Veo 3 or Imagen billing history — services it had never used were charged. This is the SKU_ESCALATION signature: not just zero AI history, but specifically zero history on the charged SKUs within an account that has some prior AI activity.

AWS Bedrock API key theft via repository scrape (Prowler / Entro / Sonrai, December 2025–January 2026): Prowler, Entro, and Sonrai each independently documented the attack surface created by AWS Bedrock API keys (bearer token authentication format, launched July 2025). The research documented attackers validating stolen Bedrock keys with a single curl command and immediately targeting the most expensive on-demand models. Dollar impact varied by attack duration and model choice; the pattern is structurally identical to the GCP incidents. AWS Bedrock API keys are a newer credential format with less organizational hygiene tooling than IAM roles.


If you built it: what to look for and how to fix it

For platform engineers, DevOps engineers, and security engineers responsible for AI service credential management.

If you have unexpected AI service charges on an account that hasn't used that service before, you may be looking at credential abuse rather than a billing mistake. Here is how to confirm it and stop it.

Step 1 β€” Confirm you're looking at a new AI service, not a billing classification change

In AWS Cost Explorer: set Service = Amazon Bedrock, Group by = Usage Type. Filter to the past 7 days. If the usage type rows appear only in the last 2–3 days with no historical baseline, that is the ZERO_HISTORY signature. Compare against your list of known Bedrock-enabled accounts and applications. If this account's team has no Bedrock workloads in flight, the charges are not from a legitimate internal source.

In GCP Billing: filter to Vertex AI or Generative Language API SKUs. Group by Project. Look for projects with no prior AI spend showing current charges. The Gemini SKU names are specific β€” gemini-1.5-pro-output-tokens, imagen-3-generation, veo-3-generation β€” they do not appear as misrouted compute charges.

Step 2 β€” Check tag coverage on the suspicious rows

In FOCUS billing data, query for tags IS NULL on recent AI rows from the affected account. Legitimate applications propagate tags from IAM role context β€” at minimum Environment and Team for any well-governed workload. Attacker API calls carry no such context. If 80%+ of your recent AI rows have no workload attribution tags, and your other AI workloads are tagged, that ratio is anomalous independent of the cost amount.

This tag signal has medium rather than high confidence β€” it is inferred from the attack vector (direct API key calls without application context), not from direct observation of billing records in public incident reports. An internal team running an ad hoc test with a borrowed API key would also produce untagged rows. Use tag absence as a corroborating signal, not as proof on its own.

Step 3 β€” Identify the credential vector

For GCP: navigate to APIs & Services β†’ Credentials in the affected project. Look for API keys with broad scope β€” specifically any key that has access to Generative Language API, Vertex AI, or Cloud AI services. Until June 19, 2026, Maps API keys created before Google's restriction policy update may have unrestricted scope including Gemini access. Check key restrictions explicitly; do not rely on the key name or intended use to infer scope.

For AWS: navigate to IAM β†’ Security credentials β†’ Access keys for any users in the affected account. AWS Bedrock API keys (bearer token format, launched July 2025) are distinct from IAM access keys. Check both formats. Any API key that appears in a public repository β€” even a private repository with broad access β€” should be treated as compromised. Run a repository audit: search your GitHub org for the key string patterns.

Step 4 β€” Remediate in the right order

  1. Disable the API entirely, not just rotate the key. On GCP, disable the Generative Language API or Vertex AI API on the affected project. Key rotation takes effect with up to 23 minutes of propagation delay; API disablement is faster. Once the immediate bleeding stops, re-enable the API with new, restricted keys.
  2. Rotate the compromised key. After disabling the API: delete the exposed key, create a replacement with explicit scope restrictions. For GCP: restrict every API key to the specific APIs it needs β€” no key should have unrestricted scope. For AWS: delete the compromised Bedrock API key and replace with IAM role-based authentication.
  3. Audit the full key inventory. The April 2026 forum incident documented abuse resuming 3 days post-rotation. The attacker had accessed a second key from the same project. Rotating one key without auditing all keys in the project does not close the exposure.
  4. Set a spending cap. GCP: Billing β†’ Budgets & alerts, set a budget per project with a hard cap action. AWS: AWS Budgets does not enforce hard caps on Bedrock, but a $50/day Bedrock-specific alert gets you a notification within 24 hours. For AWS accounts with no AI workloads, a budget of $10 total on Amazon Bedrock with email + SNS notification is appropriate.

The billing fields (FOCUS / CUR mapping)

FOCUS FieldValue During AttackValue for Legitimate AI Workload
servicecategory AI/ML AI/ML
servicename Amazon Bedrock / Vertex AI / Azure OpenAI Same
chargecategory Usage Usage
pricingcategory Standard (OnDemand β€” attackers never hold reserved capacity) May include Committed or Dynamic
tags NULL β€” direct API key calls carry no workload context Present: Environment, Team, Application, WorkloadId
Billing history (prior 30 days) Zero rows for this (subaccountid, servicename) pair Established baseline present
Temporal profile Zero for 28+ days, then vertical spike for 24–48 hours, then drops to zero Sustained or gradual growth pattern

The detection SQL (FOCUS-native, QB21)

This query identifies accounts where AI service spend has appeared within 48 hours on an account or subaccount with no prior AI billing history for that service, with a high ratio of untagged rows. Run against your consolidated FOCUS billing export.

-- QB21: Compromised API Credential β€” AI spend billing signature
-- Fires on: zero-history AI service rows + 48-hour burst + >80% untagged
-- Does NOT require a statistical baseline β€” that's the point.
WITH ai_baseline AS (
    -- AI spend per (subaccount, service) in 30-day lookback (days -33 to -3)
    -- Excludes last 3 days to avoid contamination from the attack window.
    SELECT
        subaccountid,
        servicename,
        SUM(effectivecost) AS baseline_spend_30d
    FROM focus_billing
    WHERE servicecategory = 'AI/ML'
      AND chargecategory  = 'Usage'
      AND chargeclass     = 'Regular'
      AND CAST(chargeperiodstart AS DATE)
            BETWEEN DATE_ADD('day', -33, CURRENT_DATE)
                AND DATE_ADD('day', -3,  CURRENT_DATE)
    GROUP BY subaccountid, servicename
),
ai_recent AS (
    -- AI spend in last 48 hours
    SELECT
        subaccountid,
        servicename,
        SUM(effectivecost)                             AS recent_spend_48h,
        COUNT(*)                                       AS total_rows,
        COUNT(CASE WHEN tags IS NULL THEN 1 END)       AS untagged_rows
    FROM focus_billing
    WHERE servicecategory = 'AI/ML'
      AND chargecategory  = 'Usage'
      AND chargeclass     = 'Regular'
      AND CAST(chargeperiodstart AS DATE) >= DATE_ADD('day', -2, CURRENT_DATE)
    GROUP BY subaccountid, servicename
)
SELECT
    r.subaccountid,
    r.servicename,
    COALESCE(b.baseline_spend_30d, 0.0)                                      AS baseline_spend_30d,
    ROUND(r.recent_spend_48h, 4)                                             AS recent_spend_48h,
    r.total_rows,
    r.untagged_rows,
    ROUND(CAST(r.untagged_rows AS DOUBLE) / NULLIF(r.total_rows, 0), 4)      AS untagged_ratio,
    CASE
        WHEN b.baseline_spend_30d IS NULL
                                        THEN 'ZERO_HISTORY'
        WHEN r.recent_spend_48h > COALESCE(b.baseline_spend_30d, 0.0) * 0.5
                                        THEN 'SKU_ESCALATION'
        ELSE                                 'SPEND_SPIKE'
    END                                                                      AS credential_abuse_tier
FROM ai_recent r
LEFT JOIN ai_baseline b
    ON r.subaccountid = b.subaccountid AND r.servicename = b.servicename
WHERE r.recent_spend_48h > 50.0
  AND (
      b.baseline_spend_30d IS NULL
      OR r.recent_spend_48h > COALESCE(b.baseline_spend_30d, 0.0) * 0.5
  )
  AND ROUND(CAST(r.untagged_rows AS DOUBLE) / NULLIF(r.total_rows, 0), 4) > 0.80
ORDER BY r.recent_spend_48h DESC
LIMIT 25

Reading the results: ZERO_HISTORY means the (subaccountid, servicename) pair had zero AI billing rows in the prior 30 days β€” the highest-confidence tier. SKU_ESCALATION means recent spend on a specific service exceeds 50% of the 30-day baseline for that service β€” new AI SKUs (Veo 3, Imagen) appearing on an account that uses other Gemini SKUs. The untagged_ratio column is the discriminant: a ratio above 0.80 on AI rows is anomalous for production workloads.

Why this query doesn't need a statistical baseline: AWS Cost Anomaly Detection and most FinOps tools compute a baseline from prior spend and flag deviations. An account with zero prior AI spend has no baseline β€” the threshold computation returns NULL and no alert fires. QB21 is specifically designed for the zero-baseline case: the absence of history is the signal, not the deviation from it.

AWS Bedrock API keys vs IAM SigV4 β€” the authentication risk difference

AWS Bedrock added API key authentication (bearer token format) in July 2025. Before that, all Bedrock calls used IAM SigV4 authentication β€” which requires a valid IAM access key ID, secret access key, and correctly scoped permissions, making keys harder to use out of context and easier to scope restrictively.

Bedrock API keys are simpler to use (a single bearer token in an Authorization header) but carry the same risk profile as GCP API keys: they can be called from anywhere with a single curl command, and a key scraped from a repository is immediately functional without additional IAM configuration. If your application does not specifically require Bedrock API key authentication β€” and most do not β€” prefer IAM role-based authentication. IAM roles cannot be leaked via repository scrapes; they are instance-bound and session-scoped.


If you watch the bill: how to detect this at scale

For FinOps practitioners and cloud finance analysts responsible for AI spend visibility across multiple accounts and projects.

Compromised API credential incidents are the FinOps pattern most likely to be mis-classified as a billing error when first discovered. The charges appear on accounts nobody associates with AI workloads. The SKUs are specific but unfamiliar. The person who gets paged is the FinOps analyst, not the security team β€” but the root cause is a security incident, not a cost governance failure.

Why Cost Anomaly Detection won't catch this

AWS Cost Anomaly Detection (CAD) and equivalent tools on GCP and Azure share three structural blind spots for this pattern:

  1. No baseline, no alert. CAD derives anomaly thresholds from historical spend patterns. An account or project that has never had AI spend has no AI baseline. When $50,000 in Gemini charges appears on Day 1 of that account's Gemini history, CAD has nothing to compare it against β€” it cannot classify the spend as anomalous because it has no reference point. The alert is structurally impossible for CAD to generate.
  2. Wrong detection window. CAD operates on daily or multi-day trend windows. A 48-hour burst that drops to zero looks like a one-time anomaly within CAD's standard lookback. CAD is tuned for sustained trends (a service growing 3Γ— over two weeks); the attack signature is the opposite (vertical spike, then abrupt stop).
  3. No tag join. CAD has no awareness of tagging status on billing rows. It can't distinguish between $50,000 in tagged Bedrock charges from a legitimate model training job and $50,000 in untagged Bedrock charges from an attacker. The tag absence is the discriminant that separates attack traffic from legitimate first-day usage β€” CAD doesn't see it.

Detection tiers: ZERO_HISTORY vs SKU_ESCALATION

ZERO_HISTORY is the primary signal: an account that has never had any AI service billing rows for a given service is now showing charges. This is the highest-priority tier β€” no amount of spend is appropriate on a zero-history account without a corresponding change record or team acknowledgment. Dollar floor: $50 in 48 hours (the query threshold). Most real incidents land in the $2,000–$80,000 range.

SKU_ESCALATION is the secondary signal: an account with existing AI spend is suddenly being charged for AI SKUs it has never used before. The May 2026 incident ($10,138 via Veo 3 and Imagen) is this pattern β€” the account used other Gemini SKUs, but Veo 3 video generation and Imagen had never appeared before. The threshold: recent 48-hour spend on the new SKUs exceeds 50% of the account's 30-day AI baseline. This fires on the appearance of new, expensive AI service SKUs that have no prior cost history on an account that is otherwise a known AI spender.

Dollar impact math

The economics of credential theft attacks make detection speed the primary variable:

How to set up the alert

AWS Budgets β€” zero-baseline AI accounts: For every AWS account with no authorized Bedrock workloads, create a cost budget scoped to Service = Amazon Bedrock with a threshold of $10/month. This is deliberately low β€” any Bedrock spend on a no-AI account is abnormal. Configure email + SNS notification to the account owner and the FinOps team. At scale, this requires programmatic budget creation across your AWS Organizations member accounts; the Budgets API supports this.

GCP Billing Budgets β€” per-project AI spend caps: For GCP projects with no authorized Vertex AI or Generative Language API workloads, create a budget with a $10/month threshold on those SKU families. Set a hard cap action (block billing) on projects classified as dev or test where availability is not critical.

FOCUS-native detection (QB21 query above): Run this weekly against your consolidated billing export. Any row returned represents a (subaccountid, servicename) combination meeting the three-condition alert threshold. Route results to a security-aware Slack channel, not just the FinOps team β€” credential abuse is a security incident that requires credential rotation, not a FinOps remediation that requires resource cleanup.

Slack integration sketch: The query output returns subaccountid, servicename, recent_spend_48h, and credential_abuse_tier. A Lambda function scheduled to run daily against your Athena FOCUS table can post a formatted alert to #cloud-security-alerts with direct links to the billing console for each flagged account. ZERO_HISTORY rows should page on-call; SKU_ESCALATION rows can be non-urgent alerts.

How to report this to the account team (and the security team)

This is not a standard FinOps cost governance communication. Frame it as a potential security incident from the first message:

We detected AI service charges on [account / project name] that match the billing signature of API credential abuse: $[amount] in [service name] charges over the past 48 hours, on an account with no prior [service name] history, with [untagged_ratio Γ— 100]% of billing rows missing workload attribution tags.

This pattern is consistent with a stolen or exposed API key being used to invoke AI models. It can also result from an unannounced internal experiment β€” if your team started using [service name] in the past 48 hours, please confirm and we'll close the alert. If not, treat this as a credential compromise: review API keys and access credentials associated with this account immediately, rotate anything that may be exposed, and confirm the current billing rate has returned to zero.

Security team has been notified in parallel. Please respond within 2 hours during business hours.


If you own the outcome: the governance gap and how to close it

For Engineering Managers, VPs of Engineering, and CTOs dealing with an unexpected AI bill and a root cause nobody can explain.

What happened, in plain English

An API key used by one of your services was stolen β€” either from a public repository, a CI/CD artifact, or another exposure point β€” and an attacker used it to call AI APIs on your account. The attacker ran the key hard for 24–48 hours, maximizing token consumption on the most expensive available models, then stopped when the key was rotated or the account's spending limit was hit. The bill reflects real API usage by a real attacker, not a billing error.

In many of the 2026 incidents, the credential exposure was not from a key an engineer knew was compromised. It was from a key that had gained AI service scope without the team knowing. Google Maps API keys created before June 19, 2026 had unrestricted access to Gemini models without requiring any additional configuration or explicit grant. A key intended for Maps geolocation that existed in a public repository or third-party integration became an AI billing vector without anyone in the organization making that connection.

The governance gap: three things failed

1. No AI-specific spend monitoring on accounts without AI workloads. Your existing FinOps tooling and budget alerts were calibrated for known spend patterns. An account that has never had AI spend has no AI-specific budget. When $80,000 in AI charges arrived in 48 hours, no alert was configured to catch it β€” because the account was not on anyone's list of AI accounts to watch. The gap is not bad tool configuration; it is a structural assumption that AI spend only needs monitoring where AI is authorized.

2. API key scope was never audited after cloud providers expanded it. Google's decision to extend unrestricted API key scope to Gemini models was not widely communicated. Organizations that audited key permissions once β€” at creation time β€” did not re-audit when the permission model changed. The key that attacked your account may have had valid Maps scope and incorrect AI scope for months before it was used. Scope auditing is not a one-time activity.

3. No credential exposure scanning on repositories and CI/CD artifacts. Truffle Security found 2,863 valid API keys in a single Common Crawl web archive scan. These keys were not in current, public repositories β€” they were in historical web archive snapshots that persist after the source repository has been cleaned up. A repository secret rotation conducted after an accidental commit may not remove the key from web archive copies of the commit history. This is a known gap in most secrets management programs.

The policy fix

Three changes close the majority of the risk:

  1. Create AI spend budgets on every account, including accounts with no AI workloads. The threshold for no-AI accounts is $10/month β€” any amount is a finding. For accounts with authorized AI workloads, set a budget at 2Γ— last month's AI spend. This takes 20 minutes to configure with the AWS Budgets API across your organization and permanently closes the "no baseline" detection gap for any future incident.
  2. Audit and restrict all API keys before June 19, 2026 (GCP) — and immediately for AWS Bedrock keys. For GCP: every API key must have explicit API restrictions. The default "unrestricted" state is a liability, not a convenience. The June 19 deadline is when Google closes the Maps→Gemini vector by policy; keys restricted before that date are protected; keys left unrestricted will lose Gemini access on June 19 but may have been exposed for months. For AWS: if your applications are using Bedrock API keys rather than IAM roles, migrate to IAM role-based authentication. API keys that can be used from anywhere are a higher-risk credential format than instance-bound IAM roles.
  3. Add AI service scope to your secrets scanning program. If you run GitHub Advanced Security, Gitleaks, or a similar tool: add API key patterns for Bedrock, Vertex AI, and Azure OpenAI to your detection ruleset. More importantly, validate that your scanning covers CI/CD pipeline artifacts, build logs, and Docker image layers β€” these are common sources of accidental key exposure that pure repository scanning misses.

The decision

There are two decisions to make in parallel for any confirmed incident:

Remediation decision (hours): Disable the affected API, rotate all keys associated with the compromised project or account, and audit the full key inventory for the same exposure vector. Do not stop at rotating the single compromised key β€” the April 2026 incident documented abuse resuming 3 days after rotation because a second key from the same project was also exposed.

Cost recovery decision (days to weeks): Google and AWS both have processes for reviewing unauthorized AI charges and issuing credits. The success rate is not guaranteed, but incidents with clear credential abuse patterns β€” especially ZERO_HISTORY accounts β€” are strong candidates for credit requests. Document the timeline: when the first charge appeared, when it was discovered, when the key was rotated, when the spend stopped. Cloud provider support will ask for all of it.

What good looks like going forward

Every API key in your organization has explicit scope restrictions with no "unrestricted" keys in production. New Bedrock integrations use IAM role authentication by default; API keys are used only where explicitly justified and documented. Every AWS account β€” including accounts with no AI workloads β€” has a Bedrock, Vertex AI, or Azure OpenAI budget alert at a threshold calibrated to flag any spend at all. Your secrets scanning program covers CI/CD artifacts and build logs, not just source repositories. When a credential abuse incident occurs, the QB21 query returns the flagged account within 24 hours of the first billing row arriving in your FOCUS export.


Fix checklist

  1. Restrict all GCP API keys to explicit API scope. Log into each GCP project, navigate to APIs & Services β†’ Credentials, and set API restrictions on every key. "Unrestricted" means any API the key's project has enabled β€” including Gemini, Vertex AI, and Veo. Do this before June 19, 2026; it should have been done already.
  2. For AWS: migrate Bedrock integrations from API keys to IAM roles. Bedrock API keys (bearer token, July 2025+) can be called from anywhere. IAM role credentials are instance-bound and session-scoped. Migrate any application using Bedrock API key authentication to IAM role authentication. Revoke all Bedrock API keys after migration.
  3. Create AI spend budget alerts on every cloud account, including no-AI accounts. Threshold: $10/month for accounts with no authorized AI workloads; 2Γ— last month's AI spend for accounts with active AI workloads. Email + SNS notification to the account team and the FinOps team. This closes the "no baseline" gap that Cost Anomaly Detection cannot cover.
  4. Run the QB21 detection query against your FOCUS billing export. At minimum monthly, ideally weekly. Route ZERO_HISTORY results to your security team β€” these are credential abuse candidates, not governance findings. Any account returning a ZERO_HISTORY row this month should be treated as a potential active or recent incident.
  5. Audit your key inventory β€” not just current keys, but recently rotated ones. A key rotated after an accidental commit may still exist in web archive snapshots or CI/CD logs. Verify that rotated keys are revoked at the cloud provider (not just removed from the application), and that the exposure vector (the repository or artifact that contained the old key) is also cleaned up.
  6. Add AI service API key patterns to your secrets scanning ruleset. AWS Bedrock API key format: BedrockApiKey prefix patterns. GCP API key format: AIza prefix (38-character key). Azure OpenAI key format: 32-character hex. Scan CI/CD pipeline logs and build artifacts, not just source code commits.
  7. Disable the AI API, not just rotate the key, during active incidents. GCP API keys remain functional for up to 23 minutes after deletion due to propagation delay (Google confirmed "Won't Fix"). If you have a confirmed active attack, disabling the Vertex AI or Generative Language API on the affected project stops the spend faster than key rotation alone. Re-enable with new restricted keys after the incident is contained.

Find out what else is hiding in your AI cloud bill

Compromised API credentials are one of several AI spend patterns that standard FinOps tools don't detect β€” either because they require a zero-baseline detection approach, cross the boundary between cost and security, or arrive and disappear faster than daily anomaly monitors can respond. The DropInFinOps free assessment takes 2 minutes and shows you which patterns your current billing setup is positioned to catch β€” and which ones are accumulating undetected.

Take the free assessment β†’