Architecture

Read this page first. Every other page in these docs describes one surface; this page is the map that tells you which surface you're on and why it exists. Phosra is built from three planes that are deliberately kept apart:

Control plane

Manage your Phosra account — orgs, phosra_ keys, usage, advisor agents, MCP tokens. Phosra-specific. Bearer auth.

Data plane

The enforcement path — a policy is written, compiled into a signed profile, and enforced locally on the device or platform.

Open OCSS protocol

Vendor-neutral primitives — the Trust List, signed receipts, sealed envelopes, the 123-category vocabulary. Phosra adds zero cryptographic logic here.

Phosra architecture: control plane, data plane, and the open OCSS protocol, with the enforcement path flowing Provider → Census → Platform and every signature verifying to the OCSS Trust List root.
The three planes. Management flows over the control plane; enforcement flows over the data plane; both anchor their trust in the open OCSS protocol.

The mental model in one paragraph

A Provider (a parental-control or safety vendor) writes a child's rules to the census using a signed, RFC-9421 rule-write. The census stores those rules and compiles them into a single signed enforcement profile for each enforcement endpoint. A Platform (an app, OS, router, or school network) fetches that profile once, verifies its signature to the OCSS root in its own process, caches it, and then answers every isAllowed() question locally — no network call, no per-decision latency, fail-closed when the profile is missing. The signatures on the rule-write, the profile, and every receipt are represented as OCSS protocol artifacts in the sandbox: they verify against the documented test Trust List root for that synthetic context.

The separation is intended to make the protocol surface inspectable independently of the product. It does not claim that another provider has adopted the draft or that a production federation exists.


Plane 1 — the control plane

What it is: management operations over your Phosra account. Create developer orgs, provision and revoke phosra_-prefixed API keys, register advisor agents, declare OCSS payload keys, mint and revoke MCP tokens, and pull hourly usage rollups.

Who talks to it: you, from a server or the developer console — never an end-user's device.

Auth: standard HTTP Bearer. Org and key management uses your WorkOS session bearer (from signup/login); the /developer/* routes take the phosra_ API key you mint.

Base URL:

code
https://prodapi.phosra.com/api/v1

This is the only Phosra-specific surface. Everything here is a normal REST management API — if you've used Stripe's account or key endpoints, this will feel familiar. It is live today; prove it with no key (a 401, not a 404, is the correct answer without a bearer):

bash
curl -fsS https://prodapi.phosra.com/health
# → 200 {"status":"ok"}

Control-plane reference →

Orgs, API keys, usage, advisor agents, and MCP tokens.


Plane 2 — the data plane

What it is: the enforcement path — the sequence that turns a parent's intent into an actual allow/deny decision on a device. Three roles participate:

  1. 1
    Provider writes a rule

    A Provider issues a child's rule (and the verifiable consent behind it) with a signed rule-write. On the census this is POST /api/v1/policies/{policyId}/rules; with the SDK it's a @phosra/link directive(...) call. The census returns a signed write receipt on success.

  2. 2
    Census compiles a signed profile

    The census stores the rule in child_policies and compiles all of a child's active rules into one signed §8.3.6 enforcement profile per enforcement endpoint. The census is the only coordination point — but it is not in the decision hot path.

  3. 3
    Platform enforces locally

    A Platform fetches the profile once (or on a poll) via the §9.3(b) read, GET /api/v1/enforcement-profiles/{endpoint_id}, verifies its Ed25519 signature to the OCSS root in-process, and caches it. @phosra/gatekeeper wraps this.

Auth: the phosra_ API key, with writes signed per RFC-9421.

There is no hosted decision endpoint — by design

Once the platform holds a verified profile, isAllowed({ category, signal }) evaluates every subsequent enforcement question against the cached, signed profile — zero network calls, zero latency, fail-closed when the profile is absent.

isAllowed() is the decision call. There is no POST /v1/check endpoint and none is planned. A hosted decision call would add per-decision latency, put a network dependency on the enforcement hot path, and break the fail-closed guarantee whenever the census is unreachable. The profile read is gated — without a bearer you get a 401, which proves the endpoint is real:

bash
curl -s -o /dev/null -w "%{http_code}\n" \
  https://phosra-api-sandbox-production.up.railway.app/api/v1/enforcement-profiles/pg-mia-network-edge-2026-06
# → 401

Plane 3 — the open OCSS protocol

What it is: the vendor-neutral cryptographic surface — signed write and enforcement receipts, two-layer sealed envelopes, the eIDAS-style Trust List, the succession record, and the 123-category rule vocabulary. All of it is sourced from @openchildsafety/ocss, the open OCSS reference library. Phosra adds zero cryptographic logic here.

Who talks to it: anyone. No Phosra account is required to read the Trust List, verify a receipt, or use the protocol primitives.

Phosra implements OCSS and remains its steward of record while a proposed transfer to independent governance is incomplete. The draft is open for inspection and implementation, but it is not a ratified standard and has no official IETF Datatracker record.

The Trust List is the shared anchor

Sandbox signatures verify against the sandbox registry root. The signed fixture is served at a well-known path and can be fetched without a key:

bash
curl -fsS https://phosra-api-sandbox-production.up.railway.app/.well-known/ocss/trust-list \
  | python3 -c "import sys,json; d=json.load(sys.stdin); doc=json.loads(d['document']); \
print('root key_id:', d['key_id'], '| alg:', d['alg'], '| entries:', len(doc['entries']))"
# → root key_id: root-sandbox-2026-06 | alg: ed25519 | entries: 126

The signed document is returned as a JSON string under document, with the detached signature and the signing key_id alongside it:

json
{
  "document": "{\"document_type\":\"trust_list\",\"entries\":[ ... ],\"ocss_version\":\"...\"}",
  "key_id": "root-sandbox-2026-06",
  "alg": "ed25519",
  "sig": "…base64url Ed25519 signature…"
}

This is a synthetic sandbox artifact. Phosra does not claim a production federation, production Trust List, or independent accreditation decisions today.


Why keep them separate?

ConcernControl planeData planeOpen OCSS protocol
PurposeManage your accountEnforce a child's policyTrust & verification
Talks toYou (server / console)Provider ↔ census ↔ platformAnyone
AuthWorkOS bearer / phosra_ keyphosra_ key (RFC-9421 writes)None — public
Owned byPhosraPhosra (implements OCSS)The OCSS standard
Portable across providers?NoYesYes
In the decision hot path?NoOnly the local isAllowed()No

Keeping the trust anchor in the open protocol — not in Phosra — is the asset. A standard you cannot capture is one you can safely build on: if you ever integrate a different OCSS-conformant provider, your enforcement code and every receipt you've stored keep verifying, unchanged.

Where to go next