Skip to content
Alexander Birkner edited this page Aug 31, 2026 · 3 revisions

Usage

Silo authenticates every request with one kind of credential: a database-backed token. It reaches the server through two envelopes because clients can't agree on one — gRPC and npm send Authorization: Bearer, while dnf, apk and apt can only do HTTP Basic (token in the password field, username ignored). pacman can't send credentials at all — see Usage-Pacman.

Per-format client configuration:

See Contributing to build and run silo itself locally.

Tokens

silo token create --name ci --permission write --repo myrepo
silo token create --name readonly --permission read           # all repos
silo token create --name temp --permission write --repo a --repo b \
                  --expires-in-days 30
silo token list
silo token revoke --name ci
  • Permissions are ordered: read < write < admin.
  • Scope is either every repo or an explicit list.
  • Expiry is optional; omit it for a token that never expires.
  • An admin cannot create a token with a wider scope than their own.

The secret is shown once, at creation, and is unrecoverable afterwards. Tokens are silo_<prefix>_<secret>: the prefix is a public lookup handle, the secret is a 256-bit value from the OS CSPRNG, stored as a salted (and optionally peppered) SHA-256 hash.

Users, login, and OIDC

silo user create --username alice --admin
silo login              # prompts, saves a session token to ~/.config/silo
silo whoami

silo login issues a session token carrying the user's own permission level and an expiry. Configure oidc.issuer and oidc.client_id (see Setup) to have silo login run the device authorization grant against an identity provider instead; users are provisioned on first login and matched by sub, falling back to username.

CI and other non-interactive callers

export SILO_SERVER=https://silo.example.com:8080
export SILO_TOKEN="$SILO_PUBLISH_TOKEN"
silo publish ./dist/mypkg-1.0.0-1.x86_64.rpm --repo myrepo --channel stable

SILO_TOKEN takes precedence over any config file. For short-lived sessions instead of a standing token:

export SILO_TOKEN=$(SILO_USERNAME=ci SILO_PASSWORD="$SILO_CI_PASSWORD" \
  silo login --server https://silo.example.com:8080 --print-token)

For CI providers that mint OIDC ID tokens (GitHub Actions, GitLab CI, Kubernetes), pass the token straight in and the device flow is skipped:

# GitHub Actions
permissions:
  id-token: write
steps:
  - run: |
      SILO_OIDC_TOKEN=$(curl -sH "Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" \
        "$ACTIONS_ID_TOKEN_REQUEST_URL&audience=silo" | jq -r .value) \
      silo login --server "$SILO_SERVER" --print-token

Repo mode: public vs private

Every repo is private by default: reading or writing it needs a token scoped to it. An admin can flip a repo to public:

silo repo set myrepo --mode=public
silo repo set myrepo --mode=private

Public only adds unauthenticated readdnf/apk/npm can pull from it with no credential. It changes nothing about who can write: a token that already had write access keeps it, and an uncredentialed caller can never publish, public or not.

A repo you have no access to — private and outside your token's scope, or nonexistent — behaves identically from the outside: it 404s either way, so there's nothing to tell the two apart.

This distinction is what "with and without auth enabled" means on each per-format page below: a public repo needs no credential for reads; a private repo (the default) needs a read- or write-scoped token for every request.

Administration

silo repos                                              # what exists, and its mode
silo delete --id 42                                     # remove a package
silo index rebuild --repo myrepo --channel stable --format apk
silo audit --limit 20                                    # audit log
silo version                                              # client and server, side by side

index rebuild regenerates an index from the database alone — the repair path after restoring a bucket from backup or a crash mid-publish.

See Maintenance for silo prune and the background jobs that run session cleanup, audit-log retention, and scheduled pruning.

Clone this wiki locally