Skip to content

IAM Roadmap (v0 -> v1)

Date: 2026-02-07

Goal

Define a lightweight path from early role-based access (v0) to a unified IAM service (v1) without breaking API contracts or service boundaries.

Current (v0) Assumptions

  • Roles: admin, connector_builder, viewer/auditor.
  • Services enforce authorization locally via middleware.
  • Workspace scoping applies to all records.

Tenancy Direction

  • Preserve strict tenant isolation as a non-negotiable platform invariant.
  • Assume tenant-isolated data planes by default in v0 deployment architecture.
  • Keep workspace scoping explicit in tokens, APIs, and policy evaluation.
  • Add Tenant Admin capabilities carefully, with audit coverage for cross-workspace operations.

Proposed Direction

Move toward a shared permissions vocabulary and a centralized IAM policy store, while keeping per-request enforcement local and resilient.

Permission Vocabulary (Example)

  • integrations.read
  • connections.read
  • connections.create
  • connections.update
  • connections.delete
  • connections.test
  • discovery.run
  • discovery.read
  • explorer.read
  • export.generate

Notes: - Permission names are stable identifiers, not UI labels. - UI labels can be derived by a registry for display purposes.

v0 -> v1 Path

1) v0: Role-based checks - Keep existing role checks. - Add a permissions map in each service (role -> permissions) for clarity. - Return permissions in user/session context (e.g., JWT claims or /me endpoint).

2) v0.5: Shared taxonomy - Document the canonical permission list in one spec (this file). - Services reference the same permission names in checks and logs. - UI gates actions based on permissions, not role names.

3) v1: Unified IAM service - Responsibilities: - Source of truth for roles, permissions, assignments, and authentication state. - Admin UI and audit trail for changes. - Permission registry for services to register capabilities and labels. - Services still enforce locally using cached policy or token claims. - Avoid hard per-request dependency on IAM service availability.

Minimal Scaffolding Plan (v0)

Goal: stand up a service shell that is safe to evolve without forcing other services to depend on it yet.

Phase 0: Service skeleton - Fastify service with /v1/health. - In-memory stores for permissions, roles, assignments. - Admin-only endpoints for create/register operations. - Workspace- and tenant-scoped requests using existing headers.

Phase 0.5: Optional hardening - Add audit events for registry/role/assignment changes. - Add request validation (schema or zod). - Add basic list/query endpoints for UI prototyping.

Out of scope for scaffold: - Hard dependency from other services. - Token minting or gateway integration. - Durable persistence (DB), migrations, or cross-tenant admin UX.

Registration Model (v1)

  • Services register permissions at startup:
  • service: "discovery"
  • permissions: ["discovery.run", "discovery.read"]
  • labels: {"discovery.run": "Run discovery"}
  • Authz service stores registry for UI/admin use.

Enforcement Model (v1)

  • Preferred: token claims include resolved permissions.
  • Alternative: sidecar or local cache periodically syncs policy.
  • Each service uses the same middleware signature (requirePermission(...)).

Goal: support tenant-defined roles without pushing role changes to every service.

Approach: - Authz stores role and permission definitions per tenant/workspace. - Authn/gateway mints short-lived JWTs that carry role IDs and workspace context. - JWTs include a policy_version claim per tenant/workspace. - Services verify tokens locally and check roles/permissions via cached policy.

Policy propagation: - When roles change, IAM increments policy_version. - Services keep a cached policy_version per tenant/workspace. - If token policy_version is older than cache, reject and force reauth/refresh.

Benefits: - No per-request IAM dependency. - Role changes take effect quickly via refresh. - Works for custom roles and large permission sets.

Implementation Notes (Current Scaffold)

These notes capture the current iam-service implementation so we have a shared reference while the rest of the platform evolves.

  • User ↔ Role assignments only (no groups).
  • Policy versioning per tenant/workspace; increments on role/assignment changes.
  • IAM token issuance using RS256.
  • Tokens include: sub, tenant_id, workspace_id, roles (role IDs), service, policy_version, aud (service), and iss.
  • JWKS is exposed at /.well-known/jwks.json for service verification.

API Sketch (v1, conceptual)

  • POST /v1/permissions/register
  • GET /v1/permissions
  • POST /v1/roles
  • GET /v1/roles
  • POST /v1/assignments
  • GET /v1/assignments?user_id=...&workspace_id=...

Non-Goals (v0/v1)

  • External marketplace of policies.
  • Fine-grained ABAC rules beyond workspace scoping.
  • Real-time policy evaluation on every request.

Open Questions

  • How to map roles to permissions per workspace and tenant?
  • Where should permission claims be minted (IAM gateway vs. IAM service)?
  • How to version permission names over time without breaking UI?

Permissions Inventory (Initial Brainstorm, Non-Contractual)

This section is a starting point only and not a binding contract. If a service's implementation reveals a better permission model, we should adapt and update this inventory rather than forcing a mismatch.

Integrations Service (planned/active): - integrations.read - connections.read - connections.create - connections.update - connections.delete - connections.test

Discovery Service (planned): - discovery.run - discovery.read - discovery.history.read

Access Explorer Service (planned): - explorer.read - export.generate

Platform/IAM Service (future): - permissions.register - permissions.read - roles.create - roles.read - roles.update - roles.delete - assignments.manage