> For AI agents: the complete documentation index is available at /llms.txt, the full documentation bundle is available at /llms-full.txt.

# 0069 — Project-private Run services

Status: accepted, 6 November 2026. Approved in the #1123 implementation discussion;
live GPU qualification will take place on staging.

## Context

Members need to open Gradio applications and those applications need to call
model services. Existing private output permits cover bounded files, logs and
predictions. Browser applications also need assets, forms and persistent
HTTP/WebSocket connections. Serving application code on a platform login origin
would expose platform browser authority.

## Decision

Services are accessible to current Project members with `runs.output.view`.
Each Run has its own HTTPS origin under an explicitly enrolled serving domain.
The API gateway reserves that domain from all platform handlers. A nonce-bound
redirect flow issues an HttpOnly, Secure, host-only Run handle referring to the
parent API session. The parent login cookie and transport credentials never reach
application containers. The handle grants no independent login or Project authority.

On each request the API revalidates the session, Party and AUP. Over dedicated TLS
it asks the Site Runtime to serve the exact Run for that viewer. Execution Core
checks current output permission and the latest active service Attempt. Site
Coordination authenticates the Runtime; an owner adaptor joins current Project
continuation authority and the viewer's confirmed native binding. Runtime checks
saved material, account UID, service and endpoint UIDs, Pod lineage and workspace
before forwarding to the saved ClusterIP. Callers cannot choose a native host or port.

Open connections recheck both authorities every five seconds. Revocation,
replacement, expiry and unavailable authority close them. Runtime also enforces
the absolute owner deadline independently of refresh. Requests and responses have
byte limits; responses are uncached. Application cookies stay on their Run host.
Unsafe requests and WebSockets require the exact Run origin. Service workers are refused.

The Site Agent admits workload traffic to the declared HTTP port of services in
the same canonical Project on the same Site, across its allocation namespaces.
Admission-controlled Run labels and the reserved port name `pharos-http` constrain
these policies. Cross-Project and general internet access retain existing restrictions.

## Consequences

The Project is the service trust boundary. Its applications can call its model
services without a member cookie. Workloads needing finer separation need a
different Project or a future explicit service policy. Cross-Site networking
and arbitrary internet access require separate decisions.

The gateway carries application traffic, including SSE and WebSockets. Platform
state projections continue to use authorised Centrifugo subscriptions. The bounded
private-read protocol and persisted permits remain unchanged.

Serving is disabled until the Site supplies dedicated DNS, wildcard public TLS,
private API–Runtime credentials and the
<a href="/source/gitops/manifests/pharos-site-runtime/serving/README.md.txt">activation settings</a>.
Existing Runs retain their original native manifests and remain recoverable.
Relaunch them to acquire the named port required by the Project policies.
Staging must qualify real GPU allocation, completed Gradio responses, revocation,
cross-Project denial and resource release before #1123 is live-qualified.

## Public endpoints — approved 8 November 2026

The user approved mixed public and Project-only access. A service action may
explicitly set `options.exposure: public`; the default remains `project`.
Workload Portfolio records the choice in the immutable revision and Execution
Core retains it with the Run. Repository visibility grants no endpoint access.

Anonymous requests first require the Runtime's publication check. Execution Core
confirms the saved public policy, latest active Attempt and current Project
continuation authority. The Site joins the accepted workload account, without
inventing a viewer. Runtime confirms its saved material and exact native
identities. It repeats those checks throughout open connections.

Private requests retain the session, Party, AUP and current Project-permission
checks above. Public requests carry no platform session or viewer. Public HTTP
clients can omit Origin; a supplied browser Origin must name the exact Run host.
Both modes retain isolated origins, host-only application cookies, streaming
limits and platform credential stripping. Public access ends on Run stop,
replacement, Project revocation or authority failure.

Changing the action's publication setting affects new Runs. Operators and
authorised members withdraw an existing public endpoint by stopping its Run.
The public endpoint exposes the application's HTTP surface; authors must keep
private operations behind application-level controls or use Project-only access.

<details class="page-source"><summary>Page source</summary>

<a href="/source/docs/decisions/0069-project-private-run-services.md.txt">Source snapshot</a> · Revision `f928834c8`.

</details>
