A recent supply-chain attack on tj-actions/changed-files, a popular GitHub Action that helps developers identify modified files in their repositories, has exposed a critical vulnerability in modern CI/CD infrastructure that affects over 23,000 organizations. By compromising a single maintainer’s bot account, attackers modified this widely-used component to scrape sensitive secrets directly from CI/CD server memory.
The breach resulted in exposed AWS keys, GitHub tokens, npm credentials, and private RSA keys that were logged in publicly accessible workflows. With dozens of enterprise repositories confirmed as compromised, the incident demonstrates how today’s software supply chains can transform a single point of failure into thousands of vulnerable targets.
What makes this attack particularly noteworthy isn’t just its scale, but how it exploited the growing dependence on automated pipelines and third-party actions. As organizations increasingly rely on complex CI/CD infrastructure to deliver secure software, this case highlights specific weaknesses in how non-human identities and credentials are managed throughout the development lifecycle.
Anatomy of the Attack
The attack unfolded in two key stages, exposing multiple identity security gaps:
1) Initial Compromise: Stolen Maintainer Credentials
– Attackers gained access to a GitHub bot account (@tj-actions-bot) used to manage the tj-actions repository.
– The exact method of compromise remains unclear, but it likely involved either a leaked workload credential or insufficiently protected secrets in the CI/CD pipeline rather than direct human error.
– With this access, attackers altered versioning tags, redirecting users to a modified version of tj-actions/changed-files containing malicious code.
2) Payload Execution: Credential Harvesting via Memory Scraping
– The malicious update deployed a memory scraper, which copied server memory during CI/CD pipeline execution.
– Any secrets stored in memory – such as authentication tokens, API keys, and private keys – were logged and exposed to publicly accessible CI/CD workflow logs.
– Since many tj-actions users relied on mutable tags instead of cryptographic hashes, they unknowingly pulled in the compromised version, allowing the attack to spread rapidly.
Security Implications
This breach is a textbook example of a workload identity attack, affecting both the supply chain and CI/CD environments:
- The initial compromise targeted a non-human identity (a bot account), highlighting the need for stronger workload identity security beyond human access controls.
- The memory scraper attack extracted credentials even from secure workloads, meaning just-in-time authentication alone wouldn’t prevent compromise.
- Long-lived credentials dramatically expanded the damage, giving attackers an extended window to exploit stolen secrets.
- Organizations failed to verify dependency integrity, allowing the attack to spread via mutable tags instead of pinned commit hashes.
What Made This Attack So Effective?
This breach stemmed from more than an unverified dependency or misconfigured GitHub settings. It was a failure in securing non-human identities at multiple levels.
1) The Initial Breach: Compromised Bot Account
Attackers gained control of @tj-actions-bot, a non-human identity with privileged write access to the tj-actions GitHub repository.
Why does this matter? Because service accounts and service identities are often poorly secured, rarely monitored, and hold more power than they should. They don’t require social engineering or phishing emails – just one stolen credential.
We don’t know exactly how the bot account was compromised yet. But if its credentials were exposed inside a workload, the breach could have been prevented with stronger workload identity protections.
2) The Attack Execution: Memory Scraping
Once inside, the attackers:
- Injected a memory scraper into the CI/CD pipeline, which extracted secrets from running processes.
- Logged credentials in plaintext, leaving them exposed in workflow logs.
- Avoided network-based exfiltration, making the attack harder to detect in real time.
Why does this matter? Because this wasn’t a traditional API key dump – it was a memory-based attack that targeted credentials while they were in use. While properly implemented just-in-time credentials would have significantly limited the damage window, many organizations were using temporary credentials without the additional protections of proper workload identity verification and secure credential delivery, making them vulnerable during the moment of use.
3) The Damage: Long-Lived Secrets Made It Worse
Many of the stolen credentials were AWS access keys, GitHub PATs, npm tokens, and private RSA keys.
Why does this matter? Because most of them were long-lived credentials. Had they been short-lived, just-in-time tokens, the attackers wouldn’t have had a large window of time to exploit them.
How This Could Have Been Prevented
If we look at this through a workload identity security lens, there several key fixes organizations should implement immediately:
Stop Using Long-Lived Secrets
Even if credentials are stolen, they’re useless if they expire within minutes. Just-in-time authentication – where workloads get short-lived, one-time-use credentials instead of storing static secrets – would have made these stolen secrets worthless.
Secure Your Non-Human Identities Like You Secure Users
Organizations typically implement robust security controls for human administrator accounts, including MFA, conditional access policies, and behavioral monitoring. However, these same protections are rarely extended to non-human identities despite their privileged access. The disparity in security controls between human and non-human identities creates a significant vulnerability, as demonstrated in this attack.
Service accounts need:
Strong authentication without stored secrets
Strict access policies (not “full repo” permissions)
Continuous identity validation (not just a one-time API key)
Monitor CI/CD Pipelines for Anomalies
Unexpected network traffic, altered versioning tags, or unauthorized repository changes should trigger immediate alerts and mitigation steps.
How Aembit Can Help
1) Eliminate Long-Lived Secrets With Just-in-Time Authentication
Aembit enables workloads to authenticate to services without storing long-lived secrets, replacing static credentials with policy-based, just-in-time access. This ensures that even if an attacker compromises a workload, they can’t extract a reusable credential.
2) Secure Workload Identities Without Hardcoded Credentials
Instead of relying on API keys, tokens, or hardcoded secrets, Aembit uses native workload identity verification to authenticate workloads dynamically. This prevents secrets from being stored in memory or exposed in CI/CD logs.
3) Enforce Least-Privilege Access for Non-Human Identities
Aembit ensures that software workloads and scripts only have the access they need, when they need it – and nothing more. By defining fine-grained access policies, organizations can prevent privileged non-human identities from being abused in supply-chain attacks like this one.
4) Provide Visibility into Workload Access
Aembit logs all workload authentication and access events, giving security teams clear insight into which workloads are accessing which services, under what conditions. These logs can be integrated into SIEMs or security monitoring tools for additional detection and response capabilities.
5) Reduce the Attack Surface in CI/CD Pipelines
By replacing static secrets with workload-based authentication, Aembit helps organizations close a major security gap – ensuring attackers can’t steal and reuse credentials from memory or logs during supply-chain attacks.
The Workload IAM Company
Manage Access, Not Secrets
Boost Productivity, Slash DevSecOps Time
No-Code, Centralized Access Management