> 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/packages/secure-registry.md).

# Secure Registry

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

Secure Registry is an authenticated upstream registry that sits between your developers, CI runners, and the public package registries (npm and PyPI). Every metadata request and tarball download flows through Secure Registry, which evaluates it against your configured security controls before returning a response. Requests that violate a control are blocked or modified at install time, regardless of whether the install runs in CI or on a developer's laptop.

### How it compares to GitHub Checks

Secure Registry complements [Package Cooldown](/github/github-checks/configuration.md#package-cooldown) and [Package Compromised Updates](/github/github-checks/configuration.md#package-compromised-updates) in GitHub Checks. The two enforce at different points in the dependency lifecycle:

|                         | GitHub Checks                                 | Secure Registry                                                                         |
| ----------------------- | --------------------------------------------- | --------------------------------------------------------------------------------------- |
| **Enforcement point**   | Pull request                                  | Package install                                                                         |
| **What it sees**        | Manifest and lockfile changes in a PR         | Every install request from any configured client                                        |
| **Scope**               | Repositories under StepSecurity GitHub Checks | CI runners, developer machines, and artifact managers configured to use Secure Registry |
| **Result of violation** | PR check fails, blocking merge                | Request is blocked or the response is modified at install time                          |
| **Ecosystems**          | npm, PyPI                                     | npm, PyPI Beta                                                                          |

Using both gives you layered protection: PRs cannot introduce known-bad dependencies, and environments that bypass PR review (developer laptops, ad-hoc CI scripts, fresh clones with floating versions) cannot install them either.

### How it works

* **Step 1:** Configure your developers' package clients (npm or pip), CI runners, or your artifact repository manager (JFrog Artifactory, Google Artifact Registry) to use the Secure Registry URL as the upstream registry.
* **Step 2:** Every package request flows through Secure Registry, which evaluates it against the controls you have enabled for that ecosystem.
* **Step 3:** Each evaluation is recorded in the **Policy Evaluations** log and visible in your StepSecurity dashboard.

**Follow this interactive demo to see how it works:**

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

### Supported ecosystems

| Ecosystem | Status    |
| --------- | --------- |
| npm       | Available |
| PyPI      | Beta      |

### Security controls

Open the **Policy** tab and use the **Registry** selector to choose an ecosystem (**npm** or **PyPI**), then toggle each control on or off. Controls are configured independently per ecosystem, so your npm and PyPI policies can differ. Click **Save Changes** to apply.

#### Cooldown Period

Blocks packages published within a configurable number of days, giving the community and StepSecurity's SOC time to vet new releases before they reach your environment. Set the cooldown window in the **Period (days)** field; the default is 2.

Cooldown is the first line of defense against zero-day supply chain attacks. Most malicious packages are discovered within 24 hours of publication, so a multi-day cooldown shifts the discovery window outside your installation window.

**Exempted Packages**

Use the **Exempted Packages** field to allow specific packages or scopes to bypass the cooldown window. Type a pattern and press **Enter** to add it. Patterns are matched as regular expressions, so you can exempt a single version, an entire package, or a whole scope.

| Pattern       | What it exempts                 |
| ------------- | ------------------------------- |
| `react@2.3.4` | A single version of one package |
| `lodash@*`    | All versions of one package     |
| `@scope/*`    | All packages under a scope      |

Exempted packages still flow through Secure Registry and are evaluated by every other enabled control (for example, Compromised Packages). Only the cooldown check is skipped.

Use exemptions sparingly. Each exempted pattern is an explicit opt-out of the zero-day window, so reserve them for packages you have already vetted or that you control internally.

<figure><img src="/files/1MILbIaEwHidmh7arckD" alt=""><figcaption></figcaption></figure>

#### Compromised Packages

Blocks installs of package versions that StepSecurity's SOC or the broader security community has flagged as compromised or malicious. When this control is on, any request for a flagged version is blocked, and the evaluation is recorded in the Policy Evaluations log.

This control catches packages whose maintainer account was hijacked, packages that were published with embedded malware, and packages reported as malicious after publication. Unlike Cooldown, which buys time for the community to discover an attack, Compromised Packages enforces against attacks that have already been confirmed.

Compromised Packages is independent of the cooldown window: a flagged version is blocked whether or not it falls inside the cooldown period, and exempting a package from cooldown does **not** exempt it from this control.

#### Typosquatting Protection

{% hint style="info" %}
This control is coming soon.
{% endhint %}

Blocks packages whose names closely resemble popular packages, protecting against typosquatting attacks.

### Setting up Secure Registry

Open the **Setup Guide** tab in the Secure Registry page to see your credentials and integration instructions for both npm and Pypi.

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

The Setup Guide provides your credentials (Registry URL, Username, Primary and Secondary API Keys) and step-by-step instructions for three integration paths:

* **JFrog Artifactory**: for teams that already proxy npm through Artifactory.
* **Google Artifact Registry**: for teams using GAR as their npm proxy.
* **Direct npm (.npmrc)**: for teams without an artifact manager.

Pick the path that matches how packages reach your environment and follow the in-app instructions. The Setup Guide also includes a short test sequence to confirm requests are flowing through Secure Registry once you are configured.

{% hint style="info" %}
Primary and Secondary API keys are supported so you can rotate without downtime: issue the Secondary, switch clients over, then rotate the Primary.&#x20;
{% endhint %}

### Reviewing policy evaluations

The **Policy Evaluations** tab shows every package request (npm or PyPI) that flowed through Secure Registry, with the evaluation result for each enabled control.

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

#### Filters

Filters at the top of the page let you narrow the log:

* **Status**: filter by evaluation result (Allowed, Modified).
* **Ecosystem**: filter by npm or PyPI.
* **Type**: request type (Metadata, Tarball Download).
* **Package**: exact package name (e.g., `lodash`).
* **Versions**: comma-separated versions (e.g., `4.17.21,4.17.20`).
* **Date range**: narrow to a specific time window.

#### Statuses

| Status                    | Meaning                                                                                                                                                                                             |
| ------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Allowed**               | The request matched no blocking controls and was served as-is.                                                                                                                                      |
| **Modified**              | One or more controls filtered the response. Most commonly, Cooldown removed one or more recent versions before returning metadata, so the client sees only versions older than the cooldown window. |
| **Skipped** (per-control) | The control was not evaluated for this request, either because it is disabled in the Policy tab or because it is not yet available.                                                                 |

#### Request types

* **Metadata**: a request for package metadata (for example, `npm view`, or dependency resolution during install).
* **Tarball Download**: a request for the actual package tarball during install.

#### Per-control breakdown

Click any row to expand the per-control breakdown. For a **Modified** request, the breakdown shows which control modified the response and the reason (for example, "2 version(s) filtered by cooldown period").

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


---

# 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:

```
GET https://docs.stepsecurity.io/packages/secure-registry.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
