# Private Run read permits Execution Core owns a `PrivateReadPermit` aggregate in its existing isolated aggregate store. The aggregate records one requesting Party, canonical Run and Attempt, immutable native material digest, read kind, exact path, maximum response size and absolute expiry. It has one issued state and becomes unusable at expiry; there is no renewal transition. The aggregate and command receipt commit together. The authenticated API exposes `POST /api/v1/runs/{runId}/read-permits`, requiring `attemptId`, `kind` (`output`, `logs` or `endpoint`), `path` and `maxBytes`. `Idempotency-Key` names the new permit and `If-Match: "0"` requires a new identity. The command result carries that permit ID. `GET /api/v1/run-read-permits/{permitId}` returns the permit only to its requesting Party while their permission remains current. The API supplies the authenticated Party; the body cannot select one. Issue and use both require current Beto `runs.output.view` for the Run's Project. They do not require the initiating member to remain a member. Terminal Runs remain readable, and a replacement authorised member can obtain their own permit. Each permit lasts at most 60 seconds and permits at most 4 MiB. A replay retains the original expiry. Batch output paths must be declared by the saved Run, logs use an empty path, and service endpoint paths reject traversal and external destinations. The native binding and its generation are the viewer's own in the Run's allocation, confirmed by the Site through Resource Provisioning, so a Run stays readable after its initiator's account is released. A viewer with no account there is refused (#932). That includes a member added moments ago, before Resource Provisioning lists any account for them, so the refusal is not permanent: they can ask again once it does. An inaccessible Run or read permit returns the same `not_found` error as a missing one, including when a permit belongs to another viewer or its viewer has lost Project permission. An authorised viewer can still distinguish their expired permit and request a new one. Unavailable authority remains a retryable failure. Site API's protected `POST /v1/site/executions/authorise-read` confirms a permit for its registered Site. It returns the exact saved native material and the viewer's confirmed binding, plus the permit's viewer and scope. The native Runtime and admission process use separate Site identities. A read permit cannot create user work, issue repository write credentials or extend accepted dispatch. Runtime rechecks current permission before returning bytes and admits only the fixed read-only workspace helper where a file read requires one. The public API issues and describes permits. Existing Runtime public read methods perform the bounded data reads; the platform API does not yet proxy those bytes. The real-owner qualification lane exercises API issuance and those Runtime methods. Sources: the [public API schema](../../../../contracts/execution_core/http_api/private-reads.paths.json), [owner Protobuf requests](../../contracts/requests/proto/pharos/requests/v1/contexts/execution_core/requests.proto) and [Site authority schema](../../../../contracts/http/site-private-reads.v1.yaml).