AI Agent Authorization Out of Control? An Independent Authorization Layer Intercepts Database Changes

AI Agents must obtain authorization from an independent service before execution, separating execution from authorization.
The article explores the authorization problem when AI Agents operate production systems, noting that tool access permission is not task authorization. Using LangGraph, SQLite, and BHANUJ-AIGP, the author separates execution from authorization: LangGraph runs workflows, AIGP makes authorization decisions, and SQLite only stores data. Keycloak authenticates two service identities, and delegated authorization ensures the Agent runtime cannot self-authorize. Writes occur only on ALLOW and stop on DENY; fail-closed design blocks writes during outages. Execution evidence links tool calls to decisions via causation_id but is not tamper-proof proof.
Title
AI Agent Authorization Out of Control? An Independent Authorization Layer Intercepts Database Changes
Meta Description
An AI Agent can operate a database, but that doesn't mean it's authorized to. This article examines an experiment built on LangGraph, SQLite, and the open-source governance platform BHANUJ-AIGP: through an independent authorization layer, delegation mechanism, and fail-closed design, it intercepts unauthorized database changes and preserves traceable execution evidence.
Article Content
AI Agents are moving from answering questions to operating production systems: querying databases, modifying records, calling APIs, and coordinating cross-application workflows. The more capable they become, the harder it is to avoid a fundamental question—does an Agent understanding a request mean it has the authority to execute it?
An experimental article from the developer community gives a clear negative answer, and builds a runnable verification scheme using LangGraph, SQLite, and the open-source governance platform BHANUJ-AIGP. The core idea can be stated in a single sentence: completely separate execution from authorization.

The Problem: Tool Access Permission Is Not Task Authorization
Imagine an operations assistant with two capabilities: operations.read_status (view records) and operations.update_status (modify records). When it receives the instruction "set OPS-001 to maintenance mode," it technically knows exactly which tool to call.
But a series of authorization questions remain unresolved: Who authorized this operation? Is the authorization only for this record? Is the permission still valid? Can the Agent divert the permission to another operation? What happens if the authorization service goes down? Can we later trace which decision allowed this database modification?
These questions belong to a different layer than "whether the model chose the right tool." Tool selection determines what the Agent wants to do; authorization determines what it is allowed to do. Most current Agent frameworks conflate the two, blurring the security boundary.
Architecture: Execution Is Execution, Authorization Is Authorization
The experiment deliberately keeps LangGraph as the workflow engine, responsible for reading records, preparing changes, and calling tools after approval. BHANUJ-AIGP independently makes authorization decisions and receives execution evidence. In the flow, after the Agent proposes an update, it first passes through an authorization check; only an ALLOW response permits writing to SQLite, while a DENY response stops it in place.
A key architectural division is: AIGP itself does not perform database operations. LangGraph enforces the returned authorization decision before calling SQLite. This creates a three-layer division of responsibility: LangGraph handles workflow execution and tool invocation, AIGP handles policy evaluation, authorization decisions, and evidence management, and SQLite handles application data and state.
The goal of this design is not to bolt a new governance system onto the Agent framework, but to insert an explicit security boundary at the point where "AI decisions become real-world actions."
Authentication Is Not Authorization
The most intriguing part of the experiment is the delegated authorization mechanism. A runtime can have a legitimate identity without being authorized to perform every operation. The lab used Keycloak to authenticate two separate service identities: one is the delegation issuer, trusted and authorized to issue narrowly scoped delegations; the other is the Agent runtime, which executes LangGraph workflows and requests authorization before performing protected operations.
The runtime cannot authorize itself. Before execution, the integration application establishes a delegation bound to a specific execution, runtime identity, action, resource, and expiration time, and the authorization service validates and persists that delegation. When the runtime subsequently makes a protected tool call, the authorization service independently verifies the delegation and applicable policies. There are two independent controls here: whether the issuer has the authority to delegate that action, and whether the runtime's proposed operation conforms to the policy and delegation scope.
The Agent cannot select a looser policy or expand the delegation scope by modifying its prompt. An authenticated Agent is not necessarily an authorized Agent.
Delegated Authorization is a mechanism that lets a subject holding a legitimate identity obtain temporary, fine-grained operation permissions on behalf of another subject (or itself). In the OAuth 2.0 framework, it is typically implemented through Token Exchange (RFC 8693) or JWT authorization assertions: the delegator, based on its own permissions, issues a credential to the delegatee bound to a specific action, resource, and validity period. Unlike static API keys, delegated authorization emphasizes "least privilege" and "context binding"; once execution ends or the delegation expires, the permission automatically becomes invalid. In this experiment, AIGP constrains the scope of the Agent runtime's operations precisely by establishing delegations, keeping identity authentication and operation authorization independent, thereby preventing the Agent from using its own identity to perform unauthorized actions.
Experimental Verification: Allow and Intercept
In the allowed scenario, the initial SQLite record OPS-001 has a status of PENDING, and the Agent proposes changing the status to MAINTENANCE. Before SQLite executes, the runtime requests authorization from AIGP. After evaluating the delegation bound to this execution and the effective policy, AIGP grants permission, outputting a result of WRITE_COMPLETED with the reason ALLOW_POLICY_MATCHED, the database status changes to MAINTENANCE, and the AIGP evidence status is COMPLETED.
Conversely, when the runtime's delegation only permits operations.read_status but it attempts to call operations.update_status, the operation exceeds the delegation scope, and the policy returns DENY with DELEGATION_SCOPE_DENIED. The database status remains PENDING, and the successful tool call event count is 0.
This denial result was actually verified through the running AIGP OSS API, not simulated with a local mock. An interesting detail is that the Agent's overall execution can still end successfully because it handled the denial safely. This reveals another important distinction—a workflow completing successfully does not mean the tool execution succeeded or was authorized. A well-behaved assistant can perfectly complete the task by reporting "this operation is not permitted," and the workflow result must remain separate from the authorization result.
When the Authorization Service Goes Down, Default to Deny
Whether a security boundary is useful depends on whether its failure behavior is predictable. When the Agent attempts a protected database operation and the authorization service times out, should the assistant continue executing just because the request seems reasonable? The answer is no.
For protected operations, the integration adopts a fail-closed design: denial decisions, authorization expiration, invalid responses, operation mismatches, or authorization service unavailability all block database writes. The lab also provides deterministic offline failure drills for these behaviors. The author specifically notes that the offline fixtures do not represent real AIGP authorization decisions—the aigp scenario goes through the authoritative API, while allowed, denied, and outage are local teaching and testing scenarios. This distinction is crucial when evaluating whether a security architecture can move beyond the demo environment.
Execution Evidence: Traceable, but Not Tamper-Proof
Blocking unauthorized operations is the bottom line, but operations teams also need to understand what happened after the fact. The typical investigation scenario is: an Agent modified a certain record—was this change permitted? Which execution did it? Which authorization decision preceded the tool call?
In the experiment, the AIGP integration records a bounded execution history, with a typical sequence of EXECUTION_STARTED, WORKFLOW_STEP, RUNTIME_ACTION_AUTHORIZATION, TOOL_CALL, EXECUTION_COMPLETED. Successful tool call records reference the corresponding authorization decision through causation_id, allowing reviewers to connect the action reported by the runtime with the decision that authorized it.
The evidence is privacy-bounded by design: it contains only identifiers, decision metadata, results, and references, and does not store raw prompts, full tool payloads, credentials, or model reasoning processes. The author also candidly acknowledges the limitations—AIGP receives tool results reported by the runtime; it does not independently witness the SQLite transaction. This provides useful authorization traceability and execution evidence, not tamper-proof proof of every underlying database effect.
causation_id is an identifier used to establish causal chains, commonly found in distributed tracing (such as OpenTelemetry's TraceID/SpanID) and event sourcing systems. In authorization scenarios, it links a tool call event with the authorization decision event that triggered it, enabling auditors to trace back "which decision allowed which action." Unlike a simple parent-child relationship, causation_id emphasizes causal transmission: even if events span services and storage, the path from decision to execution can be reconstructed through this ID. However, causation_id only guarantees logical association, not cryptographic integrity—if the runtime maliciously forges the ID, the authorization service cannot independently verify it. Therefore, it is suitable for operational auditing and troubleshooting, but cannot replace tamper-proof mechanisms such as digital signatures or hash chains.
Why Not Cram All Authorization into LangGraph
Of course, you can write conditional checks inside the LangGraph workflow. The question is whether those checks should constitute an authoritative security boundary. For small, isolated experiments, local checks may suffice. But enterprise systems introduce requirements such as multi-framework Agents, shared enterprise policies, independent policy management, explicit delegation and revocation, consistent denial behavior, centralized authorization evidence, and cross-execution operational visibility.
Embedding authoritative policy into every Agent implementation easily leads to inconsistent execution: one framework may enforce rules differently from another, future tool integrations may bypass a check, and policy changes are difficult to coordinate. The alternative is to separate policy decisions from framework-specific execution—each Agent runtime connects to an authoritative authorization service while retaining responsibility for enforcing that decision at the actual tool boundary. A key requirement is that the runtime cannot provide an alternate path that bypasses enforcement. If a tool can still execute without passing through the protected boundary, then the independent policy service is nothing but a facade.
Policy Decision Point (PDP) and Policy Enforcement Point (PEP) are a classic separation pattern in authorization architecture, originating from the XACML standard. The PDP is responsible for evaluating policies and making allow/deny decisions, while the PEP is responsible for intercepting requests at the resource access point and enforcing the PDP's decision. In this article, AIGP acts as the PDP, and LangGraph acts as the PEP before calling SQLite. The core value of this separation lies in centralized policy management, auditable decisions, and the inability of the enforcement point to bypass decisions. If policy logic is embedded inside LangGraph, then every Agent implementation could become an independent PDP, leading to policy fragmentation and making unified revocation and monitoring difficult. Notably, the PEP must ensure that all access to protected resources goes through the PDP; otherwise, the separation architecture is meaningless—this is precisely why the author emphasizes that "the runtime cannot provide an alternate path that bypasses enforcement."
Experimental Boundaries and Engineering Questions
The author explicitly lists the limitations: no new Agent orchestration system is introduced, no application is deployed, unauthorized changes are not automatically remediated, all downstream business constraints are not guaranteed to be satisfied, replayable SQLite execution or causal replay is not provided, and the evidence history is not a formally sealed ledger or cryptographic attestation of the underlying database transaction. The integrity binding of tool parameters protects the relationship between the authorization and the proposed operation, but cannot replace business-level validation within the application.
The experimental code has been made public, and the developer guide covers the LangGraph workflow, SQLite integration, identity configuration, policy settings, authoritative authorization paths, failure scenarios, and execution evidence inspection. The first read-only checkpoint requires no model API or paid cloud service.
Finally, the author poses a question to the engineering community that everyone deploying Agents should consider: should authorization for AI Agent tool calls be placed inside the Agent framework, at the tool boundary, or in an independent policy service? More importantly, how do you prove that unauthorized actions cannot bypass the enforcement mechanism?
When Agents begin modifying production systems, the security boundary cannot rely solely on what the model "believes" it is allowed to do. The model can decide the next action, but the authority to execute that action must come from a trusted system outside the model's control.
One-line Summary
AI Agents must obtain a decision from an independent authorization service before execution, achieving separation of execution and authorization.
Paragraph Summary
The article explores the authorization problem when AI Agents operate production systems, pointing out that tool access permission is not task authorization. The author built an experiment using LangGraph, SQLite, and the open-source governance platform BHANUJ-AIGP, with the core idea of completely separating execution from authorization: LangGraph handles workflows and tool calls, AIGP independently makes authorization decisions, and SQLite only stores data. The experiment uses Keycloak to authenticate two service identities and introduces a delegated authorization mechanism to ensure the Agent runtime cannot authorize itself. Verification shows that writes are executed only when the authorization service returns ALLOW, and stop on DENY; when the authorization service is down, a fail-closed design blocks writes. Execution evidence links tool calls to authorization decisions through causation_id, but it is not tamper-proof proof. The author concludes with an engineering question: should authorization be placed inside the framework, at the tool boundary, or in an independent policy service, and how do you prove unauthorized actions cannot bypass it?
Related articles

Chain of Thought Isn't Just for AI: How Humans Can Use CoT to Improve Thinking Quality
Chain of Thought isn't just a prompt trick for large models. Starting from a Hacker News discussion, this article analyzes why CoT works for human thinking too, breaks down actionable ways to transfer it, and highlights the key differences between human CoT and machine CoT.
Cloudflare Teams Up with OpenAI: Closi…
Cloudflare Teams Up with OpenAI: Closing the Loop from Vulnerability Discovery to Defense with AI
Cloudflare uses OpenAI Daybreak to investigate security vulnerabilities and generate reviewable remediation plans, while developers use Codex to boost coding efficiency and quality.

Orca Multi-Agent Orchestration in Practice: A Guide to Parallel Collaboration with Claude and Codex
Orca is Stable AI's free open-source agent workbench supporting 34 agents like Claude Code and Codex in parallel. Learn its Git worktree isolation, multi-model orchestration, and mobile management.