---
title: "Securing Database Writes with Vercel AI SDK v7 Tool Approvals"
description: "Giving an LLM permission to delete database rows is terrifying. I used the new human-in-the-loop tool approvals in Vercel AI SDK v7 to build a safer admin agent."
image: "https://foundrysoft.co/api/og?type=article&title=Securing+Database+Writes+with+Vercel+AI+SDK+v7+Tool+Approvals&cat=AI+Engineering&rt=8+min+read&au=Varun+Raj+Manoharan&dt=2026-07-07"
url: "https://foundrysoft.co/blog/vercel-ai-sdk-v7-tool-approvals"
---

AI Engineering 2026-07-07 8 min read

# Securing Database Writes with Vercel AI SDK v7 Tool Approvals

Giving an LLM permission to delete database rows is terrifying. I used the new human-in-the-loop tool approvals in Vercel AI SDK v7 to build a safer admin agent.

![Varun Raj Manoharan](https://foundrysoft.co/images/about/founder.webp)

Varun Raj Manoharan

Vercel AI SDK v7 Security TypeScript

I love the idea of an AI agent managing my database, right up until the moment it decides to drop a production table because it hallucinated a command. Building read-only agents is safe. Building agents that actually modify data requires serious guardrails.

Vercel AI SDK v7 introduced a native way to handle tool approvals. Instead of building custom pause-and-resume logic, you can flag specific tools as requiring human consent. I built a mock admin dashboard to test how hard it is to implement.

### The Admin Agent

I set up an agent that can read user records and delete them. Reading records is safe, so the agent can do it autonomously. Deleting records is destructive, so it requires an explicit approval token.

Here is how you define the tool with the new `requiresApproval` flag:

TypeScript

Copy

```typescript
import { generateText, tool } from 'ai';
import { openai } from '@ai-sdk/openai';
import { z } from 'zod';
import db from './my-database';

const result = await generateText({
  model: openai('gpt-4o'),
  prompt: 'Find the user with email spammer@example.com and delete their account.',
  tools: {
    findUser: tool({
      description: 'Search for a user by email',
      parameters: z.object({ email: z.string() }),
      execute: async ({ email }) => {
        return db.users.find(email);
      },
    }),
    deleteUser: tool({
      description: 'Delete a user from the database. REQUIRES APPROVAL.',
      parameters: z.object({ userId: z.string() }),
      requiresApproval: true, // The new v7 flag
      execute: async ({ userId }) => {
        await db.users.delete(userId);
        return { success: true };
      },
    }),
  },
});
```

### The Approval Flow

When the model decides it needs to call `deleteUser`, the execution pauses. The SDK returns a special `ToolApprovalRequest` object to the frontend instead of the final text.

On my frontend dashboard, I caught this object and rendered a modal. It showed me exactly what the agent wanted to do: `"Tool: deleteUser, Arguments: { userId: 'user_992' }"`.

If I click "Approve", the frontend sends an HMAC-signed token back to the API. The SDK verifies the signature to ensure nobody tampered with the approval in transit, and then executes the database query. If I click "Reject", the agent gets a rejection error and has to figure out what to do next.

### Why this matters

I used to build this manually by saving the agent's conversation history to a database, sending a Slack message, and waiting for a webhook to wake the agent back up. It was fragile.

The SDK handles the cryptographic signing and state pausing out of the box now. I did find the HMAC setup a bit tedious, you have to carefully manage your secret keys across your edge functions and client components. But once it is wired up, it gives you the confidence to let agents actually do things without risking your production data.

#### Related reading

[MCP Went Stateless: Migrating Your Server to the 2026-07-28 Spec

The 2026-07-28 MCP revision removes sessions, the initialize handshake, and server-initiated requests. Here's what actually breaks in your server, the new wire format, the requestState and MRTR patterns that replace sessions, and the SDK v2 migration path.

MCP Model Context Protocol AI Agents

](https://foundrysoft.co/blog/mcp-stateless-spec-migration)[We Open-Sourced an AI Agent for Coverage Citations: And Broke It Twice

agent-for-insurance is an open-source drafting aid that will not state a coverage conclusion without citing your policy's own text. Here's how it works, and the two parsing bugs that taught us why that rule has to be enforced in code, not prose.

Open Source AI Agents Insurance

](https://foundrysoft.co/blog/open-source-ai-agent-insurance-coverage-citations)[We Open-Sourced an AI Agent That Catches the Markup/Margin Error Costing Contractors Money

agent-for-field-service is a free, self-hosted AI copilot for HVAC, plumbing, electrical, and roofing contractors that prices jobs to a real margin instead of a markup that only looks like one.

Open Source AI Agents eve

](https://foundrysoft.co/blog/open-source-ai-agent-contractor-quoting-margin)

#### Next Article

[

Processing Video Files with Vercel AI SDK v7 Multimodal Support

](https://foundrysoft.co/blog/vercel-ai-sdk-v7-multimodal-inputs)

Available for new projects

## Let's build something great.

Have a project in mind? We are an elite software and AI development studio ready to bring your ideas to production. Let's talk about your roadmap.

Start a Project [See our work](https://foundrysoft.co/work)

```json
{
  "@context": "https://schema.org",
  "@type": "Organization",
  "name": "FoundrySoft",
  "url": "https://foundrysoft.co",
  "logo": "https://foundrysoft.co/logo.svg",
  "description": "FoundrySoft builds production-grade software and AI systems for US companies, from an India-based team of senior engineers.",
  "sameAs": [
    "https://github.com/foundrysofthq",
    "https://www.linkedin.com/company/foundrysoft",
    "https://www.instagram.com/foundrysoft/"
  ]
}
```

```json
{
  "@context": "https://schema.org",
  "@type": "WebSite",
  "name": "FoundrySoft",
  "url": "https://foundrysoft.co"
}
```

```json
{
  "@context": "https://schema.org",
  "@type": "TechArticle",
  "headline": "Securing Database Writes with Vercel AI SDK v7 Tool Approvals",
  "description": "Giving an LLM permission to delete database rows is terrifying. I used the new human-in-the-loop tool approvals in Vercel AI SDK v7 to build a safer admin agent.",
  "url": "https://foundrysoft.co/blog/vercel-ai-sdk-v7-tool-approvals",
  "mainEntityOfPage": "https://foundrysoft.co/blog/vercel-ai-sdk-v7-tool-approvals",
  "image": [
    "https://foundrysoft.co/images/blog/vercel-ai-sdk-v7-approvals.jpg"
  ],
  "datePublished": "2026-07-07",
  "dateModified": "2026-07-07",
  "keywords": "Vercel, AI, SDK v7, Security, TypeScript",
  "author": {
    "@type": "Person",
    "name": "Varun Raj Manoharan"
  },
  "publisher": {
    "@type": "Organization",
    "name": "FoundrySoft",
    "logo": {
      "@type": "ImageObject",
      "url": "https://foundrysoft.co/logo.svg"
    }
  }
}
```

```json
{
  "@context": "https://schema.org",
  "@type": "BreadcrumbList",
  "itemListElement": [
    {
      "@type": "ListItem",
      "position": 1,
      "name": "Home",
      "item": "https://foundrysoft.co/"
    },
    {
      "@type": "ListItem",
      "position": 2,
      "name": "Blog",
      "item": "https://foundrysoft.co/blog"
    },
    {
      "@type": "ListItem",
      "position": 3,
      "name": "Securing Database Writes with Vercel AI SDK v7 Tool Approvals",
      "item": "https://foundrysoft.co/blog/vercel-ai-sdk-v7-tool-approvals"
    }
  ]
}
```
