# repo-delivery-middleware HTTP middleware that serves encrypted GitLab repo bundles to customers. ## Building ```sh nix build # Go binary -> ./result/bin/repo-delivery-middleware nix build .#docker-image # streaming Docker image script -> ./result ``` ## Running (binary) Directly from the flake: ```sh nix run . -- --config config.toml nix run . -- --config config.toml --listen :9090 ``` Or after `nix build`: ```sh ./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: ```sh nix build .#docker-image ./result | docker load ``` This streams and loads the image as `repo-delivery-middleware:latest`. ```sh 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 ```toml 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: ``` 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 ```sh nix develop # shell with go and gopls ```