> ## Documentation Index
> Fetch the complete documentation index at: https://docs.phosra.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Architecture

> How the pieces fit — the Phosra control plane, the enforcement data plane, and the open OCSS protocol, and why they are kept separate.

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:

<CardGroup cols={3}>
  <Card title="Control plane" icon="sliders">
    Manage your Phosra account — orgs, `phosra_` keys, usage, advisor agents, MCP tokens.
    Phosra-specific. Bearer auth.
  </Card>

  <Card title="Data plane" icon="bolt">
    The enforcement path — a policy is written, compiled into a signed profile, and
    enforced **locally** on the device or platform.
  </Card>

  <Card title="Open OCSS protocol" icon="cube">
    Vendor-neutral primitives — the Trust List, signed receipts, sealed envelopes, the
    123-category vocabulary. Phosra adds **zero** cryptographic logic here.
  </Card>
</CardGroup>

<Frame caption="The three planes. Management flows over the control plane; enforcement flows over the data plane; both anchor their trust in the open OCSS protocol.">
  <img className="block dark:hidden" src="https://mintcdn.com/phosra/o0ansqUg4hqAQihW/images/architecture-light.svg?fit=max&auto=format&n=o0ansqUg4hqAQihW&q=85&s=765bb3ec3416dc02839cb7794bdba972" alt="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." width="940" height="660" data-path="images/architecture-light.svg" />

  <img className="hidden dark:block" src="https://mintcdn.com/phosra/o0ansqUg4hqAQihW/images/architecture-dark.svg?fit=max&auto=format&n=o0ansqUg4hqAQihW&q=85&s=5e7a7797074b4d964f782cbf6a3b5392" alt="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." width="940" height="660" data-path="images/architecture-dark.svg" />
</Frame>

## 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 all OCSS protocol artifacts: they verify against the same
**Trust List root** regardless of which accredited provider issued them.

That last sentence is the whole point of the separation: **the trust anchor is the open
standard, not Phosra.** Swap Phosra for any other OCSS-conformant provider and the data
plane and protocol surfaces are byte-for-byte identical.

***

## 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:**

```
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 theme={null}
curl -fsS https://prodapi.phosra.com/health
# → 200 {"status":"ok"}
```

<Card title="Control-plane reference →" icon="sliders" href="/platform/overview" horizontal>
  Orgs, API keys, usage, advisor agents, and MCP tokens.
</Card>

***

## 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:

<Steps>
  <Step title="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.
  </Step>

  <Step title="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.
  </Step>

  <Step title="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.
  </Step>
</Steps>

**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.

<Warning>
  `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 theme={null}
  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
  ```
</Warning>

<CardGroup cols={2}>
  <Card title="Enforcement concept →" icon="bolt" href="/concepts/enforcement" horizontal>
    Jobs, results, and the poll-don't-webhook verification contract.
  </Card>

  <Card title="Platform integration →" icon="shield-halved" href="/integration/platform" horizontal>
    Fetch a profile, verify to root, and enforce with `@phosra/gatekeeper`.
  </Card>
</CardGroup>

***

## 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.

The relationship is the same as Yubico shipping a FIDO2 key: Yubico implements FIDO2, the
FIDO Alliance owns the standard. Phosra implements OCSS, the OCSS stewardship body owns the
standard. The signing and verification primitives in these docs are not Phosra code — they
are the open OCSS library, re-exported without modification.

### The Trust List is the shared anchor

Every signature in the data plane — the rule-write receipt, the enforcement profile, the
delivery receipt — verifies against the **same Trust List root**. The list is live and
served at a well-known path; fetch it with no key:

```bash theme={null}
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 theme={null}
{
  "document": "{\"document_type\":\"trust_list\",\"entries\":[ ... ],\"ocss_version\":\"...\"}",
  "key_id": "root-sandbox-2026-06",
  "alg": "ed25519",
  "sig": "…base64url Ed25519 signature…"
}
```

<Note>
  The value above is from the **sandbox** census. Production serves a distinct root
  (`root-prod-2026-06`) and a validly-signed **empty** list until accreditation entries are
  added through OCSS governance — an empty-but-signed list is the honest, correct state, not
  a bug.
</Note>

<CardGroup cols={2}>
  <Card title="OCSS overview →" icon="cube" href="/ocss/overview" horizontal>
    Receipts, envelopes, the Trust List, and the succession record.
  </Card>

  <Card title="Trust Framework →" icon="lock" href="/ocss/trust-framework" horizontal>
    The two-layer envelope, accreditation tiers, and the conformance contract.
  </Card>
</CardGroup>

***

## Why keep them separate?

| Concern                        | Control plane                 | Data plane                      | Open OCSS protocol   |
| ------------------------------ | ----------------------------- | ------------------------------- | -------------------- |
| **Purpose**                    | Manage your account           | Enforce a child's policy        | Trust & verification |
| **Talks to**                   | You (server / console)        | Provider ↔ census ↔ platform    | Anyone               |
| **Auth**                       | WorkOS bearer / `phosra_` key | `phosra_` key (RFC-9421 writes) | None — public        |
| **Owned by**                   | Phosra                        | Phosra (implements OCSS)        | The OCSS standard    |
| **Portable across providers?** | No                            | Yes                             | Yes                  |
| **In the decision hot path?**  | No                            | Only 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

<CardGroup cols={2}>
  <Card title="Quickstart — first call in 5 min" icon="terminal" href="/quickstart" horizontal>
    Zero to an enforced policy against the live sandbox.
  </Card>

  <Card title="Pick your integration path" icon="signs-post" href="/integration/overview" horizontal>
    Platform, Provider, or protocol-only — start where you are.
  </Card>
</CardGroup>
