Skip to main content

agentgate (alpha)

Layered screening and session-hijack resistance for platforms that let operators run AI agents. Python 3.9+, one dependency (cryptography). It raises the cost of misuse and of account takeover. It does not make either impossible, and it is not legal advice.

Status: alpha (v1.2.1). Tested with synthetic data, simulated attackers, a software WebAuthn authenticator, local mocks of the model API and OpenTimestamps, and one real-authenticator run (an Apple passkey on Chrome for Mac, see docs/TESTED.md). Not yet run against real traffic, a standalone hardware security key, a live model, or the Bitcoin network. It has had a self-audit (24 defects found and fixed) but no independent review yet. Read "What is NOT verified" first, then REVIEW.md if you want to help.

The idea

No single check stops a determined attacker, so each layer targets a different kind of one:

Layer Module Catches Does NOT catch
Content policy (rules + optional model grounded in a human-vetted law KB) gate, llm_classifier Clearly harmful requests; ambiguous ones go to human review Rewording; rules are a weak floor, use a model
Behaviour baselines behavior New device + odd hour, bursts, probing, topic drift, many accounts on one device A patient attacker acting like the owner
Device-bound signatures signing Stolen tokens / cookies / device IDs Malware on the owner's own device
Decoys, recon, typing rhythm tripwire Intruders who explore; scripted or injected input Attackers who touch nothing and type like a human
Transport fingerprint, ISP (ASN), geo, output destination transport, edge Scripts, headless browsers, foreign proxies, redirected output Perfect client impersonation on the owner's own ISP
WebAuthn key approval of sensitive actions approval, webauthn Token thieves and malware inside the owner's browser (cannot make the signature) A user tricked into approving a faked prompt
Hash-chained audit log + external anchoring gate, anchor Silent rewriting of history, even by whoever runs the server Anything in real time

Responses are graded: block, escalate to a human, step-up (re-verify), allow-and-log, support (crisis resources, never gated or struck). Behavioural signals never block outright, because innocent causes (new phone, VPN, travel) are common.

Install and try it

pip install agentgate-security       # PyPI name (first release pending); the import is still `agentgate`
python -m unittest discover -s tests -t .             # 145 tests
PYTHONPATH=. python examples/quickstart.py            # every layer, including a WebAuthn registration and key tap
PYTHONPATH=. python examples/webauthn_demo.py         # browser demo: open http://localhost:8765 and use your own key
PYTHONPATH=. python -m agentgate redteam              # synthetic owners vs attackers

The package installs as agentgate-security but you import it as agentgate, and it gives you the agent-gate command. From a checkout, pip install -e . does the same; or pip install cryptography (the only dependency) and use the PYTHONPATH=. prefix shown above.

CLI: screen · verify-log · anchor / verify-anchors · backtest · calibrate · review · reinstate · kb-status / kb-approve · redteam.

from agentgate import Gate, BehaviorMonitor, TransportMonitor, DestinationMonitor, HoneyTokens, \
                      DeviceRegistry, ApprovalService, build_meta

gate = Gate("audit.jsonl", "review.jsonl", monitor=BehaviorMonitor(), transport=TransportMonitor(),
            destinations=DestinationMonitor(), tripwires=HoneyTokens(),
            approvals=ApprovalService(registry, rp_id="example.com", origin="https://example.com", allow_simple=False))
meta = build_meta(request_headers, device=device_id, client_hello=raw_hello, ip=ip, lookup=geoip_lookup,
                  sensitive_action="export:hooks.acme.com", destination=webhook_url)
d = gate.screen(operator_id, text, meta=meta, approval=client_approval)
if d.action == "STEP_UP" and d.challenge:
    ...  # pass d.challenge["webauthn_challenge"] to navigator.credentials.get(), then call screen() again

See docs/DEPLOYMENT.md for the production checklist.

Measured results (synthetic, 40-50 simulated accounts; a regression baseline, not proof)

  • Owners on a normal day: 0% friction. Browser auto-update: 0%.
  • Token thief using a script or headless browser from a datacenter: stepped up 40/40.
  • Perfect impersonator on another ISP: stepped up 40/40 for sensitive actions only; 0/40 for ordinary requests.
  • Perfect impersonator on the owner's own ISP, and malware inside the owner's browser: 0/40 on every layer except the key tap. Sensitive actions need the physical key, which they cannot produce (a property of the protocol, covered by tests, not a measured detection rate).
  • Owner on a new network doing a sensitive action: re-verification (one key tap). Owner whose VPN exits abroad: re-verification unless VPN use is already in their history.
  • Output redirected to a new endpoint: held 40/40; the owner's usual endpoint allowed 40/40.
  • Decoys at 5% of resources: a hijacker touching 40 resources is caught about 88% of the time; touching 3, about 14%.

What is NOT verified

  • Almost no real authenticators. webauthn.py is tested against a spec-following software authenticator and one real run (an Apple passkey, Chrome on macOS; registration, approval, replay refusal). Not tested with standalone hardware keys, other browsers or platforms, or the FIDO conformance suite. No vendor attestation roots are bundled: attested is true only if your attestation_verifier says so. Get it reviewed, or map a maintained library's result onto enroll_webauthn.
  • No live model or network. The Anthropic adapter ran only against a local mock; OpenTimestamps only against a fake client. Real Bitcoin confirmation takes hours and was never exercised.
  • Law knowledge base is unreviewed sample text, excluded by default until a qualified human approves entries.
  • Thresholds are guesses. Run shadow mode and agent-gate calibrate on your own traffic.
  • JA3 and GeoIP are tested on a hand-built ClientHello and stubbed lookups; maxmind_lookup is untested.
  • CI (.github/workflows/ci.yml) installs the package with pip install -e . and runs the tests, the quickstart and the red-team harness on Linux with Python 3.9, 3.10, 3.11, 3.12 and 3.13, and it passes. Developed on Python 3.13; the full suite has also passed on Python 3.9 on macOS. CI is Linux-only.
  • "What you see is what you sign": WebAuthn does not show the action on the key; use a trusted UI.

OWASP Top 10 for LLM Applications (2025) mapping

agentgate sits in front of an agent (who is asking, and should this request run?). It does not inspect model internals, training data or model output. This is a self-assessment against the 2025 list, not an OWASP endorsement or an independent review.

ID Risk Coverage Where Notes
LLM01 Prompt Injection Partial gate, llm_classifier Rules run on raw and Unicode-normalised text; the optional model classifier treats the request as data inside stripped <request> tags, and rules always run too. Only screens the operator's request, not indirect injection via documents/tools the agent reads later.
LLM02 Sensitive Information Disclosure Partial transport (DestinationMonitor), tripwire, gate Holds output sent to a new destination, honey tokens flag leaked/used fake secrets, audit log stores keyed hashes not raw text. Does not scan model output for secrets or PII.
LLM03 Supply Chain Out of scope - One dependency (cryptography); no model/package provenance checks.
LLM04 Data and Model Poisoning Out of scope - No training or embedding data handled. (Behaviour baselines resist poisoning of their own state, which is a different thing.)
LLM05 Improper Output Handling Out of scope - Model output is not validated or sanitised.
LLM06 Excessive Agency Partial approval, webauthn, signing, gate Sensitive actions need a one-time, action-bound WebAuthn key approval; graded block/escalate/step-up; device-bound request signing. You must mark which actions are sensitive server-side; it does not limit tool permissions itself.
LLM07 System Prompt Leakage Out of scope -
LLM08 Vector and Embedding Weaknesses Out of scope - No RAG/vector store.
LLM09 Misinformation Out of scope - The law KB grounding limits what the classifier may cite; it does not check agent answers.
LLM10 Unbounded Consumption Partial behavior, _util Burst detection steps up rapid requesters; bounded LRU caches stop attackers growing monitor state. Not a rate limiter or token/cost budget.

Abuse via stolen sessions (the main thing agentgate targets) is not its own Top 10 entry; it overlaps LLM06 and general access control. Corrections welcome, see REVIEW.md.

  • The audit log stores hashes, not raw text. IPs and devices use a keyed hash (key in <log>.key, mode 600, or AGENT_GATE_PII_KEY); plain hashes of IPv4 addresses can be reversed in seconds. Back the key up and restrict access; whoever holds it can match a known IP against the log.
  • Behaviour profiling and fingerprinting are personal-data processing in many jurisdictions: set retention limits, document the purpose, and give users a route to contest decisions.
  • The gateway never contacts law enforcement. Referrals are human decisions made with counsel.
  • Code cannot determine legality. It enforces the policy your legal/trust team writes.

MIT licensed. See SECURITY.md to report vulnerabilities and CHANGELOG.md for history.

Metadata

Release files for agentgate-security 1.2.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for agentgate-security 1.2.1
File Size Uploaded Provenance
agentgate_security-1.2.1.tar.gz 72.8 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for agentgate-security 1.2.1
File Interpreter ABI Platform
agentgate_security-1.2.1-py3-none-any.whl Python 3 none any Details

Total release size: 129.9 kB

Release files / agentgate_security-1.2.1.tar.gz

Download URL agentgate_security-1.2.1.tar.gz
Size 72.8 kB
Tags Source
SHA-256 checksum
How to use checksums
b62c8cef441b214722b111ae490766d645b69e4bc9941ab80cfec979ccd83257
BLAKE2b-256 checksum
How to use checksums
18b387645ba72620fa1b849c4229c9fcc105386296ab55c88481323495aacc83
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.5

Release files / agentgate_security-1.2.1-py3-none-any.whl

Download URL agentgate_security-1.2.1-py3-none-any.whl
Size 57.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
60381101d1d718c792cdeb909c49b8688c497f806d9a5670ad7db79b34849820
BLAKE2b-256 checksum
How to use checksums
25ac08994a00d90229e86c9c8142f49454f66930a22beac4df879ef0a4983c99
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.5

Security for agentgate-security 1.2.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

1.2.1 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page