A Rust service that serves an S3 bucket via the Nix Lockable HTTP Tarball Protocol, allowing you to host your own Nix channels effortlessly.
This service enables you to host Nix channels using an S3-compatible storage backend. It implements the Nix Lockable HTTP Tarball Protocol to allow these tarballs to be used as Flake inputs.
- 📦 Supports multiple channels with different versions
- 🔄 Lets S3 serve the actual tarballs for efficiency
- 🔁 Periodically refreshes channel configuration without restarts
- 🔒 Authentication via JWT (optional)
- 🛡️ Strong sandboxing via systemd (when using the Nix module)
The service provides two main endpoints:
/channel/{channel-name}.tar.xz
- Redirects to the latest version of a channel/permanent/{object-key}.tar.xz
- Serves a specific immutable tarball by key
To use a channel as a Nix Flake input:
{
inputs = {
example.url = "https://example.com/channel/nixos-25.05.tar.xz";
};
# ...
}
# Clone the repository
$ git clone https://github.com/blitz/s3-nix-channel.git
$ cd s3-nix-channel
# Build with cargo
$ cargo build --release
The binary will be available at target/release/s3-nix-channel
.
For S3 buckets that need authentication, set these environment variables:
export AWS_ACCESS_KEY_ID=<your-access-key>
export AWS_SECRET_ACCESS_KEY=<your-secret-key>
Start the server:
s3-nix-channel \
--bucket your-nix-channel-bucket \
--base-url https://example.com \
--listen 0.0.0.0:3000
For Hetzner Object Storage, set these additional environment variables:
export AWS_ACCESS_KEY_ID=<your-access-key>
export AWS_SECRET_ACCESS_KEY=<your-secret-key>
export AWS_REGION="eu-central-1"
export AWS_ENDPOINT_URL="https://nbg1.your-objectstorage.com"
Adjust the endpoint URL as necessary. Then start the server as shown above.
Most S3-compatible storage providers should work by setting the appropriate endpoint and credentials.
If authentication is required,
JWT can be used. The
supported algorithm is RS256
.
-
Generate an RSA key pair:
$ openssl genrsa -out private.pem 2048 $ openssl rsa -in private.pem -pubout -out public.pem
-
Start the server with the public key:
$ s3-nix-channel \ --bucket your-nix-channel-bucket \ --base-url https://example.com \ --listen 0.0.0.0:3000 \ --jwt-pem public.pem
-
For clients, create JWT tokens signed with the private key and use HTTP Basic authentication with the token as the password. This is designed to be used via the netrc.
This file defines the available channels:
{
"channels": ["nixos-25.05", "nixos-unstable"]
}
Each channel needs its own configuration file. Example for
nixos-25.05.json
:
{
"latest": "nixos-25.05-2025-05-15"
}
This means requests to /channel/nixos-25.05.tar.xz
will redirect to
the tarball at /permanent/nixos-25.05-2025-05-15.tar.xz
, with
appropriate immutable link headers.
New tarballs can be uploaded with s3-nix-channel-upload
. You'll need
to configure authentication via environment variables (see above).
s3-nix-channel-upload publish your-nix-channel-bucket nixos-25.05 nixos-25.05-2025-05-20.tar.xz
Contributions are welcome! Please feel free to submit a Pull Request.
See the LICENSE
file.