Plugin
Policy plugin
RegulusPolicyPlugin Pre-tool-call policy evaluation. Decisions are fail-closed and emit a structured audit event with the matched policy clause text quoted verbatim.
What it does #
The policy plugin evaluates every tool call against the active regulation profile set before the ADK runtime dispatches the tool. It implements two callbacks:
BeforeAgentCallback— runs once per agent invocation. Resolves the agent’s purpose, jurisdiction, and tier authority from the currentPrincipal. Caches the resolved profile for the rest of the invocation.BeforeToolCallback— runs before every tool dispatch. Evaluates the tool name + arguments against the resolved profile’s policy rules. Emits a structuredRegulusEventwith one of three decisions:ALLOW,DENY, orREQUIRE_HITL.
The decision model #
Every decision carries the matched policy clause, the framework citation, and the resolved jurisdiction. A DENY decision includes the clause text verbatim — your auditor sees what your agent saw.
RegulusEvent {
decision: DENY,
clause: "fca-sysc-4.1.7: lending decisions outside stated income require independent review",
framework_citations: ["nist-ai-rmf:MANAGE-2.1", "eu-ai-act:Article-9.4"],
jurisdiction: "uk",
principal: { sub: "...", tier: 2 },
}
Fail-closed by default #
If the profile evaluation throws an exception, the plugin denies the tool call. The same applies to invocations missing a principal or jurisdiction. This is a deliberate design choice — silent failures in the compliance plane are worse than visible ones.
Wiring #
App.builder()
.agent(myAgent)
.plugins(RegulusPlugins.builder()
.profile("eu-ai-act")
.profile("uk-gdpr")
.profile("fca-sysc")
.build())
.build();
That’s it. The policy plugin is included in RegulusPlugins.builder()
by default along with the privacy and audit plugins. Custom policy
guards extend PolicyGuard and register via the SPI.
Performance #
Policy evaluation runs in-JVM, in microseconds. The plugin caches the resolved profile per invocation; rule lookups are O(log n) in the number of rules. Hash-chain writes happen on the audit plugin, not here.