Skip to content

Secrets ​

Last updated

A secret is a credential stored once, encrypted, and referenced from configuration as ${secret:NAME} instead of being pasted in. Rotating a password becomes one edit here.

Open Secrets in the admin section of the sidebar. Admin only.

Create or replace a secret ​

  1. Click New secret.
  2. Name: uppercase letters, numbers and underscores, starting with a letter, up to 64 characters (e.g. SMTP_PASS). Lowercase is converted as you type. If the name exists, the form title changes to Replace "NAME" and saving replaces the value.
  3. Description: what it is for (optional).
  4. Value: the credential. Stored encrypted. It cannot be read back afterwards — only replaced.
  5. Click Save.

The list shows Name, Reference (click to copy ${secret:NAME}), and Last used — when something last resolved it and what (for example smtp), or never used.

Where references work ​

A reference is expanded only by code that knows to expand it. Today that is:

FieldUsed byExpanded
Password on the SMTP Email card in SettingsAlarm pipeline email, scheduled report email, workflow email, and everything else sent through the SMTP pathEach time mail is sent
DNS provider credential on the ACME card in CertificatesCertificate renewalEach renewal
Any credential in a device's driver settings: a password, a token, an API key, or the password inside a URL such as rtsp://admin:${secret:CAM_PW}@camera/streamOPC-UA, MQTT and HTTP devices, scales and scanners, and vision camerasEach time the device connects
Password, connection string and connection options of a remote databaseThe connection pool, the historian's SQL backend, named queries, data tables, and Test ConnectionEach time the pool opens, and on every test
Bearer token, basic-auth password, API key, any header value, and the URL of an outbound REST callOutbound RESTEach call
Password of a Sparkplug connectionThe MQTT broker loginEach time it connects

Because the value is looked up at the moment it is used, rotating a credential is one edit here. Nothing has to be saved again: replace the secret, and a device picks the new value up the next time it connects, a database on the next pool it opens.

Anywhere else a reference is not expanded and would be used literally — script source, a report, an expression, and the OPC-UA server's own password, which clients authenticate against rather than something the appliance sends anywhere.

How a reference reads back ​

A stored credential reads back as ••••••••, for every role including viewers, and saving those dots back unchanged keeps what is stored. A reference is a name rather than a credential, so it reads back exactly as you typed it, and the field shows it instead of dots. That is how you can tell, on a device or a database connection somebody else set up, that its password comes from here. Saving a reference back unchanged keeps it too.

A reference to a secret that does not exist fails where the credential is used, and the message names the secret: Secret "DB_PWD" is not in the Secrets store. Create it under Secrets, or correct the reference. You will see it as the device's connection error, as the result under Test Connection, or as the last status of an outbound call — and nothing is sent to the far end. The SMTP path is the one exception: it leaves the reference in place, so the mail server receives the literal text ${secret:SMTP_PASS} and rejects the login.

Example: SMTP password ​

  1. Secrets → New secret → Name SMTP_PASS, Value the mailbox password → Save.
  2. Settings → SMTP Email → Password → ${secret:SMTP_PASS} → Save Settings.
  3. When IT rotates the password, replace the secret. The next alarm email uses the new value.

What the encryption protects ​

  • Values are encrypted with AES-256-GCM. The key is derived from the appliance's JWT secret (JWT_SECRET, or the generated file apps/api/data/.jwt-secret).
  • No API returns a value — not to this page, not to exports, not to admins. The audit log records create, replace and delete, never the value.
  • This protects against a stolen SD card or a copied database file. It does not protect against someone with root on a running appliance, who can read the key the same way the application does.
  • Backups contain secrets in encrypted form. Restoring a backup onto a different appliance (a different JWT secret) leaves every secret undecryptable; the log reports could not be decrypted (was JWT_SECRET rotated?). Re-enter the values after such a restore.
MethodEndpointPurpose
GET/api/secretsNames, descriptions and last-used metadata
POST/api/secrets{ "name", "value", "description" } — creates or replaces
DELETE/api/secrets/:idDelete

Tip: Check Last used before deleting. A secret resolved this morning is still wired into something.

Troubleshooting ​

SymptomCauseFix
Uppercase letters, numbers and underscores; must start with a letter.Invalid nameRename, e.g. MAIL_PASSWORD_2
Mail server rejects login; its log shows ${secret:…} as the passwordThe name in the reference does not match any secretFix the reference or create the secret
Secret "NAME" is not in the Secrets store on a device, a database connection or an outbound callThe name in the reference matches no secret — check spelling and caseFix the reference, or create the secret
Secret shows never used although it is referencedIt is referenced from a field that does not expand secrets, or nothing has used it yet — a device reads it when it connects, not when you save itCheck the table above, then reconnect whatever uses it
All secrets stopped working after a restore or reinstallDifferent JWT secretRe-enter the values

See also ​

Scada.Ink Help Center