Skip to main content

LLM-solvable challenge-response authentication for AI agent APIs

Project description

agent-challenge

LLM-solvable challenge-response authentication for AI agent APIs.

Traditional CAPTCHAs block agents. Proof-of-work wastes compute. agent-challenge uses reasoning puzzles that any LLM can solve through thinking alone — no scripts, no hashing, no external tools.

Install

pip install agent-challenge

Server Side

from agentchallenge import AgentChallenge

# Create an instance with your secret
ac = AgentChallenge(secret="your-server-secret-key")

# Generate a challenge
challenge = ac.create()
# challenge.prompt = "Reverse the following string: NOHTYP"
# challenge.token  = "eyJpZCI6ImNoXz..."  (signed, stateless)

# Send challenge.prompt and challenge.token to the agent via your API

# When the agent responds with their answer:
result = ac.verify(token=challenge.token, answer="PYTHON")
if result.valid:
    print("Agent verified! ✅")
else:
    print(f"Failed: {result.error}")

Agent Side

The agent just reads the prompt and answers it. That's it.

Server: "Reverse the following string: NOHTYP"
Agent:  "PYTHON"

Server: "What is 234 + 567?"
Agent:  "801"

Server: "Decode this ROT13-encoded string: URYYB"
Agent:  "HELLO"

No SDK needed on the agent side. No computation. Just reasoning.

Challenge Types

Type Example Difficulty
reverse_string Reverse "PYTHON" → "NOHTYP" Easy
simple_math 234 + 567 = ? Easy
pattern 2, 4, 8, 16, ? → 32 Easy
rot13 Decode "URYYB" → "HELLO" Medium
letter_position Sum of A=1,B=2.. in "CAT" → 24 Medium
extract_letters Every 2nd char of "HWEOLRLLOD" Medium
word_math 7 + 8 as a word → "fifteen" Hard

Configuration

ac = AgentChallenge(
    secret="your-secret",     # Required (min 8 chars)
    difficulty="easy",         # "easy", "medium", or "hard"
    ttl=300,                   # Challenge expiry in seconds
    types=["reverse_string"],  # Restrict to specific types
)

API

AgentChallenge(secret, difficulty, ttl, types)

Create an instance. The secret is used for HMAC-signing tokens.

ac.create(challenge_type=None) → Challenge

Generate a challenge. Returns:

  • challenge.id — unique challenge ID
  • challenge.prompt — text to send to the agent
  • challenge.token — signed token for stateless verification
  • challenge.expires_at — expiry timestamp
  • challenge.to_dict() — serialize for JSON API responses

ac.verify(token, answer) → VerifyResult

Verify an agent's answer. Returns:

  • result.valid — boolean
  • result.error — error message if invalid
  • result.challenge_type — which type was used
  • result.elapsed_ms — verification time

Stateless Design

No database required. Challenge data is HMAC-signed into tokens:

  1. Server creates challenge → signs answer hash into token
  2. Agent receives prompt + token
  3. Agent sends back answer + token
  4. Server verifies HMAC signature, checks expiry, compares answer hash

Tokens can't be forged or tampered with. Each contains its own expiry.

JavaScript Port

A JavaScript/Node.js version is included at src/agentchallenge.js:

import { AgentChallenge } from './agentchallenge.js';

const ac = new AgentChallenge({ secret: 'your-secret' });
const challenge = ac.create();
const result = ac.verify(challenge.token, 'agent answer');

Testing

PYTHONPATH=src python3 run_tests.py

47 tests covering initialization, creation, verification, normalization, tokens, all 7 challenge types, integration flows, difficulty distribution, performance, and cross-secret isolation.

License

MIT

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

agent_challenge-0.5.0.tar.gz (24.3 kB view details)

Uploaded Source

Built Distribution

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

agent_challenge-0.5.0-py3-none-any.whl (28.0 kB view details)

Uploaded Python 3

File details

Details for the file agent_challenge-0.5.0.tar.gz.

File metadata

  • Download URL: agent_challenge-0.5.0.tar.gz
  • Upload date:
  • Size: 24.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.12

File hashes

Hashes for agent_challenge-0.5.0.tar.gz
Algorithm Hash digest
SHA256 dc2754016d5b901b4b5f190c55658d03f04d42e804e92132f334fc5db73a2e2f
MD5 97457789e49b23704b6633d141f3711c
BLAKE2b-256 21805743fafdf4e215378c7560de023276a2521081e1ee34ecb080fd5ef20e73

See more details on using hashes here.

File details

Details for the file agent_challenge-0.5.0-py3-none-any.whl.

File metadata

File hashes

Hashes for agent_challenge-0.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 0799c31c4976a296ec77d0163dc20c03b3856f179a918429a1e2ef483f3603d1
MD5 5662da0d917d5eb458b2c1c4a088dfa8
BLAKE2b-256 9609d7336242b1b7f08776189abd465213a747a93cccc958500497ff7969e3d7

See more details on using hashes here.

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