
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.
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:
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
Our monthly client reports followed a 40-line prompt nobody dared touch. I moved the whole playbook into an uploaded skill using the new uploadSkill API in Vercel AI SDK v7.
Explore how the finance sector is leveraging custom AI agents for quantitative analysis, automated reporting, and secure data processing.
A technical guide to building secure, HIPAA-compliant AI agents in healthcare. Learn about self-hosted models, zero-retention policies, and sandboxing PHI.
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.