PermDock

Roadmap

PermDock's phases from the Phase 0 specification to v1.0, the versioning policy, non-goals and the open design questions.

PermDock is specified before it is implemented. This page lists what each phase delivers, how versions are numbered while the API settles, what the project deliberately does not do, and the questions the plan leaves open. Adapter and standards pages carry a Status and Phase line that points back here.

Phases

Phase 0: specification (now)

README.md, PRODUCT.md, AGENTS.md (with CLAUDE.md as a symlink), the MIT LICENSE, the full docs tree under apps/docs/content/docs/, and the Fumadocs app that serves that tree as the first Vercel Service at /docs. packages/permdock, example apps and tests do not yet. See 0017: Docs first, in MDX.

Phase 1: v0.1 "core + agents"

  • Definitions: definePermissions, resource, typed references, nested groups, mergePermissions, listPermissions, findPermission.
  • Policy: definePolicy, role, allow, deny, subject; role fragments merged by name; approval: 'human' grants; allow / deny over arrays of references.
  • Tenancy (0024, tenancy): principal.memberships and principal.tenant; scoped roles (role(name, grants, { on: 'tenant' | 'team' | resource, assignable })), definePolicy({ scopes }), resource({ parent }) derivation; tenant-defined CustomRoles through RoleSource (memoryRoleSource) and MembershipSource; the memberOf condition node in the evaluator and snapshot; reasons tenant-mismatch, no-membership, scope, expired-membership; instance methods tenant, team, memberships, tenants, roles, assignable.
  • Portable conditions with the in-memory evaluator; closures as branded non-portable grants.
  • Two-principal subject (principal, actor, delegation); every subjectFrom* typed as a SubjectResolver with a schema option for custom claims (extension interfaces).
  • createPermDock with can, decide (three outcomes), assert, filter, simulate (including { roles, memberships, tenant } previews), snapshot (v2: memberships, tenant, tenants, simulated), on; describe(decision).
  • Standard Schema validation in boundary mode.
  • AuthZEN-shaped decision endpoint and batched client.
  • @permdock/testing.
  • permdock/react (usePermission, usePermissions, useFilter, useTenant, useMemberships, useRoles, useAssignableRoles, useApproval, useSubject, <Protected>; UI); permdock/next (Cache Components, explicit factory); the Fetch server kernel and permdock/hono; permdock/ai-sdk, permdock/claude-agent, permdock/eve and permdock/openai.
  • permdock/approvals (ApprovalStore, memoryApprovalStore, approvalsHandler, the PermDock-Approval resume header) and the DecisionSink interface with memorySink. See 0022.
  • permdock/jwt (subjectFromJwt, JWKS, RFC 8725 checks, profile: 'fapi2', jose optional peer; RFC 9068 roles / groups / entitlements mapped to roles and memberships, JWT authorization claims); the subjectFrom* provider pattern. See authentication.
  • @permdock/testing conformance runners for every extension interface (testSubjectResolver, testMembershipSource, testRoleSource, testApprovalStore, testDecisionSink, testSnapshotSource, testWhereCompiler); tenancy cases in the policy matrix.
  • Agent Skills (wire-permdock, audit-permissions), AGENTS.md, llms.txt; permdock skills.
  • Examples: next, react-vite, hono, ai-sdk-agent, claude-agent, eve-agent, openai-agent.
  • tests/types matrix for TypeScript 5.9, 6 and 7.
  • tests/bundle runtime conformance: core, permdock/server and every client entry load in a bare WinterTC Minimum Common API global (no Node built-ins), alongside the per-entry gzip measurements (installation, runtimes).

Phase 2: v0.2–0.5 "surfaces"

  • permdock/mcp (scopeChallenge, Enterprise-Managed Authorization, elicitation for approvals).
  • permdock/authzen full endpoint set and a certification run.
  • permdock/openapi targeting 3.2 (document and Overlay output, x-permdock-* extensions; the experimental --overlay 1.2 emitting the pinned Overlay 1.2 reusable-actions draft) with the experimental --target 3.3 emitting the pinned OpenAPI 3.3 Security Profile draft (type: profile scheme, securityProfileRequirements, x-permdock-securityProfile as twin, pin in x-permdock-catalog.drafts; 0025); register the permdock namespace in the OpenAPI registries. Composed with the toolchain, not wrapping it: the Overlay is the Next.js recipe through next-openapi-gen, Hey API / Orval / Scalar read standard security, a Spectral / Redocly / vacuum ruleset file ships alongside (0023, OpenAPI ecosystem).
  • permdock/react-native (Expo Router).
  • express, fastify, elysia, nest, node; trpc, orpc; vue, svelte, solid.
  • permdock/terminal for consumers' own CLIs (device flow login, filterCommands, --json Problem Details, agent-run mode).
  • permdock/webmcp, permdock/a2a, permdock/otel.
  • CLI: collect (with the createPermDockPlugin Next build hook and createPermDockUnplugin, an unplugin-based hook for Vite, Rollup, webpack, Rspack and esbuild so TanStack Start, React Router, SvelteKit, Nuxt, Astro and Solid projects get build-time collect before their adapters land; collect only, never runtime wiring), catalog, usage, doctor.
  • permdock/cloud: the optional client (ApprovalStore, DecisionSink, SnapshotSource over HTTP). PermDock Cloud alpha in the separate PermDock-Cloud repository (hosted AuthZEN ADS, approval inbox, decision log) and the Vercel Marketplace listing with eve-agent as its template. See 0021.
  • One example per adapter plus monorepo and terminal; tests/e2e with Playwright including instant().

Phase 3: v0.6–0.9 "data"

  • permdock.where compilers for Drizzle, Prisma and Kysely, including the memberOf node (active-tenant equality, inArray over held tenants, membership-table joins, declared-parent derivation).
  • permdock rls generate | import | verify; import emits permissions.generated.ts; memberOf compiles through the dialect's memberships table mapping, verify fixtures carry memberships and tenant.
  • supabase provider (subjectFromSupabase with tenant and memberships claims, custom access token hook emitted by rls generate --rbac-scaffold, authorize() scaffold with an optional tenant parameter).
  • Async context for relations; schema-aware field-level grants.
  • permdock/ssf CAEP receiver.
  • tests/integration parity suite on Postgres via testcontainers.
  • Examples: supabase-rls, drizzle, prisma.

Phase 4: v1.0 "ecosystem"

  • Providers: better-auth (organization and team memberships, betterAuthRoleSource over dynamic roles), clerk (active organization as tenant, memberships: 'all', custom roles and role sets as a RoleSource), convex, pdp (AuthZEN client).
  • Quota grants with a pluggable LimitStore.
  • Web Bot Auth verification in HTTP adapters; delegation-chain verification in permdock/jwt.
  • permdock simulate over Arazzo workflows; permdock arazzo check.
  • Tracked, not built: GNAP access as a delegation input; a GNAP OpenAPI scheme has its name reserved (scheme.type: 'gnap') and no output. Every unfinished specification PermDock follows carries a build / name / track posture on the standards watch list (0025).
  • Nuxt, Astro, React Router, TanStack Start; Effect.
  • Candidates evaluated at Phase 3 planning, not scheduled: MongoDB and local-first sync engines (Zero, ElectricSQL, PowerSync, InstantDB) as where targets (local-first sync); LangGraph.js as an agent adapter (agent frameworks); Vercel Chat SDK requestApproval as the reference approval-delivery recipe for self-hosters and the surface the Cloud inbox uses for Slack and Teams (a recipe and an example, not an entry; approvals adapter). Considered and not scheduled: a Cedar compile target for AgentCore Policy and Amazon Verified Permissions, a first-party GitHub Action, and a Cloud SCIM receiver for directory group-to-role assignment (commercial landscape).
  • Docs MCP server; devtools panel.

Versioning policy

  • Releases follow semver. During 0.x, minor versions may change the public API; patch versions never do.
  • Any change to a public identifier, wire format (permission leaf, condition JSON, snapshot, catalog, AuthZEN mapping) or default behaviour goes through an RFC-lite: a short pull request against the relevant docs page and decision record, open for comment before code lands. New decision records are numbered in order.
  • Adapters version with core; there is no independent adapter versioning (0002).
  • 1.0.0 is cut when Phase 4 lands. From then on, breaking changes require a major version and a migration note per adapter page.
  • @permdock/cli and @permdock/testing follow the same major version as permdock and declare the compatible permdock range as a peer dependency.
  • Deprecations are announced one minor version before removal during 0.x, one major version after 1.0.

Non-goals

  • Requiring a network call to decide. PermDock is a PDP you embed; PermDock Cloud is optional, and every hosted capability (approvals, decision log, snapshot distribution) has an in-process default behind the same interface (0021).
  • A policy DSL; policies are TypeScript data.
  • Replacing authentication or issuing tokens.
  • Zanzibar-scale relation graphs; bridge to OpenFGA or SpiceDB through a provider. Resource roles follow declared, finite parent chains only; self-referential hierarchies (folders in folders) are the bridge's job (tenancy).
  • Tenant, team, invitation, membership or custom-role storage and management APIs. PermDock reads memberships and custom roles through MembershipSource and RoleSource; the auth provider or the application owns the tables and the invitation flow (0024).
  • UI components beyond <Protected>: no tenant-switcher dropdown, role badge or approval dialog. Hooks return data; the design system renders it (UI).
  • CommonJS output or Node versions older than the ESM-only baseline.
  • Copying permix, CASL or Kilpi APIs (0001).
  • Wrapping tools that already read PermDock's output. Spec producers, SDK generators, docs UIs, auth providers with JWKS, agent frameworks without a hook of their own, audit sinks and flag SDKs are reached through wire formats and recipes (0023).
  • Angular. No permdock/angular is planned in any phase. Angular apps consume the snapshot through the AuthZEN decision endpoint and the plain JSON snapshot format (wire formats); a community adapter can follow the Vue shape. Revisited only on demonstrated demand.

Open questions

These are the questions the plan leaves open. Each is resolved in the phase where the affected code is written, by updating the linked page and, where a decision changes, adding a decision record.

  1. decide vs an explain alias. Whether to export explain as a documented alias of decide for discoverability by agents. Phase 1. See 0007.
  2. Protected vs a second inline component. Whether permdock/react also ships a Can-style render-prop component alongside Protected, or Protected grows a render-prop form. Phase 1. See React adapter.
  3. subject.* reference ergonomics vs closures. Whether subject.id style references in portable conditions are ergonomic enough that closures stay rare, or a typed builder is needed. Phase 1. See Conditions.
  4. Snapshot contents for large policies. Whether snapshot() ships full grants with conditions or per-permission booleans (with conditions only where needed) when policies are large; scoped snapshots are the current answer. Phase 1. See Snapshots.
  5. Protected-query helper. Whether to add permdock.protect(queryFn, { before, after }) for co-located authorization and redaction around a data fetch, Kilpi-style. Phase 2 or later. See Kilpi v1.
  6. collect output. Whether permdock collect emits the mergePermissions barrel or only the catalog. Phase 2. See collect.
  7. Field-level API shape. How schema-aware field-level grants are declared (fields on a grant, a separate permission per field, or * / ** patterns as in CASL). Phase 3. See Policies.
  8. Decision-endpoint authentication. Resolved: the in-app endpoint sits behind the application's session or bearer authentication via the subject option; the hosted ADS accepts Vercel OIDC tokens or OAuth client credentials verified with permdock/jwt; there is no shared-secret mode (0021, Cloud adapter).
  9. LimitStore and quotas. The LimitStore interface for limit grants, and whether quotas belong in core or in an adapter. Phase 4. See Policies.
  10. approval-required over plain HTTP. Resolved: the client retries the same request with a PermDock-Approval: <token> header; the kernel requires an approved record in the ApprovalStore and re-runs decide (0022, Approvals).
  11. Terminal token storage. Which OS keychain binding permdock/terminal uses as its optional peer, and whether the mode-0600 file fallback is acceptable in CI images. Phase 2. See Terminal.
  12. parent typing on resource. Whether parent.resource is a string name or a reference, and whether a resource may declare more than one parent. Phase 1. See Permissions, Tenancy.
  13. Separation of duty (exclusiveWith). Whether INCITS 359 dynamic separation of duty ships as a permdock doctor lint over memberships, an evaluation rule, or not at all. Phase 1 decides the lint; the rule is not planned. See Tenancy.
  14. Snapshot scope across tenants. Whether snapshot({ tenants: 'all' }) stays an opt-in for small membership lists or becomes the default when the subject holds fewer than a threshold of tenants. Phase 1. See Snapshots.
  15. useApproval transport. Poll the approvalsHandler route (default) or subscribe through a configured SnapshotSource. Phase 1 ships polling. See UI.

Resolved since Phase 0 started: multi-tenant roles, teams, resource roles and tenant-defined custom roles are memberships on the principal plus scoped role declarations, with RoleSource and MembershipSource as the only new inputs (0024); provider principal types extend through generics and Standard Schema, never module augmentation (extension interfaces); the multi-organization snapshot question on the Clerk page, the global-versus-organization roles question on the Better Auth page, the multiple-roles question on the Supabase page and the memberOf node question on the RLS page are closed by the same decision.

Resolved earlier: delegation-chain verification never happens in core; permdock/jwt and the provider adapters verify tokens and chains and hand core a subject (0018). The hosted-service non-goal was reworded and the embedded-PDP / hosted-ADS split recorded (0021); approvals storage, expiry, HTTP resume and plan approvals were fixed (0022).

Questions raised on individual pages (for example the create arity in 0004, grants emission in rls) are tracked on those pages and promoted here when they affect more than one adapter.

On this page