Manage WiFi Credentials from the Particle Web Console?

In reading the documentation about the Particle products, there is a section that indicates that they can save the last {x} sets of WiFi credentials. My assumption is that it might scan for any of these in the area when looking to connect. Is this correct?

https://docs.particle.io/reference/device-os/firmware/photon/#setcredentials-

As I was looking to manage some remote devices, I started to look for how I can manage the WiFi credentials from the Particle Web Console. I have one that is currently connected, and want to remotely add an additional set of WiFi credentials, and have it change the WiFi network it is attaching to.

I can obviously view my devices: https://console.particle.io/devices

Then I can select a device, and view all of the details. I can’t find anywhere to view the current WiFi credentials and/or edit/manage them.

Is this possible or not?

Thanks in advance!

You would need to implement some code to expose/modify your stored credentials in your own code.
If such a feature would be exposed by default it might open some security risks.

1 Like

I understand if the feature is not present. I’m not sure how it would be more of a security risk then being able to deploy firmware from the Web IDE.

After talking with a friend at Particle I’m looking to develop a Particle.function() to do this. Of course now I need to read up on securing the endpoint. :slight_smile:

I’m also not clear on how it picks from the list of credentials, when multiple are present. Does it actually iterate the list in order looking for the first to match? What I’m wondering is about a crude “priority” scheme.

If that is the case, then I can create a function, and pass an array of credentials. In the function I can then clear all credentials and set them in the order I want. Of course with the possibility that things could go wrong if no valid credentials are sent. :slight_smile:

I’m not sure how it would be more of a security risk then being able to deploy firmware from the Web IDE.

As you are aware, the WiFi credentials are stored on the WiFi module and passwords are not retrievable once set. The risk of a hacker wirelessly accessing the device is therefore limited once the WiFi credentials have been set. Deploying firmware from the web IDE requires access tokens (which is why all devices should be claimed) and is encrypted.

I’m also not clear on how it picks from the list of credentials, when multiple are present. Does it actually iterate the list in order looking for the first to match? What I’m wondering is about a crude “priority” scheme.

It doesn't, it just works through the items stored when trying to connect. There is no control over the priority of connection, like signal strength. You can't select a stored SSID and ask to connect to that one. When you go through the logic around the WiFi module it is much simpler to just store 1 WAP then you can determine things like WAP out of range or bad credentials without needing to dig into the WICED error codes.

Please share your progress on this - I think we'd all be interested in improvements around this area.

I have a few follow-up questions:

I did understand the WiFi credentials are stored in a way that the password is not readable after they have been set.

If I chose to use a Particle.function() to allow the WiFi credentials to be set, the function is only accessible over HTTPS (providing encryption) and using an Access Token (providing authentication/authorization), so that portion of the communications should be secure.

If the function request and arguments are then encrypted down to the device (which I believe is true, but am not sure) then delivering the credentials to the device would be secure. Is that correct?

At that point my thought is to provide multiple possible sets of credentials via the function to allow for a "fall back" in case the "new" credentials are not valid for some reason. I'm trying to work out a way to prevent the device from becoming disconnected permanently, requiring a physical visit to the device to get it working again.

Looking at the APIs I realized there did not seem to be a way to indicate a specific WiFi SSID to connect to ... unless I stored my own array, completely outside of the ones that can be stored in the WiFi module, and iterating through them myself "manually" in code.

The module must be storing these in a table or registers, and must have some programmatic method it uses to iterate them internally, hence my thought to "clear" all of the credentials, and then add them in the order that I want them checked ... hoping that they iterate their list in that order. (Maybe wishful thinking ... but I'll test and see what I see.)

I'll see if I can experiment with this over the weekend and I'll post my results. I'd like to find a way to better manage the connectivity in a larger infrastructure application where devices could be load balanced over multiple SSIDs, and migrated to new infrastructure as it is installed.

1 Like

The module must be storing these in a table or registers, and must have some programmatic method it uses to iterate them internally, hence my thought to “clear” all of the credentials, and then add them in the order that I want them checked

They are stored in a circular buffer, so this approach should work.

Good luck with your testing.

You’ve likely figured this out by now:

  • it’ll connect to the most recently configured credentials first (from my experience, so 99.9% sure)
  • don’t clear. Just add your backup SSID creds then the ‘real’ creds again. However, this means you’re storing the creds in encrypted format somewhere, which means they can be hacked.

Storing raw passwords isn’t that great. When you do setup via softap-browser it passes the password through the air encrypted with the device’s public key. Which is pretty good.

Ideally there would be firmware functions (there may be, I haven’t seen them) to retrieve the public key and provide new credentials with an encrypted password. You’d get the user’s wifi password in the clear, process it against the public key for the hashed password, store that and apply as a new set of creds. At least then your data source if its compromised has encrypted keys and they’re useless to gain access to the network from a new device. Just a thought.

By the way, this is why I never implemented backup wifi network details.

Thinking about it, there’s a more elegant solution. If you’re disconnected for x minutes check the list of SSID names stored in memory. Check for your backup network. If it’s not there add it. It’s all easy via existing Particle functions and event handlers (ie cloud disconnect). Your ‘real’ customer network won’t be lost and you’re not storing and moving around real passwords.

@mterrill, IMHO you can simplify the addition of a backup network. Within startup() iterate through the stored list of networks and if the backup network is not in the stored list, simply add it.