Adds OAuth2/PKCE provider definitions for Gmail, Drive, Calendar, Chat,
Admin SDK, Analytics, Classroom, Docs, Forms, Meet, Photos, Search
Console, Sheets, Slides, and Tasks. Each uses the standard Google
authorization and token endpoints with service-specific API scopes.
The generic google provider is unchanged.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
populate_by_name=True on BaseSettings caused pydantic-settings to look up
the field name 'home' as an env var, picking up the system HOME variable
instead of the default ~/.authsome.
The validation aliases on home, base_url, and active_identity were redundant
with env_prefix="AUTHSOME_", which already maps field names to the correct
AUTHSOME_* env vars. Removing them eliminates the need for populate_by_name
entirely.
ClientConfig.save now excludes inherited settings fields (home, base_url,
version) from the persisted JSON — those are operational settings, not
client-local state.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Build Next.js app and populate src/authsome/ui/web/ so GET / is served
from the static bundle rather than a Python f-string page
- Apply DESIGN.md (Deep Emerald + Obsidian, dark-first) to the Next.js
app: update globals.css tokens, switch fonts to Hanken Grotesk +
JetBrains Mono, add dark class to <html>, replace all hardcoded
bg-white/bg-slate-* with semantic CSS-variable classes
- Redesign Python interstitial pages (claim, device-code, OAuth input,
error) using the same DESIGN.md tokens in web_theme.py
- Remove Python GET / route and dashboard_page() — Next.js AuthGate
handles unauthenticated state; no Python fallback needed
- Remove the GET / special-case from _resolve_ui_auth
- Move DESIGN.md to ui/ (the Next.js root, the correct home)
- Delete test_ui_sessions.py and test_ui_dashboard.py; server-rendered
dashboard UI no longer exists as Python code
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Delete the server-rendered dashboard pages, remove the static asset mount, and route the Next dashboard provider login form through the browser-session auth path.
Split get_protected_auth_service into verify_pop_caller (caller
identification: PoP JWT validation, registration check, ownership
resolution) and get_protected_auth_service (service construction only).
Each layer now has a single responsibility; FastAPI caches
verify_pop_caller per request so the work is not duplicated.
Add OwnershipResolver.resolve_for_principal so both resolution paths
(identity-based CLI and principal-based UI) go through the ownership
resolver rather than inline registry lookups.
Remove four redundant app.state aliases (identity_registry,
vault_registry, identity_claim_registry, principal_vault_binding_registry)
that shadowed app.state.store.* and caused inconsistent access patterns.
All callers now use app.state.store.* directly.
Change get_admin_auth_service to use Depends(get_protected_auth_service)
instead of calling it directly, and fix resolve_ui_request_identity
return type (str | None → None; it never returned non-None).
Closes#354
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Entire-Checkpoint: eda543e8686c
The daemon branched on AUTHSOME_DEPLOYMENT_MODE and ran two parallel
implementations of nearly every ownership concept. "Local and hosted
behave the same" was asserted in prose (ADR 0006) but never enforced in
code, so the paths were free to drift, and the synthetic local principal
let a second local identity silently inherit the admin principal.
Collapse to one flow, identical for every deployment: authsome init
registers an identity and gets back a browser claim URL; the user
registers email+password (first principal becomes admin); that principal
confirms the claim; PoP calls are then authorized.
- Remove AUTHSOME_DEPLOYMENT_MODE, get_deployment_mode(),
LOCAL_PRINCIPAL_EMAIL, the Local*/Hosted* resolver and bootstrap
classes, and the AuthService(deployment_mode=...) parameter.
- OwnershipResolver and IdentityBootstrapService become single concrete
classes (the former hosted, claim-based implementations).
- Admin gating is purely role-based: non-admin principals are blocked in
every deployment (previously implicitly allowed in local mode).
- The server UI always requires a hosted browser session; remove the
vestigial HealthResponse.mode field.
- CLI ensure_identity_ready was already mode-agnostic; it now prints the
claim URL to stderr for headless use.
Add ADR 0007 recording the decision; amend ADR 0006 and CONTEXT.md.
BREAKING CHANGE: existing local installs have an unclaimed identity under
local@authsome.internal and are rejected until the user registers a
principal (email+password) and claims the identity.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Entire-Checkpoint: d31cf246f6f2
Implement ADR 005 by routing audit events through OpenTelemetry with a server-owned SQLite exporter and query endpoint. Implement ADR 006 by persisting principal roles, assigning first principal admin, and enforcing admin-only routes at the FastAPI dependency layer.
Entire-Checkpoint: df60966364f1