Security

Every side effect an agent can produce — writing files, running bash, pushing git — flows through a permission policy. Start from an ask or deny fallback, then list the patterns that should be allow-ed, deny-ed, or sent to the ask path. To keep a human in the loop, add a confirmation policy: ask decisions pause on a confirmation_required event so your application (or a person) can approve or reject each call. Use this whenever an agent runs against a real repository.

Node.js
Python

Add a security provider

A DefaultSecurityProvider enables input taint tracking and output sanitisation, screening tool I/O independently of the permission policy. Pass one through securityProvider (Node) / security_provider (Python); omit it to disable security entirely.

Node.js
Python
TypeScript
import { Agent, DefaultSecurityProvider } from '@a3s-lab/code';
const agent = await Agent.create('agent.acl');
const session = agent.session(process.cwd(), {
securityProvider: new DefaultSecurityProvider(),
permissionPolicy: {
allow: ['bash(echo:*)'],
ask: ['bash(*)'],
defaultDecision: 'ask',
},
});
// Privileged host operations run through the provider + policy.
const out = await session.bash('echo "screened by the security provider"');
console.log(out);
session.close();

Notes

  • defaultDecision is the fallback for any pattern not matched by allow / deny / ask (one of allow, deny, or ask). Prefer ask for real repositories and open up only what automation needs.
  • A confirmationPolicy with enabled: true is what turns ask decisions into a pausing confirmation_required event. Resolve each one with session.confirmToolUse(toolId, approved, reason?); if no answer arrives within defaultTimeoutMs, timeoutAction (reject) decides the outcome.
  • Keep release and publish actions (bash(git push*), bash(npm publish*)) on the ask or deny path unless automation owns the final step.
  • Direct host calls such as session.tool(), session.bash(), and session.git() are privileged host operations initiated by your application code. Authorize them in the host before calling the SDK; the permission policy above gates model-selected tool calls inside send, run, and stream.

A runnable confirmation loop ships at crates/code/sdk/node/examples/streaming/hitl_confirmation_loop.ts and crates/code/sdk/python/examples/hitl_confirmation_loop.py.