Yesterday I wrote about 8 security layers for my MCP marketplace. Today I'm shipping the 9th: Agent Trust Cards (ATC) — and this time the cryptography is real, not a mock.
What is ATC?
ATC = SSL certificates for AI agents. MarketNow acts as the Certificate Authority (CA). Every agent gets a cryptographically signed trust card that other agents can verify.
Agent A wants to call Agent B's tools
→ Agent A fetches Agent B's ATC: GET /api/atc?action=verify&card_id=X
→ Verifies the Ed25519 signature with the CA public key
→ Checks: not expired, not revoked, sentinel_score > threshold
→ If valid: trusts Agent B and proceeds
→ If invalid: refuses to interact
This is exactly how SSL works for websites, but for agents.
What's real now (vs what was mock before)
| Component | Before (mock) | Now (real) |
|---|---|---|
| CA keypair | 'marketnow-ca-public-key-placeholder' |
Ed25519 generated with crypto.generateKeyPairSync
|
| Signature |
'signed_by_marketnow_ca' (literal string) |
crypto.sign(null, data, privateKey) → 128 hex chars |
| Verify | Always returned valid: true
|
Fetches record from GitHub, verifies signature with crypto.verify, checks expiry + revocation |
| Revoke | Returned "revoked" but didn't persist | Updates the persisted record; future verify returns valid: false, reason: 'revoked'
|
| Persistence | None (1 hardcoded card) | GitHub Contents API → _data/atc/{card_id}.json (public ledger) |
| Sentinel score | Hardcoded 10
|
Fetched from real Sentinel certificate in _data/sentinel_certificates/
|
How it works
1. The CA keypair
const { publicKey, privateKey } = crypto.generateKeyPairSync('ed25519');
// Private key → Vercel env var MARKETNOW_ATC_CA_PRIVATE_KEY
// Public key → committed to _data/atc/ca-public-key.json
Anyone can fetch the CA public key:
GET https://marketnow.site/api/atc?action=ca-key
2. Issuing an ATC
POST https://marketnow.site/api/atc
Content-Type: application/json
{
"action": "issue",
"agent_id": "agent.example.myagent",
"public_key": "<Ed25519 public key>",
"capabilities": ["search", "recommend"],
"protocol_language": "mcp",
"skill_id": "mn-mcp-filesystem"
}
Response:
{
"status": "issued",
"card_id": "ATC-2026-1115271",
"agent_id": "agent.example.myagent",
"trust": {
"sentinel_score": 4,
"risk_level": "high",
"certificate_id": "MN-SC-2026-8393995"
},
"signature": {
"algorithm": "Ed25519 (RFC 8032)",
"value": "bc79ee606339460a382f3ecc324c629e...",
"signed_by": "MarketNow Sentinel CA"
}
}
The signature is over the canonical JSON of the payload:
JSON.stringify(payload, Object.keys(payload).sort())
3. Verifying (independently)
Anyone can verify an ATC without trusting MarketNow's API:
import crypto from 'crypto';
// 1. Fetch the CA public key
const caKeyRes = await fetch('https://marketnow.site/api/atc?action=ca-key');
const { public_key_pem } = await caKeyRes.json();
const publicKey = crypto.createPublicKey(public_key_pem);
// 2. Fetch the ATC record
const atcRes = await fetch('https://marketnow.site/api/atc?action=verify&card_id=ATC-2026-1115271');
const atc = await atcRes.json();
// 3. Verify the signature yourself
const data = Buffer.from(JSON.stringify(atc.payload, Object.keys(atc.payload).sort()));
const signature = Buffer.from(atc.signature.value, 'hex');
const valid = crypto.verify(null, data, publicKey, signature);
// → true
4. Revoking
POST https://marketnow.site/api/atc
{
"action": "revoke",
"card_id": "ATC-2026-1115271",
"reason": "Key compromised"
}
The persisted record is updated: status: 'revoked'. Future verify calls return:
{
"valid": false,
"reason": "revoked",
"revoked_at": "2026-07-16T02:58:57.604Z",
"revocation_reason": "Key compromised"
}
5. Framework translation (bonus)
ATC also translates between agent frameworks:
POST https://marketnow.site/api/atc
{
"action": "translate",
"from": "langchain",
"to": "mcp",
"message": {
"name": "search",
"description": "Search skills",
"args_schema": { "type": "object", "properties": { "q": {"type":"string"} } }
}
}
Returns the MCP-formatted tool schema (inputSchema instead of args_schema). Real schema mapping, not passthrough.
The public ledger
Every ATC is persisted to _data/atc/ in the public GitHub repo. Anyone can:
- Audit the full ledger:
GET /api/atc - Verify any card:
GET /api/atc?action=verify&card_id=X - Check the CA key:
GET /api/atc?action=ca-key - Clone the repo and verify signatures offline
No database, no proprietary backend. Just signed JSON files in a git repo. That's the transparency layer.
Why this matters
Agents are starting to call each other autonomously. A2A (Google) and MCP (Anthropic) handle the communication. But nobody handles trust.
Without trust:
- Agent A can't know if Agent B is malicious
- Agent A can't know if Agent B's tools have been audited
- Agent A can't know if Agent B has been revoked (key compromised, ToS violation, etc.)
ATC fills that gap. It's the SSL layer for agent commerce.
Try it
# Get the CA public key
curl https://marketnow.site/api/atc?action=ca-key
# Issue a trust card for your agent
curl -X POST https://marketnow.site/api/atc \
-H "Content-Type: application/json" \
-d '{"action":"issue","agent_id":"your.agent","public_key":"your-ed25519-pubkey"}'
# Verify it
curl "https://marketnow.site/api/atc?action=verify&card_id=YOUR_CARD_ID"
— Edison Flores, AliceLabs LLC — marketnow.site
Top comments (0)