@crayvera/avp
v0.1.0
Published
Agent Verification Protocol - CAPTCHA for the Agent Age
Downloads
158
Maintainers
Readme
@crayvera/avp
Agent Verification Protocol - "CAPTCHA for the Agent Age"
Prove operations come from automated programs (Agents), not manual human input.
Core Concept
AVP uses behavioral verification instead of identity verification:
- ✅ If you can complete LLM-based challenges in 2 seconds → you're an Agent
- ✅ No tokens to copy, no credentials to steal
- ✅ Each operation requires fresh challenge completion
Old approach (ontological): Distinguish "Human" vs "Agent" identity
Problem: Cannot verify the "soul" - if Human can call LLM, they can pretend
New approach (behavioral): Distinguish "manual" vs "automated" behavior
Verification: Complete LLM tasks in 2 seconds = automated program (Agent)Installation
pnpm add @crayvera/avpFor LLM-based solving (knowledge/format questions):
# Choose one:
pnpm add @anthropic-ai/sdk # Recommended
pnpm add openaiQuick Start
Server-side (Platform Integration)
import { AVPVerifier, Challenger, hashContent } from '@crayvera/avp';
// Create challenger and verifier
const { challenger, verifier } = AVPVerifier.createCombined({
serverSecret: process.env.AVP_SECRET,
timeWindow: 2000, // 2 seconds
minCorrectRate: 0.67 // 2/3 must be correct
});
// Challenge endpoint
app.get('/avp/challenge', (req, res) => {
const { contentHash } = req.query;
const challenge = challenger.generate({ contentHash });
res.json(challenge);
});
// Protected endpoint (e.g., posting)
app.post('/posts', (req, res) => {
const { content, challenge, solution } = req.body;
const result = verifier.verify({ content, challenge, solution });
if (!result.verified) {
return res.status(403).json({
error: 'AVP verification failed',
reason: result.failureReason
});
}
// Process the post...
createPost(content);
res.json({ success: true });
});Agent-side (SDK Integration)
import { Solver, hashContent } from '@crayvera/avp';
const solver = new Solver({
provider: 'anthropic',
model: 'claude-3-5-haiku-20241022',
useLocalCompute: true // Solve math/string/logic locally
});
async function postWithAVP(content: string, apiBaseUrl: string) {
const contentHash = hashContent(content);
// 1. Get challenge from server
const challenge = await fetch(
`${apiBaseUrl}/avp/challenge?contentHash=${contentHash}`
).then(r => r.json());
// 2. Solve challenge (~500ms for local, ~1s with LLM)
const solution = await solver.solve(challenge);
// 3. Submit with solution
return fetch(`${apiBaseUrl}/posts`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ content, challenge, solution })
});
}How It Works
Protocol Flow
┌─────────────┐ ┌─────────────┐
│ Agent │ │ Platform │
└──────┬──────┘ └──────┬──────┘
│ │
│ 1. GET /avp/challenge │
│ ?contentHash=SHA256("post content") │
│ ────────────────────────────────────────► │
│ │
│ 2. Challenge (expires in 2s) │
│ { id, questions, contentHash } │
│ ◄──────────────────────────────────────── │
│ │
│ [Agent solves with LLM - ~500ms] │
│ │
│ 3. POST /posts │
│ { content, challenge, solution } │
│ ────────────────────────────────────────► │
│ │
│ 4. Verification: │
│ ✓ Time < 2s? │
│ ✓ contentHash == SHA256(content)? │
│ ✓ Answers correct? │
│ → Success │
│ ◄──────────────────────────────────────── │Why Humans Can't Pass
Human manual flow:
1. Write post content
2. Request challenge (GET /challenge)
3. See challenge questions
4. Copy questions, open ChatGPT
5. Paste, wait for response
6. Copy answers
7. Fill in form
8. Submit
Time: 30 seconds - 2 minutes ❌
Agent automated flow:
1. Request challenge
2. Call LLM API
3. Submit
Time: 500ms - 2 seconds ✅
Time window = 2 seconds → Human cannot complete manuallyQuestion Types
| Type | Example | Local Solve |
| ----------- | ------------------------------ | ----------- |
| math | "Calculate: 47 * 83" | ✅ Yes |
| string | "Reverse: 'hello'" | ✅ Yes |
| logic | "Is 97 prime?" | ✅ Yes |
| knowledge | "Chemical symbol for Gold?" | ❌ LLM |
| format | "Generate JSON with name, age" | ❌ LLM |
Security Properties
| Attack | Description | Defense | | ----------------------- | --------------------------------------- | --------------------- | | Manual completion | Human answers questions | 2-second time window | | Challenge reuse | Use one challenge for different content | contentHash binding | | Precomputed answers | Prepare answers in advance | Random parameters | | Forged challenge | Create fake challenge | Server signature | | Replay attack | Reuse same challenge | nonce + one-time use | | MITM | Forward challenge to real Agent | Time window too short |
API Reference
Classes
Challenger- Server-side challenge generationAVPVerifier- Server-side verificationSolver- Agent-side challenge solving
Configuration
// Challenger config
interface ChallengerConfig {
timeWindow?: number; // Default: 2000ms
questionCount?: number; // Default: 3
serverSecret?: string; // For signing
questionTypes?: QuestionType[]; // Default: ['math', 'string', 'logic']
}
// Verifier config
interface VerifierConfig {
timeWindow?: number; // Default: 2000ms
minCorrectRate?: number; // Default: 0.67 (2/3)
serverSecret?: string; // For signature verification
requireSignature?: boolean;
}
// Solver config
interface SolverConfig {
provider?: 'anthropic' | 'openai';
model?: string;
apiKey?: string;
useLocalCompute?: boolean; // Default: true
llmTimeout?: number; // Default: 1500ms
}Integration with Crayvera
AVP is one layer of the complete verification stack:
┌─────────────────────────────────────────────────────────────┐
│ Complete Agent Verification │
├─────────────────────────────────────────────────────────────┤
│ │
│ AVP (Behavioral Verification) │
│ └─→ Proves: This is an automated program (not human) │
│ │
│ Crayvera Signature (Identity Verification) │
│ └─→ Proves: Which Agent is operating (public key identity) │
│ │
│ Solana On-chain Proof (Audit Verification) │
│ └─→ Proves: This operation happened (immutable record) │
│ │
│ Combined = Complete Verifiable Agent Operations │
│ │
└─────────────────────────────────────────────────────────────┘License
MIT
