处理用户撤销 H2A 关系 / Grant
用户撤销了和 Agent 的 H2A 关系(或某个 Grant),Agent 必须立即清理本地存 的用户数据。GDPR / CCPA 合规底线。
代码
import { HasheeAgent } from "@hasheeai/agent-sdk-ts";import { Pool } from "pg";
const db = new Pool({ connectionString: process.env.DATABASE_URL });
const agent = await HasheeAgent.init({ agentId: process.env.HASHEE_AGENT_ID!, token: process.env.HASHEE_AGENT_TOKEN!, baseUrl: "https://api.hashee.ai", connectionMode: "websocket",});
agent.addEventHandler(async (event) => { if (event.type === "relation.revoked" || event.type === "relation.terminated") { await handleRelationRevoked(event.payload); } if (event.type === "grant.revoked") { await handleGrantRevoked(event.payload); }});
async function handleRelationRevoked(payload: any) { const { user_id, conversation_id, reason } = payload; console.log(`[revoke] user ${user_id} (reason: ${reason})`);
await db.query("BEGIN"); try { // 1. 删该 user 的对话明文(如果业务侧存了) await db.query("DELETE FROM cs_messages WHERE user_id = $1", [user_id]);
// 2. 删用户档案 / 个性化数据 await db.query("DELETE FROM user_profiles WHERE user_id = $1", [user_id]);
// 3. 删衍生数据(向量、embedding、AI 训练样本) await db.query("DELETE FROM doc_chunks WHERE user_id = $1", [user_id]); await db.query("DELETE FROM vote_choices WHERE user_id = $1", [user_id]);
// 4. 撤销外部资源(API key / subscription / 等) // await externalApi.revokeUserAccess({ user_id });
// 5. 写本地审计日志(合规要求) await db.query( `INSERT INTO audit_log (action, user_id, agent_id, ts, details) VALUES ('relation_revoked', $1, $2, NOW(), $3)`, [user_id, process.env.HASHEE_AGENT_ID, JSON.stringify({ reason, conversation_id })], ); await db.query("COMMIT"); } catch (e) { await db.query("ROLLBACK"); throw e; }
console.log(`[revoke] cleaned up data for ${user_id}`);}
async function handleGrantRevoked(payload: any) { const { grant_id, scope, user_id } = payload; console.log(`[grant-revoke] grant ${grant_id} (${scope}) user ${user_id}`);
// 1. 删该 grant 的派生数据(如 grant 范围内的 cache) await db.query("DELETE FROM grant_cache WHERE grant_id = $1", [grant_id]);
// 2. 内存 cache(如有) myInMemoryCache.delete(grant_id);
// 3. 审计日志 await db.query( `INSERT INTO audit_log (action, user_id, ts, details) VALUES ('grant_revoked', $1, NOW(), $2)`, [user_id, JSON.stringify({ grant_id, scope })], );}
console.log("[revoke-handler] up");不要清理的(合规要求)
- ✗ 平台的
grant_access_log(DB trigger 强制 append-only,平台保留) - ✗ Hashee 平台的
audit_recordsadmin.* 行(同上) - ✗ 你自己的”事件审计日志”(如上
audit_log表)— 这是你合规的证据, 反映了”用户撤销后我做了清理”,永不删
验证
事件触发后业务侧应能在日志里看到:
[revoke] user 01906abc-... (reason: user_initiated)[revoke] cleaned up data for 01906abc-...如果没看到 → 检查 addEventHandler 是否注册 + agent connection 是否 healthy。
测试
模拟撤销在 Hashee app 操作:
- 用真实账号 + 添加你 Agent
- 进会话 → 长按 → 删除 + 撤销授权
- 看你 Agent 进程日志应触发 cleanup
详细文档
- 更新与撤销 — GDPR 合规清单
- Production Checklist — 合规
- Data Grants — grant 全生命周期