feat: implement GEWU service and local agent workflows
CI / quality (push) Canceled after 0s

This commit is contained in:
vasily committed 2026-10-14 19:21:35 +08:00
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.