DEV Community

Peace Thabiwa
Peace Thabiwa

Posted on

“TRUSTCHAIN — AI Agents That Audit Each Other 🤖📋”

Auth0 for AI Agents Challenge Submission

TRUSTCHAIN is a dashboard where multiple AI agents collaborate — and audit each other in real time. Every action (generate, test, deploy) is signed with an Auth0 identity, logged, and revocable.

Maker Agent writes code/artifacts.

Tester Agent validates outputs, security, and policy.

Deployer Agent pushes changes — only after Auth0-guarded approvals.

The result: a verifiable chain of responsibility (“who did what, when, and why”).

Demo

Live (prototype): https://trustchain-demo.vercel.app

Repo: https://github.com/sageworks-ai/trustchain

Test user: demo@trustchain.ai / Auth0Demo@123

Demo flow: Login → assign a task → Maker proposes → Tester signs/pass → human approves via CIBA → Deployer executes → Audit trail appears with JWT metadata.

How I Used Auth0 for AI Agents

Per-agent identities: Each bot (maker/tester/deployer) authenticates to the platform with its own Auth0 client/credentials.

Token Vault: Per-agent secrets (only Deployer can call CI/CD; Maker can’t).

Asynchronous Authorization (CIBA): human-in-the-loop for risky actions (prod deploys, key rotations).

FGA (optional): grant a specific Tester read access to specific repos or datasets.

Architecture

Auth: Auth0 OIDC (agent + human), Token Vault, CIBA

LLM Orchestration: LangChain agent executor

Audit Bus: append-only log (Kafka/Redis stream) → signed digests → optional on-chain anchor

UI: Next.js + audit timeline, JWT viewers

Signed Action Envelope (example)

{
"actor": "agent:tester-42",
"action": "validate_security",
"resource": "repo:org/app@commit:abc123",
"timestamp": 1730056200,
"jwt_claims": {
"sub":"auth0|agent_tester_42",
"scope":"repo:read audit:write"
},
"hash":"0xdeadbeef...",
"signature":"0x…"
}

Guarded Deploy (pseudo)

if (riskScore > 7) {
const ok = await auth0.cibaRequest({
userId, message:"Approve PROD deploy?", ttl:300
});
if(!ok) throw new Error("Human denied");
}
await tokenVault.with("ci_cd", (token)=>{
return ciClient.deploy({env:"prod", token});
});
audit.log("deploy", actor, resource, digest);

Lessons Learned

separating identity (Auth0) from intelligence (LLM) = clarity + safety.

auditability flips “black-box AI” into accountable automation.

human approvals (CIBA) are the right speed bump for real-world risk.

which one should you ship?

If you want emotional, human-first → MINDKEY will resonate hard.

If you want enterprise/security-first (and likely judge appeal) → TRUSTCHAIN has “this could run in a Fortune 500 on Monday” energy.

Honestly? You could post both (different repos), but if you can only polish one before deadline, go TRUSTCHAIN.

ultra-lean demo plan (both fit this)

Auth0: create tenant → app → Universal Login; enable email/password + Google.

Roles/Scopes:

mindkey: mem:read, mem:write, mem:share

trustchain: repo:read, ci:deploy, audit:write

Token Vault: add one external API key (e.g., GitHub PAT) to prove scoped tools.

CIBA: set up a push/email approval for “export memories” (MINDKEY) or “deploy prod” (TRUSTCHAIN).

Frontend: Next.js page with Login, an action button, and an audit timeline component.

Proof: record a 30–60s Loom showing login → action → approval → result.

minimal Next.js server stubs (drop-in)
// /lib/auth.ts
import { auth } from '@auth0/nextjs-auth0';
export const requireScope = (req, scope:string) => {
const s = auth.getSession(req);
if(!s || !s.user) throw new Error('unauthorized');
if(!s.user.permissions?.includes(scope)) throw new Error('forbidden');
return s.user;
};

// /pages/api/mindkey/read.ts
import { requireScope } from '@/lib/auth';
import { fga } from '@/lib/fga';
export default async function handler(req,res){
const user = requireScope(req,'mem:read');
const { agentId, memoryId } = req.body;
const ok = await fga.check({subject:agent:${agentId}, relation:'viewer', object:memory:${memoryId}, userId:user.sub});
if(!ok) return res.status(403).end();
const data = await vault.readEncrypted(memoryId, user.sub);
res.json({data});
}

// /pages/api/trustchain/deploy.ts
import { requireScope } from '@/lib/auth';
import { ciba, tokenVault, audit } from '@/lib/controls';
export default async function handler(req,res){
const user = requireScope(req,'ci:deploy');
const risk = Number(req.body.risk ?? 0);
if(risk > 7){
const approved = await ciba.request({ userId:user.sub, message:'Approve PROD deploy?', ttl:300 });
if(!approved) return res.status(401).json({error:'denied'});
}
const token = await tokenVault.get('ci_cd');
const result = await ci.deploy({ env:'prod', token });
await audit.append({ actor:user.sub, action:'deploy', resource:'prod', result });
res.json({ ok:true, result });
}

Top comments (0)