rbac: improve permission denied error messages#35880
rbac: improve permission denied error messages#35880maheshwarip wants to merge 3 commits intomainfrom
Conversation
Enhance permission denied error messages to provide more actionable
information to users:
1. Direct errors (role lacks privileges on an object):
- Show which role needs which privileges
- Show who owns the object
- Provide HINT with suggested GRANT command
2. Indirect errors (MV/view owner lacks privileges on dependency):
- Explain the dependency relationship
- Show which object in the lineage is causing the problem
- Provide HINT targeting the correct role (the owner who needs access)
Example direct error:
ERROR: permission denied for TABLE "schema.my_table"
DETAIL: The 'user1' role needs SELECT privileges on TABLE "schema.my_table"
The owner of TABLE "schema.my_table" is 'user2'
HINT: The owner ('user2') of TABLE "schema.my_table" or a superuser
can grant access: GRANT SELECT ON TABLE "schema.my_table" TO 'user1'
Example indirect error (querying an MV where owner lost access to dependency):
ERROR: permission denied for TABLE "schema.source_table"
DETAIL: The 'mv_owner' role needs SELECT privileges on TABLE "schema.source_table"
The owner of TABLE "schema.source_table" is 'source_owner'
MATERIALIZED VIEW "schema.my_mv" references TABLE "schema.source_table"
HINT: The owner ('source_owner') of TABLE "schema.source_table" or a superuser
can grant access: GRANT SELECT ON TABLE "schema.source_table" TO 'mv_owner'
Related to discussion:
https://materializeinc.slack.com/archives/CU7ELJ6E9/p1775481281751919
https://claude.ai/code/session_01FLZQqa7mRprzCTQT6oQ3Ss
|
Thanks for opening this PR! Here are a few tips to help make the review process smooth for everyone. PR title guidelines
Pre-merge checklist
|
|
There's a chance this is slop - I'm not familiar with this part of our repo! At a glance, if this is wrong, feel free to just close the PR |
| match object_id { | ||
| SystemObjectId::System => None, | ||
| SystemObjectId::Object(ObjectId::Cluster(id)) => { | ||
| Some(catalog.get_role(&catalog.get_cluster(*id).owner_id()).name().to_string()) |
There was a problem hiding this comment.
Should probably have a function owner_id on SessionCatalog that returns Option<RoleId>. Similarly, consider making get_object_owner a function on SessionCatalog. The goal is to remove duplication and separate concerns.
…thod Address review feedback by using the existing `get_owner_id` method on `SessionCatalog` instead of duplicating the logic. https://claude.ai/code/session_01FLZQqa7mRprzCTQT6oQ3Ss
def-
left a comment
There was a problem hiding this comment.
Do we still plan to merge this?
| "{} can grant access: GRANT {} ON {} TO '{}'", | ||
| granter, privileges, object_description, grant_target |
There was a problem hiding this comment.
| "{} can grant access: GRANT {} ON {} TO '{}'", | |
| granter, privileges, object_description, grant_target | |
| "{} can grant access: GRANT {} ON {} TO {}", | |
| granter, privileges, object_description, Ident::new_unchecked(grant_target) |
There was a problem hiding this comment.
Done - updated to use Ident::new_unchecked(grant_target) for proper identifier formatting.
Generated by Claude Code
| db error: ERROR: permission denied for SCHEMA "materialize.public" | ||
| DETAIL: The 'joe' role needs CREATE privileges on SCHEMA "materialize.public" | ||
| The owner of SCHEMA "materialize.public" is 'mz_system' | ||
| HINT: The owner ('mz_system') of SCHEMA "materialize.public" or a superuser can grant access: GRANT CREATE ON SCHEMA "materialize.public" TO 'joe' |
There was a problem hiding this comment.
| HINT: The owner ('mz_system') of SCHEMA "materialize.public" or a superuser can grant access: GRANT CREATE ON SCHEMA "materialize.public" TO 'joe' | |
| HINT: The owner ('mz_system') of SCHEMA "materialize.public" or a superuser can grant access: GRANT CREATE ON SCHEMA "materialize.public" TO joe |
'' is wrong, it should be "", or no quoting when not required. Same in other tests
There was a problem hiding this comment.
Fixed - updated all test expectations to use proper identifier quoting (no single quotes for simple identifiers).
Generated by Claude Code
Address review feedback: Use `Ident::new_unchecked` for role names in GRANT hint messages instead of single quotes. This produces properly formatted SQL identifiers. https://claude.ai/code/session_01FLZQqa7mRprzCTQT6oQ3Ss
Summary
Improves "permission denied" error messages to provide more actionable information to users:
Direct errors (role lacks privileges on an object):
Indirect errors (MV/view owner lacks privileges on dependency):
Example - Direct Error
Example - Indirect Error (querying MV where owner lost access to dependency)
Motivation
Users encountering permission denied errors often don't know:
This PR addresses all three by enriching error messages with owner information and actionable HINT suggestions.
Test plan
bin/sqllogictest -- test/sqllogictest/permission_denied_errors.sltbin/sqllogictest -- --rewrite-results test/sqllogictest/privilege_checks.sltto update remaining tests for new error formatRelated
Slack thread: https://materializeinc.slack.com/archives/CU7ELJ6E9/p1775481281751919
https://claude.ai/code/session_01FLZQqa7mRprzCTQT6oQ3Ss