Skip to main content

Render provider connection (hosted TypeScript service)

Keycli can perform a real Render env var mutation from the hosted control plane when the workspace has a connected Render ProviderConnection.

What is live now

  • ✅ store a Render ProviderConnection
  • ✅ test/validate a Render connection from the hosted API
  • ✅ resolve a credential ref at apply time
  • ✅ mutate a Render service env var through the Render API
  • ✅ expose Render readiness through authenticated GET /v1/capabilities
  • Render is live, but it is not the canonical morning demo path.
  • The safest live demo remains the preview-only Vercel flow in docs/VERCEL.md.
  • Render deploy/restart flows are still not implemented.

Configure a Render connection

Start the hosted API:
npm run api:hosted
Bootstrap a workspace + owner token (same pattern as docs/DEMO.md), then create a Render connection. Recommended: use an env-backed secret ref so Keycli never stores the raw token in the API object. If the token should only be used for one Render service, bind it explicitly with scope.
export RENDER_API_KEY=...

curl -s -X POST http://localhost:8788/v1/connections \
  -H "authorization: Bearer $KEYCLI_TOKEN" \
  -H 'content-type: application/json' \
  -d '{
    "provider": "render",
    "label": "main",
    "authMethod": "api_token",
    "credentialRef": "env:RENDER_API_KEY",
    "scope": {
      "provider": "render",
      "serviceId": "srv-demo"
    }
  }'
Notes:
  • Keycli stores only the credentialRef in the connection record.
  • GET endpoints return redacted credential refs.
  • In dev/test, you can also pass credential directly and Keycli will store it through the configured SecretStore.

Test the connection

This validates the token and, if you pass serviceId, confirms service access for the live path.
export KEYCLI_RENDER_CONNECTION_ID=conn_...
export KEYCLI_RENDER_SERVICE_ID=srv-demo

curl -s -X POST "http://localhost:8788/v1/connections/$KEYCLI_RENDER_CONNECTION_ID/test" \
  -H "authorization: Bearer $KEYCLI_TOKEN" \
  -H 'content-type: application/json' \
  -d "{\"serviceId\":\"$KEYCLI_RENDER_SERVICE_ID\"}"
Expected success shape:
{
  "test": {
    "ok": true,
    "status": "connected",
    "liveExecutionAvailable": true,
    "reason": "render_service_access_confirmed"
  }
}
If the connection is service-scoped and you test a different service, Keycli returns reason: "render_scope_mismatch" and leaves live execution unavailable for that target.

Live env var mutation path

When a plan targets Render and the workspace has a connected Render connection, Keycli marks the plan as:
  • plan.execution.mode: "provider-api"
On apply, for render:rotate-secret steps Keycli calls the Render API:
  • GET /v1/services/:serviceId/env-vars
  • PUT /v1/services/:serviceId/env-vars

Workspace readiness

Inspect authenticated capabilities:
curl -s http://localhost:8788/v1/capabilities \
  -H "authorization: Bearer $KEYCLI_TOKEN"
Relevant response fragment:
{
  "capabilities": {
    "workspace": {
      "liveExecution": {
        "render": {
          "supported": true,
          "configured": true,
          "available": true,
          "reason": "connected",
          "scope": "render service srv-demo",
          "connectionScope": {
            "provider": "render",
            "serviceId": "srv-demo"
          }
        }
      }
    }
  }
}

Safety / redaction

  • Secrets are retrieved via SecretStore.getSecret(ref) at apply time.
  • Secret values are not stored in plan diffs, run events, or audit logs.
  • Connection reads return redacted credentialRef values.