Files
proxmox/phoenix-deploy-api
Devin AI 57c717ad7e
Some checks failed
AI Code Review / claude-review (pull_request) Failing after 48s
security(phase1a): Phoenix Vault rotation runbook + consumer-prep scaffolding
Part of the sequenced cleanup tracked in issue #1.

Scaffolding only — no rotation executed, no secret values committed.

- docs/runbooks/PHOENIX_VAULT_ROTATION_RUNBOOK.md: authoritative
  Phoenix Vault rotation procedure (9-step: new root → rekey unseal
  → regenerate AppRoles → flip consumers → revoke old). Verification
  table + rollback path + Phase 2 handoff notes.
- docs/04-configuration/VAULT_SHARD_CUSTODY_POLICY.md: decision
  record for the next rotation. Three options documented
  (named-operator / cloud-KMS auto-unseal / Transit auto-unseal);
  selection pending operator sign-off before rotation executes.
- scripts/verify/enumerate-vault-consumers.sh: read-only grep over
  the tree for VAULT_ROLE_ID / VAULT_SECRET_ID / auth/approle/login
  references; flags which top-level consumers need a coordinated
  .env update at §1.6 of the runbook.
- scripts/verify/verify-vault-approle-auth.sh: post-rotation sanity
  check — posts AppRole login + token lookup-self; returns PASS/FAIL
  without echoing the Role ID, Secret ID, or client token.
- phoenix-deploy-api/.env.example: added VAULT_ADDR / VAULT_ROLE_ID
  / VAULT_SECRET_ID placeholder block with a pointer to the runbook.
  No values committed.
- mission-control/.env.example: NEW file (previously had none);
  documents the launchpad NEXT_PUBLIC_* vars and the same
  Vault AppRole placeholder block. Server-side only — never
  NEXT_PUBLIC_*.

Rotation execution stays with Phoenix ops; this commit only stages
the runbook + env scaffolding so the eventual rotation does not
require inventing infrastructure mid-incident.

Co-Authored-By: Nakamoto, S <defi@defi-oracle.io>
2026-04-18 20:19:06 +00:00
..

Phoenix Deploy API

Gitea webhook receiver and deploy endpoint stub for Gitea → Phoenix deployment integration.

Endpoints

Method Path Description
POST /webhook/gitea Receives Gitea push/tag/PR webhooks
POST /api/deploy Deploy request (repo, branch, target)
GET /api/v1/infra/nodes Cluster nodes (Proxmox; stub if PROXMOX_* unset)
GET /api/v1/infra/storage Storage pools (Proxmox; stub if unset)
GET /api/v1/ve/vms List VMs/CTs (optional ?node=)
GET /api/v1/ve/vms/:node/:vmid/status VM/CT status (?type=lxc for containers)
POST /api/v1/ve/vms/:node/:vmid/start, stop, reboot VM/CT lifecycle (set PHOENIX_VE_LIFECYCLE_ENABLED=1)
GET /api/v1/health/metrics Prometheus query proxy (?query=<PromQL>)
GET /api/v1/health/alerts Active alerts (optional PROMETHEUS_ALERTS_URL)
GET /api/v1/health/summary Aggregated health for Portal
GET /api/v1/public-sector/programs Public-sector / eIDAS program manifest (JSON; no API key)
GET /health Health check

All /api/v1/* routes except GET /api/v1/public-sector/programs accept optional partner API key when PHOENIX_PARTNER_KEYS is set (X-API-Key or Authorization: Bearer <key>).

Environment

Copy .env.example to .env and set GITEA_TOKEN (and optionally PHOENIX_DEPLOY_SECRET).

Variable Default Description
PORT 4001 Listen port
GITEA_URL https://gitea.d-bis.org Gitea instance URL
GITEA_TOKEN Token for commit status API
PHOENIX_DEPLOY_SECRET Optional secret for webhook/deploy auth
PROXMOX_HOST Proxmox host (IP or hostname) for API Railing
PROXMOX_PORT 8006 Proxmox API port
PROXMOX_USER root@pam Proxmox API user
PROXMOX_TOKEN_NAME Proxmox API token name
PROXMOX_TOKEN_VALUE Proxmox API token secret
PROXMOX_TLS_VERIFY 1 Set to 0 to allow self-signed Proxmox certs
PHOENIX_VE_LIFECYCLE_ENABLED 0 Set to 1 to enable VM/CT start/stop/reboot
PROMETHEUS_URL http://localhost:9090 Prometheus base URL for Health API
PROMETHEUS_ALERTS_URL (PROMETHEUS_URL)/api/v1/alerts Optional; use Alertmanager URL for firing alerts
PHOENIX_WEBHOOK_URL Outbound webhook URL; POST deploy events with X-Phoenix-Signature
PHOENIX_WEBHOOK_SECRET Secret to sign webhook payloads (HMAC-SHA256)
PHOENIX_PARTNER_KEYS Comma-separated API keys for /api/v1/* (optional)
PUBLIC_SECTOR_MANIFEST_PATH Override JSON path for /api/v1/public-sector/programs
PHOENIX_REPO_ROOT Proxmox repo root; loads config/public-sector-program-manifest.json if present

Program manifest: From a full repo checkout, the file is config/public-sector-program-manifest.json. scripts/install-systemd.sh copies it next to server.js on /opt/phoenix-deploy-api so the endpoint works without a full tree.

Gitea Webhook Configuration

In Gitea: Repository → Settings → Webhooks → Add Webhook

  • URL: https://phoenix-api-host/api/webhook/gitea (or your Phoenix API URL)
  • Content type: application/json
  • Events: Push events, Tag creation (and optionally Pull requests)
  • Secret: Optional, set PHOENIX_DEPLOY_SECRET to match

Deploy API (Trigger from Gitea Actions)

curl -X POST "https://phoenix-api-host/api/deploy" \
  -H "Authorization: Bearer $PHOENIX_DEPLOY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"repo":"d-bis/proxmox","branch":"main","sha":"abc123","target":"default"}'

Integration with Sankofa Phoenix

This service is a standalone stub. Full deployment logic should be implemented in the Sankofa Phoenix API (VMID 8600). Migrate the webhook handler and deploy logic into the Phoenix API when ready.

OpenAPI / Swagger

  • Spec: openapi.yaml
  • HTML doc: docs/index.html — static Swagger UI; open locally or serve from phoenix-deploy-api/docs/ (loads ../openapi.yaml). To serve in-app, add swagger-ui-express and mount at e.g. /api-docs.

Run

npm install
GITEA_TOKEN=xxx npm start