> 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/actions-secret.md).

# Actions Secret

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

The Action Secrets section in StepSecurity allows you to monitor, manage, and track GitHub Actions secrets across an entire organization, within specific repositories, and within repository deployment environments.

This helps ensure secure storage and proper usage of sensitive information, such as API keys, tokens, and credentials used within workflows.

To access these features, open your StepSecurity dashboard and navigate to the Action Secrets section.&#x20;

The page has three tabs: **Organization Secrets**, **Repository Secrets**, and **Environment Secrets**.

{% hint style="info" %}
StepSecurity reads secret names and dates only. It never reads secret values.
{% endhint %}

### Organization Secrets

* Provides a centralized view of all secrets used across repositories.
* Tracks the last rotation date of secrets, helping enforce regular updates for security.

<figure><img src="https://754495266-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FQJRZY4cfEeY3I7DXTOCp%2Fuploads%2F3APmXeF9DOpHjFxx2er1%2FScreenshot%202026-11-04%20at%2009.53.34.png?alt=media&amp;token=e9ca3567-148f-4ab9-98ce-d4624768c54e" alt=""><figcaption></figcaption></figure>

### Repository Secrets

The Repository Secrets tab lists secrets specific to individual repositories, along with rotation age, usage status, and OIDC replaceability.

<figure><img src="https://754495266-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FQJRZY4cfEeY3I7DXTOCp%2Fuploads%2FM1YgWMl78ZEfyk4U7YBQ%2FScreenshot%202026-11-04%20at%2009.53.44.png?alt=media&amp;token=0823bb1b-b61c-44fe-a107-1eab80e5974d" alt=""><figcaption></figcaption></figure>

#### Summary cards

At the top of the tab, summary cards give you an at-a-glance view of your cleanup opportunities:

* **Total Secrets**: every repository secret across the organization.
* **Unused Secrets**: secrets no workflow references. Strong candidates for removal.
* **Stale Secrets**: secrets whose referencing workflows have not run in over 90 days.
* **OIDC Replaceable**: secrets that could be replaced with OpenID Connect (OIDC) authentication, eliminating the need to store the secret at all.

### Environment Secrets

The Environment Secrets tab lists secrets configured on repository deployment environments (in GitHub, a repository's **Settings** > **Environments**). Each environment holds its own copy of a secret, so a secret with the same name in two environments appears as two separate rows.

<figure><img src="https://754495266-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FQJRZY4cfEeY3I7DXTOCp%2Fuploads%2FmJlDNPypTvEqcQgJJ9r3%2FScreenshot%202026-11-04%20at%2009.53.54.png?alt=media&amp;token=b2a9d302-f80c-4e60-be1f-c4607b6d8c90" alt=""><figcaption></figcaption></figure>

Each row shows:

* **Repository and Environment:** the repository and the environment that holds the secret. A lock icon next to the environment means the environment is protected. Hover over the icon to see its protection rules: required reviewers, a wait timer, or a deployment branch policy (protected branches only, or selected branches only).
* **Secret Name:** the name of the secret, linking to the repository's environment settings in GitHub.
* **Days since last rotated, Usage Status, Used in Workflows, and OIDC:** these columns work the same way as on the Repository Secrets tab. See Secret usage and OIDC.

The summary cards at the top of the tab (**Total Secrets**, **Unused Secrets**, **Stale Secrets**, and **OIDC Replaceable**) count environment secrets only.

#### **Required permission**

To list environment secrets, the StepSecurity GitHub App needs the **Environments: Read** permission. This permission gives access to environment names and protection settings, and to the names and dates of environment secrets. It never gives access to secret values.

**GitHub.com:** New installations include the permission. For an existing installation, an organization owner approves the app's permission request in GitHub. Go to the organization's **Settings** > **GitHub Apps**, select the StepSecurity app, and then select **Review request**.

**GitHub Enterprise Server (GHES):** Apps deployed from the Admin Console after this release onward include the permission. Apps deployed earlier do not receive it automatically. To add it:

1. A GHES administrator opens the StepSecurity app's settings, sets **Repository permissions** > **Environments** to **Read-only**, and saves the change.
2. An organization owner accepts the permission request in the organization's **Settings** > **GitHub Apps**.

Environment secrets appear after the next scan once the permission is granted. Until then, the Environment Secrets tab shows **No environment secrets found**, with a message explaining that an organization owner may need to approve the permission request. The Organization Secrets and Repository Secrets tabs are not affected.

#### **Rotation**

Environment secrets are included in the Secrets should be rotated periodically control, with the same 180-day threshold as organization and repository secrets. Each environment's copy of a secret is checked separately.

### Secret usage and OIDC

This section explains how StepSecurity determines the **Usage Status**, **Used in Workflows**, and **OIDC** values for each secret.

#### **Which secret a workflow receives**

When a job runs in an environment, GitHub gives the job that environment's secret if one exists with the requested name. Otherwise, GitHub falls back to the repository secret, and then to the organization secret. StepSecurity follows the same order when it decides which secret a workflow uses:

* **Job in an environment that defines the secret:** the job uses the **environment** secret.
* **Job with no environment, or in an environment that does not define the secret:** the job uses the **repository** secret, or the **organization** secret if there is no repository secret.
* **Repository secret referenced only by jobs whose environments define the same name:** the repository secret is never used. It shows as `Unused`, with an **Overridden in** note listing those environments.
* **Job whose environment is an expression, such as `environment: ${{ inputs.env }}`:** the job could receive any of these secrets. These uses are shown as `Possible`.

#### Usage status

Each secret is assigned one of five statuses:

| Status     | Meaning                                                                                                                                                                                                                         |
| ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Active`   | The secret is referenced by at least one workflow, and one of those workflows ran within the last 90 days.                                                                                                                      |
| `Stale`    | The secret is referenced by a workflow, but none of the referencing workflows have run in the last 90 days. The secret may be a leftover from a retired pipeline.                                                               |
| `Unused`   | No workflow in the analyzed repositories references the secret. It is a strong candidate for removal.                                                                                                                           |
| `Unknown`  | The repositories that could use this secret have not been analyzed for secret references yet, so usage cannot be determined. This clears automatically once analysis runs.                                                      |
| `Possible` | The secret is used only by jobs that choose their environment at run time, so a workflow may receive this secret or a same-named secret from another scope. Check how the environment is chosen before deleting or rotating it. |

The 90-day window is based on the most recent run of any workflow that references the secret. The last run time of each referencing workflow is shown in the **Used in Workflows** column. Usage and last run times update when a repository is scanned, which can take up to a day after a workflow runs. the most recent of these is the secret's effective last-used time.

{% hint style="info" %}
The `Unused` status considers only the workflows that StepSecurity has analyzed. A secret consumed outside of GitHub Actions (for example, by an external system reading it through the API) is not counted as a workflow reference
{% endhint %}

#### Where each secret is used

For every secret, the dashboard lists the workflows that reference it. Expand a secret row to see the full list of referencing workflows, each with:

* The repository and workflow file where the reference was found.
* If the reference is inside a reusable workflow, the card also names that reusable workflow.
* The Action (`uses:` value) of the step that consumes the secret, so you can see exactly which Action reads a given secret.
* Actions pinned to a full-length commit SHA (Secure Hash Algorithm) are shown with the first 7 characters of the SHA. Hover over the step to see the full reference.
* The last run of that workflow, including its conclusion and a link to the run on GitHub.

<figure><img src="https://754495266-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FQJRZY4cfEeY3I7DXTOCp%2Fuploads%2FJXz2IRrIWJ0TazlYkRen%2FScreenshot%202026-11-04%20at%2010.07.00.png?alt=media&amp;token=b8ef1873-3de2-4f7b-9178-7fb8091503da" alt=""><figcaption></figcaption></figure>

* A workflow marked **Environment chosen at run time** selects its environment with an expression. This is why the secret it uses shows as `Possible`.

#### How references are detected

StepSecurity analyzes your workflow YAML to find every way a secret can be read:

* Direct references such as `secrets.NPM_TOKEN`.
* Bracket references such as `secrets['NPM_TOKEN']`.
* Bulk references such as `toJSON(secrets)` and dynamic lookups such as `secrets[matrix.environment]`. These expose every secret in scope, so they are attributed to all secrets the workflow can access.

The analysis also follows reusable workflow calls made with `secrets: inherit`, so a secret used only inside a called workflow is still attributed correctly. References to the automatically provided `GITHUB_TOKEN` are excluded, since it is not a configured secret.

For each reference, StepSecurity also records the environment of the job that uses it, either a fixed environment name or an expression chosen at run time. For reusable workflows called with `secrets: inherit`, the environment of the called job is used.

#### OIDC recommendations

Static, long-lived secrets such as cloud credentials and registry tokens are a common source of supply chain risk. Many of them can be replaced with OIDC, where GitHub issues a short-lived token for each workflow run and no static secret is stored at all.

The dashboard flags a secret as **OIDC Available** when either of the following is true:

* The secret is passed to an Action that supports OIDC federation:
  * `aws-actions/configure-aws-credentials` (AWS)
  * `google-github-actions/auth` (GCP)
  * `azure/login` (Azure)
* The secret's name identifies a registry publishing token that supports OIDC trusted publishing, such as an npm token or a PyPI token.

When a secret is OIDC Available, the badge also shows the provider (for example, `OIDC Available · AWS`). Secrets that are referenced but have no OIDC-based alternative are marked `Not Applicable`, and unreferenced secrets show no OIDC signal.

OIDC availability is decided separately for each secret, using only the steps that receive that secret. For example, if the `production` environment passes `TOKEN` to `aws-actions/configure-aws-credentials` and the `staging` environment passes its own `TOKEN` to a different Action, only the production `TOKEN` is marked OIDC Available.

#### Filtering

Use the controls above the table to narrow down the list:

* **Search**: Filter by repository or secret name.
* **Environment:** On the Environment Secrets tab, show one environment or all environments.
* **Status filter:** Filter secrets by usage status: `Active`, `Stale`, `Unused`, `Possible`, or `Unknown`.
* **OIDC available**: Show only secrets that can be replaced with OIDC.

### Acting on the results

A typical cleanup pass looks like this:

1. Start with `Unused` secrets. Confirm they are not needed outside of Actions, then delete them.
2. Review repository secrets with an **Overridden in** note. Every job that references the secret runs in an environment that has its own copy, so those jobs always receive the environment secret. The repository secret can usually be deleted.
3. Review `Stale` secrets. If the pipeline that used them is retired, remove the secret. If it is still needed, rotate it.
4. Before deleting or rotating a `Possible` secret, check which environments the workflow's run-time expression can choose, and confirm which copy each environment receives.
5. Work through the OIDC Replaceable list. Migrate cloud credentials and publishing tokens to OIDC, then delete the static secret once the workflow is verified.

This turns the secrets inventory from a static list into an actionable checklist for reducing your standing credential footprint.

### API and MCP

Environment secrets are also available through the StepSecurity API and the [StepSecurity MCP](/administration/admin-console/integrations/stepsecurity-mcp-server.md) (Model Context Protocol) server. For request and response details, see the [API reference](/workspace/settings/stepsecurity-api-org-access.md#api-reference) tab under **Settings** > **StepSecurity API**.

* **Secrets inventory API:** returns environment secrets with `SecretType` set to `EnvironmentSecret`, and these additional fields: `Environment`, `EnvironmentProtectionRules`, and `EnvironmentDeploymentBranchPolicy`. Each workflow usage can include `Environments` and `IsPossible`, and `UsageStatus` can be `Possible`.
* **Environments permission status:** `GET https://agent.api.stepsecurity.io/v1/github/{owner}/actions/secrets/environments-status` returns whether the Environments permission is granted, with `permission` (`granted`, `missing`, or `unknown`), `permissionCheckedAt`, and `lastScannedAt`.
* **MCP:** the `list_actions_secrets` tool returns environment secrets too. If the Environments permission is not granted, an empty set of environment secrets in the result does not mean that none exist. Check the permission status first.


---

# 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 by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.stepsecurity.io/github-actions/actions-secret.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

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.
