> For the complete documentation index, see [llms.txt](https://docs.sealsecurity.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.sealsecurity.io/setup-apps-os/cli-in-cicd/custom-artifact-server.md).

# Pulling sealed packages through your own registry

Pointing the Seal CLI at a registry you control, so sealed package downloads go through your own Nexus or Artifactory proxy repository.

By default `seal fix` downloads sealed packages straight from the Seal Artifact Server: `npm.sealsecurity.io` for npm-style ecosystems, `pypi.sealsecurity.io` for Python, `maven.sealsecurity.io` for JVM packages, and so on.

The `artifact-server-base-url` setting points the CLI at a registry you control instead. The usual shape is a Sonatype Nexus or JFrog Artifactory **proxy repository** whose upstream is the relevant Seal host. Your build hosts then only need to reach your own registry, and sealed artifacts get cached there like any other dependency.

```
seal fix  ──►  your proxy repository  ──►  npm / pypi / maven.sealsecurity.io
               (caches artifacts)          (upstream, authenticated)
```

The setting redirects **package downloads only**. The CLI's other traffic is unaffected and still reaches Seal directly: vulnerability lookups go to `cli.sealsecurity.io` and authentication goes to `authorization.sealsecurity.io`.

## When to use it

* Build hosts whose egress policy allows your internal registry but not Seal's hosts.
* You already proxy every other dependency through Nexus or Artifactory, and want sealed packages to travel the same path.
* You want sealed artifacts cached inside your own network, so repeated builds do not re-fetch them from Seal.

If the hosts cannot reach Seal at all, even through a proxy repository, this is not the right pattern. See [On-prem and air-gapped environments](/setup-apps-os/on-prem.md) instead.

## Configuration

Two settings, available in `.seal-config.yml` or as environment variables:

```yaml
# .seal-config.yml
project: my-project
artifact-server-base-url: https://nexus.internal:8081/repository/seal-npm-proxy
# only if your registry requires credentials
artifact-server-authorization-header: "Basic <base64-of-user:password>"
```

```bash
export SEAL_ARTIFACT_SERVER_BASE_URL="https://nexus.internal:8081/repository/seal-npm-proxy"
export SEAL_ARTIFACT_SERVER_AUTHORIZATION_HEADER="Basic <base64-of-user:password>"
```

When the override is in effect, `seal fix` prints the base URL it is using, so you can confirm the configuration was picked up:

```
using custom artifact server: https://nexus.internal:8081/repository/seal-npm-proxy
```

What to plan for before rolling this out:

| Behavior                                      | Detail                                                                                                                                                                                                                                                                                   |
| --------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| One URL, all ecosystems                       | A single value replaces the base URL for every ecosystem the CLI supports (npm, PyPI, NuGet, Maven, Go, Composer, RubyGems, RPM, Deb, APK). A run targets one manifest, so point it at the proxy repository for that project's ecosystem and set it per project or per pipeline.         |
| A path prefix is expected                     | Registries usually mount a repository under a path, such as Nexus's `/repository/<name>`. That is handled: the CLI joins package paths under the prefix, and does not duplicate it when your registry echoes a self-referencing URL back (for example, an npm package's `dist.tarball`). |
| Must be an absolute `http` or `https` URL     | Anything else is rejected at startup.                                                                                                                                                                                                                                                    |
| Not applied by `seal image fix`               | The `seal fix` invocation generated inside the image does not inherit either setting, so an image fix still downloads from the Seal Artifact Server.                                                                                                                                     |
| Cannot be combined with the JFrog integration | `artifact-server-base-url` and `jfrog.enabled` both redirect package downloads, so setting both is rejected at startup rather than one silently winning.                                                                                                                                 |

## Authentication

Two separate credentials are involved, and they do not travel together.

**The CLI to your registry.** If your registry requires credentials for reads, set `artifact-server-authorization-header`. Its value is sent verbatim as the `Authorization` header on every request to the configured base URL. Leave it unset for an anonymous-read repository, in which case the CLI sends no `Authorization` header at all. The setting is ignored when no base URL is configured.

Generate the value from your own registry credentials:

```bash
printf '%s' 'reader:<password>' | base64
```

**Your registry to Seal.** The proxy repository authenticates upstream to the Seal Artifact Server the same way any client does: HTTP Basic, with a [Project ID](/getting-started/creating-a-seal-project.md#project-id-and-project-name) as the username and a production [token](/getting-started/tokens.md) as the password. A proxy repository is shared by every build that pulls through it, so give it a Project ID of its own rather than reusing one project's.

Your Seal token is never sent to the configured registry. It is only valid on Seal's own hosts, so the CLI deliberately withholds it from a host you configure, and sends `artifact-server-authorization-header` there instead.

## Setting up the proxy repository

Create one proxy repository per ecosystem you want to serve, with the matching Seal host as its remote URL. [Configuring package managers](/setup-apps-os/artifact-server/configuring-package-managers.md) lists the host for each ecosystem, and [JFrog Artifactory: Seal as an additional remote](/integrations/artifactory.md) walks through the Artifactory side in full.

Two registry-side settings are worth calling out, because sealed versions carry a suffix such as `2.14.1+sp3` that some registries reject by default:

* **Maven**: set the repository's version policy to **Mixed** so `+spN` versions are not treated as snapshots, and its layout policy to **Permissive** so the `+spN` path segment is not rejected as a layout violation.
* **All ecosystems**: confirm sealed versions actually come through before pointing a build at the repository. For npm, `npm view <package> versions --registry <your-repo-url>` should list `-spN` entries alongside the origin versions.

## Troubleshooting

**`artifact-server-base-url must be an absolute http(s) URL`** The value has no scheme, no host, or a scheme other than `http` or `https`. A path prefix is fine; `nexus.internal:8081/repository/seal-npm-proxy` without `https://` is not.

**`artifact-server-base-url and jfrog.enabled both redirect package downloads - set only one`** Both settings override where sealed packages come from. Unset either `artifact-server-base-url` (`SEAL_ARTIFACT_SERVER_BASE_URL`) or `jfrog.enabled` (`SEAL_JFROG_ENABLED`). When moving a pipeline off the JFrog integration, drop the `jfrog` block in the same change that adds the base URL.

**Downloads stop after upstream errors** Nexus and Artifactory both auto-block a proxy repository after repeated upstream failures. Check the repository's health in your registry's UI, fix the upstream credential, then re-enable it.

## Related

* [Environment variables](/reference/cli/environment-variables.md): the full list of CLI settings, including these two.
* [Seal Apps via the Seal Artifact Server](/setup-apps-os/artifact-server.md): the deployment method where your package manager pulls from Seal directly, with no CLI step.
* [JFrog Artifactory: Seal as an additional remote](/integrations/artifactory.md): the Artifactory setup walkthrough.
* [On-prem and air-gapped environments](/setup-apps-os/on-prem.md): the pattern for hosts that cannot reach Seal at all.
