AI Agents
·IdenticAPI

Securing AI Agents with Database Access

Secure database access for AI agents — read vs write permissions, scoped credentials, destructive-operation approval, and audit metadata.

AI agent database security starts with a clear rule: agents should not receive raw SQL credentials or unrestricted write access. Secure database agents with read-vs-write separation, scoped credentials, row- and tenant-level filters enforced in the tool layer, destructive-operation blocks or reviews, and pre-execution policy evaluation on every proposed query or mutation before it hits the database.

Database tools are among the highest-impact agent integrations. A single DELETE without a proper WHERE clause, a cross-tenant SELECT, or an export query embedded in agent context can cause data loss or compliance violations. AI agent permissions define what principals may do; Agent Action Guard evaluates whether a specific proposal matches policy before execution.

Read vs write vs destructive

Classify database tool actions explicitly:

ClassExamplesRecommended posture
Readget_user, list_orders, search, countAllow with row limits and audit logs
Writeupdate_status, insert_row, upsertReview or scoped allow per table
Destructivedelete, truncate, drop, bulk update without keyBlock or mandatory human approval
Schemamigrate, alter_table, create_indexBlock from user-facing agents

Agent Action Guard's default policy blocks destructive keywords in action and context strings and allows common read prefixes. Map your ORM or query builder action names into custom policy_id rules — do not assume default keywords cover purge_inactive or soft_delete_all.

Scoped credentials, not shared admin

Agent runtimes should use dedicated database roles:

  • Read-only role for analytics and support lookup agents
  • Limited write role — UPDATE/INSERT only on specific tables; no DDL
  • No superuser — agents never use migration credentials
  • Connection pooling per tenant with session variables for RLS

The model sees tool descriptions ("update_ticket_status") not connection strings. Credentials live in your orchestration layer.

Row-level security (RLS) and tenant filters belong in the database or repository layer — not in model instructions. Assume the model will propose over-broad filters.

// Tool layer enforces tenant scope — not the LLM
async function listOrders(args: { tenantId: string; limit: number }) {
  const capped = Math.min(args.limit, 100);
  return db.orders.findMany({
    where: { tenantId: args.tenantId },
    take: capped
  });
}

See Least Privilege for AI Agents for credential scoping patterns.

Pre-execution validation

Before executing any database tool call, submit metadata to Agent Action Guard:

curl -X POST https://www.identicapi.com/api/v1/security/agent-action \
  -H "Authorization: Bearer idapi_test_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "tool_name": "database",
    "action": "delete_users",
    "arguments": {
      "table": "users",
      "filter": { "status": "inactive" }
    },
    "context": "Agent cleanup task after admin request"
  }'

Example block response:

{
  "decision": "block",
  "policy_reason": "Rule \"Block destructive actions\" (destructive_action)",
  "findings": [
    {
      "category": "destructive_action",
      "reason": "Matched policy rule: Block destructive actions",
      "confidence": 0.9
    }
  ]
}

Integrate synchronously in the agent loop:

async function guardedDbCall(proposal: DbToolProposal) {
  const guard = await evaluateAgentAction(proposal);

  if (guard.decision === "block") {
    return dbToolError(guard.policy_reason);
  }
  if (guard.decision === "review") {
    return await approvalQueue.create(proposal, guard);
  }

  if (!await authz.canRunQuery(proposal, currentUser)) {
    return dbToolError("Not authorized");
  }

  return executeDbTool(proposal);
}

Policy evaluation does not replace authorization or RLS. All three must align.

Dangerous argument patterns

Inspect arguments in tool code and policy:

  • Missing or empty filters on delete/update — reject or force review
  • Wildcard filters"*", "1=1", empty object meaning "all rows"
  • Cross-tenant IDs — user_id from another organization
  • Large limitslimit: 1000000 on export-style reads
  • Dynamic table names from model output — allowlist tables in tool implementation

Include a short context string in guard requests for audit trails and to surface injection phrases in agent reasoning.

Destructive operations and human approval

Destructive proposals should rarely auto-execute. Pair policy blocks with human-in-the-loop approval for operations like:

  • Account deletion
  • GDPR erasure jobs
  • Archival purges
  • Permission elevation stored in DB

Use preview patterns from Safe Destructive AI Agent Actions: show affected row count from a dry-run SELECT before approval.

Secrets in query context

Agents may paste connection strings, tokens, or PII into tool arguments when summarizing chat history. Agent Action Guard scans combined context for secrets and blocks matches. Supplement with POST /api/v1/security/pii-secrets on assembled query logs if you persist proposals.

Never return raw credential columns to the model unless required; redact in tool results before re-prompting.

Read path exfiltration

Read-only access still exfiltrates data when combined with email or HTTP tools. Apply source-to-sink thinking:

  • Cap row counts on list/search tools
  • Review export or dump actions even if implemented as SELECT
  • Monitor read-then-send patterns in session logs

Audit metadata

Log for every database tool proposal:

  • tool_name, action, sanitized arguments (table names, filter keys — not full PII values)
  • Guard decision, policy_reason, findings
  • Executing principal, tenant ID, correlation ID
  • Row counts affected post-execution

Support forensics without storing full result sets in logs.

Custom policy sketch

ConditionDecision
action starts with get_, list_, search_allow
action contains delete, drop, truncateblock
action update_* with empty filter in argumentsreview
action export_*review

Test policies against your real action naming in CI when adding new database tools.

Checklist

  • Separate read and write database credentials per agent type
  • Enforce tenant scope in repository/RLS layer
  • Allowlist tables and cap row limits in tool implementations
  • Call Agent Action Guard before every database tool execution
  • Block or review destructive and bulk export actions
  • Require human approval for irreversible mutations
  • Verify authorization independently of guard decisions
  • Audit proposals and outcomes with correlation IDs

Database access for AI agents is manageable when the model never holds the keys, scopes are enforced below the LLM, and every mutation passes through policy and authorization before touching production data.

Frequently asked questions

Should AI agents use admin database credentials?

No. Use dedicated scoped roles — read-only for lookup agents, limited write on specific tables for action agents. Never expose migration or superuser credentials to agent runtimes.

How do I secure destructive database tool calls?

Block or review delete, drop, and truncate via Agent Action Guard, require primary-key-scoped arguments, implement preview counts, and route irreversible mutations to human approval.

Where is tenant isolation enforced?

In the repository or database layer with row-level security and mandatory tenant filters — not via prompt instructions. Tools must reject cross-tenant identifiers.

Does read-only database access eliminate exfiltration risk?

No. Large exports paired with email or HTTP tools still exfiltrate data. Cap row limits, review export actions, and apply source-to-sink controls.

What should I log for database agent calls?

Tool name, action, sanitized arguments, guard decision and policy_reason, principal and tenant IDs, correlation ID, and affected row counts — avoid full PII in centralized logs.

Related reading