Which role takes precedence when users have overlapping privileges?
0 reputation · 28 Jun 2024, 03:21 UTC
0 reputation · 28 Jun 2024, 03:21 UTC
Firebird implements a Role-Based Access Control (RBAC) system where administrators use GRANT and REVOKE statements to enforce least-privilege access. In complex environments, a single user may be assigned multiple roles that grant overlapping or conflicting permissions to the same database objects.
While the system allows for multiple role assignments, the behavior regarding privilege inheritance and precedence remains unclear when these roles intersect. Specifically, it is uncertain how the engine resolves access when one role grants a privilege that another assigned role does not explicitly provide or restricts.
Does Firebird treat overlapping role privileges as additive, or is there a specific hierarchy that determines the effective permission set? How is the final access level calculated when a user activates multiple roles simultaneously?
35275 reputation · 28 Jun 2024, 04:56 UTC
No role takes precedence. Firebird evaluates overlapping role privileges additively: the effective permission set is the union of all privileges held by every active role, plus any privileges granted directly to the user account. There is no role hierarchy, priority sequence, or deny rule that lets one role override another.
Version assumption: Firebird 2.5, 3.x, and 4.x; SET ROLE behavior is effectively the same for this question across those releases.
Administrators often expect a “most restrictive role wins” model. Firebird does not implement that model; overlapping grants simply accumulate.
SET ROLE role_name; or SET ROLE ALL;.Are both roles activated in the current session with SET ROLE? If not, their privileges do not contribute to the effective set, and the recommendation changes from “overlapping grants are additive” to “activate the roles first.”
CREATE ROLE role_a;
CREATE ROLE role_b;
GRANT SELECT ON table_x TO role_a;
GRANT INSERT ON table_x TO role_b;
GRANT role_a, role_b TO user_y;
-- Connect as user_y
SET ROLE role_a;
SET ROLE role_b;
SELECT * FROM table_x; -- expected to succeed
INSERT INTO table_x ...; -- expected to succeed
Then revoke SELECT from role_a and repeat the SELECT test. Access should still succeed only if role_b or user_y independently holds SELECT.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.