Claude Code Plugins

Community-maintained marketplace

Feedback
12.5k
0

>

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name prowler-api
description Prowler API patterns: RLS, RBAC, providers, Celery tasks. Trigger: When working on api/ - models, serializers, views, filters, tasks.
license Apache-2.0
metadata [object Object]
allowed-tools Read, Edit, Write, Glob, Grep, Bash, WebFetch, WebSearch, Task

Critical Rules

  • ALWAYS use rls_transaction(tenant_id) when querying outside ViewSet context
  • ALWAYS use get_role() before checking permissions (returns FIRST role only)
  • NEVER access Provider.objects without RLS context in Celery tasks
  • ALWAYS use @set_tenant then @handle_provider_deletion decorator order

1. Providers (10 Supported)

UID validation is dynamic: getattr(self, f"validate_{self.provider}_uid")(self.uid)

Provider UID Format Example
AWS 12 digits 123456789012
Azure UUID v4 a1b2c3d4-e5f6-...
GCP 6-30 chars, lowercase, letter start my-gcp-project
M365 Valid domain contoso.onmicrosoft.com
Kubernetes 2-251 chars arn:aws:eks:...
GitHub 1-39 chars my-org
IaC Git URL https://github.com/user/repo.git
Oracle Cloud OCID format ocid1.tenancy.oc1..
MongoDB Atlas 24-char hex 507f1f77bcf86cd799439011
Alibaba Cloud 16 digits 1234567890123456

Adding new provider: Add to ProviderChoices enum + create validate_<provider>_uid() staticmethod.


2. Row-Level Security (RLS)

from api.db_utils import rls_transaction

with rls_transaction(tenant_id):
    providers = Provider.objects.filter(connected=True)
    # PostgreSQL enforces tenant_id automatically

Models inherit from RowLevelSecurityProtectedModel with RowLevelSecurityConstraint.


3. Managers

Provider.objects.all()       # Only is_deleted=False
Provider.all_objects.all()   # All including deleted
Finding.objects.all()        # Only from active providers

4. RBAC

from api.rbac.permissions import get_role, get_providers, Permissions

user_role = get_role(self.request.user)  # Returns FIRST role only

if user_role.unlimited_visibility:
    queryset = Provider.objects.filter(tenant_id=tenant_id)
else:
    queryset = get_providers(user_role)  # Filtered by provider_groups

Permissions: MANAGE_USERS, MANAGE_ACCOUNT, MANAGE_BILLING, MANAGE_PROVIDERS, MANAGE_INTEGRATIONS, MANAGE_SCANS, UNLIMITED_VISIBILITY


5. Celery Tasks

@shared_task(base=RLSTask, name="task-name", queue="scans")
@set_tenant
@handle_provider_deletion
def my_task(tenant_id: str, provider_id: str):
    pass

Queues: Check tasks/tasks.py. Common: scans, overview, compliance, integrations.

Orchestration: Use chain() for sequential, group() for parallel.


6. JSON:API Format

content_type = "application/vnd.api+json"

# Request
{"data": {"type": "providers", "attributes": {"provider": "aws", "uid": "123456789012"}}}

# Response access
response.json()["data"]["attributes"]["alias"]

7. Serializers

Pattern Usage
ProviderSerializer Read (list/retrieve)
ProviderCreateSerializer POST
ProviderUpdateSerializer PATCH
RLSSerializer Auto-injects tenant_id

Commands

cd api && poetry run python manage.py migrate      # Run migrations
cd api && poetry run python manage.py shell        # Django shell
cd api && poetry run celery -A config.celery worker -l info  # Start worker

Resources