toga-ai 1.0.820 → 1.0.822

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,7 +6,7 @@ project: API
6
6
  client: shared
7
7
  type: architecture
8
8
  status: active
9
- updated: 2026-09-01
9
+ updated: 2026-09-16
10
10
  owners: [jcardinal, bala, mhammontree, dfranks]
11
11
  files:
12
12
  - api2/Controller/Index.php
@@ -63,7 +63,22 @@ lands in `api()`.
63
63
  ## Front controller — `Controller/Index.php`
64
64
 
65
65
  `api()` is the protocol router and the **transaction/logging boundary**:
66
- - **CORS:** permissive `Access-Control-Allow-*`; returns 200 for `OPTIONS` preflight.
66
+ - **CORS (2026-09-16):** **reflects the caller's `Origin` header** back in
67
+ `Access-Control-Allow-Origin` when `$_SERVER['HTTP_ORIGIN']` is present and matches a strict
68
+ shape regex `^https?://[A-Za-z0-9.\-]+(:\d+)?$` (with the `D` end-anchor flag); otherwise it
69
+ falls back to `*`. It also emits `Vary: Origin`. This block sits **before** the `OPTIONS`
70
+ preflight short-circuit (still 200 for `OPTIONS`). The reflected value must be the **whole
71
+ origin — `scheme://host[:port]` (e.g. `http://compass.togacommerce`)** — because the browser
72
+ compares it byte-for-byte; do **not** strip the scheme or "clean" `HTTP_ORIGIN` (it is an
73
+ origin, not a URL with a path). Why: some higher-security client networks strip or reject a
74
+ wildcard `*`, so a client's app fails with a CORS "no Access-Control-Allow-Origin" error
75
+ **inside** their network while working fine outside it. **Security:** reflecting any
76
+ well-formed origin is effectively equivalent to `*` here because auth is **Bearer-token, never
77
+ cookies** — no new exposure; the regex is a strict allowlist that blocks header injection, and
78
+ PHP `header()` also rejects CR/LF. **`Access-Control-Allow-Credentials` is deliberately NOT set
79
+ — do NOT add it on top of this reflection without a cookie-auth security review; that
80
+ combination would be a cross-site data-theft hole.** `Vary: Origin` stops a shared cache
81
+ serving one origin's header to another.
67
82
  - **`/health`:** 200 + empty object (EB/LB probe — keep it working).
68
83
  - **Sentry:** initialized per request; EC2 instance metadata attached.
69
84
  - **Core DB bootstrap (now guarded, 2026-07-23):** registers `Core` (`DB_CORE`), preferring a
@@ -390,9 +405,15 @@ they are the known sharp edges. Do not re-discover these from scratch.
390
405
  `Core.Database` row (`id = CORE_LOGS_DATABASE_ID`); a local Logs DB whose actual schema name
391
406
  differs throws `Unknown database`. This is environment config, not a code bug — fix the row or
392
407
  the local schema name, don't patch the bootstrap.
393
- 5. **CORS is fully permissive.** `Access-Control-Allow-*` is wide open on every route. Acceptable
394
- only because auth is bearer-token (not cookie) based — if any cookie/session-backed auth is ever
395
- added here, this becomes an exploitable hole and must be tightened first.
408
+ 5. **CORS reflects the caller's `Origin`, falling back to `*` (updated 2026-09-16).** The front
409
+ controller now echoes the request `Origin` into `Access-Control-Allow-Origin` when it matches a
410
+ strict shape regex, else falls back to `*`, and adds `Vary: Origin` (was a wide-open
411
+ `Access-Control-Allow-*`). Safe **only** because auth is Bearer-token, never cookie/session —
412
+ `Access-Control-Allow-Credentials` is intentionally **unset**, and reflecting the origin is
413
+ effectively equivalent to `*` here (no new exposure). It is a shape check, **not** a trusted-
414
+ origin allowlist — every well-formed Origin is reflected. If any cookie/session-backed auth is
415
+ ever added here, do not set credentials and re-tighten CORS to a real hardcoded allowlist first;
416
+ origin-reflection + credentials would be a cross-site data-theft hole.
396
417
  6. **`_underscore` is cloned at build from a moving branch** (`_<ENVIRONMENT>`), not pinned to a
397
418
  commit. Two deploys of the same api2 commit can produce different runtime behavior. Check the
398
419
  framework branch state when triaging an "it worked yesterday" regression.
@@ -446,6 +467,18 @@ they are the known sharp edges. Do not re-discover these from scratch.
446
467
  single-caller branches in `V2.php` as unverified until exercised directly.
447
468
 
448
469
  ## Change history
470
+ - 2026-09-16 — **CORS now reflects the caller's `Origin`** instead of a wide-open
471
+ `Access-Control-Allow-*`: the front controller (`Controller/Index.php`, `_Controller_Index::api()`,
472
+ before the `OPTIONS` short-circuit) echoes the request `Origin` into `Access-Control-Allow-Origin`
473
+ when `HTTP_ORIGIN` matches `^https?://[A-Za-z0-9.\-]+(:\d+)?$` (`D` flag), else falls back to `*`,
474
+ and adds `Vary: Origin` (whole origin incl. scheme — browser compares byte-for-byte). Motivation:
475
+ some higher-security client networks strip/reject a wildcard `*`, so a client failed with a CORS
476
+ "no Access-Control-Allow-Origin" error inside their network while it worked outside. Retires Known
477
+ issue #5. `Access-Control-Allow-Credentials` deliberately **NOT** set (auth is Bearer-token, never
478
+ cookies — reflection is equivalent to `*` here with no new exposure; adding credentials on top
479
+ would be a cross-site data-theft hole and needs a cookie-auth review). Reviewed clean by
480
+ php-reviewer (valid PHP 8.2) and cso (SAFE TO SHIP). Note: the code change is a working-tree edit,
481
+ not yet committed. (jcardinal)
449
482
  - 2026-09-01 — Recorded a **sixth EB-`Degraded` cause — a client 4xx BURST**: EB Enhanced Health
450
483
  counts application/ELB 4xx toward env health via two default-Enabled `ConfigDocument` rules
451
484
  (`ApplicationRequests4xx`, `ELBRequests4xx`, namespace
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "toga-ai",
3
- "version": "1.0.820",
3
+ "version": "1.0.822",
4
4
  "description": "TOGA Technology Team Claude Knowledge System — shared AI coding harness with skills, knowledge base CLI, and project installer for Claude Code.",
5
5
  "keywords": [
6
6
  "claude",