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-Knowledge-Curator MCP proxy target |
http://127.0.0.1:18881 |
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 |
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.
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 or 18879 publicly. The Hostinger Compose variant publishes 18877, 18878 and 18879 only on the VPS loopback interface; the clean-VPS variant keeps its administration binding on loopback as documented in its Compose file.
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/verifyRegister 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. A future Governance Hub must call a BFF that applies OIDC, tenant context, RBAC/ABAC, redaction and separation of duties rather than placing this bearer token in browser code or storage.
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