# Security Features Implemented in pgrust: PostgreSQL's Security Model in Rust

> Explore pgrust's security features, including RLS policies and SECURITY DEFINER functions. Understand PostgreSQL's security model implemented in Rust for enhanced backend security.

- Repository: [Michael Malis/pgrust](https://github.com/malisper/pgrust)
- Tags: deep-dive
- Published: 2026-07-13

---

**The pgrust crate implements PostgreSQL's complete security stack—including security-restricted operations, SECURITY DEFINER functions, row-level security policies, and GUC enforcement—mirroring the original C implementation's permission model while running inside the Rust-based backend.**

pgrust is a Rust-based reimplementation of the PostgreSQL server that executes within the backend and must enforce the same stringent security constraints as the original C code. The security features implemented in pgrust replicate critical subsystems including privileged operation blocking, definer rights management, and row-level access controls. This analysis examines the specific source code files and functions that constitute the security architecture.

## Security-Restricted Operations

The **security-restricted operation** flag is a per-session boolean that blocks privileged actions while the backend is in a restricted state.

In [`crates/backend/utils/init/miscinit_seams/src/lib.rs`](https://github.com/malisper/pgrust/blob/main/crates/backend/utils/init/miscinit_seams/src/lib.rs), the `in_security_restricted_operation` seam provides read/write access to this flag. This mechanism prevents commands like `SET ROLE` or superuser-only GUC changes during sensitive operations such as `REINDEX`, `CLUSTER`, or execution within SECURITY DEFINER functions.

```rust
use crate::miscinit_seams::in_security_restricted_operation;

/// Returns true if the backend is currently inside a security-restricted
/// operation (e.g., REINDEX, CLUSTER, or a SECURITY DEFINER function).
fn is_restricted() -> bool {
    in_security_restricted_operation::call()
}

```

The flag is checked before allowing any privileged state transition, ensuring that operations occurring inside restricted blocks cannot escalate privileges.

## Security Definer Functions

**SECURITY DEFINER** functions execute with the privileges of their owner rather than the caller, requiring careful privilege switching logic.

The implementation resides in [`crates/backend/utils/fmgr/fmgr_core/src/lib.rs`](https://github.com/malisper/pgrust/blob/main/crates/backend/utils/fmgr/fmgr_core/src/lib.rs). The `fmgr_security_definer` seam determines whether to install a security definer call handler based on the `security_definer` flag stored in the procedure cache.

```rust
if proc.security_definer || fmgr_hook_is_needed(function_id) {
    // install fmgr_security_definer as the call handler
}

```

When declared with `#[pg_extern(security_definer = true)]`, functions run under the owner's security context:

```rust
#[pg_extern(security_definer = true)]
fn privileged_action() -> Result<(), PgBox<pg_error::Error>> {
    // This code runs with the privileges of the function's owner.
    // e.g., it may CREATE EXTENSION or SET superuser-only GUCs.
    Ok(())
}

```

The `security_definer` predicate is cached in the system cache at [`crates/backend/utils/cache/syscache_seams/src/lib.rs`](https://github.com/malisper/pgrust/blob/main/crates/backend/utils/cache/syscache_seams/src/lib.rs), allowing the executor to quickly determine if definer rights are required.

## Row-Level Security (RLS)

**Row-level security** policies filter rows based on the current user, enforced per-table through policy expressions.

Core RLS logic lives in [`crates/backend/utils/misc/more/src/rls.rs`](https://github.com/malisper/pgrust/blob/main/crates/backend/utils/misc/more/src/rls.rs). The `check_enable_rls` function determines whether RLS applies to a given table, while `row_security_active` and `row_security_active_name` provide SQL-callable interfaces to check policy status.

```rust
pub fn row_security_active(mcx: Mcx<'_>, tableoid: Oid) -> PgResult<bool> {
    // Core RLS decision logic lives in backend/utils/misc/more/src/rls.rs
}

```

The `row_security` GUC boolean, defined in [`crates/backend/utils/misc/guc_tables/src/vars.rs`](https://github.com/malisper/pgrust/blob/main/crates/backend/utils/misc/guc_tables/src/vars.rs), globally enables or disables RLS evaluation at backend startup. When active, the executor consults these functions to decide whether to apply row filters before returning data.

## GUC Enforcement and Configuration Security

The **Grand Unified Configuration (GUC)** system prevents changing superuser-only parameters during restricted operations.

In [`crates/backend/utils/misc/misc_guc/src/lib.rs`](https://github.com/malisper/pgrust/blob/main/crates/backend/utils/misc/misc_guc/src/lib.rs), the seam checks `in_security_restricted_operation` before allowing `SET` commands on privileged parameters:

```rust
use crate::misc_guc::set_config_parameter;

/// Attempt to set a super-user-only GUC while a restricted operation is active.
fn try_set_guc() -> Result<(), PgError> {
    if in_security_restricted_operation::call() {
        // This will raise: "cannot set parameter \"log_statement_stats\" within security-restricted operation"
        set_config_parameter("log_statement_stats", "on")
    } else {
        Ok(())
    }
}

```

This ensures that configuration changes that could compromise security or audit trails cannot occur inside security-definer contexts or other restricted blocks.

## Role Switching and Validation

When switching session users or security contexts via `SET ROLE`, pgrust validates the transition against the current security-restricted state.

The validation logic in [`crates/backend/utils/init/miscinit/src/lib.rs`](https://github.com/malisper/pgrust/blob/main/crates/backend/utils/init/miscinit/src/lib.rs) ensures that role changes cannot occur inside a restricted block. If `in_security_restricted_operation` returns true, the function raises an error before completing the transition, preventing privilege escalation during sensitive execution paths.

## Backend State Security Hooks

Security state must propagate to parallel workers and statistics collection subsystems. The `pgstat_bestart_security` seam in [`crates/backend/utils/init/postinit/src/lib.rs`](https://github.com/malisper/pgrust/blob/main/crates/backend/utils/init/postinit/src/lib.rs) initializes the security context for background workers, ensuring that restricted flags carry over to spawned processes.

Procedural languages like PL/pgSQL reuse these security mechanisms through the handler modules in [`crates/pl/plpgsql/src/handler/src/lib.rs`](https://github.com/malisper/pgrust/blob/main/crates/pl/plpgsql/src/handler/src/lib.rs), ensuring that functions written in higher-level languages respect the same definer-rights and restricted-operation checks as compiled code.

## Summary

- **Security-restricted operations** are guarded by the `in_security_restricted_operation` flag in `miscinit_seams`, blocking privileged commands during sensitive execution.
- **SECURITY DEFINER** functions are handled by `fmgr_security_definer` in the Fmgr core, which switches execution context based on cached predicates from the syscache.
- **Row-level security** policies are enforced through `check_enable_rls` and the `row_security_active` functions, controlled by the `row_security` GUC.
- **GUC enforcement** prevents superuser-only configuration changes during restricted operations via checks in `misc_guc`.
- **Role switching** is validated against the restricted flag in `miscinit`, preventing privilege escalation during restricted blocks.
- **Backend hooks** propagate security state to parallel workers through `pgstat_bestart_security` in the post-init module.

## Frequently Asked Questions

### How does pgrust implement the security-restricted operation flag?

The flag is implemented as a seam in [`crates/backend/utils/init/miscinit_seams/src/lib.rs`](https://github.com/malisper/pgrust/blob/main/crates/backend/utils/init/miscinit_seams/src/lib.rs) that provides `in_security_restricted_operation::call()`. This function returns a boolean indicating whether the current session is inside a restricted block, which is checked before allowing privileged operations like GUC changes or role switches.

### What is the difference between SECURITY DEFINER handling in pgrust versus standard PostgreSQL?

pgrust implements the same semantic model as standard PostgreSQL but uses Rust-based seams. The `fmgr_security_definer` logic in [`crates/backend/utils/fmgr/fmgr_core/src/lib.rs`](https://github.com/malisper/pgrust/blob/main/crates/backend/utils/fmgr/fmgr_core/src/lib.rs) checks the `security_definer` boolean stored in the system cache (via `syscache_seams`) and installs the appropriate call handler to switch to the function owner's privileges during execution.

### Does pgrust support row-level security policies?

Yes. pgrust implements full RLS support through [`crates/backend/utils/misc/more/src/rls.rs`](https://github.com/malisper/pgrust/blob/main/crates/backend/utils/misc/more/src/rls.rs), which contains `check_enable_rls` for policy decisions and `row_security_active` for SQL-level checks. The feature is controlled by the `row_security` GUC defined in [`guc_tables/src/vars.rs`](https://github.com/malisper/pgrust/blob/main/guc_tables/src/vars.rs), matching PostgreSQL's behavior exactly.

### How does pgrust prevent unauthorized GUC changes during restricted operations?

Before processing a `SET` command for superuser-only parameters, the `misc_guc` seam in [`crates/backend/utils/misc/misc_guc/src/lib.rs`](https://github.com/malisper/pgrust/blob/main/crates/backend/utils/misc/misc_guc/src/lib.rs) calls `in_security_restricted_operation::call()`. If the flag is true, it raises an error preventing the change, ensuring that security-definer functions and other restricted contexts cannot modify critical configuration parameters.