diff --git a/.env.example b/.env.example index 7a288f1..454f267 100644 --- a/.env.example +++ b/.env.example @@ -35,7 +35,6 @@ PROVIDER_BASE_URL_ALLOWLIST=[] PUBLIC_BASE_URL=http://localhost:8000 CORS_ORIGINS=["http://localhost:5173","http://localhost:3000"] -CORS_ALLOW_CREDENTIALS=false VITE_API_BASE= # Production baseline overrides (set explicitly for live deployments): @@ -49,5 +48,4 @@ VITE_API_BASE= # PROVIDER_BASE_URL_ALLOWLIST=["api.openai.com"] # PUBLIC_BASE_URL=https://api.example.com # CORS_ORIGINS=["https://app.example.com"] -# CORS_ALLOW_CREDENTIALS=false # VITE_API_BASE=https://api.example.com/api/v1 diff --git a/README.md b/README.md index b93861e..6382321 100644 --- a/README.md +++ b/README.md @@ -121,7 +121,7 @@ cd frontend && npm run preview Main runtime variables are defined in `docker-compose.yml`: -- API and worker: `DATABASE_URL`, `REDIS_URL`, `REDIS_SECURITY_MODE`, `REDIS_TLS_MODE`, `STORAGE_ROOT`, `PUBLIC_BASE_URL`, `CORS_ORIGINS`, `CORS_ALLOW_CREDENTIALS`, `AUTH_BOOTSTRAP_*`, `PROCESSING_LOG_STORE_*`, `CONTENT_EXPORT_*`, `TYPESENSE_*`, `APP_SETTINGS_ENCRYPTION_KEY` +- API and worker: `DATABASE_URL`, `REDIS_URL`, `REDIS_SECURITY_MODE`, `REDIS_TLS_MODE`, `STORAGE_ROOT`, `PUBLIC_BASE_URL`, `CORS_ORIGINS`, `AUTH_BOOTSTRAP_*`, `PROCESSING_LOG_STORE_*`, `CONTENT_EXPORT_*`, `TYPESENSE_*`, `APP_SETTINGS_ENCRYPTION_KEY` - Frontend: optional `VITE_API_BASE` When `VITE_API_BASE` is unset, the frontend uses `http://:8000/api/v1`. diff --git a/backend/.env.example b/backend/.env.example index 1ede9c1..52a7358 100644 --- a/backend/.env.example +++ b/backend/.env.example @@ -37,4 +37,3 @@ TYPESENSE_PORT=8108 TYPESENSE_API_KEY=replace-with-random-typesense-api-key TYPESENSE_COLLECTION_NAME=documents PUBLIC_BASE_URL=http://localhost:8000 -CORS_ALLOW_CREDENTIALS=false diff --git a/backend/app/core/config.py b/backend/app/core/config.py index f4d9ed0..b4368eb 100644 --- a/backend/app/core/config.py +++ b/backend/app/core/config.py @@ -72,7 +72,6 @@ class Settings(BaseSettings): typesense_num_retries: int = 0 public_base_url: str = "http://localhost:8000" cors_origins: list[str] = Field(default_factory=lambda: ["http://localhost:5173", "http://localhost:3000"]) - cors_allow_credentials: bool = False LOCAL_HOSTNAME_SUFFIXES = (".local", ".internal", ".home.arpa") diff --git a/backend/app/main.py b/backend/app/main.py index 4e6ab2b..27ad4e0 100644 --- a/backend/app/main.py +++ b/backend/app/main.py @@ -39,7 +39,7 @@ def create_app() -> FastAPI: app.add_middleware( CORSMiddleware, allow_origins=allowed_origins, - allow_credentials=bool(getattr(settings, "cors_allow_credentials", False)), + allow_credentials=False, allow_methods=["*"], allow_headers=["*"], ) diff --git a/doc/operations-and-configuration.md b/doc/operations-and-configuration.md index 5232f85..c3dca1b 100644 --- a/doc/operations-and-configuration.md +++ b/doc/operations-and-configuration.md @@ -64,7 +64,6 @@ Use `.env.example` as baseline. The table below documents user-managed settings | `PUBLIC_BASE_URL` | `http://localhost:8000` | `https://api.example.com` | | `VITE_API_BASE` | empty for host-derived `http://:8000/api/v1`, or explicit local URL | `https://api.example.com/api/v1` | | `CORS_ORIGINS` | `["http://localhost:5173","http://localhost:3000"]` | exact frontend origins only, for example `["https://app.example.com"]` | -| `CORS_ALLOW_CREDENTIALS` | `false` | `false` (Authorization header flow does not need credentialed CORS) | | `REDIS_URL` | `redis://:@redis:6379/0` in isolated local network | `rediss://:@redis.internal:6379/0` | | `REDIS_SECURITY_MODE` | `compat` or `auto` | `strict` | | `REDIS_TLS_MODE` | `allow_insecure` or `auto` | `required` | @@ -77,6 +76,8 @@ Use `.env.example` as baseline. The table below documents user-managed settings | `CONTENT_EXPORT_MAX_TOTAL_BYTES` | default `52428800` (50 MiB) or lower | tuned to production capacity | | `CONTENT_EXPORT_RATE_LIMIT_PER_MINUTE` | default `6` | tuned to API throughput and abuse model | +`PUBLIC_BASE_URL` must point to the backend API public URL, not the frontend URL. + ## HTTPS Proxy Deployment Notes This application supports both: @@ -88,7 +89,7 @@ Recommended LIVE pattern: 2. Keep container published ports bound to localhost or internal network. 3. Set `PUBLIC_BASE_URL` and `VITE_API_BASE` to final HTTPS URLs. 4. Set `CORS_ORIGINS` to exact HTTPS frontend origins. -5. Keep `CORS_ALLOW_CREDENTIALS=false` for bearer header flow. +5. Credentialed CORS is intentionally disabled in application code for bearer-header auth. ## Security Controls diff --git a/docker-compose.yml b/docker-compose.yml index f3f4b9c..5519f18 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -51,7 +51,6 @@ services: PROVIDER_BASE_URL_ALLOWLIST: '${PROVIDER_BASE_URL_ALLOWLIST:-[]}' PROVIDER_BASE_URL_ALLOW_HTTP: ${PROVIDER_BASE_URL_ALLOW_HTTP:-true} PROVIDER_BASE_URL_ALLOW_PRIVATE_NETWORK: ${PROVIDER_BASE_URL_ALLOW_PRIVATE_NETWORK:-true} - CORS_ALLOW_CREDENTIALS: ${CORS_ALLOW_CREDENTIALS:-false} PROCESSING_LOG_STORE_MODEL_IO_TEXT: ${PROCESSING_LOG_STORE_MODEL_IO_TEXT:-false} PROCESSING_LOG_STORE_PAYLOAD_TEXT: ${PROCESSING_LOG_STORE_PAYLOAD_TEXT:-false} CONTENT_EXPORT_MAX_DOCUMENTS: ${CONTENT_EXPORT_MAX_DOCUMENTS:-250}