Single sign-on (SSO)
Dynv SSO uses your organisation's identity provider (IdP) to authenticate people and authorise membership. It never supplies, releases or replaces key material. A member still unlocks Dynv with their own passkey, device token or recovery kit.
SSO is available for team orgs on the Team plan. It covers the dashboard, CLI and MCP. Deployments that use process tokens are not covered.
Supported providers
Dynv supports OpenID Connect (OIDC) with discovery and the authorisation-code flow with PKCE. Use Okta, Microsoft Entra ID, Google Workspace, Auth0, Keycloak or another OIDC provider that supports discovery and PKCE S256.
Dynv requests the scopes openid email profile. With the default email claim, the ID token must also mark the address as verified.
Set up SSO as an owner
Open Settings → SSO in the org's dashboard. You need an OIDC application at your IdP and access to your domain's DNS records.
- Create an OIDC application. Enable the authorisation-code flow. Copy the redirect URI shown in Settings into the application's redirect or callback URIs. It has this form and must match exactly:
Redirect URI: https://<api>/v1/sso/oidc/callback
Scopes: openid email profile- Enter the IdP configuration. In Settings → SSO, choose OIDC and enter the issuer URL, client id and client secret. A public client can leave the secret empty and rely on PKCE. Use the issuer exactly as it appears in the IdP's OIDC discovery document. Dynv fetches and validates discovery when you save.
- Verify your email domain. Add a domain such as
acme.com. Settings shows a token; create this TXT record at your DNS provider, then choose Verify:
Name: _dynv-challenge.acme.com
Type: TXT
Value: dynv-domain-verification=<token shown in Settings>- Test the configuration. Sign in once with SSO as an owner. Require SSO cannot be turned on until an owner has completed this sign-in with the current configuration.
- Turn on Require SSO. Do this while your owner's SSO session is active. Every non-exempt human member, including owners, then needs a live SSO session on every dashboard, CLI and MCP request. Members who have not linked their IdP identity are listed before you confirm.
- Set the policy. Choose a session lifetime from 1 to 24 hours; the default is 12 hours. Exempt individual members who cannot use the IdP, such as contractors. Choose whether people from verified domains may send join requests.
Changing to a different IdP, client id or email claim, or deleting the SSO configuration, signs everyone out of SSO and drops the identity links. Require SSO then switches off until an owner signs in with the new configuration. Passkeys and devices remain.
Provider notes
| Provider | Configuration notes |
|---|---|
| Okta | Create an OIDC web application with the authorisation-code grant and the redirect URI from Settings. Use the issuer shown by your Okta org or authorisation server's OIDC discovery document. Keep the default email claim. |
| Microsoft Entra ID | Register an application, add the redirect URI as a web redirect and use your tenant's discovered issuer. Try the default email claim. If the ID token does not contain a suitable verified email, select upn or preferred_username as the email claim. Its domain must still be verified in Dynv. |
| Google Workspace | Create a web-application OAuth client and add the redirect URI as an authorised redirect URI. Use Google's discovered issuer and keep the default email claim. The Google account's verified address must be in a domain you verified. |
| Keycloak | Create an OIDC client in the realm, enable the standard authorisation-code flow and add the exact valid redirect URI. Use the realm issuer from its discovery document. Keep email as the claim and make sure users have verified email addresses. |
For every provider, the issuer's discovery, authorisation, token and key endpoints must be reachable by the Dynv API over HTTPS.
What members see
- Enter your work email on the Dynv sign-in page.
- Dynv finds the org by its verified domain and sends you to its IdP.
- Authenticate at the IdP as usual.
- Return to Dynv and unlock with your passkey, as before.
The first SSO sign-in links the IdP identity to the member by email. Later sign-ins must match that linked IdP subject. A new browser or CLI device gets its own session, bound to that device on first use.
If you are not a member, Dynv either sends a join request to the owners or tells you to ask an owner for an invite. The IdP alone never makes you a member.
CLI and MCP
Require SSO applies to a person's CLI and MCP requests too. Sign in from the CLI with its normal master-token configuration already in place:
dynv login --ssoThe CLI prints a URL and a code. Open the URL in any browser, check that the code matches and approve the sign-in. After the IdP sign-in, the CLI receives a session bound to that CLI's own device token. The IdP identity must map to the same member as that token; approving a CLI belonging to someone else fails.
The session is stored with mode 0600 in the Dynv state directory. The CLI and MCP send it with their requests. Set DYNV_SSO_SESSION to supply a session directly instead of using the file, for example in CI. An expired or missing session produces:
SSO session expired or missing: this org requires SSO; run "dynv login --sso"Run dynv login --sso again to get a fresh session. To revoke this device's session and delete its local file:
dynv logoutBreak-glass for owners
An IdP outage or bad configuration must not lock owners out of their own org. An owner can open a one-hour break-glass session without the IdP by using a passkey or recovery kit. In the dashboard, choose Break-glass sign-in. From an owner CLI device:
dynv login --break-glassThe session is bound to that owner device and does not extend; open another one if needed. Break-glass use is audited and shown to every owner for seven days. It is not offered to other members.
Owners can't exempt themselves from SSO, and every change to the exempt list is audited and shown to all owners.
Joining an org
Join requests are on by default when SSO is configured. There is no automatic join: only an owner can grant keys.
- An unknown person from a verified domain signs in through the IdP. Dynv creates a join request, not a membership or a session.
- Owners see the request in Settings → SSO and in the Members count. The address is sealed to the owners' keys and opened locally.
- Approving opens the ordinary invite dialog with that email filled in. The owner chooses the role and grants, creates the invite and sends its link to the person out of band. Declining deletes the request.
In an org with Require SSO on, an invite must include the invitee's email. Accepting it requires both the invite link and an SSO sign-in for that same email. The new device is then bound to the session. A leaked invite link alone is not enough to join.
Domain verification
- One verified domain belongs to one org. Another org cannot verify it. Public mail domains such as
gmail.comandoutlook.comare refused. - Subdomains are separate. Verifying
acme.comdoes not verifyeu.acme.com. - The IdP is trusted only for verified domains. It cannot assert an address at another company's domain. Linked identities continue to match by IdP subject.
- Records are checked daily. A missing TXT record immediately creates an audit event and an owner banner, then starts a seven-day grace period. Restoring the record ends the grace. A DNS lookup failure does not count as a missing record.
After seven days without the record, the domain is un-verified. Its addresses can no longer create identity links or join requests, and it cannot satisfy the verified-domain precondition for Require SSO. Identities that were already linked keep working by subject until an owner acts.
Sessions, sign-out and off-boarding
An SSO session is separate from the member's key. It expires after the org's configured lifetime: 12 hours by default, or 1–24 hours. In the dashboard it is kept per browser tab. In the CLI it is bound to the CLI device token.
| Event | Effect on SSO sessions |
|---|---|
Dashboard sign-out or dynv logout | Revokes the presented session. The CLI also deletes its local session file. |
| Owner chooses Sign out everywhere for a member | Revokes all of that member's SSO sessions on every device, including CLI sessions. Their passkeys and devices remain. |
| Member removed or device revoked | Revokes the member's sessions, or every session bound to that device. |
| IdP replaced or SSO configuration deleted | Revokes every SSO session in the org and drops its identity links. |
| Person disabled at the IdP | No immediate signal reaches Dynv. Their existing sessions remain valid until expiry or revocation. |
Threat model
| Adversary or event | What it can do | What it cannot do |
|---|---|---|
| Compromised or malicious IdP | Deny sign-ins, create sessions for addresses in verified domains and create join requests. It can let someone attempt a sign-in that still needs the member's passkey or device token. | Read secrets, add a member, device or key, grant access, assert addresses outside verified domains or take over a linked member by recycling an email address. |
| Stolen member device token | Act as the member when SSO is not required. With Require SSO, the thief must also get through that member's IdP sign-in. | Use a session bound to another device or bind a session for a different member. |
| Stolen SSO session secret | Nothing useful without the bound device's master token. | Work from another member's device, or after expiry or revocation. |
| Leaked invite link, with Require SSO on | Show the invite. | Join without an SSO session for the invite's email. |
| Owner using break-glass | Bypass the IdP for one hour at a time. | Do it silently: the action is audited and shown to every owner. |
| Malicious Dynv server | Ignore the server-enforced Require SSO policy, forge join requests and see SSO sign-in metadata. | Decrypt secrets or gain a key it did not already hold. SSO adds no key path to the server. |
Require SSO is a server-enforced policy. A malicious server could ignore it, just as it could ignore other route checks. The zero-knowledge key boundary still holds.
What the server stores
- The org's issuer, client id, verified domains, policy and session metadata.
- Peppered email and IdP-subject keys for identity mapping, not plaintext member email addresses.
- SHA-256 session verifiers, expiry, revocation and device-binding data. Session secrets are not stored.
- The OIDC client secret sealed at rest under a server-held key. The live server opens it only to exchange authorisation codes with the IdP.
- For a pending join request, the address sealed to the owners' public keys so they can read it locally.
OIDC ID tokens and SSO session secrets are not stored. See the security model for the wider key boundary.
Last updated