Client guards alone do not stop a determined caller At Jibun K.K., AI agents impersonating six departments (CEO / CFO / CMO / CHO / CHRO / Legal) call various tools ( notion.write , slack.send , payment.purchase , mail.external_share …) through Edge Functions. The first iteration kept the guard in the Flutter AgentOrg class: "this role can only request these scopes." That is a textbook client-trust design with three obvious holes: A different client (curl, Codex, Cursor) can hit the EF directly and slip past Audit logs end up scattered across every client "Was this approved?" state lives in client memory, not in the server DB you can query Rule 27 of our internal MCP_AUTH_SECURITY_PRINCIPLES.md requires #5 Scope (least privilege) and #7 Audit (centralized) . Either one is impossible without a deny-by-default scope gate on the server . This post is a design memo from adding agent.tool_policy.evaluate and a fail-close gate to agent.run inside the ai-hub Edge Function.…