← Security

People

How humans access gittan. Email OTP out of the box, SSO when you need it. No passwords, no enterprise add-on.

How it works

gittan has no password database. There are two ways to sign in:

  • Email OTP — a 6-digit code sent to your email on every login. Works out of the box, no setup needed.
  • OIDC (SSO) — sign in through your identity provider (Entra, Google, Okta, etc.). Your IdP becomes the source of truth for who has access.

Both methods are passwordless. Email OTP is the default — every org starts with it. OIDC can be added when your org is ready to centralize identity.

Email OTP

No configuration required. Users enter their email and receive a 6-digit code. Codes are single-use and expire after 10 minutes.

Email OTP works for any org size but does not give you centralized user lifecycle management — removing someone from your IdP has no effect because there is no IdP.

OIDC (SSO)

SSO is included on every plan. It is not an enterprise add-on. Gating SSO behind a pricing tier forces small teams into weaker authentication, and we think that is wrong. Any OIDC-compliant provider works — Entra, Google, Okta, Keycloak, etc.

CLI authentication

The CLI uses device-flow authentication:

gittan auth login

This opens your browser for approval. Tokens are stored locally and refreshed automatically. No passwords are ever stored on disk.

Offboarding

When someone leaves, an org owner must remove them from the org in gittan. This is a manual step — there is no spec-supported way to receive real-time removal events from an external IdP for third-party applications.

Remove a member via Admin > Members or the API (DELETE /orgs/:orgId/members/:userId). This revokes org access instantly — the user’s next API call returns 403. Team memberships and linked identities are cleaned up in the same operation.

Access safety net (OIDC only)

If you use OIDC and forget to remove someone from gittan, there is a safety net: on every token refresh, gittan validates the user’s session against your IdP. If the IdP rejects the token (user disabled, account deleted, token revoked), the session ends within one hour — the maximum lifetime of an access token.

This prevents lingering access but is not a substitute for proper offboarding. The user’s identity, team memberships, and audit trail remain in gittan until an org owner removes them. Treat IdP removal as the trigger to also remove them from gittan.

Transient IdP failures (5xx, timeouts) do not lock users out. Only a definitive rejection ends the session.

Email OTP users have no IdP to validate against — their sessions continue until an org owner removes them or their refresh token expires.

Setting it up

Email OTP works out of the box. The rest of this section covers OIDC setup.

Register gittan in your IdP

Register gittan as an application in your identity provider. gittan needs three things from the registration:

FieldDescription
Issuer URLYour IdP’s OIDC discovery endpoint (the URL that serves /.well-known/openid-configuration).
Client IDThe application/client ID from your IdP.
Client secretThe client secret from your IdP.

Set the redirect URI to:

https://auth.gittan.eu/identity/callback

Required scopes

gittan requests these scopes during login:

ScopeRequiredPurpose
openidYesIdentifies this as an OIDC request. Returns an ID token with the sub claim — the only claim gittan uses to identify the user.
emailRecommendedUsed during account linking to match the external identity to a gittan account. Not used after linking — identity is tracked by sub only.
profileOptionalProvides display name. gittan stores this from the user’s own profile, so this is only used as a fallback during initial setup.
offline_accessYesRequests a refresh token from your IdP. Required for the access safety net — gittan validates this token on every session refresh to confirm the user still exists in your IdP.

Required ID token claims

gittan only requires the standard OIDC claims from the ID token:

ClaimRequiredNotes
subYesStable, unique identifier for the user at the IdP. This is the only claim used for identity lookup after initial linking.
issYesMust match the configured issuer URL exactly.
audYesMust contain the configured client ID.
expYesStandard OIDC. Token must not be expired.
nonceYesMust match the nonce sent in the authorization request. Replay protection per OIDC Core §3.1.3.7.

gittan does not require or use custom claims. User profiles (name, email, avatar) are managed within gittan — your IdP only needs to confirm identity.

Provider-specific instructions

Microsoft Entra ID

  1. Register a new app in App registrations.
  2. Set Redirect URI to https://auth.gittan.eu/identity/callback (type: Web).
  3. Under API permissions, add: openid, email, profile, offline_access (all delegated, Microsoft Graph).
  4. Create a client secret under Certificates & secrets.
  5. Issuer URL: https://login.microsoftonline.com/{tenant-id}/v2.0

Entra returns offline_access as a refresh token only when explicitly requested as a scope and added as an API permission. Both are required.

Google Workspace

  1. Create an OAuth 2.0 client in Google Cloud Console > APIs & Services > Credentials.
  2. Set Authorized redirect URI to https://auth.gittan.eu/identity/callback.
  3. Issuer URL: https://accounts.google.com

Google does not use the offline_access scope. Instead, it returns a refresh token when access_type=offline is set and the user consents. gittan handles this automatically — no extra configuration needed on the Google side.

Okta

  1. Create a new Web application in Applications.
  2. Set Sign-in redirect URI to https://auth.gittan.eu/identity/callback.
  3. Under General > Allowed grant types, enable Authorization Code and Refresh Token.
  4. Issuer URL: https://{your-domain}.okta.com (or custom authorization server URL).

Okta requires offline_access as a scope and the Refresh Token grant type enabled on the app. Without both, no refresh token is issued.

Configure in gittan

Once your IdP app is registered, configure it in gittan:

  1. Go to your org’s Admin > Authentication.
  2. Enter the Issuer URL, Client ID, and Client secret.
  3. Save. gittan verifies the issuer by fetching its OIDC discovery document before saving.

The default scopes (openid email profile offline_access) are set automatically. Override them only if your IdP handles refresh tokens differently (e.g., Google — see above).

Group claims and team mapping

When your IdP includes group claims in the OIDC token, gittan can map them to team membership. An admin triggers sync via Admin → Sync groups or the API — it is not automatic on login. See group sync.