embeint.htf
Station runtime

Credentials and secrets

Provision each station independently and handle sensitive values safely.

Each station gets its own MQTT username, MQTT password, and station API key when it is created. The provisioning values appear once. Store them in a protected environment file or secret manager on that jig.

HTF_MQTT_USERNAME=station-...
HTF_MQTT_PASSWORD=st_mqtt_...
HTF_API_KEY=st_api_...

The station also needs its organisation and station IDs and the endpoint values for the HTF deployment. The sample .env.example lists the supported variables.

For the public production broker, the station also needs its own TLS client certificate and private key. Select Issue and download in the Station keys dialog during setup, or open Station settings later. The ZIP contains client.pem and client.key; install them in a private directory outside the station repository. Set HTF_MQTT_TRANSPORT=mtls and point HTF_MQTT_CLIENT_CERT and HTF_MQTT_CLIENT_KEY at those files. See the first-run walkthrough for the exact steps.

Rotate a credential

If a credential is exposed or a station connection may have been taken over, rotate it in the operator UI. Update that station's protected environment and restart it. Revoked values can no longer reconnect or call station APIs.

Station secrets

Users with station-secrets:manage permission can save named station secrets in HTF. The station fetches them at startup or reconnect and holds them in memory for stages that need them. Each run receives its own snapshot. Changes are not hot reloaded; restart or reconnect after an edit. Custom stages can request a named value from their stage context.

Open a station and select Station secrets. Enter an uppercase name, its value, and select Save secret. The UI shows the name later but does not reveal the value again. A custom stage reads it with context.require_secret("NAME").

Declare secret dependencies

In runtime v0.3.0, list the secret names a stage needs:

stages:
  - name: Register device
    kind: register_device
    required_secrets: [MANUFACTURING_TOKEN]

register_device is an example custom kind that your application must register. Its code reads the value with context.require_secret("MANUFACTURING_TOKEN"). The runtime checks all declared secrets for the lane's plan before any stage runs, so an unavailable credential stops the plan before hardware or external side effects.

If a managed-secret pull fails, the runtime clears stale values and the listener retries in the background while MQTT remains connected. Plans without secret dependencies can still run. A successful retry supplies fresh values to subsequent runs; an already-started run keeps its original snapshot. Check basic_station.secrets_pull_failed if a required-secret plan cannot start.

Keep secret values out of YAML, stage output, logs, and command-line arguments. A secret name can appear in configuration; its value should remain in the secret store and the process that needs it.