IP-restricted policy tracker
When Frontier rotates the Mac mini’s public IP, every IP-restricted policy below silently breaks until updated. This file is the canonical registry — when a drift alert fires, this is the checklist.
Current Mac mini public IP
47.204.119.46 (Frontier Communications, FL — formerly Verizon Fios)
ISP type: residential dynamic-IP, no static IP service purchased. IP is quasi-stable (typically weeks/months between rotations) but NOT guaranteed. Power outage, modem reboot, or ISP-side renewal can change it without warning.
Last verified: 2026-04-30 09:30 EDT (smoke test against Stripe API returned HTTP 200).
Active IP-restricted policies
1. Stripe Restricted API Key (RAK) — Ray COO Agent
- Service: Stripe API
- Restriction:
47.204.119.46/32(tight — single IP) - Set in: Stripe Dashboard → Developers → API Keys → “Stripe RAK - Ray” (Restricted Key, IP allowlist)
- Date set: 2026-04-30 by founder
- Credential location: 1Password vault “Ray Agent”, entry “Stripe RAK - Ray”, field
credential, IDcfbsgqonk4tbzoqnvaaerdsegu - Wired into: Stripe MCP via
~/Projects/stripe-mcp-wrapper/start.sh(registered asstripeMCP server, activates next Claude restart) - Failure mode on IP drift: Stripe API calls return HTTP 403 with
IP not allowederror. MCP server starts cleanly, individual tool calls fail. - Recovery action: Founder edits IP allowlist in Stripe Dashboard → Developers → API Keys → click “Stripe RAK - Ray” → update IP → save. Ray cannot do this autonomously; founder must use dashboard.
- Permission scope: see 2026-04-30-stripe-rak-permissions-recap (TODO file from morning) — broad Read across all surfaces, Write on storefront ops only (products, prices, customers, subscriptions, refunds, disputes, etc.). Hard No on Connect/Issuing/Treasury/Payouts/Apps Secrets.
2. App Store Connect API Key — Ray COO Agent
- Service: App Store Connect API (api.appstoreconnect.apple.com)
- Restriction: NO IP allowlist available. Apple does not expose IP restrictions for App Store Connect API keys. This is a known Apple gap.
- Set in: App Store Connect → Users and Access → Keys → “Ray COO Agent” key
- Date set: 2026-05-03 by founder
- Permissions: App Manager + Finance roles (broader than the proposed Developer-only role; gives /squarely-deploy full TestFlight + listing + submission access plus sales reports)
- Credential location: 1Password vault “Ray Agent”, entry “App Store Connect - Ray”, item ID
yv3dflxgrl3tba7627a4osazs4. Fields:notesPlain(the .p8 ECDSA P-256 private key contents),key id(F548W8HN4W),issuer id(a996996f-e470-41a7-b371-a1210eccb345). - Wired into:
~/.claude/scripts/asc-api.shwrapper (fetches creds from 1Password at runtime, generates ES256-signed JWT with 20-min TTL per Apple spec, curls api.appstoreconnect.apple.com). Used by the/squarely-deployskill. - Failure mode on key compromise: anyone holding the .p8 file + key ID + issuer ID can hit App Store Connect with App Manager + Finance scope. Could exfiltrate sales reports, modify listings, distribute TestFlight builds. CANNOT delete the app or transfer ownership (those are reserved-Account-Holder actions per Apple).
- Defense without IP allowlist: layered credential storage — 1Password “Ray Agent” service-account vault (only accessible via
opCLI with the SA token) + the wrapper script never echoes the key. No .env file on disk. - Recovery action on suspected compromise: founder revokes the key in App Store Connect → Users and Access → Keys → “Ray COO Agent” → “Revoke”. Generate a new key, update 1Password item, smoke-test wrapper. ~5 min total.
- Permission scope: see Apple’s docs on App Manager + Finance roles. Notably:
appManagerrole can do everything except billing-account changes and account-holder transfers. Finance role adds sales reports access.
Daily IP-drift check
Cron: ~/.claude/scripts/check-public-ip-drift.sh runs daily at 09:00 ET (added to ~/.claude/scripts/scheduled-jobs.txt 2026-04-30).
Workflow:
- Fetch current public IP via
curl -s ifconfig.me(cross-check with second source if first fails) - Compare against the canonical IP recorded in this file (
47.204.119.46) - If drift detected:
- Append diff entry to a drift log
- Send iMessage to founder: “⚠️ Mac mini public IP drifted from
<old>to<new>. Update Stripe RAK allowlist in dashboard ASAP — Stripe API calls will fail until you do.” - Update this tracker file’s “Current Mac mini public IP” line + “Last verified” date
- If no drift: silent (no founder ping)
Future additions to track
When new IP-restricted policies are added (or when other Mac mini-served APIs adopt allowlists), add them to “Active IP-restricted policies” above. Each entry should carry:
- Service name
- Restriction format (CIDR / single IP)
- Where it’s set (dashboard URL or config path)
- Failure mode + recovery action
- Date set + by whom
Likely future candidates:
- Cloudflare API tokens scoped by IP (if we tighten the rdco account access)
- Notion API integration (no IP restriction available currently — skip)
- Google Calendar/Gmail (OAuth-based, no per-IP option — skip)
- Mercury (when we connect it; banking APIs typically support IP allowlisting)
Known no-allowlist services (for awareness; defense relies on credential storage discipline):
- App Store Connect API (Apple — see entry #2 above)
Strategic note
IP-restriction is a real security uplift but trades off availability. The pattern only works if we:
- Catch drift fast (the daily check above)
- Have a clear recovery path (founder dashboard edit)
- Track every restricted policy in one place (this file)
If we ever upgrade to a static IP from Frontier (~$10-15/mo) or migrate to a Cloudflare Tunnel egress IP, this whole process gets simpler. Worth revisiting if drift becomes a recurring pain.
Related
- ../2026-04-29-link-cli-agent-wallet-setup — Stripe Link wallet (different surface; per-charge approval rather than IP-allowlist)
- ../../../.claude/scripts/check-public-ip-drift.sh — the daily drift check (created 2026-04-30)
- ../../../.claude/scripts/scheduled-jobs.txt — cron registry