5.9 KiB
Authentication, tenancy, and project collaboration
Security boundaries
- Every
/api/*route is authenticated except health and the authentication handshake. tenant_uuidanduser_idare 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
404where practical so callers cannot enumerate resources. - Web credentials and desktop-license credentials use separate HttpOnly cookies and cannot substitute for each other.
Authentication providers
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.
The JMS authentication adapter implements these operations:
login precheck / captcha
login (tenant name typed by user; no public tenant discovery)
authenticate via profile + tenant revalidation
local session refresh
remote logout
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:
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:
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_sessionsandaps_chat_messages: personal/project scoped conversations.aps_project_files: project asset metadata.aps_schedule_runsandaps_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:
- Back up the database and JSON storage.
- Map every historical project to a tenant and owner.
- Run
alembic upgrade headfor a new APS schema, or apply a reviewed delta migration. - Import project, session, message, file, and world data.
- Verify row counts, tenant assignments, and project memberships.
- Enable the external auth provider and run the isolation test suite.
- 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.