Understanding database schemas
Good morning all,
I am trying to get a better understanding of how schemas can be used to
limit access to objects, and I seem to be failing miserably. Can anyone
point me to documentation about, or a decent tutorial on, schema usage for
access separation? I have tried to understand through the user guide. It
leads me to believe that ownership of a schema gives the owner all rights
to it, but my experimentation seems to indicate otherwise. Creating a
schema as superuser and assigning ownership of it to another role does not
seem to make it visible to that role:
$ psql -U postgres
DROP SCHEMA IF EXISTS hrschema CASCADE;
DROP DATABASE IF EXISTS personnel;
DROP USER IF EXISTS hr_admin;
CREATE USER hr_admin
WITH CREATEDB
PASSWORD 'md5be394806d6a21c6c52aa2b76063c7d9d';
DROP DATABASE IF EXISTS personnel;
CREATE DATABASE personnel
WITH ENCODING='UTF8'
OWNER=hr_admin
TEMPLATE=template0
LC_COLLATE='C'
LC_CTYPE='C'
CONNECTION LIMIT=-1;
CREATE SCHEMA hrschema
AUTHORIZATION hr_admin;
\dnS+
List of schemas
Name | Owner | Access privileges |
Description
--------------------+----------+----------------------+----------------------------------
hrschema | hr_admin | |
information_schema | postgres | postgres=UC/postgres+|
| | =U/postgres |
pg_catalog | postgres | postgres=UC/postgres+| system catalog
schema
| | =U/postgres |
pg_temp_1 | postgres | |
pg_toast | postgres | | reserved schema for
TOAST tables
pg_toast_temp_1 | postgres | |
public | postgres | postgres=UC/postgres+| standard public
schema
| | =UC/postgres |
(7 rows)
ALTER USER hr_admin
SET search_path
TO hrschema, public;
\q
$ psql -U hr_admin personnel
SHOW search_path;
search_path
------------------
hrschema, public
(1 row)
\dnS+
List of schemas
Name | Owner | Access privileges |
Description
--------------------+----------+----------------------+----------------------------------
information_schema | postgres | postgres=UC/postgres+|
| | =U/postgres |
pg_catalog | postgres | postgres=UC/postgres+| system catalog
schema
| | =U/postgres |
pg_temp_1 | postgres | |
pg_toast | postgres | | reserved schema for
TOAST tables
pg_toast_temp_1 | postgres | |
public | postgres | postgres=UC/postgres+| standard public
schema
| | =UC/postgres |
(6 rows)
The lack of Access privileges seems to be the key, but I am failing to
understand why an object's owner would not be given any access to it by
default.
Thanks,
Melvin
On 08/02/13 09:33, Melvin Call wrote:
$ psql -U postgres
DROP SCHEMA IF EXISTS hrschema CASCADE;
DROP DATABASE IF EXISTS personnel;
DROP USER IF EXISTS hr_admin;CREATE USER hr_admin
WITH CREATEDB
PASSWORD 'md5be394806d6a21c6c52aa2b76063c7d9d';DROP DATABASE IF EXISTS personnel;
CREATE DATABASE personnel
WITH ENCODING='UTF8'
OWNER=hr_admin
TEMPLATE=template0
LC_COLLATE='C'
LC_CTYPE='C'
CONNECTION LIMIT=-1;CREATE SCHEMA hrschema
AUTHORIZATION hr_admin;
You've created 'hrschema' schema in the 'postgres' database at this
point.
You'll need to connect to the 'personnel' database before issuing this
DDL command. And since you are reconnecting, you may as well do it as
the 'hr_admin' user and skip the whole 'authorization' clause.
HTH,
Bosco.
--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general
On Fri, Aug 2, 2013 at 11:56 AM, Bosco Rama <postgres@boscorama.com> wrote:
On 08/02/13 09:33, Melvin Call wrote:
$ psql -U postgres
DROP SCHEMA IF EXISTS hrschema CASCADE;
DROP DATABASE IF EXISTS personnel;
DROP USER IF EXISTS hr_admin;CREATE USER hr_admin
WITH CREATEDB
PASSWORD 'md5be394806d6a21c6c52aa2b76063c7d9d';DROP DATABASE IF EXISTS personnel;
CREATE DATABASE personnel
WITH ENCODING='UTF8'
OWNER=hr_admin
TEMPLATE=template0
LC_COLLATE='C'
LC_CTYPE='C'
CONNECTION LIMIT=-1;CREATE SCHEMA hrschema
AUTHORIZATION hr_admin;You've created 'hrschema' schema in the 'postgres' database at this
point.You'll need to connect to the 'personnel' database before issuing this
DDL command. And since you are reconnecting, you may as well do it as
the 'hr_admin' user and skip the whole 'authorization' clause.
Thanks Bosco, that was it. The DDL is in a script, and I even had the
connection command there, but I had commented it out and sadly I just never
caught that. And I've even slept since then... I now have a department
table in personnel.hrschema that was created under the hr_admin role.
HTH,
Bosco.
If I may pigtail another related question, what is the procedure for
allowing another user access to that schema?
As you may have surmised, I am trying to create an HR database, and I want
certain users to only have access to certain entities. So hr_admin will own
the database and have access to everything. hr_user only needs access to
public information, such as department names, people names, phone numbers,
etc., and I am trying to limit that access through hrschema (which I meant
to name hr_public_schema, but let's stick with my incorrect name for the
moment for the sake of clarity). So hrschema will contain the public tables
that I want hr_user to have access to. I tried (as hr_admin):
GRANT SELECT
ON ALL TABLES IN SCHEMA hrschema
TO hr_user;
$ psql -U hr_user personnel
\c personnel
\dt
No relations found.
SELECT has_table_privilege('hr_user', 'hrschema.department', 'select');
ERROR: permission denied for schema hrschema
Obviously I am still missing something
I appreciate your time and help.
On Fri, Aug 2, 2013 at 12:56 PM, Melvin Call <melvincall979@gmail.com>wrote:
On Fri, Aug 2, 2013 at 11:56 AM, Bosco Rama <postgres@boscorama.com>wrote:
On 08/02/13 09:33, Melvin Call wrote:
$ psql -U postgres
DROP SCHEMA IF EXISTS hrschema CASCADE;
DROP DATABASE IF EXISTS personnel;
DROP USER IF EXISTS hr_admin;CREATE USER hr_admin
WITH CREATEDB
PASSWORD 'md5be394806d6a21c6c52aa2b76063c7d9d';DROP DATABASE IF EXISTS personnel;
CREATE DATABASE personnel
WITH ENCODING='UTF8'
OWNER=hr_admin
TEMPLATE=template0
LC_COLLATE='C'
LC_CTYPE='C'
CONNECTION LIMIT=-1;CREATE SCHEMA hrschema
AUTHORIZATION hr_admin;You've created 'hrschema' schema in the 'postgres' database at this
point.You'll need to connect to the 'personnel' database before issuing this
DDL command. And since you are reconnecting, you may as well do it as
the 'hr_admin' user and skip the whole 'authorization' clause.Thanks Bosco, that was it. The DDL is in a script, and I even had the
connection command there, but I had commented it out and sadly I just never
caught that. And I've even slept since then... I now have a department
table in personnel.hrschema that was created under the hr_admin role.HTH,
Bosco.If I may pigtail another related question, what is the procedure for
allowing another user access to that schema?As you may have surmised, I am trying to create an HR database, and I want
certain users to only have access to certain entities. So hr_admin will own
the database and have access to everything. hr_user only needs access to
public information, such as department names, people names, phone numbers,
etc., and I am trying to limit that access through hrschema (which I meant
to name hr_public_schema, but let's stick with my incorrect name for the
moment for the sake of clarity). So hrschema will contain the public tables
that I want hr_user to have access to. I tried (as hr_admin):GRANT SELECT
ON ALL TABLES IN SCHEMA hrschema
TO hr_user;
To clarify, I logged out as hr_admin after the above statement, and logged
in as hr_user at this point.
Show quoted text
$ psql -U hr_user personnel
\c personnel\dt
No relations found.SELECT has_table_privilege('hr_user', 'hrschema.department', 'select');
ERROR: permission denied for schema hrschemaObviously I am still missing something
I appreciate your time and help.
On 08/02/13 10:56, Melvin Call wrote:
If I may pigtail another related question, what is the procedure for
allowing another user access to that schema?
Heh. You almost have the words already:
grant usage on schema hrschema to hr_user;
This will allow them to see the objects in the schema. It does nothing
to allow them to access the objects themselves, so you'll still need to
grant the appropriate privileges on the objects within the schema. You
can use default privileges if you don't wish to grant them at creation
time. See the docs for default privs:
<http://www.postgresql.org/docs/9.2/static/sql-alterdefaultprivileges.html>
HTH,
Bosco.
--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general
On Fri, Aug 2, 2013 at 1:36 PM, Bosco Rama <postgres@boscorama.com> wrote:
On 08/02/13 10:56, Melvin Call wrote:
If I may pigtail another related question, what is the procedure for
allowing another user access to that schema?Heh. You almost have the words already:
grant usage on schema hrschema to hr_user;
Too easy! Thanks for the help. That'll teach me to try to learn something
new in the middle of development crunch time! And many thanks for the link
as well. This will help a great deal.
Show quoted text
This will allow them to see the objects in the schema. It does nothing
to allow them to access the objects themselves, so you'll still need to
grant the appropriate privileges on the objects within the schema. You
can use default privileges if you don't wish to grant them at creation
time. See the docs for default privs:<http://www.postgresql.org/docs/9.2/static/sql-alterdefaultprivileges.html
HTH,
Bosco.