The biggest threat to CI/CD security today isn’t just misconfigurations — it’s the blind trust placed in third-party GitHub Actions that can be silently compromised.
The tj-actions supply chain attack exposed how dangerous this can be. Even after the breach was discovered, organizations struggled to locate where the malicious Action was used and had to disable affected workflows manually — a time-consuming and error-prone process during a live security incident.
In another GitHub Actions security incident, attackers used stolen credentials to create a brand-new workflow in a separate branch to exfiltrate secrets. Since it didn’t touch existing workflows, it bypassed detection entirely.
From unvetted Actions and unauthorized runner labels to secrets exposed in forked pull requests, subtle deviations like these often go unnoticed until it’s too late. So far there have been tools that audit for such deviations and flag them but were not able to enforce compliance.
Today, we’re launching a new feature to change that: Workflow Run Policies
This feature empowers security and platform teams to enforce security policies across GitHub Actions workflows to ensure that all workflow runs are compliant with their policies and block the ones that are not compliant.
🗓️ Join our upcoming webinar where we'll dive deep into these new capabilities and show you how to implement them in your organization.
The Problem: Enforcing compliant GitHub Actions workflows at scale
With hundreds or even thousands of workflows running across multiple teams, visibility alone isn’t enough. We have repeatedly heard from our customers that they need guardrails - a way to enforce compliant workflows, for such scenarios:
- Allow only specific runner labels (e.g., self-hosted runners) in select repos
- Enforce allowlists for internal or third-party GitHub Actions
- Prevent an attacker from creating a new workflow to exfiltrate credentials
- Block the use of workflows with known compromised GitHub Actions
The time between introducing a vulnerable workflow and it getting exploited is shrinking. For example, in the Grafana security incident, a workflow was exploited less than 24 hours after it became vulnerable to a Pwn Request vulnerability. Security teams can’t keep up with these misconfigurations manually — and by the time an incident occurs, the damage may already be done.
The Solution: Preventive Enforcement with Workflow Run Policies
Workflow Run Policies allow you to define and enforce guardrails for GitHub Actions workflows at the organization or repository level. If a workflow run violates a policy, StepSecurity cancels the run automatically, before it runs.
You’ll see this in your workflow logs:
The run was canceled by @stepsecurity-app[bot]
It’s proactive, real-time enforcement that scales with your GitHub Actions footprint.
What You Can Enforce
Workflow Run Policies currently support four key policy types, all built to tackle common security gaps, with many more policies on the way:
- Compromised Actions Policy: Block workflows that use known compromised actions
- Secret Exfiltration Policy: Blocks modified workflows in non-default branches from using secrets unless explicitly approved.
- Allowed Actions Policy: Enforce an allowlist of GitHub Actions that can be used in workflows.
- Runner Label Policy: Control which runners are allowed or disallowed.
See Why a Workflow Was Blocked — In Real Time
Every blocked run includes a detailed policy evaluation, so your team can understand:
- Which workflow run triggered the enforcement
- What policy was violated
- Why the violation occurred

The Policy Evaluations Dashboard offers a full audit trail, helping you fine-tune rules and investigate blocked workflows with ease.
How to Get Started
Workflow Run Policies are managed through the StepSecurity dashboard or API.
You can:
- Create and edit policies through a simple UI or using the API
- Apply policies to all or selected repositories
- Choose between Enforce mode (block runs) or Dry Run mode (only alert)
- View blocked workflow runs and the specific policy violations that caused them
Policy Examples in Action
Compromised Actions Policy
- Let’s take a scenario where you want to block known compromised actions from executing workflow runs. Here is a workflow file that is using a (dummy) compromised action:
name: CI
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
# This step uses a compromised action — should be blocked by policy
- name: Run a one-line script
uses: step-security/dummy-compromised-action@main
- This is what the policy looks like for this scenario:

- StepSecurity maintains a centralized list of known compromised actions. If a workflow uses an action in this list, the StepSecurity bot will automatically cancel the workflow run and leave a comment on the pull request:

- If a workflow run is cancelled due to a compromised Action, you can navigate to the Policy Evaluations dashboard and click on the cancelled run to view which Actions were flagged as compromised

Note: The list of compromised Actions is dynamic. Once an Action has been verified as repaired or no longer poses a risk, it will be removed from the list — and any workflows using that Action will resume functioning normally.
Explore our interactive demo to see how you can set up Compromised Actions Policy in your own organization:
Secrets Exfiltration Policy
Scenario 1: Attacker Tries to Exfiltrate Secrets
- An attacker gains access to credentials and creates a new workflow in a separate branch that attempts to steal secrets. Here is an example of what the malicious workflow file will look like:
name: Secrets - Fail
on:
push:
jobs:
build:
name: Deploy
runs-on: ubuntu-latest
steps:
# Attacker's attempt to exfiltrate credentials using a new workflow
# This method was used in the Grafana security incident
- name: Convert secrets to JSON file
env:
VALUES: ${{ toJSON(secrets) }}
run: |
echo "$VALUES" > secrets.json
- name: Upload secrets file
uses: actions/upload-artifact@v3
with:
name: secret-artifact
path: secrets.json
- The Secret Exfiltration Policy detects access to secrets, and it compares the workflow with the default branch version. Here is what the policy looks like:

- Since the workflow is new and unapproved, the StepSecurity bot cancels the run

Scenario 2: Developer Needs Access to Secrets
- A legitimate developer opens a pull request that modifies a workflow requiring secret access. The policy blocks the run to ensure no unauthorized secret access occurs.

How to Unblock
- In the PR let another team member add the label “workflows-approved” to the PR and re-run the job and the workflow will run

- All approvals are recorded in the policy evaluation dashboard to maintain a full audit trail.
Explore our interactive demo to see how you can set up Secret Exfiltration Policy in your own organization:
Allowed Actions Policy
- Let’s take a scenario where you only want to allow specific actions to run. Here is a workflow file that uses an internal action which should not be allowed.
name: Actions - Fail
on:
workflow_dispatch:
jobs:
build:
name: Deploy
runs-on: ubuntu-latest
steps:
# Allowed as per policy
- name: Harden-Runner
uses: step-security/harden-runner@v2
with:
egress-policy: audit
# Allowed as per policy
- name: Code Checkout
uses: actions/checkout@v2
with:
fetch-depth: 2
# Internal action - not allowed as per policy
- name: Harden-Runner Fork
uses: actions-security-demo/harden-runner@main
with:
egress-policy: audit
- This is what the policy looks like for this scenario:

- The workflow run is blocked:

- You can view the policy evaluation to find out more details why the workflow run was blocked

How is this different from what GitHub offers?
GitHub has a feature to create an allowed list of actions, and StepSecurity Workflow Run Policies have the following benefits that can be used to compliment the GitHub feature:
- Allows setting granular policies at the repository level
- Allows blocking the use of specific internal actions
- Makes it easy to configure policies based on current usage of actions
Explore our interactive demo to see how you can set up Allowed Actions Policy in your own organization:
Runner Label policy
- Let’s take a scenario where you only want to allow the use of self-hosted runners for specific repositories. Here is a workflow file that uses a GitHub-hosted which should not be allowed.
name: RunsOn - Fail
on:
workflow_dispatch:
jobs:
build:
name: Deploy
# windows-latest runner label not allowed as per policy
runs-on: windows-latest
steps:
- name: Harden-Runner
uses: step-security/harden-runner@v2
with:
egress-policy: audit
- name: Code Checkout
uses: actions/checkout@v2
with:
fetch-depth: 2
- This is what the policy looks like for this scenario:

- The workflow run is blocked by the policy

- You can view the policy evaluation to find out more details why the workflow run was blocked

Explore our interactive demo to see how you can set up Runner Labels Policy in your own organization:
🚀 Start Your Free Trial
Want to try Workflow Run Policies in your own GitHub environment?
Start your 14 days free trial to experience proactive enforcement and safeguard your GitHub Actions workflows.
Learn More
Want to explore Workflow Run Policies in more detail?
📘 Read the Docs
Dive deeper into how each policy type works and how to configure them in your GitHub environment by checking out the Workflow Run Policies documentation.
🎙️ Join the Webinar
We’re hosting a live webinar to walk you through these new capabilities, including real-world use cases and implementation tips.