AI and security briefsSecurity

Did attackers abuse my Qubole cross-account IAM role, and what do I check in AWS?

By , founder of Digiton Dynamics

Published Updated Editorial policy

Wiz says a threat actor used IAM credentials from an AWS account associated with Qubole between 14 and 26 October 2026 to assume roles that customers had built to trust Qubole. It then read secrets and S3 data. Wiz does not say how the credentials were obtained, and we found no statement from Qubole.

Who should act: Anyone who ever gave Qubole, or any other vendor, a cross-account IAM role in AWS, including roles for tools you stopped using.

Update log

What happened

Working with Sentra and Mandiant, Wiz saw the actor assume integration roles in several customer environments (Wiz, 9 November). The calls came from AWS account 805246085872, which Wiz sees Qubole's platform using. The first, on 14 October, came from a Mullvad VPN address. Every request carried the right external ID, and every one succeeded.

Inside, the actor listed resources, read Lambda environment variables, Secrets Manager and SSM Parameter Store, and downloaded S3 objects, sometimes whole buckets. It tested stolen AWS, Entra ID and Okta credentials with TruffleHog. Session names began with quiam-. Wiz found a bootable image on the actor's server but cannot confirm it was ever used.

Wiz found no tie to other campaigns. Separately, between 8 and 11 October an actor tested customer-owned AWS access keys believed to be made for Qubole integrations. Wiz could not link that to the role abuse. Wiz does not report a Qubole response, and we found no Qubole statement today.

Who is affected

Check your exposure: find the roles and the logins

First list roles that trust an outside account, then the Qubole one by name. The AWS CLI paginates for you. You need jq.

ME=$(aws sts get-caller-identity --query Account --output text)
aws iam list-roles --output json | jq -r --arg me "$ME" '.Roles[] | {n:.RoleName, p:[.AssumeRolePolicyDocument | .. | .AWS? // empty] | flatten | map(select(contains($me) | not))} | select(.p | length > 0) | [.n, (.p | join(","))] | @tsv'

Then read CloudTrail from 1 October, in us-east-1 and every region you use. Wiz says legitimate Qubole traffic came from AWS addresses, so flag any other source, the principal ID AIDA3W7DIFLYOLTK63SFS and quiam- session names.

aws cloudtrail lookup-events --region us-east-1 --lookup-attributes AttributeKey=EventName,AttributeValue=AssumeRole --start-time 2026-10-01T00:00:00Z --output json | jq -r '.Events[].CloudTrailEvent | fromjson | select(.userIdentity.accountId=="805246085872") | [.eventTime,.sourceIPAddress,.userIdentity.principalId,.requestParameters.roleSessionName] | @tsv'

What to do now

  1. Delete roles you no longer use, or remove the vendor from their trust policy. Wiz says unused roles still accepted the actor.
    aws iam delete-role --role-name ROLE
    Detach its policies first.
  2. For roles you keep, narrow trust and demand an external ID. Qubole's docs say Qubole issues the ID, so ask Qubole to rotate it. Wiz says a source IP condition alone would have blocked every assumption it saw.
    aws iam update-assume-role-policy --role-name ROLE --policy-document file://trust.json
    In trust.json keep sts:AssumeRole, add an sts:ExternalId condition and an aws:SourceIp condition set to the vendor's published ranges.
  3. If CloudTrail shows a hostile assumption, rotate every secret, parameter and Lambda variable the role could read. Rotation does not end temporary sessions, so revoke them too (Wiz). In the console choose Revoke active sessions on the role, which adds a deny policy for sessions issued before that moment (AWS IAM docs).
  4. Revoke any Qubole-era access keys with aws iam update-access-key and delete them once nothing breaks.
  5. Turn on S3 data events or server access logs for sensitive buckets. Management events show the assumption but not the object reads.

What should have been in place

Questions people ask

Does an external ID stop this kind of attack?

Not by itself. Wiz says every assumption it saw included the right external ID and succeeded, and that the ID is logged in plaintext in CloudTrail. Pair it with a source IP condition.

I stopped using Qubole. Am I still exposed?

If the role and its trust policy still exist, yes. Wiz found unused roles that still accepted the actor, so delete them or remove the vendor account from the trust policy.

What did Qubole say about the incident?

We found no Qubole or Idera statement in the sources we could read on 9 November 2026. Wiz does not say how the credentials were obtained.

Will rotating my secrets end the attacker's access?

Not for sessions already issued. Wiz says rotating a credential does not end temporary sessions, so revoke the role's sessions as well.

Digiton's production review maps every vendor role and secret store in your cloud account, and the checks it runs are on the vibe coded app audit page.

How this brief was made: researched from the sources below, drafted with AI assistance and checked against each source on the dates shown. See the editorial policy.

Sources

  1. Wiz, Qubole cross-account access abused in the wild, 9 November 2026, read 9 November 2026. https://www.wiz.io/blog/qubole-cross-account-access-abused-in-the-wild
  2. Qubole documentation, creating a cross-account IAM role, read 9 November 2026. https://docs.qubole.com/en/latest/user-guide/managing-accounts/aws/iam-roles/create-iam-roles.html
  3. AWS IAM documentation, revoking role session credentials, read 9 November 2026. https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_revoke-sessions.html
  4. AWS IAM documentation, the confused deputy problem and external IDs, read 9 November 2026. https://docs.aws.amazon.com/IAM/latest/UserGuide/confused-deputy.html

More briefs

Were my Railway environment variables stolen, and what should I rotate?What should I rotate and move before Zeabur shuts down on 31 December?

How these briefs are sourced and corrected. All AI and security briefs

Building something that has to hold up in production?

Start with a free 25-minute scoping call. If it fits, the first paid step is a production review: five working days on your real repository, scored against ten layers, with a costed fix list.

Book a 25-minute scoping call