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(...)).
Practical Model for Custom Roles (Recommended)¶
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), andiss. - JWKS is exposed at
/.well-known/jwks.jsonfor 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