Skip to main content
PhosraLinkKit is the native-iOS Phosra Link — a Phosra-branded Connect sheet a parental-controls app (PCA) presents in about ten lines, with onSuccess / onExit callbacks. It’s the iOS peer of the web/React-Native @phosra/connect drop-in, and it drives the same @phosra/link ceremony — init → complete → bind → grant — through your own backend (BFF). The parent’s authentication and your OCSS signing key never leave your app (self-custody by default). The SDK holds no keys; your BFF signs the consent attestation. Same trust model as the rest of OCSS, same ergonomics as Plaid’s iOS SDK.

Install

Swift Package Manager, iOS 16+:
During monorepo development you can also depend on it by path (.package(path: "packages/ios-connect")).

Quickstart

That’s the whole integration. Exactly one of onSuccess / onExit fires per presentation — including if the presenter is torn down out from under the sheet — and you do not need to retain the handler (it self-retains while presented).
The platform’s OAuth runs in a system ASWebAuthenticationSession, so your app never sees the parent’s platform credentials. The Connect sheet renders in your app — there is no Phosra-hosted page or web view.
The examples above use did:ocss:loopline — the DID with a live sandbox connect config, so the ceremony actually loads against the production sandbox census. Other DIDs return the “accredited-but-unconfigured” 404; email developers@phosra.com to have one published. See How platforms are resolved.

End-to-end

The whole integration on one page — client and backend:
1

Register your redirect scheme

Add your custom scheme (e.g. yourapp) to the app target’s Info.plist CFBundleURLTypes, so ASWebAuthenticationSession can receive the platform’s OAuth callback at yourapp://phosra-link.
2

Authenticate the parent (your own login)

The parent signs in with your app’s auth — Phosra never sees their credentials. On success, mint a server-side session token (the reference BFF issues a signed phosra_parent cookie via issueParentSession). That token is the sessionToken you pass the SDK. Never accept it from the client.
3

Stand up the 3 BFF routes

POST /connect/init | /connect/complete | /connect/bind, each wrapping @phosra/link server-side — see the reference BFF. Your bind route signs the consent with your OCSS key and returns { grant_id }.
4

Present the sheet

Build PhosraLinkConfiguration (the Quickstart above) and call PhosraLink(configuration:).present(from:onSuccess:onExit:).
5

Handle the result

onSuccess delivers the grantId — persist it and drive rule directives with @phosra/link’s directive(...). onExit means the parent canceled or errored; nothing changed.
Metered census usage requires a Phosra API key — provision one in the developer console or via POST /api/v1/developers/orgs/{orgID}/keys.

What your backend provides

PhosraLinkKit never talks to Phosra directly. It calls your BFF — the three routes the reference BFF exposes, each wrapping @phosra/link server-side: Your bind route signs the consent attestation with your OCSS key and posts it to the census. The SDK relays your parent-session token (a phosra_parent cookie by default; override sessionHeaderName / sessionHeaderValue for a bearer). This is Plaid’s link_token pattern — a thin backend mints the session and finalizes the signature.

Platform logos

The sheet shows the platform’s verified logo — the one from its accredited Trust-List entry, not a logo the app pastes in. GET /api/v1/providers/{did}/connect returns the provider’s name and icon_url (from the registry); pass that URL into ConnectPlatform:
The sheet renders it, falling back to a generic glyph while it loads or if it’s missing. For a bundled asset instead of a URL, pass platformLogo: on the configuration. Because the logo comes from the accredited registry, the logo you see is the one Phosra verified — it’s part of the provider’s identity, not decoration.

The honesty contract

The sheet ports the approved design’s honesty contract verbatim, and the SDK cannot show a fake green:
  • The header reads phosra · OCSS (a subordinate mark) and the trust claim is the precise “Accredited on the OCSS Trust List” — Phosra is an accredited router, not OCSS itself.
  • Success shows “Verified on the OCSS Trust List” — the only green — and only after the server binds the grant.
  • On failure: “No rules were changed — you can try again.”
Load-bearing invariant: your bind route must return a grant_id only once the consent is minted and verified to the OCSS root. The green “Verified” rests on that signal alone — return an unverified grant_id and you have made the SDK show a fake green.

States

The sheet walks: Connect (intro + accreditation) → What gets applied (the rules preview) → the platform’s OAuth → Choose accountVerified success — or an honest error at any step. All rendered natively (SwiftUI); the marks (the Phosra spark, the wordmark, the OCSS glyph) ship as source and tint by color, so there is no asset bundle to manage.

Advanced

  • Custom transport. The 4-argument PhosraLinkConfiguration.init takes your own ConnectTransport if you route the three calls differently.
  • Fresh platform login. PhosraLinkConfiguration(prefersEphemeralSession: true) forces a new platform sign-in (no shared cookies).
  • Granular events. Pass onEvent to observe each ceremony transition.

Notes

  • iOS 16+. The core (controller, transport, sheet) is UI-framework-agnostic and unit-tested; the ASWebAuthenticationSession presenter is iOS-only.
  • MIT-licensed. All signing and verification are your backend’s; metered census usage requires a Phosra API key, billed server-side — never in this package.