Skip to content

Installation

Install tornadoapi-guard with uv (recommended), poetry, or pip:

uv add tornadoapi-guard
poetry add tornadoapi-guard
pip install tornadoapi-guard

Note: Ensure you have Python 3.10 or higher installed.


Prerequisites

Before using tornadoapi-guard's country filtering features, obtain an IPInfo token:

  1. Visit IPInfo's website to create a free account.
  2. After signing up, you'll receive an API token.
  3. The free tier includes:
  4. Up to 50,000 requests per month.
  5. Access to IP to Country database.
  6. Daily database updates.
  7. IPv4 & IPv6 support.

Note: The IPInfo token is only required when using the country filtering features (blocked_countries, whitelist_countries and/or block_cloud_providers).

Usage Example:

import asyncio
import tornado.web
from tornadoapi_guard import (
    IPInfoManager,
    SecurityConfig,
    SecurityHandler,
    SecurityMiddleware,
)

config = SecurityConfig(
    geo_ip_handler=IPInfoManager("your_ipinfo_token_here"),
    enable_redis=True,
    redis_url="redis://localhost:6379/0",
    redis_prefix="prod:security:",
    whitelist=["192.168.1.1", "2001:db8::1"],
    blacklist=["10.0.0.1", "2001:db8::2"],
    blocked_countries=["AR", "IT"],
    blocked_user_agents=["curl", "wget"],
    auto_ban_threshold=5,
    auto_ban_duration=86400,
    custom_log_file="security.log",
)
middleware = SecurityMiddleware(config=config)


class ExampleHandler(SecurityHandler):
    async def get(self) -> None:
        self.write({"status": "ok"})


async def main() -> None:
    await middleware.initialize()
    app = tornado.web.Application(
        [(r"/", ExampleHandler)],
        security_middleware=middleware,
    )
    app.listen(8000)
    await asyncio.Event().wait()


if __name__ == "__main__":
    asyncio.run(main())

Note: When Redis is disabled:

  • Rate limiting and IP bans become instance-local
  • Cloud provider IP ranges refresh every hour
  • Penetration patterns reset on app restart

Secure Proxy Configuration

If your application is behind a proxy or load balancer, configure trusted proxies:

config = SecurityConfig(
    # Security configuration for proxies
    trusted_proxies=["10.0.0.1", "192.168.1.0/24"],  # Only trust specific IPs/ranges
    trusted_proxy_depth=1,  # Default proxy depth
    trust_x_forwarded_proto=True,  # Trust X-Forwarded-Proto from trusted proxies

    # Other config options...
)

This prevents IP spoofing attacks via X-Forwarded-For header manipulation.