Skip to Content
DashboardsHow-to guidesStore datasource credentials

Store datasource credentials

A standalone server can keep datasource credentials itself, encrypted in its database. Use this when there is no ModularIoT to hold them. With ModularIoT, credentials live in ModularIoT’s Credentials screen instead, and this guide does not apply.

How it is organized

RecordHoldsWho can read it
DatasourceName, type, target address, and the name of its credentialMembers of the scope
CredentialThe secret, encrypted with AES-256-GCMNobody. The API only returns a summary: the kind and the last characters.

No dashboard, API answer or log line contains the secret.

1. Turn on the credential store

Generate a key and keep it with your other secrets:

openssl rand -base64 32

Start the server with it and a database store:

MIOT_DASHBOARD_STORE=sqlite MIOT_DASHBOARD_CREDENTIALS_KEY=<the key>

The key must have at least 32 characters, and the store must be sqlite or postgres. The server refuses to start otherwise.

If you lose the key, every stored credential becomes unreadable. If you change it, load the credentials again.

2. Store a credential

This is the only request that carries a secret:

curl -X PUT https://dashboards.example.com/tenants/acme/scopes/ops/credentials/fleet-api \ -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \ -d '{"kind":"BEARER","token":"the-api-token"}'
kindFieldsSent to the target as
NONEnoneNothing
BEARERtokenAuthorization: Bearer …
API_KEY_HEADERheader, valueThe named header
API_KEY_QUERYparam, valueA URL parameter
BASICusername, passwordAuthorization: Basic …
SERVICE_ACCOUNTprojectId, clientEmail, privateKeyA Google access token, for BigQuery

A misspelled field is refused with 400 rather than stored empty.

3. Create the datasource

curl -X POST https://dashboards.example.com/tenants/acme/scopes/ops/datasources \ -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \ -d '{ "name": "Fleet", "type": "POSTGREST", "isActive": true, "target": "https://data.acme.example/rest/v1", "credentialRef": "fleet-api" }'
typetarget
POSTGRESTThe PostgREST base URL. Must be https and must not contain user:password@.
BIGQUERYproject.dataset. With a service account, the dataset name alone is enough.

4. Test it

curl -X POST https://dashboards.example.com/tenants/acme/scopes/ops/datasources/{id}/test \ -H "Authorization: Bearer $TOKEN"
{"data":{"testable":true,"success":true,"status":200,"testedAt":"2026-10-05T12:00:00.000Z","message":"The target answered"}}
ResultMeans
success: trueThe target answered with the credential
status: 401 or 403The target refused the credential
status: 404The target does not exist, or the credential cannot see it
No statusThe target could not be reached in time

To test values before saving them, send the same body to .../datasources/test. A redirect counts as a failure, because following it would let the target choose where the credential goes. The answer never includes the target’s response body, which could echo the credential.

Let another system keep the credentials

If a different system already owns credentials, set MIOT_DASHBOARD_CREDENTIALS_URL instead of the key. The server then asks that system which headers to send, and stores nothing. See Configuration. Set the URL or the key, never both.

Last updated on