Safeguard
Supply Chain•

Tabletop script: a popular GitHub Action turns malicious

A 60 minute tabletop script for a compromised third-party GitHub Action: setup, four injects, discussion questions and what good answers look like.

Safeguard Security Team
4 min read

A compromised GitHub Action tabletop asks one question: if a third-party action in your pipeline started leaking secrets today, how fast could you find every run that used it, rotate what it saw, and prove you did? This script runs in 60 minutes with four injects and needs no tooling beyond a shared document.

Why this scenario is worth practising

In March 2025, CISA published an alert about a compromise of the tj-actions/changed-files action (CVE-2025-30066), possibly enabled by a related compromise of reviewdog/action-setup (CVE-2025-30154). CISA said exposed data could include access keys, GitHub personal access tokens, npm tokens and private RSA keys. Its advice was to find affected workflow runs, identify exposed secrets and rotate them immediately.

That sequence is the skeleton of this exercise. Use the public facts as inspiration, but run it against a fictional action name so nobody argues about the real incident.

Setup (5 minutes)

  • Facilitator: reads injects aloud and keeps time.
  • Responders: one person from platform or CI, one application engineer, one security or on-call lead.
  • Scribe: records decisions, times and open questions.
  • Rule: answers must name a real place in your setup, such as a dashboard, a command or a person. "We would check" does not count.

Fictional premise: an action called acme/changed-files-lite is used by a large share of your repositories. Maintainers report a malicious commit on a moving tag.

The four injects

Inject 1, minute 5. A maintainer post says a tag was moved to a malicious commit about two days ago. Ask: how do you learn which of your workflows reference this action, and in which repositories? Do you reference tags or full commit SHAs? GitHub's hardening guide recommends pinning to a full length commit SHA and verifying the SHA comes from the action's own repository, not a fork.

Inject 2, minute 20. You confirm 14 repositories ran the action during the window. Some logs are public. Ask: which secrets could those runs read? Who decides what is treated as exposed? GitHub notes that any user with write access can read repository secrets, so list repository, environment and organisation secrets separately.

Inject 3, minute 35. A cloud provider alert shows an unusual login using a deploy key. Ask: how do you revoke it, what breaks, and who approves downtime? What was the default permission on the workflow token?

Inject 4, minute 45. A customer asks in writing whether their data was affected. Ask: who answers, with what evidence, and what do you refuse to say yet?

What good answers look like

QuestionA strong answer
Find affected runsA search across workflow files and run history, owned by a named person
PinningActions referenced by commit SHA, with a review step to update them
Secrets exposureAn inventory of secrets per repository with owners
Token permissionsRead only default, raised per job
EvidenceTimeline, rotation records and audit log exports saved for the report

GitHub's guidance also points to the audit log, which records the action type, time and account, and gives org.update_actions_secret as an example event for tracking secret changes.

Debrief (10 minutes)

Ask each person for one thing that surprised them and one change they will make this month. Turn the answers into dated tickets with owners. Our after-action report guide shows how to record them.

Try it yourself

Click through it at your own pace, or open it full screen. Watch how a gate decides whether a change is allowed to merge, then ask where your own pipeline has no such decision point.

Safeguard offers SBOM and dependency scanning, policies and gates, and compliance evidence automation, which can help with the inventory and evidence questions above. You can run a free scan to see what your repositories depend on.

Quick check

How long should this tabletop run?

Sixty minutes is enough for four injects and a short debrief. Add time only if the team wants to rehearse the customer communication in detail.

Should we use the real tj-actions details in the exercise?

Use them as inspiration only. A fictional action name keeps the discussion on your own process instead of on arguments about the real event.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.