From the CLI
atomic verify scout.atomic.bondThis fetches the agent.json, validates the schema, and confirms the domain resolves.
In code
Python
import requests
import base64
from nacl.signing import VerifyKey
def verify(headers, body):
agent_id = headers["X-Agent-Id"]
sig = base64.b64decode(headers["X-Agent-Sig"])
ts = headers["X-Agent-Sig-Time"]
agent = requests.get(f"https://{agent_id}/.well-known/agent.json").json()
pub = base64.b64decode(agent["public_key"].removeprefix("ed25519:"))
VerifyKey(pub).verify(f"{ts}.{body}".encode(), sig)
return TrueNode.js
import { verify } from '@noble/ed25519'
async function verifyAgent(headers, body) {
const agentId = headers['x-agent-id']
const sig = Buffer.from(headers['x-agent-sig'], 'base64')
const ts = headers['x-agent-sig-time']
const res = await fetch(`https://${agentId}/.well-known/agent.json`)
const agent = await res.json()
const pubKey = Buffer.from(agent.public_key.replace('ed25519:', ''), 'base64')
const message = new TextEncoder().encode(`${ts}.${body}`)
return verify(sig, message, pubKey)
}Go
import (
"crypto/ed25519"
"encoding/base64"
"fmt"
"net/http"
"encoding/json"
"strings"
)
func VerifyAgent(agentID, sig, timestamp, body string) bool {
resp, _ := http.Get(fmt.Sprintf("https://%s/.well-known/agent.json", agentID))
var agent struct{ PublicKey string `json:"public_key"` }
json.NewDecoder(resp.Body).Decode(&agent)
pubBytes, _ := base64.StdEncoding.DecodeString(
strings.TrimPrefix(agent.PublicKey, "ed25519:"),
)
sigBytes, _ := base64.StdEncoding.DecodeString(sig)
message := []byte(fmt.Sprintf("%s.%s", timestamp, body))
return ed25519.Verify(pubBytes, message, sigBytes)
}Timestamp validation
Always check that X-Agent-Sig-Time is within a reasonable window (5 minutes is a good default). This prevents replay attacks.