# Register a client Every application needs its own reviewed OIDC client. The owned Go issuer enforces versioned confidential web client registrations stored in PostgreSQL. Exact HTTPS callbacks, permitted audiences, refresh policy, enabled state and registration version constrain code issuance, exchange, refresh, UserInfo and introspection. Disposable PostgreSQL tests exercise two clients and cross-client refusals. The mounted custom UI has passed two-client browser SSO with synthetic registrations. Real reviewed registration writing, exact person-to-project assignment and full product logout remain release gates. An approved policy does not yet install a usable client. ## Choose a profile ### Web backend Register the exact HTTPS callback, client ID, confidential secret, and logout endpoint where supported. The backend exchanges a code with PKCE S256 and stores the product session. ### Native mobile or desktop Register the exact app link or approved loopback redirect and a public client ID, with no secret. The system browser handles authorization; the app uses PKCE S256. ### Lifecycle consumer Use a reviewed project-scoped service identity and management audience. The server polls the signed lifecycle feed; this identity is separate from the browser client. A native Mail client uses a fixed reviewed callback profile. The generic `examples/native` loopback reference is not a Mail client registration. The current Go issuer does not implement arbitrary native or machine client issuance. ## Review the owned client policy 1. Use the [project review](/docs/projects) flow to establish an approved project and current owner. In the project detail page, propose a permission catalog with exact IDs and descriptions. A separate current project approver reviews that immutable revision. OIDC scopes such as `openid` are protocol inputs, not those product permissions. 2. Complete credential custody before the client-policy review. The current owner requests a short-lived [credential intent](/docs/credentials), and the operator-controlled tool delivers the credential to the configured owner runtime. The browser receives only a pending intent ID. After handoff, the operator exports a protected proof containing the preparation reference. This development boundary does not install the client. 3. Propose the owned-client policy against the approved catalog. It binds the exact owned issuer, client ID and version, callback/logout URI sets, resource audiences, refresh policy, nonsecret credential fingerprint and selected reviewed permission IDs. The server assigns the policy review reference and computes a canonical registration digest. A separate policy digest binds the project, permission catalog, selected permissions, display name and generation. Owners cannot submit or invent the review reference. 4. Have an independent approver inspect the actual policy and both exact digests. Changing the policy requires another revision. The public [reviewed project-client API group](/docs/api/groups/reviewed-project-clients) provides list, proposal, approval and revocation operations. Every mutation requires a unique `Idempotency-Key`, an audit reason and current scoped authority. Keep the same key and exact body after an uncertain response. Reusing a key with changed content returns 409. See [the Management API](/docs/management-api) for authentication and idempotency. ## Attach the preparation reference The development proposal API requires `credential_preparation_id` alongside `catalog_id` and `registration`. Use the canonical lowercase UUID from the controlled delivery proof. The intent ID is a different identifier. Do not submit the secret, a signed receipt, a browser-calculated custody digest or a filesystem path. Management obtains a fresh signed observation directly from the configured private issuer endpoint before starting the policy transaction. It verifies the exact project, issuer, client ID and version, current owner, credential fingerprint and original handoff deadline. Proposal and independent approval each require their own current observation. A retained proof is a reference for this check, not authority to skip it. Successful client responses include `credential_preparation_id` and the server-verified `custody_binding_digest`. Both are nonsecret correlation fields. Historical records may return `null`; they cannot acquire accepted custody evidence merely by being read or retried. The proposal also binds the exact independently approved permission catalog and current owner authority. Approval requires a different current authorized reviewer and recent strong authentication. This attachment implementation is undergoing combined qualification. Reviewed installation, effective client readback and production activation remain separate release gates. ## Read the review state The project admin page also reads `GET /v1/projects/{project_id}/authority-status`. Current project owners and authorized project approvers can inspect the separate review, lifecycle acknowledgement, source grant and activation observations. Management cannot confirm issuer activation from an approval or an activation request. Treat an unknown, pending or expired observation as incomplete, and verify the deployed API version before using this route. - `pending_review`: The proposed revision has no accepted independent approval. - Catalog `approved`: The reviewed permission catalog may be used in a client-policy proposal. - Client `approved_pending_readback`: The exact policy is approved, but a separate signed Go registration readback is still required. Sign-in is not enabled by this state. - `superseded` or `revoked`: Historical evidence remains available. The revision cannot supply current authority. The current API does not provide an effective client state or install a registration. Credential custody readback verifies handoff; registration readback must separately verify an installed client. The installation writer and assignment publisher remain implementation gates. A person also needs an independent sponsor/administrator review tied to their exact Access ID and version, plus effective product acknowledgement. A direct single-admin grant, a historical request or client approval alone cannot qualify them. Management's `/v1/registration-context` reports `provider: owned` and `client_registration_enabled: false` in a valid owned deployment. That flag controls the retained legacy environment-registration forms. It does not disable the owned-client proposal and review API described here, and it does not imply that an approved owned policy can already sign in. Do not mix these reviews with legacy environment provisioning. Existing `ProjectEnvironment` and credential-reveal routes serve migration and rollback. Native and machine profiles have their own contracts and are not implied by the owned confidential-web proposal API. ## Handle expiry and configuration Pending reviews expire after 90 days. A replacement proposal supersedes expired evidence in the same audited transaction. A never-approved proposal may reuse its client version with a new generation and server-assigned review reference. After an approved proposal, a missing readback could represent a lost installation response, so a replacement requires a higher client version. The platform operator sets `AUTH_ENGINE_TARGET_ISSUER` to the exact reviewed owned issuer. It is independent of the issuer trusted for current Management human tokens. The settings may coincide after an approved owned-workforce migration, but one is never inferred from the other. The privileged portal client ID and management audience remain reserved to the configured portal project; every other product gets a separate client and product audience. Missing or inconsistent authority configuration returns 503. - `403`: Check current scoped authority, independent reviewer and authentication assurance. - `409`: Re-read the exact catalog and policy. Resolve a changed owner, version, preparation binding or idempotency conflict before proposing again. - `413`: Keep the complete JSON request within 64 KiB. - `422`: Use the typed request schema, a canonical preparation UUID and JSON without duplicate fields. - `503`: The operator must restore the configured authority or private custody verification service. Do not replace verification with browser proof. ## Record the result Store the exact issuer URL, client ID, callback, allowed scopes, and credentials in deployment configuration. A confidential secret stays on the backend. Native apps cannot keep a client secret. The application should discover endpoints from `ISSUER/.well-known/openid-configuration`, validate ID tokens for its own client audience, and use a separate access token for management or product APIs. Do not reuse `taifa-identity-portal` for another application. See [web sign-in](/docs/web) and [native sign-in](/docs/native) for implementation patterns.