Private access

How a member or a guest opens a private application: the exchange on the application's host, the host-only access cookie, short resource grants, the two access errors and what privacy cannot hide.

  • Availability: Experimental
  • Evidence: Read from source
  • Reference

Public and private applications

Free applications are public: anyone with the URL can retrieve their resources. A private application is a premium capability that a platform operator enables manually for an organization. It denies its HTML and every restricted resource unless the request carries a valid resource grant. Deny is the default: without access, a private release answers ACCESS_REQUIRED even for paths that do not exist, so it reveals nothing about what it holds.

Who can open a private application

A resource grant stands on one of two things:

  • A guest grant. A person outside the organization holds an application-scoped grant that expires and can be revoked. It is not an account, a membership or a registry credential, and the management API never accepts it. See Access and guests.
  • A member pass. A member of the owning organization whose role includes application.read asks the management API for a one-time member ticket with access.tickets.create. The pass is valid for a confirmation window; asking for a ticket again confirms it again.

The exchange

Access is established on the application's own host, never on a platform host.

Request on the application host Purpose
GET /_beyond/access A static page without application content. Invitation and member links point at it: https://<host>/_beyond/access#token=… for a guest and #ticket=… for a member.
POST /_beyond/access/exchange JSON {"token": "<guest token>"} or {"ticket": "<member ticket>"}. Answers 204 with the access cookie.
POST /_beyond/access/leave Removes the cookie

The secret travels in the URL fragment. A browser never sends a fragment to a server, so the secret reaches no server log, referrer or proxy. The page reads it, posts it to the exchange endpoint and opens /.

A secret that is unknown, already used, expired, revoked or of another application answers 403 ACCESS_DENIED, without saying which. A request whose Origin names another host is refused.

HTTP
Set-Cookie: __Host-beyond-access=<grant token>; Max-Age=<seconds>; Path=/; HttpOnly; Secure; SameSite=Lax

The __Host- prefix makes browsers enforce Secure, Path=/ and the absence of Domain. The cookie is host-only: it can never be scoped to a parent domain shared with the platform or with another tenant. It holds the short resource grant, never the invitation token or the ticket.

Platform credentials have no meaning on an application host. An Authorization header is ignored there, a platform bearer token cannot be exchanged there, and no response sets a platform cookie.

Grants are short and renew themselves

A resource grant is short-lived and never outlives what it stands on. On a request in the second half of its life, the service checks the standing and, while it holds, sets a new grant with a new token on the response. An application that keeps loading keeps its access. A client that stays idle for a whole grant lifetime exchanges again: a guest with the same invitation while it is valid, a member with a new ticket.

What delivery answers

Status Code Meaning
401 ACCESS_REQUIRED No access cookie, or a grant that ran out. Exchange again.
403 ACCESS_DENIED A grant that exists and does not allow this: it was revoked, belongs to another application, or is a guest asking for member-only content such as restricted source maps

Both refusals carry Cache-Control: private, no-store and Vary: Cookie, and no WWW-Authenticate header. A successful response to an authorized request is stored privately, for the lifetime of a grant, and is never public or immutable:

Text
Cache-Control: private, max-age=60
Vary: Cookie

Revocation is bounded, not instant

  • Revoking a guest grant ends the grant and the resource grants standing on it in one transaction. The service refuses the next request with 403 ACCESS_DENIED. What a browser stored privately ages out with its max-age.
  • On any other path, such as an expiry or a lapsed member pass, the resource grant is simply never issued again and runs out by itself.
  • A removed member loses access after the confirmation window plus the time the authority's answer is cached.

A client that is not a browser

An external executor or a script does the same over HTTP:

  1. POST https://<host>/_beyond/access/exchange with Content-Type: application/json and the guest token.
  2. Keep the __Host-beyond-access cookie and send it on every request.
  3. Replace it whenever a response carries Set-Cookie.
  4. When a request answers 401, exchange again.

What privacy does not cover