diff --git a/.sops.yaml b/.sops.yaml index 5cba236..3bba812 100644 --- a/.sops.yaml +++ b/.sops.yaml @@ -3,8 +3,8 @@ keys: # Master Keys (Used for generic/global secrets if needed, but usually we encrypt for specific hosts) - - &prod_master age1... # TODO: Replace with the public key of the prod-master offline USB key - - &staging_master age1... # TODO: Replace with the public key of the staging-master key + - &prod_master age1pq12tgz8e980yvrsvd6c6ct6fa8y8eq0c8hjkdfvhp9k0phsdpjvewrrj42zsj9xhk2h2q6wmzvfnpjcgrm8x2zyzxjwv6urjpe60w89n9c2c0lw4j44qzr5j6ryxnmw8hysvngnf50s7ykrdrvy0aql9ktqqks2zzn48rd0k2mecw2snug23ydc4u4w6vphgusp3nrux9e8s6dsmf3vg7ngyc4ylgsht9fkmt6j4teq5y2sy9v9lye59ugztr29fw566dsdwu6vk3pw8dmelynkh8rg4fe88y3udntgwdcrzhun0j7kvjgxskvutyjlestwdfue27uqkdp94yhq0pgdxz8zs5tnxdnctzcf6v3yg2zlypesuzf8fatxxtt4564rr6uwdgjnepwv77gmw9erqp4hwtu40x4gxcyvz7pqpk724yd5g44ldh80fj53quhga0re7sqckmr2qfscdunqzu6s3am59t0p7dppw9jq0tfjnq4e8y78ywxhnjyct45g4q4jthn2yqh9gsep2cuuxq6pg3meye7qxs4y598t24su8ky8u25hfcfg9km5j5mf47vq9w8zu7kcaw74rqyq95wxdz84synckuut0ejt0yauzmxcyufjfmvgdx4xphvmf6882av97326hjfvr7qs72umjf6jq5jmhgmjz4vxj3j09ew4xxa3v92dcdqmwa3eshhq939c24l0ymv6lcf33wmcrr4ty869jl2yksjg33sc885q0wvrzn5wkd4ewgjmn660hgfgcs03r40wzugl7u7tssrunrs5du0scu077hc5vee2vxxtqrsgmmvg3h5usg8mcjk4yf8gnx6g6pzy076gv3ysxn6vspp3s6eyk2e39dhpj98r9u656kqa3c2tatkw3uucunru92d4z45yqp8q2wy4py3uyp0n9rsu2dv29xqvhnjh8tw324qc6favu59t7mryvz50d96sq2njfmsdqvqw3fvjxfvvrhldzllfasrlr69qt9ujtdeezycx7axwwc3jt5fhydfq7mcgdt4xuf8v4v6kk7y8fe5xxlyfyuhwlqlvpce0yjr2pnf264m5llgtprkpwa940f4n6ju4kgh0vnstw8lnw99pe9ta06pyccuqkdr6p6dkq3kk7v8mw2pxp0vzex0semjau6cewmtdlluqlkwxx9y6cuf0uaj3262qs640arlw99wfsxgzc3ev3r5fkqvy9v028gtr9mfs7s3yuyrug56qtdx0w76azyt3exfeetuqdxx9dm9k70er2ky9dqyjzfrd0ezesz55h8pqp2pltylyaptt7l9pf92qtj5cye7q2ezk2567v6hwus58rdrxefprcgshscg7ttc4hsact5c57zc6kqretwqs6dxk00qyznfz9uxzuuufekt275mxxcvf8ad4su08u3k5d56gptxcpjsg60d3qm7e4ryyqajxlq6kf4659jhvqv52fvs0ztv9zmrkz3y08hd9snurakf3fth9202gwur8gmrs3g4pdqunmrugk8kttsdxmhyegzwg46vcytuas4q0nsrjxanng6jp896szgtqm6xf5l3v86kyy5lxxtn2ht6j5wy5mkygmwus9fpzkrwqdzht3up28mesr6rfzj3pvepgdyq5nhsqzdrcu2u3xcwnx6ujvght6hgr4qg555dky50uvqxete2xcf4e6udh2d76ulakfe4uv3uxly93p4tpx4fdxgezyq9yxpmk2730akezna9fswmakxzg9446nft0ry2zy2ftnra9lr6m3vx96xszwd44rnrewt0x5fhjj248psmyztt899y28y4h2g5j3veq294np5wqd7vnn27zmkqxzadn5ylj0m3465t4fzzvrmmftdurlcxpxzj0zxmk2nhjw3h7ggtgvgzxe4wasjcfd4xflrzxs7ejp73 + - &staging_master age1w8tg8mpwj2ujxw0p9k36cpgecq285luwl4wf7a5tjtej4t2wffcq0gnzdw # Host Keys (Used by the specific VM to decrypt its own secrets at boot) # - &host_control_center age1... diff --git a/BOOTSTRAP.md b/BOOTSTRAP.md index 0db25b7..f1ceecb 100644 --- a/BOOTSTRAP.md +++ b/BOOTSTRAP.md @@ -2,28 +2,29 @@ This document outlines the manual, real-world steps required to initialize the NixOS GitOps environment for the first time. You must perform these steps before the CI/CD pipeline or any automated staging environments can function. -## 1. Secret Management Initialization (SOPS-Nix) +## Secret Management Initialization We use `sops-nix` to manage secrets, adhering to a strict separation between Production and Staging. You must generate these keys locally on a secure workstation. **Prerequisites:** Install `age` ([age documentation](https://github.com/FiloSottile/age)). 1. **Generate the Production Master Key:** + ```bash - age-keygen -o prod-master.txt + age-keygen -o prod-master.age ``` > [!CAUTION] - > Move `prod-master.txt` to a secure offline USB drive and/or print it on paper. **Do not** store this private key on any server. + > It is recommended to move `prod-master.age` to a secure offline USB drive and/or print it on paper. 2. **Generate the Staging Master Key:** ```bash - age-keygen -o staging-master.txt + age-keygen -o staging-master.age ``` 3. **Update Configuration:** - Open both `.txt` files and copy their **Public Keys** (the strings starting with `age1...`). Open `.sops.yaml` in the root of this repository and replace the `# TODO` placeholders with your newly generated public keys. Commit and push this change. + Open both `.age` files and copy their **Public Keys** (the strings starting with `age1...`). Open `.sops.yaml` in the root of this repository and replace the placeholders with your newly generated public keys. Commit and push this change. -## 2. Proxmox Hypervisor Authentication & State +## Proxmox Hypervisor Authentication & State The CI/CD pipeline needs restricted API access to Proxmox to provision Virtual Machines. @@ -46,7 +47,7 @@ The CI/CD pipeline needs restricted API access to Proxmox to provision Virtual M 3. Terraform will prompt you. You will need to provide your Proxmox `root@pam` credentials via environment variables or prompt. 4. Upon successful completion, the script will output a secure **API Token**. Copy this token securely. -## 3. Forgejo Secrets Configuration +## Forgejo Secrets Configuration The CI/CD actions require access to the Proxmox token and the staging secret key. @@ -56,7 +57,7 @@ The CI/CD actions require access to the Proxmox token and the staging secret key * `PROXMOX_TOKEN_SECRET`: Paste the token generated from Step 2. * `RENOVATE_TOKEN`: Create a Personal Access Token (PAT) for your user in Forgejo with read/write access to code and pull requests, and paste it here. -## 4. Staging Golden Key Provisioning (Proxmox Snippet) +## Staging Golden Key Provisioning (Proxmox Snippet) Instead of relying on Forgejo CI/CD to store the staging private key, we use a secure hypervisor-level Cloud-Init snippet. @@ -76,7 +77,7 @@ Instead of relying on Forgejo CI/CD to store the staging private key, we use a s ``` 3. This completely removes the secret from Forgejo. When Terraform spins up a staging VM, it simply tells Proxmox to attach this local snippet! -## 5. TrueNAS API Security (RBAC) +## TrueNAS API Security (RBAC) To prevent the CI/CD pipeline from having `root` access to your TrueNAS server, you must run the RBAC bootstrap script to create a restricted user (`forgejo-ci`) that can *only* clone datasets for staging, not destroy production data.