Directed disclosure handoff
Let an owner approve one protected delivery in AI Passport and return a content-free status to your app.
Private beta. Client admission and disclosure return URIs are managed by AI Passport operations.
Directed disclosure sends selected protected fields from AI Passport to one exact HTTPS destination after the owner approves. The protected values never pass through the requesting app, its agent, the return link, or the status endpoint.
This flow is separate from memory passes, connector passes, booking actions, and payment authorization. Approval for one does not authorize another.
Before you build
Register the relying app as an OAuth client with AI Passport. During admission, provide one exact HTTPS disclosure return URI. AI Passport stores that URI beside the admitted client. A Dynamic Client Registration or Client ID Metadata Document cannot declare or change it.
The return URI must have no credentials, query, or fragment. AI Passport appends the two callback parameters itself.
Your backend needs an OAuth access token issued to the same client with the memory scope. The status endpoint derives the client and owner from that token. A token for another client or owner receives 404.
Owner approval and return
- Create the directed-disclosure request through the protected-item disclosure tool. Name only the fields required by the exact HTTPS destination. Set
purposetodirected_disclosureortravel_booking; omitted purpose defaults todirected_disclosure. - Send the returned
/approve/:request_idURL to the owner. - On an iPhone with AI Passport installed, the universal link opens the exact native approval sheet. Without the app, the same URL remains the signed browser fallback.
- AI Passport shows the item label and type, requesting app, exact destination host, field names, reason, and expiry. It never shows the protected values in the request list or decision response.
- The owner approves or declines. Approval and the delivery job are saved together before any egress attempt. Passport retries only when the destination provably did not process the attempt: a pre-dispatch connection failure, HTTP 408, HTTP 425, or HTTP 429. An unanswered request or any 5xx response is ambiguous and is never sent again.
- When the client has an admitted return URI, AI Passport offers Return to your app after the decision.
The return URL has this shape:
https://app.example/passport-return?request_id=33333333-3333-4333-8333-333333333333&status=approvedIt is a wake signal only. It carries no protected value, destination credential, field list, reason, provider content, or authorization.
Reconcile authoritative status
On callback, first confirm that request_id belongs to the flow your app started. Ignore an unknown ID, an unexpected callback destination, or a status outside the closed vocabulary. Then have your backend reconcile with AI Passport:
GET /api/disclosures/33333333-3333-4333-8333-333333333333/status
Authorization: Bearer <access token issued to the requesting OAuth client>Successful response:
{
"request_id": "33333333-3333-4333-8333-333333333333",
"status": "approved"
}The endpoint is rate limited and returns only the request ID and status.
| Public status | Meaning | Internal outcome |
|---|---|---|
pending | The owner has not decided, delivery is queued, or the delivery outcome is ambiguous. | pending, or approved without a terminal receipt |
approved | The approved fields were delivered to the exact destination. | delivered |
rejected | The owner declined. | denied |
expired | The request deadline passed. | expired |
failed | Delivery failed. | delivery_failed receipt |
Never treat the callback status alone as authoritative. Never treat approval alone as delivery success.
Every delivery includes a stable Idempotency-Key and a short-lived
Passport-Disclosure-Attestation. Verify the attestation before reading the body:
- Verify the RS256 signature with the key selected by
kidfrom the issuer's JWKS URL. - Require
typto equalpassport-disclosure+jwtandissto equal the expected AI Passport issuer. - Require
audandpassport_disclosure.client_idto equal your exact OAuth client ID. - Require
subto equal the owner subject from that owner's ID token. - Check
iat,exp, and the 60-second clock tolerance. The signed lifetime is 120 seconds. - Match
request_id,item_type,purpose,approved_at,idempotency_key,attempt, destination origin, and destination path to the request your backend expects. - Compare
fieldsas an exact set. Any extra field is a scope widening and must fail. - Atomically consume
jtionce. A repeatedjtiis a replay and must fail before the body is handled.
Passport creates a fresh attestation for each attempt and never resends an
attestation. The idempotency key stays stable across the limited pre-dispatch
retries. An unanswered or 5xx delivery remains pending; the owner can open a
fresh request after the relying party confirms that it did not accept the first one.
Failure states
- Replay or already decided: do not submit another decision. Reconcile status. A second approval cannot deliver twice.
- Expired: start a fresh request. Expiry cannot be extended at decision time.
- Delivery failed: start a fresh request. Passport has exhausted the bounded retry window or received a permanent destination error.
- Approval stays pending: keep reconciling while Passport retries a provably unprocessed attempt. For an ambiguous outcome, confirm whether the relying party accepted the idempotency key before the owner opens a fresh request.
- Deleted or revoked item: the request is unavailable and fails closed.
- Foreign client or owner: status lookup returns
404without confirming that the request exists. - Destination mismatch: do not continue. The owner sheet displays the destination stored on the request, and the decision call accepts no destination override. The relying app must also match the callback request ID to the flow it started.
- Dependency unavailable: retry the metadata or status read. Do not turn an outage into an empty request list or an approved result.
- Return link does not open the app: the decision remains terminal. The owner can open the relying app manually, and its backend can reconcile status.
Security checklist
- Keep the OAuth access token on the relying app backend.
- Request the smallest exact field set.
- Use only
directed_disclosureortravel_bookingas the purpose. - Bind each local flow to one opaque request ID.
- Verify the disclosure attestation before reading the body.
- Match its issuer, client, owner, request, destination, purpose, and exact field set.
- Atomically consume each attestation
jtionce. - Match the signed idempotency key to the
Idempotency-Keyheader. - Accept only the five documented public statuses.
- Reconcile every callback with the authenticated status endpoint.
- Never ask an agent to relay protected values.
- Start a new request after expiry or failed delivery.
Native sign-in for iPhone and iPad
Integrate AI Passport with AuthenticationServices, universal links, PKCE, strict OIDC validation, and device-only token custody.
Deep integrations
Create passports inside your signup flow, link sources from your UI, contribute memories as an attributed source, and read them back under the owner's passes.