Uploaded image for project: 'MariaDB Server'
  1. MariaDB Server
  2. MDEV-14443

DENY clause for access control a.k.a. "negative grants"

Details

    Description

      Summary:

      Implement a way to ensure that a user can not get access to a particular resource.
      DENY will function as a separate set of rules for access control. If any resource (global, database, table, column, procedure, function, etc.) has a deny on one particular privilege, it is impossible to gain that privilege unless the DENY is revoked.

      For example:

      GRANT SELECT on *.* to alice;
      DENY SELECT on db.secret_table to alice;

      alice will not be able to select from secret_table.

      Syntax:

             DENY <privilege-list> ON <object-list> TO   <user-or-role>
       
      REVOKE DENY <privilege-list> ON <object-list> FROM <user-or-role>

      User cases

      https://stackoverflow.com/questions/6288554/mysql-grant-all-privileges-to-database-except-one-table (32k views)
      https://dba.stackexchange.com/questions/98949/grant-select-on-all-databases-except-one&#45;mysql (18k views)
      https://dba.stackexchange.com/questions/68957/block-user-access-to-certain&#45;tables (13k views)

      Details:

      1. Users should not be able to see that a DENY is assigned to them. Similar to how databases that the user can not access are not visible in show databases.
      2. DENY works on roles (as well as PUBLIC when it is implemented)
      3. Enabling a role activates that role's denies as well.
      4. Denies will be visible in SHOW GRANTS [FOR] if:
        • User has read or write access to mysql database.
        • User has read or write access to corresponding mysql privilege table. (TODO for as a separate MDEV for SHOW GRANTS)
      5. Methods of querying denies: INFORMATION_SCHEMA.USER_PRIVILEGES
      6. Introduce a form of SUPER privilege, say IGNORE_DENIES, to allow a "superuser" to ignore denies (this is compatible with SQL Server DENY behavior)

      Compatiblity with other databases (Potential future work)

      SQL Server

      • Compared to SQL Server, DENY can only be revoked via REVOKE DENY. Future possibility for SQL Server compatibility (via SQL_MODE=MSSQL) GRANT can also cancel a DENY.
      • An SQL Server quirk is that column level denies take precedence over table level denies. This is a deprecated functionality of SQL Server, meant for backwards compatibility.

      MySQL

      • MySQL treats revokes as "holes" that are filled when the privilege is granted (directly or via a a higher level grant). Deny will remain in effect in our implementation.
      • To allow MySQL compatibility, a possible extension in the future is: @@partial_revokes=1 -> REVOKE also works as DENY.

      Implementation details:

      • Current privilege checking order first checks global, database, table, column privileges (in this order). If at any point the needed privileges are met, the privilege checking code stops execution. Introducing denies will require an additional lookup, one for each individual resource accessed. Some form of quick lookup must be made to answer:
        • Does this user have denies for databases? (if global privileges met all required access bits).
        • Does this user have denies for tables in a particular database (if database level privileges met all required access bits).
        • Does this user have denies on table columns for a particular table (if table level privileges met all required access bits).
      • Should denies be stored in global_priv only, or should corresponding mysql.db, mysql.table_priv, etc. tables also have a "DENY" column?

      Milestones (each milestone includes test cases showcasing functionality):

      1. Grammar
      2. Global denies
      3. Database denies
      4. Table level denies
      5. Column level denies
      6. Stored procedure denies
      7. Information schema tables

      Attachments

        Issue Links

          Activity

            cvicentiu the Xpand team is going to start implementing this feature as well. Is there a build that we could use to compare notes?

            clieu Christine Lieu (Inactive) added a comment - cvicentiu the Xpand team is going to start implementing this feature as well. Is there a build that we could use to compare notes?

            Hi Sergei!

            Once you are done with reviewing MDEV-29458 & MDEV-29465, please start looking at the code here:

            https://github.com/MariaDB/server/pull/2258

            Things currently not completely operational:
            1. SHOW GRANTS currently only shows up-to database level denies.
            2. Wildcard DB denies.

            I'm looking for general input on architecture changes as well as functionality. I expect that by the time you get to the end of the commit tree that the missing items will also be present.

            cvicentiu Vicențiu Ciorbaru added a comment - Hi Sergei! Once you are done with reviewing MDEV-29458 & MDEV-29465 , please start looking at the code here: https://github.com/MariaDB/server/pull/2258 Things currently not completely operational: 1. SHOW GRANTS currently only shows up-to database level denies. 2. Wildcard DB denies. I'm looking for general input on architecture changes as well as functionality. I expect that by the time you get to the end of the commit tree that the missing items will also be present.

            One status update on this:

            I've rebased on top of 11.2.

            As discussed with Sergei Golubchik, I've implemented the separation of denies between users and roles. The implementation still requires testing and I am uncovering edge cases, bugs and an occasional crash. I expect around a week worth of work to stabilize this, then it should be ready for one final review.

            cvicentiu Vicențiu Ciorbaru added a comment - One status update on this: I've rebased on top of 11.2. As discussed with Sergei Golubchik, I've implemented the separation of denies between users and roles. The implementation still requires testing and I am uncovering edge cases, bugs and an occasional crash. I expect around a week worth of work to stabilize this, then it should be ready for one final review.

            Per this announcement in the Slack triage channel: https://mariadb.slack.com/archives/C05S0ANJ8BE/p1739890335402039, we will now only use the "triage" label to indicate an ongoing customer-engineering escalation. Also, I will remove it, and if it's still needed, let me know.

            julien.fritsch Julien Fritsch added a comment - Per this announcement in the Slack triage channel: https://mariadb.slack.com/archives/C05S0ANJ8BE/p1739890335402039 , we will now only use the "triage" label to indicate an ongoing customer-engineering escalation. Also, I will remove it, and if it's still needed, let me know.
            croser Christian Roser added a comment -

            After talking to Vicențiu we came to the conclusion that for our usecase DENY on database level would be sufficient and relatively easy to implement. We mainly want to prevent users with global privileges from accessing mysql schema.
            Is there a chance to get a DENY feature with limited scope implemented earlier than in 12.1?

            regards
            Christian

            croser Christian Roser added a comment - After talking to Vicențiu we came to the conclusion that for our usecase DENY on database level would be sufficient and relatively easy to implement. We mainly want to prevent users with global privileges from accessing mysql schema. Is there a chance to get a DENY feature with limited scope implemented earlier than in 12.1? regards Christian

            People

              wlad Vladislav Vaintroub
              hanzhi Hanzhi (Inactive)
              Votes:
              8 Vote for this issue
              Watchers:
              32 Start watching this issue

              Dates

                Created:
                Updated:

                Git Integration

                  Error rendering 'com.xiplink.jira.git.jira_git_plugin:git-issue-webpanel'. Please contact your Jira administrators.