mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-01-25 02:08:11 +00:00
9.3 KiB
9.3 KiB
Prowler API Configuration Reference
Settings File Structure
api/src/backend/config/
├── django/
│ ├── base.py # Base settings (all environments)
│ ├── devel.py # Development overrides
│ ├── production.py # Production settings
│ └── testing.py # Test settings
├── settings/
│ ├── celery.py # Celery broker/backend config
│ ├── partitions.py # Table partitioning settings
│ ├── sentry.py # Error tracking + exception filtering
│ └── social_login.py # OAuth/SAML providers
├── celery.py # Celery app instance + RLSTask
├── custom_logging.py # NDJSON/Human-readable formatters
├── env.py # django-environ setup
└── urls.py # Root URL config
REST Framework Configuration
Complete REST_FRAMEWORK Settings
REST_FRAMEWORK = {
# Schema Generation (JSON:API compatible)
"DEFAULT_SCHEMA_CLASS": "drf_spectacular_jsonapi.schemas.openapi.JsonApiAutoSchema",
# Authentication (JWT + API Key)
"DEFAULT_AUTHENTICATION_CLASSES": (
"api.authentication.CombinedJWTOrAPIKeyAuthentication",
),
# Pagination
"PAGE_SIZE": 10,
"DEFAULT_PAGINATION_CLASS": "drf_spectacular_jsonapi.schemas.pagination.JsonApiPageNumberPagination",
# Custom exception handler (JSON:API format)
"EXCEPTION_HANDLER": "api.exceptions.custom_exception_handler",
# Parsers (JSON:API compatible)
"DEFAULT_PARSER_CLASSES": (
"rest_framework_json_api.parsers.JSONParser",
"rest_framework.parsers.FormParser",
"rest_framework.parsers.MultiPartParser",
),
# Custom renderer with RLS context support
"DEFAULT_RENDERER_CLASSES": ("api.renderers.APIJSONRenderer",),
# Metadata
"DEFAULT_METADATA_CLASS": "rest_framework_json_api.metadata.JSONAPIMetadata",
# Filter Backends
"DEFAULT_FILTER_BACKENDS": (
"rest_framework_json_api.filters.QueryParameterValidationFilter",
"rest_framework_json_api.filters.OrderingFilter",
"rest_framework_json_api.django_filters.backends.DjangoFilterBackend",
"rest_framework.filters.SearchFilter",
),
# JSON:API search parameter
"SEARCH_PARAM": "filter[search]",
# Test settings
"TEST_REQUEST_RENDERER_CLASSES": ("rest_framework_json_api.renderers.JSONRenderer",),
"TEST_REQUEST_DEFAULT_FORMAT": "vnd.api+json",
# Uniform exception format
"JSON_API_UNIFORM_EXCEPTIONS": True,
# Throttling
"DEFAULT_THROTTLE_CLASSES": ["rest_framework.throttling.ScopedRateThrottle"],
"DEFAULT_THROTTLE_RATES": {
"token-obtain": env("DJANGO_THROTTLE_TOKEN_OBTAIN", default=None),
"dj_rest_auth": None,
},
}
Throttling Configuration
| Scope | Environment Variable | Default | Format |
|---|---|---|---|
token-obtain |
DJANGO_THROTTLE_TOKEN_OBTAIN |
None (disabled) |
"X/minute", "X/hour", "X/day" |
dj_rest_auth |
N/A | None (disabled) |
Same |
To enable throttling:
DJANGO_THROTTLE_TOKEN_OBTAIN="10/minute" # Limit token endpoint to 10 requests/minute
JWT Configuration (SIMPLE_JWT)
SIMPLE_JWT = {
# Token Lifetimes
"ACCESS_TOKEN_LIFETIME": timedelta(minutes=30), # DJANGO_ACCESS_TOKEN_LIFETIME
"REFRESH_TOKEN_LIFETIME": timedelta(minutes=1440), # DJANGO_REFRESH_TOKEN_LIFETIME (24h)
# Token Rotation
"ROTATE_REFRESH_TOKENS": True,
"BLACKLIST_AFTER_ROTATION": True,
# Cryptographic Settings
"ALGORITHM": "RS256", # Asymmetric (requires key pair)
"SIGNING_KEY": env.str("DJANGO_TOKEN_SIGNING_KEY", ""),
"VERIFYING_KEY": env.str("DJANGO_TOKEN_VERIFYING_KEY", ""),
# JWT Claims
"TOKEN_TYPE_CLAIM": "typ",
"JTI_CLAIM": "jti",
"USER_ID_FIELD": "id",
"USER_ID_CLAIM": "sub",
# Issuer/Audience
"AUDIENCE": env.str("DJANGO_JWT_AUDIENCE", "https://api.prowler.com"),
"ISSUER": env.str("DJANGO_JWT_ISSUER", "https://api.prowler.com"),
# Custom Serializers
"TOKEN_OBTAIN_SERIALIZER": "api.serializers.TokenSerializer",
"TOKEN_REFRESH_SERIALIZER": "api.serializers.TokenRefreshSerializer",
}
Database Configuration
4-Database Architecture
DATABASES = {
"default": {...}, # Alias to prowler_user (RLS enabled)
"prowler_user": {...}, # RLS-enabled connection
"admin": {...}, # Admin connection (bypasses RLS)
"replica": {...}, # Read replica (RLS enabled)
"admin_replica": {...}, # Admin on replica
"neo4j": {...}, # Graph database (attack paths)
}
Environment Variables
| Variable | Default | Description |
|---|---|---|
POSTGRES_DB |
prowler_db |
Database name |
POSTGRES_USER |
prowler_user |
API user (RLS-constrained) |
POSTGRES_PASSWORD |
- | API user password |
POSTGRES_HOST |
postgres-db |
Database host |
POSTGRES_PORT |
5432 |
Database port |
POSTGRES_ADMIN_USER |
prowler |
Admin user (migrations) |
POSTGRES_ADMIN_PASSWORD |
- | Admin password |
POSTGRES_REPLICA_HOST |
- | Replica host (optional) |
POSTGRES_REPLICA_MAX_ATTEMPTS |
3 |
Retry attempts before fallback |
POSTGRES_REPLICA_RETRY_BASE_DELAY |
0.5 |
Base delay for exponential backoff |
Celery Configuration
Broker/Backend
VALKEY_HOST = env("VALKEY_HOST", default="valkey")
VALKEY_PORT = env("VALKEY_PORT", default="6379")
VALKEY_DB = env("VALKEY_DB", default="0")
CELERY_BROKER_URL = f"redis://{VALKEY_HOST}:{VALKEY_PORT}/{VALKEY_DB}"
CELERY_RESULT_BACKEND = "django-db" # Store results in PostgreSQL
CELERY_TASK_TRACK_STARTED = True
CELERY_BROKER_CONNECTION_RETRY_ON_STARTUP = True
Task Visibility
| Variable | Default | Description |
|---|---|---|
DJANGO_BROKER_VISIBILITY_TIMEOUT |
86400 (24h) |
Task visibility timeout |
DJANGO_CELERY_DEADLOCK_ATTEMPTS |
5 |
Deadlock retry attempts |
Partitioning Configuration
PSQLEXTRA_PARTITIONING_MANAGER = "api.partitions.manager"
FINDINGS_TABLE_PARTITION_MONTHS = env.int("FINDINGS_TABLE_PARTITION_MONTHS", 1)
FINDINGS_TABLE_PARTITION_COUNT = env.int("FINDINGS_TABLE_PARTITION_COUNT", 7)
FINDINGS_TABLE_PARTITION_MAX_AGE_MONTHS = env.int("...", None) # Optional cleanup
Application Settings
| Variable | Default | Description |
|---|---|---|
DJANGO_DEBUG |
False |
Debug mode |
DJANGO_ALLOWED_HOSTS |
["localhost"] |
Allowed hosts |
DJANGO_CACHE_MAX_AGE |
3600 |
HTTP cache max-age |
DJANGO_STALE_WHILE_REVALIDATE |
60 |
Stale-while-revalidate time |
DJANGO_FINDINGS_MAX_DAYS_IN_RANGE |
7 |
Max days for findings date filter |
DJANGO_TMP_OUTPUT_DIRECTORY |
/tmp/prowler_api_output |
Temp output directory |
DJANGO_FINDINGS_BATCH_SIZE |
1000 |
Batch size for findings export |
DJANGO_DELETION_BATCH_SIZE |
5000 |
Batch size for deletions |
DJANGO_LOGGING_LEVEL |
INFO |
Log level |
DJANGO_LOGGING_FORMATTER |
ndjson |
Log format (ndjson or human_readable) |
Social Login (OAuth/SAML)
| Variable | Description |
|---|---|
SOCIAL_GOOGLE_OAUTH_CLIENT_ID |
Google OAuth client ID |
SOCIAL_GOOGLE_OAUTH_CLIENT_SECRET |
Google OAuth secret |
SOCIAL_GITHUB_OAUTH_CLIENT_ID |
GitHub OAuth client ID |
SOCIAL_GITHUB_OAUTH_CLIENT_SECRET |
GitHub OAuth secret |
Monitoring
| Variable | Description |
|---|---|
DJANGO_SENTRY_DSN |
Sentry DSN for error tracking |
Middleware Stack (Order Matters)
MIDDLEWARE = [
"django_guid.middleware.guid_middleware", # 1. Transaction ID
"django.middleware.security.SecurityMiddleware", # 2. Security headers
"django.contrib.sessions.middleware.SessionMiddleware",
"corsheaders.middleware.CorsMiddleware", # 4. CORS (before Common)
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
"api.middleware.APILoggingMiddleware", # 10. Custom API logging
"allauth.account.middleware.AccountMiddleware",
]
Security Headers
| Setting | Value | Description |
|---|---|---|
SECURE_PROXY_SSL_HEADER |
("HTTP_X_FORWARDED_PROTO", "https") |
Trust X-Forwarded-Proto |
SECURE_CONTENT_TYPE_NOSNIFF |
True |
X-Content-Type-Options: nosniff |
X_FRAME_OPTIONS |
"DENY" |
Prevent framing |
CSRF_COOKIE_SECURE |
True |
HTTPS-only CSRF cookie |
SESSION_COOKIE_SECURE |
True |
HTTPS-only session cookie |
Password Validators
| Validator | Options |
|---|---|
UserAttributeSimilarityValidator |
Default |
MinimumLengthValidator |
min_length=12 |
MaximumLengthValidator |
max_length=72 (bcrypt limit) |
CommonPasswordValidator |
Default |
NumericPasswordValidator |
Default |
SpecialCharactersValidator |
min_special_characters=1 |
UppercaseValidator |
min_uppercase=1 |
LowercaseValidator |
min_lowercase=1 |
NumericValidator |
min_numeric=1 |