You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I searched existing issues and confirmed this is not a duplicate.
I replaced the example text with the real behavior, reproduction steps, expected result, and version from the app's About menu or od --version.
What happened?
Issue
When running Open Design via docker compose up -d, the browser UI loads correctly
but every API call (e.g. /api/version, /api/runs) returns 401 API_TOKEN_REQUIRED,
making the app completely unusable.
Secondary issue: docker compose build fails
scripts/postinstall.mjs includes apps/daemon in its build targets and runs
during pnpm install. At that point in the Dockerfile, only
apps/daemon/package.json has been copied — tsconfig.json and src/ are not
yet present — so tsc -p tsconfig.json fails with:
error TS5058: The specified path does not exist: 'tsconfig.json'.
Fix: Skip build targets whose tsconfig.json is absent (the Dockerfile's
explicit pnpm --filter @open-design/daemon build step after COPY apps handles
the daemon build correctly).
Environment
Docker Desktop (macOS / Windows / Linux)
docker.io/vanjayak/open-design:latest pre-built image or local build
Any browser on the Docker host
Expected behavior
The browser UI should work without manually sending a Bearer token —
same as the local dev (pnpm tools-dev) experience.
Open Design version
0.8.1
Platform
macOS (Apple Silicon)
Logs (optional)
Screenshots (optional)
Issue
Screen.Recording.2026-06-09.at.22.14.08.mov
Expected
Screen.Recording.2026-06-09.at.22.16.47.mov
Additional context
Root cause
Docker NAT. When Docker forwards 127.0.0.1:7456 (host) → container port 7456,
the daemon sees the TCP peer address as the Docker bridge gateway (e.g. 172.17.0.1),
not 127.0.0.1.
The auth middleware in apps/daemon/src/server.ts bypasses the Bearer check for
loopback peer addresses:
if (isLoopbackPeerAddress(req.socket?.remoteAddress)) return next();
isLoopbackPeerAddress('172.17.0.1') returns false, so the bypass never fires.
The web frontend never sends a Bearer token (it has always relied on this bypass),
so every API call returns 401.
Affected request headers (from browser DevTools)
host: 127.0.0.1:7456
sec-fetch-site: same-origin
// no origin header
// no authorization header
Fix
Add isLoopbackBrowserRequest() as a fallback — checks the HTTP Host and
Origin headers instead of the TCP peer address. Both headers are browser-set
and survive Docker NAT intact.
if (isLoopbackPeerAddress(req.socket?.remoteAddress) || isLoopbackBrowserRequest(req)) return next();
Security: Origin must also be loopback when present — blocks DNS-rebinding attacks
and prevents OD_ALLOWED_ORIGINS reverse-proxy deployments from accidentally
bypassing Bearer auth.
Before you submit
od --version.What happened?
Issue
When running Open Design via
docker compose up -d, the browser UI loads correctlybut every API call (e.g.
/api/version,/api/runs) returns401 API_TOKEN_REQUIRED,making the app completely unusable.
Secondary issue: docker compose build fails
scripts/postinstall.mjs includes apps/daemon in its build targets and runs
during pnpm install. At that point in the Dockerfile, only
apps/daemon/package.json has been copied — tsconfig.json and src/ are not
yet present — so tsc -p tsconfig.json fails with:
error TS5058: The specified path does not exist: 'tsconfig.json'.
Fix: Skip build targets whose tsconfig.json is absent (the Dockerfile's
explicit pnpm --filter @open-design/daemon build step after COPY apps handles
the daemon build correctly).
Environment
Docker Desktop (macOS / Windows / Linux)
docker.io/vanjayak/open-design:latest pre-built image or local build
Any browser on the Docker host
Steps to reproduce
Steps to reproduce
deploy/README.mdOD_API_TOKENindeploy/.envdocker compose up -dhttp://localhost:7456in a browserResult: Every
/api/*request returns:{ "error": { "code": "API_TOKEN_REQUIRED", "message": "Authorization: Bearer <OD_API_TOKEN> required" } }Expected behavior
Expected behavior
The browser UI should work without manually sending a Bearer token —
same as the local dev (pnpm tools-dev) experience.
Open Design version
0.8.1
Platform
macOS (Apple Silicon)
Logs (optional)
Screenshots (optional)
Issue
Screen.Recording.2026-06-09.at.22.14.08.mov
Expected
Screen.Recording.2026-06-09.at.22.16.47.mov
Additional context
Root cause
Docker NAT. When Docker forwards 127.0.0.1:7456 (host) → container port 7456,
the daemon sees the TCP peer address as the Docker bridge gateway (e.g. 172.17.0.1),
not 127.0.0.1.
The auth middleware in apps/daemon/src/server.ts bypasses the Bearer check for
loopback peer addresses:
if (isLoopbackPeerAddress(req.socket?.remoteAddress)) return next();
isLoopbackPeerAddress('172.17.0.1') returns false, so the bypass never fires.
The web frontend never sends a Bearer token (it has always relied on this bypass),
so every API call returns 401.
Affected request headers (from browser DevTools)
host: 127.0.0.1:7456
sec-fetch-site: same-origin
// no
originheader// no
authorizationheaderFix
Add isLoopbackBrowserRequest() as a fallback — checks the HTTP Host and
Origin headers instead of the TCP peer address. Both headers are browser-set
and survive Docker NAT intact.
Auth middleware bypass updated to:
Security: Origin must also be loopback when present — blocks DNS-rebinding attacks
and prevents OD_ALLOWED_ORIGINS reverse-proxy deployments from accidentally
bypassing Bearer auth.