Skip to content

Fail-closed Tor session enforcement for Python HTTP(S) traffic

License

Notifications You must be signed in to change notification settings

ProtoXCode/ProtoX-GateKeeper

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

13 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PyPI version Python versions License

ProtoX GateKeeper

ProtoX GateKeeper is a small, opinionated Python library that enforces fail-closed Tor routing for HTTP(S) traffic.

The goal is simple:

If Tor is not active and verified, nothing runs.

GateKeeper is designed to be fire-and-forget: create a client once, then perform network operations with a hard guarantee that traffic exits through the Tor network.


What GateKeeper Is

  • A Tor-verified HTTP client
  • A thin wrapper around requests.Session with safe helpers
  • Fail-closed by default (no silent clearnet fallback)
  • Observable (exit IP, optional geo info)
  • Suitable for scripts, tooling, and automation

What GateKeeper Is NOT

  • ❌ A Tor controller
  • ❌ A crawler or scanner
  • ❌ An anonymization silver bullet
  • ❌ A replacement for Tor Browser

GateKeeper enforces transport routing only. You are still responsible for what you do with it.


Requirements

  • A locally running Tor client
  • SOCKS proxy enabled (default: 127.0.0.1:9150)

On Windows this usually means Tor Browser running in the background.


Installation

From PyPI

pip install protox-gatekeeper

From source (development)

pip install -e .

(Recommended while developing or testing.)


Basic Usage

import logging
from protox_gatekeeper import GateKeeper

logging.basicConfig(
    level=logging.INFO,
    format='[%(levelname)s] %(name)s - %(message)s'
)

gk = GateKeeper(geo=True)

gk.download(
    "https://httpbin.org/bytes/1024",
    "downloads/test.bin"
)

Example output

[INFO] gatekeeper.core - Tor verified: 89.xxx.xxx.xxx -> 185.xxx.xxx.xxx
[INFO] gatekeeper.core - Tor exit location: Brandenburg, DE
[INFO] gatekeeper.core - [Tor 185.xxx.xxx.xxx] downloading https://httpbin.org/bytes/1024 -> downloads/test.bin

This confirms:

  • clearnet IP was measured
  • Tor routing was verified
  • all traffic used the Tor exit shown

HTTP requests

GateKeeper can also be used as a Tor-verified HTTP client:

with GateKeeper() as gk:
    response = gk.get("https://httpbin.org/ip")
    print(response.json())

All requests are guaranteed to use the verified Tor session.


API Overview

GateKeeper(...)

gk = GateKeeper(
    socks_port=9150,
    geo=False
)

Parameters:

  • socks_port (int) – Tor SOCKS port (default: 9150)
  • geo (bool) – Enable best-effort Tor exit geolocation (optional)

Raises RuntimeError if Tor routing cannot be verified.


request(method, url, **kwargs)

Performs an arbitrary HTTP request through the verified Tor session.

This is a thin passthrough to requests.Session.request, with enforced Tor routing and logging.

r = gk.request(
    "GET",
    "https://httpbin.org/ip",
    timeout=10
)
print(r.json())
  • method – HTTP verb (GET, POST, PUT, DELETE, ...)
  • url – Target URL
  • **kwargs – Forwarded directly to requests

This is the core execution path used internally by helper methods like get() and post().


download(url, target_path)

Downloads a resource through the verified Tor session.

gk.download(url, target_path)
  • url – HTTP(S) URL
  • target_path – Full local file path (directories created automatically)

download(url, target_path)

Downloads a resource through the verified Tor session.

gk.download(url, target_path)
  • url – HTTP(S) URL
  • target_path – Full local file path (directories created automatically)

get(url, **kwargs)

Performs a Tor-verified HTTP GET request.

response = gk.get(url, timeout=10)

Returns a standard requests.Response.


post(url, data=None, json=None, **kwargs)

Performs a Tor-verified HTTP POST request.

response = gk.post(url, json={"key": "value"})

Returns a standard requests.Response.


Design Principles

  • Fail closed: no Tor → no execution
  • Single verification point (during construction)
  • No global state
  • No logging configuration inside the library
  • Session reuse without re-verification

Logging is emitted by the library, but configured by the application.


Logging

GateKeeper uses standard Python logging:

import logging
logging.basicConfig(level=logging.INFO)

The library does not call logging.basicConfig() internally.


Security Notes

  • Tor exit IPs may rotate over time
  • Geo information is best-effort and may be unavailable (rate-limits, CAPTCHAs)
  • GateKeeper guarantees routing, not anonymity

TLS Verification

All request methods forward arguments directly to requests. If you need to interact with legacy systems that have expired or self-signed certificates, you may disable TLS verification per request:

r = gk.request(
    "GET",
    "https://legacy.example.com",
    verify=False
)

Or for downloads:

gk.download(url, "file.bin", verify=False)

Disabling certificate verification reduces transport security and should only be used when necessary.


License

MIT License


Status

  • Version: v0.2.4
  • Phase 2 in progress
  • API intentionally minimal

Future versions may add optional features such as:

  • circuit rotation
  • ControlPort support
  • higher-level request helpers

Without breaking the core contract.

About

Fail-closed Tor session enforcement for Python HTTP(S) traffic

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages