Row-level security is often an industry requirement in secure environments, such as those dealing with payment cards.
It's supported by most major relational databases, including PostgreSQL, Microsoft SQL Server and Oracle. It works by introducing additional WHERE
clauses in SQL statements attributing the query to a particular user / tenant / domain.
The PostgreSQL wiki describes the rationale of row-level security as such:
According to the definition of ISO/IEC27001 (information security management) the design target of information security feature is to ensure confidentiality, integrity and availability of information asset. In short, these are often called C.I.A.
Access control contributes towards both confidentiality and integrity. Access controls prevent unprivileged users from reading or writing information assets based on the rules which are configured in the access control system. Information or data itself does not have a particularly tangible form and therefore it must be stored in an object. Usually, access control features allow or prohibit users access to the object that contains the information or data. The intent of RS is to allow a more fine-grained control over the information inside of the objects.
For example, regular GRANT/REVOKE mechanisms control access on the specified database object according to the access control list, but they do not allow anything more granular. This coarse access control can be a problem for multi-tenanted, hosting, and highly security sensitive environments.
Use Cases
PCI Compliant implementations Classified Environments Shared hosting / multi-tenant applications
Considering that the SQL queries are constructed and sent by the application, which is external to the database and free to construct arbitrary queries, the application is of course free to misattribute the user.
What kind of attacks does row-level security prevent?
How does row-level security "contribute towards both confidentiality and integrity"?
Note:
This question relates to row-level security, NOT row-level encryption. The distinction being that a numeric user ID is passed in the SQL clause, instead of an encryption key or encrypted data.