Despite of using GRANT … ON ALL TABLES (or ALL SEQUENCES) TO user, user cannot access newly created tables...












0















For a production server, I wanted to separate the super user, admin and app roles to limit scope of mistakes.



So I've created an account that our app uses to access the DB, and an admin account. The admin account is also used to run migrations to create tables.



I thought I'd ironed out all the issues, the app user can access all existing tables (which were created by the super user), however having now run a migration that creates a table, the app has no access to that table.



The users were granted access with the following commands:



GRANT CREATE, CONNECT ON DATABASE test TO admin;
GRANT SELECT, INSERT, UPDATE, DELETE, REFERENCES ON ALL TABLES IN SCHEMA public
TO admin;
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO admin;

GRANT CONNECT ON DATABASE test TO api;
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public
TO api;
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO api;


Then the admin user ran CREATE TABLE new_table; and trying to access that table, the app gets permission denied for relation new_table



1) What grant am I missing to allow api access to the new table
2) Out of curiousity, if I didn't have a record of the previous grants, how would I examine the grants of the users and discover the privilege that's missing










share|improve this question





























    0















    For a production server, I wanted to separate the super user, admin and app roles to limit scope of mistakes.



    So I've created an account that our app uses to access the DB, and an admin account. The admin account is also used to run migrations to create tables.



    I thought I'd ironed out all the issues, the app user can access all existing tables (which were created by the super user), however having now run a migration that creates a table, the app has no access to that table.



    The users were granted access with the following commands:



    GRANT CREATE, CONNECT ON DATABASE test TO admin;
    GRANT SELECT, INSERT, UPDATE, DELETE, REFERENCES ON ALL TABLES IN SCHEMA public
    TO admin;
    GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO admin;

    GRANT CONNECT ON DATABASE test TO api;
    GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public
    TO api;
    GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO api;


    Then the admin user ran CREATE TABLE new_table; and trying to access that table, the app gets permission denied for relation new_table



    1) What grant am I missing to allow api access to the new table
    2) Out of curiousity, if I didn't have a record of the previous grants, how would I examine the grants of the users and discover the privilege that's missing










    share|improve this question



























      0












      0








      0








      For a production server, I wanted to separate the super user, admin and app roles to limit scope of mistakes.



      So I've created an account that our app uses to access the DB, and an admin account. The admin account is also used to run migrations to create tables.



      I thought I'd ironed out all the issues, the app user can access all existing tables (which were created by the super user), however having now run a migration that creates a table, the app has no access to that table.



      The users were granted access with the following commands:



      GRANT CREATE, CONNECT ON DATABASE test TO admin;
      GRANT SELECT, INSERT, UPDATE, DELETE, REFERENCES ON ALL TABLES IN SCHEMA public
      TO admin;
      GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO admin;

      GRANT CONNECT ON DATABASE test TO api;
      GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public
      TO api;
      GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO api;


      Then the admin user ran CREATE TABLE new_table; and trying to access that table, the app gets permission denied for relation new_table



      1) What grant am I missing to allow api access to the new table
      2) Out of curiousity, if I didn't have a record of the previous grants, how would I examine the grants of the users and discover the privilege that's missing










      share|improve this question
















      For a production server, I wanted to separate the super user, admin and app roles to limit scope of mistakes.



      So I've created an account that our app uses to access the DB, and an admin account. The admin account is also used to run migrations to create tables.



      I thought I'd ironed out all the issues, the app user can access all existing tables (which were created by the super user), however having now run a migration that creates a table, the app has no access to that table.



      The users were granted access with the following commands:



      GRANT CREATE, CONNECT ON DATABASE test TO admin;
      GRANT SELECT, INSERT, UPDATE, DELETE, REFERENCES ON ALL TABLES IN SCHEMA public
      TO admin;
      GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO admin;

      GRANT CONNECT ON DATABASE test TO api;
      GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public
      TO api;
      GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO api;


      Then the admin user ran CREATE TABLE new_table; and trying to access that table, the app gets permission denied for relation new_table



      1) What grant am I missing to allow api access to the new table
      2) Out of curiousity, if I didn't have a record of the previous grants, how would I examine the grants of the users and discover the privilege that's missing







      postgresql permissions






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited 6 mins ago









      sticky bit

      1,688314




      1,688314










      asked 9 hours ago









      ChristopherJChristopherJ

      1488




      1488






















          1 Answer
          1






          active

          oldest

          votes


















          0














          ALL TABLES/ALL SEQUENCES in that context means all tables/sequences that exist now, at the time the grant is issued. It doesn't include tables/sequences created after the grant was issued.



          Your first option is to include the grants explicitly in the migrate scripts. Every time you create a table/sequence also issue the respective grants to api.



          Or you can alter the default privileges. In Postgres default privileges can be stored, that will be applied to a newly created object automatically. You can change them with ALTER DEFAULT PRIVILEGES.



          In your case your probably after



          ALTER DEFAULT PRIVILEGES IN SCHEMA public
          GRANT SELECT,
          INSERT,
          UPDATE,
          DELETE
          ON TABLES
          TO api;


          and



          ALTER DEFAULT PRIVILEGES IN SCHEMA public
          GRANT USAGE,
          SELECT
          ON SEQUENCES
          TO api;


          The privileges onobjects can be obtained via the pg_class catalog table. For example, if you wanted to query all regular tables in the schema public you could do:



          SELECT rel.relname,
          rel.relacl
          FROM pg_class rel
          INNER JOIN pg_namespace nsp
          ON nsp.oid = rel.relnamespace
          WHERE nsp.nspname = 'public'
          AND rel.relkind = 'r';


          For sequences the relkind is s instead of r, so



          SELECT rel.relname,
          rel.relacl
          FROM pg_class rel
          INNER JOIN pg_namespace nsp
          ON nsp.oid = rel.relnamespace
          WHERE nsp.nspname = 'public'
          AND rel.relkind = 's';


          would give you the sequences in public.



          The column relname displays the object's name and relacl holds an array of the privileges on the object in form of an aclitem. An ACL is represented by a string of the form <grantee>=<privileges>/<grantor>. <grantee> can be empty if the privileges are granted to public. <privileges> encodes the privileges in form of a string of letters. In your case you want to see api=arwd/admin for a regular table and api=rU/admin for sequences.





          • a is for "append" (INSERT),


          • r for "read" (SELECT),


          • w for "write" (UPDATE),


          • d for DELETE and


          • U for USAGE.


          More details on the ACLs can be found in the manual on GRANT



          Explicit granting is more "secure" in the way, that you don't "forget" the default privileges are in place one day when creating a table api shouldn't be able to access. You'd have to explicitly revoke the privileges after the creation of the object in such a case.



          Using default privileges is more convenient of course.






          share|improve this answer























            Your Answer








            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "182"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: false,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: null,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fdba.stackexchange.com%2fquestions%2f226924%2fdespite-of-using-grant-on-all-tables-or-all-sequences-to-user-user-cannot%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            0














            ALL TABLES/ALL SEQUENCES in that context means all tables/sequences that exist now, at the time the grant is issued. It doesn't include tables/sequences created after the grant was issued.



            Your first option is to include the grants explicitly in the migrate scripts. Every time you create a table/sequence also issue the respective grants to api.



            Or you can alter the default privileges. In Postgres default privileges can be stored, that will be applied to a newly created object automatically. You can change them with ALTER DEFAULT PRIVILEGES.



            In your case your probably after



            ALTER DEFAULT PRIVILEGES IN SCHEMA public
            GRANT SELECT,
            INSERT,
            UPDATE,
            DELETE
            ON TABLES
            TO api;


            and



            ALTER DEFAULT PRIVILEGES IN SCHEMA public
            GRANT USAGE,
            SELECT
            ON SEQUENCES
            TO api;


            The privileges onobjects can be obtained via the pg_class catalog table. For example, if you wanted to query all regular tables in the schema public you could do:



            SELECT rel.relname,
            rel.relacl
            FROM pg_class rel
            INNER JOIN pg_namespace nsp
            ON nsp.oid = rel.relnamespace
            WHERE nsp.nspname = 'public'
            AND rel.relkind = 'r';


            For sequences the relkind is s instead of r, so



            SELECT rel.relname,
            rel.relacl
            FROM pg_class rel
            INNER JOIN pg_namespace nsp
            ON nsp.oid = rel.relnamespace
            WHERE nsp.nspname = 'public'
            AND rel.relkind = 's';


            would give you the sequences in public.



            The column relname displays the object's name and relacl holds an array of the privileges on the object in form of an aclitem. An ACL is represented by a string of the form <grantee>=<privileges>/<grantor>. <grantee> can be empty if the privileges are granted to public. <privileges> encodes the privileges in form of a string of letters. In your case you want to see api=arwd/admin for a regular table and api=rU/admin for sequences.





            • a is for "append" (INSERT),


            • r for "read" (SELECT),


            • w for "write" (UPDATE),


            • d for DELETE and


            • U for USAGE.


            More details on the ACLs can be found in the manual on GRANT



            Explicit granting is more "secure" in the way, that you don't "forget" the default privileges are in place one day when creating a table api shouldn't be able to access. You'd have to explicitly revoke the privileges after the creation of the object in such a case.



            Using default privileges is more convenient of course.






            share|improve this answer




























              0














              ALL TABLES/ALL SEQUENCES in that context means all tables/sequences that exist now, at the time the grant is issued. It doesn't include tables/sequences created after the grant was issued.



              Your first option is to include the grants explicitly in the migrate scripts. Every time you create a table/sequence also issue the respective grants to api.



              Or you can alter the default privileges. In Postgres default privileges can be stored, that will be applied to a newly created object automatically. You can change them with ALTER DEFAULT PRIVILEGES.



              In your case your probably after



              ALTER DEFAULT PRIVILEGES IN SCHEMA public
              GRANT SELECT,
              INSERT,
              UPDATE,
              DELETE
              ON TABLES
              TO api;


              and



              ALTER DEFAULT PRIVILEGES IN SCHEMA public
              GRANT USAGE,
              SELECT
              ON SEQUENCES
              TO api;


              The privileges onobjects can be obtained via the pg_class catalog table. For example, if you wanted to query all regular tables in the schema public you could do:



              SELECT rel.relname,
              rel.relacl
              FROM pg_class rel
              INNER JOIN pg_namespace nsp
              ON nsp.oid = rel.relnamespace
              WHERE nsp.nspname = 'public'
              AND rel.relkind = 'r';


              For sequences the relkind is s instead of r, so



              SELECT rel.relname,
              rel.relacl
              FROM pg_class rel
              INNER JOIN pg_namespace nsp
              ON nsp.oid = rel.relnamespace
              WHERE nsp.nspname = 'public'
              AND rel.relkind = 's';


              would give you the sequences in public.



              The column relname displays the object's name and relacl holds an array of the privileges on the object in form of an aclitem. An ACL is represented by a string of the form <grantee>=<privileges>/<grantor>. <grantee> can be empty if the privileges are granted to public. <privileges> encodes the privileges in form of a string of letters. In your case you want to see api=arwd/admin for a regular table and api=rU/admin for sequences.





              • a is for "append" (INSERT),


              • r for "read" (SELECT),


              • w for "write" (UPDATE),


              • d for DELETE and


              • U for USAGE.


              More details on the ACLs can be found in the manual on GRANT



              Explicit granting is more "secure" in the way, that you don't "forget" the default privileges are in place one day when creating a table api shouldn't be able to access. You'd have to explicitly revoke the privileges after the creation of the object in such a case.



              Using default privileges is more convenient of course.






              share|improve this answer


























                0












                0








                0







                ALL TABLES/ALL SEQUENCES in that context means all tables/sequences that exist now, at the time the grant is issued. It doesn't include tables/sequences created after the grant was issued.



                Your first option is to include the grants explicitly in the migrate scripts. Every time you create a table/sequence also issue the respective grants to api.



                Or you can alter the default privileges. In Postgres default privileges can be stored, that will be applied to a newly created object automatically. You can change them with ALTER DEFAULT PRIVILEGES.



                In your case your probably after



                ALTER DEFAULT PRIVILEGES IN SCHEMA public
                GRANT SELECT,
                INSERT,
                UPDATE,
                DELETE
                ON TABLES
                TO api;


                and



                ALTER DEFAULT PRIVILEGES IN SCHEMA public
                GRANT USAGE,
                SELECT
                ON SEQUENCES
                TO api;


                The privileges onobjects can be obtained via the pg_class catalog table. For example, if you wanted to query all regular tables in the schema public you could do:



                SELECT rel.relname,
                rel.relacl
                FROM pg_class rel
                INNER JOIN pg_namespace nsp
                ON nsp.oid = rel.relnamespace
                WHERE nsp.nspname = 'public'
                AND rel.relkind = 'r';


                For sequences the relkind is s instead of r, so



                SELECT rel.relname,
                rel.relacl
                FROM pg_class rel
                INNER JOIN pg_namespace nsp
                ON nsp.oid = rel.relnamespace
                WHERE nsp.nspname = 'public'
                AND rel.relkind = 's';


                would give you the sequences in public.



                The column relname displays the object's name and relacl holds an array of the privileges on the object in form of an aclitem. An ACL is represented by a string of the form <grantee>=<privileges>/<grantor>. <grantee> can be empty if the privileges are granted to public. <privileges> encodes the privileges in form of a string of letters. In your case you want to see api=arwd/admin for a regular table and api=rU/admin for sequences.





                • a is for "append" (INSERT),


                • r for "read" (SELECT),


                • w for "write" (UPDATE),


                • d for DELETE and


                • U for USAGE.


                More details on the ACLs can be found in the manual on GRANT



                Explicit granting is more "secure" in the way, that you don't "forget" the default privileges are in place one day when creating a table api shouldn't be able to access. You'd have to explicitly revoke the privileges after the creation of the object in such a case.



                Using default privileges is more convenient of course.






                share|improve this answer













                ALL TABLES/ALL SEQUENCES in that context means all tables/sequences that exist now, at the time the grant is issued. It doesn't include tables/sequences created after the grant was issued.



                Your first option is to include the grants explicitly in the migrate scripts. Every time you create a table/sequence also issue the respective grants to api.



                Or you can alter the default privileges. In Postgres default privileges can be stored, that will be applied to a newly created object automatically. You can change them with ALTER DEFAULT PRIVILEGES.



                In your case your probably after



                ALTER DEFAULT PRIVILEGES IN SCHEMA public
                GRANT SELECT,
                INSERT,
                UPDATE,
                DELETE
                ON TABLES
                TO api;


                and



                ALTER DEFAULT PRIVILEGES IN SCHEMA public
                GRANT USAGE,
                SELECT
                ON SEQUENCES
                TO api;


                The privileges onobjects can be obtained via the pg_class catalog table. For example, if you wanted to query all regular tables in the schema public you could do:



                SELECT rel.relname,
                rel.relacl
                FROM pg_class rel
                INNER JOIN pg_namespace nsp
                ON nsp.oid = rel.relnamespace
                WHERE nsp.nspname = 'public'
                AND rel.relkind = 'r';


                For sequences the relkind is s instead of r, so



                SELECT rel.relname,
                rel.relacl
                FROM pg_class rel
                INNER JOIN pg_namespace nsp
                ON nsp.oid = rel.relnamespace
                WHERE nsp.nspname = 'public'
                AND rel.relkind = 's';


                would give you the sequences in public.



                The column relname displays the object's name and relacl holds an array of the privileges on the object in form of an aclitem. An ACL is represented by a string of the form <grantee>=<privileges>/<grantor>. <grantee> can be empty if the privileges are granted to public. <privileges> encodes the privileges in form of a string of letters. In your case you want to see api=arwd/admin for a regular table and api=rU/admin for sequences.





                • a is for "append" (INSERT),


                • r for "read" (SELECT),


                • w for "write" (UPDATE),


                • d for DELETE and


                • U for USAGE.


                More details on the ACLs can be found in the manual on GRANT



                Explicit granting is more "secure" in the way, that you don't "forget" the default privileges are in place one day when creating a table api shouldn't be able to access. You'd have to explicitly revoke the privileges after the creation of the object in such a case.



                Using default privileges is more convenient of course.







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered 2 hours ago









                sticky bitsticky bit

                1,688314




                1,688314






























                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Database Administrators Stack Exchange!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fdba.stackexchange.com%2fquestions%2f226924%2fdespite-of-using-grant-on-all-tables-or-all-sequences-to-user-user-cannot%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    Ronny Ackermann

                    Köttigit

                    MySQL 8.0.15 starts normally but any connection hangs