Skip to content

Conversation

@Kahitar
Copy link

@Kahitar Kahitar commented Feb 2, 2026

Description

Fixes OAuth2 client credentials authentication failure by using standard Base64 encoding instead of URL-safe Base64 for Authorization: Basic headers.

Problem: kulala.nvim was incorrectly using URL-safe Base64 encoding (+-, /_) for HTTP Basic authentication headers, violating RFC 7617 which requires standard Base64 encoding. This caused invalid_client errors with (some/strict) OAuth2 providers when client credentials contained + or / characters in their Base64 representation.

Solution: Added base64_encode_standard() function for OAuth2 Basic authentication while preserving existing URL-safe encoding for PKCE/JWT use cases.

Evidence:

  • Working credentials: Those without +// in Base64 worked by coincidence
  • Failing credentials: Those with +// failed authentication (e.g., position 83: + vs -)
  • Verification: Manual curl testing confirms standard Base64 succeeds, URL-safe fails

Files changed:

  • lua/kulala/cmd/crypto.lua: Added base64_encode_standard() function
  • lua/kulala/cmd/oauth.lua: Updated OAuth2 Basic auth to use standard encoding

Note

Please open your PR against develop branch. It will be merged into develop and in ~5-7 days merged into main
as part of Weekly updates PR.

Type of Change

  • Bug fix
  • New feature
  • Documentation update
  • Refactoring
  • Tree-sitter grammar change

Checklist

  • I have read the CONTRIBUTING.md guidelines
  • Code follows the project style (run ./scripts/lint.sh check-code)
  • Tests pass locally (make test)
  • Documentation is updated (if applicable)
  • Docs follow the style guide (run ./scripts/lint.sh check-docs)

Note

Neovim help files will be generated automatically from .md documentation, so no need to edit .txt files manually.

If this PR includes tree-sitter grammar changes:

n.a.

Related Issues

This PR addresses OAuth2 authentication failures reported by users where client credentials authentication would fail with invalid_client errors despite correct credentials.

References:

🚀 Niklas Arens and others added 2 commits February 2, 2026 15:23
- Add base64_encode_standard() function for OAuth2 Basic auth headers
- Keep base64_encode() as URL-safe for PKCE and JWT use cases
- Update oauth.lua to use standard Base64 for Authorization: Basic headers

This fixes the OAuth2 client credentials authentication issue where kulala
was incorrectly using URL-safe Base64 encoding (+ -> -, / -> _) instead of
standard Base64 encoding as required by RFC 6749 Section 2.3.1.

Fixes authentication failures with OAuth2 providers that strictly validate
Base64 encoding in Authorization: Basic headers.
…ntials

- Add unit tests for base64_encode_standard() and base64_encode() functions
- Add integration tests for OAuth2 Basic auth with safe test credentials
- Add regression test ensuring PKCE still uses URL-safe encoding

All test credentials are randomly generated safe values that produce the
required Base64 patterns (+ and / characters) without exposing real secrets.

Tests verify:
- Standard Base64 encoding for OAuth2 Basic auth (fixes "invalid_client" errors)
- URL-safe Base64 encoding still works for PKCE/JWT (no regression)
- Proper character substitutions: + vs -, / vs _, padding handling

This prevents regression of the OAuth2 client credentials authentication
bug where kulala incorrectly used URL-safe Base64 instead of standard
Base64 for Authorization: Basic headers per RFC 7617.

Co-Authored-By: Claude (claude-sonnet-4) <noreply@anthropic.com>
@YaroSpace
Copy link
Collaborator

Oh, good catch! Thank you for the PR.

The existing test expected URL-safe Base64 encoding (Y2xpZW50X2lkOmNsaWVudF9zZWNyZXQ)
but the fix correctly changed OAuth2 Basic auth to use standard Base64 encoding
(Y2xpZW50X2lkOmNsaWVudF9zZWNyZXQ=) per RFC 7617.

For the test credentials "client_id:client_secret", the only difference is
padding (= character) since this string doesn't produce + or / characters.

This fixes the CI test failure caused by the Base64 encoding fix.

Co-Authored-By: Claude (claude-sonnet-4) <noreply@anthropic.com>
@Kahitar Kahitar force-pushed the fix/base64-standard-auth-encoding branch from b73ddc0 to a365437 Compare February 3, 2026 07:21
… env

The test failures were caused by Client Secret values being overridden by the
private environment configuration. The update_env() function requires a second
parameter `true` to update the private environment where "Client Secret" is defined.

Changes:
- Update "Client Secret" in private environment for + character test
- Update "Client Secret" in private environment for / character test
- Keep "Client ID" and other settings in public environment

This ensures the test credentials (test:> and user123:?pass) are used instead
of the default client_secret, allowing proper testing of Base64 character handling.

Co-Authored-By: Claude (claude-sonnet-4) <noreply@anthropic.com>
@Kahitar Kahitar force-pushed the fix/base64-standard-auth-encoding branch from a365437 to 29d9ab5 Compare February 3, 2026 07:23
@Kahitar Kahitar force-pushed the fix/base64-standard-auth-encoding branch from b77f3b0 to 062f1d4 Compare February 3, 2026 08:20
@Kahitar
Copy link
Author

Kahitar commented Feb 3, 2026

Sure, I'm very happy to contribute :)
Sorry about the constantly failing tests... I couldn't get them to run locally so far. So fixing them is kind of annoying.

@YaroSpace
Copy link
Collaborator

No problem, that's what CI is for. You can also download our test docker image and run it locally if you want.

@Kahitar
Copy link
Author

Kahitar commented Feb 3, 2026

Yeah I got it to work now. But now the tests are already green.

@gorillamoe
Copy link
Member

Yeah I got it to work now. But now the tests are already green.

In CI they also pass. Thanks 🙏🏾👍🏾

@gorillamoe gorillamoe merged commit 51be777 into mistweaverco:develop Feb 3, 2026
3 checks passed
@gorillamoe gorillamoe assigned gorillamoe and Kahitar and unassigned gorillamoe Feb 3, 2026
@gorillamoe gorillamoe added the bug Something isn't working label Feb 3, 2026
@YaroSpace YaroSpace mentioned this pull request Feb 3, 2026
YaroSpace added a commit that referenced this pull request Feb 8, 2026
* release 5.3.4
* feat(ui): add `max_request_size` opt
* Fix OAuth2 Basic Authentication Base64 Encoding Issue (#825)
* fix: use standard Base64 encoding for OAuth2 Basic authentication
* fix(lsp): do not execute lsp.folding if parser is not loaded
---------

Co-authored-by: 🚀 Niklas Arens <niklas.arens@mercedes-benz.com>
Co-authored-by: Marco Kellershoff <1384938+gorillamoe@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants