Integrate with repository managers
Deploy the firewall together with Artifactory, Nexus, GitLab, GitHub Packages, Azure Artifacts, or AWS CodeArtifact, between them and the public registries, between developers and them, or on both sides.
The Dependency Firewall speaks the standard registry protocols on both sides. To a repository manager it looks like a registry; to a public registry it looks like an ordinary client, no different from npm, mvn, pip, dotnet, go, or conda. That makes it compatible with any repository manager that does not lock you into its own ecosystem: if the manager lets you configure your own upstream registry URLs, it can fetch through the firewall, and any manager can serve as a package source behind the firewall.
This page covers the three integration methods and how the major repository managers fit each one.
Integration methods
Firewall as the manager's upstream
The repository manager fronts developers and CI: they keep their existing repository manager URL, and the firewall is the manager's upstream. The manager's remote (proxy) repository points at the firewall instead of the public registry, so everything the manager pulls from outside passes firewall policy first.
manager's remote upstream
Choose this when the repository manager is entrenched and you cannot change client configuration. Two tradeoffs to accept:
- Identity is aggregated. Every request reaches the firewall as the repository manager's service account, so firewall logs show one user for all traffic. Per-developer attribution stays in the repository manager's own logs.
- The manager's cache answers before the firewall. Once the manager has cached a package, repeat installs are served from that cache without a firewall check, so new or tightened rules do not retroactively apply to already-cached packages. Keep proxy cache retention short for metadata, or accept that policy applies at first fetch.
On the firewall side the repository manager is just another client. Point the remote repository at the ecosystem endpoint, for example https://eu-sov-1.bytesafecloud.eu/v1/<namespace-id>/npm/<firewall-id>/, and authenticate with a Service Access Token. The firewall accepts the token as basic auth (any username, token as the password) or as a bearer header, which covers how repository managers send remote-repository credentials.
Manager as a firewall upstream
The firewall fronts developers and CI: they point at the firewall, and the repository manager is a firewall upstream, typically via its virtual, group, or feed URL, so internal packages and the manager's cache stay available behind firewall policy. Firewall rules are enforced either way; the two methods differ in who fronts the clients and therefore where identity and caching live.
policy on every request
Choose this when you want firewall policy, logs, and per-developer identity on every install, while keeping the repository manager as the package source. Client setup is the standard ecosystem setup; the repository manager side is one upstream entry:
{
"id": "e2de947a",
"endpoint": "https://acme.jfrog.io/artifactory/api/npm/npm-virtual",
"credentials": { "token": "<set via dashboard or bsfw config credentials>" },
"internal": true,
"cached": false
}Mark the upstream internal if the manager hosts your own packages; that activates the dependency confusion defense for those names.
The firewall authenticates upstream fetches with whichever credential fields the upstream has: a token is sent as Authorization: Bearer, and username/password are sent as basic auth when no token is set (Azure Artifacts endpoints additionally receive a token as basic auth, which is what Azure expects). That covers both auth styles repository managers use for reads: bearer-token registries get the token, and managers that authenticate reads with basic auth, such as Nexus user tokens or GitHub Packages PATs, get their credential as username and password.
Firewall on both sides
An advanced setup with two separate firewalls:
- a client-facing firewall between developers and the repository manager, enforcing install policy, identity, and logging,
- an egress firewall between the repository manager and public registries, controlling what may enter from outside.
Rules of the road:
- Use two firewall configurations, one per role. The client-facing firewall enforces install policy (delays, vulnerability thresholds, exceptions); the egress firewall enforces outbound policy (which registries, which packages may enter the building at all).
- Avoid loops. The egress firewall's upstream is the public registry, never the repository manager. The client-facing firewall's upstream is the repository manager. Every hop points strictly toward the public registry.
- The repository manager typically needs separate repositories for internal packages (hosted) and external packages (remote via the egress firewall), aggregated by a virtual or group repository.
This method is the first two running at once, so it works wherever both do.
Repository managers
How each manager fits the integration methods, per ecosystem, with the vendor's own documentation linked. Where a method does not work, the constraint is the named product's, stated in the notes. Conda support on the firewall side is in beta; see the Conda ecosystem page.
Two HTTP authentication styles come up in every section:
- Basic auth: the client sends a username and password with each request.
- Bearer auth: the client sends a token in the
Authorization: Bearerheader.
The firewall speaks both on both sides. It accepts either style when it receives requests (firewall as upstream). When it fetches from an upstream (manager as upstream), the upstream's credential fields decide the style: a token is sent as a bearer header, a username and password as basic auth. So the manager-as-upstream question is only which credential the vendor gives you, not whether the auth styles line up. The "yes" cells below follow the vendor's documented auth combined with this fetch behavior; not every combination has been validated against a live vendor instance.
JFrog Artifactory
Artifactory is JFrog's repository manager, self-hosted or cloud. A remote repository proxies an external registry and caches what it fetches; a virtual repository bundles several repositories behind one client URL. Remote repositories accept any upstream URL, and access tokens work both as bearer tokens and as basic-auth passwords, which makes Artifactory the strongest fit for every method.
- Firewall as upstream: the repository manager fronts clients and fetches external packages through the firewall.
- Manager as upstream: the firewall fronts clients and fetches from the repository manager.
Details in Integration methods.
Firewall as upstream: create a remote repository per ecosystem with the firewall endpoint as the URL and a Service Access Token as the password (any username works).
Manager as upstream: add the virtual repository URL as a firewall upstream with an access token. To keep the token read-only, issue it for a user or group that only has read permission; tokens created with expiry 0 never expire.
| Ecosystem | Firewall as upstream | Manager as upstream | Artifactory docs |
|---|---|---|---|
| npm | yes | yes | npm repositories |
| Maven | yes | yes | Maven repositories |
| NuGet | yes | yes | NuGet repositories |
| PyPI | yes | yes | PyPI repositories |
| Go | yes | yes | Go registries |
| Conda | yes | yes | Conda repositories |
See also: remote repositories, virtual repositories, access tokens.
Sonatype Nexus Repository
Nexus Repository is Sonatype's self-hosted repository manager. A proxy repository fetches from an external registry and caches the result; a group repository bundles several repositories behind one client URL.
- Firewall as upstream: the repository manager fronts clients and fetches external packages through the firewall.
- Manager as upstream: the firewall fronts clients and fetches from the repository manager.
Details in Integration methods.
Firewall as upstream: works for every ecosystem. Proxy repositories accept any upstream URL and authenticate outbound with a username and password: set any username and the firewall Service Access Token as the password.
Manager as upstream: works for every ecosystem. Nexus authenticates reads with basic auth: create a user token for a read-only account and store its name and passcode as the upstream's username and password. For npm you can alternatively enable the npm Bearer Token Realm and store an npm login token as the upstream's token; for Maven, PyPI, NuGet, Go, and Conda, Nexus has no bearer realms, so the user-token pair is the way. One Conda version note: proxy repositories exist in all supported Nexus versions, but hosted and group Conda repositories need Nexus 3.92 or later.
| Ecosystem | Firewall as upstream | Manager as upstream | Nexus docs |
|---|---|---|---|
| npm | yes | yes, user token as username/password, or npm Bearer Token Realm | npm registry |
| Maven | yes | yes, user token as username/password | Maven repositories |
| NuGet | yes | yes, user token as username/password | NuGet repositories |
| PyPI | yes | yes, user token as username/password | PyPI repositories |
| Go | yes | yes, user token as username/password | Go repositories |
| Conda | yes | yes, user token as username/password | Conda repositories |
See also: repository types, proxy outbound HTTP settings, realms, user tokens.
GitLab package registry
The package registry is built into GitLab: projects and groups host their own packages. It is a hosting service first; it has no general proxy repository.
- Firewall as upstream: the repository manager fronts clients and fetches external packages through the firewall.
- Manager as upstream: the firewall fronts clients and fetches from the repository manager.
Details in Integration methods.
Firewall as upstream: no for the standard package registry, with one Maven exception. The only outbound mechanism is request forwarding: when a package is not in your GitLab registry, GitLab asks the package manager's official public registry (npmjs.com for npm, pypi.org for PyPI, Maven Central for Maven). That target is hardcoded per format; you cannot point it at another URL, so it cannot go through the firewall. The exception is the Maven virtual registry (beta), which does accept custom upstream URLs with a username and password: point it at the firewall's Maven endpoint with a Service Access Token as the password.
Manager as upstream: works for npm, Maven, NuGet, and PyPI. GitLab's npm endpoint accepts tokens the way npm sends them, as a bearer header, so store the token as the upstream's token. The other formats authenticate reads with basic auth: store a deploy token's username and the token value as the upstream's username and password.
| Ecosystem | Firewall as upstream | Manager as upstream | GitLab docs |
|---|---|---|---|
| npm | no, forwarding targets are fixed | yes, token as token | npm registry |
| Maven | yes, via virtual registry (beta) | yes, deploy token as username/password | Maven virtual registry, Maven repository |
| NuGet | no, no forwarding | yes, deploy token as username/password | NuGet repository |
| PyPI | no, forwarding targets are fixed | yes, deploy token as username/password | PyPI repository |
| Go | no | no | supported functionality |
| Conda | not offered by the package registry | not offered | supported functionality |
Tokens for the manager-as-upstream method: a group deploy token or group access token with read_package_registry.
GitHub Packages
GitHub Packages is GitHub's package hosting service, tied to repositories and organizations (npm, Maven/Gradle, NuGet, RubyGems, containers; no PyPI, Go modules, or Conda). The credential for every format is a classic personal access token (PAT) with read:packages, best created on a machine user; GitHub states "GitHub Packages only supports authentication using a personal access token (classic)". The per-format question is only how the PAT is sent.
- Firewall as upstream: the repository manager fronts clients and fetches external packages through the firewall.
- Manager as upstream: the firewall fronts clients and fetches from the repository manager.
Details in Integration methods.
Firewall as upstream: does not apply. GitHub Packages does not proxy custom upstreams.
Manager as upstream: works for npm, Maven, and NuGet. For npm, bearer auth is what GitHub documents for npm installs, so store the PAT as the upstream's token. For Maven and NuGet, GitHub documents the PAT as a basic-auth password (settings.xml, Gradle credentials block, nuget.config): store the GitHub username and the PAT as the upstream's username and password.
| Ecosystem | Firewall as upstream | Manager as upstream | GitHub docs |
|---|---|---|---|
| npm | no, hosting only | yes, PAT as token | npm registry |
| Maven | no, hosting only | yes, PAT as basic-auth password | Maven registry |
| NuGet | no, hosting only | yes, PAT as basic-auth password | NuGet registry |
| PyPI | not offered by GitHub Packages | not offered | introduction |
| Go | not offered by GitHub Packages | not offered | introduction |
| Conda | not offered by GitHub Packages | not offered | introduction |
See also: permissions.
Azure Artifacts
Azure Artifacts is the package service in Azure DevOps. A feed hosts your packages and can pull missing packages from upstream sources.
- Firewall as upstream: the repository manager fronts clients and fetches external packages through the firewall.
- Manager as upstream: the firewall fronts clients and fetches from the repository manager.
Details in Integration methods.
Firewall as upstream: npm only. Custom upstream URLs are limited to npm: the upstream sources documentation states "Custom upstream sources are only supported for npm packages." Feeds for other protocols can only use the built-in public registries and other Azure feeds as upstreams, so they cannot point at the firewall.
Manager as upstream: works across Azure's protocols. The firewall detects pkgs.dev.azure.com endpoints and sends the credential as basic auth automatically, which is what Azure feeds expect. Use a PAT with Packaging: Read; the maximum lifetime is one year, organization policy may enforce shorter, so plan rotation.
| Ecosystem | Firewall as upstream | Manager as upstream | Azure docs |
|---|---|---|---|
| npm | yes, custom upstream | yes | npmrc setup |
| Maven | no, custom upstreams are npm-only | yes | upstream sources |
| NuGet | no, custom upstreams are npm-only | yes | NuGet with Visual Studio |
| PyPI | no, custom upstreams are npm-only | yes | upstream sources |
| Go | not offered by Azure Artifacts | not offered | Azure Artifacts overview |
| Conda | not offered by Azure Artifacts | not offered | Azure Artifacts overview |
See also: set up upstream sources, feed permissions, personal access tokens.
AWS CodeArtifact
CodeArtifact is AWS's managed package repository. Repositories can chain to other CodeArtifact repositories as upstreams, and public packages enter through an external connection.
- Firewall as upstream: the repository manager fronts clients and fetches external packages through the firewall.
- Manager as upstream: the firewall fronts clients and fetches from the repository manager.
Details in Integration methods.
Firewall as upstream: does not apply; an AWS design constraint, not a protocol incompatibility. External connections are a fixed list of public registries (npmjs, Maven Central, NuGet Gallery, PyPI, RubyGems, crates.io, and a few Maven variants; one per repository), and upstream repositories must be other CodeArtifact repositories. There is no field for a custom registry URL on either mechanism.
Manager as upstream: works across CodeArtifact's formats. For npm, npm auth uses _authToken, the same bearer header the firewall sends for a token. For Maven, NuGet, PyPI, and Go, AWS documents the authorization token as a basic-auth password with username aws (settings.xml with username aws, pip URL-embedded credentials): store aws as the upstream's username and the token as the password. In every case CodeArtifact authorization tokens expire after at most 12 hours, so stored credentials need scheduled rotation: push a fresh token with bsfw config credentials on a schedule, or keep tokens out of the firewall with the credential envelope.
| Ecosystem | Firewall as upstream | Manager as upstream | AWS docs |
|---|---|---|---|
| npm | no, external connections are a fixed list | yes, token as token, with rotation | npm auth |
| Maven | no, external connections are a fixed list | yes, aws + token as username/password, with rotation | Maven |
| NuGet | no, external connections are a fixed list | yes, aws + token as username/password, with rotation | NuGet |
| PyPI | no, external connections are a fixed list | yes, aws + token as username/password, with rotation | pip |
| Go | no, external connections are a fixed list | yes, aws + token as username/password, with rotation | upstream repositories |
| Conda | not offered by CodeArtifact | not offered | CodeArtifact concepts |
See also: external connections, tokens and authentication.
Other repository managers
The same two questions decide the fit for any other repository manager:
- Firewall as upstream: can it proxy a custom upstream registry URL with credentials? If yes, point that at the firewall endpoint with a Service Access Token; the firewall accepts basic auth and bearer tokens.
- Manager as upstream: does it serve reads to a client presenting a bearer token or basic-auth credentials (or allow anonymous reads)? If yes, add it as a firewall upstream with the matching credential: a token for bearer, a username and password for basic auth.
From the manager's perspective the firewall is a standard registry; from the firewall's perspective the manager is a standard upstream. There is nothing vendor-specific on the Bytesafe side.
Credentials
Repository manager to firewall (firewall as upstream)
The repository manager is the client here and the firewall is its upstream, so the credential lives in the manager's remote-repository settings. Create a Service Access Token for the repository manager; it is a service, not a person. In the manager's remote-repository credential fields, set any username (the token name is a good convention) and the token as the password. The firewall reads the token from the basic-auth password, from the username field if the password is empty, or from a Bearer header; whichever the manager sends works.
Firewall to repository manager (manager as upstream)
The firewall is the client here and the repository manager is the firewall's upstream, so the credential lives in the firewall's upstream config. Create a read-only credential on the manager's side and store it in the upstream's credential fields (dashboard, or bsfw config credentials). Which field decides the auth style the firewall sends: token goes out as a bearer header, username and password as basic auth.
| Vendor | Credential to create | Store as | Minimum scope | Expiry |
|---|---|---|---|---|
| Artifactory | Access token for a service user | token, or username/password | Read permission target on the repository or virtual repository | Configurable, non-expiring supported |
| Nexus | User token (all formats); npm alternatively an npm login token via the npm Bearer Token Realm | Username/password (user token name and passcode); npm login token as token | Repository-view read privilege | Valid until reset |
| GitLab | Group deploy token or group access token | npm: token. Maven, NuGet, PyPI: username/password | read_package_registry | Deploy tokens: optional. Access tokens: max 1 year |
| GitHub Packages | Classic PAT on a machine user | npm: token. Maven, NuGet: username (account) and PAT as password | read:packages | Optional, org policy may force one |
| Azure Artifacts | PAT | token (sent as basic auth automatically on pkgs.dev.azure.com) | Packaging: Read | Max 1 year; rotation needed |
| AWS CodeArtifact | aws codeartifact get-authorization-token | npm: token. Maven, NuGet, PyPI, Go: username aws and token as password | codeartifact:ReadFromRepository plus token issuance permissions | 15 minutes to 12 hours; rotation required |
Wrong or expired upstream credentials do not produce install errors; the upstream is skipped and its packages appear missing. See Manage upstream credentials.
Prevent bypass
Whichever method you run, the policy is only as good as the weakest path to a public registry:
- Firewall as upstream: remove or disable remote repositories that still point directly at public registries, and remove them from virtual/group repository member lists. A virtual repository that aggregates both the firewall-backed remote and a direct public remote silently bypasses policy for whatever the direct remote answers first.
- Manager as upstream: enforce the firewall endpoint in committed client config and CI images, the same as plain firewall setups; see the ecosystem pattern.
- Firewall on both sides: the repository manager host should only be able to reach public registries through the egress firewall; enforce with network egress rules, not just configuration.
Verify
Install a package through the full chain, then confirm the firewall saw it:
bsfw logs --firewall <firewall-id> --all-usersWith the firewall as the manager's upstream, the log entry's user is the repository manager's Service Access Token. With the manager as a firewall upstream, check that the entry's upstream field contains the repository manager upstream ID. Then verify a block: add a rule that blocks a test package and confirm the install fails through the whole chain, not just against the firewall directly.
Troubleshoot
The firewall skips upstreams that reject its credentials, so auth failures look like missing packages. Check that the credential sits in the right upstream field for the format (see the per-vendor tables above: token is sent as a bearer header, username/password as basic auth, and the token wins when both are set) and that it has read scope on the exact repository or feed the endpoint URL names. Test the URL from outside the firewall with the same style: curl -H "Authorization: Bearer $TOKEN" for a token, curl -u "$USER:$PASSWORD" for basic auth.
When the repository manager fronts clients (firewall as upstream), suspect the manager's cache (the package was fetched before the rule existed) or a virtual/group repository that still contains a direct public remote. Clear the manager's cache for that package and audit the repository member list.
Some path points back at itself: a firewall upstream naming a manager repository whose remote is that same firewall, or an egress firewall with the manager as upstream. Draw the chain; every hop must point strictly toward the public registry.
Expected when the firewall is the manager's upstream: the repository manager is the client, so its Service Access Token is the user on every entry. If you need per-developer identity in firewall logs, put the firewall in front of developers instead (manager as upstream, or firewall on both sides).