Skip to main content
Shared Secret authentication is the simplest way to connect a Nerves device to NervesHub. Instead of provisioning individual X.509 certificates, every device in a product shares a product_key and product_secret pair. The device derives an HMAC credential from these values at runtime and presents it to NervesHub when opening its WebSocket connection. No client certificates or hardware security modules are required, making this mode fast to set up and easy to iterate on during development.
Shared Secret authentication is designed for development and prototyping. Because all devices in a product share the same credentials, a compromised device exposes the secret for the entire fleet. For production deployments, migrate to Device Certificates or NervesKey so each device carries a unique, independently revocable identity.

How It Works

When a device running nerves_hub_link starts, it reads the configured product_key and product_secret, computes an HMAC-based authentication token, and presents that token during the Phoenix Channel handshake over the secure WebSocket connection. NervesHub verifies the token against the product’s registered secret and, if valid, accepts the connection. Because the credential is derived rather than static, the raw secret is never transmitted over the wire. The device identifier used in this mode is the device’s hardware serial number or a value you supply — there is no per-device certificate to manage or rotate.

Find Your Credentials

Retrieve your product credentials from the NervesCloud UI:
1

Open Product Settings

In NervesCloud, navigate to your organization and select the product you want to connect devices to.
2

Open the Shared Secret Tab

Click Settings in the left sidebar, then select the Shared Secret tab.
3

Copy Your Credentials

Copy the Product Key and Product Secret values. Treat the product secret like a password — do not commit it to source control.
Add nerves_hub_link to your Nerves project if you have not already, then configure the shared secret in config/target.exs:
Set the environment variables in your build environment before running mix firmware:
Using System.get_env/1 in config/target.exs bakes the values into the firmware at compile time. If you need to supply or rotate credentials at runtime — for example, reading them from a provisioned file on the device — use the NervesHubLink.Configurator behaviour instead (see below).

Securing Credentials

Use Environment Variables

Never hardcode product_key or product_secret directly in source files. Pass them through environment variables in your CI/CD pipeline or local build environment as shown above. This keeps secrets out of version control and lets you rotate them without changing code.

Runtime Configuration with Configurator

For more flexible credential management, implement the NervesHubLink.Configurator behaviour. This callback runs on device boot and lets you read credentials from any source — a provisioned file, an encrypted store, or a remote endpoint:
Then point nerves_hub_link at your configurator module:

Rotating the Product Secret

If your product secret is compromised, rotate it immediately in Product Settings → Shared Secret in the NervesCloud UI. Devices using the old secret will be disconnected until they receive the new value. Plan a rotation strategy before you go to production — this is another reason to prefer Device Certificates for production fleets.

Next Steps

Once you are ready to move beyond development, migrate your devices to a stronger authentication method:

Device Certificates

Provision each device with a unique X.509 certificate signed by your own CA. The recommended approach for production fleets.

NervesKey

Store device private keys in a hardware security module — keys never leave the chip.