Glossary/SQL Security — Users, Roles, GRANT & REVOKE
SQL & Databases

SQL Security — Users, Roles, GRANT & REVOKE

Controlling who can see and change what in your database.


Definition

SQL security manages database access through users (individual accounts), roles (named groups of permissions), and privileges (specific actions allowed on specific objects). GRANT gives privileges to a user or role. REVOKE removes them. Row-Level Security (RLS) restricts which rows a user can see within a table. Proper database security follows the principle of least privilege — users get only the permissions they need for their job, nothing more. Critical for production databases handling sensitive data.

Users, roles, and the least-privilege principle

Creating users and roles in PostgreSQL

-- CREATE USER (creates a login account)
CREATE USER api_user WITH PASSWORD 'SecurePass123!';
CREATE USER reporting_user WITH PASSWORD 'Reports2024!';
CREATE USER admin_user WITH PASSWORD 'AdminPass!' CREATEDB CREATEROLE;

-- Attributes that control login capabilities:
-- SUPERUSER / NOSUPERUSER: full admin access (avoid granting this!)
-- CREATEDB: can create databases
-- CREATEROLE: can create other roles
-- LOGIN / NOLOGIN: can this account log in?
-- CONNECTION LIMIT n: max concurrent connections (-1 = unlimited)

-- CREATE ROLE (like a group — typically no LOGIN by default)
CREATE ROLE readonly;       -- Group role: no login, just permission grouping
CREATE ROLE readwrite;
CREATE ROLE finance_team;
CREATE ROLE app_backend;

-- GRANT role to user (assign group membership)
GRANT readonly      TO reporting_user;
GRANT readwrite     TO api_user;
GRANT finance_team  TO reporting_user;
GRANT app_backend   TO api_user;

-- A user inherits all privileges of their assigned roles
-- reporting_user has: readonly + finance_team permissions

GRANT and REVOKE privileges

Complete GRANT/REVOKE reference

-- GRANT: give privileges
-- Syntax: GRANT privilege ON object TO user/role

-- TABLE privileges
GRANT SELECT ON Employee TO readonly;           -- Read only
GRANT SELECT, INSERT, UPDATE ON Orders TO readwrite;  -- Read + write
GRANT ALL PRIVILEGES ON Product TO admin_user;  -- Full control

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

-- Auto-grant on future tables too (PostgreSQL)
ALTER DEFAULT PRIVILEGES IN SCHEMA public
    GRANT SELECT ON TABLES TO readonly;

-- Specific column-level privileges (PostgreSQL/SQL Server)
GRANT SELECT (EmpID, Name, DeptID) ON Employee TO reporting_user;
-- reporting_user can query EmpID, Name, DeptID but NOT Salary or SSN!

-- Grant with GRANT OPTION (allows the grantee to grant to others)
GRANT SELECT ON Product TO team_lead WITH GRANT OPTION;

-- DATABASE-level privileges
GRANT CONNECT ON DATABASE mydb TO api_user;
GRANT CREATE  ON DATABASE mydb TO admin_user;

-- SCHEMA-level privileges
GRANT USAGE ON SCHEMA public TO readonly;   -- Can see objects in schema
GRANT CREATE ON SCHEMA public TO dev_user;  -- Can create objects

-- FUNCTION / PROCEDURE privileges
GRANT EXECUTE ON FUNCTION GetEmployeeGrade(INT) TO api_user;

-- REVOKE: remove privileges
REVOKE INSERT ON Orders FROM readwrite;    -- Remove specific privilege
REVOKE ALL PRIVILEGES ON Employee FROM reporting_user;  -- Remove all
REVOKE GRANT OPTION FOR SELECT ON Product FROM team_lead;  -- Remove grant option only

-- Check current privileges
SELECT grantee, privilege_type, table_name
FROM information_schema.role_table_grants
WHERE table_name = 'employee';

-- PostgreSQL: show all grants on a table
dp employee

Row-Level Security (RLS)

Row-Level Security — each user sees only their data

-- RLS: restrict which rows a user can read/modify
-- Use case: SaaS multi-tenant database — each tenant only sees their own data

-- 1. Enable RLS on the table
ALTER TABLE Orders ENABLE ROW LEVEL SECURITY;

-- 2. Create policies defining which rows are visible
-- Policy: each user can only see orders belonging to their company
CREATE POLICY tenant_isolation ON Orders
    USING (tenant_id = current_setting('app.current_tenant_id')::INT);

-- Policy: managers can see all orders; staff only see their own
CREATE POLICY manager_sees_all ON Employee
    USING (
        current_user = 'hr_manager'    -- HR manager sees everything
        OR EmpID = (SELECT EmpID FROM UserMapping WHERE Username = current_user)
    );

-- Policy: sales reps can only UPDATE their own opportunities
CREATE POLICY sales_rep_update ON Opportunity
    FOR UPDATE
    USING (assigned_to = current_user)
    WITH CHECK (assigned_to = current_user);

-- BYPASSRLS: superusers bypass RLS (for admin operations)
ALTER USER admin_user BYPASSRLS;

-- Set the tenant context when connecting (app-level)
SET app.current_tenant_id = '42';
SELECT * FROM Orders;  -- Only returns orders where tenant_id = 42

-- View: alternative to RLS for simpler cases
CREATE VIEW MyOrders AS
    SELECT * FROM Orders WHERE CustomerID = current_user_id();
GRANT SELECT ON MyOrders TO customer_role;
Privilege levelObjectPrivilegeDescription
DatabaseDATABASECONNECT, CREATE, TEMPCan connect/create objects/temp tables in database
SchemaSCHEMAUSAGE, CREATECan see objects / create objects in schema
TableTABLESELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCESDML operations on the table
ColumnCOLUMNSELECT, INSERT, UPDATEAccess specific columns only
FunctionFUNCTIONEXECUTECan call the function
SequenceSEQUENCEUSAGE, SELECT, UPDATECan use auto-increment sequences

Practice questions

  1. Difference between GRANT SELECT ON Employee TO user1 and GRANT SELECT (Name, DeptID) ON Employee TO user1: (Answer: First grants access to ALL columns of Employee. Second grants access to ONLY Name and DeptID columns — SELECT * still works but shows only those two columns. Column-level grants enable fine-grained access control for sensitive data like Salary, SSN, DOB.)
  2. What is the principle of least privilege in database security? (Answer: Users and applications should have ONLY the minimum permissions needed for their specific function. An API that only reads product data should have SELECT on Products only — not INSERT, UPDATE, DELETE, or access to Employee/Customer tables. Reduces damage if credentials are compromised.)
  3. REVOKE SELECT ON Employee FROM readonly — does this affect users with the readonly role? (Answer: Yes — if the privilege was granted to the readonly role, revoking it from the role removes it from all users who have that role. If a user also has SELECT granted directly, they retain it.)
  4. What is Row-Level Security used for? (Answer: RLS restricts which rows each user can see/modify within a table, without creating separate tables or views. Used for multi-tenant SaaS (each tenant sees only their data), departmental data access (HR sees only their department), or any scenario where row visibility depends on the user.)
  5. WITH GRANT OPTION — what does it mean? (Answer: Allows the grantee to grant the same privilege to others. GRANT SELECT ON Employee TO team_lead WITH GRANT OPTION means team_lead can also do: GRANT SELECT ON Employee TO other_user. Be careful — this creates chains of privilege that are hard to revoke fully.)

On LumiChats

LumiChats can design a complete permission matrix for your database, write all GRANT/REVOKE statements for a multi-role application, and implement Row-Level Security policies for multi-tenant scenarios. Describe your user types and data access requirements.

Try it free

Try LumiChats for ₹69

39+ AI models. Study Mode with page-locked answers. Agent Mode with code execution. Pay only on days you use it.

Get Started — ₹69/day

Related Terms

4 terms