A long-running dev environment for your coding agent.

Your services keep running while the agent works, and when you reconnect, everything is right where you left it, still warm and in full context.

09:42Linear · pulled
ENG-2043·BackendIn progress

Migrate Stripe webhook handler to new signature verification

Swap the three webhook routes to stripe.Webhook.constructEvent. Add replay protection (60s). Keep one release of backwards compat.

Assigned youPriority MediumEstimate 4ptsSprint S-41
billingwebhookssecuritystripe
09:44agent · scratchpad
PLAN.md● unsaved

Stripe webhooks → constructEvent

  1. Extract constructEvent wrapper
  2. Port invoice + subscription routes
  3. Port charge route
  4. 60s replay-protection
  5. Run suite, open PR
13:42diff · working tree
lib/stripe_auth.py+12−0
@@ -38,6 +38,15 @@ def constructEvent(payload, sig, secret):
38 38 ts, expected = _parse_header(sig)
39 39 provided = _compute(payload, secret, ts)
40 40 if not _sig_equal(expected, provided):
41 41 raise SignatureError("bad sig")
42+ _check_timestamp(ts, tolerance=60) # replay window
42 43 return json.loads(payload)
43 44  
@@ -71,0 +72,11 @@
72+def _check_timestamp(ts: int, tolerance: int = 60) -> None:
73+ """Reject events whose timestamp is outside tolerance.
74+ Defends against replay attacks on signed payloads."""
75+ now = int(time.time())
76+ if abs(now - ts) > tolerance:
77+ raise SignatureError(f"timestamp drift: {now - ts}s")
13:46sandbox · running stack
swift-lantern · servicesagent reaches all of these on localhost.
postgres:5432
pgdata · 1.4 GB · pinned schema
up·4h 11m
redis:6379
cache + rate-limit buckets
up·4h 11m
api (fastapi):8000
hot-reload · 3 webhook routes
up·4h 10m
worker
celery · stripe events queue
up·4h 10m
web (next):3000
billing dashboard · live
up·4h 08m
stripe-mock:12111
fixture events · signed
up·4h 11m
13:47share · live preview
13:58vault · egress
agent
stripe.charges.retrieve(...)
$STRIPE_SECRET_KEY · placeholder only
islo vault
Authorization: Bearer $STRIPE_SECRET_KEYAuthorization: Bearer sk_live_••••••••••••4f2a
injected at egress · per-request audit
stripe api
200 OK · charge_XYZ
key never touched sandbox memory
bindingegresslast used
STRIPE_SECRET_KEYapi.stripe.com4h 11m ago
DATABASE_URLpg.swift-lanternlive
GITHUB_TOKEN (scoped)api.github.com2m ago
SLACK_BOT_TOKENslack.com/apipending
DATADOG_API_KEYapi.datadoghq.com1h 03m ago
18:20session · resumed
~ · you@laptopwoken · 1.2s
$ islo use swift-lantern
 sandbox resumed · 4h 12m uptime · disk warm
 services restored · postgres redis api worker web stripe-mock
 vault re-bound · no keys written · audit chain continues

working dir   ~/work/billing (git: eng-2043-stripe-v2, 2 unstaged)
open files    lib/stripe_auth.py · routes/charge.py · PLAN.md
agent state   step 8 of 8 · paused on human approval
last action   drafted PR #4821 (14:03)
waiting on    merge call for stripe_v2_enabled

agent › Welcome back. Ready when you are.
Same filesystem. Same history. Same context.
14:03github · opened
● Draftbilling: migrate Stripe webhooks to constructEvent #4821
swift-lantern/eng-2043-stripe-v2main
14 files changed+287−164·1,284 tests passing
pytest · full suite18.7s
mypy · type check3.2s
ruff · lint0.4s
coverage · 94.2%
staging · smoke tests2m 14s
pricingprovisioned · per hour
CPU time
$0.07/CPU-hour
billed on provisioned cores while the env is running
memory time
$0.04/GB-hour
request 2 GB, pay for 2 GB while it runs
storage time
$0.0007/GB-hour
billed on provisioned disk
overnight agent session (8 hours)
CPU · 2 cores × 8h$1.12
Memory · 4 GB × 8h$1.28
Storage · 10 GB × 8h$0.06
Total$2.46
monthly team (5 devs, ~4h/day)
CPU · 800 CPU-hours$56.00
Memory · 1,600 GB-hours$64.00
Storage · 8,000 GB-hours$5.60
Total~$126/mo
Free tier · 5 concurrent sandboxes · 1h max per sandbox

Your dev env, running for the agent.