Files
browser/openspec/changes/implement-role-scoped-server-access/design.md
T
2026-07-11 14:56:10 +08:00

3.4 KiB

Context

The platform already has session APIs, role-aware frontend navigation, and server lifecycle workflows. Server instances are currently global resources with no owner or administrator membership metadata, so frontend filtering alone cannot satisfy the required visibility and management rules.

Goals / Non-Goals

Goals:

  • Bootstrap the first public registration as an active platform administrator.
  • Persist server ownership and server administrator membership on each server instance.
  • Enforce server visibility and lifecycle authorization in platform APIs.
  • Let server owners invite and remove server administrators for their own servers while hiding platform administrators from owner-facing candidate lists.
  • Keep platform administrators able to view and manage all servers.

Non-Goals:

  • Add billing, cloud host sales, marketplace SaaS workflows, or external identity providers.
  • Add persistent database migrations beyond the current in-memory model.
  • Expose run credentials, raw host paths, AI provider keys, or plugin-side direct server management.

Decisions

Store ACLs on server instances

Server instances will carry OwnerUserID and AdminUserIDs fields. This keeps authorization close to the managed resource and avoids adding a separate repository before the platform has persistent storage.

Alternative considered: add a dedicated membership repository. This was rejected for the current in-memory platform because it increases joins and lifecycle coordination without adding durability.

Authorize at API/service boundaries

Handlers will require a bearer session for user-facing server APIs and call service methods that evaluate the current user before returning data or dispatching lifecycle jobs. Platform administrators bypass the per-server ACL; server owners and server administrators require membership.

Alternative considered: filter only in platform_web. This was rejected because direct API calls would still leak global server data.

Bootstrap first registration by existing user count

Registration will inspect the user repository. If no users exist, the registered user becomes active with platform-admin and receives a session. Later registrations remain pending with server-admin.

Alternative considered: keep only a seeded local admin. This was rejected because production-like setup needs a first-account bootstrap path.

Owner-managed administrator invitations use existing users

Server owner invitations will accept an existing active non-platform-admin user ID and add that user to the server administrator list. Removing an administrator deletes only the server membership, not the user account or platform role.

Alternative considered: invite by email and create accounts inline. This was rejected because the current user lifecycle already separates registration/approval from server membership assignment.

Risks / Trade-offs

  • [Risk] In-memory ACL state is not durable across process restart. -> Mitigation: keep this scoped to the existing in-memory platform and model fields so future persistence can mirror the contract.
  • [Risk] Existing tests that create server instances without auth may fail. -> Mitigation: keep service-level direct create helpers usable while requiring auth in HTTP handlers.
  • [Risk] Platform administrators accidentally appear as removable server admins. -> Mitigation: filter platform-admin users from owner-facing candidate/member responses and reject platform-admin membership mutations.