# 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 [activation settings](../../gitops/manifests/pharos-site-runtime/serving/README.md). 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.