# Guard System Deep Dive {#guard-system-deep-dive}


NestJS guards used for authentication, authorization, and tenant isolation.


## Guard Execution Order {#guard-execution-order}






```mermaid
graph LR
    Request --> Global[Global Guards]
    Global --> Controller[Controller Guards]
    Controller --> Method[Method Guards]
    Method --> Handler[Route Handler]
```






## Core Guards {#core-guards}



### TenantPermissionGuard {#tenantpermissionguard}


The most commonly used guard. Validates:

1. User is authenticated (JWT valid)
2. User belongs to the requested tenant
3. User has required permissions

```typescript
@UseGuards(TenantPermissionGuard)
@Permissions(PermissionsEnum.ORG_EMPLOYEES_VIEW)
@Get()
async findAll() {}
```


### RoleGuard {#roleguard}


Restricts access by user role:

```typescript
@UseGuards(RoleGuard)
@Roles(RolesEnum.SUPER_ADMIN, RolesEnum.ADMIN)
@Delete(':id')
async delete(@Param('id') id: string) {}
```


### PermissionGuard {#permissionguard}


Checks specific permissions:

```typescript
@UseGuards(PermissionGuard)
@Permissions(PermissionsEnum.INVOICES_EDIT)
@Put(':id')
async update() {}
```


### OrganizationPermissionGuard {#organizationpermissionguard}


Validates organization-level access:

```typescript
@UseGuards(OrganizationPermissionGuard)
@Get()
async findByOrg() {}
```


## Guard Hierarchy {#guard-hierarchy}


| Guard                         | Validates                | Usage           |
| ----------------------------- | ------------------------ | --------------- |
| `AuthGuard('jwt')`            | JWT token valid          | All endpoints   |
| `TenantBaseGuard`             | Tenant exists in request | Most endpoints  |
| `TenantPermissionGuard`       | Tenant + permissions     | CRUD operations |
| `RoleGuard`                   | User role matches        | Admin endpoints |
| `PermissionGuard`             | Specific permission      | Feature access  |
| `OrganizationPermissionGuard` | Org membership           | Org endpoints   |


## Creating Custom Guards {#creating-custom-guards}


```typescript
@Injectable()
export class ProjectMemberGuard implements CanActivate {
  async canActivate(context: ExecutionContext): Promise<boolean> {
    const request = context.switchToHttp().getRequest();
    const projectId = request.params.projectId;
    const userId = request.user.id;

    return this.projectService.isMember(projectId, userId);
  }
}
```


## Related Pages {#related-pages}


- [Request Lifecycle](https://sourcey-gauzy.pages.dev/architecture/request-lifecycle/index.md) — full request flow
- [Interceptor Patterns](https://sourcey-gauzy.pages.dev/architecture/interceptor-patterns/index.md) — interceptors
- [Testing Guards](https://sourcey-gauzy.pages.dev/testing/testing-guards/index.md) — guard testing
