• ANNOUNCE: oauth2 - a small, pure-Tcl OAuth 2.0 client (Authorization Code + PKCE)

    From decentespresso@gmail.com@user21123@newsgrouper.org.invalid to comp.lang.tcl on Sat Jul 11 13:55:14 2026
    From Newsgroup: comp.lang.tcl


    I've released a small, self-contained OAuth 2.0 client for Tcl. It
    implements the Authorization Code grant (RFC 6749) with optional PKCE
    (RFC 7636), and depends only on the http and tls packages -- no tcllib,
    no C extension, and no Tk.

    https://github.com/johnbuckman/tcl_oauth2_library (Tcl/Tk license)


    What it does
    ------------

    It drives the whole interactive process for you: it opens the user's
    browser at the provider's authorization endpoint, catches the redirect
    on a one-shot local socket, exchanges the code for tokens, saves them to
    a private (mode 0600) JSON file, and refreshes expired access tokens transparently. After that, an authenticated GET is one line:

    package require oauth2

    set c [oauth2::new \
    -auth_url https://provider.example/authorize \
    -token_url https://provider.example/token \
    -client_id $env(CLIENT_ID) \
    -client_secret $env(CLIENT_SECRET) \
    -redirect_uri http://localhost:9876/callback \
    -scope "read write" \
    -pkce S256 \
    -token_file ~/.config/myapp/tokens.json]

    oauth2::login $c ;# first run: opens the browser, saves tokens
    set body [oauth2::get $c https://api.example/v1/things]


    Provider-agnostic
    -----------------

    Each provider's deviations from the spec are expressed as configuration,
    not code, so one code path serves them all. The included, runnable
    examples cover Basecamp (which uses type=web_server instead of response_type=code), QuickBooks Online (HTTP Basic on the token
    endpoint, and returns a realmId), and Twitter/X (requires PKCE) -- each
    in a plain-Tcl and a small-Tk variant.


    Dependencies
    ------------

    Only http (bundled with core Tcl) and tls. JSON is parsed by a small
    decoder in the package, base64 by core Tcl's [binary encode base64], and
    the SHA-256 needed for PKCE by a compact implementation in the package
    itself. It needs no Tk, so it is happy headless on a server or in cron.


    Also included
    -------------

    - transparent refresh, including refresh-token rotation
    - the client-credentials (machine-to-machine) grant
    - token introspection (RFC 7662) and (non-verifying) JWT decode
    - for servers: drive oauth2::authorize_url / oauth2::exchange_code
    yourself instead of the loopback listener


    Background: this came out of a real production need. A native (C++)
    OAuth2 library we had been using would occasionally crash, and -- worse
    -- our tokens kept silently going invalid despite hourly auto-refresh,
    and we could never work out why. The Tcl rewrite has been solid: tokens
    stay alive and refresh cleanly days later. It is in daily production
    use against Intuit/QuickBooks and Basecamp.

    A EuroTcl 2026 talk walks through it in more depth; slides (PDF):

    https://github.com/johnbuckman/tcl_oauth2_library/blob/main/OAuth2-in-Tcl.pdf

    Feedback and patches welcome. And if it proves useful, perhaps it could
    one day find a home in tcllib.

    John Buckman
    --- Synchronet 3.22a-Linux NewsLink 1.2