feat(security): add truenas rbac automation script
This commit is contained in:
parent
8fbecaa864
commit
67c7cb6ec6
2 changed files with 103 additions and 1 deletions
16
BOOTSTRAP.md
16
BOOTSTRAP.md
|
|
@ -67,5 +67,19 @@ 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!
|
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)
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
1. Ensure you have network access to your TrueNAS host.
|
||||||
|
2. Execute the RBAC setup script:
|
||||||
|
```bash
|
||||||
|
./scripts/truenas-rbac-setup.sh
|
||||||
|
```
|
||||||
|
3. Provide your TrueNAS IP and the `root` Admin API Token when prompted.
|
||||||
|
4. The script will automatically create the custom `ci-runner-role` and the `forgejo-ci` user.
|
||||||
|
5. Follow the terminal output instructions to log into the TrueNAS Web UI as the new user and generate the restricted API token.
|
||||||
|
6. Use this restricted token for the `TRUENAS_API_KEY` secret in Forgejo.
|
||||||
|
|
||||||
## Next Steps
|
## 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.
|
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 and securely.
|
||||||
|
|
|
||||||
88
scripts/truenas-rbac-setup.sh
Executable file
88
scripts/truenas-rbac-setup.sh
Executable file
|
|
@ -0,0 +1,88 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# This script automates the creation of a restricted TrueNAS user (forgejo-ci)
|
||||||
|
# and assigns it a custom privilege role strictly limited to ZFS cloning/snapshots.
|
||||||
|
|
||||||
|
echo "=========================================="
|
||||||
|
echo " TrueNAS RBAC Setup for CI/CD"
|
||||||
|
echo "=========================================="
|
||||||
|
echo "This script will create a custom Privilege Role and a Restricted User."
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
read -p "Enter your TrueNAS IP (e.g., 192.168.0.11): " TRUENAS_IP
|
||||||
|
read -s -p "Enter your current TrueNAS Admin Token (root): " ADMIN_TOKEN
|
||||||
|
echo ""
|
||||||
|
read -p "Enter a password for the new 'forgejo-ci' user: " CI_PASSWORD
|
||||||
|
|
||||||
|
BASE_URL="http://${TRUENAS_IP}/api/v2.0"
|
||||||
|
HEADERS=(
|
||||||
|
"-H" "Authorization: Bearer ${ADMIN_TOKEN}"
|
||||||
|
"-H" "Content-Type: application/json"
|
||||||
|
)
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "1. Creating Custom Privilege (ci-runner-role)..."
|
||||||
|
# In TrueNAS SCALE, we create a privilege that allows specific methods
|
||||||
|
PRIV_PAYLOAD=$(cat <<EOF
|
||||||
|
{
|
||||||
|
"name": "ci-runner-role",
|
||||||
|
"allowlist": [
|
||||||
|
{"method": "zfs.snapshot.create"},
|
||||||
|
{"method": "zfs.snapshot.clone"},
|
||||||
|
{"method": "zfs.dataset.delete"},
|
||||||
|
{"method": "zfs.snapshot.delete"},
|
||||||
|
{"method": "zfs.snapshot.query"},
|
||||||
|
{"method": "zfs.dataset.query"}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
)
|
||||||
|
|
||||||
|
# Attempt to create privilege (ignore if it already exists)
|
||||||
|
HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" -X POST "${BASE_URL}/privilege" "${HEADERS[@]}" -d "${PRIV_PAYLOAD}")
|
||||||
|
if [ "$HTTP_STATUS" -eq 200 ]; then
|
||||||
|
echo " -> Privilege created successfully."
|
||||||
|
elif [ "$HTTP_STATUS" -eq 409 ] || [ "$HTTP_STATUS" -eq 422 ]; then
|
||||||
|
echo " -> Privilege already exists or validation failed (code ${HTTP_STATUS}). Skipping."
|
||||||
|
else
|
||||||
|
echo " -> Warning: Privilege creation returned HTTP ${HTTP_STATUS}. (Your TrueNAS version might handle RBAC differently)."
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "2. Creating Restricted User (forgejo-ci)..."
|
||||||
|
USER_PAYLOAD=$(cat <<EOF
|
||||||
|
{
|
||||||
|
"username": "forgejo-ci",
|
||||||
|
"full_name": "Forgejo CI Runner",
|
||||||
|
"password": "${CI_PASSWORD}",
|
||||||
|
"password_disabled": false,
|
||||||
|
"group_create": true,
|
||||||
|
"attributes": {}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
)
|
||||||
|
|
||||||
|
HTTP_STATUS=$(curl -s -o /tmp/truenas_user.json -w "%{http_code}" -X POST "${BASE_URL}/user" "${HEADERS[@]}" -d "${USER_PAYLOAD}")
|
||||||
|
if [ "$HTTP_STATUS" -eq 200 ]; then
|
||||||
|
echo " -> User created successfully."
|
||||||
|
elif [ "$HTTP_STATUS" -eq 409 ] || [ "$HTTP_STATUS" -eq 422 ]; then
|
||||||
|
echo " -> User already exists. Skipping."
|
||||||
|
else
|
||||||
|
echo " -> Warning: User creation returned HTTP ${HTTP_STATUS}."
|
||||||
|
cat /tmp/truenas_user.json
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=========================================="
|
||||||
|
echo " Setup Complete (or mostly complete)!"
|
||||||
|
echo "=========================================="
|
||||||
|
echo "Because TrueNAS prevents root from generating API tokens for other users,"
|
||||||
|
echo "you must complete the final step manually:"
|
||||||
|
echo ""
|
||||||
|
echo "1. Log into the TrueNAS Web UI at http://${TRUENAS_IP}"
|
||||||
|
echo "2. If the script failed to attach the privilege automatically, go to Credentials > Local Users,"
|
||||||
|
echo " edit 'forgejo-ci', and assign it the ZFS roles."
|
||||||
|
echo "3. Log in as 'forgejo-ci' (or use the API Keys menu as Admin to generate a key for that user)."
|
||||||
|
echo "4. Copy the newly generated token."
|
||||||
|
echo "5. Update the TRUENAS_API_KEY secret in your Forgejo repository."
|
||||||
|
echo "=========================================="
|
||||||
Loading…
Add table
Add a link
Reference in a new issue