Skip to main content
This documentation is for the federal deployments of Devin. Back to Devin Docs
By default, access to the air-gapped build is controlled only by the license file. You can additionally require each user to sign in to your own OIDC identity provider. SSO is layered on top of the license: the license is still required, and the login flow runs against the issuer you configure.

Create the auth file

The file selects exactly one mode. If the file does not exist, the product behaves as if it contained "mode": "license".
/etc/devin/auth.json
Unknown fields are rejected. In license mode only schema_version and mode are allowed.
If your IdP uses a certificate issued by a private CA, set DEVIN_CA_BUNDLE to a PEM bundle so the CLI trusts it; see Network and certificates.

Register the client at your IdP

The CLI runs the OIDC authorization-code flow with PKCE (S256) as a public client; there is no client secret. The client you register must meet these requirements:
  1. A public client (no client secret) with the ID you put in client_id, for example devin-cli, with the authorization-code grant enabled and PKCE method S256.
  2. http://127.0.0.1/callback registered as a valid redirect URI. The CLI listens on a random loopback port (http://127.0.0.1:<port>/callback) for the browser flow and uses the fixed http://127.0.0.1/callback for the manual flow. Per RFC 8252 the IdP should ignore the loopback port; if yours does not, register a matching wildcard.
  3. If you want to use required_group, the ID token must carry the group-membership claim named in groups_claim (groups by default).
  4. The IdP returns an ID token on refresh (most do when the openid scope is granted), and the ID-token lifetime for this client is short. See How revocation propagates for why.

Sign in

Log in from a terminal on the workstation:
On a headless host or over SSH, use the manual flow. The CLI prints a URL that you open in a browser on any machine; after signing in, the browser is redirected to a 127.0.0.1 URL that will not load. Copy that full URL (including its query parameters) and paste it back into the terminal.
Devin Desktop uses the same login through the bundled agent; a user who is not signed in is prompted to sign in, in Devin settings, before starting work.

Check status and sign out

If the cached login is missing or can no longer be refreshed, the output is Status: not logged in (<reason>) followed by Run \devin auth login` to sign in.`
Logout is local only: it deletes the token cache and does not contact the IdP.

What the CLI validates

The ID token is validated locally: signature against the IdP’s JWKS, iss, aud, expiry (with a 120-second clock-skew tolerance), the login nonce, and the group gate. The ID and refresh tokens are cached in the local credentials store with owner-only permissions (0600) and refreshed silently against the IdP. When SSO is configured and no valid login exists (and silent refresh fails), the CLI exits at startup with an error telling the user to run devin auth login. The CLI never follows HTTP redirects from the IdP: a 3xx from the discovery, JWKS, or token endpoint fails the login with an error naming the endpoint, so issuer must point at the URLs the IdP actually serves.

Discovered endpoints must stay on the issuer

The authorization_endpoint, token_endpoint, and jwks_uri learned from discovery must have the same scheme, host, and port as issuer (default ports count as equal). An endpoint on any other host is refused and login fails with an error like:
Some IdP topologies legitimately serve endpoints from more than one host. The common on-prem case is Keycloak with hostname-backchannel-dynamic=true, where token_endpoint and jwks_uri are rewritten to the internal hostname the CLI connected through. If, and only if, you have confirmed with the IdP’s own configuration that the extra host is intentional, add it:
Entries are host (any port) or host:port, matched case-insensitively. There is no wildcard and no way to disable the check. The allowlist never relaxes TLS: an http:// endpoint is still refused under an https:// issuer. Do not add a host just because a login error names it; the error is the check working.

How revocation propagates

The group gate is evaluated on the cached ID token, so removing a user from required_group (or disabling the user) at the IdP takes effect on their next token refresh: at the latest when the current ID token expires, plus the 120-second skew tolerance. Keep the ID-token lifetime for this client short if fast revocation matters. A refresh response that omits a new ID token keeps the cached ID token in use, but only for up to 24 hours past that token’s exp; after that the user must sign in again even if the IdP still accepts the refresh token.

Revalidation in running sessions

While Devin Desktop (or any client of the bundled agent) is running, the agent re-checks the login every 60 seconds and forces a token refresh against the IdP at least every 15 minutes. If a check fails, the agent records an sso_revalidation_failed audit event with the IDP code, stops accepting new work, and shuts down; the user must sign in again and restart.

What gets audited

SSO activity is written to the local audit log as auth events. Every event that has a validated token at hand carries the SSO identity on actor (sso_issuer, sso_subject, sso_user, sso_groups).

IDP error codes

The complete catalog is on the Error codes page.