{"enrichment":{"faq":[{"a":"Prowler-api enforces RLS through model constraints, database triggers, and context managers. Each query filters by tenant_id via QuerySet.filter() in views, with M2M relationships using through models to maintain isolation. The @set_tenant decorator captures tenant context from request headers, passing it to Celery tasks and database transactions. RLS patterns include: tenant_id on all models, database-level CHECK constraints, and explicit permission checks in serializers before returning provider data across AWS, Azure, and GCP resources.","q":"What are prowler api row level security rls patterns?"},{"a":"Prowler-api implements RLS transactions by wrapping database operations in context managers that set tenant_id before query execution. Use django.db.transaction.atomic() combined with a custom TenantContext manager that validates the tenant exists and user has access. Within the transaction, all QuerySets automatically filter by the active tenant. For Celery tasks, the @set_tenant decorator must execute before @shared_task to preserve tenant context across async boundaries. Admin bypass uses a separate read replica database configured in settings.DATABASES with a custom router.","q":"How do you implement rls transaction in django with prowler-api?"},{"a":"Prowler-api provider lifecycle validation uses a @provider_deletion_handler decorator that triggers cascade cleanup: removing associated scans, audit results, and compliance records before soft-deleting the provider. Validation checks provider_uid format (AWS account ID, Azure subscription, GCP project) against cloud provider APIs. The deletion handler must execute within the tenant context to prevent cross-tenant data leakage. Provider state transitions (active\u2192inactive\u2192deleted) are logged with audit trails, and hard deletion is restricted to admin users accessing the bypass database.","q":"How should prowler provider lifecycle validation handle deletion?"},{"a":"Prowler-api uses four databases: primary (write operations, tenant data), read replica (analytics queries), admin bypass (cross-tenant operations, compliance reporting), and audit log store (immutable deletion/access records). The router in settings.DATABASES directs tenant queries to primary/replica based on operation type, while admin endpoints route to the bypass database. Read replicas lag by seconds; critical operations use the primary. UUIDv7 partitioned tables on the primary enable efficient tenant-scoped queries. Each database has separate credentials and network isolation.","q":"What is the prowler 4-database architecture setup?"},{"a":"Prowler-api's @set_tenant decorator must wrap @shared_task and execute first in the decorator stack to capture tenant_id from the request context before the task enters the Celery worker. The decorator extracts tenant_id from task kwargs, validates it exists, and sets it in thread-local storage for the task duration. Example: @set_tenant @shared_task def scan_provider(tenant_id, provider_uid). Without proper ordering, tasks lose tenant context and queries fail RLS filters. Use celery.canvas (chain, group) to compose multi-step scans while preserving tenant isolation across task boundaries.","q":"How do you use celery @set_tenant decorator with prowler-api tasks?"},{"a":"Prowler-api implements RBAC through role-based provider visibility: users with 'viewer' role see read-only provider data, 'operator' role can trigger scans, 'admin' role manages providers and users. Permissions are checked via get_role() helper that queries the user's role and tenant membership. Provider visibility is filtered in ViewSet.get_queryset() by role: viewers see all tenant providers, operators see assigned providers, admins see all. M2M through models link users to providers with explicit permission grants. Serializers validate role before exposing sensitive fields like credentials or compliance scores.","q":"What does prowler-api require for django rbac permissions and role-based provider visibility?"}],"shadow_tags":["multi-tenant-security","row-level-security","async-task-patterns","provider-management","celery-orchestration","rbac-implementation","database-routing","tenant-context","task-scheduling"],"summary_rewrite":"This skill guides implementation of Prowler's multi-tenant API architecture, covering row-level security enforcement, role-based access control, provider validation, and async task patterns. Learn the 4-database setup, RLS model constraints, M2M through-model requirements, and critical decorator ordering for tenant-isolated operations."},"files":[{"bytes":17465,"path":"skills/prowler-api/SKILL.md","sha256":"133438f95e3025d1758c57e60543a46955e6158a5b8fe1ec1905137dc4434e51","url":"https://skillfed.io/files/prowler-cloud/prowler/prowler-api/bc833e2a/SKILL.md"}],"id":"prowler-cloud/prowler/prowler-api","links":{"html":"https://skillfed.io/prowler-cloud/prowler/prowler-api","md":"https://skillfed.io/prowler-cloud/prowler/prowler-api.md","repo":"https://github.com/prowler-cloud/prowler"},"meta":{"agents_supported":[],"first_seen":"2026-07-28","forks":2285,"language":"Python","last_updated":"2026-07-27","license":"Apache-2.0","name":"prowler-api","publisher":"prowler-cloud","stars":14491},"relations":{"similar":[{"id":"prowler-cloud/prowler/django-drf"},{"id":"prowler-cloud/prowler/django-migration-psql"},{"id":"prowler-cloud/prowler/prowler-test-api"},{"id":"prowler-cloud/prowler/jsonapi"},{"id":"dadbodgeoff/drift/multi-tenancy"},{"id":"prowler-cloud/prowler/postgresql-indexing"},{"id":"patricio0312rev/skills/multi-tenant-safety-checker"},{"id":"troykelly/claude-skills/postgres-rls"},{"id":"vintasoftware/django-ai-plugins/django-celery-expert"},{"id":"affaan-m/ECC/django-celery"}]},"slug":{"owner":"prowler-cloud","repo":"prowler","skill":"prowler-api"},"version":"bc833e2a"}
