Diagnosing and Staging a Critical Deposit Outage: Apps Script Access Control and Multi-Endpoint Deployment Strategy
What Happened
During routine operations monitoring, all eleven event-booking pages across sailjada.com and queenofsandiego.com returned HTTP 403 and 404 errors on their deposit/reserve endpoints. The funnel was dark: inbound booking requests silently failed, revenue leakage was invisible, and the root cause required tracing back through three layers of indirection—from S3-hosted HTML, through CloudFront cache invalidation, to the actual Google Apps Script deployments.
Technical Investigation
Layer 1: S3 and CloudFront Verification
The investigation started by confirming that the event pages themselves were being served correctly from S3. Using the AWS CLI, we listed the contents of the primary events bucket and verified CloudFront distribution cache behavior:
aws s3 ls s3://queenofsandiego-events/ --recursive | grep -E "\.html$"
aws cloudfront list-distributions --query 'DistributionList.Items[?Comment==`events-cdn`]' --output table
The pages were in place and CloudFront was serving them. The failure was downstream: the inline <form> elements posting to external Google Apps Script endpoints were receiving authentication errors.
Layer 2: Endpoint URL Mapping
Each event page contains embedded reserve forms with action attributes pointing to Apps Script /exec endpoints. We mapped these:
- Primary endpoint (10 pages):
https://script.google.com/macros/s/AKfycbw.../44Pme8wCA/exec→ returning HTTP 403 Forbidden - Worship endpoint (1 page):
https://script.google.com/macros/s/AKfycbw.../AFsLWaO3/exec→ returning HTTP 404 Not Found
The 403 indicated access control misconfiguration; the 404 suggested the deployment had been deleted or never properly deployed.
Layer 3: Google Apps Script Deployment Audit
Using Google Cloud Console access logs and the Apps Script dashboard, we identified that both deployments existed in the project (1dDpSK8JZda7XUpKIGlyyAX19KLL4JqFjYVtpcunB5ZE3-NMX_9v0lQJ5) but had divergent access configurations:
- Primary deployment: Access set to a specific user or organization domain, not "Anyone"
- Worship deployment: Either deleted or never executed after the last code push
Root Cause Analysis
Apps Script deployments require explicit access control settings. The primary endpoint had its "Who has access" permission set to something more restrictive than "Anyone," blocking anonymous form submissions from the public reserve widget. The worship endpoint's 404 suggested either a failed deployment or a stale cached URL—both fixable with a fresh deployment that explicitly sets execute-as and access permissions.
The fix is not a code change; it's a deployment configuration change in the Google Apps Script console.
Staged Resolution
Remediation Steps (Not Yet Applied)
To restore both endpoints, the following changes are documented in /jada-ops/DEPOSIT-OUTAGE-FIX-2026-06-02.md:
- Open Google Apps Script project
1dDpSK8JZda7XUpKIGlyyAX19KLL4JqFjYVtpcunB5ZE3-NMX_9v0lQJ5in script.google.com - Navigate to Deploy → Manage Deployments
- Select the primary deployment (the one serving
44Pme8wCA) - Set "Who has access" = Anyone
- Set "Execute as" = Me (the account owner running the script)
- Click Deploy
- For the worship deployment: If missing, create a new deployment from the existing code with the same access settings
These are one-click changes in the Google UI—no code deployment, no CI/CD pipeline, no DNS or CDN modifications required.
Why This Architecture Matters
The reserve system uses a three-tier pattern:
- Tier 1 (Content): Static HTML hosted on S3, distributed via CloudFront
- Tier 2 (Forms): Client-side form submission to external endpoint
- Tier 3 (Backend): Google Apps Script as a lightweight, zero-ops function runner
This design avoids maintaining backend servers for booking logic. However, it creates a hard dependency on the Apps Script deployment being publicly accessible. A misconfigured access control doesn't fail gracefully—it silently blocks the entire booking funnel.
Testing and Validation Plan
Once the deployment access is corrected, verification involves:
# Test primary endpoint
curl -X POST https://script.google.com/macros/s/AKfycbw.../44Pme8wCA/exec \
-H "Content-Type: application/x-www-form-urlencoded" \
--data "eventName=TestEvent&depositAmount=100"
# Test worship endpoint
curl -X POST https://script.google.com/macros/s/AKfycbw.../AFsLWaO3/exec \
-H "Content-Type: application/x-www-form-urlencoded" \
--data "eventName=TestEvent&depositAmount=100"
Both should return HTTP 200 with a success JSON response, not 403/404.
Impact and Next Steps
Impact: This outage affects all inbound deposits across 11 active event pages. No bookings can be completed. Revenue leak is unknown but real.
Next Steps:
- Apply the deployment fix in Google Apps Script console (2-minute task)
- Verify both endpoints return 200 with curl
- Run synthetic booking test through one of the event pages
- Monitor webhook/email notifications to confirm deposits are processing
- Post-incident: implement CloudWatch or Datadog alerts on Apps Script endpoint HTTP status to catch similar issues within minutes, not hours
The fix is straightforward and immediately unblocks revenue. It requires no code changes and no coordination with external teams—just access to the Google Apps Script project console.
```