Skip to content

feat(http): OAuth2 password grant for sl.http - #193

Merged
kvlonge merged 3 commits into
mainfrom
feat/http-password-grant
Nov 12, 2026
Merged

kvlonge merged 3 commits into
mainfrom
feat/http-password-grant

Conversation

@kvlonge

@kvlonge kvlonge commented Nov 12, 2026

Copy link
Copy Markdown
Contributor

sl.http jobs can now use the OAuth2 resource-owner password grant.

  • sl.oauth2_password(token_url, *, scope=None, client_auth="basic") posts grant_type=password with the connection's username and password. It sends client_id and client_secret too when the connection has them, as basic auth or as form fields, the same as the existing OAuth2 kinds.
  • Renewal works like the existing kinds: the token is cached, renewed before it expires, and renewed once after a 401. When the token response includes a refresh_token, later renewals use it. When it doesn't, or the server refuses it, the password grant runs again. A transient failure (5xx/429) while refreshing is retried, and the password is not resent; if it persists, the run exits 75.
  • The password is redacted like the other secrets: raw, percent-encoded, form-encoded and JSON-escaped. A token-endpoint JSON error body is re-serialised before it is shown, so a password the server echoes back with its own escaping is still hidden.
  • Wrong credentials fail with exit 1 and retryable: false in --json.
  • Existing OAuth2 kinds send the same token form as before. A test asserts that only the password grant sends username and password.

Docs: sources/python.mdx (auth table and OAuth2 section) and configuration.mdx, marked as coming in 0.36.0.

Tests: new cases in packages/sqlload/tests/test_http_jobs.py against a stub token server:

  • the first grant;
  • renewal before expiry;
  • a 401 followed by a new token, with the rotated refresh token;
  • falling back to the password when the refresh token is refused;
  • a token endpoint that is down once (with retries, and without retries giving exit 75);
  • a wrong password in --json, with the echoed password redacted.

All 65 http job tests pass, and make check is clean. Mutation checks: removing the fallback, or the JSON re-serialisation, fails the matching test.

sl.oauth2_password(token_url, scope=, client_auth=) posts grant_type=password
with the connection's username and password, plus client_id and
client_secret when the connection has them. Renewal works like the other
OAuth2 kinds: before expiry and once after a 401, using the refresh token
the server handed out when there is one, and the password grant again
when there isn't or the server refuses it. The password is redacted like
the other secrets, and wrong credentials fail with exit 1, not retryable.
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying sqlload with  Cloudflare Pages  Cloudflare Pages

Latest commit: 2718e07
Status: ✅  Deploy successful!
Preview URL: https://da7201c1.sqlload.pages.dev
Branch Preview URL: https://feat-http-password-grant.sqlload.pages.dev

View logs

@kvlonge
kvlonge merged commit f9960a7 into main Nov 12, 2026
17 of 19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant