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.
- 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 is receipted before any egress attempt. Delivery success or failure is terminal, and a failed delivery requires a fresh request.
- 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, or the terminal delivery receipt is not available yet. | 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.
Directed-disclosure v1 has a narrow crash window between destination acceptance and
terminal-receipt persistence. If Passport crashes in that window, the request stays
pending indefinitely because elapsed time cannot prove either success or failure.
Open a fresh request when this happens; do not retry or reinterpret the consumed request.
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. The consumed request cannot retry egress.
- Approval stays pending without a terminal receipt: start a fresh request. This can follow a crash after destination acceptance but before receipt persistence; time alone never changes it to success or failure.
- 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.
- Bind each local flow to one opaque request ID.
- 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.