Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ jobs:
ruby -e 'require "yaml"; YAML.safe_load(File.read(".github/workflows/deploy.yml"), permitted_classes: [], permitted_symbols: [], aliases: true)'
ruby -e 'require "yaml"; YAML.safe_load(File.read(".github/workflows/verify-staging-authority.yml"), permitted_classes: [], permitted_symbols: [], aliases: true)'
ruby -e 'require "yaml"; YAML.safe_load(File.read(".github/workflows/verify-staging-profile-authority.yml"), permitted_classes: [], permitted_symbols: [], aliases: true)'
ruby -e 'require "yaml"; YAML.safe_load(File.read(".github/workflows/deploy-staging-profiles.yml"), permitted_classes: [], permitted_symbols: [], aliases: true)'
ruby -e 'require "yaml"; YAML.safe_load(File.read(".github/workflows/ci.yml"), permitted_classes: [], permitted_symbols: [], aliases: true)'
node --test tests/ci-workflow.test.js tests/release-workflow.test.js tests/firebase-release-verification.test.js tests/firebase-hosting-foundation.test.js tests/firebase-auth-staging-contract.test.js tests/firebase-profile-functions-staging-contract.test.js tests/staging-authority-workflow.test.js tests/staging-profile-authority.test.js tests/test-artifact-safety.test.js tests/root-dependency-security.test.js
- name: Build
Expand Down
53 changes: 53 additions & 0 deletions .github/workflows/deploy-staging-profiles.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
name: Deploy two staging profile Functions

on:
workflow_dispatch:

permissions: {}

concurrency:
group: staging-profile-release
cancel-in-progress: false

jobs:
deploy-profiles:
name: Deploy and verify only two staging profile Functions
runs-on: ubuntu-latest
timeout-minutes: 35
environment:
name: backend-staging
permissions:
contents: read
actions: read
id-token: write
env:
TARGET_ENVIRONMENT: backend-staging
TARGET_PROJECT_ID: ${{ vars.FIREBASE_PROJECT_ID }}
DEPLOY_SERVICE_ACCOUNT: ${{ secrets.GCP_DEPLOY_SERVICE_ACCOUNT }}
WORKLOAD_IDENTITY_PROVIDER: ${{ secrets.GCP_WORKLOAD_IDENTITY_PROVIDER }}
GH_TOKEN: ${{ github.token }}
steps:
- name: Check out exact source without persisted credentials
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
with:
persist-credentials: false
- name: Set up reviewed Node runtime
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
with:
node-version: '22'
- name: Verify exact green main before cloud authentication
run: node scripts/staging-profile-release.js context
- id: auth
name: Obtain bounded keyless staging release identity
uses: google-github-actions/auth@7c6bc770dae815cd3e89ee6cdf493a5fab2cc093 # v3
with:
token_format: access_token
access_token_lifetime: 1800s
create_credentials_file: false
export_environment_variables: false
workload_identity_provider: ${{ secrets.GCP_WORKLOAD_IDENTITY_PROVIDER }}
service_account: ${{ secrets.GCP_DEPLOY_SERVICE_ACCOUNT }}
- name: Deploy only reviewed profile bundle and verify resource settings
env:
GCP_ACCESS_TOKEN: ${{ steps.auth.outputs.access_token }}
run: node scripts/staging-profile-release.js release
2 changes: 2 additions & 0 deletions GITHUB_ISSUES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# GitHub Issue Backlog: Secure Commerce Program

**CI-001C4 / #701 (2026-10-11):** scoped staging runtime/build permissions and protected deployment/hosted proof of `createMemberOnSignUp` and `ensureMemberProfile`. Production data, payments, website publication and parent #113/#133/#136 remain outside this slice. Initial baseline has no Functions. No schema/claims migration; create-once profiles remain unchanged. Source preparation is not hosted completion. Officer impact: staged profile readiness with normal approval and administrator bypass disabled. Officer documentation: ACCESS_CONTINUITY, LOW_COST_COMMUNITY, SYSTEM_MAPS and entrypoints. Deployment evidence: pending exact source, provider readback and made-up hosted checks on the native issue.

**Prepared:** 2026-07-12
**Status:** Dated design/assessment catalog; GitHub is canonical for execution
**Execution model:** One focused issue per branch/pull request
Expand Down
2 changes: 1 addition & 1 deletion OFFICER_START_HERE.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Attach the exact wording, public link, or approved photo when you have it. The A

## Choose the closest task

**Focused authority step, 2026-10-11:** [#699](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/699) keeps backend preparation limited to staging profile setup. Production still names Dave and main, but administrator bypass is allowed again by Dave's instruction. A separate `backend-staging` identity check reads only project/access metadata and deploys nothing. See [the short authority procedure](./docs/officers/ACCESS_CONTINUITY.md#scoped-staging-profile-authority--699). It is **NOT AVAILABLE YET** until #699 records its merged source and protected proof. Member/payment operation remains unavailable; no officer handles a key or member record.
**Focused staging release, 2026-10-11:** [#699](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/699) completed its protected identity proof. [#701](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/701) separately prepares two staging profile Functions and made-up hosted tests. Dave chose disabled administrator bypass for production/backend-staging; normal self-approval remains. Original read-only staging is unchanged. Follow [the staging procedure](./docs/officers/LOW_COST_COMMUNITY.md#engineering-staging-profiles--701), **NOT AVAILABLE YET** until #701 records hosted proof. Production/payments remain unavailable; no officer handles a key or record.

**Backend ownership, 2026-10-11:** Dave approved continuing without a backup owner under [#697](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/697). Dave remains the sole backend release/recovery approver; backup coverage is absent, not complete. This removes only the backup-appointment gate. Protected deployment, staging proof, rollback and all data/payment approvals remain required. See [the sole-owner procedure](./docs/officers/ACCESS_CONTINUITY.md#sole-owner-backend-exception--approved-october-11-2026); no officer handles keys or runs commands.

Expand Down
2 changes: 2 additions & 0 deletions OPERATIONS_RUNBOOK.md
Original file line number Diff line number Diff line change
Expand Up @@ -730,6 +730,8 @@ CI/staging must eventually include:

For expand-and-contract changes:

**Isolated staging profiles (#701):** a separate manual `deploy-staging-profiles.yml` requires exact green main, normal backend-staging approval and thirty-minute keyless credentials. The v1 Functions API selects explicit runtime/build accounts, avoiding Firebase CLI default-account checks and unavailable custom v1 build-account selection. A deterministic ten-file bundle changes only the package entrypoint to `profileOnly.js`, keeping the reviewed dependencies/lockfile and profile logic. No prototype index or payment/mail endpoint is shipped. Runtime permissions: Auth user get, Firestore document get/create and begin/rollback transaction. These are staging project IAM, not collection rules. Build access: source-object read, one image repository write and logs. ActAs is granted only on the two exact staging accounts. Google auto-created a default App Engine Editor grant during API activation; #701 removes that new grant and never selects the account. Initial baseline is no Functions; reviewed roll-forward is preferred, and exact-owned two-Function removal requires Dave/specialist recovery authority, not the deploy principal. No schema migration or production changes. Source/CI/provider/hosted proof remain separate; #113/#133/#136 stay open. See the [officer procedure](./docs/officers/LOW_COST_COMMUNITY.md#engineering-staging-profiles--701).

1. Backup/export or snapshot the affected operational data according to the approved method.
2. Deploy additive indexes/rules/backend functions compatible with the current client.
3. Run migrations/backfills in dry-run mode; review counts and anomalies.
Expand Down
14 changes: 7 additions & 7 deletions docs/officers/ACCESS_CONTINUITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,33 +134,33 @@ Text alternative: the platform maintainer requests the exact verifier from `main
### Scoped staging profile authority — #699

**Purpose:** check the separate profile-release identity without deploying a backend or reading member data.
**Approver:** Dave Liu. Administrator bypass is allowed; record any use as an override rather than claiming Dave reviewed the run.
**Approver:** Dave Liu. #701 disabled administrator bypass for production and backend-staging. Dave can approve his own release through the normal gate. Original read-only staging is unchanged.
**Availability:** check [#699](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/699) first. Until exact merged source, provider activation and protected run proof are recorded there, this procedure is **NOT AVAILABLE YET**. Member/profile deployment and payments remain **NOT AVAILABLE YET** regardless of this check.
**Prerequisites:** the maintainer confirms the dedicated staging federation is enabled, the exact current main commit passed all six checks, and no runtime/build impersonation or direct member/secret permission has been added. Use only workflow **Verify staging profile authority** and environment **backend-staging**. The old **staging** environment remains read-only and separate.
**Prerequisites:** the dedicated staging federation is enabled and exact current main passed all six checks. #701 adds use of only the named staging runtime/build accounts; the deployment identity still cannot read member records or secrets directly. Use only **Verify staging profile authority** and **backend-staging**. The old **staging** environment remains read-only and separate.

```mermaid
flowchart LR
Main["Exact main; all six checks passed"] --> Approval{"Dave approval or recorded admin override"}
Main["Exact main; all six checks passed"] --> Approval{"Dave normal approval; no bypass"}
Approval --> Context["Fixed staging identity and workflow checks"]
Context --> Token["Five-minute keyless token; no credential file"]
Token --> Read["Project metadata and access check only"]
Read --> Proof["Fixed result; no backend deployed"]
```

Text alternative: exact green main and approval or a recorded override permit one fixed staging identity check; a five-minute token can read project/access metadata, and no backend or website is deployed.
Text alternative: exact green main and Dave's normal approval permit one fixed staging identity check; bypass is disabled, a five-minute token reads project/access metadata, and no backend or website is deployed.

1. Open the maintainer's run link and confirm the workflow name above.
2. Confirm branch main and environment backend-staging.
3. Confirm the request says identity check only, not backend or website deployment.
4. Confirm the exact source and all six successful checks.
5. Approve the matching request, or record the administrator override and its reason.
5. Approve the matching request through the normal gate; administrator bypass is disabled.
6. Wait for the fixed `staging_profile_authority_cloud_verified` result.
7. Ask the maintainer to record dated permission/key/trust readback on #699 privately, without provider locators or policy dumps.

**Expected result:** the check succeeds without creating a credential file, deploying anything or reading an account/document.
**Stop conditions:** stop on a wrong/stale source, changed workflow/environment, new write step, missing/failed check, unexpected permission or request for a key/member record. A failed check does not authorize a broader role.
**Success proof:** run link, exact source, named approval or recorded override, fixed result and private readback of zero user-managed keys. The role permits staging Function/Rules configuration, not direct records or project administration. IAM creation is project-scoped; the workflow, not IAM Function-name filtering, limits this step to reads.
**Undo:** ask the platform maintainer to disable only the dedicated profile federation pool or remove only its workload-identity binding, using the native service record. Existing five-minute tokens can survive until expiry. Leave the old read-only identity, project, records and unrelated roles alone. Re-enabling requires source/permission review and this check again.
**Success proof:** run link, exact source, normal named approval, fixed result and private readback of zero user-managed keys. The identity permits staging Function/Rules configuration and use of two exact staging accounts, not direct records or project administration. IAM creation is project-scoped; the workflow, not IAM Function-name filtering, limits this verifier to reads. #701 separately limits deployment to two profiles.
**Undo:** ask the maintainer to disable only the dedicated profile federation pool or remove only its workload-identity binding. Existing tokens can survive until expiry: five minutes for this verifier, up to thirty minutes for #701 deployment. Leave the old read-only identity, project, records and unrelated roles alone. Re-enabling requires source/permission review and this check again.
**Escalation:** Dave as platform owner; security specialist for an unexpected permission, exposure or identity mismatch. Actual identity revocation and later backend deployment still require a maintainer, not an officer terminal.

## Private service record
Expand Down
24 changes: 23 additions & 1 deletion docs/officers/LOW_COST_COMMUNITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Dave clarified the core scope on 2026-10-11: club membership, events, member sig

The warning budget is named **MPRC staging gross usage alerts**. It covers only staging, all services, and each calendar month. Its amount is **$10 USD**, with actual-usage alerts at **$5, $9, and $10**. Credits are excluded from the calculation so trial credits cannot hide underlying usage. Default billing-account notification recipients remain enabled; no new recipient, access grant, Pub/Sub automation, or shutdown rule was added. Configuration was read back; email delivery was not tested.

This is an **alerts-only budget**, not a bill ceiling or approval to spend club money. The only API enabled by this step was the Cloud Billing Budget API. Functions, Cloud Build, and Artifact Registry APIs remain disabled. Production billing remains disabled/unlinked. No Function, website, DNS, Stripe configuration, member record, or payment was changed. See the [staging billing map](./SYSTEM_MAPS.md#engineering-staging-billing--checked-2026-10-11).
This is an **alerts-only budget**, not a bill ceiling or approval to spend club money. #693 enabled only the Cloud Billing Budget API. #701 subsequently enabled Functions, Cloud Build and Artifact Registry in staging for two profiles. Production billing remains disabled/unlinked. #693 changed no Function, website, DNS, Stripe configuration, member record or payment. See the [staging billing map](./SYSTEM_MAPS.md#engineering-staging-billing--checked-2026-10-11).

### Check the trial and warnings without a terminal

Expand Down Expand Up @@ -95,6 +95,28 @@ The #683 source change configured no budget, spending cap, artifact-cleanup poli

**Escalation:** platform/security maintainer. A specialist remains necessary for provider setup, tests and deployment.

## Engineering staging profiles — #701

**Purpose:** prove only profile creation and recovery using made-up staging accounts. This is not membership approval, event management, a payment release or a public website launch.
**Approver:** Dave Liu, sole release/recovery owner. Administrator bypass is disabled; normal self-approval remains permitted.
**Availability:** **NOT AVAILABLE YET** until #701 records exact merged source, protected deployment, actual settings and hosted checks. #113/#133/#136 remain unresolved for production; this isolated engineering proof does not waive them.
**Prerequisites:** #693 trial/warnings, #699 keyless authority, #683/#691/#695 reviewed profile source, #676 staging isolation, and all six exact-main checks. Use only **Deploy two staging profile Functions**, environment **backend-staging**. No real member, email or payment tests.

1. Open the maintainer's run link.
2. Confirm main, backend-staging, the two-profile workflow and six passing source checks.
3. Approve the normal release request.
4. Wait for a separate verified result for each Function.
5. Ask for private readback of explicit runtime/build identities and all four resource limits above.
6. Observe made-up signup, recovery, repeated/concurrent recovery and denied invalid attestation, sign-in and injected fields.
7. Confirm existing profiles/roles stayed unchanged and made-up records were removed.
8. Record source, merge, staging deployment, hosted tests, website and production separately.

**Expected result:** two Node 22 staging Functions; no idle instances, maximum two instances each, 256 MB memory, 30-second timeout. Runtime can read Auth users and read/create database documents, not update/delete or change claims. Server IAM does not restrict individual collections; staging isolation and UID-bound code remain essential. Build access covers source objects, the profile image repository and build logs only. No Owner/Editor, secret or payment grant.
**Success proof:** fixed deployment markers, exact source/bundle digest, provider readback and hosted synthetic results on #701. Metadata/source tests alone do not prove working requests. Images keep the newest two versions per package; older images are eligible for deletion after seven days. Cleanup is asynchronous, not a cost ceiling. Native Function source recovery copies are separate.
**Stop conditions:** third handler, broad/default identity, paid upgrade, missing proof, unexpected allow, real data or unexplained bill. A failed build does not authorize wider access or disabling App Check.
**Undo:** ask Dave to hold further release work and use a reviewed same-source retry/roll-forward. Initial baseline is no staging Functions, not an older deployed runtime. If removal is needed, a specialist must verify #701 ownership and remove only these two Functions. Never delete the project, database or unrelated artifacts. The deploy identity has no Function-delete permission. No schema migration or production rollback is involved.
**Escalation:** Dave/platform specialist for release, access and recovery; club finance approver/cardholder for recurring spending. Officers do not use terminals, edit records or handle tokens. No backup owner is appointed.

## Review before a low-cost release

**Prerequisites:** issues #683 and #691 and their reviewed pull requests; the exact release source and test results; a named release approver; a private billing/payment-owner decision; and a platform maintainer. The existing release dependencies still apply. Never put payment details, passwords, or member records in an issue.
Expand Down
Loading
Loading