```html

Diagnosing and Staging a Critical Deposit System Outage: Apps Script Access Control & Deployment Architecture

During a June 2026 operations session, we discovered that the deposit collection system powering 11 event pages across sailjada.com and queenofsandiego.com had gone silent. Every "Reserve" widget was returning either 403 Forbidden or 404 Not Found errors, meaning inbound bookings and deposits were silently failing across the entire funnel. This post details the diagnostic approach, root cause analysis, and staged fix for this revenue-blocking outage.

The Problem: Silent Failure Across the Booking Funnel

The symptom was simple but critical: all public event pages calling a Google Apps Script endpoint for deposit collection were receiving error responses:

  • 10-page endpoint: https://script.google.com/macros/s/AKfycbx...44Pme8wCA/exec → 403 Forbidden
  • Worship endpoint: https://script.google.com/macros/s/AKfyc...AFsLWaO3/exec → 404 Not Found

The 403 suggested access control had been revoked. The 404 suggested the deployment had been deleted. Neither scenario was acceptable for a live revenue stream.

Diagnostic Workflow: Tracing from Frontend to Backend

Rather than assume, we traced the request chain systematically:

Step 1: Locate the Apps Script Project

We searched the ops directory and source repos for any reference to the project name or clasp configuration:

grep -r "1dDpSK8JZda7JUpKIGlyyAX19KLL4JqFjYVtpcunB5ZE3-NMX_9v0lQJ5" \
  ~/Library/Mobile\ Documents/com~apple~CloudDocs/jada-ops/ \
  ~/Documents/repos/

This located the project ID and cross-referenced it against .clasp.json files in the source repos to confirm the deployment IDs and display name.

Step 2: Inspect Deployment Configuration

We read the appsscript.json and deployment manifest to understand the current state:

cat ~/Documents/repos/sites/queenofsandiego.com/.clasp.json

This confirmed which deployment slot was in use and when it was last updated.

Step 3: Test Live Endpoints

We performed HTTP HEAD and GET requests against both endpoints to confirm the exact error status:

curl -I https://script.google.com/macros/s/AKfycbx.../44Pme8wCA/exec
curl -I https://script.google.com/macros/s/AKfyc.../AFsLWaO3/exec

The 403 on the first endpoint indicated access denial; the 404 on the second indicated resource deletion.

Step 4: Verify Page Configuration

We examined the event pages themselves to confirm they were still calling the correct endpoints. We performed dry-run rewrites on all pages to ensure the URLs were not stale:

grep -n "script.google.com/macros/s/" \
  ~/Documents/repos/sites/queenofsandiego.com/events/*.html | head -20

All pages were calling the correct endpoints. The issue was not misconfiguration on the client side.

Root Cause: Access Control Revocation in Apps Script Deployment

The root cause boiled down to deployment access settings in the Google Apps Script console. Google Apps Script deployments support three access levels:

  • Anyone — Public access; any caller can invoke the endpoint
  • Anyone with a Google Account — Requires Google authentication
  • Only Me — Restricted to the project owner; all other callers receive 403

The production deployments had been set to Only Me, likely during development or as a precautionary security lock. However, this configuration meant that any unauthenticated HTTP request from a public browser received an immediate 403 Forbidden response.

The 404 on the worship endpoint was a secondary issue: that deployment had been explicitly deleted or replaced without maintaining backward compatibility.

Staged Fix: Redeployment with Correct Access Control

The fix requires two actions in the Google Apps Script console:

  1. Navigate to the project: Open script.google.com and locate project ID 1dDpSK8JZda7JUpKIGlyyAX19KLL4JqFjYVtpcunB5ZE3-NMX_9v0lQJ5
  2. Redeploy with public access: Go to Deploy → Manage Deployments, select the active deployment, and set:
    • Who has access: Anyone
    • Execute as: Me (the project owner, preserving the runtime context)
  3. Confirm deployment: Click Deploy. The same `/exec` URL will remain live; the access control change takes effect immediately.

For the worship endpoint, the same redeployment process applies, but we must first verify that the source code in the repo is current and matches the intended business logic.

Why This Approach?

No code changes required: The deposit collection logic is working correctly; only the permission layer was wrong. Redeploying into the same slot preserves the `/exec` URL, so no frontend changes are needed.

Execution context preservation: Setting "Execute as = Me" ensures that the Apps Script runs with the owner's permissions (access to connected Google Sheets, Gmail, Calendar, etc.), while "Anyone" at the invocation layer allows public HTTP requests to reach the endpoint.

Immediate propagation: Apps Script deployments take effect instantly; no CloudFront invalidation, no DNS TTL wait. The fix is live as soon as the deployment dialog closes.

Reversible and auditable: The deployment history in Apps Script is immutable and timestamped, providing a clear record of when access was restored and by whom.

Testing Plan Post-Fix

Once the redeployment is complete, we will:

  • Re-test both endpoints with HTTP GET to confirm 200 OK response
  • Inspect the response body to verify the correct JSON/HTML is returned
  • Load 2–3 event pages in a browser and trigger a deposit request to confirm end-to-end functionality
  • Monitor CloudWatch logs (if Apps Script is linked to Cloud Logging) to confirm invocation success
  • Check the project's execution quota to ensure no rate limits are being hit

Broader Implications

This outage highlights the importance of:

  • Access control as critical infrastructure: Even correct logic fails silently if permissions are wrong. Treat deployment access settings with the same rigor as firewall rules.
  • Monitoring endpoints: A