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:
'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:
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:
$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:
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.