tcl_oauth2_library

Pure-Tcl OAuth 2.0 (Authorization Code, with PKCE) client library, with Basecamp and QuickBooks Online examples.

tcl_oauth2_library on GitHub →

What it is

tcl_oauth2_library is a self-contained OAuth 2.0 client written in pure Tcl. It implements the Authorization Code flow: it opens the user's browser, catches the redirect on a one-shot local web server, exchanges the code for tokens, persists them to a 0600 JSON file, refreshes expired access tokens, and provides a one-liner for authenticated API calls.

Dependencies: http (bundled with the core Tcl distribution) and tls (the standard Tcl TLS extension). JSON parsing and encoding are handled by a decoder included in the file, and base64 by core Tcl's binary encode base64, so nothing from Tcllib is required. tls is the one unavoidable extension: HTTPS cannot be done in pure Tcl, as there is no pure-Tcl TLS handshake.

It is licensed under the Tcl/Tk license (BSD-style), the same license used by Tcl/Tk and Tcllib, and is structured to drop into Tcllib as the module modules/oauth2/.

Features

Supported providers & examples

The library ships three self-standing examples in examples/. Each is a single file that depends only on the oauth2 library, configures one provider inline, runs the login, and makes one API call. Each runs two ways — plain Tcl, or behind a Tk UI with -gui 1 — and takes its credentials from the command line or the environment, not from the repo.

A fourth directory, examples/testing/, has five runnable programs that each demonstrate a way to test an OAuth2 configuration — OIDC discovery, Client Credentials, Introspection, live token validation, and JWT decoding. They run as-is against a public IdentityServer demo (no registration needed), then point at another provider by editing a few lines at the top.

Using it

Load the library through the package system or by sourcing the file directly:

lappend auto_path /path/to/tcl-oauth2
package require oauth2

Create a client, log in once, and make a call. Credentials shown here are placeholders; supply real ones from environment variables:

set client [oauth2::new \
    -name          myapp \
    -auth_url      https://provider.example/authorize \
    -token_url     https://provider.example/token \
    -client_id     YOUR_CLIENT_ID \
    -client_secret YOUR_CLIENT_SECRET \
    -redirect_uri  http://localhost:9876/callback \
    -scope         "read write" \
    -auth_extra            {response_type code} \
    -token_exchange_extra  {grant_type authorization_code} \
    -token_refresh_extra   {grant_type refresh_token} \
    -token_file    ~/.config/myapp/tokens.json]

oauth2::login $client   ;# first run: opens browser, saves tokens

set json [oauth2::request $client GET https://api.example/v1/things]

After the first login, tokens live in -token_file and are refreshed automatically — subsequent runs skip straight to oauth2::request.

Core API surface:

Security. Client secrets are read from the environment, never hard-coded. Tokens are written with mode 0600 and excluded from version control. The state parameter is generated per-login and verified on the redirect as a CSRF guard.

Status

Repository

Source, examples, manual, and tests: https://github.com/johnbuckman/tcl_oauth2_library