span-hacs icon indicating copy to clipboard operation
span-hacs copied to clipboard

Need to provide durable authentication

Open mbbush opened this issue 2 years ago • 6 comments

Greetings! I am a home assistant user and software developer who recently started working for Span. The local API is pretty far removed from my official job duties, but it's something I care about and am helping out with as I can find spare time.

Currently, this integration makes unauthenticated api calls, relying on the fact that you can disable auth using a "proof of proximity" bypass involving the door switch. We do not currently have plans to remove the proof of proximity bypass, but we are going to substantially reduce its duration (to something like 15 minutes) so that users don't have to choose between a local integration and a secured api.

Before we roll out an update that would break this and other community-driven integrations, we want to provide an alternative means of authentication, which you can also use on current production firmware. The big picture is:

  1. Disable authentication on the panel using the door switch.
  2. While authentication is disabled, create an authorization token for the integration.
  3. Use that token to authenticate and authorize all subsequent calls, which will no longer require the panel to be in an "unlocked" insecure state.

In more detail, the recommended auth flow which will create a secure, durable, 100% local connection to the panel is as follows:

  1. POST to /api/v1/auth/register with JSON body {"name": "home-assistant-UNIQUEID", "description": "Home Assistant Local Span Integration"}.
    • Use some unique value for UNIQUEID. Six random alphanumeric characters would be one reasonable choice. If the name conflicts with one that's already been created the request will fail.
  2. If the panel is currently "unlocked", you will get a 2xx response containing the "accessToken". If not, then prompt the user to open and close the door of the panel three times, once every two seconds, and then retry.
  3. Store the value from the "accessToken" property of the response object. It will be a long string. This is the token which should be included with all future requests.
  4. Send all future requests with the HTTP header "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c" (this is just a dummy example token)

If you have multiple span panels, you will need to repeat this process for each panel, as tokens are only accepted by the panel that generated them.

mbbush avatar Feb 16 '23 02:02 mbbush