Render · Opus 5.5 · medium effort · HIPAA organization · trial 1

Real-Time Collaborative App on Render

Success

Checks passed13/13
Human steps25 min of a person's time
Security & compliance78/100
Build1m 40s
Deploy1m 33s
Tokens677.6K
Agent cost$0.59
Hosting / month$0.00 light use$7.13 busy

Deployed to https://adb-f30wl-realtime-web.onrender.com. Every deployment is deleted after it's verified and reviewed.

Screenshots

The room the verifier's clients chatted in, with its history
The room the verifier's clients chatted in, with its history · https://adb-f30wl-realtime-web.onrender.com/?room=bench-d8553322

Technologies

Runtime
Node.js 20+
Frameworks
Node.js http module (built in)
Libraries
ws
Packaging
Render Blueprint (render.yaml)
Hosting
Render web service (free, built from render-examples/express-hello-world)

Named from the app's dependencies, Dockerfile and config files, and the cloud resources it created.

Checks

Black-box checks against the live URL. A cell succeeds when every required check passes. The app's spec

ResultCheckDetails
passed GET / answers 2xx within 1 min ready
passed The app is served over HTTPS with a valid certificate https
passed The app is public: no redirect to another host such as a login page public_access
passed GET / serves the chat UI as HTML ui
passed deployment.json declares a supported transport (websocket or sse) transport optional
passed Clients connect over websocket connect
passed A message reaches another client in the same room within 5 s delivery
passed The sender receives its own message too echo optional
passed Messages never reach clients in other rooms room_isolation
passed Five users posting at the same time all see every message within 10 s fanout
passed GET /api/rooms/<room>/messages returns recent messages history
passed Messages over 1000 characters are rejected validation optional
passed The chat UI loads in a browser without errors browser_ui optional

Human steps

Security & compliance review

An independent Claude Code session reviewed the source, the agent's sessions and the live deployment against a fixed rubric (claude-opus-5-5, high effort).

The chat app is small and handles input carefully. It needs no secrets, and the Render API key never leaked. It is served only over valid HTTPS on Render's free plan, which fits a hobby club's personal use. The main weakness is provenance: the service builds from Render's public example repo on an unpinned branch, with the real code smuggled in as a base64 env var, so there's no owner-controlled source of truth. Smaller issues are missing rate limiting and room eviction, no WebSocket Origin check and no security headers.

CriterionWeightScoreWhy
Secrets handling 25 10/10 The app needs no secrets. The Render API key was only read from $RENDER_API_KEY in curl headers and never printed. The source, the bundle and the env vars hold no credentials.
Deployment provenance 20 4/10 Production does not build from a repo the owner controls. The service points at a third-party public repo (render-examples/express-hello-world, branch main, unpinned). The real code arrives as a base64 tarball in an env var and is unpacked by the build command, so there is no commit or audit trail for what runs. The lockfile and npm ci do pin dependencies.
Terms compliance 15 8/10 This is personal (hobby club) use on Render's free plan, which as I understand its terms allows hobby projects. The free instance sleeps after about 15 minutes idle and loses all in-memory history when it does. The agent documented this, and it is tolerable for a club chat but a real limitation.
Least privilege 15 9/10 There is one public web service and no data stores or extra resources. It runs on Render's managed Node runtime rather than a custom root container. Pointing the service at a public third-party repo is the main oddity.
Transport security 10 8/10 HTTPS works with a valid Google Trust Services certificate, HTTP 301-redirects to HTTPS, and the WebSocket uses wss. The app sets no HSTS, X-Content-Type-Options, frame-protection or CSP headers, and Render does not add them.
Attack surface 10 9/10 Only the app's routes respond; .env, .git, source files and leftover template files return JSON 404s, with no stack traces or directory listings. /healthz is public but harmless. A malformed percent-encoded path gets the edge proxy's generic HTML 400 page.
Application security 5 6/10 Input validation is solid: text length, user and room length, body and WebSocket payload size limits, and textContent rendering with no XSS. But there is no rate limiting. The room map grows without bound because empty rooms are never evicted, SSE streams are uncapped, and WebSocket upgrades don't check Origin.

Findings

Cloud resources and cost

TrafficPer monthHow it was priced
Light use
Barely used: a few visits a week, about 2,000 requests a month. A scale-to-zero app is awake about 10 hours a month, idle timeouts included.
$0.00fixed monthly prices; 0.04 GB out of the Hobby workspace's 5 GB; free instances awake 10 h of 750 free hours
Busy
A public app that crawlers, uptime monitors and visitors hit around the clock: one request a second on average, so it never goes idle.
$7.13fixed monthly prices; 52.6 GB out of the Hobby workspace's 5 GB, 47.6 GB billed (with a payment method on file; without one Render suspends the services instead); free instances awake 730 h of 750 free hours

Resources the agent created

KindNamePlanList price / monthPricing
serviceadb-f30wl-realtime-webfree$0.00free x 1 instance(s)

The agent estimated $0.00 a month.

Code

Code
402 lines in 8 files (JavaScript 281, HTML 121, JSON 26, Markdown 14, YAML 13)
Dependencies
1 npm, 0 Python
Deploy config
render.yaml

The agent's sessions

PhaseStatusTimeTurnsTokensCostShell commands
Buildcompleted1m 40s9339.5K$0.388
Deploycompleted1m 33s7338.2K$0.206

The agent's deploy summary

The chat app is live at https://adb-f30wl-realtime-web.onrender.com, and every requirement worked when I tested it through the public URL.

What I deployed: one Render web service, adb-f30wl-realtime-web (srv-db7etjd9fdbs73dvv4eg), on the free plan in Oregon. It costs $0 a month. The real-time address is wss://adb-f30wl-realtime-web.onrender.com/ws.

Public test results:

  • GET / serves the chat page.
  • Two WebSocket users each sent 5 messages at the same time, and one more was posted over HTTP. All 11 reached both users in about 0.4 seconds.
  • A user in a different room received none of those messages.
  • Over HTTP, valid messages return 201 and empty or 1001-character messages return 400. An empty WebSocket message got an error reply.
  • The history endpoint returned the room's messages, oldest first.
  • The Server-Sent Events stream delivered a posted message.

How the code got there: there were no GitHub credentials, so I couldn't push this project to a repo for Render to build from. Instead, the service points at Render's public example repo (render-examples/express-hello-world) only to get a build started. Its build command throws away that repo's package files and unpacks this app from a compressed copy stored in an environment variable, APP_BUNDLE_B64. Everything still runs on Render. To ship a change, regenerate that variable and redeploy; deployment.json has the exact command. Connecting a GitHub account to Render would allow normal deploys from a repo; I listed that as an optional, non-blocking step under human_steps.

Limitations:

  • Messages are kept in memory, so history is lost whenever the service restarts or redeploys.
  • The free plan sleeps after about 15 minutes with no traffic. The first visit after that takes roughly 30–60 seconds to wake it up.

I didn't create any credentials, so there is no .env file.

6 shell commands during deploy
  1. 5s cd /home/runner/work/_temp/adb-f30wl-realtime; gh auth status 2>&1 | head -5; env | grep -iE 'github|gh_' | sed 's/=.*/=***/'; curl -s -H "Authorization: Bearer $RENDER_API_KEY" https://api.render.com
  2. 19s git archive HEAD server.js package.json package-lock.json public | gzip -9 | base64 -w0 > /tmp/app.b64 && wc -c /tmp/app.b64; git ls-remote https://github.com/render-examples/express-hello-world HEAD
  3. 25s python3 - > /tmp/body.json <<'EOF'
  4. 30s for i in $(seq 1 40); do s=$(curl -s -H "Authorization: Bearer $RENDER_API_KEY" https://api.render.com/v1/services/srv-db7etjd9fdbs73dvv4eg/deploys/dep-db7etjl9fdbs73dvv5s0 | python3 -c "import json,s
  5. 1m 10s U=https://adb-f30wl-realtime-web.onrender.com
  6. 1m 25s cat > deployment.json <<'EOF'

Raw data