-
-
Notifications
You must be signed in to change notification settings - Fork 0
Configuration
Anchor LFS uses a TOML configuration file. Copy the example template to get started:
cp config.toml.example config.tomlThe server looks for config.toml in the current working directory by default. Override the path with the ANCHOR_LFS_CONFIG environment variable.
The config file has three sections:
-
[options]: Global server settings -
[storage]: Storage backend configuration -
[[endpoints]]: Repository endpoint definitions (one or more)
[options]
listen_address = ":5420"
data_directory = "./data"
additional_logging = false
#base_url = "https://lfs.example.com"
#max_upload_size = 5368709120
#rate_limit_tokens = 10000
#rate_limit_window = "24h"
#auth_cache_ttl = "60s"
#signing_key = ""
#url_expiry = "10m"| Option | Type | Default | Description |
|---|---|---|---|
listen_address |
string | :5420 |
Address and port the server binds to. Use :5420 to listen on all interfaces, or 127.0.0.1:5420 to restrict to localhost. |
data_directory |
string | ./data |
Path where local objects, lock state, and the signing key are stored. |
additional_logging |
bool | false |
Enable human-readable console logging at debug level. When false, logs are JSON-formatted to stderr. |
base_url |
string | (derived from headers) | External base URL for transfer action hrefs (e.g., https://lfs.example.com). Recommended for production. If omitted, URLs are derived from X-Forwarded-Proto and X-Forwarded-Host request headers. |
max_upload_size |
int64 |
5368709120 (5 GiB) |
Maximum allowed upload size in bytes. Uploads exceeding this are rejected during batch negotiation. |
rate_limit_tokens |
uint64 | 10000 |
Number of tokens in the per-IP rate limiter bucket. |
rate_limit_window |
duration | 24h |
Window over which rate limit tokens are replenished. Uses Go duration syntax (e.g., 1h, 30m, 24h). |
auth_cache_ttl |
duration | 60s |
How long GitHub authentication results are cached. Set to 0s to disable caching entirely. |
signing_key |
string (hex) | (auto-generated) | HMAC signing key for transfer URLs, hex-encoded. Minimum 32 bytes (64 hex characters). If omitted, a key is auto-generated and saved to <data_directory>/signing.key. Generate one with: openssl rand -hex 32
|
url_expiry |
duration | 10m |
How long signed transfer URLs remain valid. Uses Go duration syntax. |
Warning
Always set base_url in production. Without it, the server derives transfer URLs from X-Forwarded-Proto and X-Forwarded-Host request headers, which increases the attack surface. A misconfigured or missing reverse proxy could allow clients to influence the generated URLs. Setting base_url explicitly eliminates this risk entirely.
See Storage Backends for full details. Quick summary:
# Local filesystem (default; no [storage] block needed)
[storage]
backend = "local"
# S3-compatible storage
[storage]
backend = "s3"
s3_bucket = "my-lfs-bucket"
s3_region = "us-east-1"Each [[endpoints]] block defines a Git repository whose LFS objects are served. You can configure multiple endpoints on a single server instance.
[[endpoints]]
name = "My Repository"
url = "https://github.com/org/repo"
endpoint = "/org/repo"
visibility = "public"
authentication = "github"| Field | Required | Description |
|---|---|---|
name |
Yes | A human-readable name for the endpoint (used in logs). |
url |
Yes | The GitHub repository URL (e.g., https://github.com/org/repo). Must contain exactly org/repo in the path. |
endpoint |
Yes | The URL path prefix where this endpoint is served (e.g., /org/repo). Must be unique across all endpoints. Cannot use reserved paths like /health. |
visibility |
Yes |
"public" or "private". Public endpoints allow anonymous downloads; private endpoints require authentication for all operations. |
authentication |
Yes |
"github" or "none". See Authentication for details. |
github_api_url |
No | GitHub Enterprise API URL (e.g., https://github.example.com/api/v3/). Required when the repository URL is not on github.com. |
# Public open-source repo
[[endpoints]]
name = "Open Source Project"
url = "https://github.com/myorg/public-repo"
endpoint = "/myorg/public-repo"
visibility = "public"
authentication = "github"
# Private internal repo
[[endpoints]]
name = "Internal Assets"
url = "https://github.com/myorg/private-assets"
endpoint = "/myorg/private-assets"
visibility = "private"
authentication = "github"
# GitHub Enterprise repo
[[endpoints]]
name = "Enterprise Repo"
url = "https://github.example.com/team/project"
endpoint = "/team/project"
visibility = "private"
authentication = "github"
github_api_url = "https://github.example.com/api/v3/"
# Local development (no auth)
[[endpoints]]
name = "Local Dev"
url = "https://github.com/dev/test-repo"
endpoint = "/dev/test-repo"
visibility = "public"
authentication = "none"All global options and storage settings can be overridden with environment variables. Environment variables take precedence over values in the config file.
| Variable | Overrides |
|---|---|
ANCHOR_LFS_CONFIG |
Config file path (default: config.toml) |
ANCHOR_LFS_LISTEN |
options.listen_address |
ANCHOR_LFS_DATA_DIR |
options.data_directory |
ANCHOR_LFS_BASE_URL |
options.base_url |
ANCHOR_LFS_MAX_UPLOAD_SIZE |
options.max_upload_size |
ANCHOR_LFS_SIGNING_KEY |
options.signing_key |
ANCHOR_LFS_STORAGE_BACKEND |
storage.backend |
ANCHOR_LFS_S3_BUCKET |
storage.s3_bucket |
ANCHOR_LFS_S3_REGION |
storage.s3_region |
ANCHOR_LFS_S3_ENDPOINT |
storage.s3_endpoint |
ANCHOR_LFS_S3_ACCESS_KEY_ID |
storage.s3_access_key_id |
ANCHOR_LFS_S3_SECRET_ACCESS_KEY |
storage.s3_secret_access_key |
ANCHOR_LFS_S3_PREFIX |
storage.s3_prefix |
ANCHOR_LFS_S3_PRESIGNED_URLS |
storage.s3_presigned_urls |
ANCHOR_LFS_S3_FORCE_PATH_STYLE |
storage.s3_force_path_style |
- Environment variables (highest priority)
- TOML config file values
- Built-in defaults (lowest priority)
Note: Endpoint configuration ([[endpoints]]) cannot be overridden via environment variables. Endpoints must be defined in the config file.
The server validates the entire configuration at startup and exits with a clear error message if any issues are found. Validation checks include:
- At least one endpoint must be configured
- Endpoint paths must be unique and not use reserved paths (e.g.,
/health) - Endpoint paths must not contain unsafe characters for storage directories
- Authentication must be
"github"or"none" - Visibility must be
"public"or"private" -
github_api_urlcan only be set when authentication is"github" - GitHub-authenticated endpoints must have a valid repository URL with
org/repoformat - Non-
github.comrepository URLs requiregithub_api_urlto be set - S3 backend requires
s3_bucketands3_region -
base_url,s3_endpoint, andgithub_api_urlmust be valid URLs when set -
signing_keymust be valid hex and at least 32 bytes - Duration values (
rate_limit_window,auth_cache_ttl,url_expiry) must be valid Go durations
- Storage Backends: Detailed storage configuration
- Authentication: Authentication setup
- Running the Server: Start the server