OpenWeights

Architecture

The services, what each owns, and how a request moves between them.

OpenWeights is four HTTP services over Postgres, Redis, and a Sia indexer. Two of them carry file bytes; the other two are the console and an optional proxy.

The shape of it

What each service owns

openweights-cas

Rust, Axum, listening on 8080. The control plane and the only service that writes to Sia.

It serves the Hugging Face Hub API subset the hf CLI calls, the Xet protocol endpoints hf_xet calls, the console's /admin/* and /auth/* routes, and /health and /metrics. It holds the Sia App Key, validates every credential, erasure-codes and uploads xorbs, pins them, and mints the HMAC-signed URLs the gateway will honour.

At boot it connects to Postgres, applies its embedded migrations, connects to Redis, performs the Sia handshake, constructs the URL signer, spawns the pin reconciler, and only then reports healthy. A configuration error exits 2; any other boot failure exits 1.

openweights-gateway

Go, chi, listening on 8081 and published on host port 9090. The data plane, and read-only.

Its entire router is GET /health and GET /xorb/{hash}. It verifies the CAS-minted signature on every request, serves byte ranges from a whole-xorb disk LRU cache. On a cache miss it fetches the whole xorb from Sia, verifies its hash, and caches it, then serves the requested range from that local file.

It has no write authority and no App Key write path. Postgres is reached through a dedicated openweights_gw role that can only SELECT on xorbs and INSERT into usage_log.

Prometheus metrics live on a separate loopback listener, 127.0.0.1:9100 by default, so a reverse proxy has no route onto them.

openweights-console

Vite, React 19, TanStack Router and Query, served as static files by nginx on port 80, published on host port 5173. It calls the CAS API from the browser with credentialed fetches, so the CAS allows exactly one cross-origin origin, the value of CONSOLE_BASE_URL.

Its deployment URLs are read at runtime from a /config.js the container writes at start, falling back to build-time VITE_* values and then to localhost defaults. One published image therefore serves any deployment.

openweights-hf-proxy

Go, listening on 28090. Optional. A transparent reverse proxy in front of huggingface.co that rewrites exactly one response header. See hf-proxy.

Supporting services

ServiceRole
Postgres 17Catalog, Xet metadata, sessions, API keys, usage log
Redis 7.4Token-bucket rate limits and request coalescing
Sia indexerThe path to Sia storage contracts and hosts. Not bundled: you supply the URL

Why the CAS and the gateway are separate

This split is the system's primary protection.

The CAS holds the App Key and is the only component that can write to Sia. The gateway holds no write credential and serves bytes only for URLs the CAS has signed with a shared HMAC key. Compromising the gateway yields the ability to serve bytes that were already going to be served, and nothing else.

It is also why the signed-URL format has to match byte for byte across a Rust minter and a Go verifier. Cross-language test vectors in conformance/fixtures/signed_url_vectors.json pin that contract, and both implementations assert against them.

Two ways bytes reach OpenWeights

Standalone. HF_ENDPOINT points at the CAS. OpenWeights is the hub: it owns the repository, the commit, and the bytes. huggingface.co is not involved.

Through the proxy. HF_ENDPOINT points at openweights-hf-proxy. huggingface.co owns the repository and the commit; only file bytes are diverted to OpenWeights, by rewriting the X-Xet-Cas-Url response header.

Next

Follow a request end to end: the write path and the read path.

On this page