0xPlaygrounds / 0xPlaygrounds/rig

feat(auth): support application-provided OAuth token storage

Open
#2,481 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
Rust
Stars
8.6k
Forks
959
Avg merge
4h 32m
Merged PRs (30d)
117

Description

- [x] I have looked for existing issues (including closed) about this

## Feature Request

Allow applications to supply the token storage used by the built-in ChatGPT and Copilot OAuth clients, while keeping Rig responsible for login, token refresh, and authenticated requests.

In Rig 0.42, these clients expose token-file paths through their builders. The shared [cache helpers on main](https://github.com/0xPlaygrounds/rig/blob/main/crates/rig-core/src/providers/internal/device_auth.rs) also read and write JSON files directly. I could not find a public interface for replacing that persistence with application-owned storage.

### Motivation

I maintain [Toad](https://github.com/1Broseidon/toad), a Rust/Tauri application using Rig for its native agents. We want provider credentials and MCP credentials to use the same OS-backed vault: macOS Keychain, Windows Credential Manager, and Linux Secret Service.

Ordinary API keys can already be loaded by the application and passed to Rig in memory. Built-in OAuth is different: Rig also persists tokens during login and refresh, so choosing a different file path does not let the application enforce its storage policy.

Other desktop applications, services with managed secret storage, and tests using an in-memory store could use the same extension point.

### Proposal

Add a caller-supplied OAuth token-store interface for ChatGPT and Copilot. The exact API shape is open for discussion; the intended behavior is:

- Route token reads, writes, and invalidation through the selected store, including Copilot's bootstrap credentials and derived token cache.
- Keep the existing file-backed behavior as the default.
- Keep login and refresh logic in Rig. An application selects persistence without implementing OAuth or replacing the inference client.
- Distinguish a missing record from an unavailable or failed store. A configured custom store must not silently fall back to writing token files.
- Define how the store participates in refresh coordination so concurrent clients do not overwrite rotated credentials.

The interface should follow Rig's error and WASM conventions. OS-specific implementations and dependencies can stay in the consuming application; this proposal does not require Rig to depend on a keychain library.

Tests could extend the existing ChatGPT/Copilot OAuth coverage with an in-memory/failing store, proving that login and refresh use it, failures propagate, and no default token files are created.

Related work: #2050 provides OAuth regression coverage, #2396 routes auth through the generic HTTP client, and #2088 includes useful discussion of refresh locking and preserving credentials after failed writes. #1905 also touches shared auth code, but its token persistence remains file-based.

I'm happy to contribute a focused PR once we agree on the storage boundary.

### Alternatives

- Restrict permissions on the existing token files. That limits file access but does not integrate with the application's OS credential store.
- Copy tokens between the vault and temporary files around Rig calls. This still creates plaintext copies and complicates refresh, cancellation, and crash recovery.
- Own OAuth outside Rig and inject access tokens. That duplicates login/refresh behavior we would prefer to keep in Rig.
- Add a specific keychain backend directly to Rig. A storage interface would let callers choose their backend without imposing native dependencies on everyone.

Contributor guide

Open the contributing guide

Research direction

The issue mentions token storage in crates/rig-core/src/providers/internal/device_auth.rs and references existing OAuth clients for ChatGPT and Copilot. Start by examining the current file-based token storage implementation there. Review related issues #2050, #2396, #2088, and #1905 for context on auth flow and refresh coordination. The goal is to design a storage interface that applications can implement, ensuring it works with login/refresh logic and does not silently fall back to files.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
authentication, backend
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.