Search Shortcut cmd + k | ctrl + k
quack_oauth

Extensions providing OAuth and OpenID primitives for authentication and authorization for the DuckDB quack server.

Maintainer(s): jrosskopf

Installing and Loading

INSTALL quack_oauth FROM community;
LOAD quack_oauth;

Added Functions

function_name function_type description comment examples
quack_oauth_acquire scalar One-stop client-side OAuth orchestrator (R-C-2 + R-C-4). Reads the named TYPE=quack_oauth SECRET, decides the right flow from what's available – a fresh cached access_token short-circuits; otherwise tries refresh_token grant, then client_credentials, then RFC 8628 device_code – runs it, persists rotated tokens back onto the SECRET, and returns the access_token. Designed to be threaded into ATTACH: ATTACH 'quack:host:port' AS rs (TYPE quack, token quack_oauth_acquire('cli')). Honours quack_oauth_renew_skew_s (default 60 s) – ATs within the skew window of expiry are treated as stale and re-minted. NULL [SELECT quack_oauth_acquire('my_client'), ATTACH 'quack:rs.example.com:9494' AS rs (TYPE quack, token quack_oauth_acquire('cli'))]
quack_oauth_audit_log table Returns the in-memory audit ring (last N auth decisions) as a typed table. Columns: timestamp_unix_s BIGINT, event_type VARCHAR, subject VARCHAR, issuer VARCHAR, kid VARCHAR, token_hash VARCHAR, action VARCHAR, reason VARCHAR. token_hash is the 8-hex-char SHA-256 prefix of the raw token; the raw token is never exposed. For persistent audit, set audit_table on the server SECRET. NULL [SELECT * FROM quack_oauth_audit_log() ORDER BY timestamp_unix_s DESC LIMIT 20]
quack_oauth_check_authorization scalar Authorize a query for a session whose Principal was previously cached by quack_oauth_check_token(). Parses the SQL with DuckDB's parser, classifies the action (Attach / Scan / Insert / Update / Delete / Ddl / Pragma / CopyTo / CopyFrom / ServeAdmin) and enumerates the referenced objects + columns, then evaluates the policy: either the SQL-native rules in the table named by policy_table on the active quack_oauth_server SECRET (rules can target subject / scope / action / object_pattern / column_pattern), or the default scope-based policy (quack:read → Attach + Scan; quack:write → also Insert/Update/Delete/CopyTo/CopyFrom; admin actions always denied). Returns false for unknown session_id, policy_table load failure, parser failure, or any policy deny. Wired into quack via SET quack_authorization_function = 'quack_oauth_check_authorization'. NULL [SELECT quack_oauth_check_authorization('sess-1', 'SELECT * FROM t'), SELECT quack_oauth_check_authorization('sess-1', 'COPY t TO ''out.csv''')]
quack_oauth_check_token scalar 3-argument form that matches quack's quack_check_token callback signature exactly. Validates the token AND caches the extracted Principal keyed by session_id so a subsequent quack_oauth_check_authorization() call can apply the policy. Wired into quack via SET quack_authentication_function = 'quack_oauth_check_token'. NULL [SELECT quack_oauth_check_token('sess-1', 'bearer', 'eyJhbGciOi…')]
quack_oauth_check_token scalar Validate an OAuth 2.1 / OIDC access token against the active quack_oauth_server SECRET. Returns true if the token verifies (JWKS-mode signature check, RFC 7662 introspection, or Google-style tokeninfo per the SECRET's validation_mode). NULL [SELECT quack_oauth_check_token('eyJhbGciOi…')]
quack_oauth_current_principal table Returns the per-session Principal cache as a typed table (R-S-6): one row per active session_id with subject, issuer, scopes (VARCHAR[]), and exp (BIGINT unix seconds). Populated by the 3-arg form of quack_oauth_check_token. Useful for ops introspection – e.g. SELECT * FROM quack_oauth_current_principal() WHERE exp < epoch(now()) shows stale entries that should be expired. NULL [SELECT * FROM quack_oauth_current_principal()]
quack_oauth_device_login scalar Run an RFC 8628 device authorization flow against the named quack_oauth SECRET. Requests a device + user code, prints the verification URL + user_code to stderr for the operator to visit on a second device, then polls the token endpoint with RFC 8628 §3.5 error handling (pending / slow_down back-off / access_denied / expired_token). On success persists access_token + refresh_token + expires_at back onto the SECRET and returns the ISO-8601 expires_at timestamp. Use for interactive auth on input-constrained devices. NULL [SELECT quack_oauth_device_login('my_client_secret')]
quack_oauth_diagnose table Health and configuration snapshot for the quack_oauth extension. Returns one row per component (extension, jwks_cache, decision_cache, session_principals, recent_decisions) with a status and a free-form detail string of key=value pairs. Use to verify that a freshly-loaded extension is configured and that the caches behave (R-N-13). NULL [SELECT * FROM quack_oauth_diagnose()]
quack_oauth_login scalar Run an RFC 6749 §4.4 client_credentials flow against the token endpoint of the named quack_oauth SECRET. POSTs the SECRET's token_endpoint with grant_type=client_credentials, persists the resulting access_token, refresh_token (if any), and expires_at back onto the SECRET, and returns the ISO-8601 expires_at timestamp. Use for machine-to-machine (service account) flows. NULL [SELECT quack_oauth_login('my_client_secret')]
quack_oauth_logout scalar Clears access_token, refresh_token, and expires_at on the named TYPE=quack_oauth SECRET (R-C-8). Returns true. The RFC 7009 revocation-endpoint call is a SHOULD in the spec and is deferred – this version only does the local field clear. Use after a user explicitly logs out so a stolen refresh_token cannot be reused. NULL [SELECT quack_oauth_logout('my_client_secret')]
quack_oauth_refresh scalar Run an RFC 6749 §6 refresh_token grant against the token endpoint of the named quack_oauth SECRET. Reads token_endpoint + client_id [+ client_secret] + refresh_token from the SECRET, POSTs grant_type=refresh_token, and persists the rotated access_token + refresh_token (if returned) + expires_at back onto the SECRET, and returns the ISO-8601 expires_at timestamp. Supports both public and confidential clients. NULL [SELECT quack_oauth_refresh('my_client_secret')]

Overloaded Functions

This extension does not add any function overloads.

Added Types

This extension does not add any types.

Added Settings

name description input_type scope aliases
quack_oauth_clock_skew_s Allowable clock skew (seconds) when verifying JWT exp/nbf/iat (R-S-3). INTEGER GLOBAL []
quack_oauth_enabled Swap quack's auth callbacks for the OAuth implementation (R-S-1). BOOLEAN GLOBAL []
quack_oauth_introspect_cache_s Cache lifetime (seconds) for introspect-mode decisions, capped at token exp (R-S-5). INTEGER GLOBAL []
quack_oauth_jwks_min_refresh_s Minimum seconds between JWKS refreshes per kid (R-S-4). INTEGER GLOBAL []
quack_oauth_policy_default Default decision when no policy_table rule matches: 'allow' or 'deny' (R-S-7). VARCHAR GLOBAL []
quack_oauth_provider First-class IdP preset: entra|google|keycloak|okta|github|generic (R-S-12). VARCHAR GLOBAL []
quack_oauth_renew_skew_s Client refreshes the access token this many seconds before expires_at (R-C-2). INTEGER GLOBAL []
quack_oauth_server_secret_name Name of the quack_oauth_server SECRET that check_token reads. VARCHAR GLOBAL []
quack_oauth_trust_plaintext Allow LOAD with enabled=true even when no TLS terminator is detected (R-N-4). BOOLEAN GLOBAL []
quack_oauth_validation_mode Token validation strategy: 'jwks' or 'introspect' (R-S-2). VARCHAR GLOBAL []