Configuration Reference

DeltaGlider Proxy is configured via a YAML file and/or environment variables (DGP_* prefix). Environment variables always take precedence over file contents.

As of v0.8.0, YAML is the canonical format. TOML still loads (emits a deprecation warning on every startup; suppress with DGP_SILENCE_TOML_DEPRECATION=1). Convert with:

deltaglider_proxy config migrate deltaglider_proxy.toml --out deltaglider_proxy.yaml

See the upgrade guide for the full TOML → YAML migration path.

Table of Contents


YAML Layout

The canonical YAML has four optional top-level sections:

# deltaglider_proxy.yaml

admission:   # pre-auth request gating (deny / reject / allow-anonymous)
  blocks: [...]

access:      # SigV4 credentials + iam_mode selector
  iam_mode: gui             # gui (default) or declarative
  access_key_id: admin
  secret_access_key: changeme

storage:     # backend(s) + per-bucket overrides
  s3: https://s3.example.com
  buckets: {...}

advanced:    # process-level tunables
  listen_addr: "0.0.0.0:9000"
  cache_size_mb: 2048
  log_level: deltaglider_proxy=info

Every section is optional. Fields equal to their default are omitted from canonical exports (GET /api/admin/config/export and deltaglider_proxy config migrate), keeping GitOps diffs minimal.

The flat (pre-Phase-3) shape — root-level listen_addr:, backend:, etc. — still loads unchanged. Mixing the two shapes in one document is a hard parse error naming the conflicting keys.


Shorthands

Three operator-authoring shorthands expand at load time into their canonical forms.

Storage shorthand — single backend

storage:
  s3: https://s3.example.com       # expands to backend: { type: s3, endpoint: ... }
  region: eu-central-1             # optional
  access_key_id: admin             # optional
  secret_access_key: changeme      # optional
  force_path_style: true           # optional

or

storage:
  filesystem: /var/lib/deltaglider

Only one of backend: / s3: / filesystem: may be set. Companion fields (region, access_key_id, etc.) apply only to s3:.

Bucket public: true

storage:
  buckets:
    docs-site:
      public: true           # shorthand for public_prefixes: [""]

The canonical exporter collapses public_prefixes: [""] back to public: true when unambiguous. The GUI "Public read" toggle maps 1:1 to the YAML.

Mixing public: true and a non-empty public_prefixes is a hard error.


Config-File Search Order

Config::resolve_config_path returns the first match from:

  1. DGP_CONFIG env var (returned unconditionally — if set, the path is used even when the file doesn't yet exist).
  2. ./deltaglider_proxy.yaml
  3. ./deltaglider_proxy.yml
  4. ./deltaglider_proxy.toml (deprecated)
  5. /etc/deltaglider_proxy/config.yaml
  6. /etc/deltaglider_proxy/config.yml
  7. /etc/deltaglider_proxy/config.toml (deprecated)

CLI flags (--config <path>, --listen <addr>) take precedence over all of the above; env vars take precedence over file contents.


Server / Advanced

Process-level knobs. In sectioned YAML these live under advanced:.

listen_addr

HTTP listen address.

Env varDGP_LISTEN_ADDR
YAMLadvanced.listen_addr (sectioned) or root listen_addr: (flat)
TOMLlisten_addr
Default0.0.0.0:9000
Hot-reloadNo (restart required)
advanced:
  listen_addr: "0.0.0.0:8080"

log_level

Tracing filter string. Overridden by RUST_LOG if set. Changeable at runtime via the admin GUI.

Resolution order at startup: RUST_LOG > DGP_LOG_LEVEL > advanced.log_level in file > --verbose CLI flag > default.

Env varDGP_LOG_LEVEL
YAMLadvanced.log_level
TOMLlog_level
Defaultdeltaglider_proxy=debug,tower_http=debug
Hot-reloadYes (via admin GUI or config apply)
advanced:
  log_level: deltaglider_proxy=info,tower_http=warn

request_timeout_secs

Per-request deadline (HTTP 504 when exceeded).

Env varDGP_REQUEST_TIMEOUT_SECS
Default300 (5 minutes)
Hot-reloadNo

max_concurrent_requests

Global tower ConcurrencyLimit. Requests beyond this queue.

Env varDGP_MAX_CONCURRENT_REQUESTS
Default1024
Hot-reloadNo

max_multipart_uploads

Concurrent multipart uploads cap. Each upload holds part data in memory.

Env varDGP_MAX_MULTIPART_UPLOADS
Default1000
Hot-reloadNo

blocking_threads

Tokio blocking thread-pool size. Controls how many concurrent CPU-bound ops (xdelta3 subprocesses) can run.

Env varDGP_BLOCKING_THREADS
YAMLadvanced.blocking_threads
TOMLblocking_threads
Defaulttokio default (512)
Hot-reloadNo

debug_headers

Expose debug/fingerprinting headers (x-amz-storage-type, x-deltaglider-cache). Disable in production to prevent server fingerprinting.

Env varDGP_DEBUG_HEADERS
Defaultfalse
Hot-reloadNo

cors_permissive

Enable permissive CORS for cross-origin admin access (dev only — opens the door to CSRF against session-cookie endpoints).

Env varDGP_CORS_PERMISSIVE
Defaultfalse
Hot-reloadNo

config

Path to the config file.

Env varDGP_CONFIG
DefaultAuto-detect (search list above)

When DGP_CONFIG is set, the path is returned unconditionally — a missing file there is NOT silently replaced by the default search list. This prevents the admin API from persisting to a CWD-relative file the operator never asked for.


Delta Engine

max_delta_ratio

Store an object as a delta only if delta_size / original_size is below this ratio. Lower = more aggressive savings; higher = more files kept as deltas.

Env varDGP_MAX_DELTA_RATIO
YAMLadvanced.max_delta_ratio
TOMLmax_delta_ratio
Default0.75
Hot-reloadYes

max_object_size

Maximum object size in bytes for delta processing (xdelta3 memory constraint). Larger objects are passthrough.

Env varDGP_MAX_OBJECT_SIZE
Default104857600 (100 MB)
Hot-reloadYes

cache_size_mb

In-memory reference cache size in MB. Recommend 1024+ MB for production. Undersized caches (<1024 MB) emit a startup warning.

Env varDGP_CACHE_MB
YAMLadvanced.cache_size_mb
TOMLcache_size_mb
Default100
Hot-reloadNo

metadata_cache_mb

In-memory FileMetadata cache size in MB. Set to 0 to disable. Budget: ~125K-150K entries at 50 MB. 10-minute TTL.

Env varDGP_METADATA_CACHE_MB
YAMLadvanced.metadata_cache_mb
TOMLmetadata_cache_mb
Default50
Hot-reloadNo

codec_concurrency

Maximum concurrent xdelta3 subprocesses. Auto-detected as num_cpus * 4 (min 16).

Env varDGP_CODEC_CONCURRENCY
YAMLadvanced.codec_concurrency
TOMLcodec_concurrency
Defaultnum_cpus * 4 (min 16)
Hot-reloadNo

codec_timeout_secs

Maximum time for an xdelta3 subprocess. Hung processes are killed after this.

Env varDGP_CODEC_TIMEOUT_SECS
Default60
Hot-reloadNo

Storage Backend

Filesystem Backend

Local filesystem. Activated by setting DGP_DATA_DIR or a backend: block with type = "filesystem".

data_dir

Env varDGP_DATA_DIR
YAML (shorthand)storage.filesystem: <path>
YAML (canonical)storage.backend.path
TOMLbackend.path
Default./data
Hot-reloadYes (triggers engine rebuild)
# Shorthand
storage:
  filesystem: /var/lib/deltaglider

# Canonical (equivalent)
storage:
  backend:
    type: filesystem
    path: /var/lib/deltaglider

Paths containing .. components are rejected at load time.

S3 Backend

AWS S3 / MinIO / Hetzner / Backblaze / any S3-compatible service. Activated by setting DGP_S3_ENDPOINT or a backend: block with type = "s3".

endpoint / region / force_path_style / access_key_id / secret_access_key

FieldEnv varYAML shorthandYAML canonicalTOMLDefault
endpointDGP_S3_ENDPOINTstorage.s3: <url>storage.backend.endpointbackend.endpoint— (AWS default)
regionDGP_S3_REGIONstorage.regionstorage.backend.regionbackend.regionus-east-1
force_path_styleDGP_S3_PATH_STYLEstorage.force_path_stylestorage.backend.force_path_stylebackend.force_path_styletrue
access_key_idDGP_BE_AWS_ACCESS_KEY_IDstorage.access_key_idstorage.backend.access_key_idbackend.access_key_id
secret_access_keyDGP_BE_AWS_SECRET_ACCESS_KEYstorage.secret_access_keystorage.backend.secret_access_keybackend.secret_access_key
# Shorthand
storage:
  s3: https://hel1.your-objectstorage.com
  region: hel1
  access_key_id: AKIAIOSFODNN7EXAMPLE
  secret_access_key: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY

# Canonical
storage:
  backend:
    type: s3
    endpoint: https://hel1.your-objectstorage.com
    region: hel1
    force_path_style: true
    access_key_id: AKIAIOSFODNN7EXAMPLE
    secret_access_key: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY

Endpoint URLs must start with http:// or https:// (scheme-less values rejected at load time).


Access — Authentication

The proxy refuses to start without credentials unless you set authentication = "none".

authentication

Explicit auth-mode selector. Absent = auto-detect from credentials; "none" = open access (dev only).

Env varDGP_AUTHENTICATION
YAMLaccess.authentication
TOMLauthentication
Default— (auto-detect; fatal error if absent AND no credentials)
Hot-reloadNo

access_key_id / secret_access_key

Proxy-level SigV4 credentials (the "bootstrap admin" credential pair).

Env varsDGP_ACCESS_KEY_ID / DGP_SECRET_ACCESS_KEY
YAMLaccess.access_key_id / access.secret_access_key
TOMLaccess_key_id / secret_access_key
DefaultNone
Hot-reloadYes
access:
  access_key_id: admin
  secret_access_key: changeme

bootstrap_password_hash

Bcrypt hash of the bootstrap password (encrypts the IAM config DB, signs session cookies, gates admin GUI access in bootstrap mode). Auto-generated on first run. Accepts base64-encoded hashes to avoid $ escaping in Docker/env vars.

Env varDGP_BOOTSTRAP_PASSWORD_HASH (legacy alias: DGP_ADMIN_PASSWORD_HASH)
YAMLadvanced.bootstrap_password_hash (treated as an infra secret — stripped by canonical exports)
TOMLbootstrap_password_hash
DefaultAuto-generated on first run

DGP_BOOTSTRAP_PASSWORD

Plaintext bootstrap password for the config apply / admission trace admin CLI commands (they authenticate via this env var; argv is avoided because it leaks via ps). Not read by the server itself.

Env varDGP_BOOTSTRAP_PASSWORD
ConsumerAdmin CLI (deltaglider_proxy config apply, ... admission trace)

Access — IAM Mode

The access.iam_mode YAML selector controls where IAM state (users, groups, OAuth providers, mapping rules) lives. Orthogonal to the authentication selector.

ModeMeaning
gui (default)Encrypted SQLCipher DB is source of truth. Admin GUI + admin API mutate it. YAML access.* carries only the legacy SigV4 pair + authentication selector.
declarativeYAML access.iam_users, iam_groups, auth_providers, and group_mapping_rules are authoritative. Admin API IAM mutation routes (POST/PUT/PATCH/DELETE on /users, /groups, /ext-auth/*, /migrate, backup import) return 403 { "error": "iam_declarative" }. Read routes stay accessible.
access:
  iam_mode: declarative

Mode transitions are audit-logged at warn level on the deltaglider_proxy::config target. In declarative mode, every /config/apply or section-PUT on access runs a dry validation + diff, then reconciles the encrypted config DB to YAML in one SQLite transaction. Creates, updates, and deletes emit iam_reconcile_* audit entries.

The initial gui → declarative flip is guarded: if YAML contains no users or groups while the DB is non-empty, apply fails instead of wiping IAM by accident. To seed GitOps YAML from an existing DB, use GET /_/api/admin/config/declarative-iam-export; see Declarative IAM for the full workflow.


Admission Chain

Operator-authored pre-auth request gating. Blocks are evaluated top-to-bottom; first match wins. Operator blocks fire before synthesized public-prefix blocks derived from storage.buckets[*].public_prefixes.

admission:
  blocks:
    - name: deny-known-bad-ips
      match:
        source_ip_list:
          - "203.0.113.5"
          - "198.51.100.0/24"
      action: deny

    - name: maintenance-mode
      match: {}              # empty = match every request
      action:
        type: reject
        status: 503
        message: "Planned maintenance — back at 18:00 UTC."

    - name: allow-public-zips
      match:
        method: [GET, HEAD]
        bucket: releases
        path_glob: "*.zip"
      action: allow-anonymous

Block fields

FieldTypeNotes
namestring (required)1-128 chars, [A-Za-z0-9_:.-]. Must be unique across the chain. public-prefix:* is reserved for synthesized blocks.
matchobject (default {})AND-combined predicates. Empty {} fires on every request.
match.method[string]HTTP methods: GET HEAD PUT POST DELETE PATCH OPTIONS. Case-insensitive on parse.
match.source_ipIPExact match. Mutually exclusive with source_ip_list.
match.source_ip_list[IP | CIDR]Accepts bare IPs (promoted to /32 or /128) and CIDRs. Cap: 4096 entries.
match.bucketstringTarget bucket (lowercased on parse).
match.path_globstringGlob against the full key: *.zip, releases/**, docs/readme.md.
match.authenticatedbooltrue = only authenticated; false = only anonymous; absent = either.
match.config_flagstringNamed flag. Registry is not yet live — maintenance_mode is recognised but always evaluates false; a warning fires at chain-build time.
actionstring | object (required)Simple: allow-anonymous, deny, continue. Tagged: { type: reject, status: <4xx|5xx>, message?: <string> }.

continue is an explicit terminal that falls through to authentication — useful as the final block for diagnostic visibility in trace output.

Round-trip

Operator-authored source_ip_list entries round-trip verbatim (bare IPs stay bare, CIDRs stay CIDRs) so GitOps diffs don't flip on every apply.

The admin GUI's Admission page (/_/admin/configuration/admission) is the authoring surface. Synthesized public-prefix:* blocks appear read-only below the operator list; edit them via Storage → Buckets instead.


Security

trust_proxy_headers

Trust X-Forwarded-For / X-Real-IP for rate limiting and aws:SourceIp IAM conditions. Disable if the proxy is internet-facing without a reverse proxy.

Env varDGP_TRUST_PROXY_HEADERS
Defaultfalse (secure-by-default)
Hot-reloadNo

Behind a reverse proxy that sets these headers, set to true.

session_ttl_hours

Admin GUI session TTL.

Env varDGP_SESSION_TTL_HOURS
Default4
Hot-reloadNo

clock_skew_seconds

SigV4 clock skew tolerance.

Env varDGP_CLOCK_SKEW_SECONDS
Default300 (5 min)
Hot-reloadNo

replay_window_secs

SigV4 replay detection window. Presigned URLs and idempotent methods (GET/HEAD) are exempt.

Env varDGP_REPLAY_WINDOW_SECS
Default2
Hot-reloadNo

secure_cookies

Require HTTPS for admin session cookies (Secure flag).

Env varDGP_SECURE_COOKIES
Defaulttrue
Hot-reloadNo

Rate Limiting

Per-IP brute-force protection for auth endpoints. See rate limiting for the full model.

SettingEnv varDefault
Max failures before lockoutDGP_RATE_LIMIT_MAX_ATTEMPTS100
Rolling windowDGP_RATE_LIMIT_WINDOW_SECS300 (5 min)
Lockout durationDGP_RATE_LIMIT_LOCKOUT_SECS600 (10 min)

TLS

When enabled, both the S3 API and admin GUI serve HTTPS on the single listener.

advanced:
  tls:
    enabled: true
    cert_path: /etc/ssl/certs/proxy.pem
    key_path: /etc/ssl/private/proxy-key.pem
FieldEnv varYAMLDefault
enabledDGP_TLS_ENABLEDadvanced.tls.enabledfalse
cert_pathDGP_TLS_CERTadvanced.tls.cert_pathAuto-generate self-signed
key_pathDGP_TLS_KEYadvanced.tls.key_pathAuto-generate

When cert_path and key_path are both absent, a self-signed certificate is generated on startup.


Config Sync

Multi-instance IAM sync via S3. When enabled, the encrypted config DB file is replicated to a shared S3 bucket.

Env varDGP_CONFIG_SYNC_BUCKET
YAMLadvanced.config_sync_bucket
TOMLconfig_sync_bucket
DefaultNone (disabled)
advanced:
  config_sync_bucket: my-config-bucket

Sync uses the same S3 credentials as the storage backend (DGP_BE_AWS_*) and only works when the storage backend is S3 (not filesystem). On every IAM mutation, the DB is uploaded to s3://<bucket>/.deltaglider/config.db; readers poll the S3 ETag every 5 minutes and download on change.


Multi-Backend Routing

Route different buckets to different storage backends. When backends is non-empty, the legacy single backend is ignored at runtime.

storage:
  default_backend: primary
  backends:
    - name: primary
      type: s3
      endpoint: https://s3.us-east-1.amazonaws.com
      region: us-east-1
      access_key_id: AWS_KEY
      secret_access_key: AWS_SECRET
    - name: europe
      type: s3
      endpoint: https://hel1.your-objectstorage.com
      region: hel1
      access_key_id: HETZNER_KEY
      secret_access_key: HETZNER_SECRET
    - name: local
      type: filesystem
      path: /data/cache
  buckets:
    archive:
      backend: europe
      alias: prod-archive-2024

Backends can be added/removed via the admin GUI (Storage → Backends) without restart. default_backend is validated against the backends list at load time — invalid references are cleared with a warning.


Bucket Policies

Per-bucket overrides. All fields optional.

storage:
  buckets:
    releases:
      compression: true
      max_delta_ratio: 0.9
      backend: europe
      alias: prod-releases-2024
      public_prefixes: ["builds/", "artifacts/"]
      quota_bytes: 10737418240    # 10 GiB
    docs-site:
      public: true                # shorthand for public_prefixes: [""]
FieldTypeDefaultDescription
compressionboolglobalEnable/disable delta compression for this bucket
max_delta_ratiofloat (0-1)globalOverride the delta-keep threshold
backendstringdefaultRoute to a named backend from storage.backends
aliasstringsame as bucket nameVirtual → real bucket name mapping on the backend
public_prefixes[string][]Anonymous read (GET/HEAD/LIST) scoped to these key prefixes
publicboolShorthand for public_prefixes: [""] (entire bucket public)
quota_bytesu64Soft storage quota (may overshoot by up to 5 minutes of writes); 0 = freeze bucket

Public Prefixes

When public_prefixes (or public: true) is set, anonymous users can GET, HEAD, and LIST objects under the prefix. Writes always require authentication. Use trailing / for directory-aligned matching ("builds/" matches builds/v1.zip but not buildscripts/). The empty string "" makes the entire bucket public (logged as a warning). Prefixes containing .., null bytes, or // are rejected. The proxy synthesizes public-prefix:<bucket> admission blocks from this config.


Encryption at Rest

Per-backend encryption with four modes: none, aes256-gcm-proxy, sse-kms, sse-s3. Each backend carries its own encryption block — operators can mix (e.g. SSE-KMS for the production backend, plaintext for a public-CDN backend) without sharing a single blast-radius key.

YAML — named-backends path:

storage:
  backends:
    - name: archive
      s3: { ... }
      encryption:
        mode: aes256-gcm-proxy
        key: "${DGP_BACKEND_ARCHIVE_ENCRYPTION_KEY}"
        key_id: archive-2026-04   # optional; derived from SHA-256(name + key) when absent
    - name: kms-prod
      s3: { ... }
      encryption:
        mode: sse-kms
        kms_key_id: arn:aws:kms:us-east-1:123456789012:key/abc-def
        bucket_key_enabled: true

YAML — singleton-backend path (backends: empty):

storage:
  backend: { ... }
  backend_encryption:
    mode: aes256-gcm-proxy
    key: "${DGP_ENCRYPTION_KEY}"

Env vars (infra secrets — these are the recommended key source; every key / kms_key_id field in YAML is stripped by canonical exports):

Env varBinds to
DGP_ENCRYPTION_KEYbackend_encryption.key (singleton path)
DGP_BACKEND_<NAME>_ENCRYPTION_KEYbackends[name=<NAME>].encryption.key
DGP_SSE_KMS_KEY_IDbackend_encryption.kms_key_id (singleton SSE-KMS)
DGP_BACKEND_<NAME>_SSE_KMS_KEY_IDnamed SSE-KMS override

Name normalisation: <NAME> is uppercased; - and . become _ (so eu-archiveDGP_BACKEND_EU_ARCHIVE_ENCRYPTION_KEY).

Defaults: absent encryption block → mode: none (plaintext).

Formats: key / legacy_key are 64-char lowercase hex (256 bits). kms_key_id is a KMS ARN or alias. key_id (optional) must match [A-Za-z0-9_.-]{1,64} (S3 user-metadata header-safe).

Rotation within a single mode is not automated — use the legacy_key / legacy_key_id shim fields (decrypt-only, for proxy→native transitions) or copy objects to a new backend. See encryption at rest for the full wire format, key-id mismatch mechanics, and the shim lifecycle.


CLI Subcommands

CommandPurpose
deltaglider_proxy config migrate <in> [--out <out>]Convert TOML (or YAML) to canonical YAML
deltaglider_proxy config lint <file>Offline schema + semantic validation (matches /config/validate)
deltaglider_proxy config schema [--out <out>]Emit JSON Schema for the Config shape (for CI + YAML LSP)
deltaglider_proxy config defaults [--out <out>]Emit defaults + docstrings as JSON Schema
deltaglider_proxy config apply <file> [--server <url>] [--timeout <secs>]Push a YAML document to a running server via the admin API (reads DGP_BOOTSTRAP_PASSWORD env)
deltaglider_proxy admission trace --method <m> --path <p> [--authenticated] [--query <q>]Dry-run a synthetic request through the admission chain

Lint exit codes: 0 = valid (warnings on stderr allowed); 3 = I/O error; 4 = parse error; 6 = validation error.


Full Example

A kitchen-sink YAML covering every top-level section. Fields omitted here inherit their defaults.

# deltaglider_proxy.yaml

# Operator-authored admission chain (pre-auth gating)
admission:
  blocks:
    - name: deny-known-bad-ips
      match:
        source_ip_list: ["203.0.113.0/24"]
      action: deny

    - name: allow-public-zips
      match:
        method: [GET, HEAD]
        bucket: releases
        path_glob: "*.zip"
      action: allow-anonymous

# SigV4 credentials + IAM mode
access:
  iam_mode: gui               # or declarative
  access_key_id: admin
  secret_access_key: changeme

# Backends + per-bucket overrides
storage:
  default_backend: primary
  backends:
    - name: primary
      type: s3
      endpoint: https://hel1.your-objectstorage.com
      region: hel1
      force_path_style: true
      access_key_id: HETZNER_KEY
      secret_access_key: HETZNER_SECRET
    - name: cold
      type: s3
      endpoint: https://s3.us-east-1.amazonaws.com
      region: us-east-1
      access_key_id: AWS_KEY
      secret_access_key: AWS_SECRET
  buckets:
    releases:
      backend: primary
      compression: true
      public_prefixes: ["builds/", "artifacts/"]
    archive:
      backend: cold
      alias: prod-archive-2024
      compression: false
    docs-site:
      public: true

# Process-level tunables
advanced:
  listen_addr: "0.0.0.0:9000"
  log_level: deltaglider_proxy=info,tower_http=warn
  max_delta_ratio: 0.75
  cache_size_mb: 2048
  metadata_cache_mb: 100
  codec_concurrency: 32
  config_sync_bucket: my-config-sync-bucket
  tls:
    enabled: true
    cert_path: /etc/ssl/certs/proxy.pem
    key_path: /etc/ssl/private/proxy-key.pem

Equivalent environment variables for container deployments:

DGP_LISTEN_ADDR=0.0.0.0:9000
DGP_MAX_DELTA_RATIO=0.75
DGP_MAX_OBJECT_SIZE=104857600
DGP_CACHE_MB=2048
DGP_METADATA_CACHE_MB=100
DGP_CODEC_CONCURRENCY=32
DGP_LOG_LEVEL=deltaglider_proxy=info,tower_http=warn
DGP_ACCESS_KEY_ID=admin
DGP_SECRET_ACCESS_KEY=changeme
DGP_BOOTSTRAP_PASSWORD_HASH=JDJiJDEyJENYbDVPRm84bDg2...
DGP_CONFIG_SYNC_BUCKET=my-config-sync-bucket
DGP_S3_ENDPOINT=https://hel1.your-objectstorage.com
DGP_S3_REGION=hel1
DGP_S3_PATH_STYLE=true
DGP_BE_AWS_ACCESS_KEY_ID=HETZNER_KEY
DGP_BE_AWS_SECRET_ACCESS_KEY=HETZNER_SECRET
DGP_TLS_ENABLED=true
DGP_TLS_CERT=/etc/ssl/certs/proxy.pem
DGP_TLS_KEY=/etc/ssl/private/proxy-key.pem

Environment Variable Registry

Exhaustive list of every DGP_* variable the server reads. The unit test test_registry_completeness in src/config.rs enforces that this list and ENV_VAR_REGISTRY stay in sync.

Server / Advanced

VariableDefaultDescription
DGP_CONFIGautoPath to the config file (.yaml / .yml / .toml)
DGP_LISTEN_ADDR0.0.0.0:9000HTTP listen address
DGP_LOG_LEVELdeltaglider_proxy=debug,tower_http=debugTracing filter (overridden by RUST_LOG)
DGP_BLOCKING_THREADS512Max tokio blocking threads
DGP_REQUEST_TIMEOUT_SECS300Per-request timeout (returns 504)
DGP_MAX_CONCURRENT_REQUESTS1024Tower concurrency limit
DGP_MAX_MULTIPART_UPLOADS1000Concurrent multipart upload cap
DGP_DEBUG_HEADERSfalseExpose fingerprinting headers
DGP_CORS_PERMISSIVEfalseEnable permissive CORS (dev only)

Delta engine

VariableDefaultDescription
DGP_MAX_DELTA_RATIO0.75Keep delta only if delta/original < ratio
DGP_MAX_OBJECT_SIZE104857600Max bytes eligible for delta (xdelta3 mem cap)
DGP_CACHE_MB100Reference cache size in MB
DGP_METADATA_CACHE_MB50FileMetadata cache size in MB (0 to disable)
DGP_CODEC_CONCURRENCYnum_cpus * 4 (min 16)Max concurrent xdelta3 subprocesses
DGP_CODEC_TIMEOUT_SECS60Per-subprocess timeout

Storage

VariableDefaultDescription
DGP_DATA_DIR./dataFilesystem backend data directory
DGP_S3_ENDPOINTS3 endpoint (activates S3 backend when set)
DGP_S3_REGIONus-east-1AWS region
DGP_S3_PATH_STYLEtrueUse path-style URLs (MinIO/LocalStack)
DGP_BE_AWS_ACCESS_KEY_IDBackend S3 access key
DGP_BE_AWS_SECRET_ACCESS_KEYBackend S3 secret key

Authentication

VariableDefaultDescription
DGP_AUTHENTICATION"none" for open access; absent = auto-detect
DGP_ACCESS_KEY_IDProxy SigV4 access key
DGP_SECRET_ACCESS_KEYProxy SigV4 secret key
DGP_BOOTSTRAP_PASSWORD_HASHautoBcrypt hash (legacy alias: DGP_ADMIN_PASSWORD_HASH)
DGP_BOOTSTRAP_PASSWORDPlaintext password for admin CLI only

Security

VariableDefaultDescription
DGP_TRUST_PROXY_HEADERSfalseTrust X-Forwarded-For / X-Real-IP
DGP_SESSION_TTL_HOURS4Admin session lifetime
DGP_CLOCK_SKEW_SECONDS300SigV4 clock skew tolerance
DGP_REPLAY_WINDOW_SECS2SigV4 replay detection window
DGP_SECURE_COOKIEStrueRequire HTTPS for session cookies
DGP_RATE_LIMIT_MAX_ATTEMPTS100Max auth failures before lockout
DGP_RATE_LIMIT_WINDOW_SECS300Rate-limit rolling window
DGP_RATE_LIMIT_LOCKOUT_SECS600Lockout duration

TLS / Config sync / Encryption at rest / Misc

VariableDefaultDescription
DGP_TLS_ENABLEDfalseEnable HTTPS
DGP_TLS_CERTauto self-signedPEM cert path
DGP_TLS_KEYauto self-signedPEM key path
DGP_CONFIG_SYNC_BUCKETS3 bucket for encrypted-DB multi-instance sync
DGP_ENCRYPTION_KEYSingleton-backend AES-256 key (64-char hex). Named backends use DGP_BACKEND_<NAME>_ENCRYPTION_KEY.
DGP_SSE_KMS_KEY_IDSingleton-backend SSE-KMS ARN/alias. Named backends use DGP_BACKEND_<NAME>_SSE_KMS_KEY_ID.
DGP_SILENCE_TOML_DEPRECATIONfalseSuppress the TOML-is-deprecated startup warning

Consumed only by tests / build

VariableConsumer
DGP_BUILD_TIMEbuild.rs (compile-time timestamp)
DGP_BUCKEThistorical comment in tests; no longer read