Security Decorators¶
The decorators module provides route-level security controls that can be applied to individual FastAPI endpoints. These decorators offer fine-grained control over security policies on a per-route basis, complementing the global middleware security features.
Overview¶
Security decorators allow you to:
- Apply specific security rules to individual routes
- Override global security settings for specific endpoints
- Combine multiple security measures in a clean, readable way
- Implement behavioral analysis and monitoring per endpoint
Main Decorator Class¶
. SecurityDecorator¶
guard.decorators.SecurityDecorator(config)
¶
Bases: BaseSecurityDecorator
, AccessControlMixin
, RateLimitingMixin
, BehavioralMixin
, AuthenticationMixin
, ContentFilteringMixin
, AdvancedMixin
Main security decorator class that combines all security decorator capabilities.
This class uses multiple inheritance to combine all decorator mixins, providing a single interface for all route-level security features.
Example
config = SecurityConfig() guard = SecurityDecorator(config)
@app.get("/api/sensitive") @guard.rate_limit(requests=5, window=300) @guard.require_ip(whitelist=["10.0.0.0/8"]) @guard.block_countries(["CN", "RU"]) def sensitive_endpoint(): return {"data": "sensitive"}
Source code in guard/decorators/base.py
The main decorator class that combines all security capabilities. This is the primary class you'll use in your application.
Example Usage:
from fastapi import FastAPI
from guard import SecurityConfig
from guard.decorators import SecurityDecorator
app = FastAPI()
config = SecurityConfig()
guard_deco = SecurityDecorator(config)
@app.get("/api/sensitive")
@guard_deco.rate_limit(requests=5, window=300)
@guard_deco.require_ip(whitelist=["10.0.0.0/8"])
@guard_deco.block_countries(["CN", "RU"])
def sensitive_endpoint():
return {"data": "sensitive"}
Base Classes¶
. BaseSecurityDecorator¶
guard.decorators.base.BaseSecurityDecorator(config)
¶
Base class for all security decorators with common functionality.
Source code in guard/decorators/base.py
Base class providing core decorator functionality and route configuration management.
. RouteConfig¶
guard.decorators.base.RouteConfig()
¶
Per-route security configuration that can override global settings.
Source code in guard/decorators/base.py
allowed_content_types = None
instance-attribute
¶
allowed_countries = None
instance-attribute
¶
api_key_required = False
instance-attribute
¶
auth_required = None
instance-attribute
¶
behavior_rules = []
instance-attribute
¶
block_cloud_providers = set()
instance-attribute
¶
blocked_countries = None
instance-attribute
¶
blocked_user_agents = []
instance-attribute
¶
bypassed_checks = set()
instance-attribute
¶
custom_validators = []
instance-attribute
¶
enable_suspicious_detection = True
instance-attribute
¶
ip_blacklist = None
instance-attribute
¶
ip_whitelist = None
instance-attribute
¶
max_request_size = None
instance-attribute
¶
rate_limit = None
instance-attribute
¶
rate_limit_window = None
instance-attribute
¶
require_https = False
instance-attribute
¶
require_referrer = None
instance-attribute
¶
required_headers = {}
instance-attribute
¶
session_limits = None
instance-attribute
¶
time_restrictions = None
instance-attribute
¶
Configuration class that stores security settings for individual routes.
Mixin Classes¶
The decorator system uses mixins to organize different types of security features:
. AccessControlMixin¶
guard.decorators.access_control.AccessControlMixin
¶
Bases: BaseSecurityMixin
Mixin for access control decorators.
allow_countries(countries)
¶
Only allow access from specific countries.
Source code in guard/decorators/access_control.py
block_clouds(providers=None)
¶
Block requests from cloud providers (leverages existing cloud_handler).
Parameters:
Name | Type | Description | Default |
---|---|---|---|
providers
|
list[str] | None
|
List of cloud providers to block ["AWS", "GCP", "Azure"] If None, blocks all supported providers |
None
|
Example
@guard_decorator.block_clouds(["AWS", "GCP"]) # Block AWS and GCP def sensitive_api(): return {"data": "no clouds allowed"}
Source code in guard/decorators/access_control.py
block_countries(countries)
¶
Block access from specific countries.
Source code in guard/decorators/access_control.py
bypass(checks)
¶
Bypass specific security checks for this route.
Source code in guard/decorators/access_control.py
require_ip(whitelist=None, blacklist=None)
¶
Require specific IP addresses or ranges.
Source code in guard/decorators/access_control.py
Provides IP-based and geographic access control decorators.
Available Decorators:
@guard_deco.require_ip(whitelist=[], blacklist=[])
- IP address filtering@guard_deco.block_countries(countries=[])
- Block specific countries@guard_deco.allow_countries(countries=[])
- Allow only specific countries@guard_deco.block_clouds(providers=[])
- Block cloud provider IPs@guard_deco.bypass(checks=[])
- Bypass specific security checks
. AuthenticationMixin¶
guard.decorators.authentication.AuthenticationMixin
¶
Bases: BaseSecurityMixin
Mixin for authentication decorators.
api_key_auth(header_name='X-API-Key')
¶
Require API key authentication for this endpoint.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
header_name
|
str
|
Name of the header containing the API key |
'X-API-Key'
|
Example
@guard_decorator.api_key_auth("X-API-Key") def protected_endpoint(): return {"data": "api key required"}
Source code in guard/decorators/authentication.py
require_auth(type='bearer')
¶
Require authentication for this route.
Source code in guard/decorators/authentication.py
require_headers(headers)
¶
Require specific headers to be present.
Source code in guard/decorators/authentication.py
require_https()
¶
Force HTTPS for this specific route.
Source code in guard/decorators/authentication.py
Provides authentication and authorization decorators.
Available Decorators:
@guard_deco.require_https()
- Force HTTPS@guard_deco.require_auth(type="bearer")
- Require authentication@guard_deco.api_key_auth(header_name="X-API-Key")
- API key authentication@guard_deco.require_headers(headers={})
- Require specific headers
. RateLimitingMixin¶
guard.decorators.rate_limiting.RateLimitingMixin
¶
Bases: BaseSecurityMixin
Mixin for rate limiting decorators.
geo_rate_limit(limits)
¶
Apply different rate limits based on country.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
limits
|
dict[str, tuple[int, int]]
|
Dict mapping country codes to (requests, window) tuples |
required |
Example
@guard_decorator.geo_rate_limit({ "US": (100, 3600), # 100 requests/hour for US "CN": (10, 3600), # 10 requests/hour for China "*": (50, 3600) # 50 requests/hour for others }) def api_endpoint(): return {"data": "geo-limited"}
Source code in guard/decorators/rate_limiting.py
rate_limit(requests, window=60)
¶
Apply custom rate limiting to a specific route.
Source code in guard/decorators/rate_limiting.py
Provides rate limiting decorators.
Available Decorators:
@guard_deco.rate_limit(requests=10, window=60)
- Basic rate limiting@guard_deco.geo_rate_limit(limits={})
- Geographic rate limiting
. BehavioralMixin¶
guard.decorators.behavioral.BehavioralMixin
¶
Bases: BaseSecurityMixin
Mixin for behavioral analysis decorators.
behavior_analysis(rules)
¶
Apply multiple behavioral analysis rules to an endpoint.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
rules
|
list[BehaviorRule]
|
List of BehaviorRule objects defining analysis rules |
required |
Example
rules = [ BehaviorRule("usage", threshold=10, window=3600), BehaviorRule( "return_pattern", threshold=3, pattern="win", window=86400, ) ] @guard_decorator.behavior_analysis(rules) def complex_endpoint(): return {"result": "data"}
Source code in guard/decorators/behavioral.py
return_monitor(pattern, max_occurrences, window=86400, action='ban')
¶
Monitor return values and detect if same IP gets specific results too often.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
pattern
|
str
|
Pattern to match in response (supports various formats) |
required |
max_occurrences
|
int
|
Maximum times pattern can occur for same IP |
required |
window
|
int
|
Time window in seconds (default: 24 hours) |
86400
|
action
|
Literal['ban', 'log', 'throttle', 'alert']
|
Action to take when threshold exceeded |
'ban'
|
Pattern formats
- Simple string: "win", "success", "rare_item"
- JSON path: "json:result.status==win"
- Regex: "regex:win|victory|success"
- Status code: "status:200"
Example
@guard_decorator.return_monitor( "win", max_occurrences=3, window=86400, action="ban", ) def lootbox_endpoint(): return {"result": {"status": "win", "item": "rare_sword"}}
Source code in guard/decorators/behavioral.py
suspicious_frequency(max_frequency, window=300, action='ban')
¶
Detect suspiciously high frequency of requests to specific endpoint.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
max_frequency
|
float
|
Maximum requests per second allowed |
required |
window
|
int
|
Time window to analyze |
300
|
action
|
Literal['ban', 'log', 'throttle', 'alert']
|
Action to take when exceeded |
'ban'
|
Example
@guard_decorator.suspicious_frequency( max_frequency=0.1, window=300, ) # Max 1 request per 10 seconds def expensive_operation(): return {"result": "computed"}
Source code in guard/decorators/behavioral.py
usage_monitor(max_calls, window=3600, action='ban')
¶
Monitor endpoint usage per IP and take action if threshold exceeded.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
max_calls
|
int
|
Maximum number of calls allowed from same IP |
required |
window
|
int
|
Time window in seconds (default: 1 hour) |
3600
|
action
|
Literal['ban', 'log', 'throttle', 'alert']
|
Action to take ("ban", "log", "throttle", "alert") |
'ban'
|
Example
@guard_decorator.usage_monitor( max_calls=8, window=3600, action="ban", ) def sensitive_endpoint(): return {"data": "sensitive"}
Source code in guard/decorators/behavioral.py
Provides behavioral analysis and monitoring decorators.
Available Decorators:
@guard_deco.usage_monitor(max_calls, window, action)
- Monitor endpoint usage@guard_deco.return_monitor(pattern, max_occurrences, window, action)
- Monitor return patterns@guard_deco.behavior_analysis(rules=[])
- Apply multiple behavioral rules@guard_deco.suspicious_frequency(max_frequency, window, action)
- Detect suspicious frequency
. ContentFilteringMixin¶
guard.decorators.content_filtering.ContentFilteringMixin
¶
Bases: BaseSecurityMixin
Mixin for content and request filtering decorators.
block_user_agents(patterns)
¶
Block specific user agent patterns for this route.
Source code in guard/decorators/content_filtering.py
content_type_filter(allowed_types)
¶
Restrict allowed content types for this endpoint.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
allowed_types
|
list[str]
|
List of allowed MIME types |
required |
Example
@guard_decorator.content_type_filter(["application/json", "text/plain"]) def api_endpoint(): return {"message": "json or text only"}
Source code in guard/decorators/content_filtering.py
custom_validation(validator)
¶
Add custom validation logic to this route.
Source code in guard/decorators/content_filtering.py
max_request_size(size_bytes)
¶
Limit request body size for this endpoint.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
size_bytes
|
int
|
Maximum request size in bytes |
required |
Example
@guard_decorator.max_request_size(1024 * 1024) # 1MB limit def upload_endpoint(): return {"status": "uploaded"}
Source code in guard/decorators/content_filtering.py
require_referrer(allowed_domains)
¶
Require requests to come from specific referrer domains.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
allowed_domains
|
list[str]
|
List of allowed referrer domains |
required |
Example
@guard_decorator.require_referrer(["example.com", "app.example.com"]) def api_endpoint(): return {"message": "referrer validated"}
Source code in guard/decorators/content_filtering.py
Provides content and request filtering decorators.
Available Decorators:
@guard_deco.block_user_agents(patterns=[])
- Block user agent patterns@guard_deco.content_type_filter(allowed_types=[])
- Filter content types@guard_deco.max_request_size(size_bytes)
- Limit request size@guard_deco.require_referrer(allowed_domains=[])
- Require specific referrers@guard_deco.custom_validation(validator)
- Add custom validation logic
. AdvancedMixin¶
guard.decorators.advanced.AdvancedMixin
¶
Bases: BaseSecurityMixin
Mixin for advanced detection decorators.
honeypot_detection(trap_fields)
¶
Detect bots using honeypot fields that humans shouldn't fill.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
trap_fields
|
list[str]
|
List of field names that should remain empty |
required |
Example
@guard_decorator.honeypot_detection(["bot_trap", "hidden_field"]) def form_endpoint(): return {"message": "human verified"}
Source code in guard/decorators/advanced.py
suspicious_detection(enabled=True)
¶
Enable/disable suspicious pattern detection (leverages sus_patterns_handler).
Parameters:
Name | Type | Description | Default |
---|---|---|---|
enabled
|
bool
|
Whether to enable suspicious pattern detection |
True
|
Example
NOTE: Disable for this endpoint¶
@guard_decorator.suspicious_detection(enabled=False) def upload_endpoint(): return {"status": "upload safe"}
Source code in guard/decorators/advanced.py
time_window(start_time, end_time, timezone='UTC')
¶
Restrict access to specific time windows.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
start_time
|
str
|
Start time in HH:MM format |
required |
end_time
|
str
|
End time in HH:MM format |
required |
timezone
|
str
|
Timezone (default: UTC) |
'UTC'
|
Example
NOTE: Business hours only¶
@guard_decorator.time_window("09:00", "17:00", "UTC") def business_api(): return {"message": "business hours only"}
Source code in guard/decorators/advanced.py
Provides advanced detection and time-based decorators.
Available Decorators:
@guard_deco.time_window(start_time, end_time, timezone)
- Time-based access control@guard_deco.suspicious_detection(enabled=True)
- Toggle suspicious pattern detection@guard_deco.honeypot_detection(trap_fields=[])
- Detect bots using honeypot fields
Utility Functions¶
. get_route_decorator_config¶
guard.decorators.base.get_route_decorator_config(request, decorator_handler)
¶
Extract route security configuration from the current request.
Source code in guard/decorators/base.py
Extract route security configuration from the current FastAPI request.
Integration with Middleware¶
The decorators work in conjunction with the SecurityMiddleware to provide comprehensive protection:
- Route Configuration: Decorators configure route-specific settings
- Middleware Processing: SecurityMiddleware reads decorator configurations and applies them
- Override Behavior: Route-specific settings can override global middleware settings
Example Integration:
from fastapi import FastAPI
from guard import SecurityMiddleware, SecurityConfig
from guard.decorators import SecurityDecorator
app = FastAPI()
config = SecurityConfig(
enable_ip_banning=True,
enable_rate_limiting=True,
rate_limit_requests=100,
rate_limit_window=3600
)
# Create decorator instance
guard_deco = SecurityDecorator(config)
# Apply decorators to routes
@guard_deco.rate_limit(requests=10, window=300) # Override: 10 requests/5min
@app.get("/api/limited")
def limited_endpoint():
# Uses decorator-specific rate limiting
return {"data": "limited"}
@app.get("/api/public")
def public_endpoint():
# Uses global rate limiting (100 requests/hour)
return {"data": "public"}
# Add global middleware
app.add_middleware(SecurityMiddleware, config=config)
# Set decorator handler on app state (required for integration)
app.state.guard_decorator = guard_deco
Best Practices¶
. Decorator Order¶
Apply decorators in logical order, with more specific restrictions first:
@app.post("/api/admin/sensitive")
@guard_deco.require_https() # Security requirement
@guard_deco.require_auth(type="bearer") # Authentication
@guard_deco.require_ip(whitelist=["10.0.0.0/8"]) # Access control
@guard_deco.rate_limit(requests=5, window=3600) # Rate limiting
@guard_deco.suspicious_detection(enabled=True) # Monitoring
def admin_endpoint():
return {"status": "admin action"}
. Combining Behavioral Analysis¶
Use multiple behavioral decorators for comprehensive monitoring:
@app.get("/api/rewards")
@guard_deco.usage_monitor(max_calls=50, window=3600, action="ban")
@guard_deco.return_monitor("rare_item", max_occurrences=3, window=86400, action="ban")
@guard_deco.suspicious_frequency(max_frequency=0.1, window=300, action="alert")
def rewards_endpoint():
return {"reward": "rare_item", "value": 1000}
. Geographic and Cloud Controls¶
Combine geographic and cloud provider controls:
@app.get("/api/restricted")
@guard_deco.allow_countries(["US", "CA", "GB"]) # Allow specific countries
@guard_deco.block_clouds(["AWS", "GCP"]) # Block cloud providers
def restricted_endpoint():
return {"data": "geo-restricted"}
. Content Filtering¶
Apply content filtering for upload endpoints:
@app.post("/api/upload")
@guard_deco.content_type_filter(["image/jpeg", "image/png"])
@guard_deco.max_request_size(5 * 1024 * 1024) # 5MB limit
@guard_deco.require_referrer(["myapp.com"])
def upload_endpoint():
return {"status": "uploaded"}
Error Handling¶
Decorators integrate with the middleware's error handling system. When decorator conditions are not met, appropriate HTTP responses are returned:
. 403 Forbidden¶
IP restrictions, country blocks, authentication failures
. 429 Too Many Requests¶
Rate limiting violations
. 400 Bad Request¶
Content type mismatches, missing headers
. 413 Payload Too Large¶
Request size limits exceeded
Configuration Priority¶
Security settings are applied in the following priority order:
- Decorator Settings (highest priority)
- Global Middleware Settings
- Default Settings (lowest priority)
This allows for flexible override behavior where routes can customize their security requirements while maintaining global defaults.