Update examples and docs for path-based repos and _COMMAND
Amolith
created
Rework examples/keld/config.toml to demonstrate:
- Path-based repository URLs for rclone and S3 backends
- _COMMAND environ for credential injection (B2 and rclone)
- BorgBase per-repo presets with randomized example creds
Rename example timer env files to _backup/_integrity suffixes.
Rename keld-verify to keld-integrity with --read-data for monthly
full data verification; daily backup unit now chains backup && check.
Add FOO_COMMAND to the special config keys table in AGENTS.md.
@@ -1,21 +1,56 @@
[global.backup]
exclude-if-present = ".nobackup"
+# ── Credentials (shared per backend) ─────────────────────────
+#
+# Suffix sections define the "where" — backend-specific settings shared
+# by every preset that targets this backend. Because S3/B2 credentials
+# apply to the whole account, they live here once.
+
+# Keys ending in _COMMAND are executed by keld; stdout (with trailing
+# newlines stripped) becomes the env var with the suffix removed.
+# This keeps secrets out of config files entirely.
+#
+# rclone credentials can be supplied the same way via env vars named
+# RCLONE_CONFIG_<REMOTE>_<KEY>. Remote names must use underscores, not
+# hyphens. Passwords must be piped through `rclone obscure -`.
+["@hetzner".environ]
+RCLONE_CONFIG_HETZNER_RESTIC_USER_COMMAND = "op read 'op://Vault/Hetzner Storage Box/username'"
+RCLONE_CONFIG_HETZNER_RESTIC_PASS_COMMAND = "op read 'op://Vault/Hetzner Storage Box/password' | rclone obscure -"
+
+["@b2".environ]
+AWS_ACCESS_KEY_ID_COMMAND = "op read 'op://Vault/B2/access-key-id'"
+AWS_SECRET_ACCESS_KEY_COMMAND = "op read 'op://Vault/B2/secret-access-key'"
+
+# ── What to back up ──────────────────────────────────────────
+#
+# Prefix sections define the "what" — sources, excludes, tags, and the
+# restic encryption password. The password is per-prefix so each dataset
+# gets its own encryption key, even when stored on the same backend.
+
["media@".environ]
-RESTIC_PASSWORD_COMMAND = "op read 'op://Example Vault/Media Backup/password'"
+RESTIC_PASSWORD_COMMAND = "op read 'op://Vault/Media Backup/password'"
["media@".backup]
-_arguments = "/home/example/Music/Final"
+_arguments = ["/home/user/Music/Final"]
+
+# ── Where to back up ─────────────────────────────────────────
+#
+# Full preset sections combine prefix + suffix and set the repository
+# path within each backend. Restic supports paths inside a single
+# rclone remote or S3 bucket, so you don't need a separate remote or
+# bucket per dataset.
-["media@hetzner_media"]-repository = "rclone:hetzner-restic-media:/"
+["media@hetzner"]
+repository = "rclone:hetzner_restic:/media"
-["media@b2_media"]-repository = "s3:https://s3.us-west-004.backblazeb2.com/example-bucket-id"
+["media@b2"]
+repository = "s3:https://s3.us-west-004.backblazeb2.com/fe0ae843eb0e5fb6/media"
-["media@b2_media".environ]-AWS_ACCESS_KEY_ID = "B2_EXAMPLE_ACCESS_KEY_ID"-AWS_SECRET_ACCESS_KEY = "B2_EXAMPLE_SECRET_ACCESS_KEY"
+# BorgBase provides per-repository URLs with embedded credentials, so
+# each BorgBase repo is specific to a single dataset — there's no shared
+# @borgbase suffix to reuse. Use a plain preset name (no @) or keep the
+# split form to inherit the prefix's _arguments and password settings.
-["media@rest_repo_media"]-repository = "rest:https://example-user:example-password@example.repo.borgbase.com"
+["media@borgbase_media"]
+repository = "rest:https://d6c83eee:e5ffbc1195c714996205@d6c83eee.repo.borgbase.com"