Expand description
Service-account OAuth 2.0 client for the Trust Center.
Distinct from the CLI-provider OAuth in auth_session.rs (which scrapes a
spawned CLI’s stdout): this drives the flow itself — opens the system
browser, runs a transient loopback listener (or polls a device endpoint),
exchanges the code, and stores the resulting tokens in the OS keychain.
Security posture follows RFC 8252 (OAuth for Native Apps), RFC 7636 (PKCE, S256), RFC 8628 (Device Grant), and RFC 9700 (Security BCP):
- Authorization Code + PKCE(S256) over a loopback
127.0.0.1:<ephemeral>redirect for code-flow providers (Google, Microsoft). - Device Authorization Grant for GitHub (no client secret needed).
- High-entropy
stategenerated and verified on the callback (CSRF). - Public clients carry no secret; secret-mandatory providers (Slack) use BYO credentials (the user supplies their own client_id/secret).
- Tokens are stored in the OS keychain (never the DB, never logged).
Scaffold status: the per-provider client_ids are not yet provisioned
(client_id: None below). Until a client id is supplied — either baked
into the catalog or passed as BYO — start returns a clear
“not configured” error and no flow runs. Dropping in the ids (and wiring
the frontend Connect button) activates this end to end. See
specs/SPEC_TRUST_CENTER_2026_06_15.md §4.2/§12.1.
Structs§
- ByoCredentials
- BYO OAuth-app credentials, supplied by the user for secret-mandatory providers (Slack) or to override the built-in public client.
- OAuth
Session 🔒 - OAuth
Session Manager - Pkce
Pair - A PKCE verifier/challenge pair.
challenge = BASE64URL(SHA256(verifier)). - ServiceO
Auth Config - Static per-service OAuth configuration.
client_idisNonein the shipped scaffold — supply it (or BYO) to activate the provider.
Enums§
- OAuth
Flow - How a provider’s OAuth flow is driven.
- OAuth
Status - Terminal/transient status surfaced to the frontend poll.
Constants§
- SESSION_
RETENTION 🔒 - How long a session entry is retained before it’s pruned. Generous margin over the 5-min flow timeout so a slow frontend poll still finds its result.
- SESSION_
TIMEOUT 🔒
Functions§
- config_
for - Per-provider catalog. Endpoints + flow choice follow each provider’s
native-app guidance (see SPEC §12.1).
client_idintentionallyNoneuntil provisioned. - enc 🔒
- URL-encode a query component (RFC 3986 unreserved kept).
- exchange 🔒
- http 🔒
- manager
- Process-global manager. A dedicated singleton (rather than an AppState field) keeps this scaffold’s blast radius small; service-OAuth sessions are short-lived and window-agnostic.
- open_
browser 🔒 - parse_
callback 🔒 - Extract
codeandstatefrom a raw HTTP request lineGET /callback?code=...&state=... HTTP/1.1. - percent_
decode 🔒 - persist_
oauth_ 🔒account - Persist the OAuth account: token blob → keychain, pointer + non-secret context → DB. Returns the account id.
- pkce_
pair - Generate a PKCE pair. The verifier is 256 bits of CSPRNG entropy (two v4
UUIDs, as
uuiddraws from the OS RNG) base64url-encoded — well within the 43–128 char range, charset-safe. Challenge uses S256 (neverplain). - random_
state - High-entropy CSRF
statevalue. Verified byte-for-byte on the callback. - resolve_
client - Resolve the effective client id: BYO overrides the built-in. Returns an error string when neither is available (the “not configured” gate) or when a secret-mandatory provider is missing its BYO secret.
- start
- Start an OAuth flow. Resolves config + client (gating on “not configured”),
creates a session, and spawns the background task that drives it. Returns
(session_id, initial_status). The frontend then pollsmanager().poll. - start_
code_ 🔒flow - start_
device_ 🔒flow - supports_
oauth - Whether a provider has an OAuth flow at all (frontend gating).
- token_
blob 🔒 - Tokens returned by an exchange. Stored as a keychain JSON blob — never the DB, never logged.