Skip to content

Policy v3: same CORS as /invoke - #490

Open
samgbafa wants to merge 2 commits into
mainfrom
tinycloud-bot/tc-2192-policy-v3-cors
Open

samgbafa wants to merge 2 commits into
mainfrom
tinycloud-bot/tc-2192-policy-v3-cors

Conversation

@samgbafa

@samgbafa samgbafa commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Browser calls from https://tinycloud.chat (and tauri://localhost) to /policy/v3/* were blocked by CORS because the node answered with only the Share origin. This gives /policy/v3/* the same CORS as /invoke: Access-Control-Allow-Origin: *, same methods/headers, Access-Control-Max-Age on preflights, and no Access-Control-Allow-Credentials (no /policy/v3 handler uses cookies or ambient credentials). share_security_fairing now sets only Cache-Control: no-store, X-Content-Type-Options, Referrer-Policy; cors_fairing is the single owner of CORS. The share_email.allowed_origins config and validation are unchanged (the email trust bundle still uses return_origin).

Behavior note: /policy/v3/* CORS headers are now emitted only when cors is enabled, like /invoke.

Refs TC-2192. No version bump or changelog.

test-ruling: TC-2192 (Naomi's ruling, in this builder's thread). Existing test lines changed, tinycloud-node-server/src/lib.rs (pre-change numbering):

  • 1972-1976 chromium_policy_admission_preflight_allows_authorization: removed assert_eq!(ACAO, Some("https://share.tinycloud.xyz")).
  • 1977-1984: removed Allow-Methods set == {GET, POST} assertion.
  • 1985-1997: removed Allow-Headers set == {authorization, content-type, x-request-id} assertion.
  • 1998-2003: removed Expose-Headers contains x-request-id assertion.
  • Renamed chromium_policy_admission_preflight_allows_authorization -> policy_admission_preflight_keeps_security_headers (approved by Naomi).
  • New in that test: asserts Cache-Control: no-store, X-Content-Type-Options: nosniff, Referrer-Policy: no-referrer.
  • 1949, 2010, 2048 (and the new-test client): share_security_fairing("https://share.tinycloud.xyz".into()) -> share_security_fairing(); same arg removal in attach_response_fairings(...) callers at lib.rs:2657, auth_guards.rs:438, routes/public.rs:458.
  • 2104 max_age_is_not_sent_on_actual_or_share_responses renamed max_age_is_not_sent_on_actual_responses.
  • 2122 comment "the share fairing owns /policy/v3/* and is left untouched" -> "/policy/v3/* gets the generic CORS policy, same as /invoke".
  • 2129-2132: ACAO Some("https://share.tinycloud.xyz") -> Some("*").
  • 2133-2136: Access-Control-Max-Age is_none() -> == Some("7200").

New test: cors_fairing_tests::policy_v3_preflight_and_post_match_invoke_for_any_origin (preflight + POST on /policy/v3/enforcer-bindings and /challenges, from both origins, production fairing order: wildcard origin, no credentials, security/cache headers kept). It failed before the change.

Staging stack note: deploy/share-email/docker-compose.staging.yaml sets TINYCLOUD_CORS=false. The current staging inventory (docs/plans/staging-environments.md, row 45) says tinycloud-node has no hosted non-production instance and describes this compose as hand-run and unused; repository references show no deployment workflow or browser Share consumer for it. No browser Share traffic through this stack is evidenced, so the CORS setting is unchanged.

/policy/v3/* now gets the generic wildcard CORS policy (no
Access-Control-Allow-Credentials). share_security_fairing keeps only the
security and cache headers; the Share-only origin parameter is removed.

Details: TC-2192

This branch has not been deployed

No deployments
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