Self-Hosted Setup

End-to-end walkthrough for wiring SAML SSO into a self-hosted sfp deployment (one you run yourself with sfp server init).

SAML is enabled by default on every self-hosted deployment. Signing material is generated during sfp server init, the IdP is registered through an HTTP API, and the resulting provider ID and SSO domain are auto-published to every client. There's no config-file editing required.


Prerequisites

  • A running self-hosted deployment created with sfp server init and brought up with sfp server start (V3 or later).

  • Admin access to your SAML identity provider.

  • An owner-level JWT for the sfp API. The admin user created by sfp server init has the owner role, which is what /sfp/api/sso/providers requires. Application tokens (UUID-format, created via sfp server application-token create) are explicitly rejected on this endpoint — only the user JWT works.

    # Sign in once; the token is stored in your OS keyring under service
    # `sfp-pro`, account `supabase-token-<your-email>`.
    sfp server auth login --admin \
      --email admin@<tenant>.local \
      --sfp-server-url https://<your-domain>
    
    # Extract it into a shell variable for the curl calls below.
    export SFP_JWT=$(sfp server auth display --email admin@<tenant>.local --jwt)

    Headless / WSL / SSH session? The keyring backend needs an active D-Bus session and a running gnome-keyring-daemon (or equivalent). If sfp server auth display --jwt errors with no secret service provider or dbus session found, prefix with dbus-launch or run from a graphical session.


Step 1 — Configure your IdP

Create the SAML application in your identity provider and copy out the federation metadata URL.

Pick the matching guide:

Other SAML 2.0 providers follow the same shape — see Identity Providers for the URL convention and attribute mapping.

When you finish, you should have a metadata URL that looks something like:


Step 2 — Register the IdP with sfp

One API call hands the metadata URL to sfp:

Auto-detect kicks in immediately — no restart needed. The response contains the provider id and the SAML entityId.

Verify

Remove a provider


Step 3 — Provision users

Self-registration is disabled by default, so users must be created before they can sign in. POST /sfp/api/users is the single entry point — it auto-detects the registered SSO provider and links the user to it:

User state on call
What happens

New user

Created with SSO identity.

Existing email/password user

Converted to SSO; identity linked to the IdP.

Existing SSO user

Idempotent; team membership added if missing.

Via the API:

Or via the CLI:


Step 4 — Sign in

CLI

You don't need to pass --sso-domain or --sso-provider-id if a provider is registered — the CLI fetches them from /sfp/api/config. Override only when needed:

The CLI opens your browser, completes the SAML round-trip, and stores the session in your OS keychain. SAML access tokens expire after about an hour; the CLI refreshes them automatically before expiry and on 401 responses. For long-running CI jobs, you can also force a refresh:

Web UI

Open https://<your-domain> in a browser. The login screen pre-fills the SSO domain from the server config. Click Continue to redirect to your IdP.

Desktop app

Open the desktop app and sign in with SAML — the IdP redirect is captured through the app's custom protocol handler. No extra configuration needed beyond having the provider registered on the server.


API reference

All endpoints below are owner-only unless noted.

POST /sfp/api/sso/providers

Register a SAML IdP. Body:

Returns { id, domains, entityId }.

GET /sfp/api/sso/providers

List registered providers.

DELETE /sfp/api/sso/providers/:id

Remove a provider.

GET /sfp/api/config (public)

Returns the public web-app configuration, including sso: { domain, providerId }.

POST /sfp/api/users

Create or link a user. Auto-detects the SSO provider; idempotent on re-runs.


Something not working?

See Troubleshooting.

Last updated

Was this helpful?