This commit is contained in:
1 parent
4db3f45164
commit
d25c04cdd2
175 files changed
+56243
-15
No files matched your search
@@ -0,0 +1,34 @@
|
||||
# ADR-001: Human administrator credential panel
|
||||
|
||||
Status: implemented, 14 October 2026.
|
||||
|
||||
The service now exposes a separate `/admin` web page for human administrators to list,
|
||||
create and revoke bearer credentials and read recent credential-management activity.
|
||||
The research library's knowledge remains read-only in the browser.
|
||||
|
||||
The panel reuses the existing human browser session and admin role. Agent identities,
|
||||
including identities holding both agent and admin roles, cannot administer credentials.
|
||||
Browser writes require the session CSRF token and same-origin requests. Credential
|
||||
responses use `Cache-Control: private, no-store`; only creation returns the new secret.
|
||||
The panel holds secrets in memory, never browser storage. Revoke confirmation names the
|
||||
key, and the service rejects revocation of the key backing the caller's current session.
|
||||
|
||||
The strongest alternative was retaining CLI-only provisioning. That avoids a network
|
||||
credential-management surface but does not provide the requested operator workflow.
|
||||
The first administrator still requires local operator provisioning; the panel cannot
|
||||
bootstrap anonymous access. Owner review authentication remains separate.
|
||||
|
||||
An additive `admin_events` SQLite table records time, actor, action and credential ID.
|
||||
The event and its successful credential mutation commit in one transaction. No raw
|
||||
secrets, digests, source bodies or arbitrary application log messages enter this table.
|
||||
The initial log covers panel/API creation and revocation only; CLI actions and historical
|
||||
credentials are not backfilled. Runtime logs and agent run history remain outside this
|
||||
first slice. Credential listing is paged; activity is limited to the latest 50 events.
|
||||
|
||||
Existing credentials and sessions require no migration. Reverting the UI and routes
|
||||
leaves the additive table harmlessly in place. Credentials issued through the panel
|
||||
remain usable by the existing identity store and can be revoked locally.
|
||||
|
||||
Validation: API authorization, CSRF, origin, request bounds, conflicts, secret omission,
|
||||
durable audit, bearer/session revocation, frontend credential creation and confirmation
|
||||
flows. Rendered checks use a disposable data root, separate from operator state.
|
||||
@@ -0,0 +1,59 @@
|
||||
# ADR-002: Password accounts and personal agent keys
|
||||
|
||||
Status: implemented, 14 October 2026.
|
||||
|
||||
Human users sign in with a username/password through `/v1/users/session`. Agent hosts
|
||||
continue to use independent, high-entropy bearer keys. This replaces bearer-key-only
|
||||
human login as the default UI while retaining the existing operator key for initial
|
||||
account setup and recovery. Protected owner review remains a separate password/TOTP,
|
||||
challenge-bound workflow.
|
||||
|
||||
Administrators create and disable accounts with viewer, editor or admin roles and
|
||||
project grants. Editors and administrators issue keys for their own agents at
|
||||
`/v1/me/agent-credentials`; viewers retain read-only access. The server derives the
|
||||
owner from the authenticated account and checks requested grants against current
|
||||
account grants in the same database transaction as issuance. An agent has its own
|
||||
principal identity for proposals/runs. Users can only list and revoke their own keys.
|
||||
Administrators can still inspect and revoke all keys.
|
||||
|
||||
Passwords are hashed with the existing Argon2id implementation. Login uses an
|
||||
HttpOnly, SameSite=Strict session cookie, with Secure on HTTPS. Public password login
|
||||
requires HTTPS; localhost is allowed for development. Browser writes require CSRF
|
||||
and the existing same-origin validation. The development proxy preserves the public
|
||||
Host, allowing TLS-terminating deployments to validate the browser's actual Origin.
|
||||
Forwarded scheme handling remains Uvicorn's trusted-proxy responsibility; application
|
||||
code does not trust arbitrary forwarding headers.
|
||||
|
||||
Five failed logins for a username within 15 minutes block further attempts until
|
||||
that window expires. A shared 100-failure window bounds random-username attempts.
|
||||
Unknown/disabled usernames use a dummy Argon2 verification and generic failure text.
|
||||
This initial limiter favors a small private service; shared lockouts can be abused
|
||||
for denial of service. Larger deployments should add an edge rate limiter.
|
||||
|
||||
Page loads restore existing human browser sessions through `GET /v1/session` with
|
||||
an explicit same-origin client header. The endpoint returns expiry, a CSRF token and
|
||||
account kind; it never returns the session cookie or bearer key. A stable one-way
|
||||
CSRF token is derived from the private session secret and its digest is saved beside
|
||||
the original CSRF digest. This additive migration preserves pre-upgrade sessions and
|
||||
old tabs, while preventing reloads or simultaneous tabs from invalidating each other.
|
||||
Restoration does not extend the original session lifetime. No browser storage is used.
|
||||
|
||||
Changing a password requires the current password, invalidates every browser session
|
||||
for that account, and preserves independent agent keys. Disabling an account revokes
|
||||
its login identity and its agent keys atomically under the canonical authority lock.
|
||||
Activity events include account creation, disable and password changes, without
|
||||
passwords or bearer secrets. Sensitive validation errors omit submitted inputs.
|
||||
|
||||
The strongest alternative is external OIDC/SSO. It avoids local password management
|
||||
but adds an external identity dependency beyond the requested minimal private-service
|
||||
workflow. There is no anonymous registration or email recovery in this slice.
|
||||
|
||||
Migration is additive: `user_accounts`, login failure tracking, and a nullable owner
|
||||
column on credentials. Existing bearer keys and browser sessions continue to work.
|
||||
Account login identities have an unrecoverable random bearer digest; only password
|
||||
sign-in creates their sessions. Rolling back the routes/UI preserves existing keys;
|
||||
new human accounts require the updated identity implementation.
|
||||
|
||||
Validation covers login/CSRF/TLS/body limits, password hashing and changes, session
|
||||
invalidation, user ownership, grant escalation, agent/human separation, disabled users,
|
||||
login throttling, preserved existing credentials, UI setup and personal key issuance.
|
||||
Reference in new issue
Block a user