2026-02-15 17:11:48 +05:30
2026-02-15 17:08:02 +05:30
2026-02-15 17:11:48 +05:30

repo-delivery-middleware

HTTP middleware that serves encrypted GitLab repo bundles to customers.

Building

nix build                # Go binary -> ./result/bin/repo-delivery-middleware
nix build .#docker-image # streaming Docker image script -> ./result

Running (binary)

Directly from the flake:

nix run . -- --config config.toml
nix run . -- --config config.toml --listen :9090

Or after nix build:

./result/bin/repo-delivery-middleware --config config.toml
Flag Default Description
--config Path to TOML config file
--listen :8080 Address to listen on

The CONFIG_PATH environment variable can be used instead of --config. The flag takes precedence if both are set.

Running (Docker)

The flake produces a streamLayeredImage script rather than a tarball, so building and loading is a two-step pipe:

nix build .#docker-image
./result | docker load

This streams and loads the image as repo-delivery-middleware:latest.

docker run --rm -p 8080:8080 \
  -e GITLAB_API_KEY=glpat-xxxx \
  -v /path/to/config.toml:/config.toml \
  repo-delivery-middleware:latest --config /config.toml

The image has no shell. The entrypoint is the binary; extra arguments are passed directly as flags.

Configuration

schema = "v1"

[config]
gitlab_url = "https://gitlab.example.com"
# Supports environment variable expansion ($VAR or ${VAR})
gitlab_api_key = "${GITLAB_API_KEY}"

[customers.acme]
# AES-256 key: exactly 64 hex characters (32 bytes)
key = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
repos = [
    "group/project-a",
    "group/subgroup/project-b",
]
  • schema must be "v1".
  • At least one customer is required.
  • Each customer key must be exactly 64 hex characters.
  • Each customer must list at least one repo.

API

GET /getPayload
X-API-Key: <customer_name>

Success response:

200 OK
Content-Type: application/octet-stream
Content-Disposition: attachment; filename="payload.bin"

Error codes:

Code Meaning
401 Missing or unknown X-API-Key header
405 HTTP method other than GET
500 Failed to build or encrypt payload
502 Failed to fetch repositories from GitLab

Payload format

The response body is a single binary blob:

nonce (12 bytes) || ciphertext || GCM tag (16 bytes)
  • Encrypted with AES-256-GCM using the customer's key.
  • Plaintext is a tar.gz archive containing one directory per repo, named after the repo basename (GitLab's internal prefix is stripped).
  • Repos are sorted alphabetically for deterministic output.

Development

nix develop   # shell with go and gopls
Description
No description provided
Readme 41 KiB
Languages
Go 90.2%
Nix 9.8%