Diagnosing and Staging a Critical Deposit Endpoint Outage: Apps Script Access Control Recovery
During a routine deployment audit on June 2, 2026, we discovered that all 11 event pages across the Sail Jada platform were serving broken "Reserve" widgets—silent failures in the deposit funnel affecting every inbound booking attempt. This post covers the diagnosis methodology, infrastructure investigation, and the staged fix for a 403/404 endpoint outage on our Google Apps Script deployment.
The Problem: Silent Deposit Funnel Failure
End users hitting sailjada.com or queenofsandiego.com event pages encountered non-functional reserve buttons. The issue wasn't visible in logs because the failure was upstream—at the Apps Script deployment layer, not in our application code. This represented a total stoppage on revenue inbound, not a single-charter issue.
Live endpoint states discovered:
- Primary deposit endpoint:
https://script.google.com/macros/s/.../44Pme8wCA/exec→ HTTP 403 (access revoked) - Worship event endpoint:
https://script.google.com/macros/s/.../AFsLWaO3/exec→ HTTP 404 (deployment deleted)
Diagnosis: Tracking Project Identity Across Deployment Layers
The first challenge was mapping the deployed Apps Script project to its source code and configuration. We worked through three levels of indirection:
Step 1: Identify the Project from Live Endpoints
We extracted the deployment ID from the live /exec URL and searched across infrastructure:
grep -r "44Pme8wCA" ~/jada-ops/
grep -r "44Pme8wCA" ~/code/jada-source/
This search located references in the outage documentation but not in active source repos, indicating the project was either archived or deployed from a different branch.
Step 2: Locate Project via Apps Script Config Files
We inspected .clasp.json files across all local source repositories to find which project matched:
find ~/code -name ".clasp.json" -exec cat {} \;
find ~/code -name "appsscript.json" -exec grep -l "displayName" {} \;
This revealed the project ID: 1dDpSK8JZda7XUpKIGlyyAX19KLL4JqFjYVtpcunB5ZE3-NMX_9v0lQJ5
Step 3: Cross-Reference Deployment vs. Project ID
Critical insight: the project ID and the deployment ID are different. The project ID is stable; deployment IDs change with each redeploy. Our 403 error was on a deployment that existed but had its sharing permissions revoked. The 404 on the worship endpoint indicated that specific deployment had been deleted entirely, likely from a cleanup or failed redeploy.
Root Cause Analysis: Access Control and Deployment State
Apps Script deployments exist in Google's infrastructure with metadata including:
- Deployment ID — the unique identifier in the
/execURL - Access level — "Anyone," "Specific users," or "Only me"
- Execute as — the identity under which the deployed function runs (user or service account)
- Active status — whether the deployment is live or marked for deletion
The primary endpoint's 403 meant the deployment existed but access had been restricted—likely during a security audit or permission sync. The worship endpoint's 404 meant the deployment had been fully removed, requiring a complete redeploy.
Infrastructure Changes and Staging
Documented in: ~/Library/Mobile Documents/com~apple~CloudDocs/jada-ops/DEPOSIT-OUTAGE-FIX-2026-06-02.md
We staged the fix without applying it immediately (following deployment discipline):
For the primary 403 endpoint:
- Navigate to
script.google.com→ Project1dDpSK8JZda7XUpKIGlyyAX19KLL4JqFjYVtpcunB5ZE3-NMX_9v0lQJ5 - Open Deploy → Manage deployments
- Select the active deployment (ID ending in
44Pme8wCA) - Set Who has access = "Anyone" (required for public reserve widgets)
- Set Execute as = Me (or the service account owning the sheets)
- Deploy and verify HTTP 200 response
For the 404 worship endpoint:
- Identify the current active deployment from
script.google.com - Create a new deployment from the current project version
- Update the worship event page to point to the new deployment ID
- Test endpoint before live sync
Verification via command line (before and after):
curl -I "https://script.google.com/macros/s/.../44Pme8wCA/exec"
# Expected: HTTP 403 before fix
# Expected: HTTP 200 after fix
curl -I "https://script.google.com/macros/s/.../AFsLWaO3/exec"
# Expected: HTTP 404 before redeploy
# Expected: HTTP 200 after redeploy
Event Page Endpoints: S3 and CloudFront Distribution
The 11 event pages are hosted as static HTML on S3 with embedded deposit endpoint URLs:
- S3 bucket:
s3://sailjada-public-events/ - CloudFront distribution:
d...cloudfront.net(caching 5 minutes for.htmlfiles) - Route53 DNS:
sailjada.comandqueenofsandiego.comALIAS records point to CloudFront
Event pages stored in S3:
s3://sailjada-public-events/reserve-page-template.html
s3://sailjada-public-events/events/[event-slug]/index.html
s3://sailjada-public-events/events/worship/index.html
(10 additional event pages)
Each contains hardcoded endpoint URLs in JavaScript:
<script>
const DEPOSIT_ENDPOINT = "https://script.google.com/macros/s/.../44Pme8wCA/exec";
// Reserve button click handler calls fetch(DEPOSIT_ENDPOINT, {method: 'POST', ...})
</script>
Once the Apps Script endpoints are restored to HTTP 200, the S3 pages require no changes. If endpoints are redeployed with new IDs, we perform a dry-run