PALO-AI Online VPS Deployment#
Status: Internet-reachable developer-preview deployment topology documented for PALO-AI v2.7. Deployments created from the v2.5 baseline must be upgraded and revalidated separately; this document does not assert that a live endpoint has already been upgraded. HTTPS and network isolation do not remove the blockers tracked in the public Production Readiness plan.
Live deployment status#
The reference developer-preview endpoint was deployed on 17 July 2026:
| Item | Live state |
|---|---|
| Public hostname | https://governance.paloframework.org |
| MCP transport | Dual-era Streamable HTTP at /mcp; current Compose uses shared bearer, while the runtime also supports OIDC/JWKS resource-server mode |
| Knowledge MCP transport | Dedicated OIDC-only Reader at /mcp-guide and separate ten-tool Curator at /mcp-guide-curator, backed by the self-hosted PALO identity realm; each release still requires live qualification |
| Identity | Keycloak 26.7.2 and PostgreSQL, self-hosted on the PALO VPS; public realm/OIDC routes only, with administration excluded from nginx/Caddy |
| Gateway | HTTPS under /gateway, bearer-authenticated and route-limited |
| Policy engine | OPA 1.17.0, Docker-internal only |
| TLS | Let's Encrypt ECDSA certificate with automatic renewal |
| Persistence | SQLite WAL reference state, transactional outbox and append-only evidence chain in a Docker volume |
| Release classification | Developer preview; non-production |
The live smoke test verifies HTTPS health, anonymous rejection and authenticated registry access. Public agent/policy/executor/verifier registration, approval resolution, approval enumeration, incident enumeration/resolution and direct evidence submission return 404. The remote MCP server exposes only six low-privilege governance tools; administrative and governed-execution MCP tools remain unavailable over the Internet.
Address model#
The deployment deliberately uses both private and public addresses:
| Address | Visibility | Purpose |
|---|---|---|
http://opa:8181 |
Docker network only | PALO-to-OPA policy evaluation |
http://palo-gateway:8787 |
Docker network only | Gateway behind the TLS proxy |
http://127.0.0.1:18877 |
Current VPS host only | Administrative profile registration over SSH |
http://127.0.0.1:18878 |
Current VPS host only | nginx-to-MCP proxy target |
http://127.0.0.1:18879 |
Current VPS host only | nginx-to-guide-MCP proxy target |
http://127.0.0.1:18880 |
Current VPS host only | nginx-to-Hub-control-plane target when the opt-in profile is enabled |
http://127.0.0.1:18881 |
Current VPS host only | nginx-to-Hub-UI target when the opt-in profile is enabled |
http://127.0.0.1:18882 |
Current VPS host only | nginx-to-Knowledge-Curator MCP proxy target |
http://127.0.0.1:18883 |
Current VPS host only | nginx-to-PALO-identity proxy target; the admin route is not published |
http://127.0.0.1:19000 |
Current VPS host only | Keycloak management health target |
http://palo-mcp:8788 |
Docker network only | MCP service behind the TLS proxy |
http://palo-guide-mcp:8789 |
Docker network only | Six-tool PALO Knowledge Reader behind the TLS proxy |
http://palo-guide-curator-mcp:8790 |
Docker network only | Ten-tool PALO Knowledge Curator behind the TLS proxy |
http://palo-identity:8080 |
Docker network or VPS loopback only | PALO-owned OIDC authorization server |
https://governance.paloframework.org/gateway |
Internet, authenticated | n8n/Dify adapter base URL |
https://governance.paloframework.org/mcp |
Internet, authenticated | Streamable HTTP MCP endpoint |
https://governance.paloframework.org/mcp-guide |
Internet, separately authenticated | Six read-only PALO Knowledge tools after this release is deployed |
https://governance.paloframework.org/mcp-guide/mcp |
Internet, separately authenticated | Reader compatibility alias for clients that infer Streamable HTTP from the final path segment |
https://governance.paloframework.org/mcp-guide-curator |
Internet, separately authenticated | Four curation operations plus Reader after this release is deployed |
https://governance.paloframework.org/mcp-guide-curator/mcp |
Internet, separately authenticated | Curator compatibility alias; canonical OAuth audience remains the non-alias endpoint |
https://governance.paloframework.org/hub/ |
Internet, organization-authenticated | Operational Governance Builder after external prerequisites and profile activation |
https://governance.paloframework.org/control-plane/ |
Internet, browser BFF only | OIDC session, adapter, simulation and configuration lifecycle APIs |
8181 is therefore not the public endpoint. It remains private even when the complete stack runs online on the VPS.
Private does not mean production-authenticated. The reference PALO services call OPA over HTTP inside the isolated Docker network. Before consequential deployment, threat-model sibling-container and host compromise, add authenticated policy distribution and evaluated-bundle provenance, and use mTLS or an equivalent workload-identity control when the deployment boundary requires it.
Supplied deployment#
The files under deploy/vps/palo-ai/ provide two reverse-proxy variants:
compose.host-nginx.yamlandnginx-governance.conffor the current Hostinger VPS, where nginx already serves other applications;compose.yamlandCaddyfilefor a clean VPS where PALO can own ports 80 and 443.
Both variants provide:
- Docker Compose orchestration;
- PALO-owned Keycloak 26.7.2 identity service with a separate PostgreSQL volume, five-minute access tokens, brute-force protection and audience-bound Reader/Curator clients;
- OPA 1.17.0 on a private internal network;
- PALO Gateway and MCP containers built from this repository;
- HTTPS termination and redirect through existing nginx/Certbot or Caddy 2.11.4;
- separate Docker secret files for Gateway, MCP, HMAC, identity database/admin and deployment-smoke clients;
- a dedicated volume-free Reader image with exact six-tool catalog, immutable release digest, strict OIDC audience and no PALO-AI runtime; Curator uses a different OIDC client allowlist, audience, storage boundary and exact ten-tool catalog;
- persistent PALO data and Caddy certificate volumes;
- non-root PALO containers, read-only filesystems, dropped capabilities and health checks;
- an explicit MCP host allowlist;
- public blocking of registry administration, policy registration, approval resolution and direct evidence submission;
- a VPS-local administration port bound only to
127.0.0.1.
They also contain opt-in hub-migration and hub-control-plane profiles. These profiles are inactive by default and require externally provisioned OIDC, managed PostgreSQL, a tenant-enforcing adapter and remote signer. Follow the Governance Hub control-plane operations runbook; do not activate them with the bundled unscoped preview Gateway presented as a production tenant adapter.
The OPA and Caddy versions were current stable releases when this file was prepared. Pin image digests as well as tags before a consequential deployment.
Prerequisites#
- A Linux VPS with a public IP and SSH access.
- A dedicated hostname such as
governance.paloframework.org. - An
Arecord, and anAAAArecord only if IPv6 is correctly configured, pointing that hostname to the VPS. - TCP ports 80 and 443 reachable by Caddy; UDP 443 is optional for HTTP/3.
- Docker Engine with the Compose plugin.
- No other service occupying ports 80 or 443.
Caddy can obtain and renew a public certificate only after DNS points to the VPS and ports 80/443 are reachable.
Configure the VPS#
Clone or upload the repository, then from its root:
cd deploy/vps/palo-ai
cp .env.example .envEdit .env:
PALO_DOMAIN=governance.paloframework.org
ACME_EMAIL=security@paloframework.org
PALO_ADMIN_URL=http://127.0.0.1:18877
PALO_OIDC_ALGORITHMS=RS256
PALO_OIDC_TOKEN_TYPE=JWT
PALO_READER_OIDC_ALLOWED_CLIENT_IDS=palo-reader-smoke
PALO_CURATOR_OIDC_ALLOWED_CLIENT_IDS=palo-curator-smoke
PALO_OIDC_ALLOWED_TENANTS=palo
PALO_READER_RATE_LIMIT_PER_MINUTE=120
OPA_IMAGE=openpolicyagent/opa:1.17.0-static
CADDY_IMAGE=caddy:2.11.4-alpineGenerate protected secrets without printing them:
sh setup-secrets.sh
sh setup-identity-secrets.shThe generated .env and secrets/ contents are ignored by Git. Back them up through a protected secret-management process; never upload or commit them.
When upgrading an existing deployment, preserve the existing core secrets and create only the four missing identity secrets:
sh setup-identity-secrets.shNeither setup script overwrites an existing secret. Back up the new PostgreSQL volume and identity secrets through the protected VPS process before onboarding users or clients.
Firewall#
Preserve SSH access before enabling a firewall. A typical UFW policy is:
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 443/udp
sudo ufw enableDo not open 8181, 8787, 8788, 8789, 18877, 18878, 18879, 18882, 18883 or 19000 publicly. The Hostinger Compose variant publishes these service ports only on the VPS loopback interface; the clean-VPS variant keeps its administration binding on loopback as documented in its Compose file.
When the Hub profile is enabled, do not open 18880 or 18881 publicly either. nginx or Caddy is the only Internet-facing path.
Start the online stack#
The supplied VPS currently runs nginx and Certbot for other services. On that host, use compose.host-nginx.yaml; it binds PALO only to loopback ports 18877 and 18878, leaving the existing ports and sites untouched. The generic compose.yaml with Caddy is for a clean VPS where ports 80/443 are free.
For the existing Hostinger VPS:
docker compose -f compose.host-nginx.yaml config
docker compose -f compose.host-nginx.yaml pull
docker compose -f compose.host-nginx.yaml build --pull
docker compose -f compose.host-nginx.yaml up -dInstall nginx-governance.conf as a new site, validate with nginx -t, reload nginx, then obtain the certificate with Certbot only after DNS resolves:
sudo certbot --nginx \
-d governance.paloframework.org \
--non-interactive --agree-tos \
--email sev7en@gmail.com \
--redirectFor a clean VPS using Caddy instead:
Validate configuration, pull/build and start:
docker compose config
docker compose pull
docker compose build --pull
docker compose up -d
docker compose psFollow startup and certificate issuance:
docker compose logs --tail=100 opa palo-gateway palo-mcp caddyExpected public endpoints:
https://governance.paloframework.org/mcp-health
https://governance.paloframework.org/mcp
https://governance.paloframework.org/mcp-guide-health
https://governance.paloframework.org/mcp-guide
https://governance.paloframework.org/mcp-guide/mcp
https://governance.paloframework.org/mcp-guide-curator-health
https://governance.paloframework.org/mcp-guide-curator
https://governance.paloframework.org/mcp-guide-curator/mcp
https://governance.paloframework.org/identity-health
https://governance.paloframework.org/identity/realms/palo/.well-known/openid-configuration
https://governance.paloframework.org/gateway/v1/registry
https://governance.paloframework.org/gateway/v1/actions/verifyAfter the separate Hub admission prerequisites, migration and opt-in profile are complete, the additional endpoints are:
https://governance.paloframework.org/hub/
https://governance.paloframework.org/control-plane/healthRegister an authority profile#
Administrative registration is intentionally not exposed through the public reverse proxy. SSH into the VPS and use the loopback-only gateway. The current Hostinger deployment reads PALO_ADMIN_URL=http://127.0.0.1:18877 from .env:
sh register-profile.sh \
case-runtime-example \
../../../schemas/fixtures/palo-agentic-interface.valid.jsonThe supplied profile is development data. Before external testing, create a new versioned profile with the correct agent ID, case, tools, hosts, argument schemas, scopes and HMAC key ID.
Verify the online endpoint#
sh smoke-online.shThis checks:
- the operational, Reader and Curator MCP health endpoints over HTTPS;
- rejection of anonymous operational, Reader and Curator MCP requests;
- short-lived service tokens issued by the PALO identity realm with different client IDs, scopes and exact Reader/Curator audiences;
- authenticated Reader/Curator initialization and exact 6/10-tool catalogs without operational tools;
- authenticated access to the public Gateway registry.
Inspect service-local health when troubleshooting:
docker compose -f compose.host-nginx.yaml ps
curl --fail http://127.0.0.1:18877/healthConnect n8n#
For the current n8n alpha node, configure:
Gateway URL: https://governance.paloframework.org/gateway
Bearer Token: contents of secrets/gateway-tokenUse n8n encrypted credentials; never put the token in workflow JSON or node output.
For knowledge Q&A, the current n8n MCP Client Tool v1.4 supports Streamable HTTP and can connect directly to Reader or Curator. Use the supplied node examples, force serverTransport to =httpStreamable, keep credentials in n8n's encrypted credential store and qualify the exact n8n build before go-live. The HTTPS Gateway remains a separate path for the operational PALO control-plane preview; it is not required for Reader Q&A and does not turn an AI Agent into an enforced execution boundary.
Connect other MCP clients#
Reader and Curator run only in OIDC/JWKS mode. Their RFC 9728 documents advertise https://governance.paloframework.org/identity/realms/palo, and each runtime validates issuer, exact audience, signed token type, approved client ID, PALO tenant and least-privilege scopes. The REST Gateway retains its separate preview token until an identity-aware BFF is implemented. PALO does not implement the EMA ID-JAG exchange.
For clients that support Streamable HTTP:
Endpoint: https://governance.paloframework.org/mcp
Authorization: Bearer <contents of secrets/mcp-token>Expose only the PALO-governed tools to an agent. Do not make equivalent privileged target tools available through a parallel ungoverned MCP server.
For PALO explanation, deterministic route inference and knowledge Q&A, use the Reader endpoint with a short-lived OIDC access token carrying palo:guide and palo:knowledge:read:
Endpoint: https://governance.paloframework.org/mcp-guide
Authorization: Bearer <OIDC access token for the exact /mcp-guide audience>
Tools: 3 guide tools + palo_list_knowledge_sources, palo_search_knowledge, palo_get_knowledge_recordClients that infer the transport from the last path segment may use /mcp-guide/mcp; the audience remains the canonical /mcp-guide URL. Use /mcp-guide-curator (or its /mcp alias) only with a separately registered, explicitly allowlisted Curator OAuth client. It adds submit/list/get/review draft operations; it does not expose operational PALO-AI tools. Complete the Reader production gates and host qualification before marking any client live.
Register a distinct OAuth client per deployment boundary and keep confidential-client secrets outside public browser JavaScript. Public clients must use authorization code with PKCE and an exact registered redirect URI.
Public-route boundary#
The public reverse proxy currently exposes:
- MCP
/mcp, its health endpoint and the OIDC protected-resource metadata path; the configured remote tool allowlist remains decision/status oriented and excludes administrative and execution tools; - Knowledge Reader
/mcp-guideand Curator/mcp-guide-curator, plus their terminal-/mcpcompatibility aliases, each separately authenticated and limited to its exact 6/10-tool catalog; - Gateway health and authenticated registry read;
- authenticated Action Claim verification and full-cycle governed execution;
- authenticated execution detail, outcome read and explicit re-verification addressed by execution ID;
- authenticated approval status read only when addressed by approval ID;
- authenticated incident detail read only when addressed by incident ID;
- authenticated ledger verification.
It blocks public agent/policy/executor/verifier registration, approval enumeration, approval resolution, incident enumeration, incident resolution and direct evidence submission. Every non-health Gateway route still relies on one coarse preview bearer token. The execution routes are provided only for isolated n8n/Dify evaluation with mock or reversible actions; they are not a browser API or a multi-tenant authorization boundary.
The opt-in Governance Hub now calls a separate BFF that implements OIDC, tenant context, RBAC, redaction, CSRF and author/reviewer separation without placing this bearer token in browser code or storage. The BFF accepts a production adapter only when its deployment configuration attests upstream tenant enforcement. The bundled Gateway does not meet that condition, so this implementation does not upgrade the Gateway or execution runtime to production.
Next implementation gates#
The online endpoint is ready for a controlled design-partner pilot with mock or reversible actions. The next gates are:
- install the packed
n8n-nodes-palo-aialpha in a disposable self-hosted n8n instance; - store the Gateway URL and bearer token in n8n encrypted credentials;
- register a pilot-specific authority profile through SSH, never through the public hostname;
- demonstrate
deny,pending_approvalandallowbranches with a non-consequential target tool; - add authenticated Web/mobile reviewer identity before enabling public approval resolution;
- make the governed executor unavoidable so a workflow cannot bypass PALO;
- replace preview identity, key and persistence controls before any production authorization claim.
Update and rollback#
Before an update:
docker compose ps
docker compose logs --tail=200 > pre-update.logUse an immutable Git tag or commit and pinned image digests. Then:
docker compose build --pull
docker compose up -d
sh smoke-online.shRollback means checking out the previous known-good commit and restoring the compatible data backup before rebuilding. Schema and policy migrations need an explicit compatibility plan; do not assume container rollback alone reverses stored state.
Backup warning#
The current SQLite volume is suitable only for the developer preview. Back it up while PALO services are stopped or through a SQLite-aware backup process. A production system requires a transactional database/outbox, tested restore, retention controls, key rotation and tamper-resistant evidence anchoring.
Remaining production boundary#
Putting the operational /mcp or Gateway endpoint online does not make PALO-AI production-ready. Its shared-token compatibility path, optional n8n gate, evidence provenance, policy-bundle attestation, approval identity, cached authorization and effective resource-to-scope binding issues remain. Use mock, reversible or non-consequential actions until those findings are closed. The separate canonical-only Reader follows its narrower production profile and live gates; that status does not transfer to the operational runtime or Curator.
See the public Production Readiness route, Capability Matrix, and integration guide. Internal assessment workpapers are not published.
PALO FRAMEWORK