VPC / Private Cloud Deployment
Reference for running Cybros as a single-tenant install inside a private VPC, using managed datastores and a private ingress. This is the "cloud-native but isolated" story: your account, your keys, your network.
Use deploy/helm/cybros/values-vpc.yaml as the starting overlay.
Topology
Private DNS cybros.vpc.internal
│
┌────────────▼────────────┐ internal ALB/NLB (TLS)
│ Ingress (private) │ scheme: internal
└───────┬─────────┬────────┘
│ │
┌────▼───┐ ┌───▼────┐ Private subnets (no IGW route)
│ web │ │ api │ ┌──────────────────────────────┐
│ pods │ │ pods │──┼─▶ RDS / Aurora Postgres │
└────────┘ └───┬────┘ │ (managed, encrypted, HA) │
│ └──────────────────────────────┘
┌────▼────┐ ┌──────────────────────────────┐
│ worker │──▶│ ElastiCache Redis (managed) │
│ celery-B│ └──────────────────────────────┘
└────┬────┘
│ (controlled egress via NAT + SG allowlist)
┌────────────────────────┼───────────────────────────┐
▼ ▼ ▼
GitHub App IdP (SSO/SCIM) KMS (CMEK)
api.github.com your identity provider key operations
Networking
-
Private subnets for all Cybros pods and managed datastores. No public IPs.
-
Ingress = internal load balancer (
scheme: internal). Expose to users via VPN, private link, or a corporate proxy — never a public listener. -
Egress is default-deny, opened only for the integrations you enable:
Destination When Notes api.github.com/ GHESGitHub App enabled Continuous Security Guard Your IdP SSO/SCIM enabled SAML/OIDC + provisioning Cloud KMS CMEK enabled envelope-key operations Payment API PAYMENT_PROVIDER != stubStripe/Razorpay Anthropic AI_PROVIDER = anthropicleave stubto avoidEnforce with a
NetworkPolicy(pod egress) and security-group / NAT rules.
Managed datastores
- Postgres: RDS/Aurora, encrypted at rest (with your KMS key), Multi-AZ,
automated backups + PITR.
DATABASE_URL=postgresql+asyncpg://...:5432/cybros. - Redis: ElastiCache, in a private subnet group.
REDIS_URL=redis://...:6379/0. - The chart's bundled subcharts stay disabled (
postgresql.enabled=false,redis.enabled=false).
Secrets & keys (no static credentials)
-
secrets.create=false,externalSecret.enabled=true— the chart references a Secret managed by the External Secrets Operator (or Sealed Secrets / Vault CSI) synced from your cloud secrets manager. -
The pod ServiceAccount is annotated for IRSA / Workload Identity so pods reach Secrets Manager and KMS without long-lived keys:
serviceAccount: annotations: eks.amazonaws.com/role-arn: arn:aws:iam::<acct>:role/cybros-app -
CMEK:
SECRET_ENCRYPTION_KEYis derived/unwrapped from your KMS key (cmek.provider: aws-kms,cmek.keyId: arn:...). Seedocs/data-residency.md.
Install
helm dependency build deploy/helm/cybros
helm upgrade --install cybros deploy/helm/cybros \
-f deploy/helm/cybros/values-vpc.yaml \
--namespace cybros --create-namespace \
--set ingress.host=cybros.vpc.internal \
--set cmek.keyId=arn:aws:kms:us-east-1:<acct>:key/<id>
The pre-install migration Job runs alembic upgrade head against RDS before the
app rolls. Verify residency/mode:
curl -s https://cybros.vpc.internal/api/v1/system/deployment
# { "mode":"private", "data_residency":"us", "features": { "cmek": true, ... } }
HA & scaling
api/webrun 2+ replicas;autoscaling.enabled=truegives the api an HPA.podDisruptionBudget.enabled=truekeeps ≥1 api pod during node drains.- Keep the
workerat 1 replica with-B(embedded beat) to avoid duplicate scheduled jobs; scale scan throughput by splitting beat out and adding beat-less worker replicas.