Skip to content

Configuration

Refringe edited this page Mar 8, 2026 · 1 revision

Configuration

Anchor LFS uses a TOML configuration file. Copy the example template to get started:

cp config.toml.example config.toml

The server looks for config.toml in the current working directory by default. Override the path with the ANCHOR_LFS_CONFIG environment variable.

Configuration File Structure

The config file has three sections:

  1. [options]: Global server settings
  2. [storage]: Storage backend configuration
  3. [[endpoints]]: Repository endpoint definitions (one or more)

Global Options

[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 Reference

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.

Storage Configuration

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"

Endpoint Configuration

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"

Endpoint Fields

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.

Example: Multiple Endpoints

# 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"

Environment Variable Overrides

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

Precedence Order

  1. Environment variables (highest priority)
  2. TOML config file values
  3. Built-in defaults (lowest priority)

Note: Endpoint configuration ([[endpoints]]) cannot be overridden via environment variables. Endpoints must be defined in the config file.

Validation

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_url can only be set when authentication is "github"
  • GitHub-authenticated endpoints must have a valid repository URL with org/repo format
  • Non-github.com repository URLs require github_api_url to be set
  • S3 backend requires s3_bucket and s3_region
  • base_url, s3_endpoint, and github_api_url must be valid URLs when set
  • signing_key must be valid hex and at least 32 bytes
  • Duration values (rate_limit_window, auth_cache_ttl, url_expiry) must be valid Go durations

Next Steps

Clone this wiki locally