This guide walks you through auditing who can access what in an Apache Iceberg table, across the catalog, storage, and compute layers. You’ll learn how to map permissions, identify gaps, and produce a clear audit report. Before starting, ensure you have administrative access to your Iceberg catalog (e.g., AWS Glue, Nessie, Hive Metastore), the underlying storage (S3, ADLS, GCS), and any query engines (Spark, Trino, Flink) that read the table.
What You’ll Need
- Admin credentials for the Iceberg catalog (to read table metadata and permissions)
- Storage account access (to list and check bucket/container policies)
- Access to query engine configuration (to review runtime credentials and SQL grants)
- A spreadsheet or text file to record findings
- Basic familiarity with SQL and command-line tools
Step-by-Step
- Identify all Iceberg tables in scope. Use your catalog’s API or CLI to list tables. For example, with AWS Glue:
aws glue get-tables --database-name your_db. Record table names, locations, and creation timestamps. - Map the data layers for each table. Iceberg separates metadata from data. Note the metadata file location (usually under
metadata/) and the data file location (underdata/). Also note any manifest lists and manifest files. - Audit catalog-level permissions. For each table, check who has SELECT, INSERT, UPDATE, DELETE, or ALTER grants. In Hive Metastore:
SHOW GRANT ON TABLE your_table. In AWS Glue: check the resource policy and Lake Formation permissions. In Nessie: review branch and tag ACLs. Record the principal (user/role) and the privilege. - Audit storage-level access. For the table’s data and metadata paths, list the bucket/container ACLs and bucket policies. For S3, run
aws s3api get-bucket-policy --bucket your-bucketandaws s3api get-bucket-acl --bucket your-bucket. Check for cross-account access, public access, and any conditions (like IP allowlists). Also check object-level permissions if you use bucket-owner-enforced settings. - Audit compute engine access. For each query engine that accesses the table, review the SQL grants. For Spark SQL:
SHOW GRANT ON TABLE your_table(if using Spark’s SQL standard). For Trino/Presto: queryinformation_schema.table_privileges. Also check the engine’s service account or role – the engine uses that identity to read from storage, so it must be in the storage allowlist. - Cross-reference the layers. For each principal, verify they have the same effective access across all layers. For example, a user with SELECT in the catalog but no storage read permission will fail. Conversely, a user with storage read but no catalog grant bypasses the catalog. Create a matrix: principal vs. catalog privilege vs. storage permission vs. engine grant.
- Check for wildcard and overly broad grants. Look for grants like
ALL PRIVILEGESon the database or table, or bucket policies with"Principal":"*". Flag these for review. - Review service accounts and roles. Identify which service accounts (e.g., Spark executor role) have access. Ensure they have least-privilege. For example, a read-only ETL job should not have write access to the table’s storage.
- Check for external and anonymous access. Look for any public read/write on the storage bucket, or any catalog setting that allows unauthenticated access. In S3, check for
"Effect":"Allow","Principal":"*"in the bucket policy. - Document findings. Create a report with: table name, catalog grants, storage policies, engine grants, and any discrepancies. Note the date of the audit and who performed it.
- Remediate and re-audit. For any gaps, adjust permissions. Then re-run the audit to confirm. Schedule regular audits (e.g., quarterly).
Common Mistakes
- Only auditing the catalog and ignoring storage – the most common gap. Storage permissions are the actual gate to data files.
- Forgetting that query engines use a service role, not the user’s personal credentials. You must audit the engine’s role, not just the user.
- Assuming the table location is the only path. Iceberg can have data files in multiple locations if you use partition evolution or multiple writers.
- Overlooking metadata files. If someone can write to the metadata directory, they can replace the table with a malicious version.
- Not checking for time-bound or condition-based policies. A policy that allows access only during business hours still needs auditing.
Tips
- Use the Iceberg REST catalog API if available – it provides a unified view of table metadata and can be queried programmatically.
- Automate the audit with scripts. For example, use `aws s3api get-bucket-policy` in a loop and parse the JSON.
- Keep a baseline of permissions after a clean setup, so you can diff against it later.
- Use tag-based policies in storage (e.g., S3 tags) to mark sensitive tables, then audit all resources with that tag.
- When using Lake Formation, make sure to audit both the Lake Formation grants and the underlying S3 policies – they work together.
- Test access with a dummy user or role to confirm what they can actually do, rather than just reading policies.
Troubleshooting
You get “Access Denied” when trying to list tables. Your catalog admin credentials may be insufficient. Check that you have the `GetTable` and `GetDatabase` permissions. If using Glue, ensure your IAM role has `glue:GetTables`.
You can see the catalog grants but not the storage bucket. You might not have permission to list the bucket. Ask the storage admin for read-only access to the bucket policy. If you cannot get it, ask them to run the policy check for you.
You find a user with catalog SELECT but no storage read – but they say they can query fine. The engine might be using a different role (e.g., a shared service role) that has storage access. Check the engine’s configuration to see which IAM role it assumes.
The audit report is huge and unmanageable. Filter by table or by principal. Start with the most sensitive tables (e.g., those containing PII).
You see a “public” bucket policy but can’t confirm it’s being used. Use a tool like `aws s3api get-bucket-policy-status` to see if the policy is actually applied and if public access is blocked at the account level.
Frequently Asked Questions
What exactly counts as a data layer in Iceberg?
There are three main layers: the catalog (metadata store), the storage (where data and metadata files live), and the compute engine (which reads/writes via a role). Some also consider the file format (Parquet/ORC) as a layer, but that’s not about access control.
Do I need to audit every single table?
Ideally yes, but start with tables that contain sensitive data or are accessed by many teams. You can also audit by database or by using automated scripts to cover all tables.
How often should I run an access audit?
At least quarterly, and after any major change like a new team member, a new engine, or a storage migration. Some organizations run it monthly.
Can I use the Iceberg REST catalog to simplify auditing?
Yes, the REST catalog provides a single endpoint for metadata and can be integrated with your own authorization layer. It makes auditing easier because you can query permissions via the API.
What’s the difference between catalog grants and storage policies?
Catalog grants control who can see the table and its metadata. Storage policies control who can read or write the actual files. Both must align for a user to access data.
What should I do if I find a mismatch?
Immediately document it and decide the correct access level. If a user has catalog access but no storage, grant storage read (or remove catalog access). If a user has storage but no catalog, remove storage access or add catalog grant. Always follow least-privilege.
Related
Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.
More cards in this drawer
- Access the DOM in Angular Safely
- Websites Create QR Code? How It Works
- Evaluate Private Cloud AI Security Operations Platforms
- Space Engineers Server Name & Description Setup
- Tongue Escape Events Schedule: Full Guide
- How to Turn Off Google AI Overview