feat(auth): implement PKCE S256 for all OAuth providers (closes #730)#731
Merged
Conversation
Add RFC 7636 PKCE S256 support to all three OAuth2 login flows (OIDC, Google, GitHub). The implementation is always-on and stateless: a code_verifier is generated in each Login handler, embedded in the signed JWT state, and extracted in the Callback handler to pass to conf.Exchange. No configuration changes are required. Keycloak's PKCE enforcement is enabled in the e2e test suite (pkce.code.challenge.method=S256) so that the existing TestOIDCLoginBrowser test validates the full flow end-to-end. A dedicated negative test (TestOIDCLoginBrowserPKCEEnforced) verifies that Keycloak rejects an exchange that omits the code_verifier (real code + forged stateless JWT), proving the enforcement setting is active.
Member
Author
|
docker deploy |
|
🚀 Deployment Successful! The instance at plik.root.gg has been redeployed with image |
Contributor
|
That was fast! I'm using the APT repository, so no Docker image for me. Maybe just a binary? I don't know if |
Member
Author
|
If you have git and go I would say that the easiest would be to clone the
repo, pull the PR branch (`feat/pcke-oauth-providers`) , then `make server`
and copy the binary from `server/plikd` to where it is installed by the deb
package (`/usr/bin/plikd` I think)
…On Sat, Apr 4, 2026, 23:26 Glandos ***@***.***> wrote:
*Glandos* left a comment (root-gg/plik#731)
<#731 (comment)>
That was fast!
I'm using the APT repository, so no Docker image for me. Maybe just a
binary? I don't know if go install is able to fetch a PR?
—
Reply to this email directly, view it on GitHub
<#731 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/ABQ5XPWOPUAV6KS4XXGMUBD4UF4XBAVCNFSM6AAAAACXM3HYY6VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHM2DCOBXG43TEOJXG4>
.
You are receiving this because you authored the thread.Message ID:
***@***.***>
|
Contributor
|
That's exactly what I was doing just before reading your comment 🤓 Anyway, I've tested it, after |
Member
Author
|
Great news :) I'll merge the PR
…On Sat, Apr 4, 2026, 23:38 Glandos ***@***.***> wrote:
*Glandos* left a comment (root-gg/plik#731)
<#731 (comment)>
That's exactly what I was doing just before reading your comment 🤓
Anyway, I've tested it, after kanidm system oauth2 enable-pkce plik to
re-enable PKCE, and now: it works perfectly for me 🥳
—
Reply to this email directly, view it on GitHub
<#731 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/ABQ5XPRLN7MKPLTT3TZFCML4UF6ERAVCNFSM6AAAAACXM3HYY6VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHM2DCOBXG44DONBZGY>
.
You are receiving this because you authored the thread.Message ID:
***@***.***>
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
What
Implements RFC 7636 PKCE (Proof Key for Code Exchange) S256 across all three OAuth2 login flows: OIDC, Google OAuth, and GitHub OAuth.
Why
Closes #730. Providers like Keycloak (with
pkce.code.challenge.method=S256) and Kanidm require PKCE and will reject token exchanges that omit thecode_verifier. Without this, OIDC login simply fails against enforcing providers.Changes
Server handlers (
server/handlers/)oidc.go,google.go,github.go:Logingenerates a verifier viaoauth2.GenerateVerifier(), embeds it aspkceVerifierin the signed JWT state, and passesoauth2.S256ChallengeOption(verifier)toAuthCodeURL.CallbackextractspkceVerifierfrom the state and passesoauth2.VerifierOption(pkceVerifier)toconf.Exchange.pkceVerifieris absent from the state (old clients / rolling deploy), the verifier option is simply not sent.Keycloak e2e test suite (
testing/keycloak/)run.sh: client configured withpkce.code.challenge.method: S256— Keycloak now rejects any exchange missing a verifier.TestOIDCLoginBrowserpasses, proving the happy path works.TestOIDCLoginBrowserPKCEEnforced: obtains a real authorization code from Keycloak, then calls Plik's callback with a forged state JWT that has nopkceVerifier. Keycloak returnsinvalid_grant "Code not valid", confirming enforcement is active and the test would fail if PKCE were removed.Unit tests (
server/handlers/*_test.go)code_challenge,code_challenge_method=S256, andpkceVerifierin the state JWT — for all three providers.TestOIDCCallbackPKCEVerifier: verifies the verifier is forwarded to the token endpoint.TestOIDCCallbackPKCEEnforced: mock token server rejects missing verifier.Testing
NO_RACE=1 make test— all packages passmake test-backend keycloak— all 3 Keycloak e2e tests pass including the new enforcement testmake lint— cleanmake docs— builds without errors