ADR-0012: Workspace Context via Header, Not Path Variable
Status: ACCEPTED Date: 2026-03-23 Supersedes: N/A Superseded by: N/A
Context
The original API design used {workspaceId} as a path variable that served dual purpose: resource locator (which workspace to operate on) and permission context (where to check RBAC). This created ambiguity in admin endpoints where the user's own workspace (permission source) differs from the target workspace (resource being managed). A workaround flag validateMembership=false was used to bypass membership checks, weakening security.
Source: docs/archive/specs/2026-03-23-workspace-context-header-design.md
Decision
The user's current workspace (permission context) is transmitted via the X-Workspace-Id HTTP header, validated by @RequireWorkspace annotation processing. Path variables carry no business data. Target resource identifiers (e.g., a different workspace's workspaceBizId) go in the request body. Admin endpoints that previously used GET with path variables are converted to POST with body parameters. The validateMembership and validateStatus parameters are removed; membership and status are always enforced.
Consequences
- Clean separation: header = "who am I acting as", body = "what am I acting on".
- The
validateMembership=falseworkaround is eliminated; all requests are fully validated. - Every endpoint with
@RequirePermissionmust also have@RequireWorkspace, enforced by the gateway chain. - Admin GET endpoints become POST (non-RESTful but unambiguous), consistent with ADR-0005.
- Frontend must include
X-Workspace-Idheader on all workspace-scoped requests.
Alternatives Considered
- Dual path variables (
/my-workspace/{myId}/target/{targetId}): Rejected because it makes URLs even longer and does not solve the semantic ambiguity. - JWT claims for workspace context: Rejected because workspace selection can change within a session (user switches workspaces), while the JWT is issued at login time.
- Keep
validateMembership=falsewith better documentation: Rejected because disabling membership validation is a security hole that documentation cannot fix.