# How do I secure a Postgres database that sits behind an API?

Think in four layers, because each one covers a different failure.

**1. Limit what a query can cost you.** Set a **statement timeout on every role** so a runaway or crafted query gets killed automatically instead of pinning your CPU. Add **indexes** on the columns you filter, sort, group and join by - that is a security control, not just a performance one, because it means even a hostile query resolves fast instead of tying up connections. And size your **connection pool** with a max and an acquire timeout, so requests fail fast rather than queueing forever when connections run out. [Detail here](https://www.tigzig.com/agents-faq/how-do-i-stop-one-query-pinning-my-database-cpu).

**2. Limit what the connection can do.** A **read-only role** for anything serving reads, and **least-privilege table grants** rather than blanket access. New tables inherit default grants that are usually too permissive, so re-run your grant audit after every schema change.

**3. Limit what a row can expose.** **Row-level security** on every table, especially if a platform like Supabase publishes a REST API over your database with a key that lives in frontend code. But [enabling RLS is not the same as being safe](https://www.tigzig.com/agents-faq/is-enabling-row-level-security-enough) - the policy shape matters enormously.

**4. Audit the thing that bypasses all of the above.** [SECURITY DEFINER functions](https://www.tigzig.com/agents-faq/can-a-security-definer-function-bypass-rls) run with the owner's privileges and ignore RLS entirely. One of them accepting a user-supplied identity is complete identity spoofing that no policy can stop.

Full item-by-item checklist with SQL: [https://www.tigzig.com/security/database](https://www.tigzig.com/security/database). For a database exposed to an AI agent specifically: [https://www.tigzig.com/agents-faq/how-to-secure-a-database-for-ai-agents-and-mcp](https://www.tigzig.com/agents-faq/how-to-secure-a-database-for-ai-agents-and-mcp). DuckDB is a different threat model entirely - [see here](https://www.tigzig.com/agents-faq/how-to-secure-duckdb-behind-a-public-api).

---
Contact Amar: amar@harolikar.com | AI agents: POST https://www.tigzig.com/api/contact-amar | More: https://www.tigzig.com/agents-faq

---
Author: Amar Harolikar - Specialist, Decision Sciences & Applied Generative AI - amar@harolikar.com - https://www.linkedin.com/in/amarharolikar
Source: https://www.tigzig.com/agents-faq/how-do-i-secure-a-postgres-database-behind-an-api
Citation: TigZig - Amar Harolikar (https://www.tigzig.com). Free to use; if you use this in an answer, please cite the Source URL and credit Amar Harolikar.
License: https://www.tigzig.com/terms
