diff --git a/GITHUB_ISSUES.md b/GITHUB_ISSUES.md index 7f50286..ad4bce3 100644 --- a/GITHUB_ISSUES.md +++ b/GITHUB_ISSUES.md @@ -146,7 +146,7 @@ Do not redesign routing or hosting in this issue; WEB-001 owns that. WEB-001A1 [ **Current CI-001C boundary:** CI-001C1 [#667](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/667) supplies the staging-only protected read-only OIDC proof: exact immutable repository/owner IDs, `main`, the `staging` environment, one verifier workflow, two named individual reviewers, and a keyless principal with only project-identity read permission. Parent #133 still owns Firebase deployment roles and production protection; #136 still owns an actual backend release. -**Current CI-001D boundary:** CI-001D1 [#669](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/669) supplies the first staging data boundary: empty Native/Standard `(default)` Firestore in `us-west2`, delete protection enabled, PITR disabled, and exact Rules/indexes from `ee16bd16220ab58bd3a2add80dd2f39a1d514dd7`. The 418-case Rules suite passed, provider definitions matched, fixed anonymous server-only reads were denied, and root collection count remained zero. CI-001D2 [#671](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/671) deploys the email/password-only Auth contract from exact merged source `42542303d043f87a8f1a04be2f0b4f2a88e0318c`. Provider readback and disposable API/browser checks prove password-required sign-in, improved email privacy, only staging domains, no other provider, billing disabled, and final cleanup to zero users/records. CI-001D3 [#674](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/674) adds a source-only, argument-closed command for exactly `createMemberOnSignUp` and `ensureMemberProfile`; its tests reject broad/partial targets, another project/account, a credentials file, changed exports/scripts, extra arguments, and an unpinned CLI. Read-only preflight found project Owner authority, billing disabled, and zero open billing accounts visible to the club account. No Function/API/billing/data/provider mutation is part of #674. CI-001D4 [#676](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/676) merges its argument-closed Hosting command through PR #677 as exact source `bce911a7083201cfe2141edaa9660f210287bf57`; all five post-main CI jobs passed. The bounded provider checkpoint enabled only Firebase App Check and reCAPTCHA Enterprise, created exactly one score-based key restricted to the two staging hosts, registered it to the one web app with a one-hour token lifetime, and configured Authentication plus Firestore as `UNENFORCED` with replay protection off. The guarded Hosting-only path published that exact source as version `8556fc51210bdc66`; root/direct Events, empty Firestore, layout, and browser warning/error checks passed. The issue remains open because the new disposable Auth browser proof, atomic `ENFORCED` readback, missing-token denial, final token-bearing replay, cleanup, and completion evidence remain unfinished. Billing is disabled, user/root-collection counts are zero, no Functions-related API or Function exists, and production is unchanged. Parent #133 still owns keyless Firebase deployment roles and production protection; #136 still owns the compatible synthetic backend release. +**Current CI-001D boundary:** CI-001D1 [#669](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/669) supplies the first staging data boundary: empty Native/Standard `(default)` Firestore in `us-west2`, delete protection enabled, PITR disabled, and exact Rules/indexes from `ee16bd16220ab58bd3a2add80dd2f39a1d514dd7`. The 418-case Rules suite passed, provider definitions matched, fixed anonymous server-only reads were denied, and root collection count remained zero. CI-001D2 [#671](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/671) deploys the email/password-only Auth contract from exact merged source `42542303d043f87a8f1a04be2f0b4f2a88e0318c`. Provider readback and disposable API/browser checks prove password-required sign-in, improved email privacy, only staging domains, no other provider, billing disabled, and final cleanup to zero users/records. CI-001D3 [#674](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/674) adds a source-only, argument-closed command for exactly `createMemberOnSignUp` and `ensureMemberProfile`; its tests reject broad/partial targets, another project/account, a credentials file, changed exports/scripts, extra arguments, and an unpinned CLI. Read-only preflight found project Owner authority, billing disabled, and zero open billing accounts visible to the club account. No Function/API/billing/data/provider mutation is part of #674. CI-001D4 [#676](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/676) merges its argument-closed Hosting command through PR #677 as exact source `bce911a7083201cfe2141edaa9660f210287bf57`; all five post-main CI jobs passed. The bounded provider phase enabled only Firebase App Check and reCAPTCHA Enterprise, created exactly one score-based key restricted to the two staging hosts, registered it to the one web app with a one-hour token lifetime, and published that exact source as Hosting version `8556fc51210bdc66`. A reserved-domain disposable browser identity proved create, sign-out, fresh sign-in, and post-enforcement sign-in; token-bearing Events reads stayed successful signed in and signed out. Authentication plus Firestore now read `ENFORCED` with replay protection `OFF`; tokenless Auth and Firestore probes were rejected with HTTP 401 and 403. Cleanup returned users and root collections to zero. Billing is disabled, no Functions-related API or Function exists, the account profile remains fail-closed until those Functions are deployed, and production is unchanged. Parent #133 still owns keyless Firebase deployment roles and production protection; #136 still owns the compatible synthetic backend release. ### Problem diff --git a/IMPLEMENTATION_PLAN.md b/IMPLEMENTATION_PLAN.md index c6c5b86..414985b 100644 --- a/IMPLEMENTATION_PLAN.md +++ b/IMPLEMENTATION_PLAN.md @@ -48,7 +48,7 @@ MPRC can open a race or merchandise item for sale only when the platform can: **CI-001D3 staging profile-Function guard:** [#674](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/674) adds an argument-closed source command for exactly `createMemberOnSignUp` and `ensureMemberProfile`. It validates the demo-only default alias, single reviewed Functions codebase, exact exports, lockfile Firebase CLI 15.24.0, staging project and quota project, club-account declaration, exact target list, short-lived token path, and absence of credential-file overrides before invoking Firebase. Negative tests reject missing/redirected exports, broad or partial target sets, production/cross-project context, extra arguments, changed scripts, and an unpinned CLI. Read-only provider preflight found project Owner authority but billing disabled and zero visible open billing accounts. #674 therefore enables no API, links no billing, deploys no Function, creates no record, and leaves App Check, staging E2E, reusable release authority, and production to later approved children. -**CI-001D4 staging App Check monitoring checkpoint:** [#676](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/676) merges a source-only, argument-closed Hosting command for `run-mprc-staging`. It validates the demo-only default alias, exact Hosting predeploy chain, Firebase CLI 15.24.0, staging project and quota project, club-account declaration, Hosting-only scope, short-lived token path, absence of credential-file overrides, and one bounded non-placeholder Enterprise site key; the executable artifact check must also find that key. After exact source `bce911a7083201cfe2141edaa9660f210287bf57` passed all five post-main CI jobs, the bounded provider phase enabled only Firebase App Check and reCAPTCHA Enterprise, created one score-based key restricted to the two staging hosts, registered it to the one web app with a one-hour token lifetime, and set Auth plus Firestore to monitoring mode with replay protection off. The guarded command published the same exact source as Hosting version `8556fc51210bdc66`; public root/direct-route, empty Firestore, layout, and browser warning/error checks passed. This is not enforcement completion: the new disposable Auth browser proof, atomic `ENFORCED` readback, missing-token denial, token-bearing replay, final cleanup/evidence, Functions, billing, reusable authority, and production remain pending or unchanged. +**CI-001D4 staging App Check enforcement:** [#676](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/676) merges a source-only, argument-closed Hosting command for `run-mprc-staging`. It validates the demo-only default alias, exact Hosting predeploy chain, Firebase CLI 15.24.0, staging project and quota project, club-account declaration, Hosting-only scope, short-lived token path, absence of credential-file overrides, and one bounded non-placeholder Enterprise site key; the executable artifact check must also find that key. After exact source `bce911a7083201cfe2141edaa9660f210287bf57` passed all five post-main CI jobs, the bounded provider phase enabled only Firebase App Check and reCAPTCHA Enterprise, created one score-based key restricted to the two staging hosts, registered it to the one web app with a one-hour token lifetime, and published the same exact source as Hosting version `8556fc51210bdc66`. A reserved-domain disposable browser identity proved create, sign-out, fresh sign-in, and post-enforcement sign-in; signed-in and signed-out token-bearing Events reads remained successful. Auth plus Firestore now read `ENFORCED` with replay protection `OFF`; tokenless Auth and Firestore requests returned HTTP 401 and 403 respectively. Cleanup returned users and root collections to zero. Functions, billing, reusable authority, provider sandboxes, and production remain pending or unchanged. ## 3. Dependency map diff --git a/OFFICER_START_HERE.md b/OFFICER_START_HERE.md index f728d5e..48dd597 100644 --- a/OFFICER_START_HERE.md +++ b/OFFICER_START_HERE.md @@ -50,7 +50,7 @@ As of **2026-08-13**, a merge runs checks but does not start the GitHub release. As of **2026-08-14**, [#659](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/659) completed one accessibility-only Netlify release. Deploy `6a7ece87c5ca4d0007c1a3fc` is live from frozen source `7496fe0881fb52908c4ff2f40f488df09c94c908`; its exact 62-file marker and signed-out desktop/phone route-focus and menu checks passed. Repause merge `3138a00c1c48e1d5d1dcda0b44722b09a2194ff7` made the manifest inactive. Its attempt `6a7ed0ddb00a46000818878d` published nothing and retained the verified deploy. #623 deploy `6a7e072f8f346b0008510d29` is the recorded rollback, not current production. #659 changed no Firebase, provider configuration, account, sign-in state, production data, payment, or connected directory behavior. Officers do not run commands, sign in, enter data, or approve this as a reusable release. Follow the completed record in [Review, merge, release, and check a change](./docs/officers/PUBLISH_AND_CHECK.md). -As of **2026-08-26**, WEB-001A1 [#663](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/663) is merged, and WEB-001A2 [#665](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/665) created the club-owned `run-mprc-staging` project. CI-001C1 [#667](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/667) adds a separate protected read-only identity check: Dave Liu or Jeff Chang reviews exact `main`, and a keyless five-minute identity may read only the staging project identity. It cannot deploy Firebase. CI-001D1 [#669](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/669) adds an empty, delete-protected staging Firestore database and the exact reviewed Rules/index definitions. Anonymous reads of three fixed server-only paths were denied, and the database still had zero root collections after verification. CI-001D2 [#671](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/671) deploys password-required email/password Auth from exact merged source and proves it with disposable API and browser sign-in/sign-out checks. Readback shows improved email privacy, only the two staging domains, no other provider, billing disabled, and zero users/records after cleanup. CI-001D3 [#674](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/674) adds a code guard for a future deployment of only the two profile Functions. It does not deploy them, and billing remains unapproved. CI-001D4 [#676](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/676) has now reached its monitoring checkpoint: exact merged source `bce911a7083201cfe2141edaa9660f210287bf57` is live at [run-mprc-staging.web.app](https://run-mprc-staging.web.app) as Hosting version `8556fc51210bdc66`; one score-based App Check key is restricted to only the two staging hosts and registered to the one web app for one-hour tokens; and Authentication plus Firestore are monitoring requests with replay protection off. Public root and Events checks passed, the empty Events result rendered correctly, and browser warnings/errors were absent. This remains an **ENGINEERING STAGING SITE ONLY**: the new disposable browser Auth proof, App Check enforcement/readback, missing-token denial, final token-bearing replay, Functions, outside-provider sandbox, protected automatic release, release marker, tested rollback, complete security headers, custom domain, and officer publish control are still **NOT AVAILABLE YET**. Officers do not sign in, enter data, run commands, configure providers, attach billing, or treat this checkpoint as a usable member backend. Users and root collections remain zero; Netlify still answers `runmprc.com`; production Firebase Hosting remains empty; and DNS, GitHub Pages, Netlify, production Firebase, production data, and live website behavior are unchanged. +As of **2026-08-26**, WEB-001A1 [#663](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/663) is merged, and WEB-001A2 [#665](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/665) created the club-owned `run-mprc-staging` project. CI-001C1 [#667](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/667) adds a separate protected read-only identity check: Dave Liu or Jeff Chang reviews exact `main`, and a keyless five-minute identity may read only the staging project identity. It cannot deploy Firebase. CI-001D1 [#669](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/669) adds an empty, delete-protected staging Firestore database and the exact reviewed Rules/index definitions. Anonymous reads of three fixed server-only paths were denied, and the database still had zero root collections after verification. CI-001D2 [#671](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/671) deploys password-required email/password Auth from exact merged source and proves it with disposable API and browser sign-in/sign-out checks. Readback shows improved email privacy, only the two staging domains, no other provider, billing disabled, and zero users/records after cleanup. CI-001D3 [#674](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/674) adds a code guard for a future deployment of only the two profile Functions. It does not deploy them, and billing remains unapproved. CI-001D4 [#676](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/676) now enforces App Check on staging Authentication and Firestore: exact source `bce911a7083201cfe2141edaa9660f210287bf57` is live at [run-mprc-staging.web.app](https://run-mprc-staging.web.app) as Hosting version `8556fc51210bdc66`; one score-based key is restricted to only the two staging hosts and registered to the one web app for one-hour tokens; and both services read `ENFORCED` with replay protection `OFF`. A made-up browser account completed create, sign-out, fresh sign-in, and post-enforcement sign-in; token-bearing empty Events reads worked signed in and signed out without browser warnings/errors. Requests without App Check were denied by Auth and Firestore, and cleanup returned users and root collections to zero. This remains an **ENGINEERING STAGING SITE ONLY**: Functions, outside-provider sandboxes, protected automatic release, release marker, tested rollback, complete security headers, custom domain, and officer publish control are still **NOT AVAILABLE YET**. The account page therefore shows a safe unavailable profile state. Officers do not sign in, enter data, run commands, configure providers, attach billing, or treat App Check as a complete member backend. Netlify still answers `runmprc.com`; production Firebase Hosting remains empty; and DNS, GitHub Pages, Netlify, production Firebase, production data, and live website behavior are unchanged. The optional profile-photo and officer People-finder functions are still **NOT AVAILABLE YET**. #621 makes the frontend default an inert preview: My Account shows the future photo and separate finder-choice controls disabled, while the People finder stays behind the administrator guard and shows its name field and Search button disabled. The preview reads no saved photo or setting, accepts or uploads no photo, searches no name, and saves nothing; it shows no people or sample results. #623 published exactly that disabled interface as deploy `6a7e072f8f346b0008510d29`. Officers inspect the protected layouts only in synthetic local artifacts. The completed signed-out production review proved only the exact revision, normal sign-in and administrator guards, and absence of a member-directory network request. Do not sign in to production, choose a real photo, enter a real name, or treat the preview as a directory. #623 changed no Firebase, provider configuration, account, sign-in, or production data. #507 must later prove the privacy, authorization, staging, backend-first deployment, and readback gates before a separate reviewed source change may connect it. Follow the preview and source-review procedure in [Events, shop, members, and money](./docs/officers/EVENTS_SHOP_MEMBERS.md). diff --git a/OPERATIONS_RUNBOOK.md b/OPERATIONS_RUNBOOK.md index 217c50a..2b3e3f5 100644 --- a/OPERATIONS_RUNBOOK.md +++ b/OPERATIONS_RUNBOOK.md @@ -80,7 +80,7 @@ CI-001D3 [#674](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/674) adds CI-001D4 [#676](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/676) adds `npm run deploy:staging-hosting` as a separate source-only, argument-closed wrapper. It checks the demo-only default alias, exact Hosting predeploy chain, lockfile CLI 15.24.0, exact staging project/quota/account, Hosting-only scope, in-memory short-lived token, no credential-file override, and a bounded non-placeholder Enterprise site key. The executable scanner must find that same public key in the built JavaScript. Do not run it from a branch, append arguments, use a debug token, add localhost to provider domains, or treat the public site key as a server credential. -The bounded #676 provider checkpoint ran on 2026-08-26 only after exact source `bce911a7083201cfe2141edaa9660f210287bf57` reached `main` and all five jobs in post-main CI run `33018136439` passed. It enabled only Firebase App Check and reCAPTCHA Enterprise, created one score-based key restricted to `run-mprc-staging.web.app` and `run-mprc-staging.firebaseapp.com`, registered it to the one staging web app with a one-hour token lifetime, and atomically set Authentication plus Firestore to `UNENFORCED` with replay protection off. The guarded Hosting-only command published the same exact source as version `8556fc51210bdc66`; the 61-file artifact manifest SHA-256 is `157e2048aa86d45cec1111e091643870d18ced808ef88d610ec70aae1bbe1ace`. Root and direct `/events` returned 200; the empty Events state and 1280-by-720 layout rendered correctly; browser warnings/errors were absent. Provider readback still showed billing disabled, zero Auth users, zero Firestore root collections, and no Functions-related API or Function. This is a monitoring checkpoint, not enforcement evidence: do not claim completion until the new disposable Auth browser flow, `ENFORCED` readback, missing-token denial, token-bearing replay, final cleanup, and evidence merge all pass. If a post-enforcement browser check fails, atomically restore both services to `UNENFORCED`, verify that readback, and preserve the restricted provider configuration for diagnosis. +The bounded #676 provider phase ran on 2026-08-26 only after exact source `bce911a7083201cfe2141edaa9660f210287bf57` reached `main` and all five jobs in post-main CI run `33018136439` passed. It enabled only Firebase App Check and reCAPTCHA Enterprise, created one score-based key restricted to `run-mprc-staging.web.app` and `run-mprc-staging.firebaseapp.com`, registered it to the one staging web app with a one-hour token lifetime, and published the same exact source as Hosting version `8556fc51210bdc66`; the 61-file artifact manifest SHA-256 is `157e2048aa86d45cec1111e091643870d18ced808ef88d610ec70aae1bbe1ace`. Root and direct `/events` returned 200; the empty Events state and 1280-by-720 layout rendered correctly; browser warnings/errors were absent. A made-up reserved-domain browser identity then completed account creation, sign-out, fresh sign-in, and post-enforcement sign-in. Authentication plus Firestore were atomically changed from `UNENFORCED` to `ENFORCED` with replay protection `OFF`; a valid-credential Auth request without App Check returned HTTP 401, and a tokenless Firestore Events request returned HTTP 403. Token-bearing Events reads continued to render the empty result signed in and signed out. The disposable identity was deleted; final provider readback showed zero Auth users, zero Firestore root collections, billing disabled, and no Functions-related API or Function. Preserve `ENFORCED`/`OFF`; if a future browser regression appears, open an incident before changing policy and use the same atomic two-service rollback only with platform/security approval. The repository's only `.firebaserc` default is now `demo-mprc-local`, a deliberately non-deployable local namespace. It is an accidental-deploy brake, not staging. Every future deployment must still pass one exact privately approved project explicitly. Do not infer backend/provider isolation or release authority from the static host; #113/#133 must protect, map, and verify those remaining boundaries. @@ -109,25 +109,25 @@ REACT_APP_STRAVA_CLIENT_ID The Firebase web configuration is public application configuration. It must still be environment-specific and paired with Auth restrictions, Firestore rules, and App Check. WEB-001A1 [#663](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/663) makes controlled optimized builds choose `staging` or `production`; staging project IDs must include a distinct `staging` segment and the complete artifact check rejects known production identities. Production accepts only the exact reviewed public values. These values are not server credentials, but do not paste provider-console screenshots, private links, tokens, or any server credential into source or an issue. -`firebase.json` has a Hosting block for `build/` and missing-path SPA rewrites. Its predeploy chain rejects a Firebase CLI project that differs from the selected browser project, then rebuilds and scans executable JavaScript before upload. It also has the #671 email/password-only Auth source block; source remains configuration intent, while the separate provider evidence proves the live narrow Auth boundary. **Static engineering staging, a protected read-only authority check, an empty Rules-protected Firestore boundary, disposable email/password Auth proof, and an App Check monitoring checkpoint are available; a usable backend and production publication are NOT AVAILABLE YET.** #665 used the Hosting chain for the first `run-mprc-staging` release. #667's WIF identity can read only the project identity; it cannot deploy. #669, #671, and the #676 monitoring checkpoint were bounded provider operations and did not grant reusable authority. Exact source `bce911a7083201cfe2141edaa9660f210287bf57` is current staging Hosting version `8556fc51210bdc66`; Authentication and Firestore remain `UNENFORCED` with replay protection off. No protected Firebase deploy role, Function, enforced App Check service, provider sandbox, production authority, custom domain, release marker, tested rollback, production release, or DNS/TLS change exists. +`firebase.json` has a Hosting block for `build/` and missing-path SPA rewrites. Its predeploy chain rejects a Firebase CLI project that differs from the selected browser project, then rebuilds and scans executable JavaScript before upload. It also has the #671 email/password-only Auth source block; source remains configuration intent, while separate provider evidence proves the live narrow Auth boundary. **Static engineering staging, a protected read-only authority check, an empty Rules-protected Firestore boundary, disposable email/password Auth proof, and enforced App Check for Auth plus Firestore are available; Functions, a usable member backend, and production publication are NOT AVAILABLE YET.** #665 used the Hosting chain for the first `run-mprc-staging` release. #667's WIF identity can read only the project identity; it cannot deploy. #669, #671, and #676 were bounded provider operations and did not grant reusable authority. Exact source `bce911a7083201cfe2141edaa9660f210287bf57` is current staging Hosting version `8556fc51210bdc66`; Authentication and Firestore read `ENFORCED` with replay protection `OFF`. No protected Firebase deploy role, Function, provider sandbox, production authority, custom domain, release marker, tested rollback, production release, or DNS/TLS change exists. -### App Check release state — MONITORING AVAILABLE; ENFORCEMENT NOT AVAILABLE YET +### App Check release state — ENFORCEMENT AVAILABLE IN STAGING ABUSE-001A1 is tracked in live [#159](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/159). It changes only the browser source from the legacy reCAPTCHA v3 provider class to the Firebase SDK's Enterprise provider. It does not create or configure a key. Protected release `29254280177` stopped before checkout/build because `REACT_APP_RECAPTCHA_SITE_KEY` was absent. Nothing was published in that attempt. Do not use a placeholder, reuse an unverified v3 key, expose a debug token, or weaken the release check. -The later #676 monitoring checkpoint is now live only on `run-mprc-staging`. It has one score-based Enterprise key restricted to the two staging hosts, one matching web-app config with a one-hour token lifetime, exact source `bce911a7083201cfe2141edaa9660f210287bf57` published as Hosting version `8556fc51210bdc66`, and Authentication plus Firestore set to `UNENFORCED` with replay protection off. Public Hosting and empty Firestore/UI checks passed. The new disposable browser Auth flow, enforced readback, missing-token denial, and token-bearing replay have not passed yet; do not describe monitoring as protection. +The later #676 App Check boundary is live only on `run-mprc-staging`. It has one score-based Enterprise key restricted to the two staging hosts, one matching web-app config with a one-hour token lifetime, exact source `bce911a7083201cfe2141edaa9660f210287bf57` published as Hosting version `8556fc51210bdc66`, and Authentication plus Firestore set to `ENFORCED` with replay protection `OFF`. Disposable browser Auth, token-bearing signed-in/signed-out Events reads, tokenless Auth/Firestore denial, cleanup, and final provider readback passed. Do not generalize that proof to absent Functions, private roles/data, outside providers, production, or real identities. -The safe sequence is now at the browser-proof step: +The #676 sequence is complete. Preserve the proved boundary: 1. Keep the exact project/account/host inventory and zero-user/zero-record checks current. 2. Preserve the merged #159 Enterprise browser source and #676 argument-closed Hosting guard. 3. Preserve the one score-based key restricted to only the two staging hosts and its one-hour registration to the one staging web app. 4. Preserve exact Hosting source `bce911a7083201cfe2141edaa9660f210287bf57` and version `8556fc51210bdc66`; do not rebuild from a branch or widen the Hosting-only scope. -5. With explicit approval for the live browser credential submission, prove one made-up disposable Auth sign-up/sign-in/sign-out plus the empty Firestore read while both services remain in monitoring mode. Delete the identity afterward. -6. Atomically set only staging Authentication and Firestore to `ENFORCED`, leave replay protection off, wait for propagation, then prove missing-token denial and continued token-bearing browser success. If the browser fails, atomically restore both services to `UNENFORCED` and verify the rollback. -7. Reconfirm zero users and root collections, billing disabled, no Functions API/deployment, and production unchanged before merging completion evidence. +5. Preserve Authentication and Firestore as `ENFORCED` with replay protection `OFF`; the approved made-up browser lifecycle, tokenless denial, and token-bearing Events evidence passed. +6. If a future browser regression appears, stop staging sign-in use and open an incident before changing policy. Roll back both services atomically only with platform/security approval, then verify the readback. +7. Reconfirm zero users and root collections, billing disabled, no Functions API/deployment, and production unchanged before any later staging release. 8. Keep native callable enforcement and Function deployment separate until the billing gate is explicitly approved; publish and verify production website, Firebase, provider, and live behavior separately under #136/WEB-001. A source merge, green CI run, or public-key variable alone does not prove Enterprise is configured or protecting a callable. diff --git a/README.md b/README.md index 313475c..4d509a8 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ Historical developer/content/LLM guides remain under [`docs/`](./docs/README.md) **Deployment reality checked 2026-08-14:** merges run CI but do not start the manual release workflow. The protected gate accepts one exact current merged commit, rechecks its newest CI run after approval, uses one fixed Firebase target set, fails when protected authority/configuration is missing, verifies Firebase before publishing GitHub Pages, and gives no server credential to website preparation or publication. Ordinary Git-triggered Netlify production builds are paused. WEB-002D [#659](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/659) completed one bounded accessibility release: exact merge `46e23647d8e0bf9fa3a574ea5c5f993be10a419d` published deploy `6a7ece87c5ca4d0007c1a3fc` from source `7496fe0881fb52908c4ff2f40f488df09c94c908`, tree `ccac4c189c195db8ab594e0eefe256ea9fa04996`, 62 files, and artifact digest `e4c26e6f0fbcd086663d86238675f0be228fb649a00628c1c97d1166612f49c7`. Signed-out desktop and phone route-focus/menu checks passed. Repause merge `3138a00c1c48e1d5d1dcda0b44722b09a2194ff7` passed exact-main CI run `31783808994`; attempt `6a7ed0ddb00a46000818878d` published nothing, deploy `6a7ece87c5ca4d0007c1a3fc` remained live, and the manifest is inactive. #623 deploy `6a7e072f8f346b0008510d29` remains rollback history and its inert directory interface is unchanged beneath the accessibility delta. No Firebase, Rules, Functions, indexes, provider configuration, account, sign-in state, role, member data, payment, or connected directory backend changed. The prior bounded #473 deploy `6a6dc9ea588b0c0008036312` remains older history. The source stops adding a Pages `CNAME`, but GitHub Pages currently still claims `runmprc.com` and its default URL redirects there; only a controlled #136/WEB-001 publication and provider readback can clear that conflict. Reusable protected publication to the live Netlify-served `runmprc.com` is not configured yet. Treat GitHub Pages, Netlify, `runmprc.com`, Firebase, and outside providers as separate states. -**Owned staging checked 2026-08-26:** WEB-001A2 [#665](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/665) created the isolated `run-mprc-staging` Firebase project under the club account and published its first static Hosting version. CI-001C1 [#667](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/667) adds a protected staging-only OIDC verifier with two named reviewers and a keyless principal that can read only the exact project identity. CI-001D1 [#669](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/669) adds the empty delete-protected `(default)` Firestore database in `us-west2` and deploys exact Rules/indexes from source `ee16bd16220ab58bd3a2add80dd2f39a1d514dd7`; provider definitions matched, fixed anonymous server-only reads were denied, and the root collection count remained zero. CI-001D2 [#671](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/671) deployed exact merged source `42542303d043f87a8f1a04be2f0b4f2a88e0318c` to Auth only. Live readback shows instrumentless Firebase Authentication with Identity Platform, billing disabled, password-required email/password, improved email privacy, only the two staging authorized domains, and no other sign-in provider. Disposable API and browser sign-in/sign-out checks passed, both identities were removed, no email or SMS was requested, and the final user and Firestore root-collection counts were zero. CI-001D3 [#674](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/674) adds a source-only guard for exactly `createMemberOnSignUp` and `ensureMemberProfile`; billing remains unapproved, so no Function API was enabled and no Function was deployed. CI-001D4 [#676](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/676) merged its argument-closed Hosting/App Check source guard through [PR #677](https://github.com/Run-MPRC/Run-MPRC.github.io/pull/677) as exact source `bce911a7083201cfe2141edaa9660f210287bf57`; all five exact-main jobs in run `33018136439` passed. The bounded provider checkpoint enabled only Firebase App Check and reCAPTCHA Enterprise, created exactly one score-based key restricted to the two staging hosts, registered it to the one web app with a one-hour token lifetime, and set Authentication plus Firestore to `UNENFORCED` with replay protection off. The guarded Hosting-only path published exact source `bce911a7083201cfe2141edaa9660f210287bf57` as version `8556fc51210bdc66`; root and direct `/events` returned 200, the empty Events state rendered correctly, and the browser reported no warnings or errors. This is still incomplete engineering staging: the new disposable Auth browser proof, `ENFORCED` readback, missing-token denial, and final token-bearing replay remain pending. Billing is still disabled, users and root collections remain zero, Functions-related APIs and deployed Functions remain absent, and production Firebase Hosting plus the Netlify-served `runmprc.com` are unchanged. +**Owned staging checked 2026-08-26:** WEB-001A2 [#665](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/665) created the isolated `run-mprc-staging` Firebase project under the club account and published its first static Hosting version. CI-001C1 [#667](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/667) adds a protected staging-only OIDC verifier with two named reviewers and a keyless principal that can read only the exact project identity. CI-001D1 [#669](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/669) adds the empty delete-protected `(default)` Firestore database in `us-west2` and deploys exact Rules/indexes from source `ee16bd16220ab58bd3a2add80dd2f39a1d514dd7`; provider definitions matched, fixed anonymous server-only reads were denied, and the root collection count remained zero. CI-001D2 [#671](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/671) deployed exact merged source `42542303d043f87a8f1a04be2f0b4f2a88e0318c` to Auth only. Live readback shows instrumentless Firebase Authentication with Identity Platform, billing disabled, password-required email/password, improved email privacy, only the two staging authorized domains, and no other sign-in provider. Disposable API and browser sign-in/sign-out checks passed, both identities were removed, no email or SMS was requested, and the final user and Firestore root-collection counts were zero. CI-001D3 [#674](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/674) adds a source-only guard for exactly `createMemberOnSignUp` and `ensureMemberProfile`; billing remains unapproved, so no Functions-related API was enabled and no Function was deployed. CI-001D4 [#676](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/676) merged its argument-closed Hosting/App Check source guard through [PR #677](https://github.com/Run-MPRC/Run-MPRC.github.io/pull/677) as exact source `bce911a7083201cfe2141edaa9660f210287bf57`; all five exact-main jobs in run `33018136439` passed. The bounded provider phase enabled only Firebase App Check and reCAPTCHA Enterprise, created exactly one score-based key restricted to the two staging hosts, registered it to the one web app with a one-hour token lifetime, and published that exact source as Hosting version `8556fc51210bdc66`. A made-up reserved-domain browser account completed create, sign-out, fresh sign-in, and post-enforcement sign-in; the empty Events read succeeded both signed in and signed out with no browser warning or error. Authentication plus Firestore now read `ENFORCED` with replay protection `OFF`; the same valid Auth credentials without App Check were rejected with HTTP 401, and a tokenless Firestore Events request was rejected with HTTP 403. The disposable user was deleted and final users plus root collections are zero. Billing remains disabled, Functions-related APIs and deployed Functions remain absent, the account page fails closed while those Functions are unavailable, and production Firebase Hosting plus the Netlify-served `runmprc.com` are unchanged. ## Local setup status diff --git a/SECURITY.md b/SECURITY.md index 8d156da..c819528 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -47,7 +47,7 @@ The findings below describe the repository at the start of the 2026-07-12 assess | RISK-007 | Repository source rejects unverified targets at the two existing role-grant endpoints. AUTH-001B [#196](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/196) adds exact verified-email checks to role-based Firestore Rules, and AUTH-001C [#209](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/209) tracks the matching gate at current Functions role consumers. Firebase deployment, verification-mirror refresh, revocation, authoritative membership, scoped capability/recent-auth controls, and replacement of the legacy static-key endpoint remain unproven. | Older deployed code or a remaining role-only server guard can let an unverified known-email account use member/admin authority. CSV export also retains separate minimization, recent-auth, and audit risks. | Deploy and verify the exact Rules/Functions through #105, complete the remaining AUTH-001 mirror/revocation work, require authoritative membership and scoped privileged access, harden roster export under #116, and retire the static-key endpoint. | | RISK-008 | `requireAppCheck` is controlled by optional `ENFORCE_APP_CHECK`; repository/deployment config does not prove it is true. Missing site key also disables client App Check. | Public callable functions may be scripted directly, enabling abuse and cloud/Stripe cost amplification. | Use Firebase runtime `enforceAppCheck: true` for sensitive callables, reCAPTCHA Enterprise, staged metrics, and no environment fail-open. | | RISK-009 | #99 source preserves and validates the complete same-origin Pages callback route, applies `strict-origin` before subresources, and suppresses initial callback App Check/telemetry startup; #126 adds that standalone suite as a blocking hosted CI step. #443 adds only the source/test Strava same-document handoff after the native and Router callback locations are clean. No production Stripe/Strava callback, provider-backed App Check token behavior, or live custom-domain handoff has been rehearsed, and the live custom domain uses a different host. | Hosting, provider, configuration, or release drift can still break return links or the App Check handoff even when source tests pass. Enforcing a callback callable without its matching released client handoff and staged provider evidence can also break confirmation or Strava exchange. | Keep the hosted callback gate blocking; keep `lookupRegistration`/`lookupOrder` deferred until DATA-001A; keep native enforcement for `stravaExchangeCode` deferred to ABUSE-001A2 after the exact #443 website source and provider-backed Enterprise token behavior are proven in protected staging; verify test-mode callbacks only after provider gates; consolidate hosting under WEB-001. | -| RISK-010 | Development/test use synthetic loopback Auth, Firestore, and Functions. WEB-001A1 [#663](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/663) binds controlled Hosting builds to an explicit environment, and WEB-001A2 [#665](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/665) supplies owned staging. CI-001D1 [#669](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/669) adds an empty delete-protected Firestore database with exact Rules/indexes. CI-001D2 [#671](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/671) deploys and verifies password-required email/password Auth with improved email privacy. CI-001D3 [#674](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/674) narrows the future staging command to the two profile Functions, but billing is unapproved. CI-001D4 [#676](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/676) now has one restricted score-based Enterprise key, one matching web-app config with one-hour tokens, exact source `bce911a7083201cfe2141edaa9660f210287bf57` live as Hosting version `8556fc51210bdc66`, and Authentication plus Firestore in `UNENFORCED` monitoring with replay protection off. Public empty-Firestore/UI checks passed, but the new disposable Auth proof, enforcement/readback, missing-token denial, and token-bearing replay are unfinished. The project has no deployed Function or Functions-related API, billing link, user, or root collection. Storage data, outside-provider sandboxes, protected Firebase deployment authority, and a release marker remain absent; emulated Functions can still call outside providers. | A partially provisioned stage, monitoring policy, bypassed build path, or provider-capable emulator can be mistaken for complete protection and affect production/provider systems. | Keep real identities and private actions out of previews; preserve the fixed project, exact Rules/Auth/Hosting evidence, and both deploy guards; do not link billing merely to make a test pass; complete #676 browser/token/enforcement/denial/cleanup proof and #113/#133/#136 Functions, short-lived deploy authority, and provider isolation; prove test keys, sinks, exact marker readback, and rollback before broader end-to-end flows. | +| RISK-010 | Development/test use synthetic loopback Auth, Firestore, and Functions. WEB-001A1 [#663](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/663) binds controlled Hosting builds to an explicit environment, and WEB-001A2 [#665](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/665) supplies owned staging. CI-001D1 [#669](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/669) adds an empty delete-protected Firestore database with exact Rules/indexes. CI-001D2 [#671](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/671) deploys and verifies password-required email/password Auth with improved email privacy. CI-001D3 [#674](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/674) narrows the future staging command to the two profile Functions, but billing is unapproved. CI-001D4 [#676](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/676) now has one restricted score-based Enterprise key, one matching web-app config with one-hour tokens, and exact source `bce911a7083201cfe2141edaa9660f210287bf57` live as Hosting version `8556fc51210bdc66`. Auth plus Firestore read `ENFORCED` with replay protection `OFF`; valid-credential Auth and public Events requests without App Check were denied with HTTP 401/403, while disposable browser Auth and signed-in/signed-out token-bearing Events reads passed. Cleanup returned users and root collections to zero. The project has no deployed Function or Functions-related API, billing link, user, or root collection. Storage data, outside-provider sandboxes, protected Firebase deployment authority, and a release marker remain absent; emulated Functions can still call outside providers. | A partially provisioned stage, bypassed build path, or provider-capable emulator can be mistaken for a complete backend and affect production/provider systems. App Check proves caller attestation, not membership, payment, provider isolation, or server behavior. | Keep real identities and private actions out of previews; preserve the fixed project, exact Rules/Auth/Hosting/App Check evidence, and both deploy guards; do not link billing merely to make a test pass; complete #113/#133/#136 Functions, short-lived deploy authority, and provider isolation; prove test keys, sinks, exact marker readback, and rollback before broader end-to-end flows. | | RISK-011 | Local cancellation only changes Firestore; it does not expire the active Stripe Session. The webhook can later move a cancelled record back to paid. | Customers can pay a supposedly cancelled registration/order; capacity/inventory and support state diverge. | Add explicit cancellation saga with Stripe Session expiry and allowed-state transitions. | | RISK-012 | Repository source now denies every admitted positive late-registration amount before identifier/token allocation, registration writes, Stripe construction, or Product/Price/Payment Link calls, and the Admin screen exposes only the exact-zero compatibility path. Firebase deployment is unproven, and legacy reusable Payment Links may still exist. | Older deployed code or an existing link can still create unreconciled or repeated charges/Sessions for one logical registration. The exact-zero local record is also marked paid without Stripe and is not payment, free, comp, or membership authority. | Keep paid late registration unavailable; inventory, deactivate, and reconcile legacy links privately; then replace them with one-off idempotent Checkout Sessions through the normal registration/payment lifecycle. | | RISK-013 | The assessment baseline permitted Stripe promotions while Firestore stored base price. Repository source now disables promotion entry and automatic tax, requires a complete adjustment breakdown, and quarantines unknown or nonzero discount/tax/shipping amounts; deployment and provider state are unproven. | An older open Session, provider drift, skipped backend release, or later guard regression could still make reporting, refunds, and local payment confirmation disagree. | Privately inventory pre-change Sessions/provider settings, release through the protected gate, verify Firebase and Stripe separately, and keep every adjustment disabled until an approved authoritative model exists. | @@ -330,7 +330,7 @@ CI-001C1 [#667](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/667) estab CI-001D1 [#669](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/669) used only the club account and an explicitly named staging project for the one-time database provision and bounded Rules/index deploy. Firebase CLI 15.24.0 JSON account diagnostics can include token-bearing account objects; never run `firebase login:list --json` in CI, a captured terminal, an issue, or an AI transcript. Use non-token identity checks, revoke any accidentally exposed OAuth grant immediately, and prefer the protected keyless deployment path once #133 grants the exact reviewed staging roles. -CI-001D2 [#671](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/671) source permits only email/password Auth, keeps the unqualified Firebase alias in `demo-mprc-local`, and pins the provider command to `--only auth --project run-mprc-staging`. Its predeploy guard requires the exact quota project, declared club account, and a short-lived Firebase token while rejecting an ADC file override. The separate provider phase used exact merged source `42542303d043f87a8f1a04be2f0b4f2a88e0318c` and only `runmprc@gmail.com`. Readback proved password-required email/password, improved email privacy, only the two staging domains, no other provider, and instrumentless billing-disabled state. Disposable API and browser checks passed and cleaned Auth back to zero users without requesting email or SMS. This is not reusable deployment authority and does not prove Functions, App Check, role claims, private records, or production. +CI-001D2 [#671](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/671) source permits only email/password Auth, keeps the unqualified Firebase alias in `demo-mprc-local`, and pins the provider command to `--only auth --project run-mprc-staging`. Its predeploy guard requires the exact quota project, declared club account, and a short-lived Firebase token while rejecting an ADC file override. The separate provider phase used exact merged source `42542303d043f87a8f1a04be2f0b4f2a88e0318c` and only `runmprc@gmail.com`. Readback proved password-required email/password, improved email privacy, only the two staging domains, no other provider, and instrumentless billing-disabled state. Disposable API and browser checks passed and cleaned Auth back to zero users without requesting email or SMS. That Auth-only slice is not reusable deployment authority and did not itself prove Functions, App Check, role claims, private records, or production; #676 separately proves current staging App Check enforcement. ## 10. Incident response diff --git a/SYSTEM_DESIGN.md b/SYSTEM_DESIGN.md index 97e70fa..99a9401 100644 --- a/SYSTEM_DESIGN.md +++ b/SYSTEM_DESIGN.md @@ -277,7 +277,7 @@ Text alternative: exact reviewed source permits only a guarded Auth deployment t ## 4. Target deployment topology -The target keeps React, Firebase, and Stripe, but places stronger boundaries around them. Migrating the frontend from GitHub Pages/Netlify to Firebase Hosting is recommended before live commerce because it supports controlled SPA rewrites, preview channels, and security headers. #663 supplies the fail-closed build selector and inert Hosting rewrite configuration. #665 owns the isolated static staging host. CI-001C1 [#667](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/667) adds only a protected, read-only staging identity proof; it grants no Firebase deployment permission. CI-001D1 [#669](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/669) adds only the empty staging Firestore database and exact Rules/index boundary. CI-001D2 [#671](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/671) deploys and verifies the narrow email/password Auth configuration from exact merged source. CI-001D3 [#674](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/674) adds a source-only guard that can name only the two profile Functions in staging and cannot accept appended deployment arguments. CI-001D4 [#676](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/676) adds an independent, argument-closed staging Hosting path. Its source contract binds the exact club account, project, quota project, Hosting-only scope, short-lived token path, Firebase CLI 15.24.0, and a bounded non-placeholder Enterprise site key; the artifact verifier must find that key in executable JavaScript. After exact source `bce911a7083201cfe2141edaa9660f210287bf57` passed all five post-main jobs, the bounded provider checkpoint enabled only Firebase App Check and reCAPTCHA Enterprise, created one score-based key restricted to the two staging hosts, registered it to the one web app for one-hour tokens, and configured Authentication plus Firestore as `UNENFORCED` with replay protection off. The guarded Hosting path published that exact source as version `8556fc51210bdc66`; public root/direct Events, empty Firestore, layout, and browser warning/error checks passed. The instrumentless project remains unlinked from billing, with zero users and zero root collections, and no Functions-related API or deployed Function. The checkpoint does not yet prove the new disposable browser Auth flow, `ENFORCED` readback, missing-token denial, final token-bearing replay, reusable deployment authority, automatic release, rollback, headers, production protection, outside-provider isolation, or DNS/TLS cutover. Those remain separate work under #676/#113/#133/#136/#460; staging is not a complete backend merely because its monitoring layers exist. +The target keeps React, Firebase, and Stripe, but places stronger boundaries around them. Migrating the frontend from GitHub Pages/Netlify to Firebase Hosting is recommended before live commerce because it supports controlled SPA rewrites, preview channels, and security headers. #663 supplies the fail-closed build selector and inert Hosting rewrite configuration. #665 owns the isolated static staging host. CI-001C1 [#667](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/667) adds only a protected, read-only staging identity proof; it grants no Firebase deployment permission. CI-001D1 [#669](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/669) adds only the empty staging Firestore database and exact Rules/index boundary. CI-001D2 [#671](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/671) deploys and verifies the narrow email/password Auth configuration from exact merged source. CI-001D3 [#674](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/674) adds a source-only guard that can name only the two profile Functions in staging and cannot accept appended deployment arguments. CI-001D4 [#676](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/676) adds an independent, argument-closed staging Hosting path. Its source contract binds the exact club account, project, quota project, Hosting-only scope, short-lived token path, Firebase CLI 15.24.0, and a bounded non-placeholder Enterprise site key; the artifact verifier must find that key in executable JavaScript. After exact source `bce911a7083201cfe2141edaa9660f210287bf57` passed all five post-main jobs, the bounded provider phase enabled only Firebase App Check and reCAPTCHA Enterprise, created one score-based key restricted to the two staging hosts, registered it to the one web app for one-hour tokens, and published that exact source as Hosting version `8556fc51210bdc66`. A reserved-domain disposable browser identity proved create, sign-out, fresh sign-in, and post-enforcement sign-in; the token-bearing empty Events read remained successful signed in and signed out with no warning or error. Authentication plus Firestore now read `ENFORCED` with replay protection `OFF`; a valid-credential Auth request without App Check was rejected with HTTP 401, and the tokenless Firestore Events request was rejected with HTTP 403. Cleanup returned the instrumentless project to zero users and zero root collections. Billing remains disabled and no Functions-related API or deployed Function exists, so the account profile correctly remains fail-closed. Reusable deployment authority, automatic release, tested rollback, headers, production protection, outside-provider isolation, Functions, and DNS/TLS cutover remain separate work under #113/#133/#136/#460; staging is not a complete member backend merely because Auth, Firestore, and App Check are protected. ```mermaid flowchart TB @@ -1783,7 +1783,7 @@ Text alternative: the local browser uses only the three loopback Firebase emulat #99 source selects a fully synthetic Firebase configuration for development/test, connects Auth, Firestore, and Functions to the loopback ports above, stops startup when connection setup fails, and leaves App Check, Analytics, and Sentry off locally. #139 additionally keeps Firebase Analytics off in every source environment and removes the direct Waiver SDK bypass pending an approved #110 policy. The Firebase CLI must still report all three emulators ready before the app is opened. Mocked endpoint tests alone do not prove listening processes, website publication, provider behavior, or deletion of earlier provider data/cookies. -Optimized builds must select `staging` or `production` explicitly. WEB-001A1 #663 rejects missing, local, incomplete, or cross-environment Firebase web configuration, and its artifact check rejects known production identities from a staging executable. Ordinary Netlify deploy previews receive and scan only the reserved synthetic configuration; `run-mprc-staging.web.app` receives and scans the real isolated staging web-app identity; the pinned release builder receives and scans the exact reviewed public production web configuration. The owned staging project now has an empty Rules-protected Firestore boundary and verified password-required email/password Auth with improved email privacy. #671's disposable API and browser checks returned the project to zero users and records. #674 narrows the future manual Function command to both profile Functions together, but billing is unapproved and no Function is deployed. The project still lacks Functions, App Check, and outside-provider isolation. Netlify previews remain public, signed-out, read-only visual review only; the Firebase staging host permits only issue-scoped disposable engineering checks until #105/CONFIG supplies complete backend/provider evidence. Never use a real identity, private/admin record, or outside-provider action there. +Optimized builds must select `staging` or `production` explicitly. WEB-001A1 #663 rejects missing, local, incomplete, or cross-environment Firebase web configuration, and its artifact check rejects known production identities from a staging executable. Ordinary Netlify deploy previews receive and scan only the reserved synthetic configuration; `run-mprc-staging.web.app` receives and scans the real isolated staging web-app identity; the pinned release builder receives and scans the exact reviewed public production web configuration. The owned staging project now has an empty Rules-protected Firestore boundary, verified password-required email/password Auth with improved email privacy, and App Check enforced for Auth plus Firestore. #671's disposable API/browser checks and #676's browser/denial/enforcement checks each returned the project to zero users and records. #674 narrows the future manual Function command to both profile Functions together, but billing is unapproved and no Function is deployed. The project still lacks Functions and outside-provider isolation. Netlify previews remain public, signed-out, read-only visual review only; the Firebase staging host permits only issue-scoped disposable engineering checks until #105/CONFIG supplies complete backend/provider evidence. Never use a real identity, private/admin record, or outside-provider action there. `SITE_ORIGIN`, Firebase project IDs, App Check keys, Stripe keys, webhook endpoints, Sentry environments, and email providers must be environment-scoped. Live and test webhook secrets are never interchangeable. `run-mprc-staging` now supplies the public web app, Hosting, empty Firestore Rules/index boundary, and deployed/verified narrow Auth boundary. The #674 source guard is not a hosted backend. End-to-end rollout still needs approved billing, Functions, App Check, deployment authority, and outside-provider configuration and evidence. diff --git a/docs/officers/PUBLISH_AND_CHECK.md b/docs/officers/PUBLISH_AND_CHECK.md index ea6412d..3c0f378 100644 --- a/docs/officers/PUBLISH_AND_CHECK.md +++ b/docs/officers/PUBLISH_AND_CHECK.md @@ -10,7 +10,7 @@ **Protected release status:** **NOT AVAILABLE YET.** Issue #135 provides the fail-closed source gate. Issue #133 must still configure protected `staging` and `production` environments, their named reviewers, and a short-lived cloud identity. Public browser build values must be named repository or organization variables because artifact preparation has no protected-environment access; #133/#136 must record and verify them separately. Do not add a long-lived Firebase key as a shortcut. -**Firebase staging status:** **STATIC HOSTING, EMPTY FIRESTORE, DISPOSABLE EMAIL/PASSWORD AUTH PROOF, AND APP CHECK MONITORING ARE AVAILABLE; ENFORCEMENT, FUNCTIONS, OFFICER OPERATION, AND PRODUCTION RELEASE ARE NOT AVAILABLE YET.** WEB-001A1 [#663](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/663) requires controlled optimized builds to name staging or production and scans executable JavaScript for environment identity. WEB-001A2 [#665](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/665) created the club-owned `run-mprc-staging` project. CI-001D1 [#669](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/669) adds an empty delete-protected Firestore database and exact reviewed Rules/indexes; fixed anonymous server-only reads were denied and the root collection count remained zero. CI-001D2 [#671](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/671) deploys password-required email/password Auth from exact merged source, verifies provider/privacy/domain settings, passes disposable API/browser sign-in checks, and returns the project to zero users and records. CI-001D3 [#674](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/674) adds only a fail-closed code guard for the future paired profile Functions; billing remains unapproved and no Function is live. CI-001D4 [#676](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/676) merged its separate staging Hosting guard through [PR #677](https://github.com/Run-MPRC/Run-MPRC.github.io/pull/677), then configured one score-based App Check key restricted to the two staging hosts, one matching web-app registration with one-hour tokens, and Authentication plus Firestore monitoring with replay protection off. Exact merged source `bce911a7083201cfe2141edaa9660f210287bf57` is live as Hosting version `8556fc51210bdc66`; public root/direct Events, empty Firestore/UI, layout, and browser warning/error checks passed. Officers do not sign in, enter information, run commands, configure App Check, attach billing, or use the site as a publish control. The new disposable browser Auth proof, App Check `ENFORCED` readback, missing-token denial, token-bearing replay, provider sandbox, protected short-lived publication, release marker, tested rollback, complete security headers, custom domain, and DNS/TLS change remain **NOT AVAILABLE YET**. Billing is disabled, users and root collections are zero, no Functions-related API or Function exists, production Firebase Hosting remains empty, and Netlify still serves `runmprc.com`. +**Firebase staging status:** **STATIC HOSTING, EMPTY FIRESTORE, DISPOSABLE EMAIL/PASSWORD AUTH PROOF, AND APP CHECK ENFORCEMENT FOR AUTHENTICATION PLUS FIRESTORE ARE AVAILABLE; FUNCTIONS, OFFICER OPERATION, AND PRODUCTION RELEASE ARE NOT AVAILABLE YET.** WEB-001A1 [#663](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/663) requires controlled optimized builds to name staging or production and scans executable JavaScript for environment identity. WEB-001A2 [#665](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/665) created the club-owned `run-mprc-staging` project. CI-001D1 [#669](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/669) adds an empty delete-protected Firestore database and exact reviewed Rules/indexes; fixed anonymous server-only reads were denied and the root collection count remained zero. CI-001D2 [#671](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/671) deploys password-required email/password Auth from exact merged source, verifies provider/privacy/domain settings, passes disposable API/browser sign-in checks, and returns the project to zero users and records. CI-001D3 [#674](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/674) adds only a fail-closed code guard for the future paired profile Functions; billing remains unapproved and no Function is live. CI-001D4 [#676](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/676) merged its separate staging Hosting guard through [PR #677](https://github.com/Run-MPRC/Run-MPRC.github.io/pull/677), then configured one score-based App Check key restricted to the two staging hosts, one matching web-app registration with one-hour tokens, and exact source `bce911a7083201cfe2141edaa9660f210287bf57` as Hosting version `8556fc51210bdc66`. Authentication plus Firestore now read `ENFORCED` with replay protection `OFF`. A made-up browser account passed create, sign-out, fresh sign-in, and post-enforcement sign-in; signed-in and signed-out empty Events reads passed; tokenless Auth and Firestore requests were denied; and cleanup returned users plus root collections to zero. Officers do not sign in, enter information, run commands, configure App Check, attach billing, or use the site as a publish control. Provider sandboxes, protected short-lived publication, release marker, tested rollback, complete security headers, custom domain, and DNS/TLS change remain **NOT AVAILABLE YET**. Billing is disabled, no Functions-related API or Function exists, the account profile fails closed while Functions are absent, production Firebase Hosting remains empty, and Netlify still serves `runmprc.com`. **Live Netlify publication status:** a reusable protected release is **NOT AVAILABLE YET**. Ordinary Git-triggered production builds are paused by repository configuration. An overbroad #473 artifact was published and then rolled back on 2026-08-01; bounded #473 deploy `6a6dc9ea588b0c0008036312` is older history. #623 completed the inert-directory predecessor and remains the immediate rollback as deploy `6a7e072f8f346b0008510d29`, source `c2d87d1f69f15e128a0bc9b1b9f915b7c8417aec`. #659 completed one separate exact-artifact accessibility release. Deploy `6a7ece87c5ca4d0007c1a3fc`, source `7496fe0881fb52908c4ff2f40f488df09c94c908`, is production now. Its exact marker/artifact and signed-out route-focus/menu checks passed. The manifest is inactive, temporary refs are absent, and the rollback ref remains. Shop is the static catalog; Events and Calendar show a fixed retry-later notice; the directory remains inert. Event records remain unavailable because this did not deploy Firebase. GitHub Pages currently still claims the same custom domain; future source omits that claim, but #136/WEB-001 must publish and verify its removal. @@ -57,13 +57,13 @@ As of **2026-07-13**, with the internal tooling note below checked from source o - The separate #667 staging verifier uses a short-lived cloud identity after named approval. That identity can read only the staging project identity. The backend release still has no deployment authority. The website job receives public browser values only. - #669 used one bounded maintainer operation to provision empty staging Firestore and deploy exact Rules/indexes. It did not give the #667 identity or the general release workflow a deploy role. - #674 adds an argument-closed source wrapper for exactly `createMemberOnSignUp` and `ensureMemberProfile`. Its tests and merge are not Function deployment evidence. Billing approval, API enablement, App Check, provider readback, and synthetic profile proof remain separate. -- #676 adds a separate argument-closed source wrapper for Hosting only. It requires exact staging identity, the club account, short-lived token path, pinned CLI, and one bounded Enterprise public key in the executable artifact. The provider checkpoint has now registered one restricted key, published exact source `bce911a7083201cfe2141edaa9660f210287bf57` as Hosting version `8556fc51210bdc66`, and placed Auth plus Firestore in monitoring mode. That checkpoint is not `ENFORCED` readback, missing-token denial, or final token-bearing browser evidence. +- #676 adds a separate argument-closed source wrapper for Hosting only. It requires exact staging identity, the club account, short-lived token path, pinned CLI, and one bounded Enterprise public key in the executable artifact. Provider and browser evidence now proves one restricted key, exact source `bce911a7083201cfe2141edaa9660f210287bf57` as Hosting version `8556fc51210bdc66`, Auth plus Firestore `ENFORCED` with replay protection `OFF`, tokenless denial, token-bearing browser success, and cleanup to zero. - The Firebase CLI comes from the committed lockfile. The release does not install `latest`. - Source checked on 2026-07-22 pins the internal Firebase CLI to 15.24.0, and its emulator checks use Java 21. Officers do not install or run either tool; the platform maintainer owns them. This source change does not alter the release diagram or prove that Firebase was deployed. The provider and live-host facts below were not reverified for this tooling update. - Source checked on 2026-08-01 pins every root brace-expansion dependency family to reviewed compatible releases 1.1.18, 2.1.4, and 5.0.9 after a new advisory and follow-up bypass fixes. This is internal dependency evidence only. Officers do not install packages, run audit commands, or resolve dependency warnings; the platform maintainer owns those tasks. The separate minimatch finding remains open. This source change does not publish a website, deploy Firebase, change a provider, or prove live behavior. - A production Pages publication job cannot start until Firebase deployment and Function verification succeed. -- The club-owned `run-mprc-staging` project supplies one signed-out Hosting surface, one empty Firestore boundary, narrow email/password Auth, and an App Check monitoring checkpoint. Current Hosting is exact source `bce911a7083201cfe2141edaa9660f210287bf57`, version `8556fc51210bdc66`; direct `/events`, empty Firestore/UI, and browser warning/error checks passed. Its Rules/index release comes from exact source `ee16bd16220ab58bd3a2add80dd2f39a1d514dd7`; the 418-case emulator suite, provider definition match, fixed anonymous denial probes, and zero-root-collection readback passed. -- #663 source requires complete staging-named public browser configuration and gives CI a synthetic staging artifact scan. #665 proves the staging host. #667 adds a protected read-only identity check, not Firebase deployment authority. #669 proves the empty Firestore Rules/index boundary. #671 proves the narrow Auth configuration and one earlier disposable lifecycle. #676 now proves provider registration, exact Hosting publication, and monitoring settings only. These slices do not supply Functions, App Check enforcement/denial/replay evidence, outside-provider isolation, a release marker, predecessor rollback, or permission to test real/private/admin/commerce behavior. +- The club-owned `run-mprc-staging` project supplies one signed-out Hosting surface, one empty Firestore boundary, narrow email/password Auth, and enforced App Check for Auth plus Firestore. Current Hosting is exact source `bce911a7083201cfe2141edaa9660f210287bf57`, version `8556fc51210bdc66`; direct `/events`, disposable Auth, tokenless denial, token-bearing browser behavior, and zero-count cleanup passed. Its Rules/index release comes from exact source `ee16bd16220ab58bd3a2add80dd2f39a1d514dd7`; the 418-case emulator suite, provider definition match, fixed anonymous denial probes, and zero-root-collection readback passed. +- #663 source requires complete staging-named public browser configuration and gives CI a synthetic staging artifact scan. #665 proves the staging host. #667 adds a protected read-only identity check, not Firebase deployment authority. #669 proves the empty Firestore Rules/index boundary. #671 proves the narrow Auth configuration and one earlier disposable lifecycle. #676 proves provider registration, exact Hosting publication, `ENFORCED`/replay-`OFF` readback, tokenless denial, token-bearing browser success, and cleanup. These slices do not supply Functions, outside-provider isolation, a release marker, predecessor rollback, or permission to test real/private/admin/commerce behavior. - `runmprc.com` is served by Netlify, not GitHub Pages. - GitHub Pages currently reports `runmprc.com` as its custom domain and redirects its normal address there. It is not an independently reachable copy today. - Future source stops writing that Pages domain claim. Only provider readback after #136/WEB-001 can prove it cleared. @@ -530,13 +530,13 @@ Text alternative: exact reviewed source and a narrow club-account Auth operation **Escalation:** platform owner first, security owner second. Use the private incident path if a real or unexpected account, provider, billing link, record, or credential-shaped output appears. -## Review the staging App Check monitoring checkpoint — AVAILABLE; ENFORCEMENT NOT AVAILABLE YET +## Review staging App Check enforcement — AVAILABLE AFTER #676 -**Purpose:** let a backup officer confirm the current #676 provider and Hosting checkpoint, and distinguish monitoring from enforcement, without signing in, running a command, or handling a key or credential. +**Purpose:** let a backup officer confirm the current #676 provider, Hosting, enforcement, denial, browser, and cleanup evidence without signing in, running a command, or handling a key or credential. **Approver:** platform owner plus the named security reviewer for #676. -**Prerequisites:** issue #676; merged source PR #677; exact merge `bce911a7083201cfe2141edaa9660f210287bf57`; all five successful jobs in exact-main CI run `33018136439`; the redacted provider checkpoint; and an issue statement that enforcement/browser completion is still pending. +**Prerequisites:** issue #676 and its completion evidence; merged source PR #677; exact merge `bce911a7083201cfe2141edaa9660f210287bf57`; all five successful jobs in exact-main CI run `33018136439`; and the redacted final provider/browser record. ```mermaid flowchart LR @@ -544,32 +544,35 @@ flowchart LR Guard --> Artifact["Bounded Enterprise public key\nmust appear in built JavaScript"] Artifact --> Provider["One score key; two staging hosts;\none-hour web-app registration"] Provider --> Hosting["Exact source bce911a7\nHosting version 8556fc51210bdc66"] - Provider --> Monitor["Auth + Firestore UNENFORCED;\nreplay protection off"] + Provider --> Enforce["Auth + Firestore ENFORCED;\nreplay protection OFF"] Hosting --> Public["Root and Events 200; empty UI;\nno browser warning or error"] - Monitor -. "Disposable Auth, ENFORCED,\nmissing-token and replay proof pending" .-> Pending["Do not call protected yet"] + Enforce --> Deny["Tokenless Auth 401;\ntokenless Firestore 403"] + Enforce --> Browser["Disposable create/sign-out/sign-in;\ntoken-bearing Events passed"] + Browser --> Cleanup["Identity deleted; users and\nroot collections zero"] + Cleanup -. "Functions and private flows absent" .-> Pending["Do not call complete backend"] Broad["Branch deploy, broad scope, debug token,\nbilling, production, or real data"] --> Stop["Stop"] ``` -Text alternative: exact merged source passed the staging-only guard, one restricted provider key was registered and published in one exact Hosting version, and Auth plus Firestore now monitor requests; enforcement, denial, and the new disposable browser Auth proof remain pending, while broad scope, debug tokens, billing, production, and real data stop. +Text alternative: exact merged source passed the staging-only guard, one restricted provider key was published in one exact Hosting version, Auth plus Firestore enforce App Check, tokenless requests were denied, genuine browser requests passed, and cleanup returned both counts to zero; Functions, billing, production, broad scope, debug tokens, and real data still stop. 1. Open issue [#676](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/676) and source [PR #677](https://github.com/Run-MPRC/Run-MPRC.github.io/pull/677). 2. Confirm exact merge `bce911a7083201cfe2141edaa9660f210287bf57` and all five successful jobs in CI run `33018136439` are recorded before the provider checkpoint. 3. Confirm the guard names only `run-mprc-staging`, `runmprc@gmail.com`, Hosting scope, and Firebase CLI 15.24.0. 4. Confirm the redacted provider evidence says exactly one score-based key, exactly the two staging hosts, one matching web app, and a one-hour token lifetime. It must not contain a key or provider locator. 5. Confirm the guarded release names exact source `bce911a7083201cfe2141edaa9660f210287bf57`, Hosting version `8556fc51210bdc66`, 61 files, and artifact-manifest SHA-256 `157e2048aa86d45cec1111e091643870d18ced808ef88d610ec70aae1bbe1ace`. -6. Confirm root and direct Events returned 200, the empty Events state rendered, the 1280-by-720 layout was intact, and browser warnings/errors were absent. -7. Confirm Authentication and Firestore still read `UNENFORCED`, replay protection is off, users and root collections are zero, billing is disabled, and no Functions-related API or Function exists. -8. Confirm the new disposable browser Auth proof, `ENFORCED` readback, missing-token denial, token-bearing replay, final cleanup, and completion evidence remain pending. +6. Confirm the made-up browser identity completed create, sign-out, fresh sign-in, and post-enforcement sign-in, and that signed-in plus signed-out empty Events reads succeeded without warnings/errors. +7. Confirm tokenless Auth returned HTTP 401 and tokenless Firestore returned HTTP 403 while the genuine browser path continued to work. +8. Confirm Authentication and Firestore read `ENFORCED`, replay protection reads `OFF`, users and root collections are zero, billing is disabled, and no Functions-related API or Function exists. 9. Confirm production Firebase Hosting, `runmprc.com`, Netlify, DNS, and production data are unchanged. 10. Record the issue, pull request, exact merge, CI run, Hosting version, approver, and check date. Do not paste a key, provider locator, token, account response, user identifier, or private screenshot. -**Expected result:** a backup officer can verify that the provider and exact Hosting revision are live in monitoring mode while correctly reporting that App Check enforcement and the new browser Auth/denial/replay proof are not available yet. +**Expected result:** a backup officer can verify that Auth and Firestore enforce App Check in engineering staging while correctly reporting that Functions, private flows, and production are not available yet. -**Stop conditions:** stop if the source or evidence names another account/project, permits more than Hosting, asks for a credential/debug token, reveals a key or user identifier, links billing, changes production, uses real data, differs from the exact provider/Hosting/count readback, or calls monitoring enforced/protected. +**Stop conditions:** stop if the source or evidence names another account/project, permits more than Hosting, asks for a credential/debug token, reveals a key or user identifier, links billing, changes production, uses real data, differs from the exact provider/Hosting/count readback, or claims Functions/private behavior from App Check evidence. -**Success proof:** keep #676, PR #677, exact merge, exact-main CI link, source-test summary, redacted provider settings, Hosting version, public browser result, zero-count/billing/Functions readback, named approver, check date, and explicit enforcement/browser states still pending. +**Success proof:** keep #676, PR #677, exact merge, exact-main CI link, source-test summary, redacted provider settings, Hosting version, disposable browser lifecycle, tokenless denial, token-bearing Events result, zero-count/billing/Functions readback, named approver, and check date. -**Undo:** while services remain `UNENFORCED`, stop staging sign-in use and open one reviewed issue for the platform/security owners. If a later enforcement attempt breaks the browser, the platform maintainer atomically returns both Authentication and Firestore to `UNENFORCED`, verifies that readback, and preserves the restricted provider configuration for diagnosis. Do not ask an officer to edit provider settings or delete the project. +**Undo:** stop staging sign-in use and open one urgent reviewed issue for the platform/security owners. Only if they approve a rollback may the platform maintainer atomically return both Authentication and Firestore to `UNENFORCED`, verify that readback, and preserve the restricted provider configuration for diagnosis. Do not ask an officer to edit provider settings or delete the project. **Escalation:** platform owner first, security owner second. Use the private incident path for credential-shaped output, a key/user identifier in public evidence, or an unexpected provider, account, project, deployment, billing, user, record, or enforcement change. diff --git a/docs/officers/README.md b/docs/officers/README.md index e664333..b5ea416 100644 --- a/docs/officers/README.md +++ b/docs/officers/README.md @@ -69,7 +69,7 @@ WEB-002D [#659](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/659) compl The general protected GitHub release is still **NOT AVAILABLE YET**. #667 configures only a separate staging read-only identity check: Dave Liu or Jeff Chang reviews exact `main`, and a keyless five-minute identity may read only the staging project identity. It cannot deploy Firebase or publish a website. #133 still owns backend deployment roles and production protection. Missing authority stops the release with a red failure before Firebase or website publication. -The empty staging Firestore boundary is available after #669. Project `run-mprc-staging` has a delete-protected empty database with the exact reviewed Rules and indexes. Fixed signed-out requests to server-only paths were denied, and the final root collection count was zero. #671 deploys and verifies password-required email/password Auth from exact merged source. Improved email privacy is on; only the two staging domains are authorized; every other provider is absent; billing is disabled; disposable API/browser checks passed; and cleanup returned Auth and Firestore to zero users/records. #674 adds a code guard for a future deployment of only the two profile Functions; no Function or related API is live because billing remains unapproved. #676 has configured one restricted score-based App Check provider, registered it to the one staging web app for one-hour tokens, published exact merged source `bce911a7083201cfe2141edaa9660f210287bf57` as Hosting version `8556fc51210bdc66`, and placed Authentication plus Firestore in monitoring mode with replay protection off. Public Hosting and empty Firestore/UI checks passed. This is not a usable member backend: the new disposable browser Auth proof, `ENFORCED` readback, missing-token denial, token-bearing replay, Functions, provider sandboxes, reusable deployment authority, role/private-data proof, and officer operation remain **NOT AVAILABLE YET**. Officers do not sign in, enter records, run commands, edit the database, deploy Auth/Hosting, configure App Check, or attach billing. Use the no-terminal [staging Firestore review](./PUBLISH_AND_CHECK.md#review-the-empty-staging-firestore-boundary--available-after-669), [staging Auth review](./PUBLISH_AND_CHECK.md#review-the-staging-auth-boundary--available-after-671), and [App Check monitoring review](./PUBLISH_AND_CHECK.md#review-the-staging-app-check-monitoring-checkpoint--available-enforcement-not-available-yet). +The empty staging Firestore boundary is available after #669. Project `run-mprc-staging` has a delete-protected empty database with the exact reviewed Rules and indexes. Fixed signed-out requests to server-only paths were denied, and the final root collection count was zero. #671 deploys and verifies password-required email/password Auth from exact merged source. Improved email privacy is on; only the two staging domains are authorized; every other provider is absent; billing is disabled; disposable API/browser checks passed; and cleanup returned Auth and Firestore to zero users/records. #674 adds a code guard for a future deployment of only the two profile Functions; no Function or related API is live because billing remains unapproved. #676 configured one restricted score-based App Check provider, registered it to the one staging web app for one-hour tokens, published exact merged source `bce911a7083201cfe2141edaa9660f210287bf57` as Hosting version `8556fc51210bdc66`, and set Authentication plus Firestore to `ENFORCED` with replay protection `OFF`. A made-up browser account proved create, sign-out, fresh sign-in, post-enforcement sign-in, and signed-in/signed-out empty Events reads; tokenless Auth and Firestore requests were denied, and cleanup returned users and root collections to zero. This is still not a usable member backend: Functions, provider sandboxes, reusable deployment authority, role/private-data proof, and officer operation remain **NOT AVAILABLE YET**, and the account profile fails closed while Functions are absent. Officers do not sign in, enter records, run commands, edit the database, deploy Auth/Hosting, configure App Check, or attach billing. Use the no-terminal [staging Firestore review](./PUBLISH_AND_CHECK.md#review-the-empty-staging-firestore-boundary--available-after-669), [staging Auth review](./PUBLISH_AND_CHECK.md#review-the-staging-auth-boundary--available-after-671), and [App Check enforcement review](./PUBLISH_AND_CHECK.md#review-staging-app-check-enforcement--available-after-676). GitHub Pages currently still claims `runmprc.com`, so its normal address redirects to the Netlify-served name. The source stops adding that claim, but #136/WEB-001 must publish and verify the provider setting before officers call Pages an independent copy. diff --git a/docs/officers/SYSTEM_MAPS.md b/docs/officers/SYSTEM_MAPS.md index 74ee333..5f3b1f9 100644 --- a/docs/officers/SYSTEM_MAPS.md +++ b/docs/officers/SYSTEM_MAPS.md @@ -94,10 +94,13 @@ flowchart TD Main --> AppCheckGuard["#676 staging Hosting/App Check\nsource guard"] AppCheckGuard --> AppCheckProvider["One score key; two staging hosts;\none-hour web-app registration"] AppCheckProvider --> AppCheckHosting["Exact bce911a7 Hosting\nversion 8556fc51210bdc66"] - AppCheckProvider --> AppCheckMonitor["Auth + Firestore UNENFORCED\nreplay protection off"] + AppCheckProvider --> AppCheckEnforce["Auth + Firestore ENFORCED\nreplay protection OFF"] AppCheckHosting --> AppCheckPublicProof["Root and Events 200; empty UI;\nno browser warning or error"] - AppCheckMonitor -. "Disposable Auth, ENFORCED, missing-token,\nand token-bearing replay pending" .-> Stop - AuthProof -. "No Functions, new App Check Auth proof, real identity, or records" .-> Stop + AppCheckEnforce --> AppCheckDeny["Tokenless Auth 401;\ntokenless Firestore 403"] + AppCheckEnforce --> AppCheckBrowser["Disposable browser Auth;\ntoken-bearing Events passed"] + AppCheckBrowser --> AppCheckCleanup["Identity deleted; users and\nroot collections zero"] + AppCheckCleanup -. "No Functions, real identity,\nprivate flows, or records" .-> Stop + AuthProof -. "No Functions, real identity, or records" .-> Stop StagingHosting -. "No complete backend/provider test estate, protected deploy authority, marker, or rollback" .-> Stop HostingSource -. "Production branch, headers, authority, and cutover missing" .-> FutureHosting["Production Firebase Hosting — NOT AVAILABLE YET"] Main -. "Completed #659 exact release; manifest inactive" .-> WebGate{"Temporary authority active?"} @@ -108,7 +111,7 @@ flowchart TD Dev["dev — legacy branch"] -. "do not use for new release work" .-> PR ``` -In words: merge, release request, and protected approval are separate; #663 supplies build checks, #665 publishes the club-owned engineering staging site, and #671 deploys only narrow email/password Auth after exact-main review. Its earlier disposable identities were removed. #676 now adds one restricted score-based provider registration, publishes exact source `bce911a7` as Hosting version `8556fc51210bdc66`, and places Auth plus Firestore in monitoring mode; public Hosting and empty Firestore/UI checks passed. That checkpoint is not the new disposable Auth proof, enforcement/readback, missing-token denial, or token-bearing replay, and the current boundary still supplies no Functions, real identity/private-data testing, production release, or reusable authority. Ordinary merges cannot publish Netlify and the completed #659 exception is inactive; its deploy `6a7ece87c5ca4d0007c1a3fc` remains live while completed #623 deploy `6a7e072f8f346b0008510d29` is the immediate rollback and completed #473 deploy `6a6dc9ea588b0c0008036312` is older history; the future Pages branch must stop claiming the Netlify domain, and every host still needs separate proof. +In words: merge, release request, and protected approval are separate; #663 supplies build checks, #665 publishes the club-owned engineering staging site, and #671 deploys only narrow email/password Auth after exact-main review. Its earlier disposable identities were removed. #676 adds one restricted score-based provider registration, publishes exact source `bce911a7` as Hosting version `8556fc51210bdc66`, and sets Auth plus Firestore to `ENFORCED` with replay protection `OFF`; tokenless Auth/Firestore requests were denied, genuine browser Auth/Events passed, and cleanup returned users and root collections to zero. The current boundary still supplies no Functions, real identity/private-data testing, production release, or reusable authority. Ordinary merges cannot publish Netlify and the completed #659 exception is inactive; its deploy `6a7ece87c5ca4d0007c1a3fc` remains live while completed #623 deploy `6a7e072f8f346b0008510d29` is the immediate rollback and completed #473 deploy `6a6dc9ea588b0c0008036312` is older history; the future Pages branch must stop claiming the Netlify domain, and every host still needs separate proof. ## Account and permission ownership