Database security and access control

Maria Garcia Feb 2026
2 tabs
-- Create roles
CREATE ROLE readonly;
CREATE ROLE readwrite;
CREATE ROLE admin WITH LOGIN PASSWORD 'secure_password';

-- Grant permissions to roles
GRANT CONNECT ON DATABASE mydb TO readonly;
GRANT USAGE ON SCHEMA public TO readonly;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO readonly;

-- Grant future tables automatically
ALTER DEFAULT PRIVILEGES IN SCHEMA public
  GRANT SELECT ON TABLES TO readonly;

-- Read-write permissions
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public
  TO readwrite;
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO readwrite;

-- Create user and assign role
CREATE USER app_user WITH LOGIN PASSWORD 'password123';
GRANT readwrite TO app_user;

-- Revoke permissions
REVOKE DELETE ON users FROM readwrite;
REVOKE ALL ON TABLE sensitive_data FROM PUBLIC;

-- Column-level permissions
GRANT SELECT (id, email, name) ON users TO readonly;
-- Can't see password_hash, ssn, etc.

-- View permissions
SELECT
  grantee,
  table_schema,
  table_name,
  privilege_type
FROM information_schema.table_privileges
WHERE grantee = 'readonly';

-- Schema-level permissions
CREATE SCHEMA app_schema;
GRANT USAGE ON SCHEMA app_schema TO app_user;
GRANT ALL ON ALL TABLES IN SCHEMA app_schema TO app_user;

-- Function execution permissions
CREATE FUNCTION get_user_count() RETURNS INT AS $$
  SELECT COUNT(*) FROM users;
$$ LANGUAGE SQL SECURITY DEFINER;

GRANT EXECUTE ON FUNCTION get_user_count() TO readonly;

-- SECURITY DEFINER: Runs with creator's permissions
-- SECURITY INVOKER: Runs with caller's permissions (default)

-- Remove login capability
ALTER ROLE readonly NOLOGIN;

-- Set connection limits
ALTER ROLE app_user CONNECTION LIMIT 10;

-- Password policies
ALTER ROLE app_user VALID UNTIL '2025-12-31';

-- Require SSL connections
ALTER ROLE app_user SET ssl TO on;
2 files · sql Explain with highlit

Database security protects data from unauthorized access. I use GRANT/REVOKE for permissions—SELECT, INSERT, UPDATE, DELETE. Role-based access control groups permissions. Row-level security filters data per user. Column-level security restricts sensitive fields. Encryption at rest protects stored data. SSL/TLS encrypts connections. Audit logging tracks access patterns. Prepared statements prevent SQL injection. Principle of least privilege minimizes attack surface. Database users shouldn't share credentials. Connection limits prevent resource exhaustion. Understanding schema permissions, table ownership, and security definer functions is critical. Regular security audits identify vulnerabilities. Proper security requires defense in depth—multiple layers of protection.