Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/admin/service-accounts.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ Concretely:
- Adding `client_credentials` to a client that has no linked SA is rejected — no ownerless M2M clients.
- The `authorization_code` / `device_code` / `implicit` paths refuse to issue a token whose client has a `LinkedServiceAccountId`.

::: tip Dual-role BFF backends
A backend-for-frontend that both **brokers user login** (redeeming a native grant like `urn:cocoar:otp` server-side) **and** acts **machine-to-machine** (e.g. minting invite codes via `client_credentials`) needs **two** clients, not one — a login client carrying the native grant **plus** a separate SA-linked client for `client_credentials`. The single shared secret lives on the M2M client; the login client can be public (one secret total) or confidential (client-auth on the redeem). See [Native app integration → server-side BFF](../integrate/native-apps#2-create-the-oauth-client).
:::

## Creating a Service Account

1. Open `/admin/service-accounts` and click **Create**.
Expand Down
2 changes: 2 additions & 0 deletions docs/integrate/native-apps.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ What a realm administrator must configure in Modgud before the app can connect.

Granting a native grant on the client sets the matching `gt:urn:cocoar:*` permission. Both the realm flag **and** this per-client permission must be present.

> **Server-side BFF (confidential redeem).** "Public" is the right posture for a true native app that can't keep a secret. A **backend-for-frontend** that redeems the OTP / magic / passkey grant *server-side* (browser never touches Modgud) may instead use a **confidential** client — there is no public-only enforcement on these grants, so a `client_secret` adds client authentication on top of the user's factor. If such a BFF also acts machine-to-machine (e.g. minting [invite codes](../admin/applications#invite-codes-the-invitecode-posture) via `client_credentials`), that is a **separate** client: a single client cannot hold both user-flow and `client_credentials` grants (see [strict grant separation](../admin/service-accounts#strict-grant-separation)). So a dual-role BFF runs **two clients** — a login client carrying `urn:cocoar:otp` (public for a single shared secret, or confidential for client-auth on the redeem) **plus** a separate SA-linked client for `client_credentials`.

### 3. Passkeys: set the per-client RP-ID and serve an AASA

For `urn:cocoar:passkey`, set the client's **WebAuthn RP-ID** to the app's branded apex (e.g. `app.example.com`). If left blank it falls back to the realm's primary domain.
Expand Down