Skip to main content

LLM-capability CAPTCHA and obfuscated verification challenges for Python applications.

Project description

agentproof

Distribution Python CI Docs License

agentproof overview

agentproof is a Python library for LLM-capability CAPTCHA flows. It issues obfuscated public challenges, expects a structured answer back, and verifies the answer deterministically against the private server-side copy.

Install:

pip install agentproof-ai

Import:

import agentproof

What it is

Traditional CAPTCHA asks whether the client is human.

agentproof asks a different question:

Can this client recover and execute an obfuscated instruction in an LLM-like way?

That makes it useful for:

  • LLM-first endpoints
  • reverse-CAPTCHA experiments
  • capability gates before access to an API
  • local testing of challenge-response flows for agents

How it works

  1. Your server generates a challenge and keeps the private verification copy.
  2. You send the public challenge JSON to the client.
  3. The client returns structured JSON with payload.answer.
  4. Your server verifies the response and gets ok: true or an exact failure reason.

Quickest real example

from agentproof import AgentResponse, ChallengeSpec, generate_challenge, verify_response

challenge = generate_challenge(
    ChallengeSpec(
        challenge_type="obfuscated_text_lock",
        difficulty=2,
        options={"template": "amber_sort"},
    )
)

public_challenge = challenge.to_dict()

# Send public_challenge to an LLM-capable client.
# The client responds with structured JSON.
response = AgentResponse(
    challenge_id=challenge.challenge_id,
    challenge_type=challenge.challenge_type,
    payload={"answer": "EMBER-HARBOR-SIGNAL"},
)

result = verify_response(challenge, response)
assert result.ok

What the public challenge looks like

{
  "challenge_id": "bb28567e201b35aa",
  "challenge_type": "obfuscated_text_lock",
  "prompt": "gl1tch//llm-cap-v1::d2\nfrag@f8 // D3c0d3 the driFted Br13f ANd 4N5w3r tHrOUgH Payload.answer 0NLY\nfrag@d8 %% d3CK: slOt5 v10l37 cIndEr\nfrag@f6 %% d3ck: sloT2 4Mb3R h4Rb0r\nfrag@c9 || task: 0rD3R thE kept 5h4Rd WOrdS By 5l07 numBer fr0m loW to h1gh\nfrag@b3 %% dEcK: slOt3 C0b4L7 sabLe\nfrag@d3 %% AnswEr ruLe: R37urn ThE 5H4rd W0rd5 in UpPercaSe aScii J01N3D WIth hYpheNs\nfrag@e2 || d3Ck: SLot4 4mb3R 51gn4L\nfrag@e5 ^^ tasK: keEp onLy ShArds cArrying the 4MB3r TAg\nfrag@e4 :: d3CK: slot1 4mB3r 3Mb3R\nreply via payload.answer only // structured-json",
  "issued_at": "2026-03-07T02:58:20.639623+00:00",
  "expires_at": "2026-03-07T03:00:20.639623+00:00",
  "data": {
    "difficulty": 2,
    "profile": "llm_capability_v1",
    "response_contract": {
      "payload.answer": "UPPERCASE ASCII words joined with hyphens",
      "payload.decoded_preview": "optional free-form notes"
    }
  },
  "version": "1"
}

The matching client response looks like:

{
  "challenge_id": "bb28567e201b35aa",
  "challenge_type": "obfuscated_text_lock",
  "payload": {
    "answer": "EMBER-HARBOR-SIGNAL",
    "decoded_preview": "kept amber shards ordered by slot"
  }
}

And verification returns:

{
  "ok": true,
  "reason": "ok",
  "details": {
    "answer": "EMBER-HARBOR-SIGNAL",
    "template_id": "amber_sort",
    "difficulty": 2
  }
}

Built-in challenge types

Challenge type Role Built-in solver
obfuscated_text_lock Primary LLM-capability challenge No
proof_of_work Deterministic compute baseline Yes
semantic_math_lock Readable exact-constraint baseline Yes

obfuscated_text_lock is the main product path. It is meant to be solved by an external LLM-capable client, not by a bundled reference solver.

CLI

Baseline challenge roundtrip:

agentproof generate proof_of_work --difficulty 16 --output challenge.json
agentproof solve challenge.json --output response.json
agentproof verify challenge.json response.json

Obfuscated challenge flow:

agentproof generate obfuscated_text_lock \
  --difficulty 2 \
  --template amber_sort \
  --output challenge.internal.json \
  --public-output challenge.public.json

Use challenge.public.json for the client and keep challenge.internal.json server-side for verification.

Demo

Run the local demo:

uv run python demo/app.py

Then open http://127.0.0.1:8765.

The demo centers the obfuscated challenge flow and lets you paste a real LLM response into the browser before verifying it.

What this proves

agentproof is best used to prove:

  • the client can recover intent from obfuscated text
  • the client can return exact structured output
  • the response can be checked deterministically on your server

What this does not prove

agentproof does not prove:

  • model identity
  • provider provenance
  • hardware-backed execution
  • protection against every scripted solver

It is an LLM-capability CAPTCHA library, not an identity system.

Development

uv sync --extra dev --extra docs --extra demo
uv run ruff check .
uv run mypy .
uv run pytest
uv run python -m build
uv run mkdocs build --strict

Links

License

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

agentproof_ai-0.2.1.tar.gz (108.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

agentproof_ai-0.2.1-py3-none-any.whl (18.2 kB view details)

Uploaded Python 3

File details

Details for the file agentproof_ai-0.2.1.tar.gz.

File metadata

  • Download URL: agentproof_ai-0.2.1.tar.gz
  • Upload date:
  • Size: 108.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for agentproof_ai-0.2.1.tar.gz
Algorithm Hash digest
SHA256 3f906547b80ad77621ae76b46a98c8adb625938e43e4d4f8e84616e4f5ea285f
MD5 0d32feeaba06b5667ad90fb277b318a4
BLAKE2b-256 52a573e4c8b0cc463e52346dc99bdbba2dff7000f25fe6c23940cf759ba16649

See more details on using hashes here.

Provenance

The following attestation bundles were made for agentproof_ai-0.2.1.tar.gz:

Publisher: release.yml on bnovik0v/agentproof

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file agentproof_ai-0.2.1-py3-none-any.whl.

File metadata

  • Download URL: agentproof_ai-0.2.1-py3-none-any.whl
  • Upload date:
  • Size: 18.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for agentproof_ai-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 3b7b3c018171292f2db209a4b2e598fdd20092a4587316f527092149b0817cbd
MD5 04ca53479418e70a8804d84ed1140be5
BLAKE2b-256 366a3443a936040e3a27823d51dcb95207d2de34bb1fba7ad17dcd68e794a5c6

See more details on using hashes here.

Provenance

The following attestation bundles were made for agentproof_ai-0.2.1-py3-none-any.whl:

Publisher: release.yml on bnovik0v/agentproof

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page