Suggestion: an "Integration tokens" screen for third-party clients

Hi Ben,

I love SecuritySpy. I run it with 11 cameras of my own. I've been building a standalone async Python library for it, aiosecurityspy (pip install aiosecurityspy), which will eventually power a Home Assistant integration. That integration is still in active development and not ready for use yet, but the library is published and meant to be reusable by any Python project. I'd like to run an idea past you before assuming anything.

What works well today. The URL Generator's authentication tokens are excellent. A token for live video on one camera opens exactly that and nothing else, and it never exposes the account password. That's the right security model for anything that hands a stream URL to ffmpeg, go2rtc, VLC, or similar tools, which tend to print URLs in their logs.

Where integrations run into trouble. Each token covers one camera and one resource, and the only way to create one is the URL Generator window on the Mac. With my own 11 cameras, that means opening the window and pasting 11 URLs, then doing it again whenever the account changes. Asking every user of an integration to do that doesn't scale, so in practice integrations fall back to putting base64 username:password in auth=, which exposes the whole account wherever that URL ends up.

The suggestion. An Integration tokens screen, perhaps under web server or account settings, where an admin could:

  • Create a named token (e.g. "Home Assistant") tied to a specific account
  • Choose which cameras it covers: all, or a selection
  • Choose which resources it grants: live RTSP, snapshots, HLS/MJPEG, event stream, captures
  • See when each token was created and last used, and revoke it independently of the account password

A token created this way could replace the account credentials in a client's configuration entirely. It would be least-privilege by design, and revoking one integration wouldn't break the others.

Optionally, an authenticated endpoint that issues such a token (an admin-only equivalent of the URL Generator) would let integrations set this up automatically. The screen alone would already solve most of it.

This is not blocking me. In the meantime, aiosecurityspy is getting a local RTSP relay: the client connects to a local address, and the library adds credentials only on its own connection to SecuritySpy, so the password never appears in a URL any external tool sees. It works, but a first-class token in SecuritySpy would be cleaner for every integration, including Homebridge, Scrypted, and others. If you do add token support, the library would adopt it right away.

Is this something you'd consider worth building? Happy to share details on how the library uses the API if that's useful.

Thanks for SecuritySpy, and for the URL Generator tokens in the first place!

Comments

  • It's great to learn about your Python library! We love it when users build applications on top of SecuritySpy, and I'm sure that many others will be interested in the kind of integration with Home Assistant that this will unlock.

    Your request for token-based authentication is a good idea, so we've now added this in the latest beta version of SecuritySpy (currently 6.22b9). Here's how it works:

    • Under Settings > Web, edit or add an account.
    • You will see a new "API Key" section; click the disclosure triangle to reveal it.
    • Press the refresh button to create a unique key that is associated with the account.
    • Embed this key in URLs in the usual way ("...&auth=API_abcdefg")

    In terms of the security of these tokens:

    • Compared with username:password in the URL: much better. No username/password leak risk; tokens can never open the web interface, log in, manage accounts, or run commands on or control the Mac.
    • Compared with existing resource-specific tokens: while the new API tokens don't vary per URL, they are much less hackable because they are random strings rather than hashes (which can be brute-forced by a determined attacker with enough compute and patience).

    Currently the date of creation or last use is not recorded or displayed (could be something to add later, but more of a nice-to-have).

    Please provide your feedback when you've had a chance to test this new functionality.

  • Hi Ben, thanks for turning this around so quickly! I've been testing 6.22b10 and it's working well. Using the key as the password (HTTP Basic auth) works on ++systemInfo, ++image, ++eventStream and RTSP, and the username doesn't matter. The key follows the account's permissions, and the web interface correctly refuses it.

    My integration currently runs live video through a small local RTSP relay, so no username or password ever appears in a stream URL, a log or Home Assistant's config. With keys, I can either have the relay sign in with a key instead of the account password, or possibly drop the relay for servers that support keys, since a leaked key is far less dangerous than a password. Older SecuritySpy versions will keep using the relay with username and password.

    A few things I noticed:

    1. auth=<key> in the URL. Passing the key directly as &auth=API_... returns 401 for me on both HTTP and RTSP. Base64-encoding it like a password (auth=base64(username:key), or with an empty username) works. Is the raw form meant to work, or should the help text mention the encoding?
    2. Password identical to the key. As an edge-case test, I set an account's password to the exact same string as its key. SecuritySpy then treated it as a key: any username worked and the web interface returned 403, so that user can't log in to the web UI with their own password. Unlikely in practice, but it may be worth preventing a password that matches the key, or starts with API_.
    3. Key format. Every key I've generated is API_ followed by 32 letters and digits. Can I rely on the API_ prefix as a stable format? I'd like to use it to tell a key from a password and to make sure keys are always redacted from logs and diagnostics. I'd also like to know whether the length might change.

    Thanks again, this is a great addition.

  • Did some more negative testing of the feature — found an edge case worth flagging.

    Finding: an account whose password (not an API Key) happens to start with API_ gets silently locked out of the API/RTSP surface, even when the account has no API Key configured at all.

    Repro:

    1. Create or edit an account in Settings > Web.
    2. Set its password to something starting with API_ but not matching a real key's shape (e.g. API_test123, or any value that isn't exactly API_ + 32 alphanumeric characters).
    3. Make sure the account has no API Key generated.
    4. Log into the web UI with that username/password — works fine.
    5. Send an HTTP request to an API endpoint (e.g. ++systemInfo) using Authorization: Basic with that same username/password — refused with 401.

    So the same credential works at the web login but not on the API surface. It looks like the API/RTSP auth path treats any password starting with API_ as an attempted key lookup and rejects it outright when there's no matching key, rather than falling back to checking it as an ordinary password. The web login form doesn't seem to apply that same check.

    This is a fairly nasty trap for anyone whose password generator (or habit) happens to produce something starting with API_ — their web login keeps working, so there's no obvious signal that the API access is broken, and it's indistinguishable from a wrong password from a client's point of view.

    Not urgent, but wanted to document it in case it's not already known — happy to share more detail on the exact requests/responses if useful.

  • Thanks for the excellent feedback!

    • The auth parameter parsing had a bug whereby it wasn't correctly accepting the naked "API_xyz" token - this has now been fixed.
    • You're right that the ability to create a regular web password with the "API_" prefix was a trap; this is now disallowed.
    • Yes, the "API_" prefix for the API keys is fixed and can be relied upon.

    We've posed a new beta (6.22b11) with the fixes, so please continue your testing with this one, and let me know if you see any further issues.

  • Are the integration tokens for accessing HA data or something else?

    Is the goal to offer similar integration between Sec Spy and HA that existed prior?

    When completed will this integration be third party, part of Sec Spy or part of HA (they like it and want to run with it)?


    Apparently HA has become a serious platform, they reported to have grown to 50+ employed programmers. Thanks much for the post, I'm in the process of redoing my hodgepodge systems, gonna give HA a try first, be nice if its works with Sec Spy which I'm seriously considering.

  • Hi @SecuritySpyM6, SecuritySpy already has basic integration with Home Assistant via our bridge app HomeHelper. This allows one system to trigger the other when events happen.

    But what I think what is being aimed for here is more direct and rich interoperability, whereby you would add a "SecuritySpy" integration to Home Assistant, give it the SecuritySpy server IP and API token, and then you would get a bunch of various entities in Home Assistant that provide viewing and control of SecuritySpy. @jensenchappell please correct me and/or provide more details about what you are building, as I would be very interested to learn more!

    (something like this did exist previous with the briis plugin, but this project is now defunct unfortunately).

  • Thanks Ben, HA has a lot of momentum, I saw a nice YouTube interview by NASCompares on its expanding usage, but its not something thats gonna record 24/7 or process in detail video. But is surely can work OFFICIALLY with such things.

  • Ben
    Ben
    edited September 20

    @SecuritySpyM6 if you're currently choosing between different home automation platforms, I would highly recommend Home Assistant, it's great. I personally use it in my house - it manages everything - locks / lights / HVAC / hot water and more. Very wide device support - Zigbee, Matter, HomeKit, and various IP-based integrations. I bridge a core set of accessories back to HomeKit to provide remote access, Siri voice control, and guest sharing from the Home app. It's best to run HA on dedicated hardware (e.g. Home Assistant Green).

  • Thanks Ben, Yes gonna try HA out and hoping it's 3/4 as good as what is reported by YouTube and AI queries. Apparently it has the ability to do ALPR and facial recognition with RTSP feeds which I'm not sure how it does that locally but once I get comfortable with the smart home stuff I'll give a try.