Unifies first-run setup into a single idempotent command that registers
identity, completes claim, and imports API keys from env. Persists
--base-url in client config for remote daemon connections.
Closes#434
Co-authored-by: Cursor <cursoragent@cursor.com>
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
auth/ should own only flow implementations and models — no storage,
no audit. AuthService is a coordinator (flows + vault + audit), not a
flow; it belongs in server/credential_service.py.
Target graph: identity/, auth/, vault/, audit/ are all leaves with zero
intra-codebase imports. server/ is the single composition root.
TODOS phase E updated: move AuthService → server/credential_service.py,
update all import sites, delete auth/service.py, remove global
AuthService(identity="server") singleton from app.py.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Entire-Checkpoint: ff7325231d64
- Replace ambiguous "Imported by" phrasing with an explicit ASCII
dependency graph at the top of the module section
- identity/, vault/, audit/ are leaf modules — import nothing
- auth/ imports only vault/ and audit/
- server/ is the only module that imports all four
- cli/ and proxy/ communicate with server/ over HTTP, not Python imports
- Flag auth/ -> identity/ as a known violation (TODOS phase A+C)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Entire-Checkpoint: 413bcd28e31a
CONTEXT.md:
- Defines the single responsibility of each module (identity, auth,
vault, audit, server, proxy, cli) with explicit owns/does-not-own
and import-direction rules
- Updates terminology from PrincipalHandle/VaultHandle to the current
PrincipalId/VaultId naming established in UBIQUITOUS_LANGUAGE.md
- Replaces Claim/IdentityRegistration with IdentityClaimRecord
- Flags identity="server" as a known violation to be removed
TODOS.md:
- Phase A: move server-owned registry implementations from identity/
to server/registries.py (keep domain models in identity/)
- Phase B: break identity/ -> cli/ import in local.py
- Phase C: remove auth/service.py reach into server registries and paths
- Phase D: move proxy_routes() out of AuthService to server/
- Phase E: remove global AuthService(identity="server") singleton
- Phase F: remove vault.home filesystem property from Vault
- Phase G: optional audit injectable logger
- Phase H: terminology alignment across codebase
- Phase I: docs update pass
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Entire-Checkpoint: d5c6558896f0
Extends ADR 0003 with the full vault design: Principal owns one or more
named Vaults (VaultHandle), storage keys move to
vault:<principal>:<vault_handle>:..., AuthService gains a vault_handle
argument, and the domain model is split across three registries
(principals.json, identities.json, vaults.json). One vault per principal
for now; structure supports multiple without a future breaking change.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Entire-Checkpoint: fd3f66ffdce4
Adds the Principal-owned vault design to the domain language:
- CONTEXT.md (new): canonical glossary for Principal, PrincipalHandle,
PrincipalRegistry, Claim, ClaimStatus, and the on-behalf-of model
- docs/adr/0003-principal-owned-vault.md: records the trade-off between
identity-scoped and principal-scoped vault namespaces, and why
profile/email were rejected as vault keys
- docs/UBIQUITOUS_LANGUAGE.md: adds Principal/Claim terms, retires Profile
(breaking change in v0.4), updates Relationships and example dialogue
Vault keys move from identity:<handle>:... to principal:<handle>:...
AuthService constructor gains `principal` param alongside `identity`.
All accepted agents under a Principal share its connections.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Entire-Checkpoint: ccd880046890