Skip to main content

Configuration

Every option can be passed to dashOtaMiddleware() / createOtaBackend() or set through an environment variable. Options you pass win over the environment; an option passed as undefined counts as not passed. Pass only what you need.

dashOtaMiddleware({
adminToken: process.env.OTA_ADMIN_TOKEN,
storageDir: '/var/lib/dash-ota/storage',
dataDir: '/var/lib/dash-ota/data',
verifyEnrollToken: async (token) => <YOUR_SESSION_CHECK>(token),
});

Options and environment variables​

OptionEnvDefaultMeaning
portOTA_PORT4455listen port of the standalone server
adminTokenOTA_ADMIN_TOKENempty: admin routes disabledtoken for /admin/*, sent in the x-ota-admin-token header
storageDirOTA_STORAGE_DIR<cwd>/.dash-ota/storagerelease files, with the disk store
dataDirOTA_DATA_DIR<cwd>/.dash-ota/datarelease and device metadata, with the disk store
timestampSkewMsOTA_TS_SKEW_MS300000 (5 min)allowed clock difference on signed requests
nonceTtlMsOTA_NONCE_TTL_MS600000 (10 min)how long a request nonce is remembered; keep it at least twice timestampSkewMs
downloadTokenTtlMsOTA_DL_TTL_MS1800000 (30 min)lifetime of a download token; reusable for every file of that release until then
maxBundleBytesOTA_MAX_BUNDLE_BYTES104857600 (100 MiB)cap on a whole release
maxBlobBytesOTA_MAX_BLOB_BYTES67108864 (64 MiB)cap on one uploaded file, enforced while it arrives
maxAdminBodyBytesOTA_MAX_ADMIN_BODY_BYTES33554432 (32 MiB)cap on an admin JSON body, such as a release manifest
enrollRateLimitOTA_ENROLL_RATE10/enroll requests per install per window; 0 turns it off
checkRateLimitOTA_CHECK_RATE60/check requests per install per window; 0 turns it off
rateLimitWindowMsOTA_RATE_WINDOW_MS60000rate-limit window
autoPauseFailureRateOTA_AUTOPAUSE_RATE0.2share of failure reports that pauses a release
autoPauseMinSamplesOTA_AUTOPAUSE_MIN5reports needed before auto-pause can trigger
requireRequestSignatureOTA_REQUIRE_SIGtruerequire the device-key signature on /check and /confirm
requireEnrollAuthOTA_REQUIRE_ENROLL_AUTHtruerequire an enroll token (checked by verifyEnrollToken if you set it, otherwise only for presence)

Other limits are fixed: device and unauthenticated JSON bodies are capped at 64 KiB, and larger bodies get 413 too_large.

The standalone server also reads OTA_ACCESS_LOG=true, which logs every request's status, method and path.

Storage​

Set one of these to replace the disk defaults. See Storage providers.

OptionEnvSelects
databaseUrlOTA_DATABASE_URLPostgres database (optional peer pg)
sqlitePathOTA_SQLITE_PATHSQLite database (optional peer better-sqlite3)
redisUrlOTA_REDIS_URLRedis cache (optional peer ioredis); needed with more than one instance
s3Bucket, s3Region, s3Endpoint, s3ForcePathStyle, s3PrefixOTA_S3_BUCKET, OTA_S3_REGION, OTA_S3_ENDPOINT, OTA_S3_FORCE_PATH_STYLE=true, OTA_S3_PREFIXS3, R2 or MinIO file storage (optional peer @aws-sdk/client-s3)

Hooks​

verifyEnrollToken, onConfirm, onPublish and logger are options too. See Hooks.

Production checklist​

  • Set a long random adminToken, and reach /admin/* only over HTTPS. With no token the admin routes answer 503 admin_disabled.
  • Set verifyEnrollToken to check a real user session.
  • Leave requireRequestSignature and requireEnrollAuth on. They exist to be turned off in tests.
  • Set storageDir and dataDir to a backed-up location, or use a database and object storage.
  • With more than one instance, set redisUrl so replay protection and rate limits are shared.

resolveBackendConfig​

resolveBackendConfig(options) returns the complete configuration: your options over the environment over the defaults. The middleware and the factory call it; use it if you need the resolved values yourself.

→ Hooks · Endpoints