Complete Guide to Creating Read-Only Users in PostgreSQL

Nov 13, 2025 · Programming · 12 views · 7.8

Keywords: PostgreSQL | Read-Only User | Permission Management | GRANT Command | Database Security

Abstract: This article provides a comprehensive guide to creating read-only users in PostgreSQL, covering user role creation, permission granting, schema access control, and other essential steps. It explores fundamental permission settings to advanced default privilege configurations, offering solutions tailored to different PostgreSQL versions while delving into the underlying mechanisms of the permission system. Through detailed code examples and theoretical explanations, readers will gain a thorough understanding of PostgreSQL permission management concepts and practical techniques.

Overview of PostgreSQL Permission System

PostgreSQL's permission management system is based on the concept of roles, which differs significantly from other database systems like MySQL. In PostgreSQL, both users and groups are implemented through roles, providing a unified design that makes permission management more flexible and consistent. Understanding PostgreSQL's permission hierarchy is crucial for properly configuring read-only users.

Basic Permission Configuration Process

The first step in creating a read-only user is to establish the role and set connection permissions. The following code demonstrates the complete configuration process:

-- Create read-only user role
CREATE ROLE readonly_user WITH LOGIN PASSWORD 'secure_password';

-- Connect to target database
\c target_database;

-- Grant database connection permission
GRANT CONNECT ON DATABASE target_database TO readonly_user;

-- Grant schema usage permission
GRANT USAGE ON SCHEMA public TO readonly_user;

-- Grant query permission on existing tables
GRANT SELECT ON ALL TABLES IN SCHEMA public TO readonly_user;

Detailed Permission Hierarchy

PostgreSQL's permission system employs a hierarchical structure, with permissions refined layer by layer from the database level down to the object level. The GRANT CONNECT permission at the database level only allows users to connect to the database, while actual table access permissions must be granted separately at the schema and table levels. This design ensures fine-grained permission control but also increases configuration complexity.

Bulk Permission Management Techniques

For databases containing a large number of tables, granting permissions individually is impractical. PostgreSQL version 9.0 and above provide bulk permission management functionality:

-- Grant query permission on all tables in schema
GRANT SELECT ON ALL TABLES IN SCHEMA public TO readonly_user;

-- Grant read permission on sequences (optional)
GRANT SELECT ON ALL SEQUENCES IN SCHEMA public TO readonly_user;

Default Permission Configuration

To ensure that newly created tables automatically inherit permission settings, use the ALTER DEFAULT PRIVILEGES command:

-- Set default query permissions for future tables
ALTER DEFAULT PRIVILEGES IN SCHEMA public
    GRANT SELECT ON TABLES TO readonly_user;

It's important to note that default permissions only affect objects created by the user executing the command. In team development environments, it's recommended that the database owner uniformly sets default permissions.

Legacy Version Compatibility Solutions

For PostgreSQL versions prior to 9.0, dynamic SQL can be used to generate permission grant statements:

SELECT 'GRANT SELECT ON ' || relname || ' TO readonly_user;'
FROM pg_class 
JOIN pg_namespace ON pg_namespace.oid = pg_class.relnamespace
WHERE nspname = 'public' 
    AND relkind IN ('r', 'v', 'S');

This method generates corresponding GRANT statements by querying system catalog tables, making it suitable for situations with a large number of tables.

Permission Verification and Testing

After configuration is complete, it's essential to verify the correctness of permission settings. Testing can be performed through the following steps:

-- Connect as read-only user
psql -U readonly_user -d target_database

-- Test query permissions
SELECT * FROM some_table LIMIT 1;

-- Test write permissions (should fail)
INSERT INTO some_table VALUES (1, 'test');

Security Best Practices

When configuring read-only users, consider the following security measures:

Common Issues and Solutions

In practical applications, you might encounter issues where permission configurations don't take effect. Common causes include:

Through systematic permission configuration and rigorous testing procedures, you can ensure that read-only user functionality meets expectations.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.