From Exposure to Lockdown: How AWS Neutralizes Compromised IAM Credentials through Managed Policies
Executive Summary
This article explores how AWS mitigates the security risks associated with publicly exposed Identity and Access Management (IAM) access keys through its AWSCompromisedKeyQuarantine managed policy. We discuss the evolution of the different versions of this AWS managed policy. We also show how the managed policy AWSCompromisedKeyQuarantine evolved over time to protect organizations by relating it directly to new cloud attacks against AWS environments.
Additionally, this article provides background to the partner integration between GitHub's secret scanning program and AWS. Our research details how the managed policy automatically gets attached with a step-by-step timeline of a real-world exposure test.
Finally, the article highlights practical monitoring strategies for security teams to detect quarantine events within their own logging environments to ensure rapid incident response.
Palo Alto Networks customers are better protected from the threats discussed above through the following products and services:
Unit 42 Cloud Security Assessment is an evaluation service that reviews cloud infrastructure to identify misconfigurations and security gaps.
If you think you might have been compromised or have an urgent matter, contact the Unit 42 Incident Response team.
| Related Unit 42 Topics | IAM, Exposed Credentials, Identity |
AWSCompromisedKeyQuarantine Background
When organizations face attacks against their AWS environments, misuse of AWS IAM user access keys continue to account for a large majority of initial attack vectors. These long-term access keys pose security risks to organizations if the permissions associated with the IAM users do not follow the principle of least privilege.
Access keys and their associated secrets become exposed in many different ways, commonly through publication in public code repositories or exposure in environment variable files. If AWS receives notifications about access keys and secrets exposed in public GitHub repositories or through other notices, it promptly secures those credentials and notifies the owners.
AWS secures the exposed credentials using automated processes, which allows it to quickly support victim organizations and limit their exposure. This automated process has been around for many years and was documented by cloud security researcher Pawel Rzepa in the AWS Access Keys Leak in GitHub Repository and the Some Improvements in Amazon Reaction posts.
Before delving into the importance of the AWSCompromisedKeyQuarantine managed policy and its purpose, we will first discuss how managed policies work within AWS environments.
The AWS IAM service offers various features for configuring identities within an AWS account. In particular, AWS provides a policy feature that aggregates permissions into an object for attachment to a principal.
Policies encompass a wide range of types, but this article focuses on identity-based policies. Identity-based policies specifically attach to an identity, while other policy types attach to resources or define permission limitations, such as a permission boundary.
These policies consist of managed (AWS-managed and customer-managed) and inline policies. Managed policies include three sub-types:
Figure 1 shows the breakdown of these policies.
AWS-managed policies exist to assist organizations with IAM permission management. They also enable organizations to configure permissions to stand up resources within an AWS account swiftly and securely. Of the AWS-managed policies, AWSCompromisedKeyQuarantine specifically helps protect an IAM user in case of an exposed AWS IAM access key and secret. Access keys grant long-term command line interface (CLI) access to an IAM user.
AWS created the AWSCompromisedKeyQuarantine managed policy on Aug. 11, 2020, later releasing V2 on April 21, 2021, and V3 on Aug. 21, 2024. According to the V3 managed policy description, this policy:
“Denies access to certain actions, applied by AWS in the event that an IAM user's credentials have been compromised or exposed publicly. The policy aims to limit the potential damage that may be caused by fraud-related activity leading to unauthorized charges, while not impacting the existing resources. Do NOT remove this policy. Instead, please follow the instructions specified in the support case created for you regarding this event.”
We will cover the evolution of the policy permissions and the implication of those changes in the Managed Policy Permission Evolution section of this article.
Analyzing this policy in detail matters because AWS automatically attaches it upon locating exposed credentials in public code repositories or external exposure notifications. The AWSCompromisedKeyQuarantine managed policy proactively assists customers during access key exposures to minimize potential damage from attackers. Once attached, the managed policy limits the scope of permissions associated with the IAM user by denying various permissions commonly misused by threat actors.
GitHub Secret Scanning Partner Program
Long-term access keys can be exposed in many different ways. For example, it could be due to them being included in publicly accessible environment variable files and or public code repositories.
To help protect against exposing sensitive credentials, GitHub established the secret scanning partner program starting in 2018 and expanded to include AWS in 2020. It then created validity checks in January 2023 and push protection in August 2023 (discussed in more detail in the GitHub Validity Checks for Detecting Secrets Exposure section).
The GitHub secret scanning partner program allows it to scan public surfaces across GitHub, including repositories and public npm packages for specific sequences to identify exposed credentials. These scans occur by default within public repositories. Administrators and owners can also enable scanning on private repositories. Service partners can work with GitHub to create specific sequences for scanning and then provide an HTTP endpoint for GitHub to alert the service provider to exposed credentials in public repositories.
This alert allows the service provider to then proactively notify their customers about exposed credentials, and in some cases, the service providers take steps to secure the secret by revoking or quarantining the exposed secret. GitHub documentation lists more than 500 detectors across over 200 service partners, such as AWS. The checkbox in GitHub’s documentation notes when GitHub has an agreement to share compromised secret leaks with the respective issuer.
Managed Policy Attachment and Notification Process
When AWS first released the AWSCompromisedKeyQuarantine managed policy, the notification process differed from the current iteration. The original process entailed emailing the AWS account owner of the exposure. The process evolved to also attach the managed policy to the IAM user associated with the exposed access key and secret. The process has evolved again to include a support ticket generated within the AWS account containing the exposed access key.
We performed a test exposing an access key with a public GitHub repository in the main branch to track the response time and notification process. During the test scenario, AWS attached the AWSCompromisedKeyQuarantineV3 managed policy within 10 seconds of the access key exposure. A second later, GitHub generated a notification. This was followed shortly by AWS generating various Health and Support tickets.
The timeline below details each step of the testing process with commentary about what actions appear in the default AWS CloudTrail logs. The CloudTrail service, enabled by default for 90 days, records all management events occurring within an AWS account. During the test, we did not enable any additional CloudTrail data events so all the events in the timeline appear in the default CloudTrail logs. All times listed below are in Coordinated Universal Time (UTC).
- Dec. 19, 2025 17:28:39 - CreateUser - CloudTrail logs showed the creation of the initial IAM user with the arbitrary username TestUser
- Dec. 19, 2025 17:29:44 - CreateAccessKey - CloudTrail logs showed the creation of the new access key associated with the newly created IAM user
- Dec. 19, 2025 17:34:23 - GetCallerIdentity - CloudTrail logs showed the initial test of the access key with aws sts get-caller-identity
- Dec. 19, 2025 18:46:57 - When trying to push a new text file into the GitHub repository, GitHub push protection noted that it identified an access key and secret, as noted below in Figure 2. Both the access key and the secret each generated a pop-up asking whether the push with the credentials was purposeful.
- Dec. 19, 2025 18:50:05 - Access key and secret successfully pushed to public GitHub Repository
- Dec. 19, 2025 18:50:15 - CloudTrail logs show the attachment of the AWSCompromisedKeyQuarantineV3 managed policy with the AttachUserPolicy event as noted in Figure 3. The CloudTrail log did not indicate this was an AWS automated action. Instead, the userIdentity JSON field, which identifies the action's performer, listed the IAM user's name (TestUser as shown in Figure 4) even though TestUser did not perform this action.
- Dec. 19, 2025 18:50:16 - GitHub also sent out an email notification stating that it identified the sensitive access key and secret. Figure 5 shows the body of this email notification.
- Dec. 19, 2025 18:50:17 - In the AWS console, a notification appeared noting that an AWS Health alert was created with the name Risk IAM quarantine, as noted below in Figure 6. This action did not generate an event in the CloudTrail logs.
- Dec. 19, 2025 18:50:26 - AWS also sent out an email notification, shown below in Figure 7. This contained the same information as a Support ticket created seconds later in the AWS console.
- Dec. 19, 2025 18:50:59 - In the AWS console, a Support case was also created with details of the exposed access key and IAM user. Figure 8 shows the details of this case. Creating a Support case also did not generate an event in the CloudTrail logs.
Figure 9 shows the high-level chain of events from the timeline illustrated in Figures 2–8.
Within some organizations, the cloud engineering teams monitor emails regarding an AWS account and the security team is unaware of these emails. To prevent these communication gaps, security professionals can leverage AWS Systems Manager Explorer which helps aggregate AWS Support cases. The security team can also proactively enable alerting in the tool of their choice, based on the attachment event in the CloudTrail logs.
Within the CloudTrail logs, when any version of the AWSCompromisedKeyQuarantine managed policy gets attached to an IAM user, the event name AttachUserPolicy with the event source of IAM will be generated. The name of the managed policy will be present within the requestparameters subfield PolicyArn. This helps security teams proactively stay on top of exposed credentials and quickly begin investigating the access key in question.
Managed Policy Permission Evolution
After the initial release of the AWSCompromisedKeyQuarantine managed policy on Aug. 11, 2020, AWS has continued to update the policy to keep protecting their customers from new threats. AWS performs two types of version updates for managed policies. In minor updates, AWS makes changes to the permissions in the policy and updates the policy version without changing the managed policy name. In major updates, AWS creates a new managed policy and appends vX with the new version number to the end of the policy name.
Originally, the permissions of AWSCompromisedKeyQuarantine v1 focused on limiting 28 actions for the following five services:
However, with each new version of the managed policy, those permissions have evolved and expanded.
The code snippet below from the AWSCompromisedKeyQuarantine v1 managed policy JSON permissions details the full JSON permissions associated with the first version of this managed policy. Unlike traditional managed policies, this specific policy contains a Deny effect on permissions. After identifying an exposed access key, AWS does not need to modify the existing permissions associated with the IAM user to protect the identity from exploitation.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
{ "Version" : "2012-10-17", "Statement" : [ { "Effect" : "Deny", "Action" : [ "iam:AttachGroupPolicy", "iam:AttachRolePolicy", "iam:AttachUserPolicy", "iam:ChangePassword", "iam:CreateAccessKey", "iam:CreateInstanceProfile", "iam:CreateLoginProfile", "iam:CreateRole", "iam:CreateUser", "iam:DetachUserPolicy", "iam:PutUserPermissionsBoundary", "iam:PutUserPolicy", "iam:UpdateAccessKey", "iam:UpdateAccountPasswordPolicy", "iam:UpdateUser", "ec2:RequestSpotInstances", "ec2:RunInstances", "ec2:StartInstances", "organizations:CreateAccount", "organizations:CreateOrganization", "organizations:InviteAccountToOrganization", "lambda:CreateFunction", "lightsail:Create*", "lightsail:Start*", "lightsail:Delete*", "lightsail:Update*", "lightsail:GetInstanceAccessDetails", "lightsail:DownloadDefaultKeyPair" ], "Resource" : [ "*" ] } ] } |
Simply attaching these AWSCompromisedKeyQuarantine policies with the Deny component helps limit unauthorized usage of the key. When interpreting IAM user permissions, AWS dictates that explicit Deny overrides explicit Allow. So even if the IAM user permissions contained iam:CreateUser with an Allow for the effect, the AWSCompromisedKeyQuarantine managed policy containing iam:CreateUser with a Deny for the effect will override the Allow.
If the IAM user had completely different permissions than those listed below, then the purpose of the identity would not be impacted by these permission limits. Since the attachment of this specific managed policy occurs automatically, AWS wants to balance operational impact with securing the exposed credentials.
Another policy exists, AWSDenyAll, which denies all actions. However, this has a significant impact on any processes using the access key and secret. The AWSCompromisedKeyQuarantine policy limits the majority of risky threat actor activity while also allowing normal business operations.
AWS purposefully denies specific actions rather than completely disabling the compromised access key or user password. However, this decision allows advanced threat actors to use the exposed credentials for any actions the policy does not explicitly deny.
With AWSCompromisedKeyQuarantineV2, released on April 21, 2021, the permissions evolved to include the Amazon Simple Storage Service (S3) service with 11 permissions and 16 additional permissions to the original five services. Throughout the five versions of AWSCompromisedKeyQuarantineV2, AWS ultimately added a total of 61 permissions to the Deny list across 17 services.
When reviewing the different JSON permissions within v1 and v2 of AWSCompromisedKeyQuarantineV3, we identified that it replicated the additions to AWSCompromisedKeyQuarantineV2 v4 and v5 and added no additional permissions. Tables 1–3 detail the modifications made throughout each version of the managed policy.
| Managed Policy Version | Version Release Date | Permissions changed |
| v1 | 2020-08-11 18:04:13 | N/A |
Table 1. AWSCompromisedKeyQuarantine permission changes per version.
| Managed Policy Version | Version Release Date | Permissions changed |
| v1 | April 21, 2021 22:30:59 | Add: "iam:AddUserToGroup", "iam:CreatePolicyVersion", "iam:PassRole", "iam:PutGroupPolicy", "iam:PutRolePolicy", "iam:SetDefaultPolicyVersion", "iam:UpdateAssumeRolePolicy", "iam:UpdateLoginProfile", "lambda:AddLayerVersionPermission", "lambda:AddPermission", "lambda:GetPolicy", "lambda:ListTags", "lambda:PutProvisionedConcurrencyConfig", "lambda:TagResource", "lambda:UntagResource", "lambda:UpdateFunctionCode", "s3:DeleteBucket", "s3:DeleteObject", "s3:DeleteObjectVersion", "s3:PutLifecycleConfiguration", "s3:PutBucketAcl", "s3:DeleteBucketOwnershipControls", "s3:DeleteBucketPolicy", "s3:ObjectOwnerOverrideToBucketOwner", "s3:PutAccountPublicAccessBlock", "s3:PutBucketPolicy", "s3:ListAllMyBuckets" |
| v2 | Nov. 11, 2021 21:32:48 | Add: "s3:PutBucketOwnershipControls", Remove: "s3:DeleteBucketOwnershipControls" |
| v3 | Aug. 10, 2022 21:15:53 | Add: "cloudtrail:LookupEvents" |
| v4 | March 16, 2023 00:20:25 | Add: "ec2:PurchaseReservedInstancesOffering", "ec2:AcceptReservedInstancesExchangeQuote", "ec2:CreateReservedInstancesListing", "savingsplans:CreateSavingsPlan" |
| v5 | Oct. 2, 2024 16:41:39 | Add: "ecs:CreateService", "ecs:CreateCluster", "ecs:RegisterTaskDefinition", "ecr:GetAuthorizationToken", "bedrock:CreateModelInvocationJob", "bedrock:InvokeModelWithResponseStream", "bedrock:CreateFoundationModelAgreement", "bedrock:PutFoundationModelEntitlement", "bedrock:InvokeModel", "s3:CreateBucket", "s3:PutBucketCors", "s3:GetObject", "s3:ListBucket", "sagemaker:CreateEndpointConfig", "sagemaker:CreateProcessingJob", "ses:GetSendQuota", "ses:ListIdentities", "sts:GetSessionToken", "sts:GetFederationToken", "amplify:CreateDeployment", "amplify:CreateBackendEnvironment", "codebuild:CreateProject", "glue:CreateJob", "iam:DeleteRole", "iam:DeleteAccessKey", "iam:ListUsers", "lambda:GetEventSourceMapping", "sns:GetSMSAttributes", "mediapackagev2:CreateChannel" |
Table 2. AWSCompromisedKeyQuarantineV2 permission changes per version.
| Managed Policy Version | Version Release Date | Permissions changed |
| v1 | 2024-08-21 17:36:49 | Same as AWSCompromisedKeyQuarantineV2 v4 |
| v2 | 2024-10-02 16:52:27 | Same as AWSCompromisedKeyQuarantineV2 v5 AWSCompromisedKeyQuarantineV3 v2 created 11 minutes after AWSCompromisedKeyQuarantineV2 v5 |
Table 3. AWSCompromisedKeyQuarantineV3 permission changes per version.
After releasing a new version, AWS stops attaching older policies to the exposed IAM users. Starting with AWSCompromisedKeyQuarantineV2, the Support service contains the support ticket with the attachment details as outlined in Table 1.
Cloud Attack Transition Based on Policy Updates
The evolution of the AWSCompromisedKeyQuarantine managed policy reflects how threat actors have changed their attacks against AWS environments. This section discusses an example permission added to the various versions of the managed policy and illustrates how various attacks might have caused that addition.
Let’s start with iam:CreateRole and lambda:CreateFunction in the AWSCompromisedKeyQuarantine v1 managed policy. This AWS Security Blog discusses how AWS uncovered a cryptomining campaign. Part of the attack involved creating a new IAM role to attach to the threat actor-created Lambda function. Once attached, the AWSCompromisedKeyQuarantine managed policy would have prevented this threat actor from creating a Lambda function and role.
The AWSCompromisedKeyQuarantineV2 v1 managed policy contains the s3:DeleteObject action. As discussed in an InfoRisk Today article, threat actors delete data from S3 buckets after exfiltration to maximize impact and encourage payment of extortion fees. Once again, if attached, the managed policy would have prevented the threat actor from successfully deleting all the data from the S3 bucket.
To counter malicious activity targeting the Amazon Bedrock service, AWS expanded v5 of the AWSCompromisedKeyQuarantineV2 managed policy to restrict five Bedrock permissions. This update was directly influenced by research from Permiso, which exposed how attackers exploit Bedrock to run unauthorized API calls like InvokeModel. Due to these policy enhancements, the attack methods uncovered by Permiso can now also be blocked.
GitHub Validity Checks for Detecting Secrets Exposure
GitHub has also created validity checks as part of its GitHub Secret Protection program (a subprogram of the GitHub Advanced Security program, or GHAS). When enabled, these checks periodically verify the validity of a detected credential by testing it against API endpoints provided by that service provider.
A list of supported secret scanning patterns can be found within the GitHub support secret scanning patterns documentation. Once GitHub identifies a secret, the platform proactively checks with various service providers to determine whether the exposed secret remains active or inactive, or whether it cannot be confirmed. GitHub also performs GET requests with the exposed credentials to confirm the credential’s validity and filters out dummy data.
After exposure of long-term AWS access keys in GitHub repositories, these GET requests take the form of performing the AWS Security Token Service (STS) API call GetCallerIdentity. This API event subsequently appears in the CloudTrail logs for the specific AWS account containing the exposed access key. Our testing triggered the newer push protection features that assist with catching secrets before they’re pushed to repositories.
A note of caution: There are some scenarios where push protection may will not scan a code push or alert on all identified secrets:
- In one scenario, push protection does not detect secrets in the event of an overly large code push (e.g., pushing thousands of files or a public repository exceeding 50 MB)
- In another scenario, if a single code push contains more than five exposed secrets, only five will generate alerts
These scenarios could result in an identification gap. Security teams should monitor for these potential cases to ensure additional scanning occurs on those code pushes, preventing any missed secrets.
Our testing generated CloudTrail logs that contain IP addresses, which resolve to the GitHub Autonomous System Number (ASN). The user agent present within the logs identifies the API event as originating from an automated testing process.
In early October of 2025, GitHub updated the user agent associated with AWS credential checks from:
aws-sdk-go-v*/*.*.* os/linux lang/go#*.*.* md/GOOS#linux md/GOARCH#amd64 api/sts#*.*.* GHAS-AWS_KEYID-validation-1.0.0-This-call-originates-from-an-automated-process-that-tests-AWS_KEYIDs-committed-to-GitHub-repos.-Please-contact-secret-scanning-github.com-for-more-info.
To:
aws-sdk-go-v*/*.*.* os/linux lang/go#*.*.* md/GOOS#linux md/GOARCH#amd64 api/sts#*.*.* GHAS-AWS_KEYID-validation-1.0.0-This-call-originates-from-an-automated-process-that-tests-AWS_KEYIDs-committed-to-GitHub-repos.-For-questions-on-our-processes--please-contact-secret-scanning-github.com.
Note: The above user agent strings use an asterisk (*) as a wildcard value for the version numbers.
Organizations need strong internal relationships between teams managing the organization’s GitHub repositories and cloud environments to promptly address exposed credentials. To circumvent organizational inefficiencies and issues between teams, security teams can also monitor for these exposed access keys by creating alerts specifically around GitHub ASN IP addresses with the above user agents performing GetCallerIdentity. This helps security teams proactively monitor exposed credentials and quickly begin investigating the access key before a potential attacker can misuse it.
Conclusion
The creation of the AWSCompromisedKeyQuarantine managed policy has proactively secured many organizations against unknowingly exposed IAM access keys and secrets. As the managed policy evolves, it reflects how attackers change their tactics when targeting cloud environments. Using the attachment of the managed policy and the presence of the GitHub validity check user agent, organizations can quickly address an exposure and investigate potential unwanted activity.
Palo Alto Networks Protection and Mitigation
Palo Alto Networks customers are better protected from the threats discussed above through the following products:
- Cortex Cloud can help protect cloud posture and runtime operations against identity-driven threats by pairing static permission baselines with deep behavioral context. By embedding the functional identity baselines discussed in this research into our detection engine for both cloud VM compute and serverless agents, Cortex Cloud adds a vital layer of operational context, enabling security teams to filter out noisy false positives and decisively catch threat actors attempting to masquerade, alter configurations, or execute anomalous operations in the environment.
- Idira Privilege Access Management (PAM) can help unify privileged access across human, machine, and agentic identities to secure cloud access across multi-cloud environments. Building on proven PAM, it delivers centralized secrets management alongside modern controls like Just-in-Time access and Zero Standing Privileges. This enforces consistent least-privilege security across on-premises, cloud, and SaaS targets.
Unit 42 Cloud Security Assessment is an evaluation service that reviews cloud infrastructure to identify misconfigurations and security gaps.
If you think you may have been compromised or have an urgent matter, get in touch with the Unit 42 Incident Response team or call:
- North America: Toll Free: +1 (866) 486-4842 (866.4.UNIT42)
- UK: +44.20.3743.3660
- Europe and Middle East: +31.20.299.3130
- Asia: +65.6983.8730
- Japan: +81.50.1790.0200
- Australia: +61.2.4062.7950
- India: 00080005045107
Palo Alto Networks has shared these findings with our fellow Cyber Threat Alliance (CTA) members. CTA members use this intelligence to rapidly deploy protections to their customers and to systematically disrupt malicious cyber actors. Learn more about the Cyber Threat Alliance.
Indicators of Compromise
User Agents:
aws-sdk-go-v*/*.*.* os/linux lang/go#*.*.* md/GOOS#linux md/GOARCH#amd64 api/sts#*.*.* GHAS-AWS_KEYID-validation-1.0.0-This-call-originates-from-an-automated-process-that-tests-AWS_KEYIDs-committed-to-GitHub-repos.-Please-contact-secret-scanning-github.com-for-more-info.
aws-sdk-go-v*/*.*.* os/linux lang/go#*.*.* md/GOOS#linux md/GOARCH#amd64 api/sts#*.*.* GHAS-AWS_KEYID-validation-1.0.0-This-call-originates-from-an-automated-process-that-tests-AWS_KEYIDs-committed-to-GitHub-repos.-For-questions-on-our-processes--please-contact-secret-scanning-github.com.
Note: The above user agent strings use an asterisk (*) as a wildcard value for the version numbers.
How it works
Once you click Generate, Ollama reads this article and crafts 5 comprehension questions. Your answers are graded against the article content — general knowledge won't be enough. Score 70+ to count toward your certificate.
Questions are cached — you'll always get the same 5 for this article.