scopeblind-agent
v1.1.3
Published
DPoP agent identity SDK for ScopeBlind. Adds proof-of-possession headers to agent, CLI, and MCP requests.
Maintainers
Readme
scopeblind-agent
Cryptographic device identity for AI agents, CLIs, and MCP tool servers.
Uses DPoP (RFC 9449) to create proof-of-possession for each request. The agent generates an ES256 key pair on first use and stores it locally. Each request includes a self-signed JWT proof that binds it to the agent's key — no CAPTCHAs, no browser, no account.
Install
npm install scopeblind-agentQuick Start
import { createAgent } from 'scopeblind-agent';
const agent = await createAgent();
console.log('Agent device ID:', agent.deviceId);
// Fetch wrapper — DPoP proof attached automatically
const res = await agent.fetch('https://api.example.com/endpoint', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ prompt: 'Hello' }),
});How It Works
- On first call,
createAgent()generates a persistent ES256 key pair and stores it in.scopeblind/agent-key.json - Every request gets a self-signed DPoP JWT proof containing the HTTP method, URL, timestamp, and nonce
- The server running ScopeBlind middleware verifies the proof and identifies the agent by the SHA-256 hash of its public key
- Abusive agents are caught by key hash — IP rotation doesn't help
API
createAgent(options?): Promise<ScopeBlindAgent>
Creates a ScopeBlind agent instance.
Options:
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| keyPath | string | .scopeblind/agent-key.json | Path to store the key pair |
| jwk | object | — | Existing JWK key pair (for serverless/in-memory) |
Returns a ScopeBlindAgent with:
| Property/Method | Type | Description |
|----------------|------|-------------|
| deviceId | string | SHA-256 hash of public key (16 hex chars) |
| publicKey | JWK | The agent's public key |
| createProof(method, url) | string | Create a DPoP proof JWT |
| headers(method, url, extra?) | Record<string, string> | Get headers with DPoP proof |
| fetch(url, init?) | Promise<Response> | Fetch wrapper with automatic proof |
Usage Patterns
With your own HTTP client
const agent = await createAgent();
// Get headers to attach to any HTTP client
const headers = agent.headers('POST', 'https://api.example.com/data');
await axios.post('https://api.example.com/data', payload, { headers });In-memory keys (serverless)
const agent = await createAgent({
jwk: {
publicKey: { kty: 'EC', crv: 'P-256', x: '...', y: '...' },
privateKey: { kty: 'EC', crv: 'P-256', x: '...', y: '...', d: '...' },
},
});MCP Tool Server
import { createAgent } from 'scopeblind-agent';
const agent = await createAgent({ keyPath: '.scopeblind/mcp-key.json' });
// Every tool call includes DPoP proof
async function callProtectedAPI(url: string, body: object) {
return agent.fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body),
});
}CLI
# Initialize agent identity
npx scopeblind-agent init
# Show agent status and device ID
npx scopeblind-agent status
# JSON output for scripts
npx scopeblind-agent status --jsonServer-Side Verification
The ScopeBlind middleware automatically verifies DPoP proofs:
import { scopeblind, scopeblindDPoP } from 'scopeblind';
scopeblindDPoP(app, { slug: 'YOUR_SLUG' });
app.post('/api/data', scopeblind(), (req, res) => {
// req.scopeblind.dpopVerified → true if valid proof
// req.scopeblind.dpopDeviceId → stable key hash
});Zero Dependencies
The agent SDK has zero runtime dependencies. It uses only Node.js built-in crypto and fs modules.
Requirements
- Node.js >= 18.0.0
Standards
- RFC 9449 — DPoP (Demonstrating Proof-of-Possession)
- ES256 (ECDSA on P-256) for key generation and signing
- SHA-256 for device ID derivation
License
FSL-1.1-MIT — converts to full MIT after 2 years.
Links
- ScopeBlind — Agent-safe access control for public APIs
- Documentation
- GitHub
