Skip to content
View rls-guard's full-sized avatar

Block or report rls-guard

Block user

Prevent this user from interacting with your repositories and sending you notifications. Learn more about blocking users.

You must be logged in to block users.

Maximum 250 characters. Please don’t include any personal information such as legal names or email addresses. Markdown is supported. This note will only be visible to you.
Report abuse

Contact GitHub support about this user’s behavior. Learn more about reporting abuse.

Report abuse
rls-guard/README.md

RLS Guard

A powerful CLI tool for managing PostgreSQL Row Level Security (RLS) policies as code using TypeScript.

Features

  • πŸ”’ Declarative RLS policies - Define your security policies in TypeScript using a fluent API
  • πŸš€ Easy deployment - Deploy policies to your PostgreSQL database with a single command
  • πŸ“₯ Policy extraction - Pull existing RLS policies from your database and generate TypeScript configs
  • πŸ” Dry-run support - Preview SQL commands before executing them
  • 🎯 Type-safe configuration - Full TypeScript support with intellisense and type checking
  • πŸ—οΈ Built-in helpers - Common RLS patterns like user isolation, tenant separation, and role-based access
  • πŸ”§ Cross-platform - Works on macOS, Linux, and Windows

Installation

Install via npm:

npm install -g rls-guard

Quick Start

  1. Initialize a new configuration:

    rls-guard init
  2. Configure your database and policies in rls.config.ts:

    import { config, currentUserId, tenantId, publicAccess } from 'rls-guard/lib/rls-config';
    
    const rlsConfig = config()
      .database(db => db
        .connectionUrl("postgresql://user:pass@localhost:5432/mydb")
      )
      
      // Users can only see their own records
      .addPolicy(p => p
        .name("user_isolation")
        .onTable("users")
        .forCommand("SELECT")
        .withExpression(currentUserId())
        .forRoles("authenticated_user")
      )
      
      // Admin users have full access
      .addPolicy(p => p
        .name("admin_full_access")
        .onTable("users")
        .forCommand("ALL")
        .withExpression(publicAccess())
        .forRoles("admin")
      );
    
    export default rlsConfig;
  3. Deploy your policies:

    # Preview changes
    rls-guard deploy --dry-run
    
    # Apply to database
    rls-guard deploy

Configuration

Database Connection

Connect using a connection URL:

.database(db => db
  .connectionUrl("postgresql://user:pass@localhost:5432/mydb?sslmode=disable")
)

Or individual parameters:

.database(db => db
  .host("localhost")
  .port(5432)
  .database("mydb")
  .username("user")
  .password("pass")
  .ssl(false)
)

Policy Types

Permissive policies (default) - Allow access when conditions are met:

.addPolicy(p => p
  .name("user_data_access")
  .onTable("user_data")
  .forCommand("SELECT")
  .withExpression(currentUserId())
  .forRoles("user")
  .asPermissive()  // This is the default
)

Restrictive policies - Block access unless conditions are met:

.addPolicy(p => p
  .name("sensitive_data_restriction")
  .onTable("sensitive_data")
  .forCommand("SELECT")
  .withExpression("false")  // Block by default
  .forRoles("public")
  .asRestrictive()
)

Built-in Helper Functions

  • currentUserId(column?) - Match current user ID
  • tenantId(column?) - Multi-tenant isolation
  • recentData(column, days) - Time-based access
  • ownerOnly(userCol, ownerCol) - Owner-based access
  • roleCheck(role) - Role-based conditions
  • publicAccess() - Always allow (returns true)
  • noAccess() - Always deny (returns false)

Commands

rls-guard init

Create a new rls.config.ts file with example policies.

rls-guard pull [options]

Extract existing RLS policies from your PostgreSQL database and generate a configuration file.

Options:

  • --connection <url> - Database connection string (or set DATABASE_URL env var)
  • --output, -o <file> - Output file path (default: rls.config.ts)
  • --tables, -t <tables> - Comma-separated list of tables to extract
  • --format, -f <format> - Output format: typescript or json (default: typescript)
  • --comments, -c - Add explanatory comments to generated config
  • --no-mask - Don't mask sensitive connection info in output

Example:

# Extract all policies to TypeScript config
rls-guard pull --connection "postgresql://user:pass@localhost:5432/mydb"

# Extract specific tables with comments
rls-guard pull --tables "users,posts" --comments --output policies.config.ts

rls-guard deploy [options]

Deploy RLS policies to your PostgreSQL database.

Options:

  • --dry-run - Show SQL commands without executing them
  • --config, -c <path> - Path to config file (default: rls.config.ts)

Requirements

  • Node.js 18+
  • PostgreSQL 9.5+ (RLS support)
  • TypeScript configuration file

Contributing

We welcome contributions! RLS Guard is an open-source project that benefits from community involvement.

πŸ—ΊοΈ Feature Roadmap

Check out our Feature Roadmap to see planned features and improvements. Pick any item that interests you!

πŸš€ Quick Start for Contributors

  1. Fork the repository on GitHub
  2. Clone your fork locally
  3. Install dependencies: npm install
  4. Submit a pull request with a clear description

🎯 Ways to Contribute

  • πŸ› Report bugs - Found an issue? Let us know!
  • πŸ’‘ Suggest features - Ideas for improvements are welcome
  • πŸ“š Improve docs - Help make RLS Guard easier to use
  • πŸ§ͺ Add tests - Help us maintain quality
  • ⚑ Performance - Optimize queries and connections
  • 🎨 UX improvements - Better CLI output and error messages

πŸ“‹ Development Areas

  • CLI enhancements and better error handling
  • Additional PostgreSQL features and cloud provider support
  • IDE integrations (VS Code extension, auto-completion)
  • Policy templates and testing frameworks
  • CI/CD integrations and monitoring tools

See the complete roadmap for detailed feature plans and development priorities.

License

MIT License

Popular repositories Loading

  1. rls-guard rls-guard Public

    TypeScript

  2. hello-py hello-py Public

    Python 22