@dudousxd/nestjs-agent-authz
Adapts a @dudousxd/nestjs-authz Gate to the agent's RolesPolicy SPI, so ability-gated tools run through your app's real authz policies.
For anything richer than a role list — ownership, per-resource rules, policies — this package
delegates a tool's ability gate to a @dudousxd/nestjs-authz
Gate, while tools with no ability still fall through to the built-in role-based policy.
pnpm add @dudousxd/nestjs-agent-authz @dudousxd/nestjs-authznpm install @dudousxd/nestjs-agent-authz @dudousxd/nestjs-authzMinimal example
import { AuthzModule } from '@dudousxd/nestjs-authz';
import { AgentModule } from '@dudousxd/nestjs-agent';
import { AgentAuthzModule } from '@dudousxd/nestjs-agent-authz';
@Module({
imports: [
AuthzModule.forRoot(/* your abilities & policies */),
AgentModule.forRoot({ /* model, store, actorResolver, ... */ }),
AgentAuthzModule.forRoot(),
],
})
export class AppModule {}@AiTool({
name: 'purgeCache',
kind: 'action', // never auto-executes, waits for HITL approval
description: 'Purge a cache key.',
input: z.object({ key: z.string() }),
ability: 'cache.purge', // delegated to the authz Gate
})
export class PurgeCacheTool implements ToolHandler<{ key: string }> {
async execute(input: { key: string }) {
/* ... */
}
}AgentAuthzModule does not import AuthzModule
It injects the Gate from your app's global AuthzModule — register AuthzModule.forRoot(...)
once at the root; otherwise the Gate provider is missing and DI fails at boot.
Exports
| Export | Kind | Purpose |
|---|---|---|
AgentAuthzModule | @Global DynamicModule factory | .forRoot(options?) binds an AuthzRolesPolicy (built from the injected Gate) under the AGENT_ROLES_POLICY token the agent loop's tool gate consults |
AuthzRolesPolicy | class (RolesPolicy) | can(actor, tool) — delegates to gate.forUser(...).allows(ability) when the tool declares ability, else falls through to DefaultRolesPolicy |
AuthzRolesPolicyOptions | type | { fallbackRoles?: string[] } — roles used by the fallback DefaultRolesPolicy when a tool has neither ability nor roles (defaults to ADMIN-only) |
userFromActor(actor) | function | Maps the agent's Actor ({ id, roles? }) onto the minimal { id, roles? } shape authz's default role resolver reads — no host user entity required |
AuthzUser | type | The shape userFromActor returns / gate.forUser(...) expects |
Decision logic
- Tool declares an
ability→ decision goes to the Gate:gate.forUser(userFromActor(actor)).allows(ability). - Tool has no
ability→ falls through toDefaultRolesPolicy, matching the actor's roles against the tool'sroles(orfallbackRoles, ADMIN-only by default).
Peer dependencies
@dudousxd/nestjs-authz (~0.6.3) and @nestjs/common (^10 \|\| ^11).
When to use it
Reach for this package the moment a tool's authorization needs more than "does the actor have role
X" — ownership checks, resource-scoped policies, or any rule your app's authz layer already knows
how to evaluate. Tools that only ever need a role check don't need this package at all; the built-in
roles gate on @AiTool covers that case with zero dependencies.
Related
- Identity & Authorization — roles vs abilities, the
ActorResolver, and why there's no insecure default identity @dudousxd/nestjs-authzdocs —Gate, abilities, and policies
@dudousxd/nestjs-agent-telescope
Telescope extension that adds an "Agent" tab — live runs + tool calls off diagnostics, historical spend off the governance read-model.
@dudousxd/nestjs-agent-codegen
A @dudousxd/nestjs-codegen extension that injects a typed api.agent.* client for the agent's JSON REST routes into your generated api.ts.