Deployment
cassh server can be deployed to various platforms. Choose based on your needs:
| Platform | Cost | Complexity | Best For |
|---|---|---|---|
| Render | Free tier | Low | Quick setup, auto-deploy |
| Fly.io | <$5/mo | Low | Edge deployment, scaling |
| Railway | <$5/mo | Low | Simple deploys |
| Google Cloud Run | Pay-per-use | Low | GCP ecosystem, auto-scaling |
| AWS App Runner | Pay-per-use | Medium | AWS ecosystem, enterprise |
| Azure Container Apps | Pay-per-use | Medium | Azure/Entra integration |
| Self-Hosted | ~$5/mo | Medium | Full control |
Render
Render offers a free tier with auto-deploy from GitHub.
Step 1: Connect Repository
- Push your repo to GitHub
- Go to render.com
- Click New → Web Service
- Connect your GitHub repo
Step 2: Configure Build
- Build Command:
go build -o cassh-server ./cmd/cassh-server - Start Command:
./cassh-server
Step 3: Set Environment Variables
Add these in the Render dashboard:
CASSH_SERVER_URL=https://your-app.onrender.com
CASSH_OIDC_CLIENT_ID=your-client-id
CASSH_OIDC_CLIENT_SECRET=your-client-secret
CASSH_OIDC_TENANT=your-tenant-id
CASSH_CA_PRIVATE_KEY=-----BEGIN OPENSSH PRIVATE KEY-----...
Step 4: Deploy
Click Create Web Service. Render will build and deploy automatically.
Using render.yaml
The repo includes a render.yaml for infrastructure-as-code deployment.
Fly.io
Step 1: Install Fly CLI
Step 2: Login
Step 3: Launch App
Step 4: Set Secrets
fly secrets set CASSH_SERVER_URL="https://cassh-yourcompany.fly.dev"
fly secrets set CASSH_OIDC_CLIENT_ID="your-client-id"
fly secrets set CASSH_OIDC_CLIENT_SECRET="your-client-secret"
fly secrets set CASSH_OIDC_TENANT="your-tenant-id"
fly secrets set CASSH_CA_PRIVATE_KEY="$(cat ca_key)"
Step 5: Configure fly.toml
app = "cassh-yourcompany"
primary_region = "sjc"
[build]
[http_service]
internal_port = 8080
force_https = true
auto_stop_machines = true
auto_start_machines = true
min_machines_running = 0
[env]
PORT = "8080"
Step 6: Deploy
Your server is live at https://cassh-yourcompany.fly.dev
Railway
Step 1: Install CLI
Step 2: Login and Initialize
Step 3: Set Variables
railway variables set CASSH_SERVER_URL="https://your-app.up.railway.app"
railway variables set CASSH_OIDC_CLIENT_ID="your-client-id"
# ... set other variables
Step 4: Deploy
Google Cloud Run
Google Cloud Run is a serverless container platform with automatic scaling and pay-per-use pricing.
Step 1: Install Google Cloud CLI
Step 2: Authenticate and Configure
gcloud auth login
gcloud config set project YOUR_PROJECT_ID
gcloud services enable run.googleapis.com containerregistry.googleapis.com
Step 3: Set Environment Variables
export CASSH_OIDC_CLIENT_ID='your-client-id'
export CASSH_OIDC_CLIENT_SECRET='your-client-secret'
export CASSH_OIDC_TENANT='your-tenant-id'
export CASSH_CA_PRIVATE_KEY="$(cat ca_key)"
Step 4: Deploy
Use the included deployment script:
Or deploy manually:
# Build and push image
gcloud builds submit --tag gcr.io/YOUR_PROJECT/cassh
# Deploy to Cloud Run
gcloud run deploy cassh \
--image gcr.io/YOUR_PROJECT/cassh \
--platform managed \
--region us-central1 \
--allow-unauthenticated \
--set-env-vars "CASSH_OIDC_CLIENT_ID=$CASSH_OIDC_CLIENT_ID" \
--set-env-vars "CASSH_OIDC_CLIENT_SECRET=$CASSH_OIDC_CLIENT_SECRET" \
--set-env-vars "CASSH_OIDC_TENANT=$CASSH_OIDC_TENANT" \
--set-env-vars "CASSH_CA_PRIVATE_KEY=$CASSH_CA_PRIVATE_KEY"
Step 5: Get Service URL
Update your Entra app redirect URI to https://YOUR_SERVICE_URL/auth/callback.
Useful Commands
AWS App Runner
AWS App Runner is a fully managed container service that handles deployment, scaling, and load balancing.
Step 1: Install AWS CLI
Step 2: Configure Credentials
Step 3: Set Environment Variables
export CASSH_OIDC_CLIENT_ID='your-client-id'
export CASSH_OIDC_CLIENT_SECRET='your-client-secret'
export CASSH_OIDC_TENANT='your-tenant-id'
export CASSH_CA_PRIVATE_KEY="$(cat ca_key)"
Step 4: Deploy
Use the included deployment script:
The script will:
- Create an ECR repository
- Build and push the Docker image
- Create IAM roles for App Runner
- Deploy the service with health checks
- Configure OAuth redirect URLs
Step 5: Get Service URL
aws apprunner list-services --query "ServiceSummaryList[?ServiceName=='cassh'].ServiceUrl" --output text
Update your Entra app redirect URI to https://YOUR_SERVICE_URL/auth/callback.
Useful Commands
Azure Container Apps
Azure Container Apps is a serverless container platform that integrates seamlessly with Microsoft Entra ID.
Step 1: Install Azure CLI
Step 2: Login
Step 3: Set Environment Variables
export CASSH_OIDC_CLIENT_ID='your-client-id'
export CASSH_OIDC_CLIENT_SECRET='your-client-secret'
export CASSH_OIDC_TENANT='your-tenant-id'
export CASSH_CA_PRIVATE_KEY="$(cat ca_key)"
Step 4: Deploy
Use the included deployment script:
The script will:
- Create a resource group
- Create an Azure Container Registry
- Build and push the Docker image
- Create a Container Apps environment
- Deploy the service with ingress
Step 5: Get Service URL
az containerapp show --name cassh --resource-group cassh-rg --query 'properties.configuration.ingress.fqdn' --output tsv
Update your Entra app redirect URI to https://YOUR_SERVICE_URL/auth/callback.
Useful Commands
Self-Hosted (VPS)
Any $5/mo VPS works (DigitalOcean, Linode, Vultr, Hetzner).
Step 1: Build on Server
Step 2: Create Systemd Service
# /etc/systemd/system/cassh.service
[Unit]
Description=cassh SSH Certificate Server
After=network.target
[Service]
Type=simple
User=cassh
WorkingDirectory=/opt/cassh
EnvironmentFile=/etc/cassh/cassh.env
ExecStart=/opt/cassh/cassh-server
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
Step 3: Create Environment File
# /etc/cassh/cassh.env
CASSH_SERVER_URL=https://cassh.yourcompany.com
CASSH_OIDC_CLIENT_ID=your-client-id
CASSH_OIDC_CLIENT_SECRET=your-client-secret
CASSH_OIDC_TENANT=your-tenant-id
CASSH_CA_PRIVATE_KEY_PATH=/etc/cassh/ca_key
Step 4: Start Service
Step 5: Configure Reverse Proxy
Use nginx or Caddy for HTTPS termination.
Caddy (recommended):
nginx:
server {
listen 443 ssl http2;
server_name cassh.yourcompany.com;
ssl_certificate /etc/letsencrypt/live/cassh.yourcompany.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/cassh.yourcompany.com/privkey.pem;
location / {
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
Docker
A Dockerfile is included for containerized deployments:
docker build -t cassh-server .
docker run -p 8080:8080 \
-e CASSH_SERVER_URL="https://cassh.yourcompany.com" \
-e CASSH_OIDC_CLIENT_ID="your-client-id" \
-e CASSH_OIDC_CLIENT_SECRET="your-client-secret" \
-e CASSH_OIDC_TENANT="your-tenant-id" \
-e CASSH_CA_PRIVATE_KEY="$(cat ca_key)" \
cassh-server
Update Entra Redirect URI
After deployment, update your Entra app's redirect URI to match your production URL:
- Go to Azure Portal → Entra ID → App registrations
- Select your cassh app
- Go to Authentication
- Update the redirect URI to
https://your-production-url/auth/callback