Repositories
Classes
| Class | What it does |
|---|---|
| Local | Stores what you deploy. |
| Remote | Proxies an upstream registry and caches what it fetches. |
| Virtual | Serves several repositories at one URL, resolving from its members in order. |
Create a repository in Repositories → New repository, or in YAML with relic apply -f
(see Resources). Relic stores each content once per SHA-256, so copies
and moves take no extra storage.
Remote repositories
A remote repository fetches a file from its upstream on first request and then serves it
from the cache. Metadata (npm packuments, PyPI pages, maven-metadata.xml) is fetched again
after the metadata cache period.
- Checksums. A fetched file must match the checksum its upstream publishes
(
X-Checksum-*headers, a Maven.sha1, npm'sdist.shasum, a PyPI#sha256=). A mismatch is not stored. Package managers get502; the Relic API answersunavailable(503over REST and on/api/v1/files/). - Missing files. An upstream
404or410is remembered for 30 minutes (Remember upstream misses;missedRetrievalCachePeriodSecsin the JFrog® Artifactory®-compatible API). 0 asks every time. - Failures.
429,502,503,504and dropped connections are tried three times, honouringRetry-After. DNS and certificate errors are not retried. Package managers get502and the Relic APIunavailable; the failure is not remembered. Relic's own failures answer500withCache-Control: no-store. - Cooldown. Cooldown (days) hides npm and PyPI versions published upstream more
recently than that, and refuses their files with
403. Other formats ignore it. - Version selection. npm packuments and PyPI pages leave out versions that are cooling
down, in the malicious package catalog, quarantined or blocked by a watch. npm's
latesttag moves to the newest version left. - One fetch. Concurrent requests for the same file fetch it once per replica.
In YAML, a remote repository's settings go under remote:
apiVersion: relic.build/v1
kind: Repository
metadata:
name: npm-remote
spec:
class: remote
format: npm
remote:
url: https://registry.npmjs.org
cooldownDays: 7
quarantine: true
| Form field | remote field | Effect |
|---|---|---|
| Upstream URL | url | The upstream registry. |
| Upstream username, Upstream password or token | username, password | Upstream credentials, never in the URL. The password is never shown again; an update without one keeps it while the URL's scheme, host and port stay the same. |
| Package index URL | indexUrl | The upstream's index when it is not at url (PyPI, a NuGet v3 feed). |
| Metadata cache (seconds) | cachePeriodSeconds | Default (0): 2 hours. |
| Upstream timeout (ms) | timeoutMilliseconds | Default (0): 15 seconds. |
| Remember upstream misses (seconds) | missedRetrievalCachePeriodSeconds | Default: 1800. |
| Cooldown (days) | cooldownDays | See Cooldown. |
| Quarantine | quarantine | Hold cached files until Relic Scan finds them not malicious or an administrator releases them. |
| Offline | offline | Serve only the cache; never contact the upstream. |
| Do not cache | disableCache | Fetch every download from the upstream and keep nothing. |
Virtual repositories
In YAML, a virtual repository's settings go under virtual:
apiVersion: relic.build/v1
kind: Repository
metadata:
name: npm
spec:
class: virtual
format: npm
virtual:
members: [npm-local, npm-remote]
deployTo: npm-local
localOnlyPatterns: ["@acme/*"]
| Form field | virtual field | Effect |
|---|---|---|
| Members, in resolution order | members | Repositories of the same format; Maven, Gradle, Ivy and sbt mix. A deleted repository leaves the virtual repositories it was in. |
| Default deployment repository | deployTo | The local member that receives uploads. Without one, uploads are refused. |
| Local-only names | localOnlyPatterns | See Dependency confusion. |
Dependency confusion
A public package named like an internal one can be installed through a virtual repository
that proxies the public registry. List internal names as Ant patterns under Local-only
names (localOnlyPatterns): @acme/* (npm scope), com/acme (Maven group), acme-* (PyPI),
github.com/acme/** (Go). Matching names resolve only from local members, never from a remote,
even in a nested virtual repository. Patterns are case-sensitive, except for PyPI, which
normalizes names (Acme_* equals acme-*).
Client URLs
relic package setup <client> <repository> writes these URLs into a client's configuration.
Set me up in the UI shows the configuration for the common clients and curl commands.
| Format | URL |
|---|---|
| npm, yarn, pnpm | https://relic.example.com/npm/<repo>/ |
| PyPI | https://relic.example.com/pypi/<repo>/simple |
| Maven, Gradle | https://relic.example.com/maven/<repo>, https://relic.example.com/gradle/<repo> |
| Go | https://relic.example.com/go/<repo> |
| NuGet | https://relic.example.com/nuget/<repo>/index.json (V2: https://relic.example.com/nuget/<repo>) |
| RubyGems | https://relic.example.com/gems/<repo>/ |
| Cargo | sparse+https://relic.example.com/cargo/<repo>/index/ |
| Conan | https://relic.example.com/conan/<repo> |
| Helm | https://relic.example.com/helm/<repo> |
| Terraform | https://relic.example.com/terraform/<repo>/providers/; modules as relic.example.com/<repo>__<namespace>/<name>/<provider> |
| Hugging Face | HF_ENDPOINT=https://relic.example.com/huggingface/<repo> |
| Nix | https://relic.example.com/nix/<repo> |
| Git LFS | lfs.url = https://relic.example.com/lfs/<repo> |
| Debian, Alpine | https://relic.example.com/debian/<repo>, https://relic.example.com/alpine/<repo> |
| RPM | https://relic.example.com/rpm/<repo> |
| Docker, OCI, Helm OCI | relic.example.com/<repo>/<image> |
Browsing
Find by name searches the whole repository. An item's tabs:
| Tab | Shows |
|---|---|
| General | Path, URL, checksums and downloads. |
| Properties | Editable properties. |
| Security, SBOM | Scan results. |
| Builds | Builds that produced or used the file. |
| Permissions | For administrators: who has which access, and which permission grants it. |
| Archive, View | Archive entries; text files. |
| Package tabs | npm, PyPI, Helm, Docker and Maven details. |
Limits
A local repository can limit what it accepts:
apiVersion: relic.build/v1
kind: Repository
metadata:
name: libs-local
spec:
class: local
format: maven
maxUploadSize: 1073741824 # 1 GiB
maxStorage: 536870912000 # 500 GiB
| Setting | Effect |
|---|---|
maxUploadSize | The largest file, in bytes; larger uploads fail with 413. RELIC_MAX_UPLOAD_SIZE sets a server-wide limit; the lower one applies. |
immutable | Refuse replacing a file with other content, so container tags cannot move. Re-uploading the same content succeeds. |
maxStorage | The quota in bytes. A deploy, copy or move past it fails with 413. A file in two repositories counts in both. relic get repository shows the current usedBytes. |
Cleanup policies
A cleanup policy moves old or unused items of local repositories to the trash can, daily.
Define policies on the Cleanup policies page or with relic apply:
apiVersion: relic.build/v1
kind: CleanupPolicy
metadata:
name: old-app-versions
spec:
enabled: true
repositories: [libs-local]
pathPattern: org/app/*
olderThanDays: 90
keepLatest: 5
| Setting | Effect |
|---|---|
repositories | The local repositories covered. |
pathPattern | Ant pattern of items to consider: org/app/* takes the version folders of org/app, **/*.tgz every tarball. Empty is **. A folder moves with its contents. |
olderThanDays | Only items created more than this many days ago. |
notDownloadedDays | Only items not downloaded for this many days, or never downloaded and older. |
keepLatest | Keep this many newest matched items per folder. |
A policy needs at least one of the last three. Files Relic generates, such as
maven-metadata.xml, and held items are never selected. A policy whose last repository is
deleted is disabled until it names one again.
Preview what a policy selects, limited to what you may read:
relic cleanup preview old-app-versions
Run it now:
relic cleanup run old-app-versions
Legal holds
A held item, or folder with its contents, cannot be deleted, moved, overwritten or cleaned up, and its repository cannot be deleted. Administrators place and release holds.
Place a hold:
relic hold add libs-local/org/app/1.4.0 --reason "audit 2026-14"
List the holds:
relic hold list
Release a hold:
relic hold remove libs-local/org/app/1.4.0
Trash can
A deleted item moves to the auto-trashcan repository for 14 days (RELIC_TRASH_RETENTION).
Administrators restore or purge it in Administration → Trash can or the Relic API.
Deleting a whole repository is permanent.
A folder with more than 100 items moves in several transactions of up to 100 items each, so other uploads and deletes go through while it moves. It shows up as a trash entry once all of it has moved. If the delete fails partway, the files already moved stay in the trash repository and the rest stays in place; deleting the folder again finishes the move.
List the newest 50 entries and the total:
relic api trash
List the next 50:
relic api 'trash?page=2'
Restore one item:
relic api /api/relic.v1.TrashService/RestoreTrash -d '{"path": "libs-local/org/app/1.0/app-1.0.jar"}'
A restore fails if a file has since been deployed at the same path. Delete that file first,
or restore elsewhere with toRepository and toPath.
Empty the trash can:
relic api /api/relic.v1.TrashService/EmptyTrash -d '{}'
Replication
Replication pushes a local repository to another server, pulls from one, or keeps two in
sync (federated). It runs on a schedule; push with onChange and federated replication also
run after each change. Configure it in Administration → Replication or with a
Replication resource (see Replication).