Requirements & goals:- Allow data engineers full modify/manage on metadata and pipelines.- Analysts: read/subscribe/annotate, limited schema edits (e.g., add tags).- External partners: restricted read on specific schemas/tables and row-level filters.- Enforce least privilege, auditable changes, and flexible policy authoring.High-level design:- Centralized policy engine (e.g., AWS Lake Formation/IAM, Apache Ranger, or OPA + custom authz) integrated with data catalog (Glue/Atlas/Amundsen) and query engines (Presto, BigQuery, Snowflake).- Two layers of enforcement: 1) Schema-level (catalog/table/column) 2) Row-level (RLS predicates or views)Schema-level approach:- Role definitions: data_engineer, analyst, partner.- Resource model: catalog > database/schema > table > column > tag/column-metadata.- Policies stored as RBAC entries (role -> resource -> actions: read, write, manage, tag).- Example policy (JSON) for a partner read on a table:json
{ "role": "partner", "resource": "sales.public.transactions", "actions": ["select"], "columns": ["id","amount","date"] }
- Enforcement: query engine checks catalog policy before allowing metadata or data access. Column masking allowed via policy (e.g., mask email).Row-level approach:- Implement RLS using native DB features (Postgres RLS, Snowflake row access policies, BigQuery authorized views) or query-time predicates from the policy engine.- Example Postgres RLS predicate for partners (only see their org_id):sql
CREATE POLICY partner_rls ON transactions USING (current_setting('request.org_id')::int = org_id);
- Alternatively generate parameterized views: CREATE VIEW partner_tx AS SELECT * FROM transactions WHERE org_id = :org_id; grant SELECT on view.Integration & workflow:- Use IAM/group sync from SSO (Okta/AzureAD) to map users to roles.- Admin UI in catalog for owners to grant role-scoped access, tags, and approvals; store policies in versioned git-backed store.- Enforcement points: metadata API (catalog UI), query engine (pre-exec), and ETL jobs (service principals).Auditing, testing, and lifecycle:- Log every policy change, metadata edit, and data access with requestor, role, resource, and query.- Periodic access reviews and automated least-privilege checks.- Unit tests for policies (simulate users), integration tests in staging, and monitor denied accesses to tune rules.Trade-offs & notes:- Native RLS is safest for row-level; view-based approaches easier to audit but may proliferate objects.- Central policy engine adds complexity but unifies access across heterogeneous stores.- Start with coarse-grained RBAC + tag-based column sensitivity, then iterate to fine-grained RLS for partners and sensitive fields.