AgentSkillsCN

prowler-api

Prowler API 的常见模式:JSON:API、RLS、RBAC、提供商、Celery 任务。触发时机:当您在 api/ 目录下,针对涉及租户隔离(RLS)、RBAC、JSON:API 或提供商生命周期的模型/序列化器/视图集/过滤器/任务进行开发时。

SKILL.md
--- frontmatter
name: prowler-api
description: >
  Prowler API patterns: JSON:API, RLS, RBAC, providers, Celery tasks.
  Trigger: When working in api/ on models/serializers/viewsets/filters/tasks involving tenant isolation (RLS), RBAC, JSON:API, or provider lifecycle.
license: Apache-2.0
metadata:
  author: prowler-cloud
  version: "1.0"
  scope: [root, api]
  auto_invoke: "Creating/modifying models, views, serializers"
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)

ProviderUID FormatExample
AWS12 digits123456789012
AzureUUID v4a1b2c3d4-e5f6-...
GCP6-30 chars, lowercase, letter startmy-gcp-project
M365Valid domaincontoso.onmicrosoft.com
Kubernetes2-251 charsarn:aws:eks:...
GitHub1-39 charsmy-org
IaCGit URLhttps://github.com/user/repo.git
Oracle CloudOCID formatocid1.tenancy.oc1..
MongoDB Atlas24-char hex507f1f77bcf86cd799439011
Alibaba Cloud16 digits1234567890123456

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


2. Row-Level Security (RLS)

python
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

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

4. RBAC

python
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

python
@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

python
content_type = "application/vnd.api+json"

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

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

7. Serializers

PatternUsage
ProviderSerializerRead (list/retrieve)
ProviderCreateSerializerPOST
ProviderUpdateSerializerPATCH
RLSSerializerAuto-injects tenant_id

Commands

bash
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