refactor(security): move staging age key from forgejo secrets to proxmox snippet

This commit is contained in:
Tibo De Peuter 2026-07-17 23:01:44 +02:00
parent 53a539dd91
commit 8fbecaa864
Signed by: tdpeuter
SSH key fingerprint: SHA256:u/h/LVoqKF1Iz02uOyxe6hcjmoZASCGV2HM0TG9ZMoU
3 changed files with 22 additions and 30 deletions

View file

@ -38,7 +38,6 @@ jobs:
TF_VAR_pr_number: ${{ github.event.pull_request.number }}
# VM_ID could be dynamically generated or based on PR number (e.g., 8000 + PR_NUMBER)
TF_VAR_vm_id: ${{ format('8{0:03}', github.event.pull_request.number) }}
TF_VAR_staging_age_key: ${{ secrets.STAGING_AGE_KEY }}
# TrueNAS integration (Secrets would need to be added to Forgejo)
TRUENAS_IP: "truenas.local"
@ -61,7 +60,6 @@ jobs:
PROXMOX_VE_API_TOKEN: ${{ secrets.PROXMOX_TOKEN_SECRET }}
TF_VAR_pr_number: ${{ github.event.pull_request.number }}
TF_VAR_vm_id: ${{ format('8{0:03}', github.event.pull_request.number) }}
TF_VAR_staging_age_key: ""
# TrueNAS integration
TRUENAS_IP: "truenas.local"

View file

@ -45,8 +45,27 @@ The CI/CD actions require access to the Proxmox token and the staging secret key
2. Go to **Settings > Actions > Secrets** for this repository.
3. Add the following repository secrets:
* `PROXMOX_TOKEN_SECRET`: Paste the token generated from Step 2.
* `STAGING_AGE_KEY`: Paste the *entire contents* of your `staging-master.txt` file (the private key).
* `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)
Instead of relying on Forgejo CI/CD to store the staging private key, we use a secure hypervisor-level Cloud-Init snippet.
1. SSH into your Proxmox server (`pve`).
2. Create the Cloud-Init snippet file:
```bash
cat << 'EOF' > /var/lib/vz/snippets/staging-key.yaml
#cloud-config
write_files:
- path: /var/lib/sops-nix/key.txt
permissions: '0600'
content: |
AGE-SECRET-KEY-1... (paste your staging-master private key here)
runcmd:
- echo "Staging age key injected successfully."
EOF
```
3. This completely removes the secret from Forgejo. When Terraform spins up a staging VM, it simply tells Proxmox to attach this local snippet!
## Next Steps
Once these bootstrap steps are complete, the foundational authentication is in place. The Forgejo CI actions will now have the necessary permissions to build images, provision VMs, and test staging environments autonomously.

View file

@ -17,12 +17,6 @@ variable "pr_number" {
type = string
}
variable "staging_age_key" {
description = "The private age key for decrypting staging secrets. Injected via Cloud-Init."
type = string
sensitive = true
}
provider "proxmox" {
# Relies on PROXMOX_VE_ENDPOINT and PROXMOX_VE_API_TOKEN environment variables
}
@ -58,37 +52,18 @@ resource "proxmox_virtual_environment_vm" "staging_vm" {
# Cloud-Init configuration to inject the staging age key and set up networking
initialization {
initialization {
ip_config {
ipv4 {
address = "dhcp"
}
}
user_data_file_id = proxmox_virtual_environment_file.cloud_config.id
user_data_file_id = "local:snippets/staging-key.yaml"
}
}
resource "proxmox_virtual_environment_file" "cloud_config" {
content_type = "snippets"
datastore_id = "local-zfs"
node_name = "pve"
source_raw {
data = <<-EOF
#cloud-config
write_files:
- path: /var/lib/sops-nix/key.txt
permissions: '0600'
content: |
${indent(10, var.staging_age_key)}
runcmd:
- echo "Staging age key injected successfully."
EOF
file_name = "staging-pr-${var.pr_number}-cloud-init.yaml"
}
}
resource "proxmox_virtual_environment_firewall_options" "staging_vm_fw_options" {
vm_id = proxmox_virtual_environment_vm.staging_vm.vm_id