Cloud Functions request-surface security review
Status: repository contract validated; deployed-inventory reconciliation and legitimate-client production canaries remain open under #183/#305
This review replaces Issue #183's historical two-callable inventory. It covers
the versioned request surface at commit b1078611dcf5aa016a399f402c65bc927d495e4d
without invoking or modifying production.
Versioned inventory
The default Functions source exports 29 callable or direct HTTP request endpoints: 27 callable endpoints and two HTTP endpoints.
Account and integrity callables
synchronize_verified_emailverify_app_check_installationreport_app_check_diagnostic_failuredelete_my_accountget_user_recipe_count
Subscription callables
record_purchase_callrefresh_subscription_entitlement
Membership and bounded-write callables
manage_recipe_box_membersmanage_shopping_list_memberscreate_recipe_boxsave_recipedelete_recipecreate_shopping_listcreate_shopping_itemsave_aisle_mapupsert_user_itemauthorize_recipe_image_uploadrelease_recipe_image_reservation
User-backup callables
request_user_backup_exportget_user_backup_exportcancel_user_backup_exportcreate_user_backup_downloadrequest_user_backup_importfinalize_user_backup_import_uploadget_user_backup_importget_active_user_backup_importconfirm_user_backup_import
Direct HTTP endpoints
app_store_server_notificationsauthenticates Apple-signed notification payloads against the configured trust material. Its focused tests cover signature/trust handling and bounded endpoint options.download_user_backup_exportrequires both Firebase ID and App Check tokens, verifies them server-side, binds the download session to the authenticated user, applies expiry/use/range limits, and returns sanitized failures.
Scheduled, task-queue, Firestore, and Storage event handlers remain security relevant but are not client/public request endpoints. They use isolated selectors, service identities, Scheduler/Cloud Tasks authentication, or event delivery controls and belong in the complete deployed Function inventory.
Control reconciliation
Automated contract coverage now proves that:
- the 29-name callable/HTTP inventory cannot drift silently;
- every request endpoint remains Gen 2 in
us-east1; - every request endpoint declares a parameterized scoped runtime identity;
- timeouts, memory, and maximum-instance settings remain bounded;
- managed secrets are declared by name rather than embedded values;
- every callable rejects an unauthenticated request; and
- 26 protected callables reject a missing App Check context.
report_app_check_diagnostic_failure is the sole intentional callable App
Check exception. Requiring a valid App Check token would prevent installations
that cannot obtain one from reporting the failure. It still requires Firebase
Authentication, validates and bounds categorical diagnostic fields, applies a
per-user daily transaction limit, records no App Check token, and has focused
tests in app_check_diagnostics.test.ts.
The source also contains focused authorization, ownership, replay/idempotency, archive-boundary, lifecycle, and rule tests. Passing repository tests establish source behavior; they do not prove the deployed inventory or IAM state.
The review found and corrected one bounded-input gap shared by both membership
callables: email addresses and member UIDs previously had no explicit maximum
length, and resource IDs accepted negative safe integers. A shared pure parser
now caps email addresses at 254 characters, Firebase UIDs at 128 characters,
rejects control characters and negative IDs, and requires operation-specific
fields before any Auth or Firestore request. Unit tests preserve valid ID 0,
normalization, and the existing list/add/remove behavior.
Errors, logging, and incident evidence
Callable handlers return typed HttpsError results with customer-safe messages.
Direct HTTP handlers map failures to bounded HTTP responses. Security review
must reject any change that logs or returns receipts, JWTs, private keys,
secret values, notification payloads, full request bodies, customer content,
or persistent private identifiers.
Monitor and investigate at least these categories without logging sensitive payloads:
- rejected authentication and App Check requests;
- membership and ownership denials;
- purchase verification rejection, replay, environment, product, or ownership mismatches;
- Apple notification verification/replay failures;
- rate/resource-limit rejections and unusual endpoint error/latency volume;
- backup export/import authorization or download-token failures; and
- unexpected changes to endpoint count, runtime identity, secrets, timeout, memory, concurrency, or maximum instances.
For an incident, preserve aggregate counts, timestamps, deployed revision, endpoint name, error category, and trace correlation needed for diagnosis. Do not copy secret values, tokens, receipts, payloads, customer content, or private identifiers into public issues.
Remaining #183 evidence
Before #183 can close:
- Compare the production callable/HTTP/event/scheduled/task inventory with the exact versioned exports and isolated codebase configurations.
- Verify deployed runtime identities, invoker bindings, App Check enforcement, secret bindings by name/version metadata only, and bounded runtime options.
- Confirm monitoring/alert delivery for the rejection and failure categories above.
- Run legitimate-client release canaries for membership and subscription verification against the frozen candidate under #305.
- Record sanitized evidence and stop on any unexpected endpoint, broad identity/invoker, missing control, or source/deployment drift.
The Apple Support hold in #335 prohibits using this review to retry Apple, deploy, modify App Check/IAM/secrets, or repair production. Any production audit or canary requires its own issue-recorded scope and approval.
Cost, stop conditions, and rollback
Repository validation costs engineering/test time only. Stop if validation requires production mutation, secret-value access, an Apple request, App Store Connect access, deployment, or exposure of a private identifier.
Rollback is repository-only revert of the inventory contract and documentation if merged. Production rollback is not authorized by this review and must follow the focused deployment/runbook approval for the affected endpoint.