framework-compliance-t…
Make a cloud account compliant with a security or industry framework using Prowler Cloud.
Prowler API patterns: RLS, RBAC, providers, Celery tasks, SSE. Trigger: When working in api/ on models/serializers/viewsets/filters/tasks involving tenant isolation (RLS), RBAC, provider lifecycle, Celery tasks or SSE endpoints.
Claude Code
$ npx -y skills add prowler-cloud/prowler --skill prowler-api --agent claude-code
Codex
$ npx skills add prowler-cloud/prowler --skill prowler-api -a codex -y
Cursor
$ npx skills add prowler-cloud/prowler --skill prowler-api -a cursor -y
Gemini CLI
$ npx skills add prowler-cloud/prowler --skill prowler-api -a gemini-cli -y
GitHub Copilot
$ npx skills add prowler-cloud/prowler --skill prowler-api -a github-copilot -y
OpenCode
$ npx skills add prowler-cloud/prowler --skill prowler-api -a opencode -y
Windsurf
$ npx skills add prowler-cloud/prowler --skill prowler-api -a windsurf -y
name: prowler-api description: > Prowler API patterns: RLS, RBAC, providers, Celery tasks, SSE. Trigger: When working in api/ on models/serializers/viewsets/filters/tasks involving tenant isolation (RLS), RBAC, provider lifecycle, Celery tasks or SSE endpoints. license: Apache-2.0 metadata: author: prowler-cloud version: "1.3.0" scope: [root, api] auto_invoke: "Creating/modifying models, views, serializers" allowed-tools: Read, Edit, Write, Glob, Grep, Bash, WebFetch, WebSearch, Task
Use this skill for **Prowler-specific** patterns:
For **generic DRF patterns** (ViewSets, Serializers, Filters, JSON:API), use `django-drf` skill.
All paths below are relative to `api/src/backend/` unless they start with `api/`.
---
> `rls_transaction(value, parameter=POSTGRES_TENANT_VAR, using=None, retry_on_replica=True)` validates that `value` is a UUID (UUID objects and strings both work) and raises `ValidationError` otherwise.
---
| Alias | DB user | Purpose | RLS | |-------|---------|---------|-----| | `default` | `POSTGRES_USER` (`default` = the `prowler_user` entry) | Standard API queries | **Yes** | | `admin` | `POSTGRES_ADMIN_USER` | Migrations, auth lookups, Django internal tables | No | | `replica` | `POSTGRES_REPLICA_USER` | Read-only queries | **Yes** | | `admin_replica` | `POSTGRES_ADMIN_USER` | Admin reads on replica | No | | `neo4j` | `NEO4J_USER` | Graph DB for Attack Paths (not routed by Django) | - |
from api.db_router import MainRouter, READ_REPLICA_ALIAS
User.objects.using(MainRouter.admin_db).get(id=user_id) # Auth lookups (bypasses RLS)
with rls_transaction(tenant_id, using=READ_REPLICA_ALIAS): # Read-heavy task code
Finding.objects.filter(scan_id=scan_id).count()Request -> BaseRLSViewSet.dispatch() replica for SAFE_METHODS (if configured), transaction.atomic
-> BaseRLSViewSet.initial() tenant_id from request.auth (JWT or API key)
rls_transaction(tenant_id) -> set_config('api.tenant_id', ...)
-> queries are tenant-scoped; serializer context gets tenant_idOther bases in the same file: `BaseTenantViewset` (tenant CRUD), `BaseUserViewset` (user endpoints), `BaseViewSet` (no RLS).
---
| # | Pattern | Reference | Key Points | |---|---------|-----------|------------| | 1 | **RLS Models** | `api/rls.py` | Inherit `RowLevelSecurityProtectedModel`, add `RowLevelSecurityConstraint` | | 2 | **RLS Transactions** | `api/db_utils.py` | `rls_transaction(tenant_id)` context manager | | 3 | **RBAC Permissions** | `api/rbac/permissions.py` | `Permissions` enum, `HasPermissions`, `get_role()`, `get_providers()` | | 4 | **Provider Validation** | `api/models.py` | `validate_<provider>_uid()` staticmethods on `Provider` | | 5 | **Celery Tasks** | `tasks/tasks.py`, `api/decorators.py`, `config/celery.py` | `@shared_task(base=RLSTask, name=...)`, `@set_tenant`, `@handle_provider_deletion` | | 6 | **Task business logic** | `tasks/jobs/*.py` | Keep `tasks.py` thin; logic lives in `jobs/` | | 7 | **RLS Serializers** | `api/v1/serializers.py` | Inherit `RLSSerializer` to auto-inject `tenant_id` | | 8 | **Base ViewSets** | `api/base_views.py` | `BaseRLSViewSet` for tenant-scoped resources | | 9 | **SSE endpoints** | `api/sse/` | Subclass `BaseSSEViewSet`, build channels with `make_channel_name()` | | 10 | **Changelog** | `api/changelog.d/` | Add a towncrier fragment, never edit `CHANGELOG.md` (see `prowler-changelog`) |
> **Full file paths**: See [references/file-locations.md](references/file-locations.md)
---
Tenant-scoped data -> RowLevelSecurityProtectedModel Global/shared data -> models.Model + BaseSecurityConstraint (rare) Partitioned time-series -> PostgresPartitionedModel + RowLevelSecurityProtectedModel Hide data of deleted providers -> objects = ActiveProviderManager(); all_objects = models.Manager()
Normal queries -> Model.objects (ActiveProviderManager filters out deleted providers) Include deleted records -> Model.all_objects Celery task context -> Must be inside rls_transaction() first
Standard API queries -> default (automatic via V
Prowler is the world’s most widely used Open-Source Cloud Security Platform that automates security and compliance across any cloud environment.
Make a cloud account compliant with a security or industry framework using Prowler Cloud.
Vercel AI SDK patterns for the installed major (ui/package.json: `ai` 6.x, `@ai-sdk/react` 3.x). The skill name is historical;…
Django REST Framework patterns. Trigger: When implementing generic DRF APIs (ViewSets, serializers, routers, permissions,…
Reviews Django migration files for PostgreSQL best practices specific to Prowler. Trigger: When creating migrations, running…
Create and maintain GitHub Agentic Workflows (gh-aw) for Prowler. Trigger: When creating agentic workflows, modifying gh-aw…
Strict JSON:API v1.1 specification compliance. Trigger: When creating or modifying API endpoints, reviewing API responses, or…
Use for authorized security assessment of REST, GraphQL, WebSocket, or SOAP APIs, including discovery, authentication,…
Extract and decrypt Windows DPAPI-protected secrets (Credential Manager, browser logins/cookies, Wi-Fi credentials, KeePass keys)…
Clean and finalize authorized natural-language text intended for readers by auditing suspicious invisible Unicode and rewriting…