prompts / p2p-production-hardening.md
edit FILL IN & copy this prompt →849 words

Prompt: take an ird p2p app from dev to production

Have an agent harden an existing ird p2p app for launch: tight origins, a branded wildcard hostname on your own zone, mailbox tokens minted only by your backend, limits sized to the rooms and peers you expect, monitoring hooks, a cost model from the relay rates, and a written rollback — each change snapshotted first and applied only on your yes.

Needs: ird access (MCP server or the ird CLI, logged in); an existing p2p app; for the custom domain, a zone hosted on ird DNS Costs: the app's existing hourly rate and per MB relayed / per MiB-hour cached (credits_prices → recurring.p2p-app-hourly); each backend token mint bills p2p.credentials; origin, domain and limit changes have no price-book entry Group: p2p

Paste everything below the line into a fresh conversation. Fill in the FILL IN block first.


Task

Bring the app below to production configuration, with a before/after diff per change, applied only after I confirm. Nothing is deleted or disabled.

FILL IN

APP:          notes                       # existing p2p app (name, hostname or id)
PROD_ORIGINS: https://notes.example.ro, *.notes.example.ro   # only these; bare wildcards
DOMAIN:       rtc.example.ro              # hostname on an ird-DNS zone, or blank
WILDCARD:     yes                         # also serve *.DOMAIN (zone must be on ird DNS)
ROOMS:        200                         # expected concurrent rooms
PEERS_ROOM:   8                           # expected peers per room
SESSIONS_MO:  20000                       # sessions per month
MB_SESSION:   30                          # average MB per session
TURN_SHARE:   0.15                        # share of sessions falling back to TURN/relay (assumption, replace with measured)
CLOSED_MINT:  yes                         # mailbox tokens only from my backend (if the mailbox is on)

Non-negotiable rules

  1. Snapshot before every change. Save the full p2p_list_apps entry (CLI: ird p2p info APP --json) — origins, settings, domains, mailbox flags — as the rollback baseline. Show the diff, wait for a yes, apply, re-read.
  2. Origins replace whole. p2p_set_origins overwrites the list; send it complete. Wildcards are bare (*.example.ro); https://*.example.ro is rejected. Never empty in production.
  3. Never disable the mailbox or delete the app. Disabling drops stored messages; deleting stops the hostnames immediately.
  4. Rates from credits_prices, usage from p2p_usage. No numbers from memory.

Steps

A. Baseline. p2p_list_apps → the APP entry; p2p_usage (CLI: ird p2p usage) → relayed bytes this period, relay_bytes_total, mailbox_bytes_total, cached_bytes, hourly/monthly. GET https://<host>/.well-known/ap2p → the live limits.

B. Origins. Diff current vs PROD_ORIGINS; drop localhost and staging. p2p_set_origins(app=APP, origins=[PROD_ORIGINS]) (CLI: ird p2p origins APP --set a,b) gates the WebSocket upgrade, /turn-credentials, the relay upgrade and the mailbox open mint; live within a minute. Verify: curl -H "Origin: https://evil.example.com" https://<host>/turn-credentials is refused, a PROD origin is not.

C. Custom domain. If DOMAIN: its zone must be in dns_list_zones. p2p_domain_add(app=APP, hostname=DOMAIN, wildcard=WILDCARD) (CLI: ird p2p domains add APP DOMAIN --wildcard). On an ird-hosted zone records and certificate are automatic — a wildcard needs this. Otherwise set the returned dns_cname_target as a CNAME and run p2p_domain_verify(app=APP, domain=DOMAIN). The descriptor is host-aware: fetched from DOMAIN it advertises DOMAIN's multiaddrs. Switch the client to DOMAIN and repeat the two-browser test.

D. Closed-mint mailbox. Only if mailbox_enabled and CLOSED_MINT: p2p_set_mailbox(app=APP, open_mint=false) (CLI: ird p2p mailbox APP --closed-mint); omit enabled. The browser mint then refuses; my backend mints with p2p_mailbox_credentials(app=APP, room=<room or omit>, ttl_sec=…) (CLI: ird p2p mailbox creds APP --room …; API: POST /p2p/apps/:id/mailbox-credentials) and hands the token to the client in its invite flow. Tokens verify offline — no revocation — so keep ttl_sec short and room-scoped. Each mint bills p2p.credentials.

E. Limits. Defaults (from p2p_set_limits): signaling max_rooms 500, max_room_peers 16, max_conns_per_ip 20, max_bytes_per_sec 256 KiB/s; relay max_relay_reservations 128, max_relay_circuits 64, relay_circuit_duration_sec 3600, relay_circuit_data_mb 512, max_relay_bytes_per_sec 256 KiB/s, max_relay_conns_per_ip 20; mailbox mailbox_ttl_hours 24, mailbox_max_mb 256, mailbox_max_message_kb 64, mailbox_mint_ip_per_min 10, mailbox_mint_app_per_min 600. Size (×1.5 = headroom, an assumption): max_rooms ≥ ROOMS × 1.5 (one pool shared by /ws, y-webrtc topics, tracker swarms and PeerJS clients), max_room_peers ≥ PEERS_ROOM × 1.5, max_conns_per_ip up for users behind one office NAT; libp2p: reservations ≥ concurrent browser peers. Only passed keys change, 0 resets, values are clamped; more relay throughput means more can bill. p2p_set_limits(app=APP, …) (CLI: ird p2p limits APP --set k=v). Re-read the descriptor.

F. Monitoring. Weekly p2p_usage (relayed bytes and cached_bytes vs the model in G); client logging of signaling error codes too-many-rooms, room-full, rate-limited and relay/mint HTTP 429; a boot-time descriptor fetch so limits and relay ids are never hardcoded.

G. Cost model. Monthly ≈ per_hour × 730 + SESSIONS_MO × MB_SESSION × TURN_SHARE × per_mb_relayed + average cached MiB × 730 × per_mb_hour_cached + mints × p2p.credentials. Direct WebRTC bytes cost nothing. After a week, replace TURN_SHARE with the measured share.

H. Rollback. Per change: origins → p2p_set_origins with the saved list; domain → p2p_domain_delete(app=APP, domain=DOMAIN), client back to <name>.ap2p.ro; mint → p2p_set_mailbox(app=APP, open_mint=true); limits → p2p_set_limits with the saved values (or 0 per key). No price-book entry; origins and limits apply within a minute.

Deliverable

The before/after table (origins, domains, mailbox mint, changed limits), verification output for B, C and E, the cost model, the monitoring checklist, and the rollback commands beside the saved baseline.

static mirror of HEAD · about · clone: git clone https://ird.cod-sursa.ro/prompts.git