Policy Store

The Policy Store centrally manages Harden-Runner egress policies for your organization. Instead of writing allowed-endpoints inline in each workflow file, you define a policy once, attach it to a scope (workflow, repository, organization, or ARC cluster), and Harden-Runner fetches and enforces it automatically at runtime.

This makes it possible to update egress rules across hundreds of repositories without touching a single workflow file, and to keep an auditable history of every change.

Open Harden Runner → Policy Store from the sidebar to manage all of your organization's policies in one place.

The page has three sections:

Global Block Policy: A red callout at the top of the page surfaces the Global Block Policy, which blocks known-malicious domains and IPs across every workflow run in your organization, even when a policy is in Audit mode. The Global Block Policy is maintained by the StepSecurity SOC and is enforced automatically; you cannot edit or detach it.

Your policies: A counter row below the callout summarizes your organization's policies and acts as a filter:

Filter
Shows

Total

Every policy in the organization

Block

Policies in Block (enforce) mode

Audit

Policies in Audit (observe) mode

Unattached

Policies that are not attached to any scope and are therefore inactive

Use the Search policies by name input to filter the table further.

Policies table: Each row is one policy:

Column
Description

Policy name

The display name set when the policy was created

Mode

Block or Audit, with a colored dot (red for Block, orange for Audit)

Endpoints

Number of entries in the allowed-endpoints list

Attached to

The scope the policy is currently attached to (e.g., Organization, 2 Repositories), or Not attached if it is dormant

The three-dot menu at the end of each row exposes the per-policy actions described in Managing policies.

Key concepts

Policy

A policy is a YAML document that configures Harden-Runner's runtime behavior. It has the same shape as the with: block you would write in a workflow file:

A policy can also include a lockdown-mode section (see Lockdown Mode below).

Scope and attachment

A policy on its own does nothing. To take effect, it must be attached to one or more of the following scopes:

Scope
Applies to

Workflow

A single workflow file in a single repository

Repository

All workflows in a repository

Organization

All repositories in a GitHub organization

Cluster

All jobs running on a specific Actions Runner Controller (ARC) cluster

A policy listed as Not attached in the Policy Store exists but is not applied anywhere. Attach it to a scope to activate it.

Precedence

When multiple policies could apply to the same job, Harden-Runner picks the most specific one:

If a workflow-level policy exists, it wins. Otherwise the repository policy applies; if none, the organization policy; and finally the cluster policy (for ARC).

circle-info

When a reusable workflow is called, the calling repository's policy is applied — not the policy of the repository that hosts the reusable workflow. This means every repository gets its own enforcement even when sharing workflows.

Policy history

Every change to a policy — content edits, attachments, detachments, and scope modifications — is recorded on the policy's History page. Each entry captures who made the change, when, and what was changed, including a side-by-side diff for content edits. See View policy history for details.

Creating a policy

You can create a policy three ways:

  1. From scratch in the Policy Store

  2. From a baseline, importing endpoints observed during past workflow runs

  3. From the Baseline page, auto-populated with endpoints from a selected source

Creating A New Security Policy In StepSecurity

Made by Varun Sharma with Scribearrow-up-right

Learn how to establish a new security policy for your GitHub actions by importing existing configurations from an established repository. This guide simplifies the setup process by utilizing baseline sources to ensure consistent security coverage across your projects.

Policy Setup

1. Navigate to https://app.stepsecurity.io/github/actions-security-demo/actions/policiesarrow-up-right

2. Click "Create policy"

Baseline Configuration

3. Click "Import from baseline"

4. Select "Repository" from the Baseline source dropdown.

5. Select "arc-demo-repo" from the Repository dropdown.

6. Click "Import endpoints" to add the selected baseline.

7. Click "Create policy" to finalize and save the configuration.

Made with Scribearrow-up-right

From scratch

Step 1: Navigate to Harden Runner → Policy Store in the sidebar and click "Create policy"

Step 2: Enter a policy name and choose the enforcement mode (audit and block)

Step 3: Add endpoints manually or import them from a baseline.

Step 4. Optionally enable lockdown-mode configuration (see Lockdown Mode).

Step 5. Click Add Policy.

The policy is created in the Not attached state. See Attaching a policy to a scope to activate it.

From a baseline (during creation)

  • During Step 3 above, click Import Endpoints from Baseline instead of typing endpoints manually.

  • Choose a baseline source:

    • Organization — endpoints observed across all repositories in the organization

    • Repository — endpoints observed in a single repository

    • ARC Cluster — endpoints observed on a specific ARC cluster

    • Job — endpoints observed in a single job's history

    • Local file — upload a file with endpoints

  • Click Import Endpoints to populate the policy, then Add Policy to save.

From the Baseline page

Step 1: Navigate to Harden Runner → Baseline

Step 2: Select a job, repository, ARC cluster, or organization, then click Create Policy

Step 3: You will be redirected to the new policy page with endpoints automatically populated

Step 4: (Optional) Click Export Endpoints to download the list as a text file

Step 5: Click Create Policy to save

Attaching a policy to a scope

A newly-created policy is inactive until you attach it.

Step 1: In the Policy Store, click the three-dot menu next to the policy and select "Attach policy"

Step 2. Choose the scope type — Cluster, Organization, Repository, or Workflow — and select the specific target.

You can attach the same policy to multiple scopes, and a single scope can only have one policy attached at a time (replacing the current attachment if you attach a new one).

Applying policies at runtime

Creating and attaching a policy is not enough on its own — the runner also needs to know to fetch policies from the Policy Store. How that's configured depends on the runner type.

GitHub-Hosted runners

For GitHub-hosted runners, enable policy fetching in your workflow file:

To get your API key:

  1. Go to Settings → Harden-Runner Installation and select GitHub-Hosted Custom VM.

  2. Copy the API key.

  3. Store it as an organization-level secret named STEP_SECURITY_API_KEY so every repository in the organization can use it.

circle-info

The API key only grants access to the Policy Store. It does not grant access to any other StepSecurity APIs.

When this step runs, Harden-Runner looks up the attached policy following the precedence rules and enforces it. No other workflow changes are needed.

GitHub-Hosted Custom VMs and Self-Hosted runners

For custom VMs and self-hosted runners, policy fetching is configured on the runner itself, so no workflow changes are needed.

Step 1. Configure the pre-job hook:

Step 2. Create and attach policies as described above. The runner will fetch and enforce the attached policy at the start of each job.

Managing policies

The three-dot menu next to each policy in the Policy Store provides the following actions:

Action
Description

View policy

Read-only view of the policy YAML

Edit policy

Modify the policy YAML content (egress policy, allowed endpoints, lockdown settings)

Modify attachment

Change the scope a policy is attached to

Detach policy

Remove all attachments. The policy is preserved but becomes inactive

View history

See the full audit trail of changes to this policy

Delete policy

Permanently remove the policy. All attachments are removed first

Edit a policy

Click Edit policy to open the YAML editor. You can edit the policy content directly, or click Import Endpoints from Baseline to add endpoints from an observed baseline. Click Update Policy to save.

Saved changes are applied on the next workflow run that fetches the policy.

View policy history

The Policy History page shows a timeline of every change made to a policy — content updates, attachments, detachments, and scope modifications — so you can audit exactly what changed, when, and who made the change.

To open the history page:

  1. In the Policy Store, click the three-dot menu next to the policy.

  2. Select View history.

Event types:

Event
Shown when

Policy Created

The policy was first added to the Policy Store

Policy Updated

The policy's YAML content was edited — displayed with a side-by-side diff highlighting added (green) and removed (red) lines

Policy Attached

The policy was attached to a new scope, or an existing attachment was modified (e.g., changed from specific workflows to entire repo)

Policy Detached

All or some attachments were removed

Each entry includes:

  • The type of change (with an icon indicating whether it was a content edit or an attachment change)

  • The user who made the change

  • Timestamp (absolute and relative)

  • Details of what changed:

    • For content changes, a side-by-side diff of the policy YAML

    • For attachment changes, the scopes added (green) and removed (red), and any transitions (e.g., specific workflows → entire repo)

From the history page, you can click Edit Policy in the top right to jump directly to the editor.

Lockdown Mode

circle-info

Lockdown Mode is currently available only for ARC clusters

Lockdown Mode provides automatic blocking of CI/CD jobs when critical security threats are detected in real-time.

How Lockdown Mode Works

When Lockdown Mode is active for a workflow, Harden-Runner continuously monitors the job at runtime. If a detection matching one of the configured detection types is triggered:

  • The running job is immediately terminated.

  • A notification is sent with details about the blocked threat, including the detection type, job ID, and workflow run.

  • The detection event is recorded in the StepSecurity dashboard and forwarded to any configured integrations (e.g., Webhook, Slack, S3).

Configuring Lockdown Mode

To enable Lockdown Mode for your workflows:

  • Navigate to the Policy Store

  • Create a new policy or edit an existing one

  • Add the lockdown configuration using the following syntax:

  • Attach the policy to your desired scope (cluster, organization, repository, or workflow)

Supported Detection Types

Detection
Description

Privileged-Container

Blocks containers running with elevated privileges

Runner-Worker-Memory-Read

Blocks unauthorized memory reading attempts

Reverse-Shell

Blocks reverse shell connection attempts

Note: When lockdown mode is enabled and a threat is detected, the job will be immediately terminated and you will receive a notification with details about the blocked threat.

Exempting Workflows from Lockdown Mode

In some cases, you may need to exempt specific workflows from Lockdown Mode — for example, workflows that intentionally run privileged containers for testing or infrastructure provisioning.

To exempt a workflow, create a separate policy with lockdown mode disabled:

Then attach this policy to the specific scope you want to exempt. The exemption policy can be applied at any level:

  • Workflow level — Disables lockdown for a single workflow.

  • Repository level — Disables lockdown for all workflows in a repository.

  • Organization level — Disables lockdown for all workflows in an organization.

circle-info

Use the most specific scope possible when creating exemptions. For instance, if only one workflow in a repository needs to run privileged containers, attach the exemption policy at the workflow level rather than disabling lockdown for the entire repository.

Example: Policy Enforcement

  • Suppose you create a policy that only allows specific endpoints

  • During a workflow run, if the job attempts to call a domain not on the allowlist, the request will be automatically blocked.

Job Markdown
  • On the Network Events tab of the Insights page, you can see that the policy was responsible for blocking the request and causing the run to fail

Network Events Tab

Last updated

Was this helpful?