Skip to main content

Access Control Model

Status: DRAFT Owner: Engineering Last Review: 2026-02-21 Applicable Standards: SOC 2 (CC6.1, CC6.2, CC6.3) / GDPR (Art. 25, Art. 32)

1. Purpose

This document describes the access control model that governs who can view, edit, and manage data within the Equa platform. It covers role-based access control (RBAC), the cascading permission model for organization hierarchies, data room access, agent permission controls, unauthenticated guest chat access, and frontend enforcement.

2. Scope

3. RBAC Overview

Source: equa-server/modules/auth/src/authorization.ts, equa-server/modules/common/src/permissions.ts, equa-server/modules/common/src/roles.ts Equa implements role-based access control (RBAC) with the following characteristics:
  • Permissions are granted through roles, not directly to users
  • Roles are assigned to members within the context of an organization
  • A user can hold different roles in different organizations
  • Global roles exist for site-level administration
  • Permissions cascade through organization hierarchies

4. Permission Definitions

Source: equa-server/modules/common/src/permissions.ts

4.1 Built-In Permissions (14)

4.2 Custom Permissions

Organizations can define custom roles with any combination of the built-in permissions via the Roles entity: Source: equa-server/modules/persistence/src/schema.ts (Roles entity)

5. Built-In Roles

Source: equa-server/modules/common/src/roles.ts

6. Cascading Permission Model

Source: equa-server/docs/cascading-permission.puml, equa-server/modules/api/src/site/authorization.ts The Equa platform supports nested organization hierarchies (parent-child relationships). When a user views a parent organization, their effective permissions are calculated by combining direct and indirect permissions.

6.1 Algorithm

  • Direct permissions: The union of all permissions granted by roles assigned to the user in the target organization
  • Indirect permissions: The intersection of permission sets from all child organizations where the user is a member (the user must have the permission in every child org for it to be indirect)
  • Effective permissions: The union of direct and indirect permissions

6.2 Key Function

getUserDirectAndIndirectPermissions() in equa-server/modules/api/src/site/authorization.ts implements this algorithm. Endpoint handlers call requirePermissions() which wraps the endpoint with a permission check before the handler executes.

7. Permission Enforcement

7.1 Backend Enforcement

Source: equa-server/modules/auth/src/authorization.ts Every API endpoint declares its required permissions. The vineyard-lawn framework calls the permission check function before the handler: Failure returns HTTP 403 Forbidden.

7.2 Frontend Enforcement

Source: equa-web/src/shared/hocs/with-permissions.tsx, equa-web/src/app/components/routes/routes.tsx
Frontend enforcement is a UX convenience only. All security-critical checks are enforced server-side. A user bypassing frontend guards will still be blocked by the backend permission checks.

8. Data Room Access Control

Source: equa-server/modules/persistence/src/schema.ts (DataRoomsMembers entity) Data rooms provide document storage with per-member access control, separate from the general permission system.

8.1 DataRoomsMembers Entity

This is a composite primary key — the combination of data room, member, and permission is unique. A member can have multiple permission levels in the same data room.

8.2 Directory-Level Access

Data rooms use a virtual file system (DirectoryItems entity) scoped to organizations: All file operations require the appropriate document permission (viewDocuments, editDocuments, deleteDocuments).

9. Global Roles

Source: equa-server/modules/persistence/src/schema.ts (GlobalRolesUsers entity) For site-level administration, users can be assigned global roles that operate outside the organization context: Global roles grant site-wide privileges (e.g., managing all organizations, accessing admin panel). The isSiteAdmin check in the frontend route guard uses this.

10. Agent Permission Proxy

Source: equa-server/modules/agent/src/security/permission-proxy.ts The AI agent (Equanaut) operates within the same permission model as human users. The permission proxy ensures agents can only execute tools that the owning user has permission for: Each agent tool declares its required permissions. Before execution, the proxy verifies the user has the necessary permissions in the target organization.

10.1 Unauthenticated Chat Access (Guest Mode)

Source: equa-web/src/modules/equanaut/services/api/chat/messages.ts, equa-web/src/modules/equanaut/index.tsx, equa-web/src/modules/equanaut/services/api/config.ts As of spec 042 (Guest Access to Equanaut Sidebar), the Equanaut regular-chat path is accessible to unauthenticated (guest) users. This path operates entirely outside the permission proxy described in Section 10. What guest chat can do:
  • Answer general questions about the Equa platform, features, and navigation
  • Explain equity terminology (vesting, cap tables, option pools, etc.)
  • Provide onboarding guidance for new visitors
What guest chat cannot do:
  • Execute agent tools (blocked at the frontend; useAgentChat is never selected without a user and organization)
  • Access organization data, member lists, documents, or cap tables
  • Perform any write operations on the platform
  • View or modify any authenticated user’s information
Rate limiting: Rate limiting for the unauthenticated chat endpoint is not yet implemented. This was scoped as tasks T004 and T005 in spec 042 and deferred to a future sprint. Until implemented, the endpoint is theoretically vulnerable to abuse (high-volume requests from unauthenticated clients). The practical risk is limited because the endpoint only returns AI-generated text with no data exposure, but cost and availability concerns apply.
This section requires security review sign-off. The unauthenticated endpoint should be re-evaluated when rate limiting (spec 042, T004/T005) is implemented.

11. Access Control Gaps

12. Regulatory References

13. Revision History