Files
semantica/docker-compose.dev.yml
Mohd KaifandZohaib Hassnain 3496d62335 security: require API-key auth on all Explorer API routes (GHSA-j4mq) (#909)
* security: require API-key auth on all Explorer API routes (GHSA-j4mq-hprp-987v)

Every Explorer route (bulk import/export, delete, LLM-backed ontology
generation, SPARQL, etc.) was mounted with no authentication, and both
server entrypoints bind 0.0.0.0 by default. Anyone reaching the port got
full read/write/delete on the graph.

- Add require_auth dependency (explorer/dependencies.py): checks
  X-API-Key against SEMANTICA_API_KEY, fails closed with 503 if
  unconfigured (not silently anonymous), 401 on wrong/missing key.
  SEMANTICA_ALLOW_ANONYMOUS=true opts out explicitly for local dev.
- Wire dependencies=[Depends(require_auth)] into all 11 API routers in
  both explorer/app.py and server.py. /health, /api/info, static assets,
  and the SPA catch-all stay public.
- /ws/graph-updates handshake now checks the same key via header or
  ?api_key= query param (browsers can't set custom WS headers) before
  accepting the connection.
- Default bind changed from 0.0.0.0 to 127.0.0.1 in server.py's main()
  and cli.py's `server start`; the CLI warns if a non-loopback host is
  passed explicitly without a key configured.
- Startup logging reports the resolved auth mode in both app factories.
- Document/generate SEMANTICA_API_KEY in the deploy recipes that expose
  a public endpoint by default: docker-compose, Railway, Fly, Render.

Added tests/explorer/test_explorer_auth.py covering fail-closed default,
wrong/missing/correct key, anonymous opt-in, public-route exemptions, and
the WS handshake. Added tests/explorer/conftest.py defaulting the
pre-existing ~200 explorer tests to SEMANTICA_ALLOW_ANONYMOUS=true so
they keep exercising route logic without needing a key.

* fix CORS

---------

Co-authored-by: Zohaib Hassnain <109234410+ZohaibHassan16@users.noreply.github.com>
2026-08-11 14:05:00 +05:00

49 lines
1.2 KiB
YAML

services:
explorer:
command:
- python
- -m
- uvicorn
- semantica.explorer.app:app
- --host
- 0.0.0.0
- --port
- "8000"
- --reload
- --reload-dir
- /app/semantica
environment:
ALLOWED_ORIGINS: http://localhost:5173,http://127.0.0.1:5173,http://localhost:8000,http://127.0.0.1:8000
FALKORDB_HOST: falkordb
FALKORDB_PORT: "6379"
# Local dev only: this compose file is not for public exposure.
SEMANTICA_ALLOW_ANONYMOUS: "true"
volumes:
- ./semantica:/app/semantica
- ./pyproject.toml:/app/pyproject.toml:ro
frontend:
image: node:22-alpine
working_dir: /app/explorer
command: sh -c "npm ci && npm run dev -- --host 0.0.0.0"
environment:
VITE_EXPLORER_API_TARGET: http://explorer:8000
VITE_EXPLORER_WS_TARGET: ws://explorer:8000
ports:
- "5173:5173"
volumes:
- ./explorer:/app/explorer
- explorer_node_modules:/app/explorer/node_modules
depends_on:
explorer:
condition: service_started
networks:
- semantica
networks:
semantica:
driver: bridge
volumes:
explorer_node_modules: