Vetrix Docs

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_SECRET environment variables. The server never read them — setting them had no effect. The admin-settings path above is the only supported configuration surface. See oauth2-external-providers.md for 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/apps with the separate /api/v1/admin/oauth2/apps surface. 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/apps path 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 the admin:oauth2 admin 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/providers is 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 the oauth2.dcr.enabled setting. It exists for MCP connectors rather than general application registration, and caps every client it creates at the mcp:read scope. An authenticated caller must hold the admin:oauth2 scope; unauthenticated calls are accepted only within a configured redirect-URI allow-list and a per-source-IP rate limit.

Authorization code flow (PKCE):

  1. 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
    
  2. User approves → Vetrix redirects to redirect_uri?code=<code>&state=<state>.

  3. 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:

  1. Add the dependency: go get github.com/go-ldap/ldap/v3
  2. Implement auth.LDAPAuthenticator using the library.
  3. 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:

  1. Add the dependency: go get github.com/crewjam/saml
  2. Implement auth.SAMLProvider using the library.
  3. 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