Operations
The Operations section is where a deployment's administrators see what the server is doing and change how it runs in the background. Its pages - Metrics, Security posture, Caches and Walks - are for the deployment's administrators. Two pages of each repository belong here too, for anyone with the admin role there: Deploy, once switched on, and Export, which takes a repository's contents out to another repository, as Migrating in and out describes. Beside them this chapter covers what a monitoring system reads over HTTP, webhooks, and the rate limit.
Caches
Caches lists the read caches of the server that renders the page - each one's time to live, how often it answered and how much it holds - and Clear caches on this node empties them. The clear also tells every other server of the deployment to read credentials afresh, so a revoked key another server still remembers stops working there too; the other caches on those servers expire on their own time to live.
Metrics
Metrics lists what every installed module reports about itself: counters, gauges, health checks and the state of each background task, each with its current value and a line saying what it measures. A module that is not installed, or is switched off, reports nothing, so the page shows what this deployment is actually doing - how full the storage quota is, how often the proxy cache answered locally, when the collector last ran.
Security posture
Security posture lists every configuration choice that makes the deployment less safe than it could be, most severe first - running without keys, a gate that admits known malware, no rate limit. Each entry says why it matters and which setting changes it. A clean deployment lists nothing, which is the healthy state, and the count shown in the header is the length of this list.
Observing the posture never changes it: the page is read-only, and it names the setting at fault and the value that fixes it, never a secret the deployment holds. Each entry links here, to its own line of this table:
| Advisory | Severity | Raised when |
|---|---|---|
jenrepo. |
critical | JENREPO_ - every request is served without a key, writes included. |
jenrepo. |
critical | The dev profile is active, so the console runs its local-only sign-in. |
jenrepo. |
critical | anonymous-rights lets a caller without a key write or administer. |
jenrepo. |
critical | malware-action is ALLOW for a tenant, so a package known to be malicious is admitted. |
jenrepo. |
critical | One server of several runs with different settings or tenants from the others. |
jenrepo. |
critical | Two servers answer the same path with different content. |
jenrepo. |
warning | anonymous-rights lets a caller without a key read - right for a public mirror, and worth knowing otherwise. |
jenrepo. |
warning | vulnerability-action is ALLOW for a tenant, so an artifact over the threshold is served. |
jenrepo. |
warning | vulnerability-threshold is NONE for a tenant, which switches the vulnerability check off. |
jenrepo. |
warning | deny-list-action is ALLOW for a tenant, so the deny list is ignored. |
jenrepo. |
warning | block-private-import-hosts= - an import may reach internal addresses, or travel unencrypted. |
jenrepo. |
warning | rate-limit is 0, so nothing throttles a client. |
jenrepo. |
warning | One server of several has stopped catching up with what the others have seen. |
jenrepo. |
warning | Two installed modules report under the same advisory name - a packaging fault, shown rather than hidden. |
Walks
Some work needs to look at everything the store holds - applying retention, reclaiming space, rebuilding the indexes clients read. The server does it in walks: one pass over the store that every such job rides along on, so the store is read once rather than once per job.
Walks shows the scheduled walks, with when each last ran and what it did. Two are scheduled by default:
| Walk | When | What rides along |
|---|---|---|
retention |
Daily at 03:00 UTC | Applying each repository's retention policy |
rebuild |
Sundays at 03:00 UTC | Every job: reclaiming space, repairing indexes, back-filling what a newly installed module needs |
Each walk can be edited in place - its schedule as a cron expression with seconds first, in UTC
(0 0 3 * * *), whether it is switched on, and which jobs ride along - or removed, and Add a walk schedules
another. Walk the store now starts the rebuild walk at once, with the jobs its entry names - every job by
default, and every job too when no rebuild walk is scheduled. Like any walk, a rebuild walk naming one job
carries that job alone.
Deploy
Deploy, a page of each repository, publishes a single file from the browser - a one-off artifact that has no
build to publish it. Enter the path the artifact is published under, such as
/, pick the file, and press Publish. It passes the same gate a client's
upload does, and it is an admin's to use.
The page is switched off by default; switch it on with JENREPO_ or under Settings → Modules.
Webhooks
The server can call you back when something happens - a publish, a removal, a hold, a release, a new finding. Webhooks are configured under Settings → Settings, in the Webhooks group:
| Setting | Meaning |
|---|---|
webhook |
Switches delivery on. |
webhook-endpoints |
One endpoint per line, https:/ - the events after the URL, or none for all. |
webhook-secrets |
Per endpoint, a secret the server signs each delivery with (HMAC-SHA256), as https:/. |
webhook-attempts |
How many times a failing delivery is retried, with a growing pause, before it is set aside. Five by default. |
Deliveries go out from a background queue, so a slow receiver never slows a publish. An endpoint must be
https and on a public address unless webhook-allow-internal permits otherwise.
Rate limits
Every request is metered against a per-tenant ceiling - 6 000 requests a minute by default, a hundred a
second - and a request over it is answered 429 with Retry-After: 60. The ceiling is the rate-limit setting:
for every tenant under Settings → Settings, or with JENREPO_, and for one tenant on Repositories →
Limits. 0 for the deployment removes it.
A request is charged to its key's tenant, and every request without a key shares one bucket of its own. A bucket holds a minute's worth of burst, so a build resolving a large dependency graph in a quick burst gets through while a sustained flood is shed. Health probes and metric scrapes are never limited. Each server of a multi-node deployment keeps its own buckets, so behind a load balancer the effective ceiling is the setting times the number of servers.
When something fails
A failure the server did not mean - a store that cannot be read, a bug - is never answered with its insides. No
surface shows an exception, a stack trace, a path on disk or a store key. Each one says that something went wrong
and gives a reference, twelve letters and digits, such as 8vjbm05qakwk:
| Surface | What it shows |
|---|---|
| API | A 500 problem document (application/) with title and reference |
| Console | The error page, with the reference to quote |
jenrepo |
The refusal, ending Reference: 8vjbm05qakwk |
| A package client | Its own error format, with the same sentence and reference: an OCI error for docker, an npm or Cargo error document, plain text for the rest |
The server logs the whole failure under that reference, stack trace included, at ERROR:
ERROR ... Unexpected failure 8vjbm05qakwk while GET /repository/default/releases/...
So a user who reports the reference has told you where to look. / finds the line and the
request that failed, and the server's own output - docker logs, kubectl logs - holds the stack trace beneath it.
A reference is minted per failure, so two reports with one reference are one failure.
A refusal the server did mean - a 404, a 403, a policy verdict - is not a failure. It carries no reference and
says why, as it always has.
Endpoints for monitoring
| Endpoint | Answers | Who may read it |
|---|---|---|
/, /, / |
Up or down, for probes | Anyone; the detail only to an administrator |
/ |
The server's meters, for a monitoring system | A key holding manage:read over *, such as the admin role, of the operator tenant |
/ |
The most recent log entries, filterable by level and text | A key holding manage:read over *, of the operator tenant |
/ |
The security posture, as JSON | A key holding manage:read over * |
/ keeps the last thousand entries in memory, with a sequence number on each, so a script can tail it:
curl -H "Jenesis-Repository-Key: $ADMIN_KEY" \
'https://repo.example.com/api/logs?level=WARN&limit=50'