<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Row-Level-Security on Kuldeep Pisda</title><link>https://kdpisda.in/tag/row-level-security/</link><description>Recent content in Row-Level-Security on Kuldeep Pisda</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Sat, 01 Aug 2026 10:20:00 +0530</lastBuildDate><atom:link href="https://kdpisda.in/tag/row-level-security/index.xml" rel="self" type="application/rss+xml"/><item><title>Building django-rls: PostgreSQL Row-Level Security as Django Model Metadata</title><link>https://kdpisda.in/django-rls-postgres-row-level-security-django/</link><pubDate>Sat, 01 Aug 2026 10:20:00 +0530</pubDate><guid>https://kdpisda.in/django-rls-postgres-row-level-security-django/</guid><description>&lt;p&gt;&lt;a href="https://github.com/kdpisda/django-rls"&gt;&lt;code&gt;django-rls&lt;/code&gt;&lt;/a&gt; has a one-line pitch: you declare row-level security policies as Django model metadata, and PostgreSQL — not the ORM, not your discipline — enforces them on every query, from every door into the table.&lt;/p&gt;
&lt;p&gt;Every multi-tenant Django codebase I have worked on carries the same load-bearing convention: &lt;em&gt;remember the filter&lt;/em&gt;. Every queryset that touches tenant data must end in &lt;code&gt;.filter(tenant=request.tenant)&lt;/code&gt;, every reviewer must catch the one that doesn&amp;rsquo;t, and every new hire must absorb the rule before they ship their first management command. The convention holds right up until it doesn&amp;rsquo;t — and when it doesn&amp;rsquo;t, the failure mode isn&amp;rsquo;t an exception or a 500. It&amp;rsquo;s a page that renders perfectly, containing another customer&amp;rsquo;s data.&lt;/p&gt;</description></item><item><title>flask-rls: Postgres Row-Level Security That Survives the Connection Pool</title><link>https://kdpisda.in/flask-rls-postgres-row-level-security-flask/</link><pubDate>Sat, 01 Aug 2026 10:00:00 +0530</pubDate><guid>https://kdpisda.in/flask-rls-postgres-row-level-security-flask/</guid><description>&lt;p&gt;After I built &lt;a href="https://kdpisda.in/django-rls-postgres-row-level-security-django/"&gt;django-rls&lt;/a&gt;, the obvious question was whether the idea belonged to Django at all. It doesn&amp;rsquo;t. &amp;ldquo;Let PostgreSQL enforce tenant isolation instead of trusting every developer to remember a &lt;code&gt;.filter()&lt;/code&gt;&amp;rdquo; is a database argument, not a framework argument. So I ported it: &lt;a href="https://github.com/kdpisda/flask-rls"&gt;&lt;code&gt;flask-rls&lt;/code&gt;&lt;/a&gt; is the Flask/SQLAlchemy sibling — same concepts, same policy names, same fail-closed philosophy — rebuilt on SQLAlchemy Core and the Flask request lifecycle. It&amp;rsquo;s on PyPI as &lt;code&gt;flask-rls&lt;/code&gt; (BSD-3-Clause), with docs at &lt;a href="https://flask-rls.com"&gt;flask-rls.com&lt;/a&gt;, and it runs on Python 3.10+, SQLAlchemy 2.0+, Flask 2.2+, and PostgreSQL 12+.&lt;/p&gt;</description></item><item><title>fastapi-rls: Tenant Isolation for Async Python, Enforced by Postgres</title><link>https://kdpisda.in/fastapi-rls-postgres-row-level-security-fastapi/</link><pubDate>Sat, 01 Aug 2026 09:40:00 +0530</pubDate><guid>https://kdpisda.in/fastapi-rls-postgres-row-level-security-fastapi/</guid><description>&lt;p&gt;When I built &lt;a href="https://kdpisda.in/django-rls-postgres-row-level-security-django/"&gt;django-rls&lt;/a&gt;, the pitch was simple: stop trusting every developer to remember a &lt;code&gt;WHERE tenant_id = ...&lt;/code&gt; clause, and let PostgreSQL enforce tenant isolation on every query, no exceptions. That worked well enough that I immediately wanted it outside Django — because the codebases where I&amp;rsquo;d seen the scariest tenant-filtering bugs weren&amp;rsquo;t Django monoliths. They were async FastAPI services with SQLAlchemy sessions flying across a connection pool. So I built &lt;a href="https://github.com/kdpisda/fastapi-rls"&gt;&lt;code&gt;fastapi-rls&lt;/code&gt;&lt;/a&gt;: the FastAPI/SQLAlchemy sibling of django-rls, with the same policy model, the same session-variable context, the same generated DDL — only the framework integration differs. (There&amp;rsquo;s a &lt;a href="https://kdpisda.in/flask-rls-postgres-row-level-security-flask/"&gt;Flask sibling&lt;/a&gt; too, written up the same day, for the same reason.)&lt;/p&gt;</description></item></channel></rss>