feat(#286): Add workspace access validation to federation endpoints
Security improvements: - Apply WorkspaceGuard to all workspace-scoped federation endpoints - Enforce workspace membership verification via Prisma - Prevent cross-workspace access attacks - Add comprehensive test coverage for workspace isolation Changes: - Add WorkspaceGuard to federation connection endpoints: - POST /connections/initiate - POST /connections/:id/accept - POST /connections/:id/reject - POST /connections/:id/disconnect - GET /connections - GET /connections/:id - Add workspace-access.integration.spec.ts with tests for: - Workspace membership verification - Cross-workspace access prevention - Multiple workspace ID sources (header, param, body) Part of M7.1 Remediation Sprint P1 security fixes. Fixes #286 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -12,6 +12,7 @@ import { FederationAuditService } from "./audit.service";
|
||||
import { ConnectionService } from "./connection.service";
|
||||
import { AuthGuard } from "../auth/guards/auth.guard";
|
||||
import { AdminGuard } from "../auth/guards/admin.guard";
|
||||
import { WorkspaceGuard } from "../common/guards/workspace.guard";
|
||||
import { CsrfGuard } from "../common/guards/csrf.guard";
|
||||
import { SkipCsrf } from "../common/decorators/skip-csrf.decorator";
|
||||
import type { PublicInstanceIdentity } from "./types/instance.types";
|
||||
@@ -76,11 +77,11 @@ export class FederationController {
|
||||
|
||||
/**
|
||||
* Initiate a connection to a remote instance
|
||||
* Requires authentication
|
||||
* Requires authentication and workspace access
|
||||
* Rate limit: "medium" tier (20 req/min) - authenticated endpoint
|
||||
*/
|
||||
@Post("connections/initiate")
|
||||
@UseGuards(AuthGuard)
|
||||
@UseGuards(AuthGuard, WorkspaceGuard)
|
||||
@Throttle({ medium: { limit: 20, ttl: 60000 } })
|
||||
async initiateConnection(
|
||||
@Req() req: AuthenticatedRequest,
|
||||
@@ -99,11 +100,11 @@ export class FederationController {
|
||||
|
||||
/**
|
||||
* Accept a pending connection
|
||||
* Requires authentication
|
||||
* Requires authentication and workspace access
|
||||
* Rate limit: "medium" tier (20 req/min) - authenticated endpoint
|
||||
*/
|
||||
@Post("connections/:id/accept")
|
||||
@UseGuards(AuthGuard)
|
||||
@UseGuards(AuthGuard, WorkspaceGuard)
|
||||
@Throttle({ medium: { limit: 20, ttl: 60000 } })
|
||||
async acceptConnection(
|
||||
@Req() req: AuthenticatedRequest,
|
||||
@@ -127,11 +128,11 @@ export class FederationController {
|
||||
|
||||
/**
|
||||
* Reject a pending connection
|
||||
* Requires authentication
|
||||
* Requires authentication and workspace access
|
||||
* Rate limit: "medium" tier (20 req/min) - authenticated endpoint
|
||||
*/
|
||||
@Post("connections/:id/reject")
|
||||
@UseGuards(AuthGuard)
|
||||
@UseGuards(AuthGuard, WorkspaceGuard)
|
||||
@Throttle({ medium: { limit: 20, ttl: 60000 } })
|
||||
async rejectConnection(
|
||||
@Req() req: AuthenticatedRequest,
|
||||
@@ -149,11 +150,11 @@ export class FederationController {
|
||||
|
||||
/**
|
||||
* Disconnect an active connection
|
||||
* Requires authentication
|
||||
* Requires authentication and workspace access
|
||||
* Rate limit: "medium" tier (20 req/min) - authenticated endpoint
|
||||
*/
|
||||
@Post("connections/:id/disconnect")
|
||||
@UseGuards(AuthGuard)
|
||||
@UseGuards(AuthGuard, WorkspaceGuard)
|
||||
@Throttle({ medium: { limit: 20, ttl: 60000 } })
|
||||
async disconnectConnection(
|
||||
@Req() req: AuthenticatedRequest,
|
||||
@@ -171,11 +172,11 @@ export class FederationController {
|
||||
|
||||
/**
|
||||
* Get all connections for the workspace
|
||||
* Requires authentication
|
||||
* Requires authentication and workspace access
|
||||
* Rate limit: "long" tier (200 req/hour) - read-only endpoint
|
||||
*/
|
||||
@Get("connections")
|
||||
@UseGuards(AuthGuard)
|
||||
@UseGuards(AuthGuard, WorkspaceGuard)
|
||||
@Throttle({ long: { limit: 200, ttl: 3600000 } })
|
||||
async getConnections(
|
||||
@Req() req: AuthenticatedRequest,
|
||||
@@ -190,11 +191,11 @@ export class FederationController {
|
||||
|
||||
/**
|
||||
* Get a single connection
|
||||
* Requires authentication
|
||||
* Requires authentication and workspace access
|
||||
* Rate limit: "long" tier (200 req/hour) - read-only endpoint
|
||||
*/
|
||||
@Get("connections/:id")
|
||||
@UseGuards(AuthGuard)
|
||||
@UseGuards(AuthGuard, WorkspaceGuard)
|
||||
@Throttle({ long: { limit: 200, ttl: 3600000 } })
|
||||
async getConnection(
|
||||
@Req() req: AuthenticatedRequest,
|
||||
|
||||
Reference in New Issue
Block a user