Disconnect & reconnect
Disconnect is a signed lifecycle, not a row deletion or an optimistic UI toggle. The provider first revokes its test authority; the sandbox Gatekeeper then updates or releases the synthetic platform target so you can observe the result.
Disconnect an authorized grant
Use the Golden Link server after re-authorizing the exact grant against your own parent and tenant boundary:
const projection = await server.disconnectGrant({
grantId: authorizedGrant.id,
platformDid: authorizedGrant.platformDid,
targetRef: authorizedGrant.targetRef,
})
if (projection === null) {
return new Response("Not found", { status: 404 })
}The tuple { grantId, platformDid, targetRef } is deliberate. Load the persisted
grant for the authenticated parent and reuse its exact saved targetRef; do not
reconstruct it from a child ID, householdRef, display value, or browser body.
householdRef proves provider-local family authority during issuance, while the
saved grant targetRef is the exact authority required for this grant operation.
projection.snapshot.stage === "revoked" proves that provider-side authority is
revoked. It does not by itself prove the platform removed controls. Use
projection.releaseStatus for that second fact.
releaseStatus | Parent-facing meaning |
|---|---|
pending | “Disconnected—waiting for the platform to confirm removal.” |
| complete | “Disconnected.” The exact signed release was durably acknowledged. |
Keep the Link worker running so the release event, retry, acknowledgement, and platform evidence can converge after the HTTP request finishes.
The Golden Gatekeeper runtime performs one additional safety exchange
automatically during final release. It records the platform's exact last
verified profile authority with Phosra, then fetches the final router-signed
tombstone. The tombstone must match the Link, child, selected profile, lifecycle
generation, and predecessor artifact before the platform release adapter can
run. Do not recreate this request in application code; upgrade
@phosra/gatekeeper and keep its worker running.
Shared-profile behavior
One platform profile may represent multiple independently linked children. For example, Ramsay and Coldy can share one Notflix Kids profile.
Disconnecting Ramsay while Coldy remains is a partial removal:
- Ramsay's member is revoked.
- Gatekeeper computes the effective policy for the remaining member.
- The platform receives an aggregate apply operation.
- Your adapter applies and observes the remaining policy.
- Native profile settings are not restored.
Disconnecting Coldy afterward is the final release:
- The last member is revoked.
- Gatekeeper sends an aggregate release operation.
- Your adapter removes the Phosra-managed overlay.
observeReleaseconfirms removal independently.- Native profile settings are restored.
Do not equate “one child disconnected” with “release the platform profile.” The
SDK's opaque targetOperation and generation fencing tell Gatekeeper which lane
is authorized; application code must preserve the provided idempotency key and
must not forge or clone that authority.
Decline and cancel are not disconnect
- Decline: the parent does not authorize the platform handoff. No active grant exists to release.
- Cancel before binding: Link retires the time-limited ceremony and its recovery locator.
- Close after a durable binding: the connection remains; Link preserves the recovery state while platform evidence converges.
- Disconnect: an existing grant is revoked and the signed release lifecycle begins.
Let PhosraLink handle callback errors, cancellation, expiry, and recovery. Do
not manually exchange an OAuth code after the server session reports decline or
terminal cancellation.
Reconnect
Reconnect by opening a new PhosraLink ceremony for the same authenticated child
and platform:
<PhosraLink
createSession={({ signal }) => fetch("/api/phosra/link/sessions", {
method: "POST",
signal,
headers: { "content-type": "application/json" },
body: JSON.stringify({
child_ref: child.id,
platform_did: platform.did,
return_to: window.location.pathname,
}),
}).then(async (response) => {
if (!response.ok) throw new Error("Unable to reconnect")
return response.json()
})}
onEvent={recordLinkEvent}
onExit={closeLink}
/>The new ceremony creates fresh signed authority, state, and replay boundaries. Never reuse an old authorization code, state value, endpoint label, or browser recovery object.
For a shared target, reconnecting a previously removed child adds a new member generation and recomputes the effective profile. It does not create a second copy of the platform profile unless the parent selects a different platform profile during authorization.
Operational verification
Provider applications can read the exact grant projection with
getSnapshotForGrant(...). Platforms can read the privacy-projected shared-target
feed with phosra.readTopology().
During partial removal, expect an active target with one revoked member and at
least one active member. The signed v2 release acknowledgement for the removed
member reports nativeRestored: false; this is successful partial removal, not
a degraded release. During final release, expect state: "released", zero active
members, and nativeRestored: true. Topology aliases are opaque and must not be
joined to product identifiers.
Checklist
- Re-authorize the grant tuple on the server before disconnecting.
- Show provider revocation separately from platform release completion.
- Keep workers running after the request returns.
- Preserve controls during partial removal from a shared profile.
- Restore native settings only after final release.
- Start reconnect as a new ceremony; reuse no old OAuth or recovery material.
- Base success copy on signed lifecycle evidence, not HTTP status.
See @phosra/link, the Provider quickstart,
and the Platform quickstart.