Skip to content

feat(work-management): implement workspace administration and RBAC (#9) - #65

Merged
jacksonsr451 merged 1 commit into
mainfrom
feat/9-workspaces-projects-rbac
Oct 16, 2026
Merged

jacksonsr451 merged 1 commit into
mainfrom
feat/9-workspaces-projects-rbac

Conversation

@jacksonsr451

Copy link
Copy Markdown
Owner

Summary

Implements workspace and project administration, membership management, secure invitations, and action-level Role-Based Access Control (RBAC) for EventFlow's Work Management bounded context.

This PR establishes the workspace as the primary tenant isolation and authorization boundary, integrating with the trusted AuthenticatedPrincipal infrastructure delivered by Issue #10.

The implementation includes authenticated HTTP endpoints, tenant-aware application services, PostgreSQL persistence, transactional membership operations, concurrency protections, audit records, and comprehensive IDOR/BOLA security tests.

Changes

  • Implement workspace creation, retrieval, listing, and updates.
  • Implement workspace-scoped project creation, retrieval, listing, and updates.
  • Add membership persistence, role assignment, role changes, and access revocation.
  • Implement secure workspace invitations with identity-bound acceptance and digest-only token storage.
  • Support six workspace roles: owner, admin, triager, approver, contributor, and viewer.
  • Implement centralized action-level RBAC enforcement.
  • Integrate authorization with the existing authenticated principal.
  • Enforce workspace isolation at HTTP, application-service, and repository boundaries.
  • Add owner-preservation invariants and transactional consistency.
  • Introduce PostgreSQL concurrency protections for membership and invitation operations.
  • Extend OpenAPI and shared schemas for workspace administration.
  • Add integration, security, IDOR/BOLA, and concurrency regression tests.

Motivation

EventFlow requires secure workspace-level isolation to support multiple independent teams, projects, integrations, and members.

Although the existing authentication infrastructure verifies user identity, authentication alone does not establish which workspace resources a user may access or modify.

This PR introduces explicit workspace membership and action-level authorization, ensuring that users can access only the resources and operations permitted by their active membership.

It also establishes the authorization foundation required by future Work Management workflows and integrations.

Type of Change

  • Bug fix
  • New feature
  • Refactoring
  • Performance improvement
  • Security improvement
  • Documentation
  • CI/CD or infrastructure
  • Dependency update
  • Breaking change

Related Issues

Closes #9

Depends on:

Related:

Implementation Details

Architecture

The implementation preserves EventFlow's bounded-context architecture.

Work Management owns workspace administration, projects, membership, invitations, and authorization.

Order Processing remains independent and unchanged.

The authorization flow is:

  1. Validate authentication through the existing Issue [FEAT] Implementar autenticação e gestão segura de sessão dos três clientes #10 infrastructure.
  2. Resolve the trusted internal user UUID.
  3. Identify the requested workspace.
  4. Resolve active workspace membership.
  5. Evaluate the required action-level permission.
  6. Validate resource ownership by the workspace.
  7. Execute the operation within the appropriate transactional boundary.

Authorization is enforced in application services, not exclusively in HTTP route handlers.

This prevents bypasses when business operations are invoked outside the HTTP layer.

Persistence

Introduces:

  • workspace_memberships
  • workspace_invitations

Adds Alembic migration:

0003_workspace_membership_rbac

The migration depends on:

0002_auth_sessions

Persistence includes:

  • UUID-based identities.
  • Workspace-scoped relationships.
  • Partial unique indexes.
  • Membership and invitation lifecycle constraints.
  • Digest-only invitation token storage.
  • Transactional audit integration.

Existing migrations remain unchanged.

Workspace and Project Management

Implements authenticated administration for workspaces and their projects.

Workspace creation atomically establishes the initial owner membership.

Project operations validate both workspace membership and resource ownership.

Cross-workspace identifier substitution does not grant access.

Membership and RBAC

Implements the following workspace roles:

Role Responsibility
owner Full workspace administration and ownership management
admin Workspace and project administration within ownership restrictions
triager Authorized triage operations
approver Authorized approval operations
contributor Permitted operational contributions
viewer Read-only access to permitted workspace resources

Permissions are evaluated per action rather than relying solely on HTTP methods or route-level role checks.

The current workspace administration policy includes:

Action Allowed roles
workspace:read All six roles
workspace:update Owner, Admin
project:create Owner, Admin
project:read All six roles
project:update Owner, Admin
membership:read All six roles
membership:update_role Owner, Admin, subject to assignment restrictions
membership:revoke Owner, Admin, subject to ownership restrictions
membership:transfer_ownership Owner only
membership:invite Owner, Admin

Workspace creation, accessible-workspace listing, and identity-bound invitation acceptance use authenticated-principal scope with additional operation-specific checks.

An administrator cannot grant, assign, or demote the owner role outside the explicit ownership policy.

Secure Invitations

Implements invitation creation, acceptance, revocation, and expiration.

Security properties include:

  • Identity-bound acceptance.
  • Cryptographically protected invitation tokens.
  • Digest-only token persistence.
  • Replay prevention.
  • Expiration enforcement.
  • Revocation enforcement.
  • Atomic membership creation.
  • Concurrency-safe state transitions.

Invitation response semantics:

  • Consumed invitation: 404.
  • Revoked invitation: 404.
  • Pending but expired invitation: 409.

Transactional Consistency

Workspace and membership operations use explicit transactional units of work.

The implementation protects:

  • Atomic workspace and initial-owner creation.
  • Membership uniqueness.
  • Invitation acceptance.
  • Membership role changes.
  • Membership revocation.
  • Ownership preservation.
  • Audit consistency.

The last active owner cannot be removed or demoted through ordinary membership operations.

Concurrency Protection

PostgreSQL row-level locking and database constraints protect concurrent membership and invitation operations.

The final audit identified a race condition in invitation revocation.

Previously, revocation checked invitation state without acquiring the same row lock used by acceptance.

A concurrent acceptance could commit membership creation before revocation updated the invitation state, producing contradictory results.

The correction introduces:

InvitationRepository.get_for_update(...)

Invitation revocation now follows the same locking protocol as acceptance.

The defect was reproduced with a regression test before the fix was restored and validated.

HTTP API and Contracts

Implements 16 authenticated workspace administration routes.

Extends:

  • contracts/openapi/work-management.yaml
  • contracts/schemas/work_management.yaml

Preserves:

  • OpenAPI 3.1.
  • /v1/ API prefix.
  • RFC 9457 Problem Details.
  • Existing authentication schemes.
  • Action-level authorization metadata.
  • ETag/If-Match behavior.
  • Established domain boundaries.

Three operations use x-authorization-scope: authenticated with additional identity or membership restrictions appropriate to their responsibilities.

Security Considerations

Tenant Isolation

Workspace membership is evaluated using the trusted internal user identity.

Resource identifiers alone never establish access rights.

Workspace-scoped resources are protected against cross-tenant access.

IDOR/BOLA Protection

Security tests cover identifier substitution involving:

  • Workspace IDs.
  • Project IDs.
  • Membership IDs.
  • Invitation IDs.
  • Cross-workspace invitation acceptance.
  • Invalid invitation tokens.

Unauthorized cross-workspace access is concealed with 404 responses under the implemented policy.

Privilege Escalation

The implementation rejects:

  • Viewer self-promotion.
  • Unauthorized administrative role assignment.
  • Admin-to-owner escalation through role changes.
  • Admin-to-owner escalation through invitations.
  • Unauthorized membership administration.
  • Invalid ownership changes.

Membership Revocation

Revoked members immediately lose workspace authorization, even if their authentication credentials remain valid.

Owner Preservation

Transactional safeguards prevent operations from leaving a workspace without an active owner.

Auditability

Membership, invitation, and workspace administration operations integrate with the existing audit infrastructure.

Invitation secrets are not persisted in plaintext.

Testing

The final local validation used PostgreSQL 17.10 and the existing jsr-testrunner infrastructure.

Results

Suite Passed Failed Skipped
Work Management, PostgreSQL and security integration 116 0 1
Repository contracts and regression tests 110 0 0
Total 226 0 1

The single skipped test requires a live Keycloak environment and belongs to the Issue #10 authentication integration suite.

The previously skipped 59 PostgreSQL-dependent tests were executed successfully.

Verified Scenarios

  • PostgreSQL 17.10 integration.
  • Alembic migration upgrade.
  • Migration downgrade and re-upgrade.
  • Workspace creation and initial-owner assignment.
  • Project administration.
  • Membership lifecycle.
  • Action-level RBAC.
  • HTTP authorization.
  • Cross-workspace isolation.
  • IDOR/BOLA identifier substitution.
  • Membership revocation.
  • Last-owner protection.
  • Invitation acceptance and revocation.
  • Invitation token replay protection.
  • Concurrent invitation acceptance.
  • Concurrent invitation acceptance versus revocation.
  • Concurrent membership creation.
  • Concurrent role changes.
  • Concurrent ownership operations.
  • Concurrent privilege escalation rejection.
  • OpenAPI validation.
  • Contract and repository validation.
  • Order Processing regression tests.
  • Pre-commit validation.

Validation Commands

testrunner services/work-management/tests --disable-plugin-autoload
testrunner tests --disable-plugin-autoload
python scripts/validate_contracts.py
git diff --check

Concurrency Test Evidence

Scenario Result
Concurrent acceptance of the same invitation One effective acceptance; one active membership
Concurrent acceptance and revocation Serialized; no contradictory invitation/membership state
Concurrent duplicate membership creation One successful commit; duplicate rejected
Concurrent last-owner revocation Rejected; owner preserved
Concurrent owner demotion At least one owner preserved
Concurrent ownership transfer At least one owner preserved
Concurrent privilege escalation Rejected; role unchanged
Concurrent role changes Serialized; consistent final state
Concurrent workspace creation with the same slug One creation; conflicting request rejected

Concurrency tests used real PostgreSQL transactions and deterministic thread barriers.

Known Limitations

Keycloak Integration Test

One existing Issue #10 integration test was skipped locally because the live Keycloak authentication stack was not started.

The CI authentication job is configured to run the corresponding integration tests.

Remote CI execution remains pending.

Concurrent ETag Updates

The current API enforces stale ETag preconditions and returns 412 when appropriate.

However, simultaneous updates presenting the same initially valid ETag are not guaranteed to prevent every lost-update race.

This limitation is documented in the existing API architecture and is outside the currently guaranteed optimistic-concurrency contract.

It should be addressed separately if stronger atomic compare-and-update semantics become a requirement.

Backward Compatibility

  • Existing Order Processing behavior is preserved.
  • Existing OAuth/OIDC authentication remains unchanged.
  • Existing Work Management domain boundaries are maintained.
  • Previously merged migrations are not rewritten.
  • Existing API versioning conventions are preserved.
  • Workspace authorization is added without trusting client-provided identity or role claims.

Review Checklist

  • Workspace and project administration implemented.
  • Membership lifecycle implemented.
  • Invitation lifecycle implemented.
  • Six workspace roles supported.
  • Action-level RBAC implemented.
  • Trusted authentication principal integrated.
  • Tenant isolation enforced.
  • IDOR/BOLA scenarios tested.
  • Privilege escalation scenarios tested.
  • Owner invariants validated.
  • PostgreSQL integration tests executed.
  • Concurrency tests executed.
  • Identified invitation race condition corrected.
  • Regression tests added.
  • OpenAPI and schema contracts updated.
  • Documentation updated.
  • Existing regression suites passed.
  • Local Git working tree clean.
  • Remote CI verification.
  • Final code review.

Commits

Outcome

Issue #9 establishes the workspace administration, membership, invitation, and authorization foundation required by EventFlow's Work Management domain.

All required Issue #9 PostgreSQL integration, authorization, IDOR/BOLA, and concurrency tests passed locally.

The implementation is ready for Pull Request review, subject to remote CI verification and final maintainer approval.

@jacksonsr451
jacksonsr451 merged commit 0c5add5 into main Oct 16, 2026
3 checks passed
@jacksonsr451
jacksonsr451 deleted the feat/9-workspaces-projects-rbac branch October 16, 2026 14:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEAT] Implementar workspaces, projetos, membros e permissões

1 participant