CREATE TABLE roles ( id bigserial PRIMARY KEY, code text UNIQUE NOT NULL ); CREATE TABLE roles_permissions ( role_id bigint NOT NULL REFERENCES roles ON DELETE CASCADE, permission_id bigint NOT NULL REFERENCES permissions ON DELETE CASCADE, PRIMARY KEY (role_id, permission_id) ); CREATE TABLE users_roles ( user_id bigint NOT NULL REFERENCES users ON DELETE CASCADE, role_id bigint NOT NULL REFERENCES roles ON DELETE CASCADE, PRIMARY KEY (user_id, role_id) ); INSERT INTO roles (code) VALUES ('viewer'), ('contributor'), ('admin'); INSERT INTO roles_permissions (role_id, permission_id) SELECT r.id, p.id FROM roles r, permissions p WHERE (r.code = 'viewer' AND p.code = 'issues:read') OR (r.code = 'contributor' AND p.code IN ('issues:read', 'issues:write', 'issues:vote')) OR (r.code = 'admin' AND p.code IN ('issues:read', 'issues:write', 'issues:vote', 'users:read')); DROP TABLE users_permissions;