Skip to content

v1.12.0 — CORS allowlist for the X-Authorization mirror; APP_ENV defaults to production

Latest

Choose a tag to compare

@hideyukiMORI hideyukiMORI released this 26 Sep 09:02
· 6 commits to main since this release
6146abd

Backward-compatible minor release.

⚠️ Migration note first — APP_ENV default is now production (#1599)

When APP_ENV is unset or empty, the default environment changed from local to production (secure by default). Production and staging deployments must set APP_ENV explicitly; local development must set APP_ENV=local explicitly (see .env.example). Only environments that silently relied on the implicit local default are affected. Behavior with an explicit APP_ENV is unchanged, including the NENE2_ALLOW_DEV_SECRET opt-in under explicit local.

Highlights

Fixed — cross-origin deployments with the X-Authorization mirror (#1668, #1669)

@hideyukimori/nene2-client (≥ 1.1.0) mirrors the Bearer token into X-Authorization on every request. When the frontend and the API live on different origins, the built-in CORS middleware rejected that header at the browser preflight, so every authenticated request failed with a CORS error. Now, when enableAuthorizationHeaderFallback: true, RuntimeApplicationFactory appends X-Authorization to Access-Control-Allow-Headers automatically (case-insensitive, no duplicate). Same-origin deployments are unaffected.

Added

  • RuntimeApplicationFactory: new trailing constructor argument corsAllowedHeaders (default CorsMiddleware::DEFAULT_ALLOWED_HEADERS = Content-Type, Authorization, X-Request-Id) to advertise additional custom request headers in Access-Control-Allow-Headers. New public constant CorsMiddleware::DEFAULT_ALLOWED_HEADERS keeps the middleware and factory defaults in sync. (#1668)
  • Nene2\Mcp\LocalMcpToolCatalog::withFilter(callable): self — immutable filtered view of the tool catalog; both tools() and find() honor the predicate, so filtered tools are unreachable from tools/call as well. (#1570)

Changed

  • Conformance linter ConformanceRunner::withDefaultRules() now contains only the generic rules (D1–D4 / R1 / R2). The fleet-specific R3 rule moved to the opt-in fleet layer (withFleetRules() / tools/conformance.php --fleet). (#1593)
  • APP_ENV default local → production — see the migration note above. (#1599)

Breaking changes

None. All public API additions are trailing default arguments or new methods.

Verification

  • composer check: 900 tests / 2215 assertions, PHPStan level 8 clean, PHP CS Fixer clean, OpenAPI contract valid, MCP catalog valid, conformance OK, version consistency OK (1.12.0)
  • CI on #1669 and #1671: Composer Check / npm Check / npm Audit / Playwright Smoke all passing

Related

Known risks / follow-up

  • corsAllowedHeaders only takes effect when the built-in CORS middleware is active (allowedOrigins non-empty). Consumers that wrapped the factory in their own outer CorsMiddleware as a workaround keep working unchanged and can drop the wrapper after upgrading.
  • Exposing allowedMethods / maxAge from the factory is out of scope; open an issue if needed.

Full Changelog

v1.11.0...v1.12.0