> ## Documentation Index
> Fetch the complete documentation index at: https://docs.perflo-api.proofof.tech/llms.txt
> Use this file to discover all available pages before exploring further.

# Prepare a client for registration

> Supply the exact profile, redirects, origins, keys, grants, and scopes for a Perflo client.

Perflo provisions clients through a reviewed administrative process because Dynamic Client Registration (DCR) is unavailable. Prepare one explicit client profile, exact redirect Uniform Resource Identifiers (URIs), browser origins, and key material before requesting registration.

## Provide the client identity and profile

Registration assigns a server-generated client identifier and an operator-verified unique display name. Consent and account pages show the verified name so a resource owner never has to trust a raw identifier.

Choose one profile and supply its required values:

| Profile                    | Registration values                                                                                                                                                                           |
| -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Confidential web or server | HTTPS redirect URIs, authorization code and optional refresh grants, inline JSON Web Key Set (JWKS) or approved `jwks_uri`, `private_key_jwt`, registered scopes, and pairwise-subject sector |
| Public browser             | HTTPS redirect URIs, exact browser origins, authorization code and optional refresh grants, token endpoint authentication `none`, registered scopes, and pairwise-subject sector              |
| Public native              | Exact redirect URIs, authorization code and optional refresh grants, token endpoint authentication `none`, registered scopes, and pairwise-subject sector                                     |
| Command-line or device     | Device authorization and optional refresh grants, token endpoint authentication `none`, and registered scopes                                                                                 |
| Service account            | Client credentials, inline JWKS or approved `jwks_uri`, `private_key_jwt`, one fixed service owner and provider binding, and a fixed scope ceiling                                            |

Public clients have no shared secret. Confidential client assertions may use only `ES256` or `PS256`.

## Register exact redirect URIs

Web and browser redirect URIs must use Hypertext Transfer Protocol Secure (HTTPS) and match the registered value exactly. They cannot contain a fragment, wildcard host, wildcard path, user information, or trailing-dot ambiguity.

Native loopback redirects have one narrow exception. Register a Hypertext Transfer Protocol (HTTP) URI on literal `127.0.0.1` or `[::1]` with an exact path and no query or fragment. Perflo then accepts any ephemeral port on the same literal address family and path.

Do not use `localhost`, switch between IPv4 and IPv6, vary the path, or register a loopback redirect for a browser client.

## Register browser origins separately

An allowed browser origin contains only `https://host[:port]`. Local development may use HTTP on a literal loopback host.

Origins cannot contain:

* A path, query, fragment, or user information
* A wildcard or regular expression
* A trailing-dot hostname
* The opaque `null` origin

Register every browser origin separately from redirect URIs. An accepted redirect URI does not grant cross-origin access.

## Supply assertion keys for confidential clients

Prefer an inline JSON Web Key Set (JWKS). Each key needs a nonempty `kid` and metadata compatible with its allowed assertion algorithm. When a set repeats a `kid`, Perflo filters candidates by the assertion algorithm, use, key operations, key type, and curve, then requires exactly one compatible verification key.

A remote `jwks_uri` must use HTTPS on an approved public host and port 443. Perflo rejects redirects, private or loopback addresses, ambiguous keys, and key sets over 256 KiB or 20 keys.

Client assertions must contain:

* `iss` and `sub` equal to the registered `client_id`
* `aud` equal to the environment issuer as one string
* `iat`, a unique `jti`, and `exp` no more than five minutes after `iat`
* Optional `nbf` that is valid at verification time

Perflo rejects assertion replay and accepts no more than 10 seconds of future clock skew.

## Set the grant and scope ceiling

Register only the grants and scopes that the client needs. Consent can narrow this ceiling but cannot expand it.

Mutation scopes require individual approval for a public client:

* `cards:manage`
* `beneficiaries:write`
* `spending:withdraw`

`purchases:execute` is unavailable. Perflo does not register or grant it in this release.

Register `openid` only for authorization-code clients. Register `offline_access` only for authorization-code or device clients. Client credentials cannot request either scope.

## Keep service accounts separate from people

A service account belongs to one Perflo-controlled service resource owner and provider binding. Its client-credentials grant cannot select or attach an existing human owner.

A third-party server that acts for a person must use authorization code and a client-authenticated refresh grant bound with Demonstrating Proof of Possession (DPoP). It cannot substitute a service account or client-credentials grant.

## Treat client changes as immediate

An enabled client can use only its current registered redirects, origins, grants, keys, and scope ceiling. Reducing that ceiling applies to current grants through live client and grant checks.

Disabling a client immediately blocks new protocol requests and revokes its grants and tokens. Plan key rollover so the current and replacement verification keys overlap before removing the old key.

See [Choose an OAuth client profile](/oauth/client-profiles) for flow requirements and [Call Perflo from a browser](/oauth/browser-access) for cross-origin behavior.
