OAuth partner apps (admin)
In brief: Register partner apps, rotate client secrets, suspend or revoke OAuth access from the platform-admin console.
The /admin/oauth-clients page is the registry behind the Stripe-style
OAuth Connect flow at /v1/oauth/authorize. Every row here is a third-
party app that can request OAuth access to a firm's Certivus workspace
via a hosted consent screen.
This is the opposite side of API access (firm → Certivus) and the operator counterpart to a firm's Connected apps page.
When to register a partner app
Register a new partner app when:
- A first-party Rajoka product needs Certivus access on a customer's behalf (Hirenza, Bryxo, Havens, Lexuvo — tick First-party at registration).
- An external integrator (CRM, onboarding tool, accounting platform) has signed a partner agreement and needs OAuth access.
Do not register when:
- The integrator is calling on its own behalf (cron job, backend sync). Use Client Credentials instead — they generate API keys at Settings → API access.
- Less than one firm is going to connect (don't pollute the registry).
Registration form fields
| Field | Notes |
|---|---|
| Name | Shown on the consent screen as the partner's name ("Hirenza wants to access your workspace"). Use the trading name. |
| Description | One sentence shown beneath the name. Plain-language pitch. |
| Homepage URL | Optional. Adds a clickable link on the consent screen. |
| Support email | Optional. Shows on the firm's Connected apps row so firms can contact the partner directly. |
| Logo URL | Optional. 1:1 ratio recommended. Defaults to a colored initials avatar. |
| First-party | Tick only for Rajoka portfolio apps. Adds a "First-party" pill on the consent screen + firm-side card. |
| Redirect URIs | RFC 6749 §3.1.2.4 — exact-match enforced at /v1/oauth/authorize. No wildcards. https:// only (localhost http:// allowed for dev). Add one URI per environment (prod, sandbox). |
| Allowed scopes | Maximum scope set the partner can request. Every scope on a /authorize call must be a subset. Tick conservatively — easier to expand than narrow. |
| Default webhook URL | Optional. Destination for connection.created / connection.revoked events. Each per-firm grant can override. |
Scopes reference
| Scope | Risk |
|---|---|
cases:read | Read |
cases:write | Write |
verifications:create | Write |
passes:read | Read |
passes:write | Write |
webhooks:manage | Write |
access:revoke | Destructive — revoke Pass access grants |
firms:provision | High-trust — spin up new firms. Hirenza-class only |
The secret reveal
Registration returns the client_id + client_secret once.
- Copy both immediately.
- Hand off via the partner's secure channel (encrypted email, 1Password share, signal). Never paste into a public chat.
- If you lose it, rotate (below). The original cannot be recovered.
Rotating the client_secret
Use Manage → Rotate secret… when:
- The partner reports a leak.
- Routine credential rotation (annual recommended).
- An employee with secret access leaves the partner's team.
Grace period. Default 24h — the previous secret keeps working alongside the new one so the partner can roll over without downtime. Set 0 to invalidate the old secret instantly (use sparingly — breaks in-flight requests).
Suspend vs revoke
| Action | What changes | When to use |
|---|---|---|
| Suspend | New /authorize calls blocked. Existing access tokens drain for ≤15 min. Refresh blocked. | Investigation / temporary pause. Reversible by clicking Reactivate. |
| Revoke | All of suspend, PLUS every outstanding refresh token attached to active grants is invalidated immediately. Partner cannot reconnect without re-registering. | Kill-switch for confirmed compromise or terminated partnership. |
Neither action deletes the row — the audit trail is preserved.
Active firm count
Each row shows N active firms connected. This is the live count of
non-revoked oauth_grants for that partner. Useful for:
- Spotting unused registrations (0 firms after 90 days → consider removing).
- Estimating blast radius before suspending or revoking.
- Annual partner reviews.
Audit log
Every register / rotate / suspend / reactivate / revoke is recorded
under the oauth.client.* action category. Filter the
platform audit log by category to see the full
history.
Common operator playbooks
A partner claims their secret leaked
- Confirm via their security team (don't act on unverified reports).
- Manage → Rotate secret… with grace
4(4-hour rollover window). - Send the new secret via their pre-agreed secure channel.
- After 4h, confirm with the partner that they've cut over.
- If still on the old secret after grace expires, the partner's integration is broken — but the leaked secret is dead. Better than leaving it live.
A partner is acquiring or being acquired
- Wait for the operator to confirm legal status.
- Manage → Suspend — pauses new connections without killing existing ones.
- After legal sign-off, either Reactivate or Revoke depending on the outcome.
A first-party app needs sandbox + prod credentials
- Register TWO entries — one for sandbox (
*_test_*slug) and one for prod (*_live_*slug). Different redirect URIs. - Tick First-party on both.
Help on the firm side
When a firm asks "what does this partner have access to?" they can see
the live scope list + last-used timestamp at
Settings → Connected apps (/firm/settings/connections). Point
them at the firm-side help article
rather than answering scope-by-scope yourself.
Related
docs/api/OAUTH_CONNECT.md— partner-facing integration guide.docs/api/openapi.yaml— machine-readable spec for/v1/oauth/*.- PRD: OAuth Partner Connect — design decisions D-3 through D6-6.
Didn't find what you needed?
Contact support