Skip to content

Conversation

@MuhammadTahaNaveed
Copy link
Member

Previously, age only set ACL_SELECT and ACL_INSERT in RTEPermissionInfo, bypassing pg's privilege checking for DELETE and UPDATE operations. Additionally, RLS policies were not enforced because AGE uses CMD_SELECT for all Cypher queries, causing the rewriter to skip RLS policy application.

Permission fixes:

  • Add ACL_DELETE permission flag for DELETE clause operations
  • Add ACL_UPDATE permission flag for SET/REMOVE clause operations
  • Recursively search RTEs including subqueries for permission info

RLS support:

  • Implemented at executor level because age transforms all cypher queries to CMD_SELECT, so pg's rewriter never adds RLS policies for INSERT/UPDATE/DELETE operations. There isnt an appropriate rewriter hook to modify this behavior, so we do it in executor instead.
  • Add setup_wcos() to apply WITH CHECK policies at execution time for CREATE, SET, and MERGE operations
  • Add setup_security_quals() and check_security_quals() to apply USING policies for UPDATE and DELETE operations
  • USING policies silently filter rows (matching pg behavior)
  • WITH CHECK policies raise errors on violation
  • DETACH DELETE raises error if edge RLS blocks deletion to prevent dangling edges
  • Add permission checks and rls in startnode/endnode functions
  • Add regression tests

Assisted-by AI

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request adds comprehensive Row-Level Security (RLS) support and fixes permission checking for the Apache AGE extension. Previously, AGE only checked SELECT and INSERT permissions, bypassing PostgreSQL's privilege system for UPDATE and DELETE operations. Additionally, RLS policies were not enforced because AGE transforms all Cypher queries to CMD_SELECT, preventing PostgreSQL's rewriter from applying RLS policies.

Changes:

  • Added ACL_DELETE and ACL_UPDATE permission checks for DELETE, SET, and REMOVE clause operations
  • Implemented executor-level RLS enforcement for INSERT/UPDATE/DELETE operations with WITH CHECK and USING policies
  • Added permission and RLS checks to startNode/endNode functions
  • Comprehensive regression test suite covering both permission checks and RLS scenarios

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
src/include/executor/cypher_utils.h Added SecurityQualContext struct and RLS function declarations
src/backend/parser/cypher_clause.c Added permission tracking functions and integrated ACL checks into DELETE/SET/REMOVE clauses
src/backend/executor/cypher_utils.c Core RLS implementation with policy setup and checking functions
src/backend/executor/cypher_set.c Integrated RLS WITH CHECK and USING policies for UPDATE operations
src/backend/executor/cypher_merge.c Added RLS WITH CHECK policies for MERGE operations
src/backend/executor/cypher_delete.c Integrated RLS USING policies for DELETE and DETACH DELETE operations
src/backend/executor/cypher_create.c Added RLS WITH CHECK policies for CREATE operations
src/backend/utils/adt/agtype.c Added permission and RLS checks for startNode/endNode functions
regress/sql/security.sql Comprehensive test suite for permissions and RLS
regress/expected/security.out Expected output for security tests
Makefile Added security test to regression test suite

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

- Previously, age only set ACL_SELECT and ACL_INSERT in RTEPermissionInfo,
  bypassing pg's privilege checking for DELETE and UPDATE operations.
- Additionally, RLS policies were not enforced because AGE uses CMD_SELECT
  for all Cypher queries, causing the rewriter to skip RLS policy application.

Permission fixes:
- Add ACL_DELETE permission flag for DELETE clause operations
- Add ACL_UPDATE permission flag for SET/REMOVE clause operations
- Recursively search RTEs including subqueries for permission info

RLS support:
- Implemented at executor level because age transforms all cypher
  queries to CMD_SELECT, so pg's rewriter never adds RLS
  policies for INSERT/UPDATE/DELETE operations. There isnt an
  appropriate rewriter hook to modify this behavior, so we do it
  in executor instead.
- Add setup_wcos() to apply WITH CHECK policies at execution time
  for CREATE, SET, and MERGE operations
- Add setup_security_quals() and check_security_quals() to apply
  USING policies for UPDATE and DELETE operations
- USING policies silently filter rows (matching pg behavior)
- WITH CHECK policies raise errors on violation
- DETACH DELETE raises error if edge RLS blocks deletion to prevent
  dangling edges
- Add permission checks and rls in startnode/endnode functions
- Add regression tests

Assisted-by AI

idk
@jrgemignani jrgemignani merged commit 1702ae0 into apache:master Jan 20, 2026
7 checks passed
jrgemignani pushed a commit to jrgemignani/age that referenced this pull request Jan 21, 2026
- Previously, age only set ACL_SELECT and ACL_INSERT in RTEPermissionInfo,
  bypassing pg's privilege checking for DELETE and UPDATE operations.
- Additionally, RLS policies were not enforced because AGE uses CMD_SELECT
  for all Cypher queries, causing the rewriter to skip RLS policy application.

Permission fixes:
- Add ACL_DELETE permission flag for DELETE clause operations
- Add ACL_UPDATE permission flag for SET/REMOVE clause operations
- Recursively search RTEs including subqueries for permission info

RLS support:
- Implemented at executor level because age transforms all cypher
  queries to CMD_SELECT, so pg's rewriter never adds RLS
  policies for INSERT/UPDATE/DELETE operations. There isnt an
  appropriate rewriter hook to modify this behavior, so we do it
  in executor instead.
- Add setup_wcos() to apply WITH CHECK policies at execution time
  for CREATE, SET, and MERGE operations
- Add setup_security_quals() and check_security_quals() to apply
  USING policies for UPDATE and DELETE operations
- USING policies silently filter rows (matching pg behavior)
- WITH CHECK policies raise errors on violation
- DETACH DELETE raises error if edge RLS blocks deletion to prevent
  dangling edges
- Add permission checks and rls in startnode/endnode functions
- Add regression tests

Assisted-by AI

Resolved Conflicts:
	src/backend/executor/cypher_create.c
	src/backend/executor/cypher_delete.c
	src/backend/executor/cypher_merge.c
	src/backend/executor/cypher_set.c
	src/backend/executor/cypher_utils.c
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

master override-stale To keep issues/PRs untouched from stale action

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants