AWS Credentials Used from GitHub Actions and Non-CI/CD Infrastructure
Description
Detects AWS access keys that are used from both GitHub Actions CI/CD infrastructure and non-CI/CD infrastructure. This pattern indicates potential credential theft where an attacker who has stolen AWS credentials configured as GitHub Actions secrets and is using them from their own infrastructure.
Query · esql
from logs-aws.cloudtrail-* metadata _id, _version, _index
| WHERE event.dataset == "aws.cloudtrail"
AND aws.cloudtrail.user_identity.access_key_id IS NOT NULL
AND @timestamp >= NOW() - 7 days
AND source.as.organization.name IS NOT NULL
// AWS API key used from github actions
| EVAL is_aws_github = user_agent.original LIKE "*aws-credentials-for-github-actions"
// non CI/CD related ASN
| EVAL is_not_cicd_infra = not source.as.organization.name IN ("Microsoft Corporation", "Amazon.com, Inc.", "Amazon Technologies Inc.", "Google LLC")
| STATS Esql.is_github_aws_key = MAX(CASE(is_aws_github, 1, 0)),
Esql.has_suspicious_asn = MAX(CASE(is_not_cicd_infra, 1, 0)),
Esql.last_seen_suspicious_asn = MAX(CASE(is_not_cicd_infra, @timestamp, NULL)),
Esql.source_ip_values = VALUES(source.address),
Esql.source_asn_values = VALUES(source.as.organization.name) BY aws.cloudtrail.user_identity.access_key_id, user.name, cloud.account.id
// AWS API key tied to a GH action used from unusual ASN (non CI/CD infra)
| WHERE Esql.is_github_aws_key == 1 AND Esql.has_suspicious_asn == 1
// avoid alert duplicates within 1h interval
AND Esql.last_seen_suspicious_asn >= NOW() - 1 hour
| KEEP user.name, aws.cloudtrail.user_identity.access_key_id, Esql.*
Investigation fields
Pivot points the source recommends for triage.
aws.cloudtrail.user_identity.access_key_iduser.name
Known false positives
- AWS credentials legitimately shared between GitHub Actions and another Microsoft/Azure service may trigger this rule. Verify whether the non-CI/CD source IP is expected for the workload.
- GitHub Actions self-hosted runners running on non-Microsoft/Amazon/Google infrastructure will appear as suspicious. Add the ASN of your self-hosted runner infrastructure to the is_cicd_infra allowlist.
Analyst notes
Investigating AWS Credentials Used from GitHub Actions and Non-CI/CD Infrastructure
This rule detects when an AWS access key appears in CloudTrail from both GitHub Actions runners
(identified by Microsoft ASN or the github-actions user agent string) and from infrastructure
outside the expected CI/CD provider ASNs. This is a strong indicator that AWS credentials stored
as GitHub repository or organization secrets have been exfiltrated and are being used by an
attacker from their own infrastructure.
Possible investigation steps
- Identify which GitHub repository owns the credential by cross-referencing the access key ID with your GitHub Actions workflow configurations and AWS IAM user/role assignments.
- Review the suspicious source IPs and ASNs — residential ISPs, VPN providers, or budget hosting providers are high-confidence indicators of credential theft.
- Check the actions performed from the suspicious source —
sts:GetCallerIdentityfollowed by enumeration calls (ListBuckets,DescribeInstances,ListUsers) is a common attacker recon pattern after credential theft. - Review the user agent strings from the suspicious source —
aws-cliorboto3from a non-runner IP confirms manual/scripted usage outside CI/CD. - Check GitHub audit logs for recent workflow changes, new collaborators, or secret access events that could indicate how the credential was stolen.
- Determine if the credential is a long-lived IAM user key or a temporary STS session — temporary
credentials from
AssumeRoleWithWebIdentity(OIDC) are less likely to be exfiltrated but still possible.
Response and remediation
- Immediately rotate the compromised AWS access key in IAM and update the GitHub repository/org secret.
- Review and revoke any resources created or modified by the suspicious source IP using CloudTrail event history filtered by the access key ID.
- Audit the GitHub repository for signs of compromise — check for unauthorized workflow modifications, new secrets, or suspicious pull requests that could have exfiltrated the credential.
- Implement OIDC-based authentication (
aws-actions/configure-aws-credentialswithrole-to-assume) instead of long-lived access keys to eliminate the credential theft vector entirely. - If using OIDC, add IP condition policies to the IAM role trust policy to restrict
AssumeRoleWithWebIdentityto known GitHub runner IP ranges. - Enable GitHub's secret scanning and push protection to detect accidental credential exposure in code or logs.