This page describes Calíope 1.7, the version I am building right now. 1.6 is on the App Store for the Mac, iPad, iPhone, Apple Watch, Apple TV and Apple Vision Pro. The changelog says which version each feature landed in.
Adds an “Open in Calíope” button to every topic. It only works with the app installed.
Create, edit and delete server accounts along with their privileges.
Where it is: Workspace › Tools › Users
Open Users from the workspace navigation bar. The left panel lists every account on the server, with the ones the server installs grouped separately; the search field filters by name. Select an account to load its privileges.
What appears on the right depends on the engine, because the security model is not the same. In MySQL and MariaDB an account is user@host and privileges are granted at four scopes: Global, Database, Table and Routine. In PostgreSQL an account is a role, there is no host, and instead of the global scope you get its attributes, which are not granted but set. What an engine does not have is not drawn greyed out: it is not drawn.
Inside each card the checkboxes are grouped by Data, Structure, Routines, Administration and Replication. Tick what applies and press Save changes; while there are unsaved changes the header says so, and Discard changes goes back to what is on the server.
In SQL Server an account is a server login, with no host; in each database it acts through the user linked to it, which Calíope finds on its own. Privileges go at five scopes —Global (the server), Connection (a database), Database (a schema), Table and Routine— and a DENY is shown as a third state, crossed out and named: here it can be seen but not changed; it is set and removed from the SQL Editor.
Without permission to read the accounts — in MySQL and MariaDB, SELECT on the mysql database — the list says “Couldn’t read the server’s accounts”, with the server's reason underneath and a button to retry, and the footer shows no count. In PostgreSQL it does not happen: any account can read the roles. In SQL Server, without VIEW ANY DEFINITION you see fewer accounts, with no error. And in Backups, without that permission the server accounts section does not appear.
ClickHouse
In ClickHouse the list brings accounts and roles together. Accounts defined in the server's configuration file, and default, appear under System with a padlock: they can't be changed through SQL. A partial revoke —granting on a database and revoking on one of its tables— shows on that table's card struck through and labelled REVOKE: here you can see it but not change it. The privileges of each card come from the server, so they change with its version. Permission to write belongs to the connection: if your account lacks ACCESS MANAGEMENT or CREATE USER, also through a role, the tool lists the same, but the buttons are off and a strip with a padlock says why. Changes take effect at once, there are no hourly limits and only roles are offered for granting.
Oracle
In Oracle the list shows accounts and roles together, plus PUBLIC, the role everyone belongs to; Oracle's own accounts and roles appear under System. Each account owns the schema that bears its name. Privileges come in four scopes: Global (system privileges such as CREATE TABLE), Database (privileges on a whole schema, such as SELECT ANY TABLE on it), Table and Routine, where packages appear too. Above them you see the profile with its password limits, when the password expires and the tablespace: they're read, not changed here. For PUBLIC and Oracle's accounts only what's granted on user schemas is shown. Without permission to read DBA_USERS the list shows only your account, with its roles and privileges, and a banner says so. Privileges on sequences, types and columns aren't shown. Writing needs one system privilege per action on your connection: CREATE USER to create, ALTER USER to change the password or lock, DROP USER to delete, and GRANT ANY PRIVILEGE, GRANT ANY OBJECT PRIVILEGE or GRANT ANY ROLE to grant; without it, that button is disabled and says which one is missing. Oracle's own accounts aren't changed here: a banner says so.
With a read-only environment tag, this tool isn’t offered. With one that confirms writes, every change —creating or editing a user, their privileges, their roles— asks first with the action’s name, and deleting a user carries the tag in its confirmation title.
Keywords: users, roles, privileges, permissions, GRANT, user admin
Press New user in the Users bar. Enter the name, the host and the password. The account is created with no privileges and is left selected, so you can assign them right away.
The host field and the authentication method picker only appear where the engine has them. PostgreSQL has neither: where a connection is accepted from is decided by the server’s pg_hba.conf, and how the password is encrypted is decided by the server configuration, not by the account. The role is created with LOGIN and INHERIT, as CREATE USER does, so it can sign in; its other attributes are ticked afterwards on its own card.
SQL Server doesn't have them either: the account is a login, with no host and no method to choose.
Oracle
In Oracle there's no host and no method: the account is created with CREATE USER … IDENTIFIED BY and gets CREATE SESSION, which is what lets it log in. The password can't contain double quotes. Without a password a schema-only account is created (NO AUTHENTICATION), which holds objects but can't log in. The server sets the tablespace and the quota: without a quota the account can't store rows, and you give it one from the SQL Editor (ALTER USER … QUOTA). In a pluggable database (PDB) a name starting with C## belongs to a common user and isn't created here: the form says so.
Keywords: create user, new user, CREATE USER, password
Select the account in the left panel and press Delete in the header. A confirmation dialog shows what will be removed. The action cannot be undone.
The accounts the server installs appear in their own group and cannot be deleted from here.
In PostgreSQL the server may refuse, and that is not a Calíope bug: a role that owns objects or holds granted privileges cannot be dropped until those are removed. Calíope does not issue DROP OWNED BY on its own, because that would delete data nobody asked to delete. Remove its grants first —including the “all tables” ones, which also leave a default privilege behind— or reassign what it owns.
In SQL Server deleting removes the account's user in every database and then the login. The server refuses while one of those users owns a schema: hand the schema to someone else first (ALTER AUTHORIZATION).
Oracle
In Oracle an account is its schema: deleting it is DROP USER … CASCADE, which also deletes all its tables, views and code, and the confirmation says so. A role is deleted with DROP ROLE. Oracle's own accounts can't be deleted here.
Select the account in the left panel and press Edit in the header. The edit form opens.
The form only shows what the engine has. In MySQL and MariaDB it carries the password, the authentication method, the account lock and the hourly resource limits. In PostgreSQL it carries the password and nothing else: there is no lock —an account is closed by removing its LOGIN attribute, which is on its own card— and no hourly limits, while the concurrent connection count and the expiry date are edited next to the attributes.
The form opens with what the server has: whether the account is locked and its hourly limits. A limit of 0 means no limit, and setting one back to 0 removes it. Leave the password field empty if you only want to change the other settings.
In SQL Server it carries the password and the lock (ALTER LOGIN … DISABLE: the login can't sign in and keeps its permissions); there are no hourly limits and no expiry date per account.
Oracle
In Oracle it has the password and the lock (ALTER USER … ACCOUNT LOCK: the account can't log in and the server answers ORA-28000). There are no hourly limits: the password limits come from its profile, shown in the account header. The password can't contain double quotes.
Keywords: change password, password, edit user, ALTER USER, credentials, new password
Assign granular permissions at the database, table, or specific routine level.
Where it is: Users › Privileges tree
Each privilege scope is a card with its granted counter and its WITH GRANT OPTION switch:
- Role attributes — PostgreSQL only. These are not privileges: they are properties of the role (LOGIN, SUPERUSER, CREATEDB…) written with ALTER ROLE. Concurrent connections and the expiry date sit at the bottom.
- Global — MySQL family and SQL Server. They apply to the whole server (e.g. SUPER or PROCESS in MySQL, VIEW SERVER STATE in SQL Server).
- Connection — PostgreSQL and SQL Server. In PostgreSQL, the privileges of the cluster database the profile points at: CONNECT, CREATE and TEMPORARY, which decide whether the account can connect at all. In SQL Server, those over a whole database (CONNECT, CREATE TABLE…).
- Database — over every object in a database (in PostgreSQL and SQL Server, of a schema).
- Table — over one specific table.
- Routine — over a stored procedure or function.
Inside each card the checkboxes are grouped by category, with Select all per group, and ALL PRIVILEGES is highlighted at the top because it grants the whole scope at once.
To add a scope that is not listed, use Add object in the bottom bar. Save changes runs the required REVOKE and GRANT statements; if the server rejects any, a notice appears next to the button with the detail. In MySQL and MariaDB it then runs FLUSH PRIVILEGES, and so do creating, editing and deleting an account.
ClickHouse
With ClickHouse there are three cards: Global, Database and Table. There is no Routine, Connection or role attributes.
Oracle
With Oracle there are four cards: Global (system privileges; its switch is the ADMIN OPTION), Database (privileges on a whole schema, such as SELECT ANY TABLE ON SCHEMA), Table (also views and materialized views) and Routine (procedures, functions and packages). There's no Connection card and no role attributes.
Why this screen does not look like the MySQL one, and what each part means.
Where it is: Workspace › Tools › Users
PostgreSQL has no separate users and groups: it has roles, and a role is both at once. A role with the LOGIN attribute can sign in; one without it exists to group privileges and hand them to others. That is why the screen changes shape, and not on a whim.
There is no host. An account is a bare name. Where a connection is accepted from is decided by pg_hba.conf, which belongs to the server and not to the account, so Calíope neither shows it here nor can change it.
Attributes are not privileges.SUPERUSER, CREATEDB, CREATEROLE, REPLICATION, BYPASSRLS, INHERIT and LOGIN are set with ALTER ROLE, not granted with GRANT. On save, Calíope writes all of them: whatever you leave unticked is turned off. That is what makes the screen truthful — if only the ticked ones were written, unticking a box would not turn it off and it would come back on its own the next time you opened the account.
Membership is transitive. If app is a member of readers and readers of auditors, then app has what auditors has without anyone granting it. The Member of card tells direct memberships from inherited ones and shows the path of each. Inherited ones cannot be removed from here, which is why they have no button: what would have to be revoked is the link, and that link belongs to another role.
PUBLIC is not a role: it is everyone. It appears in the list as one more account because otherwise an object granted to everyone would look private. By default PUBLIC may connect to the database and execute any function.
The owner has everything over what it owns, and that never appears as a grant. A freshly created table has no privilege rows in the catalogue at all, and its owner can still do whatever it likes with it. That is why the header carries the “owns N objects” badge and those cards are drawn ticked and greyed out: there is nothing to grant and nothing to revoke.
“Grant on all tables” is two statements. In MySQL, ON database.* also covers tables created tomorrow; here it takes two commands that do not mean the same thing: one reaches the tables that exist now and the other the future ones. The second one, moreover, only covers those created by the account Calíope is connected with. Neither comes back afterwards as a checkbox on the schema card, because they are not schema privileges. The button next to it undoes both, and it is needed: while the default privilege remains, the server will not let you delete the account.
What is missing. There is no account lock —you remove LOGIN—, no hourly limits —only the concurrent connection count—, no authentication method picker —the server decides— and no FLUSH PRIVILEGES: here the catalogue is the source, and a GRANT is already in force by the time the server answers.