# Enterprise Permissions -- PRD

## Status

In Progress (Phase 1)

## Executive Summary

The Enterprise Permissions system transforms Coda from an internal-only tool with no access controls into a white-label platform with full enterprise authorization. By building RBAC with hierarchical roles, attribute-based policy conditions, multi-tenant isolation, audit logging, and feature gating into a dedicated platform service, this feature enables external customer deployment, SOC 2 compliance, and plan-based commercial pricing.

## The Problem

Coda is transitioning from internal beta to external product. The current authorization model is a stateless JWT from the Grass identity platform plus email-based admin allowlists. This creates five critical gaps:

1. **No permission granularity.** Every authenticated user has access to every feature. There is no way to restrict a user to read-only access, limit which AI models they can use, or prevent them from running Snowflake queries.

2. **No tenant isolation.** All users operate in a single shared context. An analyst at one record label can potentially access another label's data. There is no concept of organizational boundaries.

3. **No audit trail.** Permission checks are not recorded. When a compliance officer asks "who accessed what and when," there is no answer. This blocks SOC 2 Type II certification.

4. **No feature gating.** Without plan-based access tiers, there is no mechanism for commercial pricing (Starter/Professional/Business/Enterprise). Every user gets every feature regardless of what the customer pays for.

5. **No admin tooling.** Customer IT admins cannot manage their own users, roles, or security policies. Every change requires engineering intervention.

These gaps are blockers for external customer deployment, enterprise sales, and compliance certification.

## The Opportunity

Enterprise permissions unlock three value streams:

**Commercial pricing.** Plan-based feature gating (Starter at $40/seat, Professional at $80/seat, Business at $120/seat, Enterprise custom) with AI credit metering. Each tier unlocks progressively more features, models, and data tools.

**Enterprise sales.** Large organizations require RBAC, audit logging, SSO/SCIM, SoD constraints, and IP allowlists as table stakes. Without these, Coda cannot pass enterprise security reviews.

**Platform scalability.** Multi-tenancy with proper isolation enables serving hundreds of customer organizations from the same infrastructure, each with their own permissions, branding, and compliance configuration.

## Goals & Success Criteria

| Goal                            | Success Criteria                                                                                                              |
| ------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| Enterprise-grade access control | Full RBAC with hierarchical roles, ABAC conditions, deny overrides. NIST RBAC Level 2+ compliant.                             |
| Multi-tenant isolation          | Zero cross-tenant data leakage. Every query scoped by tenant ID. Verified by integration tests.                               |
| Compliance readiness            | Immutable audit log for every permission check (grant and denial). Crypto-shredding for GDPR erasure. SOC 2 and SOX controls. |
| Performance                     | Permission check <5ms p99 cached, <50ms p99 cold. Cache hit ratio >95% steady state.                                          |
| Feature gating                  | 4-tier plan system with plan-based feature keys. AI credit metering with per-operation costs.                                 |
| Operational safety              | Shadow mode rollout. Feature-flagged pipeline steps. Fail-closed on all errors.                                               |
| Zero false grants               | Denial accuracy: 0 false grants (false denials acceptable). Deny-wins invariant enforced.                                     |

## Target Users

### External personas (customer tenants)

| Persona           | Default Role  | Key needs                                                              |
| ----------------- | ------------- | ---------------------------------------------------------------------- |
| **Business User** | `contributor` | Chat with AI, get answers, generate exports. Clear denial feedback.    |
| **Data Analyst**  | `analyst`     | Query tools (Snowflake, GraphQL), sandboxed code, report building.     |
| **Power User**    | `power_user`  | All tools and models without admin responsibility.                     |
| **Executive**     | `executive`   | Dashboards, reports, high-level AI conversations.                      |
| **Tenant Admin**  | `admin`       | Manage users, roles, permissions. View audit logs. Configure security. |
| **Viewer**        | `viewer`      | Read-only access to shared conversations and reports.                  |

### Internal personas (Orchard/Sony staff)

| Persona              | Super Admin Level | Description                                                        |
| -------------------- | ----------------- | ------------------------------------------------------------------ |
| **Engineering**      | `full`            | Full platform control. Tenant lifecycle, impersonation, debugging. |
| **Customer Success** | `support`         | Cross-tenant impersonation (audit-logged). Debug customer issues.  |
| **Product/QA**       | `product`         | Test all features. Impersonate in test tenants only.               |
| **Legal/Compliance** | `read_only`       | Cross-tenant audit log access. Verify SoD. Export compliance data. |
| **Data/Analytics**   | `analytics`       | Cross-tenant aggregate metrics. No individual PII access.          |

## User Stories

**Business User:**

- I can chat with the AI and get answers about my catalog and royalties.
- I can only see and invoke tools my role permits.
- When denied, I see a clear message with the missing permission and how to request elevated access.

**Tenant Admin:**

- I can create custom roles with fine-grained, module-organized permissions.
- I can assign/revoke roles, grant temporary overrides with expiration.
- I can define SoD constraints (mutually exclusive roles).
- I can view audit logs filtered by user, action, date, and outcome.
- I can configure IP allowlists, session timeouts, and step-up policies.

**Super Admin (full):**

- I can create tenants with a plan and seeded defaults.
- I can suspend/reactivate tenants, immediately revoking all sessions.
- I can impersonate a tenant user for debugging, with full audit trail.
- I can manage plans and feature assignments.

**Compliance Officer (read_only):**

- I can query audit logs for any time range across any tenant.
- I can reconstruct a user's effective permissions at any past date via the permission change log.
- I can export audit data in JSON or CSV format.

## Proposed Solution

### Architecture

A dedicated ConnectRPC microservice (`apps/platform`) decomposed into four domains:

| Domain         | Responsibility                                                              |
| -------------- | --------------------------------------------------------------------------- |
| **Access**     | Authorization (16-step pipeline), entitlements, plans, credits, rate limits |
| **Platform**   | Tenants, users, groups, departments, invitations, SCIM, branding            |
| **Compliance** | Audit logs, consent, privacy requests, data classification                  |
| **Growth**     | Promotions, referrals, codes, redemptions                                   |

All four domains run in one process today. Each has its own proto package (`@coda/admin-api`, etc.) so future decomposition into separate services is a routing change, not a rewrite.

### Key capabilities

| Capability      | Approach                                                                                             |
| --------------- | ---------------------------------------------------------------------------------------------------- |
| RBAC            | Hierarchical roles with inheritance. 7 default roles seeded per tenant.                              |
| ABAC            | 6 typed condition evaluators (ownership, department, time window, resource state, IP range, custom). |
| Deny overrides  | Deny-wins at step 8, before super admin. Cannot be bypassed.                                         |
| Feature gating  | Plan -> PlanFeature -> Tenant. Module prefix matching.                                               |
| Credit metering | Per-operation credit costs by plan tier. Atomic deduction with overage policies.                     |
| Audit logging   | Async via Redis buffer. PII encrypted with per-user keys (crypto-shredding).                         |
| Multi-tenancy   | TenantUser membership required. Every query scoped by tenantId.                                      |
| Shadow mode     | Log-only enforcement for gradual rollout validation.                                                 |

### Plan tiers

| Tier         | Target                         | Price           | Credits/seat/month |
| ------------ | ------------------------------ | --------------- | ------------------ |
| Starter      | Indie labels, small publishers | $40/seat/month  | 200                |
| Professional | Mid-size labels, distributors  | $80/seat/month  | 1,000              |
| Business     | Large labels, multi-team orgs  | $120/seat/month | 3,000              |
| Enterprise   | Major label divisions          | Custom          | Custom             |

### Resource sharing model

All shareable resources (dashboards, data sources, chats, reports) use a unified `ResourceShare` model with three access levels (`view`, `edit`, `manage`) and four share targets (`user`, `role`, `group`, `tenant`). Access requires both the role permission AND the share -- they are complementary, not alternatives.

## Non-Goals

- Custom policy expression language (typed evaluators only)
- Permission analytics/recommendations
- Real-time permission change push via WebSocket (cache invalidation is sufficient)
- Federated IdP configuration beyond Grass (Grass handles all authentication)
- Billing integration (credit metering tracks usage; billing is a separate system)

## Costs

### Engineering effort

Implementation is split into 8 plan files across ~10 weeks:

| Phase    | Scope                                                        | Effort             |
| -------- | ------------------------------------------------------------ | ------------------ |
| Phase 1A | Schema, migrations, seed data                                | ~1.5 weeks         |
| Phase 1B | Proto definitions, buf codegen                               | ~1 week            |
| Phase 1C | 16-step pipeline, caching, crypto-shredding                  | ~2 weeks           |
| Phase 1D | Core service handlers (Role, Policy, Session, Tenant, Audit) | ~2 weeks           |
| Phase 1E | Server setup, middleware integration, shadow mode            | ~1.5 weeks         |
| Phase 1F | Migration cutover, tenant bootstrap                          | ~1 week            |
| Phase 1G | Cross-cutting tests (load, chaos, e2e)                       | ~1 week (parallel) |

### Infrastructure

| Component                          | Monthly cost |
| ---------------------------------- | ------------ |
| Fargate (2 vCPU / 4 GB, 2 tasks)   | ~$120        |
| ElastiCache (shared with existing) | Incremental  |
| Aurora (shared with existing)      | Incremental  |
| S3 (audit archive)                 | < $5         |

## Risks & Mitigations

| Risk                                     | Severity | Mitigation                                                                                                |
| ---------------------------------------- | -------- | --------------------------------------------------------------------------------------------------------- |
| Misconfigured permissions lock out users | High     | Shadow mode validates before enforcement. Fail-closed is correct but disruptive if permissions are wrong. |
| Cache staleness causes stale grants      | High     | Synchronous cache invalidation on all writes. 30s TTL for effective permissions.                          |
| Grass JWT claim mapping undefined        | Medium   | `ResolveTenant` encapsulates the mapping. Stub until Grass team confirms the claim field.                 |
| Performance regression on hot path       | Medium   | <5ms target with Redis cache. Benchmark validates before enforcement.                                     |
| Schema migration on shared DB            | Medium   | Additive-only migrations. No column renames or type changes on existing tables.                           |

## Timeline

| Milestone                                | Target   |
| ---------------------------------------- | -------- |
| Phase 1 schema + pipeline complete       | Week 4   |
| Shadow mode deployed to QA               | Week 6   |
| Shadow mode validation complete          | Week 8   |
| Enforcement enabled (first routes)       | Week 9   |
| Full enforcement + first external tenant | Week 10+ |

## Open Questions

- **Grass JWT claim mapping:** Which claim field maps to a Coda tenant? Candidates: `GrassApplication.id`, `GrassProfile.profileType`, or a new dedicated field. Must be resolved before `ResolveTenant` can work in production.
- **Billing integration:** Credit metering tracks usage but does not handle invoicing. The billing system integration is out of scope for Phase 1.
- **Multi-region deployment:** The `dataResidency` field is stored from day one but not enforced at the infrastructure level until China or Russia tenants are needed.
