Render
Sync KeyEnv secrets to Render services.
Render Integration
Sync secrets from KeyEnv to your Render services.
Prerequisites
- Render account with a deployed service
- Render API key
- KeyEnv service token with read access
Integration Scripts
The integrations/render/
directory contains ready-to-use sync scripts in Bash, TypeScript, and Python.
These scripts use the Render API directly (no KeyEnv CLI required):
# Clone or copy from the repo
cd integrations/render
export KEYENV_TOKEN=your-keyenv-token
export RENDER_API_KEY=your-render-api-key
export RENDER_SERVICE_ID=srv-xxxxxxxxxxxxx
./sync-to-render.sh # Bash
npx ts-node sync-to-render.ts # TypeScript
python3 sync-to-render.py # PythonBy default the scripts merge KeyEnv secrets with existing Render env vars
(KeyEnv takes precedence). Set REPLACE_ALL=true to replace all Render vars.
Quick Sync
For a one-off sync using the KeyEnv CLI:
#!/bin/bash
set -euo pipefail
export KEYENV_TOKEN=your-keyenv-token
export RENDER_API_KEY=your-render-api-key
RENDER_SERVICE_ID=srv-xxxxxxxxxxxxx
# Export and sync
secrets=$(keyenv export -p YOUR_PROJECT_ID -e production --format json)
echo "$secrets" | jq '[.secrets[] | {key: .key, value: .value}]' | \
curl -s -X PUT "https://api.render.com/v1/services/$RENDER_SERVICE_ID/env-vars" \
-H "Authorization: Bearer $RENDER_API_KEY" \
-H "Content-Type: application/json" \
-d @-
echo "Secrets synced to Render!"Find Your Service ID
- Go to your Render Dashboard
- Click on your service
- The Service ID is in the URL:
dashboard.render.com/web/srv-xxxxxxxxxxxxx
Or use the API:
curl -s "https://api.render.com/v1/services" \
-H "Authorization: Bearer $RENDER_API_KEY" | \
jq '.[] | {name: .service.name, id: .service.id}'Sync Script
Create a reusable sync script:
#!/bin/bash
# sync-to-render.sh
set -euo pipefail
: "${KEYENV_TOKEN:?KEYENV_TOKEN is required}"
: "${RENDER_API_KEY:?RENDER_API_KEY is required}"
PROJECT_ID="${KEYENV_PROJECT:-YOUR_PROJECT_ID}"
ENVIRONMENT="${KEYENV_ENV:-production}"
SERVICE_ID="${RENDER_SERVICE_ID:-srv-xxxxxxxxxxxxx}"
echo "Syncing KeyEnv ($ENVIRONMENT) to Render ($SERVICE_ID)..."
# Export secrets from KeyEnv
secrets=$(keyenv export -p "$PROJECT_ID" -e "$ENVIRONMENT" --format json)
# Transform and sync to Render
echo "$secrets" | jq '[.secrets[] | {key: .key, value: .value}]' | \
curl -s -X PUT "https://api.render.com/v1/services/$SERVICE_ID/env-vars" \
-H "Authorization: Bearer $RENDER_API_KEY" \
-H "Content-Type: application/json" \
-d @-
echo "Done! Render will automatically redeploy."CI/CD Integration
GitHub Actions
name: Deploy to Render
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install KeyEnv CLI
run: curl -fsSL https://keyenv.dev/install.sh | bash
- name: Sync secrets to Render
run: |
export PATH="$HOME/.keyenv/bin:$PATH"
secrets=$(keyenv export -p ${{ vars.KEYENV_PROJECT }} -e production --format json)
echo "$secrets" | jq '[.secrets[] | {key: .key, value: .value}]' | \
curl -s -X PUT "https://api.render.com/v1/services/${{ vars.RENDER_SERVICE_ID }}/env-vars" \
-H "Authorization: Bearer ${{ secrets.RENDER_API_KEY }}" \
-H "Content-Type: application/json" \
-d @-
env:
KEYENV_TOKEN: ${{ secrets.KEYENV_TOKEN }}
- name: Trigger deploy
run: |
curl -X POST "https://api.render.com/v1/services/${{ vars.RENDER_SERVICE_ID }}/deploys" \
-H "Authorization: Bearer ${{ secrets.RENDER_API_KEY }}"Multiple Services
Sync to multiple Render services:
#!/bin/bash
# sync-all-services.sh
declare -A SERVICES=(
["web"]="srv-web123"
["api"]="srv-api456"
["worker"]="srv-worker789"
)
for name in "${!SERVICES[@]}"; do
service_id="${SERVICES[$name]}"
echo "Syncing to $name ($service_id)..."
secrets=$(keyenv export -p YOUR_PROJECT_ID -e production --format json)
echo "$secrets" | jq '[.secrets[] | {key: .key, value: .value}]' | \
curl -s -X PUT "https://api.render.com/v1/services/$service_id/env-vars" \
-H "Authorization: Bearer $RENDER_API_KEY" \
-H "Content-Type: application/json" \
-d @-
doneEnvironment Groups
Render supports environment groups for sharing secrets across services. Sync to a group:
# Get environment group ID
curl -s "https://api.render.com/v1/env-groups" \
-H "Authorization: Bearer $RENDER_API_KEY" | jq '.'
# Sync to environment group
ENV_GROUP_ID="evg-xxxxxxxxxxxxx"
secrets=$(keyenv export -p YOUR_PROJECT_ID -e production --format json)
echo "$secrets" | jq '[.secrets[] | {key: .key, value: .value}]' | \
curl -s -X PUT "https://api.render.com/v1/env-groups/$ENV_GROUP_ID/env-vars" \
-H "Authorization: Bearer $RENDER_API_KEY" \
-H "Content-Type: application/json" \
-d @-Selective Sync
Sync only specific secrets:
secrets=$(keyenv export -p YOUR_PROJECT_ID -e production --format json)
# Only sync secrets starting with "DB_" or "API_"
echo "$secrets" | \
jq '[.secrets[] | select(.key | test("^(DB_|API_)")) | {key: .key, value: .value}]' | \
curl -s -X PUT "https://api.render.com/v1/services/$SERVICE_ID/env-vars" \
-H "Authorization: Bearer $RENDER_API_KEY" \
-H "Content-Type: application/json" \
-d @-Verify Sync
Check current environment variables:
curl -s "https://api.render.com/v1/services/$SERVICE_ID/env-vars" \
-H "Authorization: Bearer $RENDER_API_KEY" | \
jq '.[] | {key: .envVar.key}'render.yaml Configuration
For Blueprint-based deployments, non-sensitive config goes in render.yaml:
services:
- type: web
name: myapp
env: node
buildCommand: npm install && npm run build
startCommand: npm start
envVars:
- key: NODE_ENV
value: production
- key: LOG_LEVEL
value: info
# Sensitive values synced from KeyEnv via APIBest Practices
- Use environment groups - Share common secrets across services
- Automate syncing - Run sync in CI/CD before deployments
- Don't mix methods - Either use render.yaml OR API sync, not both for the same keys
- Version control non-secrets - Put non-sensitive config in render.yaml
Troubleshooting
API Rate Limits
Render has API rate limits. If syncing many services:
for service_id in "${SERVICE_IDS[@]}"; do
# ... sync ...
sleep 1 # Add delay between requests
doneService Not Redeploying
Trigger a manual deploy after syncing:
curl -X POST "https://api.render.com/v1/services/$SERVICE_ID/deploys" \
-H "Authorization: Bearer $RENDER_API_KEY"Permission Errors
Verify your API key has the right permissions:
curl -s "https://api.render.com/v1/owners" \
-H "Authorization: Bearer $RENDER_API_KEY"