Single Sign-On (SSO)
Vetrix supports three SSO mechanisms: OAuth2 (for external identity providers), LDAP/Active Directory, and SAML 2.0. Each is configured independently.
OAuth2 (External Providers)
Vetrix ships an OAuth2 client that can authenticate users against any standards-compliant OAuth2 provider.
Built-in providers
External login providers (GitHub, Google, GitLab, Microsoft Entra) are configured through admin settings, not environment variables. Client IDs and client secrets live in the app_settings table under the oauth.<provider>.* keys; the secrets are AES-256-GCM sealed with SECRET_ENC_KEY (see the SECRET_ENC_KEY section in ../../admin-docs/admin/security.md).
Set each value through the Admin UI (Admin → Settings → OAuth Providers) or the settings API:
# GitHub
curl -X PUT https://<vetrix-host>/api/v1/admin/settings/oauth.github.client_id \
-H "Authorization: Bearer <admin-token>" -H "Content-Type: application/json" \
-d '"<client-id>"'
curl -X PUT https://<vetrix-host>/api/v1/admin/settings/oauth.github.client_secret \
-H "Authorization: Bearer <admin-token>" -H "Content-Type: application/json" \
-d '"<client-secret>"'
curl -X PUT https://<vetrix-host>/api/v1/admin/settings/oauth.github.enabled \
-H "Authorization: Bearer <admin-token>" -H "Content-Type: application/json" \
-d '"true"'
# Google
curl -X PUT https://<vetrix-host>/api/v1/admin/settings/oauth.google.client_id \
-H "Authorization: Bearer <admin-token>" -H "Content-Type: application/json" \
-d '"<client-id>"'
curl -X PUT https://<vetrix-host>/api/v1/admin/settings/oauth.google.client_secret \
-H "Authorization: Bearer <admin-token>" -H "Content-Type: application/json" \
-d '"<client-secret>"'
curl -X PUT https://<vetrix-host>/api/v1/admin/settings/oauth.google.enabled \
-H "Authorization: Bearer <admin-token>" -H "Content-Type: application/json" \
-d '"true"'
Note: historical versions of this document listed
OAUTH2_GITHUB_CLIENT_SECRET/OAUTH2_GOOGLE_CLIENT_SECRETenvironment variables. The server never read them — setting them had no effect. The admin-settings path above is the only supported configuration surface. Seeoauth2-external-providers.mdfor the full per-provider walkthrough (redirect URI registration, scopes, troubleshooting).
OAuth2 Authorization Server
Vetrix also acts as an OAuth2 server (PKCE authorization code flow), allowing third-party applications to request access tokens on behalf of users.
Register an application:
Registering an OAuth2 application through this endpoint is a self-service developer action, not an administrative one. Any authenticated user may call it with their own token, and the resulting application is owned by the user who registered it. No administrator privileges and no admin scope are required.
Ownership is exclusive only for changing an application: updating it
(PATCH /api/v1/user/oauth2/apps/{id}) and rotating its secret
(POST /api/v1/user/oauth2/apps/{id}/rotate-secret) are available to the owner
alone, because the administrative surface exposes no equivalent route. Listing,
inspecting and deleting are not owner-exclusive — the
/api/v1/admin/oauth2/apps endpoints described below reach every registered
application, whoever owns it.
POST /api/v1/user/oauth2/apps
Authorization: Bearer <user-jwt>
{
"name": "My CI Tool",
"description": "Automated pipeline trigger",
"redirect_uris": "https://my-ci-tool.example.com/callback",
"scopes": ["read:repo", "write:pipeline"]
}
Note: do not confuse
/api/v1/user/oauth2/appswith the separate/api/v1/admin/oauth2/appssurface. The/user/path above is the self-service developer console described here, scoped to the calling user's own applications. The/api/v1/admin/oauth2/appspath is a genuinely admin-only, instance-wide management view (list, inspect, suspend, unsuspend and delete any registered application, plus its grants and audit trail); every one of its endpoints requires theadmin:oauth2admin scope, and an instance super-admin clears that gate without holding the scope explicitly. It is a moderation surface, not a registration surface — administrators register their own applications through the/user/endpoint like everyone else./api/v1/admin/oauth2/providersis a different surface again: it configures the external identity providers covered earlier in this document, not registered applications.
Note: one further registration surface exists and is disabled by default:
POST /api/v1/oauth2/register(RFC 7591 dynamic client registration), gated by theoauth2.dcr.enabledsetting. It exists for MCP connectors rather than general application registration, and caps every client it creates at themcp:readscope. An authenticated caller must hold theadmin:oauth2scope; unauthenticated calls are accepted only within a configured redirect-URI allow-list and a per-source-IP rate limit.
Authorization code flow (PKCE):
-
Redirect the user to
/api/v1/oauth2/authorize:GET /api/v1/oauth2/authorize ?client_id=vetrix_... &redirect_uri=https://my-ci-tool.example.com/callback &response_type=code &scope=read:repo+write:pipeline &state=<random> &code_challenge=<base64url(SHA-256(verifier))> &code_challenge_method=S256 -
User approves → Vetrix redirects to
redirect_uri?code=<code>&state=<state>. -
Exchange code for a token:
POST /api/v1/oauth2/token Content-Type: application/x-www-form-urlencoded grant_type=authorization_code &code=<code> &redirect_uri=https://my-ci-tool.example.com/callback &client_id=vetrix_... &code_verifier=<verifier>
LDAP / Active Directory
LDAP authentication requires a third-party Go library (github.com/go-ldap/ldap/v3)
not included by default. To enable it:
- Add the dependency:
go get github.com/go-ldap/ldap/v3 - Implement
auth.LDAPAuthenticatorusing the library. - Wire the implementation into the application startup.
Configuration keys (environment variables):
| Variable | Description |
|---|---|
LDAP_URL |
Server URL, e.g. ldaps://dc.example.com:636 |
LDAP_BIND_DN |
Service account DN for searches |
LDAP_BIND_PASSWORD |
Service account password |
LDAP_BASE_DN |
Search base, e.g. dc=example,dc=com |
LDAP_USER_FILTER |
Filter template; {username} is replaced at query time |
SAML 2.0
SAML SP support requires github.com/crewjam/saml (not included by default).
To enable it:
- Add the dependency:
go get github.com/crewjam/saml - Implement
auth.SAMLProviderusing the library. - Register the metadata and ACS endpoints with the identity provider.
The auth.SAMLConfig struct documents all required configuration fields.
Required IdP configuration
| SP field | Value |
|---|---|
| Entity ID | https://<vetrix-host>/saml/metadata |
| ACS URL | https://<vetrix-host>/saml/acs |
| Name ID format | Email address |