Files
repo-delivery-middleware/README.md
2026-02-15 17:11:48 +05:30

123 lines
2.7 KiB
Markdown

# 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: <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
```sh
nix develop # shell with go and gopls
```