diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 731b9cf3187ace58601e9a21cdd923fb91097ecd..f0410d1689fce55427f859e4267bfd27d271423b 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -47,19 +47,11 @@ docker:
     DEBIAN_FRONTEND: noninteractive
     BUILDAH_ISOLATION: chroot
   image:
-    name: debian:bullseye-slim
+    name: debian:bookworm-slim
     entrypoint: [""]
   before_script:
     - apt update
-    - apt install -y buildah qemu-user-static ca-certificates qemu-user-static
-    - |
-      cat << EOF > /etc/containers/storage.conf
-      [storage]
-      driver = "overlay"
-      [storage.options.overlay]
-      mount_program = "/usr/bin/fuse-overlayfs"
-      mountopt = "nodev,fsync=0"
-      EOF
+    - apt install -y buildah qemu-user-static ca-certificates binfmt-support
     - update-binfmts --enable qemu-aarch64
   script:
     - buildah login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
diff --git a/Dockerfile b/Dockerfile
index 5d8244f8990d514363c95c76abf3e32194bfec46..458b35e6772b4c6abe6e5d5e6593fe0594bba7a5 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,6 +1,6 @@
 ARG DEBIAN_FRONTEND=noninteractive
 
-FROM debian:bullseye-slim as builder
+FROM debian:bookworm-slim as builder
 ENV LC_ALL=C.UTF-8
 RUN apt-get update \
  && apt-get install -y python3 \
@@ -11,7 +11,7 @@ RUN cd /tmp/proxy && python3 setup.py install
 
 
 # Build server container
-FROM debian:bullseye-slim as server
+FROM debian:bookworm-slim as server
 LABEL maintainer Andrej Shadura <andrew.shadura@collabora.co.uk>
 ENV LC_ALL=C.UTF-8
 
diff --git a/obs_proxy/server.py b/obs_proxy/server.py
index 16c04626ad4307b8d419203a24d6c908a984165c..d77cfa29f63b994ab1362d71f774a021d1b8dc8c 100755
--- a/obs_proxy/server.py
+++ b/obs_proxy/server.py
@@ -91,25 +91,23 @@ def require_auth(f):
             http_port=port,
         )
         if port == config.server.port:
-            auth_header = ctx.headers.get("Authorization")
-            if not auth_header or not (
-                auth_header.startswith("Basic") or auth_header.startswith("Bearer")
-            ):
+            if not ctx.authorization:
                 return 'auth required', 401, {'WWW-Authenticate': 'Basic'}
 
-            # Quart parses Basic auth for us
-            if ctx.authorization:
+            # Quart parses auth for us
+            if ctx.authorization.type == "basic":
                 if (
                     ctx.authorization["username"] != config.auth.username
                     or ctx.authorization["password"] != config.auth.password
                 ):
                     logger.debug(f"{ctx.authorization = }, {config.auth = }")
                     abort(403)
-            else:
-                _, token = auth_header.split(' ', maxsplit=1)
-                if token != config.auth.token:
-                    logger.debug(f"{auth_header = }, {config.auth = }")
+            elif ctx.authorization.type == "bearer":
+                if ctx.authorization.token != config.auth.token:
+                    logger.debug(f"{ctx.authorization = }, {config.auth = }")
                     abort(403)
+            else:
+                abort(403)
 
         return await f(*args, **kwargs)
 
diff --git a/obs_proxy/utils.py b/obs_proxy/utils.py
index cf09f28d4f5a67c6a506bfbb3335988c4fe61f28..9c75393709c83c9e9046ed410b6a07395c043612 100644
--- a/obs_proxy/utils.py
+++ b/obs_proxy/utils.py
@@ -114,6 +114,8 @@ def configure_logging():
     # Too verbose for us
     ws_logger = logging.getLogger("websockets.client")
     ws_logger.setLevel(logging.INFO)
+    httpcore_logger = logging.getLogger("httpcore")
+    httpcore_logger.setLevel(logging.INFO)
 
     http_logger = logging.getLogger("http.server")
     http_logger.addHandler(handler)
diff --git a/setup.cfg b/setup.cfg
index 2e4e7d529fcf60484407ed3989f206988a3a8651..60fe92b5ccd40c761969c7fd5ba5449979423f05 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -27,6 +27,7 @@ install_requires =
     httpx ~= 0.22
     json-rpc ~= 1.12
     Quart ~= 0.18
+    Werkzeug ~= 2.3
     websockets ~= 10.0
     xmltodict ~= 0.13
     aiofiles ~= 0.8
diff --git a/tests/test_auth.py b/tests/test_auth.py
new file mode 100644
index 0000000000000000000000000000000000000000..9bcc9893a596b657eb06eb81745ff16d4c9299df
--- /dev/null
+++ b/tests/test_auth.py
@@ -0,0 +1,81 @@
+import logging
+from http import HTTPStatus
+from typing import Generator
+
+import pytest
+from pytest import LogCaptureFixture  # noqa: PT013
+from quart import Quart
+
+from obs_proxy.config import config
+from obs_proxy.server import require_auth
+
+
+@pytest.fixture
+def app(caplog: LogCaptureFixture, tmp_path) -> Generator[Quart, None, None]:
+    caplog.set_level(logging.DEBUG)
+    app = Quart(__name__)
+
+    @app.route('/ping')
+    @require_auth
+    async def ping():
+        return "ok"
+
+    return app
+
+
+@pytest.fixture
+def test_app(app: Quart) -> Generator[Quart, None, None]:
+    return app.test_app()
+
+
+@pytest.mark.asyncio
+async def test_userpass(test_app: Quart):
+    config.auth.username = "foobar"
+    config.auth.password = "barfoo"
+    client = test_app.test_client()
+
+    response = await client.get(
+        '/ping',
+        scope_base={
+            "server": ("127.0.0.1", config.server.port),
+        },
+    )
+
+    assert response.status_code == HTTPStatus.UNAUTHORIZED
+
+    response = await client.get(
+        '/ping',
+        auth=(config.auth.username, config.auth.password),
+        scope_base={
+            "server": ("127.0.0.1", config.server.port),
+        },
+    )
+
+    assert response.status_code == HTTPStatus.OK
+
+
+@pytest.mark.asyncio
+async def test_token(test_app: Quart):
+    config.auth.token = "barfoobarbaz"
+    client = test_app.test_client()
+
+    response = await client.get(
+        '/ping',
+        scope_base={
+            "server": ("127.0.0.1", config.server.port),
+        },
+    )
+
+    assert response.status_code == HTTPStatus.UNAUTHORIZED
+
+    response = await client.get(
+        '/ping',
+        headers={
+            "Authorization": f"Bearer {config.auth.token}",
+        },
+        scope_base={
+            "server": ("127.0.0.1", config.server.port),
+        },
+    )
+
+    assert response.status_code == HTTPStatus.OK