Skip to content

Powered by Grav

Database credentials — cloaking

Database credentials — cloaking

Open a hosted Drupal or Backdrop site's sites/<uri>/settings.php and you will not find a database password. You will find this instead:

PHP
'password' => $_SERVER['db_passwd'],

That is credential cloaking: the file names the credentials rather than containing them, and something outside the file supplies the values at the moment they are needed. It is on by default.

Why the password is not in that file

Each Octopus instance runs one PHP-FPM pool, as the instance's own web user (oN.<php>.web, in group www-data). Every site in that instance is served by that pool — and so is the instance's own Ægir panel. For any of them to be served, settings.php has to be readable by that shared web user; it ships 0440 owned oN:www-data precisely so it can be.

That makes settings.php the wrong place to keep a secret. Anything running as the pool user can read every one of them, and the panel's own database account is far more privileged than a single site's. Cloaking removes the value from the file the web user can read, and keeps it in files the web user cannot.

The isolation between Octopus accounts has never depended on this — separate Unix users and separate pools do that work, and each site's database account is granted rights over its own database and nothing else. Cloaking closes the one channel that sat inside an instance, where the sharing is by design.

Where the credentials actually live

Holder Mode Read by
The site's Nginx vhost, as fastcgi_param db_* 0600 oN:users Nginx, which passes the values into PHP as $_SERVER
sites/<uri>/drushrc.php 0440 oN:users Drush and the shell identities (oN, oN.ftp)
A site backup archive inside the archive see Backups below

The common thread is the group. settings.php carries group www-data because the web server must read it. Both on-disk holders carry group users instead, which the web pool user is not a member of — so a web request can obtain the credentials for the site it is serving, and nothing else can read them off disk. The Ægir site alias in ~/.drush/ is not a credential holder: it records db_server and the site's other context, and Drush takes the credentials themselves from drushrc.php.

The two paths

A web request arrives through the site's vhost, which passes the six db_* values to PHP-FPM. settings.php reads them from $_SERVER, builds the connection, and the request proceeds normally. Nothing about this is visible to the site's code beyond the connection itself.

The command line has no vhost, so $_SERVER is empty. settings.php therefore falls back to reading the values out of the sibling drushrc.php, which the shell identities can read. This is what keeps ordinary Drush, site-local Drush and vdrush in the limited shell working exactly as before — including updatedb and cache rebuilds on Drupal 10 and 11, which run through a site-local Drush of their own.

You do not have to do anything to get either path. Both are wired by Provision when it writes the site.

Backups keep the real credentials

A backup is deliberately not cloaked. Before the archive is written the credentials are put back into settings.php in full, and restored to their cloaked form immediately afterwards. Without that, an archive would be useless anywhere except a server that already had a matching vhost — which would defeat the point of an off-site backup.

So an archive from ~/backups, or one opened with boa-restore, contains a working settings.php with real credentials. Treat those archives as secrets, which is the same rule that already applied to the database dump inside them.

Where cloaking does not apply

Textpattern keeps its credentials in textpattern/config.php, and Grav sites have no database at all. Neither participates in cloaking. Nothing is weakened by that: those sites hold only their own database account, scoped to their own database, exactly as a Drupal site's is.

Reading a site's credentials as an operator

When you need the values — to open a client's database by hand, for instance — take them from drushrc.php, or let the tooling do it:

BASH
drush @<site-alias> sql-connect

The database GUI tools and sqlmagic work through the site's Drush alias rather than by reading settings.php, so they are unaffected.

Advanced — turning it off

Cloaking is a property of the HTTP service, resolved per site when Provision writes settings.php:

PHP
$this->cloaked = drush_get_option('provision_db_cloaking', ->cloaked_db_creds());

The Nginx service returns TRUE, so cloaking is the default for every site on the server. A single Provision command can be overridden:

BASH
drush @<site-alias> provision-verify --provision_db_cloaking=0

That re-renders one site's settings.php with literal credentials, and the next ordinary Verify puts it back. There is no reason to run it in normal operation; it exists for the backup path described above and for debugging. Turning cloaking off server-wide means editing the Provision service and is not supported as a configuration choice.

© 2026 BOA Documentation. All rights reserved.