Dynamic, database-backed permission systems allow enterprise applications to enforce fine-grained access control lists (ACLs) and attribute-based access control (ABAC) at runtime without requiring static configuration file redeployments.
This guide details database schema design for dynamic permissions, PostgreSQL Row-Level Security (RLS), Open Policy Agent (OPA) integration, and multi-tier permission caching.
+-----------------------------------------------------------------------------------------+
| PERMISSION SCHEMA PATTERNS |
+-----------------------------------------------------------------------------------------+
| Model | Advantages | Performance Considerations |
+------------------------+-----------------------------------+----------------------------+
| Normalized ACL Tables | Granular per-resource overrides | Requires JOIN on every read|
| Row-Level Security(RLS)| Enforced in DB engine kernel | Query planner optimization |
| Policy Engine (OPA) | Decoupled Rego business logic | In-memory sub-ms latency |
| Precomputed Bitmasks | Ultra-fast bitwise AND operations | Static role ceiling limits |
+-----------------------------------------------------------------------------------------+
-- Enabling RLS on Wiki Pages
ALTER TABLE wiki_pages ENABLE ROW LEVEL SECURITY;
-- Policy: Users can read public pages or pages in their tenant group
CREATE POLICY page_read_policy ON wiki_pages
FOR SELECT
USING (
is_public = TRUE
OR tenant_id = CURRENT_SETTING('app.current_tenant_id')::UUID
OR EXISTS (
SELECT 1 FROM page_acl
WHERE page_acl.page_id = wiki_pages.id
AND page_acl.user_id = CURRENT_SETTING('app.current_user_id')::UUID
AND page_acl.permission = 'READ'
)
);
To prevent database bottlenecks, permissions are evaluated once and cached in Redis with a 5-minute TTL. Invalidation events are published when user roles or group memberships change.