
๐ค Ghostwritten by GPT 5.4 ยท Fact-checked & edited by Claude Opus 4.6 ยท Curated by Tom Hundley
A compromised GitHub Action can steal your secrets, and that is exactly what happened. In March 2025, attackers injected malicious code into tj-actions/changed-files, a popular action used to detect which files changed in a pull request. The code searched runner memory for credentials and dumped them into workflow logs. StepSecurity publicly reported the issue around March 14, 2025, and the affected action was widely used across open-source and commercial projects. If you use GitHub Actions you copied from a template, an AI tool, or a tutorial, this is your wake-up call.
Here's the plain-English version: GitHub Actions are automation helpers that run when you push code, deploy a site, or test an app. They're useful. They're also a supply chain attack target โ hackers go after the tool you trust so they can reach you through it. The big lesson is simple: your workflow is part of your app's security boundary. If you don't know what your workflows run, you don't know who has access to your keys.
TL;DR: A popular third-party GitHub Action was compromised, turning routine automation into a credential-stealing trap.
If you've never touched GitHub Actions on purpose, you may still be using them. They are the automated steps in a GitHub repo that do jobs for you โ checking code, building your app, or deploying it. Think of them like hiring a temporary worker to enter your office after hours and move papers around. If that worker gets replaced by a thief, the thief now has access to whatever was left on the desk.
That is the heart of this GitHub Actions security problem. The tj-actions/changed-files action was widely used to detect which files changed in a project. According to public reporting from StepSecurity in March 2025, malicious code was inserted into the action. The code reportedly scanned the memory of the machine running the workflow, looking for secrets like cloud keys, GitHub personal access tokens, and package publishing tokens. Wiz later reported that impacts reached large organizations, not just hobby projects.
One widely cited figure from the incident was that more than 23,000 repositories were affected. That number matters because it shows this was not some obscure edge case. It was a mainstream, copy-pasted dependency sitting inside GitHub workflow files everywhere.
A GitHub secrets compromise like this is dangerous because many people assume, "I stored the secret safely in GitHub, so I'm fine." Not quite. If the workflow loads that secret into a running job, and the job runs malicious code, the secret can be exposed during the run.
If this sounds familiar, it should. It's the same basic lesson as Your AI Coding Assistant Is Leaking Your API Keys and .env Files Explained: Protect Your API Keys Today: storage matters, but usage matters just as much.
TL;DR: The attacker didn't need to break into your repo directly โ they only needed your workflow to run poisoned code with access to secrets.
Your workflow starts. GitHub spins up a temporary machine to do the work. Your workflow pulls in third-party actions โ reusable chunks of code made by other people. If one of those actions is compromised, your workflow runs attacker code as if it were trusted.
That attacker code reportedly searched the machine's memory for credentials. Memory is the computer's short-term working area, like papers spread across a desk while someone is in the middle of a task. Even if you lock the filing cabinet, anything left on the desk can still be photographed.
That's why third-party action risk is so serious. You may have done nothing "wrong" in your app. But if your workflow used a compromised helper, the attacker could:
Here's a comparison of safer and riskier workflow habits:
| Workflow habit | Risk level | Why it matters |
|---|---|---|
| Pinning a third-party action to a specific trusted commit SHA | Lower | You control exactly what version runs |
Using @main or @master for an action |
High | The code can change underneath you |
| Using many unknown third-party actions | High | Every extra dependency is another door into your project |
| Using first-party GitHub actions where possible | Lower | Fewer outside maintainers in the chain |
| Giving workflows broad secrets by default | High | A single compromise exposes more than necessary |
| Splitting workflows so deploy secrets only exist in deploy jobs | Lower | Limits blast radius |
Definitive statement: The most dangerous GitHub workflow is the one you didn't review because it "just worked."
TL;DR: If AI generated your workflow, you may be running dependencies you never chose and permissions you don't understand.
This is where vibe coder GitHub security gets real. Many non-developers ship apps with AI tools that happily generate workflow files for testing, deployment, previews, and releases. Those files often work on the first try โ great for momentum, terrible for scrutiny. Most people never go back and ask, "Who wrote this action? Why does it need that permission? Why is it pulling from four outside sources?"
That makes vibe coders especially exposed to supply chain attacks. You're not lazy. You just weren't taught that automation files are executable trust documents. They are not harmless settings. They are instructions telling GitHub what code to run, what secrets to load, and what access to grant.
Here are the red flags to look for in any .github/workflows file:
uses: lines pointing to actions you don't recognize@v1, @main, or @masterGitHub hosts over 200 million repositories and is the largest source code platform in the world, which is exactly why attackers target workflow security there. The platform itself is not the problem. The problem is the trust chain around reusable automation.
If you also have a public site or app repo, pair this check with Git Folder Exposure: Fix This Before You Deploy. Attackers love stacked mistakes. A weak workflow plus exposed repo metadata plus overpowered database access is how a "small" issue becomes a full breach. And if your app touches user data, make sure you understand Supabase RLS Explained: The Lock Your Database Needs, because backend permissions are often the second punch after a secret leak.
TL;DR: If you used the compromised action, rotate secrets immediately; then reduce third-party dependencies and monitor future workflow behavior.
You do not need to become a security engineer tonight. But you do need to take these steps.
Open your GitHub repository. Click the folder named .github. Open workflows. Look through each workflow file for lines containing:
uses: tj-actions/changed-filesIf you find it, treat that as potentially compromised until you confirm otherwise.
If the action was present during the affected period, assume exposed secrets are burned. Replace them.
That means changing:
Do not just delete the workflow and call it fixed. If a house key was copied, changing the doormat doesn't help. You change the lock.
In GitHub, open your repo. Go to Settings โ Secrets and variables โ Actions. Look at every secret and ask:
Prefer built-in GitHub features and official actions where possible. Fewer moving parts means fewer surprise failures.
Instead of using a floating version tag, pin to a specific commit SHA. That locks the exact version being run rather than trusting future changes automatically.
StepSecurity offers tools to inspect and monitor workflow behavior. Even if you don't adopt a tool immediately, the mindset matters: workflows need monitoring too, not just apps.
TL;DR: Use AI to simplify your workflow, not to import a pile of unreviewed dependencies.
Paste this into your AI coding tool:
Review my GitHub workflow for security. Explain it in plain English for a non-developer. Remove unnecessary third-party actions, prefer official GitHub actions where possible, minimize permissions, and flag any action versions that are not pinned safely. Then give me a cleaned-up workflow and a checklist of which secrets I should rotate if a third-party action may have been compromised.
If you want a more forceful version:
I am a non-developer using AI-generated GitHub workflows. Assume a recent supply chain attack affected one of my third-party actions. Audit this workflow like a paranoid security reviewer. Identify every external dependency, every secret used, every permission granted, and every risky default. Rewrite it to use the fewest possible dependencies and explain each change like you're teaching a beginner.
And here is a minimal example pattern you can compare against:
name: Basic Check
on: [push]
permissions:
contents: read
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run a basic check
run: echo "Review this workflow before adding deploy secrets"That example is intentionally boring. Boring is good. Boring is easier to trust.
TL;DR: Spend 15 minutes checking your workflow files before your next deploy.
Before tomorrow's lesson, do one thing: open every file in .github/workflows and make a list of every uses: line. If you don't know what one of them does, stop and investigate before you ship again.
GitHub Actions is GitHub's built-in automation system. It lets your repository run tasks automatically โ testing code, building a site, or deploying an app โ whenever something happens like a code push. Think of it as setting up automatic chores for your project.
Because the compromised action was widely reused across thousands of repositories, so one poisoned dependency reached a huge number of projects at once. StepSecurity reported more than 23,000 repositories were affected โ a textbook example of how supply chain attacks scale.
Secrets are loaded into a running workflow job when that job needs them. If malicious code runs inside that job, it can read or expose those secrets while they are in use. Locked storage doesn't help if you hand the key to a compromised process. This is different from someone breaking into GitHub's secret storage directly.
Start by opening your .github/workflows files and listing every third-party action your project uses. Remove anything unnecessary, prefer official GitHub actions, pin versions to commit SHAs, and rotate any secrets that may have been exposed. Ask your AI tool to explain every workflow line in plain English until you understand what it does.
Rotate the affected secrets immediately โ don't investigate first, rotate first. Then inspect workflow logs and recent workflow changes. Finally, remove or replace the risky action and reduce permissions so the next incident has a smaller blast radius.
tj-actions/changed-files compromise showed how one trusted action can become a supply chain attack path.If your app uses GitHub Actions, your workflow deserves the same suspicion you'd give any stranger asking for your house keys. Check what runs. Cut what you don't need. Rotate what might be exposed. And don't let "the AI set it up for me" become the story you tell after a breach.
Come back tomorrow for the next lesson, and share this with someone who needs it.
Discover more content: