On April 19th, 2026, Vercel disclosed a security incident involving unauthorized access to their internal systems. According to their incident report, the attacker compromised an employee’s Google Workspace account via a third-party AI tool named Context.ai, who have since confirmed that their consumer-focused AI Office Suite environment was indeed compromised. This incident is in effect a double supply chain attack, where access to Context.ai was leveraged to gain access to their customers, including Vercel, and then Vercel’s customers.
For more information and guidance related to Vercel’s security incident, see their advisory.
Technical details
Context.ai disclosed that they determined that OAuth tokens for some consumer users were likely compromised as a result of this incident. According to their statement, at least one Vercel employee had authorized the affected OAuth application with broad (“Allow All”) permissions, which enabled the attacker to leverage the stolen token to access Vercel’s Google Workspace.
Public reporting by Hudson Rock has noted that a recent infostealer infection of a Context.ai employee may have been leveraged to gain access to Context.ai's internal systems and ultimately acquire the OAuth application credentials, but this remains unconfirmed.
This activity hasn’t been attributed to a specific threat actor, but an actor claiming to be associated with ShinyHunters has claimed responsibility for Vercel’s incident. However, these claims remain unverified, and the group may have been impersonated by a copycat.
This campaign aligns with a broader class of attacks abusing trusted third-party OAuth integrations as an initial access vector. In similar incidents, such as the Salesloft Drift incident targeting Salesforce environments, attackers leveraged compromised OAuth tokens from a third-party provider to access downstream SaaS platforms and exfiltrate data via legitimate APIs. This tradecraft has also been observed in state-aligned activity, including the Midnight Blizzard campaign against Microsoft, where OAuth applications were abused to maintain persistent access to enterprise environments. Rather than exploiting vulnerabilities in the primary platform, these attacks rely on pre-authorized access and delegated permissions, enabling stealthy lateral movement and expanding the blast radius across multiple organizations that trusted the same integration. For additional background on detection and abuse patterns, see Wiz’s research on malicious OAuth applications and OAuth-based attack techniques.
Indicators of Compromise
| Type | Indicator | Details |
|---|---|---|
| OAuth App client ID | 110671459871-30f1spbu0hptbs60cb4vsmv79i7bbvqj.apps.googleusercontent.com | Compromised Google Workspace OAuth application linked to the incident |
What actions should security teams take?
Security teams should approach this incident as a third-party OAuth compromise with potential downstream impact across multiple SaaS platforms. Response efforts should focus on three parallel tracks: (1) identifying and revoking access to the compromised Context.ai application across identity providers, (2) assessing potential exposure by rotating credentials and tokens associated with affected users, and (3) investigating account activity for signs of misuse or data access. Given the nature of OAuth-based access, particular attention should be paid to cross-application activity and any services accessible through delegated permissions.
Assess exposure and clean up
Google Workspace:
Check if the Context.ai OAuth app is authorized in your environment. Navigate to Admin Console → Security → API Controls → Manage Third-Party App Access and search for "Context" or the OAuth Client ID.
Search for authorization events across all users:
curl -H "Authorization: Bearer $(gcloud auth print-access-token)" \
"https://admin.googleapis.com/admin/reports/v1/activity/users/all/applications/token?eventName=authorize&filters=client_id==110671459871-30f1spbu0hptbs60cb4vsmv79i7bbvqj.apps.googleusercontent.com&maxResults=1000"For each identified user, check if the token is still active:
curl -H "Authorization: Bearer $(gcloud auth print-access-token)" \
"https://admin.googleapis.com/admin/directory/v1/users/AFFECTED_USER_EMAIL/tokenshttps://admin.googleapis.com/admin/directory/v1/users/AFFECTED_USER_EMAIL/tokens
"Review the response for any token where clientId contains 110671459871.
If present: revoke the grant immediately via Admin Console → Security → API Controls. Rotate Google Workspace credentials and any linked SaaS/API tokens for all affected users.
Azure / Entra ID:
Context.ai offered Azure AD SSO integration configured as a per-tenant SAML SSO application. Search by name or by Context.ai's Entra tenant identifiers:
d06415cc-3d2c-4ffd-940e-76e35cef3a46(context.ai domain)008dd1ce-2db3-4ffa-b318-0f52bc4c3a82(context.inc domain)
# Search by display name
curl -H "Authorization: Bearer $(az account get-access-token --resource https://graph.microsoft.com | jq -r .accessToken)" -H "ConsistencyLevel: eventual" "https://graph.microsoft.com/v1.0/servicePrincipals?\$filter=startswith(displayName,'context')&\$count=true&\$select=displayName,appId,appOwnerOrganizationId"
# Search by Context.ai's Entra tenant ID
curl -H "Authorization: Bearer $(az account get-access-token --resource https://graph.microsoft.com | jq -r .accessToken)" -H "ConsistencyLevel: eventual" "https://graph.microsoft.com/v1.0/servicePrincipals?\$filter=appOwnerOrganizationId eq
d06415cc-3d2c-4ffd-940e-76e35cef3a46&\$count=true&\$select=displayName,appId,appOwnerOrganizationId"Or via PowerShell:
Connect-MgGraph -Scopes "Application.Read.All"
Get-MgServicePrincipal -Filter "startswith(displayName,'context')" -CountVariable CountVar -ConsistencyLevel eventual -Property "displayName,appId,appOwnerOrganizationId"
Get-MgServicePrincipal -Filter "appOwnerOrganizationId eq 'd06415cc-3d2c-4ffd-940e-76e35cef3a46'" -Property "displayName,appId,appOwnerOrganizationId"Or via Azure CLI:
az ad sp list --filter "startswith(displayName,'context')" --query "[].{name:displayName, appId:appId, owner:appOwnerOrganizationId}" -o tableIf found: delete the service principal via Entra ID → Enterprise Applications. Rotate credentials for all assigned users.
Okta:
Navigate to Applications → Applications and search for "Context".
# Search for the application
curl -H "Authorization: SSWS YOUR_OKTA_API_TOKEN" \
"https://YOUR_OKTA_DOMAIN/api/v1/apps?q=context&limit=20"
# If found, list assigned users
curl -H "Authorization: SSWS YOUR_OKTA_API_TOKEN" \
"https://YOUR_OKTA_DOMAIN/api/v1/apps/CONTEXT_APP_ID/users?limit=200"If found: remove the app assignment and rotate credentials for all assigned users.
Investigate activity on affected accounts
For each user identified in the previous section, investigate activity across Google Workspace services that were accessible via the OAuth grant. Review the scope field in the authorization event to determine which services to prioritize.
Drive activity:
curl -H "Authorization: Bearer $(gcloud auth print-access-token)" \
"https://admin.googleapis.com/admin/reports/v1/activity/users/AFFECTED_USER_EMAIL/applications/drive?startTime=2025-06-01T00:00:00.000Z&maxResults=1000"Google Workspace Oauth2 audit logs:
If your Google Workspace logs are ingested into GCP, you can use the Log Explorer to identify the application’s activity via the following query-
https://console.cloud.google.com/logs/query;query=protoPayload.methodName%3D~%22%2528google.identity.oauth2.GetTokenInfo%7Cgoogle.identity.oauth2.GetToken%2529%22%0AprotoPayload.metadata.event.parameter.value%3D%22110671459871-30f1spbu0hptbs60cb4vsmv79i7bbvqj.apps.googleusercontent.com%22%0AprotoPayload.serviceName%3D%22oauth2.googleapis.com%22;summaryFields=protoPayload%252Fmetadata%252Fevent%252F0%252Fparameter%252F1%252Fvalue:false:32:beginning;cursorTimestamp=2026-04-20T11:39:11.204987Z;startTime=2026-03-19T23:00:11.262Z;endTime=2026-04-20T11:39:11.262Z?referrer=search&hl=en&organizationId=<ORG-ID>
Investigate app activity: Validate source IP and audit user actions. -
https://console.cloud.google.com/logs/query;query=protoPayload.authenticationInfo.principalEmail%3D%22<USER_EMAIL>%22%0AprotoPayload.requestMetadata.callerIp%3D%22<IP_ADDRESS>%22;cursorTimestamp=2026-04-20T11:39:11.034112Z;startTime=2026-03-19T23:00:11.262Z;endTime=2026-04-20T11:39:11.262Z?referrer=search&hl=en&organizationId=<ORG_ID>
Login activity:
curl -H "Authorization: Bearer $(gcloud auth print-access-token)" "https://admin.googleapis.com/admin/reports/v1/activity/users/AFFECTED_USER_EMAIL/applications/login?startTime=2025-06-01T00:00:00.000Z&maxResults=1000"Gmail activity:
curl -H "Authorization: Bearer $(gcloud auth print-access-token)" \
"https://admin.googleapis.com/admin/reports/v1/activity/users/AFFECTED_USER_EMAIL/applications/gmail?startTime=2026-03-01T00:00:00.000Z&endTime=2026-03-31T00:00:00.000Z&maxResults=1000"Entra ID sign-in logs (if Context.ai was found as an Enterprise Application):
curl -H "Authorization: Bearer $(az account get-access-token --resource https://graph.microsoft.com | jq -r .accessToken)" \
"https://graph.microsoft.com/v1.0/auditLogs/signIns?\$filter=appId eq 'APP_ID_FROM_SECTION_1'&\$select=userPrincipalName,appDisplayName,ipAddress,createdDateTime,status"Okta sign-in logs (if Context.ai was found as an Okta app):
curl -H "Authorization: SSWS YOUR_OKTA_API_TOKEN" \
"https://YOUR_OKTA_DOMAIN/api/v1/logs?filter=target.displayName+eq+%22Context%22+and+eventType+eq+%22user.authentication.sso%22&since=2025-06-01T00:00:00.000Z&limit=1000"Review the output for anomalous patterns: unexpected volumes of API calls, activity from IP addresses that don't match the user's normal sign-in locations, or access to services outside the user's typical usage patterns.
If affected users had access to cloud environments (AWS, GCP, Azure), review those logs for anomalous activity as well.
For Vercel customers
Rotate environment variables, while prioritizing those not marked as "sensitive", as these may have been accessible during the incident. In Vercel, variables marked as “sensitive” are stored and handled in a way that prevents them from being read or enumerated, even if an attacker gains access to environment configuration interfaces
Review activity logs and deployments for suspicious behavior
Enforce use of "sensitive" environment variables for all secrets. This control limits the blast radius of similar attacks by preventing direct exposure of secret values. This is a preventative measure for future protection. Marking variables as sensitive does not mitigate exposure in this incident for any values that were previously stored as non-sensitive and may have already been accessed
Rotate Deployment Protection tokens and validate configuration
How can Wiz help?
Wiz customers can use the pre-built query and advisory in the Wiz Threat Intel Center to search for relevant instances in their environment.