aps-agent/docs/architecture/auth-tenancy.md

129 lines
5.9 KiB
Markdown
Raw Permalink Normal View History

# Authentication, tenancy, and project collaboration
## Security boundaries
- Every `/api/*` route is authenticated except health and the authentication handshake.
- `tenant_uuid` and `user_id` are taken only from the verified server-side identity context.
- Personal sessions are authorized by `(tenant_uuid, owner_user_id)`.
- Project sessions, files, and scheduling state are authorized through `aps_project_members`.
- Tenant-scoped world, checkpoint, knowledge, embedding, preference, and report files use namespaced paths.
- Cross-boundary resource lookups return `404` where practical so callers cannot enumerate resources.
- Web credentials and desktop-license credentials use separate HttpOnly cookies and cannot substitute for each other.
## Authentication providers
2026-07-29 23:22:40 +08:00
`APS_AUTH_PROVIDER=jms` enables the real JMS account/password flow. The server calls
login precheck, captcha, login, profile, tenant, and logout endpoints at
`JMS_AUTH_BASE_URL`. The browser submits a hand-typed enterprise **name** (no public
tenant list — that API was removed to avoid leaking tenant directory). The server maps
known aliases (e.g. `平台` → `platform`), forwards name/code to JMS login, then revalidates
the authenticated tenant from JMS before binding identity. Optional
`JMS_AUTH_TENANT_CODE` / `JMS_AUTH_TENANT_NAME` can lock the deployment to one tenant.
`unconfigured` keeps every business API closed.
2026-07-29 23:22:40 +08:00
The JMS authentication adapter implements these operations:
```text
2026-07-29 23:22:40 +08:00
login precheck / captcha
login (tenant name typed by user; no public tenant discovery)
2026-07-29 23:22:40 +08:00
authenticate via profile + tenant revalidation
local session refresh
remote logout
```
2026-07-29 23:22:40 +08:00
User-directory search remains closed with `AUTH_USER_DIRECTORY_NOT_CONFIGURED` until the
user-management scope is integrated. The current JMS OpenAPI has no self-registration or
unauthenticated self-service password-recovery endpoint. Account creation and password
reset remain enterprise-admin workflows.
The normalized identity is:
```text
user_id, username, fullname, tenant_uuid, roles, expires_at
```
The external adapter must reject deleted or disabled users and tenants. Client-supplied
tenant or user identifiers are never used as authorization input.
## Desktop license provider
Electron clients do not show account or phone login. A stable installation UUID is stored
in `~/.aps/device-id`; an authorization code is activated through
`POST /api/auth/license/activate` and bound to that installation. The server records only
hashes of the code and device identifier.
`APS_LICENSE_PROVIDER=unconfigured` is the production-safe default.
`APS_LICENSE_PROVIDER=mock` is development-only and includes hour, day, week, month, year,
and permanent demo grants. Demo code strings are reusable across developer installations,
but every resulting activation remains device-bound. License duration is determined by the validated code, never by
a client-side selection. Every desktop business request revalidates the activation row,
device binding, status, revocation state, and expiry.
The temporary desktop identity derives a stable `user_id` from the installation UUID so
personal projects and sessions retain `(tenant_uuid, owner_user_id)` isolation. The real
license service adapter must return the authoritative tenant and licensed seat identity.
The external license integration must implement:
```text
activate / validate_code
authenticate / validate_activation
refresh
logout
revocation and expiry lookup
```
## Project roles
| Action | owner | editor | viewer |
| --- | --- | --- | --- |
| Read project, chat, files, schedule | yes | yes | yes |
| Edit data and run scheduling | yes | yes | no |
| Add project sessions and files | yes | yes | no |
| Manage members and delete project | yes | no | no |
A project starts with one owner membership. Sharing adds a membership in the same
tenant; it never copies project data. Personal sessions remain private even when the
same user also belongs to shared projects.
## Storage model
- `aps_workspace_projects`: project owner and collaborative data version.
- `aps_project_members`: tenant-local project ACL.
- `aps_user_workspaces`: per-user active project and session.
- `aps_chat_sessions` and `aps_chat_messages`: personal/project scoped conversations.
- `aps_project_files`: project asset metadata.
- `aps_schedule_runs` and `aps_schedule_results`: scheduling execution/version records.
- `aps_audit_events`: actor, tenant, project, action, and resource audit trail.
- `aps_license_activations`: hashed authorization-code binding, device owner, duration, expiry, and revocation state.
Existing master-data tables include `tenant_uuid`; platform routing templates use the
explicit `platform` tenant and are read-only to normal tenants.
## Database rollout
New databases use Alembic revisions `20260727_01` and `20260728_02`. Existing SQLite development databases
receive compatibility columns at startup. Production MySQL upgrades must be tested on a
copy, and existing rows must be mapped to an explicit tenant and owner before constraints
are made authoritative.
Recommended cutover:
1. Back up the database and JSON storage.
2. Map every historical project to a tenant and owner.
3. Run `alembic upgrade head` for a new APS schema, or apply a reviewed delta migration.
4. Import project, session, message, file, and world data.
5. Verify row counts, tenant assignments, and project memberships.
6. Enable the external auth provider and run the isolation test suite.
7. Keep old JSON data read-only during the rollback window.
## External API mapping checklist
- Login request and response fields.
- Token verification or introspection endpoint.
- Cookie/Bearer transport, expiry, refresh, and revocation behavior.
- User and tenant state fields and deletion semantics.
- Tenant-local user search endpoint.
- Role/permission claims and MFA or forced-password-change responses.
- License-code validation response, duration units, tenant/seat mapping, device limits, revocation, and offline grace policy.