Manage credentials
Connection string formats, safe rotation, and the minimal read-only database roles Backup needs.
Credentials live on the datasource. Backup stores them KMS-encrypted (how exactly); the plaintext exists only in memory — on the control plane briefly during save and connection tests, and inside the backup worker for the duration of a job.
Provide credentials
After creating a datasource the credentials page opens automatically; later you can reach it from the datasource's ⋯ menu → Credentials.
The dashboard takes one field — the full connection string:
postgres://user:password@host:5432/database?sslmode=requiremongodb://user:password@host:27017/database?tls=true&authSource=adminThe URI is stored as-is, so anything your database needs — TLS options,
authSource, mongodb+srv scheme, non-default ports — goes into the
string. (The API additionally accepts a field-by-field mode — host,
port, user, password, database — if you're integrating
programmatically; see the API reference.)
Click Save Credentials. Two things happen:
- The credentials are envelope-encrypted (AES-256-GCM + KMS) before they touch the database.
- A connection test runs immediately. You'll see "Credentials saved. Connection OK (X ms)." — or a 10-second warning toast with the failure reason and the blunt truth: "Your scheduled backup will fail until you fix this."
Passwords with special characters
Because credentials are a URI, characters that have a meaning in a URL must be percent-encoded in the password — otherwise the string parses into the wrong pieces and you get the confusing case where the connection test passes but the backup fails (or vice-versa). The ones that break parsing:
| Character | Encode as | Character | Encode as |
|---|---|---|---|
/ | %2F | # | %23 |
? | %3F | % | %25 |
For example, a password of p@ss/w#rd goes into the URI as
p@ss%2Fw%23rd:
postgres://user:p@ss%2Fw%23rd@host:5432/database?sslmode=requireA literal @ in the password is tolerated (it's split at the last
@ before the host), but percent-encoding every reserved character is
the safe habit. When in doubt, run your password through a URL-encoder.
Rotate credentials
Create new credentials in your database
ALTER USER ... PASSWORD '...' for Postgres, or
db.updateUser(...) / db.createUser(...) for Mongo. Prefer creating
a new role so both work during the switch.
Update the datasource
Open ⋯ → Credentials, paste the new URI, Save Credentials. The automatic connection test confirms the new credentials work.
Let a backup run on the new credentials
Future backups use the new credentials immediately; a job already in flight finishes on the old ones. Wait for the next successful run (check Backup jobs) before revoking anything.
Revoke the old role
Drop or disable the old database role.
Use a read-only role
Backup only needs read access. A dedicated minimal role limits the blast radius if credentials ever leak — and makes the access easy to revoke without touching your app's credentials.
CREATE ROLE norcube_backup LOGIN PASSWORD '...';
GRANT pg_read_all_data TO norcube_backup;pg_read_all_data (Postgres 14+) covers every table and sequence. On
older versions, grant SELECT per schema:
GRANT SELECT ON ALL TABLES IN SCHEMA public TO norcube_backup; plus
matching ALTER DEFAULT PRIVILEGES.
db.createUser({
user: 'norcube_backup',
pwd: '...',
roles: [{ role: 'read', db: 'myDatabase' }],
});To back up multiple databases through one URI, grant read on each —
or readAnyDatabase on admin if that fits your security posture.
Behaviour and edge cases
- Credentials are write-only. Once saved, no screen or API response ever returns them — the dashboard only shows whether credentials exist. Keep your own copy in a secret manager.
- Saving new credentials replaces the old ones entirely. There's one credential slot per datasource.
- Audit trail without secrets. Every save writes a
datasource.credentials_setaudit entry — with a success flag only, never the credential material. - A failed post-save test doesn't block saving. The credentials are stored either way (you might be mid-firewall-change); the toast just warns you that backups will fail until the connection works.