A Shardman cluster emulates a usual PostgreSQL security model, which, however, has features inherent to a distributed DBMS. This section describes these features and aims to give you an idea of access management in a Shardman cluster.
When a Shardman cluster is initialized, security-related settings are taken from the initialization file. You can change them later, but do this with care and remember that in most cases, the change will require a DBMS restart.
A Shardman cluster has two special users: administrative and replication. Stolon and Shardman manage controlled DBMS instances with administrative users. Stolon needs replication users for replications between controlled DBMS instances.
Security-related settings from the initialization file specify:
Authentication methods for administrative and replication
users — PgSuAuthMethod,
PgReplAuthMethod
Usernames for administrative and replication
users — PgSuUsername,
PgReplUsername
Passwords for administrative and replication
users — PgSuPassword,
PgReplPassword
pg_hba.conf rules used by DBMS instances
— StolonSpec.pgHBA
See sdmspec.json for detailed descriptions of these settings.
To change security-related user settings, perform these steps:
Check that the user that you want to specify in
PgReplUsername/PgSuUsername
exists with REPLICATION/SUPERUSER privileges on all replication groups in the
cluster and his password
matches the new PgReplPassword/PgSuPassword setting.
If this is true, create dump of the
shardman/cluster0/clusterdata etcd key
(here and further the name of the Shardman
cluster is assumed to be cluster0). For example:
$etcdctl --endpoints etcdserver:2379 get --print-value-only shardman/cluster0/clusterdata |jq . > clusterdata.json
This example creates the dump of the clusterdata key for
the Shardman cluster with the cluster0
name from the etcd server etcdserver listening on port
2379, formats it with jq and saves to
the clusterdata.json file.
Edit the dump as necessary and store it back in etcd:
$cat clusterdata.json | etcdctl --endpoints etcdserver:2379 put shardman/cluster0/clusterdata
Modifying these settings will lead to a DBMS restart.
Unlike the above settings,
the StolonSpec.pgHBA setting can be changed online.
To do this, perform these steps:
Extract the StolonSpec definition from
shardman/cluster0/clusterdata, save to some file, modify
as necessary and update cluster settings with the
shardmanctl update command:
$etcdctl --endpoints etcdserver:2379 get --print-value-only shardman/cluster0/clusterdata | jq .Spec.StolonSpec . > stolonspec.json
Edit stolonspec.json and replace
the StolonSpec.pgHBA definition with the appropriate one,
for example:
"pgHBA": [
"host all postgres 0.0.0.0/0 md5",
"host replication postgres 0.0.0.0/0 md5",
"host replication postgres ::0/0 md5",
"host all someuser 0.0.0.0/0 md5"
],
Apply the edited stolonspec.json file:
$shardmanctl --store-endpoints etcdserver:2379 --cluster-name cluster0 update -f stolonspec.json
Users and roles in a Shardman cluster are usual PostgreSQL users and roles. You can manage them separately on each server or globally, using broadcast DDL. However, Shardman uses concepts of global users and global roles. Operations on such users are always performed on all replication groups simultaneously. For example, when you include a global role in some other role or drop it, this operation will be performed on all replication groups.
You can create a global user with a CREATE USER ... IN ROLE global
statement, for example:
CREATE USER someuser ENCRYPTED PASSWORD 'somepass' IN ROLE global;
When a global user is created, Shardman automatically creates user mappings on all replication groups and grants this user with access to all foreign servers corresponding to existing replication groups. Therefore, when you create a global user, you need to specify either a cleartext password, so that it can be saved in a user mapping, or no password at all. A passwordless global user or role is unable to access foreign servers, but you can use such a role to accumulate some permissions and grant it to different users. You can also set a password for a passwordless global user later.
ALTER and DROP statements for global
users are broadcasted to all replication groups. When a role is granted to
a global user, this operation is also broadcasted. Renaming a global user is not
supported since this invalidates md5 passwords stored in user mappings.
The list of global users is stored in the shardman.users table.
Role management operations in Shardman are restricted
to superusers.
The CREATEROLE permission is currently not enough to manage
global users. However, a global user can change his own settings, such as the password
or configuration parameters, with the ALTER USER statement.
A special pre-created shardman_ddl global role has
permissions to create or drop sharded tables.
You can grant it to a regular user, along with the necessary CREATE permissions,
if you want him to create sharded tables. Note that such a user can modify
Shardman metadata directly,
so it is not safe to grant this role to an untrusted user.
The role specified in PgSuUsername (usually,
postgres) is also created as global user during
cluster initialization. However, the role specified in
PgReplUsername is created as local user on each
replication group.
The role global is reserved and cannot be used directly in
a Shardman cluster.
In Shardman, a sharded table is basically a partitioned table where partitions are either local shards or foreign tables referencing shards in other replication groups.
Permissions granted on a sharded table are broadcasted to all replication groups and to all partitions of the table.
When a new replication group is added to a cluster,
shardman-ladle copies the schema from a random existing
replication group to the new one. It also creates a foreign server for the new
replication group on all existing replication groups and recreates foreign servers
on new replication groups. Permissions for the created foreign servers and user
mappings are copied from a random foreign server in an existing replication
group. In the new replication group, for each partition of the sharded table
shardman-ladle
creates a foreign table referencing
the existing shard and replaces the partition with this foreign table.
Later some of these foreign tables can be replaced by real tables.
This happens during the shardman-ladle addnodes
rebalance stage when rebalance is enabled. Data for these partitions is
transferred from existing nodes using logical replication.
When shardman-ladle creates tables (or foreign
tables), it copies permissions from the parent table. The parent table must
already have correct permissions since they were copied from an existing replication group.
These examples assume administrator privileges.
If you want to create a sharded table and a global user, as well as grant him read-only access to the table, you can use the following statements:
CREATE USER someuser ENCRYPTED PASSWORD 'somepass' IN ROLE global;
CREATE TABLE pgbench_branches (
bid integer NOT NULL PRIMARY KEY,
bbalance integer,
filler character(88)
)
WITH (distributed_by = 'bid', num_parts = 8);
GRANT SELECT ON pgbench_branches TO someuser;
To allow someuser to access a
Shardman cluster, you
should also provide proper settings in pg_hba.conf
(as this is done
earlier).
Now assume that a new clover is added to the cluster with
the shardman-ladle addnodes command, like this:
$shardman-ladle --store-endpoints http://etcdserver:2379 --cluster-name cluster0 addnodes -n newnode1,newnode2
In this example, some shards of the pgbench_branches table are transferred to
new replication groups and someuser is granted
the SELECT privilege on this table.
Later you can drop someuser from all replication groups in the cluster
in one command:
DROP USER someuser;