-
Notifications
You must be signed in to change notification settings - Fork 1k
Bootstrapped databases with best practice role setup #843
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
1355fdc
7256e13
0631361
9d9807a
b666877
6aa734c
31fd352
18da6e5
7d9cfe9
0fa16ee
e2bf0fd
7a3a5c7
7a20bfe
c8f987e
1a8862e
fa6faaf
59f4d4e
353eb69
e246ba7
f9b8b63
f620a15
e580da8
4efdfae
8cef3b2
7a12da3
901f410
e8a4495
8bebd81
0225f18
46f6550
7469ead
ef5cc65
eb176ca
4268d97
0f703b2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -94,7 +94,10 @@ created on every cluster managed by the operator. | |
| * `teams API roles`: automatically create users for every member of the team | ||
| owning the database cluster. | ||
|
|
||
| In the next sections, we will cover those use cases in more details. | ||
| In the next sections, we will cover those use cases in more details. Note, that | ||
| the Postgres Operator can also create databases with pre-defined owner, reader | ||
| and writer roles which saves you the manual setup. Read more in the next | ||
| chapter. | ||
|
|
||
| ### Manifest roles | ||
|
|
||
|
|
@@ -216,6 +219,166 @@ to choose superusers, group roles, [PAM configuration](https://github.com/CyberD | |
| etc. An OAuth2 token can be passed to the Teams API via a secret. The name for | ||
| this secret is configurable with the `oauth_token_secret_name` parameter. | ||
|
|
||
| ## Prepared databases with roles and default privileges | ||
|
|
||
| The `users` section in the manifests only allows for creating database roles | ||
| with global privileges. Fine-grained data access control or role membership can | ||
| not be defined and must be set up by the user in the database. But, the Postgres | ||
| Operator offers a separate section to specify `preparedDatabases` that will be | ||
| created with pre-defined owner, reader and writer roles for each individual | ||
| database and, optionally, for each database schema, too. `preparedDatabases` | ||
| also enable users to specify PostgreSQL extensions that shall be created in a | ||
| given database schema. | ||
|
|
||
| ### Default database and schema | ||
|
|
||
| A prepared database is already created by adding an empty `preparedDatabases` | ||
| section to the manifest. The database will then be called like the Postgres | ||
| cluster manifest (`-` are replaced with `_`) and will also contain a schema | ||
| called `data`. | ||
|
|
||
| ```yaml | ||
| spec: | ||
| preparedDatabases: {} | ||
| ``` | ||
|
|
||
| ### Default NOLOGIN roles | ||
|
|
||
| Given an example with a specified database and schema: | ||
|
|
||
| ```yaml | ||
| spec: | ||
| preparedDatabases: | ||
| foo: | ||
| schemas: | ||
| bar: {} | ||
| ``` | ||
|
|
||
| Postgres Operator will create the following NOLOGIN roles: | ||
|
|
||
| | Role name | Member of | Admin | | ||
| | -------------- | -------------- | ------------- | | ||
| | foo_owner | | admin | | ||
| | foo_reader | | foo_owner | | ||
| | foo_writer | foo_reader | foo_owner | | ||
| | foo_bar_owner | | foo_owner | | ||
| | foo_bar_reader | | foo_bar_owner | | ||
| | foo_bar_writer | foo_bar_reader | foo_bar_owner | | ||
|
|
||
| The `<dbname>_owner` role is the database owner and should be used when creating | ||
| new database objects. All members of the `admin` role, e.g. teams API roles, can | ||
| become the owner with the `SET ROLE` command. [Default privileges](https://www.postgresql.org/docs/12/sql-alterdefaultprivileges.html) | ||
| are configured for the owner role so that the `<dbname>_reader` role | ||
| automatically gets read-access (SELECT) to new tables and sequences and the | ||
| `<dbname>_writer` receives write-access (INSERT, UPDATE, DELETE on tables, | ||
| USAGE and UPDATE on sequences). Both get USAGE on types and EXECUTE on | ||
| functions. | ||
|
|
||
| The same principle applies for database schemas which are owned by the | ||
| `<dbname>_<schema>_owner` role. `<dbname>_<schema>_reader` is read-only, | ||
| `<dbname>_<schema>_writer` has write access and inherit reading from the reader | ||
| role. Note, that the `<dbname>_*` roles have access incl. default privileges on | ||
| all schemas, too. If you don't need the dedicated schema roles - i.e. you only | ||
| use one schema - you can disable the creation like this: | ||
|
|
||
| ```yaml | ||
| spec: | ||
| preparedDatabases: | ||
| foo: | ||
| schemas: | ||
| bar: | ||
| defaultRoles: false | ||
| ``` | ||
|
|
||
| Then, the schemas are owned by the database owner, too. | ||
|
|
||
| ### Default LOGIN roles | ||
|
|
||
| The roles described in the previous paragraph can be granted to LOGIN roles from | ||
| the `users` section in the manifest. Optionally, the Postgres Operator can also | ||
| create default LOGIN roles for the database an each schema individually. These | ||
| roles will get the `_user` suffix and they inherit all rights from their NOLOGIN | ||
| counterparts. | ||
|
|
||
| | Role name | Member of | Admin | | ||
| | ------------------- | -------------- | ------------- | | ||
| | foo_owner_user | foo_owner | admin | | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am not 100% sure we want to encourage owner roles with login privileges. Yes, there are cases for it like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah that is a bit difficult. Ideally not the case. But then often by mistake objects are ultimately created and owned by the login role. @CyberDem0n any thoughts? |
||
| | foo_reader_user | foo_reader | foo_owner | | ||
| | foo_writer_user | foo_writer | foo_owner | | ||
| | foo_bar_owner_user | foo_bar_owner | foo_owner | | ||
| | foo_bar_reader_user | foo_bar_reader | foo_bar_owner | | ||
| | foo_bar_writer_user | foo_bar_writer | foo_bar_owner | | ||
|
|
||
| These default users are enabled in the manifest with the `defaultUsers` flag: | ||
|
|
||
| ```yaml | ||
| spec: | ||
| preparedDatabases: | ||
| foo: | ||
| defaultUsers: true | ||
| schemas: | ||
| bar: | ||
| defaultUsers: true | ||
| ``` | ||
|
|
||
| ### Database extensions | ||
|
|
||
| Prepared databases also allow for creating Postgres extensions. They will be | ||
| created by the database owner in the specified schema. | ||
|
|
||
| ```yaml | ||
| spec: | ||
| preparedDatabases: | ||
| foo: | ||
| extensions: | ||
| pg_partman: public | ||
| postgis: data | ||
| ``` | ||
|
|
||
| Some extensions require SUPERUSER rights on creation unless they are not | ||
| whitelisted by the [pgextwlist](https://github.com/dimitri/pgextwlist) | ||
| extension, that is shipped with the Spilo image. To see which extensions are | ||
| on the list check the `extwlist.extension` parameter in the postgresql.conf | ||
| file. | ||
|
|
||
| ```bash | ||
| SHOW extwlist.extensions; | ||
| ``` | ||
|
|
||
| Make sure that `pgextlist` is also listed under `shared_preload_libraries` in | ||
| the PostgreSQL configuration. Then the database owner should be able to create | ||
| the extension specified in the manifest. | ||
|
|
||
| ### From `databases` to `preparedDatabases` | ||
|
|
||
| If you wish to create the role setup described above for databases listed under | ||
| the `databases` key, you have to make sure that the owner role follows the | ||
| `<dbname>_owner` naming convention of `preparedDatabases`. As roles are synced | ||
| first, this can be done with one edit: | ||
|
|
||
| ```yaml | ||
| # before | ||
| spec: | ||
| databases: | ||
| foo: db_owner | ||
|
|
||
| # after | ||
| spec: | ||
| databases: | ||
| foo: foo_owner | ||
| preparedDatabases: | ||
| foo: | ||
| schemas: | ||
| my_existing_schema: {} | ||
| ``` | ||
|
|
||
| Adding existing database schemas to the manifest to create roles for them as | ||
| well is up the user and not done by the operator. Remember that if you don't | ||
| specify any schema a new database schema called `data` will be created. When | ||
| everything got synced (roles, schemas, extensions), you are free to remove the | ||
| database from the `databases` section. Note, that the operator does not delete | ||
| database objects or revoke privileges when removed from the manifest. | ||
|
|
||
| ## Resource definition | ||
|
|
||
| The compute resources to be used for the Postgres containers in the pods can be | ||
|
|
@@ -586,8 +749,8 @@ don't know the value, use `103` which is the GID from the default spilo image | |
| OpenShift allocates the users and groups dynamically (based on scc), and their | ||
| range is different in every namespace. Due to this dynamic behaviour, it's not | ||
| trivial to know at deploy time the uid/gid of the user in the cluster. | ||
| Therefore, instead of using a global `spilo_fsgroup` setting, use the `spiloFSGroup` field | ||
| per Postgres cluster. | ||
| Therefore, instead of using a global `spilo_fsgroup` setting, use the | ||
| `spiloFSGroup` field per Postgres cluster. | ||
|
|
||
| Upload the cert as a kubernetes secret: | ||
| ```sh | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.