> For the complete documentation index, see [llms.txt](https://docs.stepsecurity.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.stepsecurity.io/github-actions/harden-runner/self-hosted-runners.md).

# Self-Hosted Runners

{% hint style="warning" %}
Available for **Enterprise** Tier only
{% endhint %}

{% hint style="info" %}
To show self-hosted runners registered at the **organization** level, the StepSecurity GitHub App needs the **Self-hosted runners: Read-only** organization permission.

If you installed the app before **August 10th**, this permission is requested but not yet granted. Until an organization admin approves it, the runner inventory still works and shows repository-level runners, but organization-level runners are not listed. See Grant the organization permission.

**Note**: This is read-only access. GitHub labels this permission "View and manage Actions self-hosted runners available to an organization", but at the **Read-only** access level StepSecurity can only list runners and read their metadata. It cannot register, modify, remove, or take runners offline
{% endhint %}

{% hint style="info" %}
Once the Harden-Runner Agent is deployed, no configuration or code changes are needed to start seeing runtime monitoring
{% endhint %}

In the StepSecurity app, go to **Harden Runner → Self Hosted Runners**. The page has three tabs:

* **ARC Clusters** shows the health and security posture of your Actions Runner Controller clusters.
* **Self Hosted Runners** shows a consolidated inventory of every self-hosted runner StepSecurity knows about, including VM-based execution environments.
* **Persistent Hosts** lists long-lived machines running the Harden-Runner agent. This tab appears only if your organization has at least one such host.

### Cluster Status

The Cluster Status feature in StepSecurity provides real-time visibility into the health and security posture of your clusters. This allows you to ensure that runtime security policies are enforced across your production environments.

On the **ARC Clusters** tab, search for or select a cluster from the list to see its details.

<figure><img src="/files/UVo3FZiSXUAUJ3KgQuug" alt=""><figcaption></figcaption></figure>

### How StepSecurity discovers runners

StepSecurity builds a single inventory of your self-hosted runners from several independent sources. A runner is frequently visible to more than one source, so StepSecurity merges the records into one entry per runner and presents the combined result.

| Source                                       | What it covers                                                                                                            | Required GitHub App permission |
| -------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- | ------------------------------ |
| **Harden Runner agent host**                 | Runners with the Harden-Runner agent installed on the runner host. The agent reports the runner directly to StepSecurity. | None                           |
| **Registered on GitHub, organization level** | Runners registered to the organization in GitHub, under **Settings → Actions → Runners**.                                 | Self-hosted runners: Read-only |
| **Registered on GitHub, repository level**   | Runners registered to an individual repository.                                                                           | Administration: Read-only      |
| **Workflow run insights**                    | Runners observed executing a job while Harden-Runner was monitoring the workflow run.                                     | None                           |

Combining these sources surfaces information that no single source provides on its own. A runner that is registered in GitHub but has never reported in from the agent, for example, appears in the inventory as registered and unmonitored, which identifies a runtime coverage gap.

### Grant the organization permission

Until the **Self-hosted runners: Read-only** permission is granted, the Self Hosted Runners tab shows a banner titled **Grant access to list your organization's runners**, and organization-level runners are omitted from the inventory. Repository-level runners continue to appear.

<figure><img src="/files/uu8ekd0afBT9ralcCVhy" alt=""><figcaption></figcaption></figure>

An organization admin can approve the pending request:

1. In GitHub, go to your organization's settings, then **GitHub Apps**. You can go there directly at `https://github.com/organizations/YOUR_ORG/settings/installations`.
2. Find the StepSecurity app and open its configuration.
3. Approve the pending permission request.

Organization-level runners appear in the inventory on the next sync. Select **Refresh** on the Self Hosted Runners tab to sync immediately.

### Runner inventory

The **Self Hosted Runners** tab lists every runner StepSecurity has discovered, from all of the sources above.

<figure><img src="/files/z9bmqgmvuDfzeXLQVz5x" alt=""><figcaption></figcaption></figure>

The header also shows when runner data was **last synced**, and how many runners are currently loaded out of the total observed. Large inventories load in pages, so the loaded count is often lower than the observed count. Select **Refresh** to re-sync.

{% hint style="warning" %}
Refreshing consumes a GitHub App installation token, which is rate-limited by GitHub. Avoid refreshing repeatedly in a short period.
{% endhint %}

Each row shows:

| Column                  | Description                                                                                                                                                                                                                                                                                                                                                    |
| ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Runner**              | The runner name, with badges beneath it.                                                                                                                                                                                                                                                                                                                       |
| **Status**              | The runner's registration and connectivity state. Values include **Online**, **Offline**, **Unknown**, **Inactive**, and **Not registered**. **Unknown** means StepSecurity has a record of the runner but no current connectivity state for it, which is common for runners that were discovered from workflow activity rather than from a live registration. |
| **Harden Runner**       | Whether the Harden-Runner agent is present on the runner. **Monitored** means the agent is installed and reporting, with the agent version shown alongside. **Not installed** means no agent has been seen on this runner.                                                                                                                                     |
| **Last Activity (GMT)** | The most recent recorded activity. For runners with no activity yet, this shows when the runner was first seen.                                                                                                                                                                                                                                                |

Rows where an agent is present also offer a **Download Setup Logs** action, which is useful when an agent has been installed but the runner is not reporting as expected. Rows showing **Not installed** do not offer this action.

If the table reads **No runners found**, either no self-hosted runners have been discovered yet, or the active filters exclude them all.

#### **Runner badges**

| Badge                    | Meaning                                                            |
| ------------------------ | ------------------------------------------------------------------ |
| **Org**                  | The runner is registered at the organization level in GitHub.      |
| **Repo: `<repository>`** | The runner is registered to that specific repository.              |
| **Persistent**           | The runner stays registered between jobs.                          |
| **Ephemeral**            | The runner is created for a single job and deregisters afterwards. |

A runner discovered only by the Harden-Runner agent, and never seen as registered in GitHub, has no **Org** or **Repo** badge.

#### Runner details

Select any runner to open its details panel. **The fields shown depend on how StepSecurity discovered the runner**, because each source provides different metadata.

<figure><img src="/files/gsIqTdSt7Tv3lmNsF5zr" alt=""><figcaption></figcaption></figure>

Every panel shows:

| Field      | Description                                                                                                    |
| ---------- | -------------------------------------------------------------------------------------------------------------- |
| **Runner** | The runner name.                                                                                               |
| **Source** | How StepSecurity discovered this runner, for example **Harden Runner agent host** or **Registered on GitHub**. |

Runners reported by the **Harden-Runner agent** also show:

| Field                     | Description                                                     |
| ------------------------- | --------------------------------------------------------------- |
| **Agent Version**         | The version of the Harden-Runner agent installed on the runner. |
| **Agent Installed (GMT)** | When the agent was first installed on the runner.               |

Runners **registered on GitHub** also show:

| Field                | Description                                             |
| -------------------- | ------------------------------------------------------- |
| **Level**            | The scope the runner is registered at.                  |
| **OS**               | The operating system reported for the runner.           |
| **Runner Group**     | The GitHub runner group the runner belongs to.          |
| **Last Job (GMT)**   | When the runner last executed a job.                    |
| **First Seen (GMT)** | When StepSecurity first observed the runner.            |
| **Jobs Observed**    | How many jobs StepSecurity has recorded on this runner. |
| **Labels**           | The labels assigned to the runner in GitHub.            |

**Events History**

For runners reported by the Harden-Runner agent, an **Events History** tab lists agent lifecycle and job events with their timestamps. Observed event types include **Started** and **Terminated** for the agent itself, and **JobStarted** and **JobFinished** for the jobs it ran.

This gives you a per-runner audit trail of when the agent was running and which jobs executed while it was.

**Workflow Runs**

The **Workflow Runs** tab lists recent workflow runs executed on the runner. Only runs that Harden-Runner monitored appear here. Runs that executed without Harden-Runner are not listed. Select **Insights** on any run to open the full network and process detail for that run.

### Persistent Hosts

The **Persistent Hosts** tab lists long-lived machines that run the Harden-Runner agent, such as always-on build servers and persistent VM runners.

This tab appears only if your organization has at least one long-lived host running the Harden-Runner agent. If you have none, the tab is hidden.

Use the search box above the table to find a host by name.

| Column                   | Description                                                              |
| ------------------------ | ------------------------------------------------------------------------ |
| **Host Name**            | The machine's hostname.                                                  |
| **Status**               | Whether the host is currently reporting to StepSecurity.                 |
| **Host ID**              | The identifier StepSecurity assigns to the host.                         |
| **Agent Version**        | The version of the Harden-Runner agent installed on the host.            |
| **Updater Version**      | The version of the agent updater installed on the host.                  |
| **Last Heartbeat (GMT)** | When the host last reported in.                                          |
| **Platform**             | The host's operating system and architecture, for example `linux-amd64`. |

Each row offers these actions:

* **Update**: triggers an agent update on the host. This action is recorded in your audit logs.
* **History**: shows the host's update history.
* **Updater Logs**: downloads the updater logs for the host, which is the first place to look when an update has not applied.

**Follow this interactive demo to see how to enable runtime monitoring for your self hosted runners:**

{% embed url="<https://app.storylane.io/share/qi1xljlrdhw4>" %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.stepsecurity.io/github-actions/harden-runner/self-hosted-runners.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
