- Phoenix API Railing: proxy to PHOENIX_RAILING_URL, tenant me routes - Tenant-auth: X-API-Key support for /api/v1/* (api_keys table) - Migration 026: api_keys table; 025 sovereign stack marketplace - GET /graphql/schema, GET /graphql-playground, api/docs OpenAPI - Integration tests: phoenix-railing.test.ts - docs/api/API_VERSIONING: /api/v1/ railing alignment - docs/phoenix/PORTAL_RAILING_WIRING Made-with: Cursor
3.4 KiB
Phoenix Portal — API Railing Wiring
Purpose: How the Phoenix Portal (UX/UI) calls the Phoenix API Railing for infrastructure, VMs, and health.
Related: Phoenix API Railing Spec (proxmox repo: docs/02-architecture/PHOENIX_API_RAILING_SPEC.md)
1. Base URL
Portal should call the Phoenix API (GraphQL + REST). When running locally: http://localhost:4000. In production: https://api.phoenix.sankofa.nexus (or the configured API URL). All REST railing routes are under /api/v1/.
2. Infrastructure Overview (Portal)
| Portal area | REST endpoint | Notes |
|---|---|---|
| Cluster nodes | GET /api/v1/infra/nodes |
Returns { nodes: [...] }; each node has node, status, cpu, mem, etc. |
| Storage pools | GET /api/v1/infra/storage |
Returns { storage: [...] }. |
Auth: Use the same session/token as for GraphQL (Keycloak OIDC). The Phoenix API forwards these to the railing (phoenix-deploy-api or internal) when PHOENIX_RAILING_URL is set.
3. VM/CT List and Actions (Portal)
| Portal area | REST endpoint | Notes |
|---|---|---|
| List VMs/CTs | GET /api/v1/ve/vms?node=<node> |
Optional node query to filter by Proxmox node. |
| VM/CT status | `GET /api/v1/ve/vms/:node/:vmid/status?type=lxc | qemu` |
| Start | `POST /api/v1/ve/vms/:node/:vmid/start?type=lxc | qemu` |
| Stop | `POST /api/v1/ve/vms/:node/:vmid/stop?type=lxc | qemu` |
| Reboot | `POST /api/v1/ve/vms/:node/:vmid/reboot?type=lxc | qemu` |
Auth: Required. Gate destructive actions (start/stop/reboot) by role in the API; Portal should only show actions when the user has permission.
4. Health / Dashboards (Portal)
| Portal area | REST endpoint | Notes |
|---|---|---|
| Health summary | GET /api/v1/health/summary |
Returns { status, hosts, alerts, updated_at }. |
| Metrics (PromQL) | GET /api/v1/health/metrics?query=<encoded PromQL> |
Proxy to Prometheus; use for custom dashboards. |
| Active alerts | GET /api/v1/health/alerts |
Returns { alerts: [...] }. |
5. Tenant-Scoped (Client API)
For tenant users (API key or JWT with tenant scope):
| Endpoint | Description |
|---|---|
GET /api/v1/tenants/me/resources |
Resources for the current tenant (from tenantContext). |
GET /api/v1/tenants/me/health |
Health summary (proxied to railing when configured). |
Auth: Require Authorization: Bearer <token> with tenant claim or API key with tenant scope.
6. Keycloak Integration
Portal authenticates via Keycloak (OIDC). Backend (Portal server or BFF) should obtain a token and call the Phoenix API with Authorization: Bearer <access_token>. The Phoenix API validates the token and sets tenantContext from the token claims; railing proxy and tenant me routes use that context.
7. Implementation Checklist
- 3.1 Portal: Infrastructure overview page — fetch
GET /api/v1/infra/nodesandGET /api/v1/infra/storage, display hosts and storage. - 3.2 Portal: VM/CT list — fetch
GET /api/v1/ve/vms, display table; buttons for start/stop/reboot call the POST endpoints. - 3.3 Portal: Health/dashboards — fetch
GET /api/v1/health/summaryand optionallyGET /api/v1/health/alerts; render status and alerts. - 3.4 Keycloak: Ensure Portal backend or BFF uses server-side token for API calls; token includes tenant when applicable.