It is unfortunately common that developers “bake in” credentials to both 3rd party services as well as credentials to the actual device into the firmware or software. This is commonly done out of convenience, despite it contradicting best practices. The downside with this however is that it both makes it very easy for an attacker or malicious user to extract this data. What makes matters worse is that these credentials are often shared across the entire fleet of devices. Depending on what type of credentials these are, the attacker could do things such as:
Assuming you as the developer even detect that that these credentials leaked, your only remedy is to issue a firmware update to the entire fleet in order to rotate the credentials. However, even this is a somewhat pointless exercise, as it the attacker can easily repeat the attack to gain access to the new credentials.
Enter WoTT. As per industry best practice dictates, you should never include credentials as part of your code base or firmware. WoTT makes enables you to easily separate out your credentials from the software. In real simple terms, the way it works is that you read the credentials from a JSON file on disk. Because of this separation, WoTT makes it easy to manage the credentials independently from the firmware. Moreover, as part of this separation, WoTT makes it easy to rotate keys across the entire fleet, or to provide unique credentials for every single device.
In scenarios where you might require an API key to a 3rd party service for your applications. Let’s assume this is a non-critical service, weather service that looks up the temperature for given location (that is compared to the temperature from a sensor to calculate the temperature delta).
To do this, we login to the WoTT Dashboard. On the left of WoTT Dashboard you can see a section called “Credentials”. Click on it.
Select ‘Add a credential’
Let’s break down the fields:
my_app
.api_key
.pi
.This should now be accessible on any device with the tag that you added. The agent will periodically fetch these credentials. To speed things up, you can run the command sudo wott-agent credentials
when you are testing this out.
With the credentials synced, you should be able to find all credentials in the folder /opt/wott/credentials/$USERNAME/$NAME.json
. To reveal the API key we generated above, simply run:
$ cat /opt/wott/credentials/pi/my_app.json
{
"api_key": "abc123"
}
All we now need to do in our application is to instead of hardcoding the credentials in our application, we read them from the above JSON file. In most programming languages, this would merely require a few lines of code.
In the above example, we used tags to assign a shared key to one or more devices in a fleet. In a perfect world, you’d have individual credentials for each device. WoTT enables you to do this too. We call this “Device Metadata”. You can find this configuration if you navigate to a device and select the “Metadata” tab. You can then create as many per-device keys as you want. These can be anything from configuration values, to credentials.
If we for instance create a new key-value pair “Hello: World”, we can read this back much as we did above:
$ sudo cat /opt/wott/device_metadata.json
{
"manufacturer": "Raspberry Pi",
"Hello": "World",
"model-decoded": "Zero v1.2",
"device-name": "My Device",
"model": "900092",
"device_id": "x.d.wott.local"
}
As you can see above, we automatically populate this file with some handy meta data that you might want want to use as part of your application logic. It is however worth noting that the device metadata does not have the same granularity of permission access control, as it is locked down to “root” in order to avoid accidental leakage.
Please do note that if you want to speed up a sync, you need to use the command sudo wott-agent device-metadata
.