Skip to content
NebulaCtrldocs
Concepts

Database accounts

The two accounts every database has, which one your services sign in with, what the application account cannot do, and how a database made before the application account moves to it.

A database has an administrative account and an application account. Your services sign in with the application account. The administrative account stays with the database and the agent.

Who holds which account

The application account is named app. It is the account in every connection URL and in the variables a connected service receives, such as DATABASE_URL_PG_SLUG. It can use everything in the application database and nothing else on the server.

The administrative account is the engine's own: postgres for PostgreSQL, root for MySQL and MongoDB, default for Valkey. Its password is the database's POSTGRES_PASSWORD, MYSQL_ROOT_PASSWORD, MONGO_INITDB_ROOT_PASSWORD or REDIS_PASSWORD variable. The engine reads it at start, and the agent uses it for the console, dumps and restores. A service gets it only if you reference that variable yourself.

EngineApplication accountWhat it can doWhat it cannot do
PostgreSQLapp, owner of the database appCreate, alter and drop everything in app; use trusted extensionsBe a superuser; read or write server files; run programs; create roles or databases; create an extension that needs superuser
MySQLappEvery privilege on app.*Privileges on other schemas; FILE, PROCESS, SUPER, RELOAD; grant privileges
MongoDBapp, role readWrite on appRead and write every collection of app, create collections and indexesOther databases; users and roles; server administration
Valkeyapp, an ACL userEvery command except the administrative ones: CONFIG, DEBUG, MODULE, REPLICAOF, SHUTDOWN, ACL and the rest of @adminChange the server's configuration or leave the database

A service that is compromised through its own bugs can therefore harm its own data, and nothing else.

PostgreSQL has no superuser login

A PostgreSQL database made since 0.42.0 has POSTGRES_SUPERUSER_ACCESS set to disabled. CloudNativePG then gives the postgres account no password, so nothing can sign in as it from the network. The console and dumps sign in as app, which owns every object in the database. The agent reads statistics through a separate account, nebula_agent, that is a member of pg_monitor and nothing else.

Setting the variable to enabled and deploying the database turns the postgres login back on, with the password in POSTGRES_PASSWORD.

Extensions

app can create an extension that PostgreSQL marks trusted, such as pgcrypto, citext, hstore, uuid-ossp and pg_trgm. An extension that needs superuser, such as postgis or pg_stat_statements, is refused with permission denied to create extension. To create one, see Create an extension that needs superuser.

How a database made earlier moves

A database made before 0.42.0 hands out the administrative account in its connection URL. It keeps working while it moves, in this order:

  1. The control plane gives the database an application password. Nothing a service holds changes.
  2. The database creates the account. PostgreSQL does it within a minute of the agent updating, and moves the objects the postgres account owned to app. MySQL, Valkey and MongoDB do it when the database is next deployed, because their start command creates it.
  3. Once the database shows the account exists, the control plane rewrites the connection URL variables to name it. A service picks the new URL up on its next deploy. Until then it keeps the administrative account, which is not rotated or removed, so a service that has not been redeployed, a rolled-back release and a stopped service that starts again all keep connecting.

A URL variable you edited yourself is left as you wrote it. The superuser of a PostgreSQL database that moved stays on until you set POSTGRES_SUPERUSER_ACCESS to disabled, because only you know every service has been redeployed. The steps are in Move an existing database to the application account.

Boundaries

  • A database on a cluster whose agent is older than the control plane is not moved, and a new PostgreSQL database cannot be deployed to it. The console says to update the agent.
  • Compose import gives a Valkey consumer the administrative default user, because a client that gives a password and no user name signs in as it. Name the app user in the client's URL to use the application account.
  • The application account of MySQL, MongoDB and Valkey is created from letters and digits only. A password you set yourself that holds anything else is ignored and the account is not created.

On this page