Skip to content

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
def __init__(self, config: SecurityConfig) -> None:
    self.config = config
    self._route_configs: dict[str, RouteConfig] = {}
    self.behavior_tracker = BehaviorTracker(config)

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
def __init__(self, config: SecurityConfig) -> None:
    self.config = config
    self._route_configs: dict[str, RouteConfig] = {}
    self.behavior_tracker = BehaviorTracker(config)

behavior_tracker = BehaviorTracker(config) instance-attribute

config = config instance-attribute

get_route_config(route_id)

Get security config for a specific route.

Source code in guard/decorators/base.py
def get_route_config(self, route_id: str) -> RouteConfig | None:
    """Get security config for a specific route."""
    return self._route_configs.get(route_id)

initialize_behavior_tracking(redis_handler=None) async

Initialize behavioral tracking with optional Redis backend.

Source code in guard/decorators/base.py
async def initialize_behavior_tracking(self, redis_handler: Any = None) -> None:
    """Initialize behavioral tracking with optional Redis backend."""
    if redis_handler:
        await self.behavior_tracker.initialize_redis(redis_handler)

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
def __init__(self) -> None:
    self.rate_limit: int | None = None
    self.rate_limit_window: int | None = None
    self.ip_whitelist: list[str] | None = None
    self.ip_blacklist: list[str] | None = None
    self.blocked_countries: list[str] | None = None
    self.allowed_countries: list[str] | None = None
    self.bypassed_checks: set[str] = set()
    self.require_https: bool = False
    self.auth_required: str | None = None
    self.custom_validators: list[Callable] = []
    self.blocked_user_agents: list[str] = []
    self.required_headers: dict[str, str] = {}
    # Behavioral analysis fields
    self.behavior_rules: list[BehaviorRule] = []
    # Additional security fields
    self.block_cloud_providers: set[str] = set()
    self.max_request_size: int | None = None
    self.allowed_content_types: list[str] | None = None
    self.time_restrictions: dict[str, str] | None = None
    self.enable_suspicious_detection: bool = True
    self.require_referrer: list[str] | None = None
    self.api_key_required: bool = False
    self.session_limits: dict[str, int] | None = None

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
def allow_countries(
    self, countries: list[str]
) -> Callable[[Callable[..., Any]], Callable[..., Any]]:
    """Only allow access from specific countries."""

    def decorator(func: Callable[..., Any]) -> Callable[..., Any]:
        route_config = self._ensure_route_config(func)
        route_config.allowed_countries = countries
        return self._apply_route_config(func)

    return decorator

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
def block_clouds(
    self, providers: list[str] | None = None
) -> Callable[[Callable[..., Any]], Callable[..., Any]]:
    """
    Block requests from cloud providers (leverages existing cloud_handler).

    Args:
        providers: List of cloud providers to block ["AWS", "GCP", "Azure"]
                  If None, blocks all supported providers

    Example:
        @guard_decorator.block_clouds(["AWS", "GCP"])  # Block AWS and GCP
        def sensitive_api():
            return {"data": "no clouds allowed"}
    """

    def decorator(func: Callable[..., Any]) -> Callable[..., Any]:
        route_config = self._ensure_route_config(func)
        if providers is None:
            route_config.block_cloud_providers = {"AWS", "GCP", "Azure"}
        else:
            route_config.block_cloud_providers = set(providers)
        return self._apply_route_config(func)

    return decorator

block_countries(countries)

Block access from specific countries.

Source code in guard/decorators/access_control.py
def block_countries(
    self, countries: list[str]
) -> Callable[[Callable[..., Any]], Callable[..., Any]]:
    """Block access from specific countries."""

    def decorator(func: Callable[..., Any]) -> Callable[..., Any]:
        route_config = self._ensure_route_config(func)
        route_config.blocked_countries = countries
        return self._apply_route_config(func)

    return decorator

bypass(checks)

Bypass specific security checks for this route.

Source code in guard/decorators/access_control.py
def bypass(
    self, checks: list[str]
) -> Callable[[Callable[..., Any]], Callable[..., Any]]:
    """Bypass specific security checks for this route."""

    def decorator(func: Callable[..., Any]) -> Callable[..., Any]:
        route_config = self._ensure_route_config(func)
        route_config.bypassed_checks.update(checks)
        return self._apply_route_config(func)

    return decorator

require_ip(whitelist=None, blacklist=None)

Require specific IP addresses or ranges.

Source code in guard/decorators/access_control.py
def require_ip(
    self,
    whitelist: list[str] | None = None,
    blacklist: list[str] | None = None,
) -> Callable[[Callable[..., Any]], Callable[..., Any]]:
    """Require specific IP addresses or ranges."""

    def decorator(func: Callable[..., Any]) -> Callable[..., Any]:
        route_config = self._ensure_route_config(func)
        if whitelist:
            route_config.ip_whitelist = whitelist
        if blacklist:
            route_config.ip_blacklist = blacklist
        return self._apply_route_config(func)

    return decorator

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
def api_key_auth(
    self, header_name: str = "X-API-Key"
) -> Callable[[Callable[..., Any]], Callable[..., Any]]:
    """
    Require API key authentication for this endpoint.

    Args:
        header_name: Name of the header containing the API key

    Example:
        @guard_decorator.api_key_auth("X-API-Key")
        def protected_endpoint():
            return {"data": "api key required"}
    """

    def decorator(func: Callable[..., Any]) -> Callable[..., Any]:
        route_config = self._ensure_route_config(func)
        route_config.api_key_required = True
        route_config.required_headers[header_name] = "required"
        return self._apply_route_config(func)

    return decorator

require_auth(type='bearer')

Require authentication for this route.

Source code in guard/decorators/authentication.py
def require_auth(
    self, type: str = "bearer"
) -> Callable[[Callable[..., Any]], Callable[..., Any]]:
    """Require authentication for this route."""

    def decorator(func: Callable[..., Any]) -> Callable[..., Any]:
        route_config = self._ensure_route_config(func)
        route_config.auth_required = type
        return self._apply_route_config(func)

    return decorator

require_headers(headers)

Require specific headers to be present.

Source code in guard/decorators/authentication.py
def require_headers(
    self, headers: dict[str, str]
) -> Callable[[Callable[..., Any]], Callable[..., Any]]:
    """Require specific headers to be present."""

    def decorator(func: Callable[..., Any]) -> Callable[..., Any]:
        route_config = self._ensure_route_config(func)
        route_config.required_headers.update(headers)
        return self._apply_route_config(func)

    return decorator

require_https()

Force HTTPS for this specific route.

Source code in guard/decorators/authentication.py
def require_https(self) -> Callable[[Callable[..., Any]], Callable[..., Any]]:
    """Force HTTPS for this specific route."""

    def decorator(func: Callable[..., Any]) -> Callable[..., Any]:
        route_config = self._ensure_route_config(func)
        route_config.require_https = True
        return self._apply_route_config(func)

    return decorator

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
def geo_rate_limit(
    self, limits: dict[str, tuple[int, int]]
) -> Callable[[Callable[..., Any]], Callable[..., Any]]:
    """
    Apply different rate limits based on country.

    Args:
        limits: Dict mapping country codes to (requests, window) tuples

    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"}
    """

    def decorator(func: Callable[..., Any]) -> Callable[..., Any]:
        # TODO: This would need integration with existing geo IP handler
        # For now, store the configuration
        route_config = self._ensure_route_config(func)
        route_config.required_headers["geo_rate_limits"] = str(limits)
        return self._apply_route_config(func)

    return decorator

rate_limit(requests, window=60)

Apply custom rate limiting to a specific route.

Source code in guard/decorators/rate_limiting.py
def rate_limit(
    self, requests: int, window: int = 60
) -> Callable[[Callable[..., Any]], Callable[..., Any]]:
    """Apply custom rate limiting to a specific route."""

    def decorator(func: Callable[..., Any]) -> Callable[..., Any]:
        route_config = self._ensure_route_config(func)
        route_config.rate_limit = requests
        route_config.rate_limit_window = window
        return self._apply_route_config(func)

    return decorator

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
def behavior_analysis(
    self, rules: list[BehaviorRule]
) -> Callable[[Callable[..., Any]], Callable[..., Any]]:
    """
    Apply multiple behavioral analysis rules to an endpoint.

    Args:
        rules: List of BehaviorRule objects defining analysis rules

    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"}
    """

    def decorator(func: Callable[..., Any]) -> Callable[..., Any]:
        route_config = self._ensure_route_config(func)
        route_config.behavior_rules.extend(rules)
        return self._apply_route_config(func)

    return decorator

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
def return_monitor(
    self,
    pattern: str,
    max_occurrences: int,
    window: int = 86400,  # 24 hours default
    action: Literal["ban", "log", "throttle", "alert"] = "ban",
) -> Callable[[Callable[..., Any]], Callable[..., Any]]:
    """
    Monitor return values and detect if same IP gets specific results too often.

    Args:
        pattern: Pattern to match in response (supports various formats)
        max_occurrences: Maximum times pattern can occur for same IP
        window: Time window in seconds (default: 24 hours)
        action: Action to take when threshold exceeded

    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"}}
    """

    def decorator(func: Callable[..., Any]) -> Callable[..., Any]:
        route_config = self._ensure_route_config(func)

        rule = BehaviorRule(
            rule_type="return_pattern",
            threshold=max_occurrences,
            window=window,
            pattern=pattern,
            action=action,
        )
        route_config.behavior_rules.append(rule)
        return self._apply_route_config(func)

    return decorator

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
def suspicious_frequency(
    self,
    max_frequency: float,  # requests per second
    window: int = 300,  # 5 minutes
    action: Literal["ban", "log", "throttle", "alert"] = "ban",
) -> Callable[[Callable[..., Any]], Callable[..., Any]]:
    """
    Detect suspiciously high frequency of requests to specific endpoint.

    Args:
        max_frequency: Maximum requests per second allowed
        window: Time window to analyze
        action: Action to take when exceeded

    Example:
        @guard_decorator.suspicious_frequency(
            max_frequency=0.1,
            window=300,
        )  # Max 1 request per 10 seconds
        def expensive_operation():
            return {"result": "computed"}
    """

    def decorator(func: Callable[..., Any]) -> Callable[..., Any]:
        route_config = self._ensure_route_config(func)
        max_calls = int(max_frequency * window)

        rule = BehaviorRule(
            rule_type="frequency",
            threshold=max_calls,
            window=window,
            action=action,
        )
        route_config.behavior_rules.append(rule)
        return self._apply_route_config(func)

    return decorator

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
def usage_monitor(
    self,
    max_calls: int,
    window: int = 3600,  # 1 hour default
    action: Literal["ban", "log", "throttle", "alert"] = "ban",
) -> Callable[[Callable[..., Any]], Callable[..., Any]]:
    """
    Monitor endpoint usage per IP and take action if threshold exceeded.

    Args:
        max_calls: Maximum number of calls allowed from same IP
        window: Time window in seconds (default: 1 hour)
        action: Action to take ("ban", "log", "throttle", "alert")

    Example:
        @guard_decorator.usage_monitor(
            max_calls=8,
            window=3600,
            action="ban",
        )
        def sensitive_endpoint():
            return {"data": "sensitive"}
    """

    def decorator(func: Callable[..., Any]) -> Callable[..., Any]:
        route_config = self._ensure_route_config(func)

        rule = BehaviorRule(
            rule_type="usage", threshold=max_calls, window=window, action=action
        )
        route_config.behavior_rules.append(rule)
        return self._apply_route_config(func)

    return decorator

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
def block_user_agents(
    self, patterns: list[str]
) -> Callable[[Callable[..., Any]], Callable[..., Any]]:
    """Block specific user agent patterns for this route."""

    def decorator(func: Callable[..., Any]) -> Callable[..., Any]:
        route_config = self._ensure_route_config(func)
        route_config.blocked_user_agents.extend(patterns)
        return self._apply_route_config(func)

    return decorator

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
def content_type_filter(
    self, allowed_types: list[str]
) -> Callable[[Callable[..., Any]], Callable[..., Any]]:
    """
    Restrict allowed content types for this endpoint.

    Args:
        allowed_types: List of allowed MIME types

    Example:
        @guard_decorator.content_type_filter(["application/json", "text/plain"])
        def api_endpoint():
            return {"message": "json or text only"}
    """

    def decorator(func: Callable[..., Any]) -> Callable[..., Any]:
        route_config = self._ensure_route_config(func)
        route_config.allowed_content_types = allowed_types
        return self._apply_route_config(func)

    return decorator

custom_validation(validator)

Add custom validation logic to this route.

Source code in guard/decorators/content_filtering.py
def custom_validation(
    self,
    validator: Callable[[Request], Awaitable[Response | None]],
) -> Callable[[Callable[..., Any]], Callable[..., Any]]:
    """Add custom validation logic to this route."""

    def decorator(func: Callable[..., Any]) -> Callable[..., Any]:
        route_config = self._ensure_route_config(func)
        route_config.custom_validators.append(validator)
        return self._apply_route_config(func)

    return decorator

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
def max_request_size(
    self, size_bytes: int
) -> Callable[[Callable[..., Any]], Callable[..., Any]]:
    """
    Limit request body size for this endpoint.

    Args:
        size_bytes: Maximum request size in bytes

    Example:
        @guard_decorator.max_request_size(1024 * 1024)  # 1MB limit
        def upload_endpoint():
            return {"status": "uploaded"}
    """

    def decorator(func: Callable[..., Any]) -> Callable[..., Any]:
        route_config = self._ensure_route_config(func)
        route_config.max_request_size = size_bytes
        return self._apply_route_config(func)

    return decorator

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
def require_referrer(
    self, allowed_domains: list[str]
) -> Callable[[Callable[..., Any]], Callable[..., Any]]:
    """
    Require requests to come from specific referrer domains.

    Args:
        allowed_domains: List of allowed referrer domains

    Example:
        @guard_decorator.require_referrer(["example.com", "app.example.com"])
        def api_endpoint():
            return {"message": "referrer validated"}
    """

    def decorator(func: Callable[..., Any]) -> Callable[..., Any]:
        route_config = self._ensure_route_config(func)
        route_config.require_referrer = allowed_domains
        return self._apply_route_config(func)

    return decorator

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
def honeypot_detection(
    self, trap_fields: list[str]
) -> Callable[[Callable[..., Any]], Callable[..., Any]]:
    """
    Detect bots using honeypot fields that humans shouldn't fill.

    Args:
        trap_fields: List of field names that should remain empty

    Example:
        @guard_decorator.honeypot_detection(["bot_trap", "hidden_field"])
        def form_endpoint():
            return {"message": "human verified"}
    """

    def decorator(func: Callable[..., Any]) -> Callable[..., Any]:
        async def honeypot_validator(request: Request) -> Response | None:
            try:
                if request.method in ["POST", "PUT", "PATCH"]:
                    # Check form data
                    if "application/x-www-form-urlencoded" in request.headers.get(
                        "content-type", ""
                    ):
                        form = await request.form()
                        for field in trap_fields:
                            if field in form and form[field]:
                                return Response("Forbidden", status_code=403)

                    # Check JSON data
                    elif "application/json" in request.headers.get(
                        "content-type", ""
                    ):
                        try:
                            json_data = await request.json()
                            for field in trap_fields:
                                if field in json_data and json_data[field]:
                                    return Response("Forbidden", status_code=403)
                        except Exception:
                            pass
            except Exception:
                pass
            return None

        route_config = self._ensure_route_config(func)
        route_config.custom_validators.append(honeypot_validator)
        return self._apply_route_config(func)

    return decorator

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
def suspicious_detection(
    self, enabled: bool = True
) -> Callable[[Callable[..., Any]], Callable[..., Any]]:
    """
    Enable/disable suspicious pattern detection (leverages sus_patterns_handler).

    Args:
        enabled: Whether to enable suspicious pattern detection

    Example:
        # NOTE: Disable for this endpoint
        @guard_decorator.suspicious_detection(enabled=False)
        def upload_endpoint():
            return {"status": "upload safe"}
    """

    def decorator(func: Callable[..., Any]) -> Callable[..., Any]:
        route_config = self._ensure_route_config(func)
        route_config.enable_suspicious_detection = enabled
        return self._apply_route_config(func)

    return decorator

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
def time_window(
    self, start_time: str, end_time: str, timezone: str = "UTC"
) -> Callable[[Callable[..., Any]], Callable[..., Any]]:
    """
    Restrict access to specific time windows.

    Args:
        start_time: Start time in HH:MM format
        end_time: End time in HH:MM format
        timezone: Timezone (default: UTC)

    Example:
        # NOTE: Business hours only
        @guard_decorator.time_window("09:00", "17:00", "UTC")
        def business_api():
            return {"message": "business hours only"}
    """

    def decorator(func: Callable[..., Any]) -> Callable[..., Any]:
        route_config = self._ensure_route_config(func)
        route_config.time_restrictions = {
            "start": start_time,
            "end": end_time,
            "timezone": timezone,
        }
        return self._apply_route_config(func)

    return decorator

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
def get_route_decorator_config(
    request: Request, decorator_handler: BaseSecurityDecorator
) -> RouteConfig | None:
    """Extract route security configuration from the current request."""
    if hasattr(request, "scope") and "route" in request.scope:
        route = request.scope["route"]
        if hasattr(route, "endpoint") and hasattr(route.endpoint, "_guard_route_id"):
            route_id = route.endpoint._guard_route_id
            return decorator_handler.get_route_config(route_id)
    return None

Extract route security configuration from the current FastAPI request.


Integration with Middleware

The decorators work in conjunction with the SecurityMiddleware to provide comprehensive protection:

  1. Route Configuration: Decorators configure route-specific settings
  2. Middleware Processing: SecurityMiddleware reads decorator configurations and applies them
  3. 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:

  1. Decorator Settings (highest priority)
  2. Global Middleware Settings
  3. Default Settings (lowest priority)

This allows for flexible override behavior where routes can customize their security requirements while maintaining global defaults.