Basicauth requiring authentication multiple times with Frigate NVR service?

I'm running Traefik in a docker container on my mini home server along with several other services. I only access these services through my local network (they are not exposed to the internet). I have basicauth setup for the Traefik dashboard and Frigate, an open source NVR solution. I've posted about this issue on the Frigate GitHub but haven't been able to find a solution, so I figured I'd ask here since I think it's either a limitation with Traefik basicauth or a configuration issue.

With the Traefik dashboard, basicauth works as expected. The first time I try to access the dashboard, it asks me to authenticate and I can navigate to different pages without ever being asked to authenticate.

With Frigate, it asks me to authenticate twice when I access the main page, and anytime I try to access a separate camera page, it asks me to authenticate again. Additionally, if I'm on a page with a camera feed and select a different browser tab for a few minutes then come back to the Frigate camera feed page, it will ask me to authenticate again. Looking at the Web Inspector view using Safari, it appears every time Frigate is trying to establish a new websocket connection, that's what's causing the re-authentication. There are folks running Authelia in front of Frigate without this issue, so I'm wondering if maybe it's just a limitation of Traefik basicauth or something I need to change in my configuration.

Commands and labels for my Traefik container using docker compose:

    command:
      - "--api.dashboard=true"
      - "--accesslog=false"
      - "--providers.file.filename=/services.yml"
      - "--providers.docker"
      - "--providers.docker.exposedbydefault=false"
      - "--serversTransport.insecureSkipVerify=true"
      - "--certificatesresolvers.cloudflare.acme.dnschallenge"
      - "--certificatesresolvers.cloudflare.acme.dnschallenge.provider=cloudflare"
      - "--certificatesresolvers.cloudflare.acme.dnschallenge.resolvers=1.1.1.1:53,8.8.8.8:53"
      - "--certificatesresolvers.cloudflare.acme.email=user@email.com"
      - "--certificatesresolvers.cloudflare.acme.storage=/acme.json"
      - "--entryPoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
      - "--entrypoints.web.http.redirections.entryPoint.to=websecure"
      - "--entrypoints.web.http.redirections.entryPoint.scheme=https"
      - "--entrypoints.web.http.redirections.entrypoint.permanent=true"
      - "--entrypoints.websecure.http.tls.domains[0].main=mydomain.com"
      - "--entrypoints.websecure.http.tls.domains[0].sans=*.mydomain.com"
      - "--entrypoints.websecure.http.tls.certresolver=cloudflare"
    labels:
      - "traefik.enable=true"
      - "traefik.http.middlewares.traefik-auth.basicauth.users=username:password"
      - "traefik.http.routers.traefik.rule=Host(`traefik.mydomain.com`)"
      - "traefik.http.routers.traefik.service=api@internal"
      - "traefik.http.routers.traefik.entrypoints=websecure"
      - "traefik.http.routers.traefik.middlewares=traefik-auth"
      - "traefik.http.services.traefik.loadbalancer.server.port=8080"

Labels for the Frigate container:

    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.frigate.rule=Host(`frigate.mydomain.com`)"
      - "traefik.http.routers.frigate.entrypoints=websecure"
      - "traefik.http.routers.frigate.tls.certresolver=cloudflare"
      - "traefik.http.routers.frigate.middlewares=traefik-auth"
      - "traefik.http.services.frigate.loadbalancer.server.port=5000"

I have tried setting the realm and headerField per the Traefik basicauth docs, but still no change in behavior.

Any tips or advice would be greatly appreciated! I've been trying to figure this out for a while and not sure if I'm just wasting my time trying to chase down something that isn't even possible, or if there is a solution out there besides spinning up an instance of Authelia.

Can you check in browser developer tools network tab what URLs are requested, that lead to auth requests?

Using the Network tab with Web Inspector, the first "ws" connection I see has this info:

URL: wss://frigate.mydomain.com/ws
Status: 101 Switching Protocols
Source: —

Request
Cache-Control: no-cache
Connection: Upgrade
Origin: https://frigate.mydomain.com
Pragma: no-cache
Sec-Fetch-Dest: websocket
Sec-Fetch-Mode: websocket
Sec-Fetch-Site: same-origin
Sec-WebSocket-Extensions: permessage-deflate
Sec-WebSocket-Key: redacted
Sec-WebSocket-Version: 13
Upgrade: websocket
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4.1 Safari/605.1.15

Response
Connection: upgrade
Date: Tue, 16 Apr 2024 17:23:00 GMT
Sec-WebSocket-Accept: GBu8f8AarEmQna7/at6CLcrLdoo=
Sec-WebSocket-Version: 13
Server: nginx/1.25.3
Upgrade: websocket

When I access a camera page that asks me to reauthenticate, this is what I see in the second "ws" connection:

URL: wss://frigate.mydomain.com/live/webrtc/api/ws?src=front
Status: 101 Switching Protocols
Source: —

Request
Cache-Control: no-cache
Connection: Upgrade
Origin: https://frigate.mydomain.com
Pragma: no-cache
Sec-Fetch-Dest: websocket
Sec-Fetch-Mode: websocket
Sec-Fetch-Site: same-origin
Sec-WebSocket-Extensions: permessage-deflate
Sec-WebSocket-Key: redacted
Sec-WebSocket-Version: 13
Upgrade: websocket
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4.1 Safari/605.1.15

Response
Connection: upgrade
Date: Tue, 16 Apr 2024 17:23:11 GMT
Sec-WebSocket-Accept: redacted
Server: nginx/1.25.3
Upgrade: websocket

Query String Parameters
src: front

Not sure if this matters but the cameras Frigate is using are on a separate VLAN, and Frigate uses go2rtc streams using RTSP. Basically in my Frigate configuration, it has go2rtc setup to access the camera streams using the direct camera URL. Example: rtsp://camer_username:camera_password@192.168.20.1:554/cam/realmonitor?channel=1&subtype=0

For basicauth, you will see an initial status code 401 for the first request, telling the browser to open the auth dialog. Then another request with the auth data included will happen.

The browser is usually storing the auth data for the session, re-supplying it to every request in the headers.

This is probably just for the same domain and for the first path and beneath. If you change domain or use IP or go outside of the original path, you might be asked again. But that’s just my theory.