Security guidelines for deploying and using Sindri.
Sindri's security model is based on:
- Isolated Environments - Each deployment is isolated
- SSH-Based Access - No password authentication
- Secrets Management - Provider-specific secret handling
- User Separation - Non-root developer user in containers
- Network Isolation - Provider network policies
- SBOM Tracking - Software bill of materials for auditing
Best Practices:
-
Use Ed25519 keys:
ssh-keygen -t ed25519 -C "[email protected]" -
Use passphrase protection:
ssh-keygen -t ed25519 -C "[email protected]" # Enter passphrase when prompted
-
Use ssh-agent:
eval "$(ssh-agent -s)" ssh-add ~/.ssh/id_ed25519
-
Rotate keys regularly:
# Generate new key ssh-keygen -t ed25519 -C "[email protected]" -f ~/.ssh/id_ed25519_new # Update Fly.io flyctl ssh issue --agent -a my-app # Remove old key rm ~/.ssh/id_ed25519_old*
Fly.io:
# List authorized users
flyctl ssh issue --help
# Revoke access
# Remove user from Fly.io organizationKubernetes:
# Use RBAC for access control
kubectl create rolebinding dev-access \
--clusterrole=edit \
--user=developer \
--namespace=dev-envsBad:
# sindri.yaml - NEVER DO THIS
environment:
ANTHROPIC_API_KEY: sk-ant-actual-key # WRONG!Good:
# sindri.yaml
# Secrets managed via provider mechanismsSet secrets:
flyctl secrets set ANTHROPIC_API_KEY=sk-ant-... -a my-app
flyctl secrets set GITHUB_TOKEN=ghp_... -a my-appBest practices:
-
Use per-environment secrets:
flyctl secrets set API_KEY=sk-ant-dev... -a my-dev-app flyctl secrets set API_KEY=sk-ant-prod... -a my-prod-app
-
Rotate secrets regularly:
# Generate new API key # Update secret flyctl secrets set ANTHROPIC_API_KEY=sk-ant-new... -a my-app
-
Audit secret usage:
# List secrets (values hidden) flyctl secrets list -a my-app
Use .env files:
# .env (not committed)
ANTHROPIC_API_KEY=sk-ant-...
GITHUB_TOKEN=ghp_...Ensure .gitignore:
# .gitignore
.env
.env.*
!.env.exampleUse docker-compose secrets:
# docker-compose.yml
services:
sindri:
env_file: .envCreate secret:
kubectl create secret generic sindri-secrets \
--from-literal=ANTHROPIC_API_KEY=sk-ant-... \
--from-literal=GITHUB_TOKEN=ghp_... \
--namespace=dev-envsUse sealed secrets (recommended):
# Install sealed-secrets controller
kubectl apply -f https://github.com/bitnami-labs/sealed-secrets/releases/download/v0.24.0/controller.yaml
# Create sealed secret
kubeseal --format=yaml < secret.yaml > sealed-secret.yaml
# Commit sealed-secret.yaml (encrypted)
git add sealed-secret.yamlDefault security:
- Private networking within organization
- Public IP with firewall rules
- SSH port exposed (configurable)
Restrict SSH access:
# fly.toml (generated)
[[services]]
[[services.ports]]
port = 10022
handlers = ["tcp"]
# Add IP allowlist
allowlist = ["1.2.3.4/32", "5.6.7.8/32"]Use Fly.io private network:
# fly.toml
[env]
FLY_PRIVATE_NETWORK = "true"Restrict ingress:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: sindri-policy
namespace: dev-envs
spec:
podSelector:
matchLabels:
app: sindri
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
access: allowed
ports:
- protocol: TCP
port: 22Restrict Docker host access:
# Allow only specific IPs to connect
sudo ufw allow from 1.2.3.4 to any port 22
sudo ufw enableSindri runs as developer user (UID 1001), not root.
Verify:
whoami # developer
id # uid=1001(developer)System files in /docker/lib are owned by root and read-only.
Verify:
ls -la /docker/lib
# drwxr-xr-x root rootContainers run with minimal capabilities.
Docker:
# docker-compose.yml
services:
sindri:
cap_drop:
- ALL
cap_add:
- NET_BIND_SERVICE # Only if neededKubernetes:
# securityContext
securityContext:
capabilities:
drop:
- ALL
readOnlyRootFilesystem: false # /workspace is writable
runAsNonRoot: true
runAsUser: 1001Track all installed software:
# Generate SBOM
./cli/extension-manager bom --format cyclonedx > sbom.cdx.json
# Scan for vulnerabilities
grype sbom:sbom.cdx.json
# Or with Trivy
trivy sbom sbom.cdx.jsonScan Docker image:
# Using Trivy
trivy image sindri:latest
# Using Grype
grype sindri:latest
# Using Docker Scout
docker scout cves sindri:latestKeep base image updated:
# Dockerfile
FROM ubuntu:24.04 # Use specific version, not 'latest'Rebuild regularly:
# Monthly or after security updates
pnpm buildValidate extensions:
# Validate all extensions
./cli/extension-manager validate-all
# Check BOM for vulnerabilities
./cli/extension-manager bom --format cyclonedx | grype sbom:-Use trusted sources:
- npm registry:
registry.npmjs.org - PyPI:
pypi.org - mise plugins: Official mise registry
Avoid:
- Unknown package sources
- Unverified binaries
- Unofficial mirrors
Fly.io:
# View activity logs
flyctl auth logs -a my-appKubernetes:
# Enable audit logging
# Configure kube-apiserver with --audit-log-pathContainer logs:
# Extension installation logs
cat /workspace/.system/logs/*.log
# Command history
cat ~/.bash_historyGenerate compliance report:
# SBOM in SPDX format
./cli/extension-manager bom --format spdx > sbom.spdx
# Scan against CVE database
grype sbom:sbom.spdxDeployment:
- SSH key-based authentication only
- Secrets via provider mechanisms
- Network policies/firewall configured
- Non-root container user
- Read-only system files
- Resource limits set
- Auto-updates enabled (Fly.io)
Operations:
- Regular SSH key rotation
- Regular secret rotation
- SBOM generation and scanning
- Docker image updates
- Extension updates
- Audit log review
- Backup verification
Development:
- .env files in .gitignore
- No secrets in code
- SBOM tracked in version control
- Security scanning in CI/CD
- Code review process
If you suspect compromise:
-
Isolate immediately:
# Fly.io: Stop machine flyctl machine stop <machine-id> -a my-app # Docker: Stop container docker compose stop # Kubernetes: Scale to zero kubectl scale statefulset my-app --replicas=0 -n dev-envs
-
Rotate secrets:
# Generate new API keys # Update secrets flyctl secrets set ANTHROPIC_API_KEY=sk-ant-new... -a my-app
-
Rotate SSH keys:
# Generate new SSH key ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_new # Update Fly.io flyctl ssh issue --agent -a my-app
-
Review logs:
# Check for suspicious activity flyctl logs -a my-app # Check command history cat ~/.bash_history
-
Recreate environment:
# Destroy compromised environment ./cli/sindri teardown # Redeploy clean environment ./cli/sindri deploy
Report security vulnerabilities:
- Email: security@[repository-owner-domain]
- GitHub Security Advisories: Private disclosure
- Do not open public issues for security vulnerabilities
- Security Audit Report - Comprehensive security assessment and remediation status
- Bill of Materials
- Deployment Guide
- Configuration Reference
- Troubleshooting