OAuth authentication from Jupyter notebooks for IAP-protected GCP services.
- anywidget with "Sign in with Google" button
- Authorization Code flow with PKCE for security and refresh tokens
- Token persistence across sessions
- IAPClient for authenticated HTTP requests with auto-refresh
pip install tokentossOr with uv:
uv add tokentoss- Create a Desktop OAuth client in GCP Console
- Download
client_secrets.json - Add the Desktop client ID to your IAP's programmatic access allowlist
- Grant yourself the "IAP-secured Web App User" role
Use the ConfigureWidget for a password-safe setup (credentials never appear in notebook source):
from tokentoss import ConfigureWidget
display(ConfigureWidget())
# Enter Client ID and Client Secret, click "Configure"Or configure programmatically:
import tokentoss
tokentoss.configure(client_id="YOUR_CLIENT_ID", client_secret="YOUR_SECRET")Credentials are stored to ~/.config/tokentoss/client_secrets.json so they stay out of version control.
from tokentoss import GoogleAuthWidget
# Widget auto-discovers credentials from the standard config location
widget = GoogleAuthWidget()
display(widget)
# Click "Sign in with Google" and complete the flow
# Widget shows "Signed in as user@example.com"from tokentoss import IAPClient
# Create client (auto-discovers credentials)
client = IAPClient(base_url="https://my-iap-service.run.app")
# Make requests - ID token added automatically
data = client.get_json("/api/data")
response = client.post("/api/items", json={"name": "test"})configure()stores OAuth client credentials to a standard platform location- Widget opens a popup for Google OAuth
- User authenticates and grants consent
- AuthManager exchanges auth code for tokens (with PKCE)
- Tokens are stored securely (file permissions 0600)
- IAPClient uses ID token for IAP authentication
- Tokens refresh automatically when expired
# Clone and install
git clone https://github.com/NicholasGrundl/tokentoss.git
cd tokentoss
uv sync --group dev
# Run tests
uv run pytest
# Lint and format
uv run ruff format src/ tests/
uv run ruff check src/ tests/
# Type check (advisory)
uv run ty check src/
# Start Jupyter for testing
uv run jupyter labMIT