Skip to content

Roles & permissions

Repod uses role-based access control (RBAC) with 5 roles. The roles are not a strict hierarchy — auditor is a lateral role that grants read access to audit and security data without any write capability.


Role definitions

Role Label Purpose
reader Lecteur Read-only access to packages and statistics. Intended for client machines and read-only service accounts.
uploader Packager / CI-CD Can upload and import packages. Intended for CI/CD pipelines. Cannot delete, quarantine, or access audit logs.
auditor Auditeur Read-only access to audit logs, CVE review queue, and the full package catalog. Cannot upload or write anything. Intended for compliance and security teams.
maintainer Mainteneur Full package lifecycle management: upload, import, delete, quarantine, sync, CVE rescan, and CVE decisions. Can read audit logs. Cannot manage users or settings.
admin Administrateur Full access: all maintainer permissions plus user management, settings, and GPG key management.

Dependency resolver (authentication middleware)

The API enforces access using five dependency functions. Each endpoint declares which function it requires:

Dependency Roles allowed
get_current_user All authenticated roles (reader, uploader, auditor, maintainer, admin)
get_uploader_user uploader, maintainer, admin
get_auditor_user auditor, maintainer, admin
get_maintainer_user maintainer, admin
get_admin_user admin only

Permission matrix

Permission reader auditor uploader maintainer admin
Packages
List packages (GET /packages/)
View artifact details (GET /artifacts/{name})
View dependencies (GET /artifacts/{name}/dependencies)
Upload packages (POST /upload/)
Import from upstream (POST /import/fetch)
Batch import (POST /import/batch)
Delete all versions (DELETE /artifacts/{name})
Delete specific version (DELETE /artifacts/{name}/{version})
Sync index (POST /artifacts/admin/sync-index)
Distributions
List distributions (GET /distributions/)
List packages by distribution
Initialise distributions (POST /distributions/init)
Promote / migrate (Enterprise only)
Security
View antivirus status (GET /security/clamav/status)
Update antivirus signatures (POST /security/clamav/update)
View CVE findings (GET /security/vulnerabilities)
View CVE posture (GET /security/packages-posture)
View per-package CVE (GET /security/packages/{n}/{v}/cve)
View review queue (GET /security/review-queue)
Make a CVE decision (POST /security/packages/{n}/{v}/decide)
Get decision + SLA (GET /security/packages/{n}/{v}/decision)
Trigger CVE rescan (POST /security/packages/{n}/{v}/rescan)
Quarantine a package (POST /security/packages/{n}/{v}/quarantine)
Security report (GET /security/report)
Trigger SLA check (POST /security/check-sla)
SBOM (Enterprise only)
Export SBOM (GET /sbom/export)
Per-package SBOM (GET /sbom/{name}/{version})
SBOM preview (GET /sbom/preview)
Import & sync
Search upstream index (GET /import/search)
Resolve dependencies (GET /import/resolve/{name})
Sync all sources (POST /import/sync)
Sync one source (POST /import/sync/{source_id})
Sync security sources (POST /import/sync-security)
List import groups (GET /import/groups)
Delete import group (DELETE /import/groups/{name})
Inventory & SSH
Inventory summary (GET /inventory/summary)
List clients (GET /inventory/clients)
Client details (GET /inventory/clients/{id})
Client packages / updates / summary
List scans (GET /inventory/scans)
Scan status (GET /inventory/clients/{id}/scan/status)
CVE results (GET /inventory/cve)
Compliance report (GET /inventory/compliance)
Trigger scan (POST /inventory/clients/{id}/scan)
Reset SSH fingerprint (TOFU)
Audit trail
Read audit logs (GET /artifacts/audit/logs)
Users & API tokens
View current user (GET /auth/me)
Change own password (POST /auth/change-password)
List all users (GET /auth/users)
Create / update / delete users
Reset another user's password
Create API tokens (POST /auth/api-tokens)
Revoke API tokens (DELETE /auth/api-tokens/{id})
Settings (Enterprise only)
Read settings (GET /settings/)
Modify settings (PATCH /settings/)
GPG key info / generate
Test webhook / LDAP / email
Run retention manually
Dashboard & health
Dashboard stats (GET /dashboard/stats)
Dashboard history (GET /dashboard/history)
Download stats (GET /downloads/stats)
Health endpoints (GET /health*) ✅ (public)

Enterprise-only endpoints in Community

Endpoints marked "Enterprise only" above are gated behind an active Enterprise license.


Scoped access: distributions and machines (Enterprise)

The 5-role matrix above answers "what can this user do?" — for larger fleets, Repod adds a second, independent axis that answers "what can this user see and touch?":

  • Per-distribution access restricts which distribution codenames (or Maven/PyPI/npm repositories, or OCI container repositories) a role or group can read from and publish to. A codename with no restrictions configured stays open to everyone with the base role permission — this is opt-in, so existing setups are unaffected until you configure it.
  • Per-machine access applies the same restriction to the fleet inventory: which machines (individually, or by tag) a role or group can see, scan, or target with a remote install job.

Both follow the same rules: an admin account always bypasses the restriction (so a distribution or machine can never end up unreachable by everyone), and a denial on a read returns 404 rather than 403 — so a restricted distribution or machine is indistinguishable from one that doesn't exist, rather than confirming its existence to someone without access.


Role descriptions

reader

Read-only access to packages, distributions, dashboard, and health endpoints.

Intended for: client machines or service accounts that browse the package catalog without uploading.


auditor

Read-only access to packages plus audit logs and the CVE review queue. Cannot upload, delete, or modify anything.

Intended for: compliance officers, CISO team members, and SIEM service accounts. Give this role to users who need complete visibility of security decisions without any operational capability.

Tip

A SIEM service account with role auditor can poll GET /artifacts/audit/logs for all security events without any write capability.


uploader

Can upload and import packages, and search the upstream index. Cannot delete, quarantine, make CVE decisions, or access audit logs.

Intended for: CI/CD pipelines. This is the minimum role for automated publishing. Do not grant a higher role to automated systems.

Warning

If a CI/CD token with uploader role is compromised, the attacker can upload packages but cannot approve their own CVE-flagged uploads, delete existing packages, or modify settings.


maintainer

Full package lifecycle: upload, import, delete, quarantine, sync sources, trigger rescans, and make CVE decisions (approve/reject packages from the review queue). Can read audit logs. Cannot manage users or modify settings.

Intended for: platform engineers and repository maintainers responsible for daily operations and security remediation.


admin

All maintainer capabilities plus user management, API token management, settings (LDAP, webhook, email, CVE policy, retention), and GPG key management.

Intended for: repository administrators. Limit to the minimum number of accounts.

Danger

An admin account can modify CVE policies, disable antivirus or CVE scanning, and manage all users. Restrict it accordingly.


Assigning roles

Web UI

Go to Users in the left sidebar. Click the role dropdown next to any user to change their role immediately.

API

curl -X PATCH http://REPO_HOST:8000/auth/users/jdupont \
  -H "Authorization: Bearer $ADMIN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"role": "maintainer"}'

Note: the field is role (singular string), not roles.

LDAP group mapping

Configure the mapping in Settings → LDAP. Each role has a corresponding group_<role> field in settings.json. At login, Repod evaluates groups in priority order (admin > maintainer > uploader > auditor > reader) and assigns the highest matching role. If no group matches, default_role is applied (defaults to reader). See Configure LDAP.


API tokens

API tokens (format: repod_<random>) are created by admins via POST /auth/api-tokens. Each token is assigned a fixed role at creation time.

# Create a token with uploader role for CI pipelines
curl -X POST http://REPO_HOST:8000/auth/api-tokens \
  -H "Authorization: Bearer $ADMIN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "ci-pipeline", "role": "uploader"}'

The plaintext token is returned only once in the creation response — it is stored as a hash and cannot be retrieved afterwards.

Valid roles for API tokens: admin, maintainer, uploader, reader, auditor.


Role changes take effect immediately

Role changes apply to the user's next API request. Existing JWT tokens embed the role at issuance and are not re-validated mid-session (tokens expire after 60 minutes by default).

To immediately block a user, deactivate the account rather than changing the role. A deactivated account is rejected at the get_current_user dependency on every request, regardless of token validity.