{"slug": "how-to-set-up-postgresql-permissions-for-ai-coding-tools-cursor-claude-copilot", "title": "How to set up PostgreSQL permissions for AI coding tools (Cursor, Claude, Copilot)", "summary": "A developer has outlined a method for restricting PostgreSQL permissions when connecting AI coding tools like Cursor, Claude, and Copilot to databases. The approach involves creating a dedicated PostgreSQL role with only the necessary privileges—such as read-only or limited read-write access—rather than using a full admin connection string. The developer also recommends granting broad access and then revoking it from sensitive tables or schemas to protect data like billing information and PII.", "body_md": "Most developers I talk to connect Cursor or Claude directly to their databases using a full admin connection string. Wether it's a local Docker database, or cloud-based QA or even production database, since it's not hidden in a subnet and publicly available. Many of developers have open-to-world QA databases, replicating prod data, where multiple developers work.\n\nIt works. But it's the equivalent of giving someone your house keys because they need to water your plants.\n\nThis post covers how to set up PostgreSQL permissions specifically for AI tools - what to create, what to restrict, and how to actually enforce it at the query level.\n\nWhen you drop a raw postgresql://user:password@host:5432/db into Cursor, you're giving it whatever privileges that user has. If that's your admin user - and it usually is - the AI can:\n\n`SELECT anything`\n\nUPDATE anything\n\nDELETE anything\n\nDROP tables\n\nRun TRUNCATE on production data\n\nNot that Cursor would do this on purpose. But AI tools generate SQL based on context, and mistakes happen. One misunderstood prompt, one \"fix this data\" instruction gone wrong - and you're restoring from backup. If you have one. If it's restorable.\n\nThe fix is two things: a restricted PostgreSQL role, and a permission layer that validates queries before they reach the database.\n\nNever use your admin user for AI tools. Create a separate role with only the privileges the AI actually needs.\n\n```\n-- Create the role\nCREATE ROLE ai_readonly WITH LOGIN PASSWORD 'your-strong-password';\n\n-- Grant connection to the database\nGRANT CONNECT ON DATABASE your_database TO ai_readonly;\n\n-- Grant usage on the schema\nGRANT USAGE ON SCHEMA public TO ai_readonly;\n\n-- Grant SELECT on all existing tables\nGRANT SELECT ON ALL TABLES IN SCHEMA public TO ai_readonly;\n\n-- Grant SELECT on future tables too\nALTER DEFAULT PRIVILEGES IN SCHEMA public\n  GRANT SELECT TO ai_readonly;\n```\n\nFor a read-write setup where the AI needs to insert or update (for example, a coding assistant that runs migrations):\n\nCREATE ROLE ai_readwrite WITH LOGIN PASSWORD 'your-strong-password';\n\n```\nGRANT CONNECT ON DATABASE your_database TO ai_readwrite;\nGRANT USAGE ON SCHEMA public TO ai_readwrite;\nGRANT SELECT, INSERT, UPDATE ON ALL TABLES IN SCHEMA public TO ai_readwrite;\nALTER DEFAULT PRIVILEGES IN SCHEMA public\n  GRANT SELECT, INSERT, UPDATE TO ai_readwrite;\n\n-- Explicitly block DELETE and destructive operations\n-- (just don't grant them - absence of GRANT = denied)\n```\n\nKey point: in PostgreSQL, not granting a privilege is enough to block it. You don't need to explicitly REVOKE anything you never granted.\n\nEven with a read-only role, you probably don't want the AI seeing everything. Billing data, PII, internal audit tables - these should be off limits.\n\n```\n-- Revoke access to specific tables after the blanket GRANT\nREVOKE SELECT ON TABLE users FROM ai_readonly;\nREVOKE SELECT ON TABLE billing_events FROM ai_readonly;\nREVOKE SELECT ON TABLE api_keys FROM ai_readonly;\n\n-- Or lock down an entire schema\nREVOKE USAGE ON SCHEMA internal FROM ai_readonly;\n```\n\nThe pattern: grant broadly, then revoke specifically. This is easier to maintain than trying to grant table by table.\n\nIf your database has multiple schemas and the AI only needs access to one of them:\n\n```\n-- Only grant access to the 'app' schema, not 'internal' or 'audit'\nGRANT USAGE ON SCHEMA app TO ai_readonly;\nGRANT SELECT ON ALL TABLES IN SCHEMA app TO ai_readonly;\n\n-- Don't grant anything on other schemas\n```\n\nThis is the cleanest approach for teams where different schemas have different sensitivity levels.\n\nPostgreSQL role-level permissions are necessary, but not sufficient on their own. They don't:\n\nLog what queries the AI actually ran\n\nBlock TRUNCATE (which requires only ownership, not a special privilege)\n\nPrevent the AI from querying system catalogs (pg_catalog, information_schema)\n\nGive you per-tool control (different permissions for Cursor vs a contractor's Claude setup)\n\nThis is where a tool like [DataMCP](https://datamcp.app) comes in. It sits between your AI tool and PostgreSQL, adds a second permission layer, and validates every query before execution.\n\nThe setup looks like this:\n\n```\nCursor / Claude / VS Code\n        |\n        | MCP protocol\n        v\n   DataMCP (permission check + query validation)\n        |\n        | only validated queries pass through\n        v\n   PostgreSQL (your ai_readonly role)\n```\n\nWith this setup, effective permissions = PostgreSQL role permissions AND DataMCP permission rules. Both have to allow a query for it to execute.\n\nIn DataMCP you can:\n\nDon't assume the permissions are working - verify them.\n\n```\n-- Connect as the AI user and test\npsql postgresql://ai_readonly:password@host:5432/db\n\n-- This should work\nSELECT id, email FROM users LIMIT 5;\n\n-- This should fail with \"permission denied\"\nDELETE FROM users WHERE id = 1;\n\n-- This should fail\nDROP TABLE users;\n\n-- This should fail if you revoked it\nSELECT * FROM billing_events;\n```\n\nRun through the operations you blocked and confirm they return permission errors, not results.\n\nWith a dedicated PostgreSQL role plus a permission layer:\n\nThe PostgreSQL role is your first line of defense. The permission layer is your second. Neither alone is enough - you want both.\n\nIf you're using Cursor or Claude with a PostgreSQL database and want to skip the manual setup, [DataMCP](https://datamcp.app) handles the permission layer out of the box. Free tier covers one database connection.\n\n**Do I need both a restricted PostgreSQL role AND a separate permission layer?**\n\nYes. PostgreSQL roles control what the database user can do. A permission layer like DataMCP adds query-level validation, audit logging, and per-tool access control on top. Use both.\n\n**Can I use row-level security (RLS) instead?**\n\nRLS is great for multi-tenant apps but adds complexity for AI tools. The AI needs to understand the RLS policies to write correct queries. A simpler approach: restricted role + table-level REVOKE + a permission layer.\n\n**What if I'm using Supabase or Neon?**\n\nThe same SQL commands work. Supabase and Neon both expose standard PostgreSQL role management. Create the restricted role through the SQL editor in their dashboard.\n\n**How do I connect the restricted role to Cursor?**\n\nAdd it to `.cursor/mcp.json`\n\n- either directly as a connection string (basic, no permission layer) or via an MCP gateway like DataMCP (recommended). The MCP approach gives you the audit trail and query validation on top of the PostgreSQL role restrictions.\n\n**Does this work for Claude Desktop?**\n\nYes. Claude Desktop supports MCP via mcp-remote. The same DataMCP MCP URL works for Cursor, Claude Desktop, VS Code, and any other MCP-compatible tool.", "url": "https://wpnews.pro/news/how-to-set-up-postgresql-permissions-for-ai-coding-tools-cursor-claude-copilot", "canonical_source": "https://dev.to/andrei_mironov_3484cf5cb5/how-to-set-up-postgresql-permissions-for-ai-coding-tools-cursor-claude-copilot-28kj", "published_at": "2026-05-29 08:17:15+00:00", "updated_at": "2026-05-29 08:42:24.129310+00:00", "lang": "en", "topics": ["ai-tools", "ai-safety", "ai-infrastructure", "artificial-intelligence", "large-language-models"], "entities": ["Cursor", "Claude", "Copilot", "PostgreSQL", "Docker"], "alternates": {"html": "https://wpnews.pro/news/how-to-set-up-postgresql-permissions-for-ai-coding-tools-cursor-claude-copilot", "markdown": "https://wpnews.pro/news/how-to-set-up-postgresql-permissions-for-ai-coding-tools-cursor-claude-copilot.md", "text": "https://wpnews.pro/news/how-to-set-up-postgresql-permissions-for-ai-coding-tools-cursor-claude-copilot.txt", "jsonld": "https://wpnews.pro/news/how-to-set-up-postgresql-permissions-for-ai-coding-tools-cursor-claude-copilot.jsonld"}}