ArtiFerrisSecurity

Security and your data

The measures that protect an instance, described precisely. The data stays on your server; only the names and versions of audited packages go to registry.npmjs.org.

What the server sends back

The security headers, as an instance sends them.

$ curl -s -D - -o /dev/null https://app.artiferris.pro/healthz
HTTP/2 200
content-security-policy: default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob: https:; font-src 'self' data:; connect-src 'self'; object-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'none'
content-type: text/plain; charset=utf-8
cross-origin-opener-policy: same-origin
cross-origin-resource-policy: same-origin
date: Tue, 06 Oct 2026 14:31:01 GMT
permissions-policy: accelerometer=(), autoplay=(), camera=(), display-capture=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), midi=(), payment=(), usb=(), xr-spatial-tracking=()
referrer-policy: same-origin
strict-transport-security: max-age=31536000; includeSubDomains; preload
vary: origin
x-content-type-options: nosniff
x-frame-options: DENY
x-xss-protection: 1; mode=block
content-length: 2
The production instance, version 0.6.1, asked for /healthz on 6 October 2026. The server sets the content policy, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, Permissions-Policy and the Cross-Origin policies; here, Strict-Transport-Security and X-XSS-Protection come from the reverse proxy.
Two-factor authentication is mandatory
An authenticator app or a passkey, with ten backup codes. A separate, short-lived token stands for "password checked, second factor expected"; it does not act as a session.
Passwords hashed with Argon2
For local accounts. LDAP and OIDC accounts authenticate with their provider, and failed sign-ins are throttled.
Rights checked on every route
A repository's rights are enforced by the server, not just hidden in the interface. Request bodies are only read after these checks.
Secrets encrypted with AES-256-GCM
SMTP, LDAP and OIDC passwords, proxy credentials and TOTP seeds, under SECRETS_ENCRYPTION_KEY, which can be changed without loss through a rotation.
Tokens, stored hashed
Command-line tools authenticate with an API token, which the server cannot read back. The tokens Docker gets after docker login last 2 minutes.
Bounded memory
Docker blobs go to disk as they arrive. Documents kept in memory draw on a 1 GiB budget, and a client has at most four bodies in progress.
A budget for anonymous traffic
Public pages, the public API and npm and Docker reads have a budget per client and per minute, shared between replicas. The database only receives fingerprints, never an address.
Audit and security logs
Kept 365 days by default. Sign-ins, denied accesses and administrative actions are recorded there.
Controlled outbound connections
LDAP, SMTP, OIDC and proxies reach no private address, except the ranges you allow. A proxy only sends its credentials to the configured upstream registry, over https.
Your data, on your server
PostgreSQL and a volume, both yours to back up. With the Helm chart, the pod runs unprivileged, on a read-only file system.

The Security section of the README

Try ArtiFerris, then deploy your own instance.

The public instance lets you discover the product. Your instance keeps your packages.

Start the stack with Docker Compose
git clone https://github.com/Masmarino/ArtiFerris.git
cd ArtiFerris
cp .env.example .env
# set POSTGRES_PASSWORD, JWT_SECRET, SECRETS_ENCRYPTION_KEY, PUBLIC_URL and the first admin in .env
docker compose up -d --build