Skip to Content
DashboardsReferenceConfiguration

Configuration

The server reads its configuration from environment variables at startup. All of them start with MIOT_DASHBOARD_, except PORT, HOST and NODE_ENV. A change needs a restart.

The server refuses to start on a combination that is unsafe or contradictory, and says which. It never falls back to a weaker setting.

Network

VariableDefaultMeaning
PORT3070Port to listen on
HOST127.0.0.1Address to bind. The container image uses 0.0.0.0.
MIOT_DASHBOARD_BASE_PATHemptyPrefix for every API route, when the server is not at the root
MIOT_DASHBOARD_DOCSonServe /openapi.yaml, /dashboard-config.schema.json and Swagger UI at /docs
MIOT_DASHBOARD_CORS_ORIGINSoffOrigins allowed to call from a browser, comma-separated and exact. No wildcards.
MIOT_DASHBOARD_CORS_CREDENTIALSfalseAllow cookies and HTTP authentication from those origins
MIOT_DASHBOARD_CORS_HEADERSemptyExtra request headers to allow, such as a ticket header

CORS always allows Authorization, Content-Type and If-Match, and exposes ETag.

Storage

VariableDefaultMeaning
MIOT_DASHBOARD_STOREmemorymemory, sqlite or postgres
MIOT_DASHBOARD_SQLITE_PATH./data/dashboards.dbThe SQLite file
MIOT_DASHBOARD_POSTGRES_URLnonePostgreSQL connection string. Contains a password.
MIOT_DASHBOARD_POSTGRES_POOL_SIZE10Pooled connections
MIOT_DASHBOARD_POSTGRES_CONNECTION_TIMEOUT5000Milliseconds to wait for a connection
MIOT_DASHBOARD_DOCUMENTSinlineinline, fs, s3 or gcs
MIOT_DASHBOARD_DOCUMENTS_PATH./data/documentsDirectory, with fs
MIOT_DASHBOARD_DOCUMENTS_BUCKETnoneBucket, with s3 or gcs. Required for those.
MIOT_DASHBOARD_DOCUMENTS_PREFIXdashboards/Object prefix, with s3 or gcs
MIOT_DASHBOARD_S3_REGIONSDK defaultAWS region, with s3
MIOT_DASHBOARD_ORPHAN_SWEEP_INTERVAL3600Seconds between leftover-document sweeps. 0 turns them off.
MIOT_DASHBOARD_ORPHAN_MIN_AGE86400Seconds before a leftover document may be removed. At least 1.
MIOT_DASHBOARD_SEEDnonePath to a seed file with memberships and starting dashboards, or example

Identity

JWT

VariableDefaultMeaning
MIOT_DASHBOARD_JWT_ISSUERnoneRequired. The exact iss tokens must carry.
MIOT_DASHBOARD_JWT_AUDIENCEnoneRequired. One audience, or several separated by commas.
MIOT_DASHBOARD_JWT_JWKS_URLnoneKey source: the provider’s JWKS (RS256)
MIOT_DASHBOARD_JWT_PUBLIC_KEYnoneKey source: a PEM public key (RS256)
MIOT_DASHBOARD_JWT_SECRETnoneKey source: a shared secret of at least 32 bytes (HS256)
MIOT_DASHBOARD_JWT_USER_CLAIMsubClaim holding the user ID
MIOT_DASHBOARD_JWT_GROUPS_CLAIMnoneClaim holding the user’s groups
MIOT_DASHBOARD_JWT_NAME_CLAIMnameClaim holding a display name
MIOT_DASHBOARD_JWT_CLOCK_TOLERANCE30Seconds of clock difference allowed on expiry. At most 300.

Set exactly one key source. JWT verification needs the jose package.

Tickets

VariableDefaultMeaning
MIOT_DASHBOARD_TICKET_HEADERnoneRequired. Request header carrying the ticket.
MIOT_DASHBOARD_TICKET_VALIDATE_URLnoneRequired. The issuer’s check endpoint, using {ticket} or {ticketBase64}
MIOT_DASHBOARD_TICKET_ALLOW_HTTPfalseAccept an http:// check endpoint on a private network
MIOT_DASHBOARD_TICKET_VALIDATE_METHODGETGET or POST. POST when presenting in the body.
MIOT_DASHBOARD_TICKET_USER_PATHnoneRequired. Dotted path to the user ID in the answer
MIOT_DASHBOARD_TICKET_SCHEMEnonePrefix to strip, for a header like Ticket <value>
MIOT_DASHBOARD_TICKET_PRESENTheaderHow to send the ticket to the issuer: header, query or body
MIOT_DASHBOARD_TICKET_PRESENT_NAMEnoneHeader or query parameter name for the issuer
MIOT_DASHBOARD_TICKET_PRESENT_VALUEnoneHeader value template, such as Basic {ticketBase64}
MIOT_DASHBOARD_TICKET_SERVICE_HEADERnoneName of a header with the server’s own credential
MIOT_DASHBOARD_TICKET_SERVICE_VALUEnoneIts value
MIOT_DASHBOARD_TICKET_GROUPS_PATHnoneDotted path to the groups in the answer
MIOT_DASHBOARD_TICKET_NAME_PATHnoneDotted path to a display name
MIOT_DASHBOARD_TICKET_INVALID_STATUS401,404Statuses that mean “not valid”. Required with a service credential.
MIOT_DASHBOARD_TICKET_CACHE60Seconds a valid ticket is reused. 0 checks every request.
MIOT_DASHBOARD_TICKET_NEGATIVE_CACHE30Seconds a rejection is reused
MIOT_DASHBOARD_TICKET_TIMEOUT5000Milliseconds to wait for the issuer

Development only

VariableMeaning
MIOT_DASHBOARD_INSECURE_AUTHTrust x-dev-user and x-dev-groups headers without checking. Refused with NODE_ENV=production, a non-loopback HOST, JWT or ticket settings, or a proxy key.

Memberships

Organizations

VariableDefaultMeaning
MIOT_DASHBOARD_TENANTS_URLnone (seed file)Lookup over {userId} and {tenantId}. A GET URL must contain both.
MIOT_DASHBOARD_TENANTS_METHODGETGET, or POST with the question as JSON
MIOT_DASHBOARD_TENANTS_ENTITLED_PATHnoneDotted path to a boolean, for a service that answers 200 either way
MIOT_DASHBOARD_TENANTS_SERVICE_HEADERnoneHeader with the server’s own credential
MIOT_DASHBOARD_TENANTS_SERVICE_VALUEnoneIts value
MIOT_DASHBOARD_TENANTS_ABSENT_STATUS404Statuses that mean “not a member”
MIOT_DASHBOARD_TENANTS_CACHE60Seconds a yes is reused
MIOT_DASHBOARD_TENANTS_NEGATIVE_CACHE30Seconds a no is reused
MIOT_DASHBOARD_TENANTS_TIMEOUT5000Milliseconds to wait

Scopes

VariableDefaultMeaning
MIOT_DASHBOARD_SCOPES_URLnone (seed file)Lookup over {tenantId}, {scopeId} and {userId}. A GET URL must contain {userId} and {scopeId}.
MIOT_DASHBOARD_SCOPES_METHODGETGET or POST
MIOT_DASHBOARD_SCOPES_ROLE_PATHroleDotted path to the role in the answer
MIOT_DASHBOARD_SCOPES_ROLE_MAPnonetheirs=ours pairs, such as admin=Coordinator,reader=Consumer
MIOT_DASHBOARD_SCOPES_SERVICE_HEADERnoneHeader with the server’s own credential
MIOT_DASHBOARD_SCOPES_SERVICE_VALUEnoneIts value
MIOT_DASHBOARD_SCOPES_ABSENT_STATUS404Statuses that mean “not a member”
MIOT_DASHBOARD_SCOPES_CACHE60Seconds a membership is reused
MIOT_DASHBOARD_SCOPES_NEGATIVE_CACHE30Seconds a non-membership is reused
MIOT_DASHBOARD_SCOPES_TIMEOUT5000Milliseconds to wait

Roles from groups

Organization and scope membership read from the caller’s groups. It replaces the two lookups above and the seed file’s memberships.

VariableDefaultMeaning
MIOT_DASHBOARD_GROUP_ROLES_PATTERNoffThe group name with {tenant} and {role}, and optionally {scope}, such as GROUP_DHB_{tenant}_{role}. Matched without regard to case or surrounding spaces. With {scope}, scope ids cannot contain the characters next to it.
MIOT_DASHBOARD_GROUP_ROLES_MAPCONSUMER=Consumer,CONTRIBUTOR=Contributor,EDITOR=Editor,COORDINATOR=Coordinatortheirs=ours pairs for the {role} part

Needs MIOT_DASHBOARD_TICKET_GROUPS_PATH or MIOT_DASHBOARD_JWT_GROUPS_CLAIM. The server refuses to start with the pattern and MIOT_DASHBOARD_TENANTS_URL or MIOT_DASHBOARD_SCOPES_URL together.

Trusted proxy

VariableDefaultMeaning
MIOT_DASHBOARD_PROXY_KEYnoneShared key, at least 32 characters. Requests carrying it may assert organization, scope and role. Also authenticates calls the server makes to the host.

Datasource credentials

VariableDefaultMeaning
MIOT_DASHBOARD_CREDENTIALS_KEYoffStore credentials in this server, encrypted with this key. At least 32 characters. Needs sqlite or postgres.
MIOT_DASHBOARD_CREDENTIALS_URLoffAsk another system for credentials instead. Must contain {tenantId} and {credentialRef}. Needs the proxy key.
MIOT_DASHBOARD_CREDENTIALS_ALLOW_HTTPfalseAccept an http:// URL on a private network
MIOT_DASHBOARD_CREDENTIALS_TIMEOUT5000Milliseconds to wait
MIOT_DASHBOARD_CREDENTIALS_CACHE60Seconds an answer is reused. At most 300.

Set the key or the URL, never both.

Saved queries

VariableDefaultMeaning
MIOT_DASHBOARD_OPERATIONS_MODULEoffAbsolute path to a trusted .mjs, .js or .cjs file that exports createDashboardOperations(), and optionally createDashboardQueryCatalog()
MIOT_DASHBOARD_OPERATIONS_URLoffA host endpoint that runs queries itself. Needs the proxy key.
MIOT_DASHBOARD_OPERATIONS_ALLOW_HTTPfalseAccept an http:// operations URL on a private network
MIOT_DASHBOARD_OPERATIONS_TIMEOUT20000Milliseconds, from 1 to 20000

Set the module or the URL, never both. Without either, query routes answer 404.

The bundled ModularIoT module

/app/examples/modulariot-operations.mjs in the container image reads these:

VariableDefaultMeaning
MIOT_DASHBOARD_PLAN_URLnoneRequired. The host’s plan endpoint, such as .../internal/dashboard-operations/resolve
MIOT_DASHBOARD_PLAN_ALLOW_HTTPfalseAccept http:// for the plan endpoint
MIOT_DASHBOARD_CATALOG_URLoffThe host’s catalog endpoint. Unset, editors cannot pick operations.
MIOT_DASHBOARD_DATA_ORIGINSemptyComma-separated data origins queries may call. Empty allows BigQuery only.
MIOT_DASHBOARD_DATA_ALLOW_HTTPfalseAccept http:// data origins

The two ALLOW_HTTP flags accept only true or false.

Testing

VariableMeaning
MIOT_DASHBOARD_TEST_POSTGRES_URLA throwaway PostgreSQL database for the package’s own tests. The tests empty it.
Last updated on