Despite of using GRANT … ON ALL TABLES (or ALL SEQUENCES) TO user, user cannot access newly created tables...
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
add a comment |
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
add a comment |
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
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
postgresql permissions
edited 6 mins ago
sticky bit
1,688314
1,688314
asked 9 hours ago
ChristopherJChristopherJ
1488
1488
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
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.
ais for "append" (INSERT),
rfor "read" (SELECT),
wfor "write" (UPDATE),
dforDELETEand
UforUSAGE.
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.
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.
ais for "append" (INSERT),
rfor "read" (SELECT),
wfor "write" (UPDATE),
dforDELETEand
UforUSAGE.
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.
add a comment |
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.
ais for "append" (INSERT),
rfor "read" (SELECT),
wfor "write" (UPDATE),
dforDELETEand
UforUSAGE.
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.
add a comment |
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.
ais for "append" (INSERT),
rfor "read" (SELECT),
wfor "write" (UPDATE),
dforDELETEand
UforUSAGE.
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.
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.
ais for "append" (INSERT),
rfor "read" (SELECT),
wfor "write" (UPDATE),
dforDELETEand
UforUSAGE.
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.
answered 2 hours ago
sticky bitsticky bit
1,688314
1,688314
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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