Recent Chats
Sign in to access your chat history.
So I've just managed to get Sourcebot spun up this morning, and upon configuring JC SSO, the request appears to fail. The SB login screen gives a generic "An error occurred during authentication. Please try again" banner.
Looking at the request flows, I can see the following response from the JC auth request:
error=invalid_state&error_description=The+state+is+missing+or+does+not+have+enough+characters+and+is+therefore+considered+too+weak.+Request+parameter+%27state%27+must+be+at+least+be+8+characters+long+to+ensure+sufficient+entropy.&state=
Details
Answer
invalid_state ErrorThe error you're seeing — invalid_state / The state is missing or does not have enough characters — is not a bug in Sourcebot's code, but almost certainly a configuration issue with the AUTH_SECRET environment variable.
Sourcebot uses Auth.js (NextAuth.js) for authentication. During an OIDC flow (like JumpCloud SSO), Auth.js generates a cryptographic state parameter that it sends to the identity provider as a CSRF protection measure. This state is derived from the AUTH_SECRET value.
The default AUTH_SECRET in the docker-compose.yml is a placeholder value of all zeros docker-compose.yml:21-21:
If you haven't overridden AUTH_SECRET with a properly generated random secret, Auth.js will produce a weak or degenerate state value. JumpCloud is stricter than some other OIDC providers and enforces a minimum of 8 characters of entropy on the state parameter — hence the rejection.
Generate a proper AUTH_SECRET using the command suggested in the docker-compose comment:
Set AUTH_SECRET in your environment (either in a .env file or directly in your docker-compose.yml override) with the generated value.
Also verify AUTH_URL is set correctly docker-compose.yml:20-20. It must match the externally accessible URL of your Sourcebot instance (e.g., https://sourcebot.coolcorp.com), not the default http://localhost:3000. Auth.js uses this to construct the callback URL and state validation. A mismatch here can also cause state issues.
Restart Sourcebot after making changes.
Make sure your JumpCloud SSO app is configured per the docs idp.mdx:527-568:
<your_AUTH_URL>/api/auth/callback/jumpcloud<your_AUTH_URL>/loginhttps://oauth.id.jumpcloud.comAnd your Sourcebot config file includes the JumpCloud identity provider idp.mdx:546-565:
The JumpCloud provider is created as a generic OIDC provider in sso.ts:437-447, which relies on Auth.js's standard OIDC state handling — so the fix is entirely on the configuration side.
| Check | What to verify |
|---|---|
AUTH_SECRET | Must be a strong random string (≥33 chars), not the default zeros |
AUTH_URL | Must match your external Sourcebot URL exactly |
| JumpCloud redirect URI | Must be <AUTH_URL>/api/auth/callback/jumpcloud |
| JumpCloud issuer env var | Typically https://oauth.id.jumpcloud.com |
AUTH_SECRET is set to a suitable value.
However the login attempts are still failing. It looks like the generated request URL for JumpCloud doesn't include the state param. Example:
Details
Answer
checks in createJumpCloudProviderThis is a bug in Sourcebot's createJumpCloudProvider implementation. The state parameter is absent from the authorization URL because the JumpCloud provider is defined as a plain object without a checks field, which tells Auth.js which security mechanisms to use during the OIDC flow.
The createJumpCloudProvider function sso.ts:437-447 returns a bare object with just the minimum fields:
Auth.js uses the checks array on a provider config to decide what to include in the authorization URL. Without it explicitly set, Auth.js defaults to ["pkce"] only for OIDC providers — meaning it generates a code_challenge and code_challenge_method (which you can see in your URL), but omits the state parameter, since "state" is not in the checks list.
JumpCloud's OIDC implementation requires the state parameter to be present and at least 8 characters long.
Compare with createAuthentikProvider sso.ts:427-435 or createOktaProvider sso.ts:306-314 — these use the official next-auth provider wrappers (e.g. Authentik(...), Okta(...)) which include proper defaults like checks: ["pkce", "state"] internally. The JumpCloud provider uses a raw object and misses this.
The createJumpCloudProvider function needs checks: ["pkce", "state"] added to the provider object sso.ts:437-447:
This will cause Auth.js to include both the code_challenge (PKCE) and the state parameter in the redirect URL sent to JumpCloud, satisfying JumpCloud's entropy requirement.
If you cannot patch the code directly, you could raise this as a bug with the Sourcebot team referencing the createJumpCloudProvider function sso.ts:437-447 — the fix is a one-line addition and straightforward.
So the changes suggested have been made, however it's still failing with:
Details
Answer
It looks like your message got cut off! Could you share the error you're seeing after applying the fix? For example:
docker logs <container>)Details
Answer
client_secret_post Auth MethodGood progress — the state fix is working (JumpCloud is now getting far enough to attempt token exchange), but now the token endpoint authentication method is mismatched.
By default, Auth.js sends client credentials using client_secret_basic (i.e., base64-encoded in the Authorization HTTP header). JumpCloud expects client_secret_post (i.e., credentials sent in the POST body).
Interestingly, the exact same fix already exists in the codebase for the Bitbucket Server provider via the client field sso.ts:381-381:
Add the same client field to createJumpCloudProvider sso.ts:437-448:
This instructs Auth.js's underlying openid-client library to send the client_id and client_secret as POST body parameters during the token exchange, which is what JumpCloud's token endpoint requires.
| Fix | Field Added | Resolves |
|---|---|---|
| 1 | checks: ["pkce", "state"] | Missing state param in auth URL |
| 2 | client: { token_endpoint_auth_method: "client_secret_post" } | invalid_client on token exchange |
Both fields together should get you through the full OIDC flow with JumpCloud.
It was possible to "fix" this by updating the JC app to use client_secret_basic :)
Details
Answer
That's a completely valid alternative fix! Both approaches are equivalent — you're just making the two sides agree on the same auth method:
| Approach | Where the change is made |
|---|---|
Add client: { token_endpoint_auth_method: "client_secret_post" } to Sourcebot | Sourcebot adapts to JumpCloud's default |
Change JumpCloud app to use client_secret_basic | JumpCloud adapts to Auth.js's default |
Changing it on the JumpCloud side is arguably the less invasive option since it doesn't require a code change or redeployment of Sourcebot.
Is the login flow fully working now end-to-end, or are you still hitting issues further along in the flow?
login flow is fully working :)
Details
Answer
That's great news! 🎉
To summarise what was needed to get JumpCloud SSO working with Sourcebot:
AUTH_SECRET must be set to a strong random value (e.g. openssl rand -base64 33) — the default placeholder breaks state generationchecks: ["pkce", "state"] needs to be added to createJumpCloudProvider sso.ts:437-447 — without it, Auth.js omits the state param from the authorization URL, which JumpCloud rejectsclient: { token_endpoint_auth_method: "client_secret_post" } to the Sourcebot provider config, or configure the JumpCloud app to use client_secret_basic (your chosen approach)It would be worth raising a bug/PR against Sourcebot for point #2 specifically — the missing checks field in createJumpCloudProvider sso.ts:437-447 is a genuine bug that will affect any user trying to set up JumpCloud SSO out of the box, regardless of how they handle the auth method question.
Point 2 was fixed in https://github.com/sourcebot-dev/sourcebot/pull/1020 :)
Details
Answer
Great — the fix from your debugging session has already landed in the codebase! Commit 9921abce sso.ts:437-448 (authored by you — fatmcgav) merged PR #1020, which added checks: ["pkce", "state"] to createJumpCloudProvider:
So anyone pulling the latest version of Sourcebot will now have the state fix included out of the box sso.ts:445-445.
The one thing that hasn't been upstreamed yet is the client_secret_post vs client_secret_basic discrepancy — but as you worked around that by configuring JumpCloud to use client_secret_basic, it's arguably not a Sourcebot bug, just a JumpCloud default that differs from Auth.js's default. Either way, future JumpCloud SSO users benefit from the state fix already being in place. Nice work getting it merged! 🎉
Docs fix is in https://github.com/sourcebot-dev/sourcebot/pull/1022 :)
Details
Answer
That's great — PR #1022 has also landed! The JumpCloud docs section idp.mdx:523-568 now exists with full setup instructions covering:
<sourcebot_url>/api/auth/callback/jumpcloud), login URL idp.mdx:529-538CLIENT_ID, CLIENT_SECRET, and ISSUER idp.mdx:539-541https://oauth.id.jumpcloud.com idp.mdx:537-537So between PR #1020 (code fix) and PR #1022 (docs), future JumpCloud SSO users should have a much smoother experience than you did this morning! 🎉 Great contributions.
This chat is read-only.
