Back to KB
Difficulty
Intermediate
Read Time
9 min

Building a Secure AI Agent Harness for a Bank: From Architecture to Working Code

By Codcompass TeamΒ·Β·9 min read

Engineering Deterministic Control Planes for Enterprise LLM Agents: A Policy-Driven Implementation Guide

Current Situation Analysis

Financial institutions and regulated enterprises are rapidly integrating Large Language Models (LLMs) into operational workflows. The industry faces a critical disconnect: LLMs are probabilistic reasoning engines, while enterprise security requires deterministic, auditable control.

The prevailing misconception is that system prompts and instruction tuning provide sufficient guardrails. In regulated environments, this is a fatal flaw. System prompts are advisory; they can be overridden by model drift, context window manipulation, or sophisticated jailbreak techniques. When an AI agent interacts with infrastructure, identity stores, or financial data, "advisory" controls are unacceptable.

The core pain point is authorization leakage. An agent acting on behalf of a user must not inherit the user's full privileges. Instead, the agent requires a constrained execution envelope defined by policy, not by the model's interpretation of instructions. Without a hard policy layer, organizations risk:

  • Privilege Escalation: Agents performing write operations beyond the user's intent.
  • Data Exfiltration: Agents retrieving sensitive records via indirect tool chaining.
  • Audit Gaps: Inability to reconstruct why a specific tool was invoked or output generated.

Data from enterprise AI deployments indicates that incidents involving unauthorized tool usage often stem from the absence of a runtime policy enforcement point. The solution is not better prompting; it is a Deterministic Control Plane that sits between the model and the tools, enforcing identity, least privilege, and auditability through code.

WOW Moment: Key Findings

The distinction between prompt-based control and policy-gateway control is not incremental; it is architectural. The following comparison highlights why a policy-driven approach is mandatory for production-grade agents in regulated sectors.

Control MechanismEnforcement PointBypass ResistanceAudit GranularityKill-Switch Latency
System PromptsModel InferenceLow (Jailbreak/Drift)NoneHigh (Requires retraining)
RBAC on ToolsAPI GatewayMedium (Context Blind)User-LevelMedium
Policy Control PlaneRuntime CodeHigh (Deterministic)Tool/Decision-LevelNear-Zero

Why this matters: A Policy Control Plane decouples authorization logic from the model. It enables security teams to revoke access, enforce device posture checks, and require approvals without modifying the model or the application code. It transforms the agent from a "black box" into a verifiable process where every tool invocation is a policy-evaluated event.

Core Solution

We will implement a Policy-First Control Plane using TypeScript. This stack provides strong typing for policy schemas, robust async I/O handling for tool orchestration, and a ecosystem rich with validation libraries. The architecture follows a pipeline pattern:

Request β†’ Identity Resolver β†’ Policy Evaluator β†’ Tool Executor β†’ Output Sanitizer β†’ Audit Sink

Architecture Decisions

  1. Separation of Policy Definition and Enforcement: Policies are defined in a declarative schema (YAML/JSON) and loaded into a runtime engine. This allows security teams to update rules without developer intervention.
  2. Deterministic Evaluation: The PolicyEvaluator returns a Verdict object. The agent cannot proceed unless the verdict is ALLOWED. This removes ambiguity.
  3. Output Sanitization: Tool responses are sanitized before reaching the LLM context window to prevent data leakage and prompt injection via tool outputs.
  4. Immutable Audit Trail: Every decision, including denials, is logged with a trace ID for forensic analysis.

Implementation

We use fastify for the gateway service and zod for runtime schema validation.

1. Define Policy Schema and Models

import { z } from 'zod';

// Policy Schema Definition
const PolicySchema = z.object({
  version: z.string(),
  kill_switch: z.object({
    global_read_only: z.boolean(),
    disabled_tools: z.array(z.string()),
    disabled_users: z.array(z.string()),
  }),
  tools: z.record(z.string(), z.

πŸŽ‰ Mid-Year Sale β€” Unlock Full Article

Base plan from just $4.99/mo or $49/yr

Sign in to read the full article and unlock all 635+ tutorials.

Sign In / Register β€” Start Free Trial

7-day free trial Β· Cancel anytime Β· 30-day money-back