add README.md
This commit is contained in:
122
README.md
Normal file
122
README.md
Normal file
@@ -0,0 +1,122 @@
|
||||
# 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
|
||||
```
|
||||
Reference in New Issue
Block a user