Added fixes before token usage cutoff. Added required credentials for dns api for cert-manager and external-dns
This commit is contained in:
7 files changed
+117
-60
No files matched your search
@@ -1,36 +0,0 @@
|
||||
# .sops.yaml — SOPS creation rules for the platform repo (ADR-0007, R-SEC-01).
|
||||
#
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
# EFFECTIVE LOCATION: this file must live at the REPOSITORY ROOT to govern
|
||||
# encryption of secrets under platform/** and apps/**. It is AUTHORED here in
|
||||
# bootstrap/sops/ (the security engineer's subtree); the PM/clusters owner
|
||||
# installs it at the repo root (copy or symlink). See bootstrap/sops/README.md
|
||||
# "Interface / handoff". SOPS discovers .sops.yaml by walking UP from the file
|
||||
# being encrypted to the repo root, so it only takes effect from root.
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
#
|
||||
# HOW ENCRYPTION WORKS HERE:
|
||||
# - Only committed secrets are encrypted; plaintext never enters git.
|
||||
# - `encrypted_regex` encrypts ONLY the value fields (data/stringData), leaving
|
||||
# keys and structure in cleartext → readable, reviewable diffs (ADR-0007).
|
||||
# - `age` recipient below is the PUBLIC key from age-keygen.sh. Filling it is a
|
||||
# bootstrap step; the matching PRIVATE key is installed in-cluster as the
|
||||
# `sops-age` Secret (age-key-secret.md) so Flux can decrypt at reconcile.
|
||||
#
|
||||
# TO ENCRYPT A SECRET (operator, not agents):
|
||||
# sops --encrypt --in-place path/to/secret.sops.yaml
|
||||
# # picks up the age recipient + rules below automatically.
|
||||
|
||||
creation_rules:
|
||||
# Platform + app Secrets. Convention: encrypted files are named `*.sops.yaml`
|
||||
# or live under a `secrets/` directory anywhere in the tree.
|
||||
- path_regex: (^|/)(platform|apps|catalog)/.*(secret|sops)\.ya?ml$
|
||||
encrypted_regex: "^(data|stringData)$"
|
||||
# >>> REPLACE-ME <<< paste the age PUBLIC recipient printed by age-keygen.sh.
|
||||
# Example shape (NOT a real key): age1qy...placeholder...0abcd
|
||||
age: "REPLACE-ME-AGE-PUBLIC-RECIPIENT"
|
||||
|
||||
- path_regex: (^|/)secrets/.*\.ya?ml$
|
||||
encrypted_regex: "^(data|stringData)$"
|
||||
# >>> REPLACE-ME <<< same age PUBLIC recipient as above.
|
||||
age: "REPLACE-ME-AGE-PUBLIC-RECIPIENT"
|
||||
+13
-10
@@ -6,16 +6,19 @@ Spec: [ADR-0007 (SOPS+age)](../../../home-network-k3s/decisions/adr-0007-secrets
|
||||
[docs/07](../../../home-network-k3s/docs/07-security-and-secrets.md) · Requirement: **R-SEC-01**
|
||||
(secrets encrypted at rest in git, decrypted only in-cluster).
|
||||
|
||||
> **AUTHOR-ONLY. Nothing here has been executed. No key or secret material exists in this output.**
|
||||
> No `age-keygen`, `sops`, or `kubectl` was run. The age keypair is generated later by the operator;
|
||||
> `.sops.yaml` carries only a **placeholder** for the public recipient.
|
||||
> The SOPS **creation rules** live in the single canonical [repo-root `.sops.yaml`](../../.sops.yaml).
|
||||
> The operator generates the age keypair via `age-keygen.sh`, pastes the **public** recipient into that
|
||||
> root file, and installs the **private** key in-cluster as the `sops-age` Secret. No private key
|
||||
> material ever enters git. (`CREDENTIALS.md` is the end-to-end provisioning checklist.)
|
||||
|
||||
## Files
|
||||
| File | Purpose |
|
||||
|---|---|
|
||||
| `age-keygen.sh` | Operator-run script: generates the age keypair to a path **outside the repo**, prints only the **public** recipient. **Refuses** to write inside the repo or clobber an existing key. |
|
||||
| `.sops.yaml` | SOPS creation rules (encrypt only `data`/`stringData` → readable diffs). `age:` recipient is a clearly-marked `REPLACE-ME` placeholder filled at bootstrap. **Effective home is the repo root** (see below). |
|
||||
| `age-key-secret.md` | Runbook + `kubectl create secret` template installing the age **private** key as the `sops-age` Secret in `flux-system` (the sanctioned out-of-band step). Rotation + DR custody included. |
|
||||
| `CREDENTIALS.md` | End-to-end operator checklist: SOPS setup + the full secret inventory (per component/phase). |
|
||||
| `secret-templates/` | `*.yaml.example` scaffolds (correct name/namespace/keys, placeholder values) to copy → fill → `sops -e`. |
|
||||
| repo-root [`.sops.yaml`](../../.sops.yaml) | The single canonical SOPS creation rules (encrypt only `data`/`stringData` → readable diffs). **At the repo root, NOT here** — a copy in this dir would shadow it for files under `bootstrap/**`. |
|
||||
|
||||
## How this satisfies R-SEC-01 / ADR-0007
|
||||
- Secrets are committed **encrypted** (`sops --encrypt`) using the age **public** recipient in
|
||||
@@ -27,11 +30,11 @@ Spec: [ADR-0007 (SOPS+age)](../../../home-network-k3s/decisions/adr-0007-secrets
|
||||
- No key material appears in scripts, docs, PRs, or logs (AGENTS.md §5).
|
||||
|
||||
## Interface / handoff
|
||||
- **`.sops.yaml` belongs at the REPOSITORY ROOT.** SOPS discovers it by walking up from the file
|
||||
being encrypted, so it only governs `platform/**` and `apps/**` from root. It is authored here (in
|
||||
this worker's subtree); the **PM/clusters owner installs it at the repo root** (copy or symlink).
|
||||
Flagged as an escalation in the T-1.4 report.
|
||||
- **Fill two placeholders at bootstrap:** the `age:` recipient in `.sops.yaml` (from
|
||||
`age-keygen.sh`'s output) — same value in both creation rules.
|
||||
- **`.sops.yaml` is a SINGLE file at the REPOSITORY ROOT.** SOPS discovers it by walking up from the
|
||||
file being encrypted, so a root file governs `platform/**`, `apps/**`, `catalog/**`, and `secrets/**`.
|
||||
Do **not** keep a second copy in this directory — it would be discovered first for files under
|
||||
`bootstrap/**` and shadow the root config (that duplicate was removed after it caused exactly that).
|
||||
- **Fill the recipient at bootstrap:** paste `age-keygen.sh`'s public recipient into the root
|
||||
`.sops.yaml` — the same value in both creation rules.
|
||||
- **Order** (see `../flux/README.md`): `age-keygen.sh` → install `sops-age` Secret (`age-key-secret.md`)
|
||||
→ `../flux/bootstrap.sh`. The Flux entrypoint fails fast if the Secret is missing.
|
||||
@@ -12,7 +12,7 @@
|
||||
# ~/.config/sops/age/keys.txt — SOPS's conventional location, honoured by the
|
||||
# SOPS_AGE_KEY_FILE default lookup).
|
||||
# - Prints ONLY the PUBLIC recipient (age1...) to stdout. The public recipient
|
||||
# is safe to paste into bootstrap/sops/.sops.yaml. The PRIVATE key stays in
|
||||
# is safe to paste into the repo-root .sops.yaml. The PRIVATE key stays in
|
||||
# the file and is NEVER printed, NEVER committed (see .gitignore: age.key,
|
||||
# *.key). Spec docs/07 + AGENTS.md §5: no secret material in logs/PR/output.
|
||||
#
|
||||
@@ -81,5 +81,5 @@ age-keygen -o "${key_abs}" >/dev/null
|
||||
echo "age private key written (0600) to: ${key_abs}"
|
||||
echo "This file is OUTSIDE the repo and must stay that way — do NOT commit it."
|
||||
echo
|
||||
echo "Public recipient (safe to share — paste into bootstrap/sops/.sops.yaml):"
|
||||
echo "Public recipient (safe to share — paste into the repo-root .sops.yaml, both age: lines):"
|
||||
age-keygen -y "${key_abs}" # prints ONLY the public recipient (age1...)
|
||||
Reference in new issue
Block a user