Documenso + Keycloak: Add Single Sign-On to Your Self-Hosted E-Signing

Documenso + Keycloak: Add Single Sign-On to Your Self-Hosted E-Signing

Documenso is great until your team grows past five people. Suddenly you are creating accounts one by one, resetting passwords, and praying that nobody puts a customer NDA behind a personal Gmail. Plug Documenso into Keycloak and that whole problem disappears. New hires get access on day one through the same SSO flow they use for everything else, and offboarding becomes "disable in Keycloak, done."

This guide walks through the actual OIDC wiring. No theory, no marketing pages, just the environment variables and Keycloak client settings you need to ship it today.

What You Need Before You Start

  • A Keycloak instance reachable from your Documenso server (HTTPS, not localhost)
  • A Documenso self-hosted instance you can restart (Docker Compose, Kubernetes, or anything that lets you set env vars)
  • Admin access to a Keycloak realm
  • Your Documenso public URL (the value you set in NEXT_PUBLIC_WEBAPP_URL)

If you do not have Keycloak running yet, the one-click Keycloak deployment on Elestio takes about three minutes and gives you a managed instance with backups and TLS. Same for Documenso on the other side.

Step 1. Create the Keycloak Client

Sign in to your Keycloak admin console and select the realm you want Documenso users to authenticate against. We will use documenso as the realm name in the rest of the guide.

Go to Clients > Create client and fill in:

  • Client type: OpenID Connect
  • Client ID: documenso
  • Name: Documenso

Click Next. On the Capability config screen:

  • Client authentication: ON (this makes it a confidential client and generates the client secret you will need)
  • Authentication flow: keep Standard flow checked, uncheck the others

Click Next. On the Login settings:

  • Root URL: https://docs.example.com (your Documenso URL)
  • Valid redirect URIs: https://docs.example.com/api/auth/callback/oidc
  • Web origins: https://docs.example.com

Save. Now go to the Credentials tab and copy the client secret. You will paste it into Documenso in Step 2.

While you are still in Keycloak, go to Client scopes > documenso-dedicated > Add mapper > By configuration > User Attribute if you want to map custom attributes (job title, department) into the OIDC token. For a basic setup the default email, profile, and openid scopes are enough.

Step 2. Configure Documenso

Add the following environment variables to your Documenso deployment. The exact path depends on how you deploy: .env for local Docker, the Helm values file for Kubernetes, or the environment tab in the Elestio dashboard.

NEXT_PRIVATE_OIDC_WELL_KNOWN="https://keycloak.example.com/realms/documenso/.well-known/openid-configuration"
NEXT_PRIVATE_OIDC_CLIENT_ID="documenso"
NEXT_PRIVATE_OIDC_CLIENT_SECRET="paste-the-secret-from-keycloak-here"
NEXT_PRIVATE_OIDC_PROVIDER_LABEL="Sign in with Company SSO"
NEXT_PRIVATE_OIDC_SKIP_VERIFY="true"
NEXT_PRIVATE_OIDC_PROMPT="login"

A few things worth knowing:

  • NEXT_PRIVATE_OIDC_PROVIDER_LABEL is what users see on the login button. Make it match the language your team already uses ("Sign in with Okta", "Sign in with Google Workspace", etc.) instead of leaving the default OIDC.
  • NEXT_PRIVATE_OIDC_SKIP_VERIFY=true trusts the email from your IdP and skips Documenso's own email verification step. Set this to true when Keycloak is the source of truth for identity. Leave it false if you want a belt-and-suspenders confirmation email.
  • NEXT_PRIVATE_OIDC_PROMPT controls the OIDC prompt parameter. The default login forces a fresh login each time. Set to an empty string ("") if you want users to stay logged in via Keycloak's session cookie.

Restart Documenso. The login page should now show a second button below the email/password form: "Sign in with Company SSO."

Step 3. Test the Round Trip

Open a private browser window and visit your Documenso URL. Click the SSO button. You should land on Keycloak's login page, authenticate with a test user, and be bounced back to Documenso with an active session.

Two things to verify:

  1. First-time users: Documenso should automatically create a local user record on first SSO login, with the email and name pulled from the OIDC claims.
  2. Existing users: If the email in the OIDC token matches an existing Documenso account, the SSO login should link to that account rather than creating a duplicate.

Optional: Require Pre-Provisioned Accounts

By default, Documenso auto-creates a local user the first time someone signs in through SSO. That is convenient, but it also means anyone in your Keycloak realm gets a Documenso account on first login. If you want tighter control, set:

NEXT_PUBLIC_DISABLE_OIDC_SIGNUP="true"

That blocks first-time account creation through OIDC. Users who already exist in Documenso (and have the OIDC provider linked) can still sign in. New people get rejected at login until an admin invites them. Useful when your Keycloak realm spans more people than should have signing rights.

Troubleshooting

"Invalid redirect_uri" from Keycloak. Your Documenso URL and the Valid redirect URIs in Keycloak do not match exactly. Common cause: HTTP vs HTTPS, trailing slash, or a port number in one place but not the other. The full callback path is /api/auth/callback/oidc.

"client_id not found" or 401 from the token endpoint. The NEXT_PRIVATE_OIDC_CLIENT_ID value does not match the client ID you set in Keycloak. They are case-sensitive. Also double-check that the client is enabled in Keycloak (the toggle at the top of the client settings page).

SSO button shows but clicking it does nothing. Documenso could not reach the well-known URL on startup. Check container logs for connection errors, and confirm the Keycloak realm URL resolves correctly from inside the Documenso network (docker compose exec documenso curl <well-known-url>).

Login succeeds but Documenso shows "user not found". Your IdP is not returning an email claim, or the claim is in a non-standard field. In Keycloak, go to Client scopes > documenso-dedicated > Add predefined mapper and make sure the email and profile mappers are active.

Wrapping Up

You now have a Documenso instance where new hires get e-signing access the moment they show up in Keycloak, and revoking access is a single click. The bonus is audit trail: every signature is now tied to a centrally-managed identity rather than a one-off Documenso account.

If you want to skip the SSL certs, backups, and version-pinning that come with running both Keycloak and Documenso yourself, you can deploy them in one click on Elestio and connect them with the same env vars above.

Thanks for reading. See you in the next one.