Auth and Identity
Complete guide to authentication, MFA, OAuth, session management, and identity lifecycle in GitOpsHQ.
GitOpsHQ provides a complete identity layer that handles user registration, login, multi-factor authentication, session management, and organization context switching. Every API call is scoped to both a verified identity and an active organization.
Authentication Methods
GitOpsHQ supports two primary authentication methods: email/password credentials and OAuth social login. The available methods are configurable per deployment.
Email and Password
Standard registration and login with email and password. Passwords are hashed and stored securely. Users receive a verification email after registration.
OAuth Providers
GitOpsHQ supports three OAuth providers out of the box:
| Provider | Scopes Requested | Use Case |
|---|---|---|
openid, email, profile | Teams using Google Workspace | |
| GitHub | user:email, read:org | Engineering-heavy organizations |
| Microsoft | openid, email, profile | Enterprises on Azure AD / Entra ID |
OAuth providers are enabled per deployment. Use GET /api/v1/auth/config to discover which providers are available in your environment.
OAuth Login Flow
Initiate
User clicks an OAuth button. GitOpsHQ redirects to the provider's authorization endpoint with the configured client_id, redirect_uri, and scopes.
Authenticate
User authenticates with the provider (Google, GitHub, or Microsoft). If already signed in to the provider, this step is automatic.
Callback
The provider redirects back to GitOpsHQ with an authorization code. GitOpsHQ exchanges the code for an access token and retrieves the user's profile.
Session
GitOpsHQ creates or links the user account, issues a JWT access token, and sets a refresh token in an HttpOnly cookie.
Auth Configuration Endpoint
GET /api/v1/auth/configResponse:
{
"registrationOpen": true,
"providers": ["google", "github", "microsoft"],
"mfaAvailable": true
}This endpoint is public and allows the login page to dynamically render the correct set of sign-in options.
Multi-Factor Authentication (MFA)
GitOpsHQ supports TOTP-based MFA (compatible with Google Authenticator, Authy, 1Password, and other authenticator apps) and email OTP as a fallback.
MFA Setup Flow
Generate Secret
Navigate to Profile > Security > Enable MFA. GitOpsHQ generates a TOTP secret and presents a QR code.
Scan QR Code
Scan the QR code with your authenticator app. The app will begin generating 6-digit codes that rotate every 30 seconds.
Verify First Code
Enter the current 6-digit code from your app to prove the secret was registered correctly.
Save Recovery Codes
GitOpsHQ generates 8 single-use recovery codes. Store them in a secure location (password manager, printed sheet in a safe). Each code can be used exactly once in place of a TOTP code.
MFA Active
All future logins will require a TOTP code after the password step.
MFA Methods
Time-based One-Time Passwords using the TOTP standard (RFC 6238). Works offline and is the recommended primary method.
- 6-digit codes, 30-second rotation
- Compatible with any TOTP authenticator app
- No network dependency at verification time
If email delivery is configured, users can request a one-time code sent to their registered email address.
- 6-digit code delivered via email
- Valid for 10 minutes
- Requires email delivery service to be configured on the deployment
If email delivery is not configured in your deployment, the email OTP option is unavailable. TOTP remains the primary and required method.
Recovery codes are generated when MFA is first enabled. They are a safety net for when you lose access to your authenticator app.
- 8 codes generated at setup time
- Each code is usable exactly once
- After all codes are consumed, you must contact an org owner to reset MFA
- Recovery codes can be regenerated from the security settings page (invalidates old codes)
Disabling MFA
To disable MFA on your account, you must provide either a valid TOTP code or one of your unused recovery codes. This prevents an attacker who has your password from disabling your second factor.
Session Management
GitOpsHQ uses a JWT-based session model with short-lived access tokens and long-lived refresh tokens.
| Token Type | Storage | Lifetime | Purpose |
|---|---|---|---|
| Access Token (JWT) | In-memory / Authorization header | 15 minutes | API authentication |
| Refresh Token | HttpOnly, Secure, SameSite cookie | Configured via SessionDurationH | Silent token renewal |
Token Lifecycle
JWT Claims
The access token includes the following claims:
| Claim | Description | Example |
|---|---|---|
sub | User ID (set via standard RegisteredClaims.Subject) | usr_01H5K3M... |
uid | User ID | usr_01H5K3M... |
email | User email | alice@example.com |
org_id | Active organization ID | org_01H5K3N... |
role | Role in the active organization | admin |
exp | Token expiration timestamp | 1719500000 |
Token Refresh
POST /api/v1/auth/refreshThe refresh token is sent automatically via the HttpOnly cookie. If valid, a new access token and a rotated refresh token are returned. Refresh token rotation ensures that a stolen token can only be used once.
Logout
POST /api/v1/auth/logoutLogout invalidates the refresh token on the server and clears the cookie on the client. The access token remains valid until its natural expiration (up to 15 minutes), but the refresh mechanism is immediately broken.
Organization Context
Users in GitOpsHQ can belong to multiple organizations. Every API call is scoped to the user's active organization.
How Organization Context Works
- After login, if the user belongs to exactly one organization, it becomes active automatically.
- If the user belongs to multiple organizations, they select one from the organization picker.
- The active organization ID is encoded in the JWT
org_idclaim. - All subsequent API calls are scoped to this organization.
Switching Organizations
PUT /api/v1/auth/active-organization
Content-Type: application/json
{
"organizationId": "org_01H5K3N..."
}Switching organizations issues a new JWT with the updated org_id and role claims. The UI immediately refreshes to show the new organization's resources.
Switching organizations changes your effective permissions. UI elements (menus, buttons, actions) may appear or disappear based on your role in the new organization.
Organization Context Header
The X-Organization-ID header is used only during POST /api/v1/auth/refresh (token refresh) to select which organization context the new access token should contain. It is not used on regular Bearer API calls to override the organization context embedded in the JWT.
curl -X POST \
-H "X-Organization-ID: org_01H5K3N..." \
https://app.gitopshq.io/api/v1/auth/refreshInvitation Flow
Organization admins and owners can invite new users via email.
Invitation Lifecycle
| Stage | Endpoint | Description |
|---|---|---|
| Send | POST /api/v1/organizations/{slug}/invitations | Admin sends invitation with target email and role |
| Lookup | GET /api/v1/invitations/{token} | Public endpoint to verify invitation details before accepting |
| Accept | POST /api/v1/invitations/{token}/accept | Invited user accepts and joins the organization |
| Reissue | POST /api/v1/organizations/{slug}/invitations/{id}/reissue | Reissue the invitation email with a new token |
| Revoke | DELETE /api/v1/organizations/{slug}/invitations/{id} | Cancel a pending invitation |
Invitation Rules
- Invitations expire after 7 days by default.
- Accepting an invitation with a different email than the one it was sent to will fail with
403 invitation email mismatch. - An invitation can be reissued, which generates a new token and resets the expiry.
- Only
ownerandadminroles can send invitations.
MFA States
MFA has four distinct states visible throughout the identity lifecycle:
| State | Meaning | User Action |
|---|---|---|
not-configured | User has not set up MFA | Set up via Profile > Security |
required | Login succeeded but MFA challenge is pending | Enter TOTP code or recovery code |
verified | MFA challenge completed | Full access granted |
recovery-needed | All recovery codes consumed, authenticator lost | Contact org owner for MFA reset |
Auth Error Reference
The backend uses plain string messages rather than structured error codes. The table below lists typical messages you may encounter; exact wording may vary across versions.
Security Best Practices
- Enable MFA on your account immediately after registration. Use TOTP, not email OTP.
- Store recovery codes in a password manager, not in plain text files.
- Use OAuth where available to reduce password fatigue.
- Log out of shared devices explicitly; do not rely on token expiration.
- Check your active organization before performing any write operation.
- Use role-based access: Assign the minimum role required for each member.
- Review audit logs regularly for unexpected auth events (failed logins, MFA disables, org switches).
- Rotate service account tokens on a regular schedule (every 90 days recommended).
- Revoke invitations that are not accepted within a reasonable timeframe.
- Limit owner count to 2-3 trusted individuals to minimize blast radius.
Identity and Authorization Chain
Authentication is only the first step. The full authorization chain in GitOpsHQ works as follows:
- Identity establishes who the user is (authentication).
- Organization context determines which organization's resources are visible.
- Org role provides baseline permissions (owner, admin, member, viewer).
- Resource grants refine access at the cluster, project, or tenant level.
- Approval policies may gate specific actions even when the user has permission.
For detailed information on roles, grants, and governance policies, see Organization and Governance.