Skip to content

security: require auth token and restrict CORS on viewer API - #26

Merged
rdasilveiracabral merged 1 commit into
mainfrom
security/viewer-api-authorization-and-cors
Jul 27, 2026
Merged

security: require auth token and restrict CORS on viewer API#26
rdasilveiracabral merged 1 commit into
mainfrom
security/viewer-api-authorization-and-cors

Conversation

@rdasilveiracabral

Copy link
Copy Markdown
Collaborator

The viewer exposed trace, evaluation, memory, annotation, explorer, OTLP and journal APIs with no authorization while listening on all interfaces, and its CORS policy allowed every origin, method and header.

Add a _require_viewer_authorization dependency on every API router and every /v1 ingest/sync endpoint. When NOOA_VIEWER_AUTH_TOKEN is set, requests must send Authorization: Bearer <token>, compared with hmac.compare_digest(). When it is unset, loopback clients keep working so existing local development and ingest clients are unaffected, while non-loopback clients get a 403.

Restrict CORS to http://localhost:5001 and http://127.0.0.1:5001 by default, overridable via a comma-separated NOOA_VIEWER_CORS_ORIGINS, and narrow allowed methods and headers to the ones the viewer APIs use.

What does this PR do?

Related issues

Checklist

  • Code follows the project style (uv run ruff check . and uv run ruff format --check . pass)
  • Tests added/updated and passing (uv run pytest)
  • Docs updated if behavior or public APIs changed
  • New source files carry an SPDX license header

The viewer exposed trace, evaluation, memory, annotation, explorer, OTLP
and journal APIs with no authorization while listening on all interfaces,
and its CORS policy allowed every origin, method and header.

Add a `_require_viewer_authorization` dependency on every API router and
every `/v1` ingest/sync endpoint. When `NOOA_VIEWER_AUTH_TOKEN` is set,
requests must send `Authorization: Bearer <token>`, compared with
`hmac.compare_digest()`. When it is unset, loopback clients keep working
so existing local development and ingest clients are unaffected, while
non-loopback clients get a 403.

Restrict CORS to `http://localhost:5001` and `http://127.0.0.1:5001` by
default, overridable via a comma-separated `NOOA_VIEWER_CORS_ORIGINS`,
and narrow allowed methods and headers to the ones the viewer APIs use.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@rdasilveiracabral
rdasilveiracabral force-pushed the security/viewer-api-authorization-and-cors branch from 2d7cc0d to ba42b28 Compare July 27, 2026 09:03
@rdasilveiracabral

Copy link
Copy Markdown
Collaborator Author

Security issue

The viewer exposed trace, evaluation, memory, annotation, playground, OTLP, and journal APIs without an authorization check while listening on all interfaces. Its CORS policy allowed every origin, method, and header. A network client or malicious browser origin could read stored agent information or invoke state-changing routes.

@rdasilveiracabral

Copy link
Copy Markdown
Collaborator Author

Patch

Set NOOA_VIEWER_AUTH_TOKEN to enable authorization on every API router and every /v1 ingest/synchronization endpoint. Protected requests must send:

Authorization: Bearer <NOOA_VIEWER_AUTH_TOKEN>

The token is read at request time and compared with hmac.compare_digest(). Frontend assets and the SPA shell remain accessible without the API token. Leaving the variable unset preserves existing loopback development and ingest clients, but protected endpoints reject non-loopback clients. Network-exposed deployments must configure the token.

CORS now allows only http://localhost:5001 and http://127.0.0.1:5001 by default, with explicit override through a comma-separated NOOA_VIEWER_CORS_ORIGINS value. Allowed methods and headers are limited to the ones the viewer APIs use.

@rdasilveiracabral
rdasilveiracabral merged commit bf3f557 into main Jul 27, 2026
@alessiodevoto
alessiodevoto deleted the security/viewer-api-authorization-and-cors branch August 3, 2026 06:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant