OpenBalena V3: How to get `api secret`?

In the openBalena V2, the BALENA_SUPERVISOR_API_KEY variable on each device is same with the api secret field value in device table of the openBalena database.

But seems it’s now encrypted or modified in V3.

We were using this to authenticate our devices on our custom web server.

Is there anyway to get this api secret value from the supervisor api key of each device?

On balenaOS device:

root@viso:/usr/app# printenv | grep BALENA
BALENA_HOST_OS_VERSION=balenaOS 2.67.0+rev1

But DB:


Can you please check if the value for api secret matches BALENA_API_KEY instead?

You can find more info about these variables here

Thanks for your quick reply, @rahul-thakoor

This is weird, I cannot find BALENA_API_KEY value in the container! Please check my previous message… no such value from printenv | grep BALENA!


Hey there
Can you add io.balena.features.balena-api: 1 to your docker-compose file? Similar to how you’ve enabled the supervisor api (since BALENA_SUPERVISOR_API_KEY key is available)

Hmm, not same with the API_KEY, unfortunately… :confused:

root@viso:/usr/app# printenv | grep BALENA_API_KEY

Not sure how we can get the api secret value in the device table?
Maybe hashed? Or any other column is used instead?


Hey there, I don’t quite understand your use case, you want to use the API key inside a container? I see BALENA_API_KEY is defined correctly, what is the problem you are having?


We were using SUPEVISOR_API_KEY in a container. Actually were using that to authenticate to our custom REST API server on the openBalena instance.
The device table has that value, so our server was able to use this value to authenticate.

But now, on V3, api secret field value in the device table is not same with the API_KEY value on device. So our custom server cannot authenticate the balenaOS devices…
Does this make sense?

It does makes sense, thanks for clarifying. We hash the value of the API key as an improved security measure, and you shouldn’t depend on being able to read the raw value from the table, so I think the approach is not the right one. You should treat the API service as your authentication service, and pass to it an API key the same way the device does it for example. I am not sure what your custom server does, but my guess would be something like this:

Device -> get something from custom server -> custom server compares key against DB value -> decides whether it should respond with 200.

Device -> get something from custom server -> custom server checks with API if token has the asked permission -> decides whether it should respond with 200

Does that make sense? For example, your custom server can try to get the information of the device from the API, and if it succeeds, it means that API key comes from the device it claims it does.