2.7 KiB
2.7 KiB
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",
]
schemamust 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