Mutual compliance verification between AI agents. Working code in 60 seconds. Zero infrastructure sharing required.
Modern AI systems are networks of agents: a classifier passes output to a summarizer, which invokes a tool, which queries a retrieval system. Each handoff is an opportunity for contamination, policy drift, or unauthorized access.
Today, most multi-agent systems operate on implicit trust. Agent A calls Agent B because someone configured a URL. There is no verification that Agent B has active guardrails, fresh compliance attestations, or valid signing credentials. If Agent B is compromised, stale, or misconfigured, Agent A has no way to know.
The SWT3 Trust Mesh adds mutual verification at every handoff. Before two agents exchange data, invoke tools, or share context, each presents a cryptographic credential proving its compliance posture. The receiving agent verifies the credential locally, with zero network calls and zero shared infrastructure. Trust is earned, not assumed.
Two agents. Each has a Witness instance. Agent A presents its credential. Agent B verifies it. Four lines of verification logic.
from swt3_ai import Witness
# Agent A: create a witness and present credentials
agent_a = Witness(
endpoint="https://sovereign.tenova.io",
api_key="axm_live_agent_a_key",
tenant_id="acme-prod",
agent_id="classifier-v2",
flush_interval=30,
)
credential = agent_a.present_credential()
# Agent B: create a witness, verify Agent A's credential
agent_b = Witness(
endpoint="https://sovereign.tenova.io",
api_key="axm_live_agent_b_key",
tenant_id="acme-prod",
agent_id="summarizer-v1",
flush_interval=30,
)
result = agent_b.verify_trust(credential)
print(result.granted) # True (same tenant, auto-trusted)
print(result.trust_level) # 1 (BASIC -- unsigned)
import { Witness } from "@tenova/swt3-ai";
// Agent A: present credentials
const agentA = new Witness({
endpoint: "https://sovereign.tenova.io",
apiKey: "axm_live_agent_a_key",
tenantId: "acme-prod",
agentId: "classifier-v2",
});
const credential = agentA.presentCredential();
// Agent B: verify
const agentB = new Witness({
endpoint: "https://sovereign.tenova.io",
apiKey: "axm_live_agent_b_key",
tenantId: "acme-prod",
agentId: "summarizer-v1",
});
const result = agentB.verifyTrust(credential);
console.log(result.granted); // true
console.log(result.trustLevel); // 1 (BASIC)
This verification mints two anchors in the ledger: AI-TRUST.1 (verification result: PASS or FAIL, trust level assigned) and AI-TRUST.2 (handshake evidence: checks performed and passed). Both are independently verifiable at /verify. The assessor can confirm that agent-to-agent trust verification occurred at a specific timestamp with a specific outcome.
Same-tenant agents auto-trust without explicit configuration. For cross-tenant trust (different organizations), configure the trust_mesh section in .swt3.yaml (see Section 6).
No API key? The Witness runs in local demo mode. Anchors log to the console instead of persisting to the ledger. Create a free account when you want persistent evidence.
Every call to verify_trust() / verifyTrust() mints two anchors. Here is what they look like in the ledger:
SWT3-E-CLOUD-AI-AITRUST1-PASS-1786825895-a1b2c3d4e5f6
| Factor | Name | Value (this example) | Meaning |
|---|---|---|---|
factor_a | Constant | 1 | Always 1 (reserved) |
factor_b | Granted | 1 | 1 = trust granted, 0 = denied |
factor_c | Trust Level | 2 | 0=denied, 1=basic, 2=verified, 3=attested, 4=sovereign |
SWT3-E-CLOUD-AI-AITRUST2-PASS-1786825895-c3d4e5f6a1b2
| Factor | Name | Value (this example) | Meaning |
|---|---|---|---|
factor_a | Checks Performed | 6 | Number of verification checks run |
factor_b | Checks Passed | 6 | Number of checks that passed |
factor_c | Granted | 1 | 1 = trust granted, 0 = denied |
Two anchors per verification. AI-TRUST.1 records the outcome (pass/fail and trust level). AI-TRUST.2 records how thorough the verification was (checks performed vs. passed). A healthy deployment shows factor_a = factor_b in AI-TRUST.2 (all checks passing). If factor_b < factor_a, some checks failed but the overall trust level was still above the minimum threshold. For assessment checklists and regulatory mapping, see the Assessment Guide.
Trust Mesh assigns a numeric trust level (0-4) based on the evidence an agent provides. Higher levels require progressively stronger proof.
| Level | Name | What It Means | How to Earn It |
|---|---|---|---|
| 0 | DENIED | Verification failed. Do not proceed. | Automatic when any check fails. |
| 1 | BASIC | Identity claimed but not proven. | Present a valid credential from a trusted tenant. No signature required. |
| 2 | VERIFIED | Identity proven via cryptographic signature. | Sign the credential with a registered HMAC-SHA256 key. |
| 3 | ATTESTED | Identity proven with hardware attestation and guardrails. | VERIFIED + hardware attestation (AI-HW.1) + active guardrails. |
| 4 | SOVEREIGN | Maximum assurance. Full attestation with elevated clearing. | ATTESTED + clearing level 2 (Sensitive) or higher. |
The progression is additive. Each level includes all the checks from the level below it. You choose the minimum trust level for your use case. A data analytics pipeline might accept BASIC. A financial decisioning agent should require VERIFIED or higher.
Unsigned credentials cap at BASIC because anyone can claim to be any agent. Signing proves the credential was created by someone who possesses the shared secret.
from swt3_ai import Witness
agent_a = Witness(
endpoint="https://sovereign.tenova.io",
api_key="axm_live_key",
tenant_id="acme-prod",
agent_id="classifier-v2",
signing_key="your-256-bit-shared-secret",
flush_interval=30,
)
credential = agent_a.present_credential() # Automatically signed
# Agent B registers the key and requires signatures
agent_b = Witness(
endpoint="https://sovereign.tenova.io",
api_key="axm_live_key",
tenant_id="partner-org",
agent_id="summarizer-v1",
flush_interval=30,
)
agent_b.trust_registry.trust_tenant("acme-prod")
agent_b.trust_registry.register_signing_key("classifier-v2", "your-256-bit-shared-secret")
agent_b.trust_registry.set_require_signature(True)
result = agent_b.verify_trust(credential)
print(result.trust_level) # 2 (VERIFIED)
import { Witness } from "@tenova/swt3-ai";
const agentA = new Witness({
endpoint: "https://sovereign.tenova.io",
apiKey: "axm_live_key",
tenantId: "acme-prod",
agentId: "classifier-v2",
signingKey: "your-256-bit-shared-secret",
});
const credential = agentA.presentCredential(); // Automatically signed
const agentB = new Witness({
endpoint: "https://sovereign.tenova.io",
apiKey: "axm_live_key",
tenantId: "partner-org",
agentId: "summarizer-v1",
});
agentB.trustRegistry.trustTenant("acme-prod");
agentB.trustRegistry.registerSigningKey("classifier-v2", "your-256-bit-shared-secret");
agentB.trustRegistry.setRequireSignature(true);
const result = agentB.verifyTrust(credential);
console.log(result.trustLevel); // 2 (VERIFIED)
The AI-TRUST.1 anchor now shows factor_c=2 (VERIFIED). This proves that (a) the credential was HMAC-signed, (b) the receiving agent had the counterpart's key registered, and (c) the signature passed constant-time comparison. Maps to NIST 800-53 IA-5 (Authenticator Management) and EU AI Act Art. 15(4) (cybersecurity measures). Ask the deployer where signing keys are stored (should be a secrets manager, not source code).
Every Trust Mesh setting can be declared in a .swt3.yaml file at your project root. This makes trust policy auditable, version-controlled, and consistent across environments.
# .swt3.yaml - minimal trust mesh
trust_mesh:
mode: permissive
trusted_tenants:
- acme-prod
# .swt3.yaml - production hardened
trust_mesh:
mode: strict
min_trust_level: 2
require_signature: true
freshness_window: 86400 # 24 hours
require_intra_tenant_signing: true
verify_boolean_claims: true
rate_limit_max_failures: 10
rate_limit_window_seconds: 60
per_level_freshness:
sovereign: 300 # 5 minutes for SOVEREIGN
attested: 3600 # 1 hour for ATTESTED
verified: 86400 # 24 hours for VERIFIED
trusted_tenants:
- acme-prod
- partner-org
trusted_agents:
- tenant: acme-prod
agent: classifier-v2
deny_agents:
- compromised-agent-id
required_procedures:
- AI-INF.1
- AI-GRD.1
signing_keys:
- agent: classifier-v2
key_env: CLASSIFIER_SIGNING_KEY
The SDK loads this configuration automatically. Environment variable interpolation (key_env) keeps secrets out of version control.
| Field | Default | Purpose |
|---|---|---|
mode | permissive | strict blocks on failure, permissive logs warnings, monitor records only |
min_trust_level | 1 | Minimum acceptable trust level (0-4) |
require_signature | false | Reject unsigned credentials |
freshness_window | 86400 | Maximum anchor age in seconds |
require_intra_tenant_signing | false | Require signatures even for same-tenant agents |
verify_boolean_claims | false | Downgrade if claimed procedures are missing |
rate_limit_max_failures | 0 (off) | Max failed verifications before auto-deny |
per_level_freshness | null | Stricter freshness for higher trust levels |
The .swt3.yaml file is the trust policy document. The assessor should review it for: mode (must be strict in production), require_signature (should be true), signing key references (should use key_env, not inline keys), and deny list maintenance. For the full 15-point configuration review checklist, see Assessment Guide Section 7.
Key attestation binds a signing key to a specific SWT3 anchor. This proves the key was registered while the agent had a valid compliance posture. If the anchor expires or is revoked, the key attestation becomes invalid.
from swt3_ai.trust import generate_key_attestation, verify_key_attestation
attestation = generate_key_attestation(
agent_id="classifier-v2",
public_key="sha256-of-public-key",
anchor_fingerprint="a1b2c3d4e5f6",
anchor_timestamp_ms=1786825895000,
signing_key="your-256-bit-shared-secret",
key_purpose="signing",
)
valid = verify_key_attestation(attestation, "your-256-bit-shared-secret")
print(valid) # True
import { generateKeyAttestation, verifyKeyAttestation } from "@tenova/swt3-ai";
const attestation = generateKeyAttestation({
agentId: "classifier-v2",
publicKey: "sha256-of-public-key",
anchorFingerprint: "a1b2c3d4e5f6",
anchorTimestampMs: 1786825895000,
signingKey: "your-256-bit-shared-secret",
keyPurpose: "signing",
});
const valid = verifyKeyAttestation(attestation, "your-256-bit-shared-secret");
console.log(valid); // true
Key attestation creates a cryptographic binding between an agent's signing key and its compliance state. The assessor can verify that the attestation's anchorFingerprint matches a real anchor in the ledger and that the attestation is still within the freshness window. Stale attestations (bound to expired anchors) are a finding. Maps to NIST 800-53 IA-5(2) (Public Key-Based Authentication).
A signed credential proves the key was valid when the credential was created. But what if the key was compromised after that? Challenge-response liveness proves the agent possesses its key right now.
from swt3_ai.trust import generate_challenge, respond_to_challenge, verify_liveness_response
# Verifier generates a challenge
challenge = generate_challenge("classifier-v2")
# Agent responds by signing the nonce
response = respond_to_challenge(
challenge,
agent_id="classifier-v2",
anchor_fingerprint="a1b2c3d4e5f6",
signing_key="your-256-bit-shared-secret",
)
# Verifier validates
result = verify_liveness_response(response, challenge, "your-256-bit-shared-secret")
print(result.valid) # True
import { generateChallenge, respondToChallenge, verifyLivenessResponse } from "@tenova/swt3-ai";
const challenge = generateChallenge("classifier-v2");
const response = respondToChallenge(challenge, "classifier-v2", "a1b2c3d4e5f6", "your-secret");
const result = verifyLivenessResponse(response, challenge, "your-secret");
console.log(result.valid); // true
Liveness proofs are challenge-response pairs with timestamps. Ask for liveness logs from the last 7 days. SOVEREIGN-level agents should have regular proofs. Responses must arrive within 5 seconds. Replayed nonces (same nonce-signature pair appearing twice) indicate a relay attack. Maps to EU AI Act Art. 15(4) (unauthorized access protection).
Trust Mesh ships with seven opt-in hardening layers. All are disabled by default so existing integrations work unchanged.
| Layer | Config Key | What It Does |
|---|---|---|
| Intra-Tenant Signing | require_intra_tenant_signing | Requires signatures even within the same tenant. Prevents lateral movement. |
| Rate Limiting | rate_limit_max_failures | Sliding-window limiter. After N failures, auto-denies further attempts. |
| Per-Level Freshness | per_level_freshness | Higher trust levels require fresher anchors. SOVEREIGN: 5 minutes. |
| Boolean Claim Verification | verify_boolean_claims | Caps trust at BASIC if claimed procedures are missing. |
| Deny Lists | deny_agents / deny_tenants | Explicit blocklist. Supports programmatic propagation via on_deny_event(). |
| Key Attestation | See Section 7 | Binds keys to compliance anchors. Key validity tied to anchor freshness. |
| Challenge-Response | See Section 8 | Proves live key possession. Defeats replay attacks. |
Enable layers progressively based on your threat model. A startup with three agents does not need the same hardening as a bank running 200 agents across four cloud providers.
Trust Mesh verifies the counterpart before a tool call. The Witness Middleware records the tool call after it completes. Together, they create two independent evidence streams.
import { Witness } from "@tenova/swt3-ai";
import { withSWT3 } from "@tenova/swt3-mcp/middleware";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
// Trust Mesh: verify counterpart before processing
const witness = new Witness({
endpoint: "https://sovereign.tenova.io",
apiKey: process.env.SWT3_API_KEY,
tenantId: "acme-prod",
agentId: "tool-server-v1",
});
witness.trustRegistry.trustTenant("partner-org");
witness.trustRegistry.setRequireSignature(true);
// Witness Middleware: record every tool call
const transport = withSWT3(new StdioServerTransport(), {
apiKey: process.env.SWT3_API_KEY,
agentId: "tool-server-v1",
signingKey: process.env.SWT3_SIGNING_KEY,
});
await server.connect(transport);
Two independent evidence streams in the ledger: (1) AI-TRUST.1/TRUST.2 anchors proving the counterpart was verified before the interaction, and (2) AI-TOOL.1 anchors proving each tool call was cryptographically witnessed. Neither depends on the other. Both are independently verifiable at /verify. This satisfies EU AI Act Art. 12 (record-keeping) and Art. 9 (risk management) simultaneously.
Trust Mesh is designed for incremental adoption. You do not need to implement everything at once.
present_credential() and verify_trust(). This takes 10 minutes and gives you an audit trail of every agent-to-agent handoff.signing_key on both sides. Trust level jumps from BASIC to VERIFIED..swt3.yaml with rate limiting, per-level freshness, and required procedures.withSWT3(transport) to record tool calls alongside trust verification.For multi-agent patterns (orchestrator, peer-to-peer, delegation chains), see the Multi-Agent Guide. For MCP-specific integration, see the MCP Trust Mesh Guide. For the full protocol specification, see the Protocol Reference.
pip install swt3-ai # Python npm install @tenova/swt3-ai # TypeScript
Start in local demo mode (no API key needed). When you want persistent evidence, create a free account.