CloudOps SRE Platform uses a short-lived EKS environment to validate network, identity, secret, image, and deployment controls. This document separates the controls implemented in the repository from the safeguards a persistent production environment would still need.
The internet-facing AWS Application Load Balancer created through Kubernetes Ingress is the application entry point.
Runtime path:
- User traffic reaches the public ALB.
- ALB sends traffic to the Kubernetes Ingress.
- Ingress routes to the frontend ClusterIP Service.
- The frontend Nginx container serves React assets and proxies
/api/*to the backend ClusterIP Service. - FastAPI talks to PostgreSQL through the private RDS endpoint.
The worker node group runs in private subnets and uses one NAT gateway for outbound access. RDS runs in dedicated database subnets, has no public endpoint, and uses a route table without an internet or NAT route.
The EKS API has private access enabled. Terraform disables public API access
when eks_public_access_cidrs is empty. The July 25 validation run enabled the
public endpoint for the operator's temporary /32 address; the allowlist never
included 0.0.0.0/0 or ::/0.
Terraform creates an RDS security group that accepts PostgreSQL traffic on port
5432 only from the EKS cluster security group.
RDS controls in the validation environment:
publicly_accessible = false- storage encryption
- PostgreSQL logs exported to CloudWatch
- database credentials generated by Terraform
- database connection details stored in AWS Secrets Manager
The validation environment disables backup retention and deletion protection and skips the final snapshot so Terraform can destroy it on the same day. Those settings fit the disposable environment and do not fit a persistent database.
Terraform generates the database password and writes the connection details to AWS Secrets Manager.
During the manual AWS deployment, GitHub Actions reads the Secrets Manager value and creates a Kubernetes Secret named cloudops-database in the cloudops namespace. The backend reads the database_url key from that Kubernetes Secret.
The repository also documents an External Secrets Operator path in external-secrets.md. That path lets the cluster sync the database URL through IRSA instead of asking the deployment workflow to create the Kubernetes Secret.
No AWS database credential is committed to Git. The Compose files use the
documented cloudops credential only for the local development database.
Terraform state contains the generated password and secret value even though the configuration does not. The short-lived single-operator workflow keeps local state out of Git. A persistent or shared environment needs encrypted remote state, restricted state access, locking, and audit logging as described in terraform-state.md.
Terraform creates separate IAM roles for:
- the EKS control plane
- the EKS worker nodes
- the AWS Load Balancer Controller
The AWS Load Balancer Controller uses IRSA. Terraform creates an EKS OIDC provider and a role trust policy that allows sts:AssumeRoleWithWebIdentity only for the configured Kubernetes ServiceAccount:
system:serviceaccount:<aws_load_balancer_controller_namespace>:<aws_load_balancer_controller_service_account>
The trust policy also checks the OIDC audience value:
sts.amazonaws.com
This attaches ALB management permissions to the controller ServiceAccount instead of every application pod.
The application pods do not use their own workload IRSA role in the completed AWS validation run. They receive database configuration through the Kubernetes Secret populated from Secrets Manager.
AWS deployment jobs use GitHub Actions OIDC with AWS_ROLE_TO_ASSUME. The
workflow requests short-lived AWS credentials and does not require static AWS
access keys in repository secrets. The AWS role and its GitHub trust policy are
account prerequisites; this repository does not provision them.
The image-publish job can use a GitHub-hosted runner. The Helm deployment job
requires a self-hosted Linux runner labeled cloudops-deploy with VPC access
to the private EKS endpoint. This avoids reopening the cluster API for a hosted
runner.
The deployment role needs enough permission to:
- log in to ECR and push backend/frontend images
- describe the EKS cluster and update kubeconfig
- read the database secret from Secrets Manager
- deploy Kubernetes resources through Helm
The role trust policy should restrict assumption by repository, branch, and GitHub environment. A shared production platform should also separate image publishing, cluster deployment, and secret-read permissions.
The default CI path runs without creating AWS resources.
Security-related checks include:
- backend unit tests
- frontend lockfile install, high/critical dependency audit, and production build
- Docker image builds
- Helm lint and rendered numeric non-root security-context validation
- strict Kubernetes manifest validation with kubeconform
- Terraform format and validate
- Terraform cost/security guardrail script
- blocking Checkov scan against
infra/
AWS deployment requires workflow_dispatch with deploy_to_aws = true. The
publish job waits for ECR scans and blocks the rollout when either image has a
critical or high finding. The controlled July 25
runtime record
reports zero findings at all reported severities for both deployed images.
Both ECR repositories reject tag replacement, so the tag scanned by the
publish job cannot move to another image before Helm deploys it.
Repository rules require a pull request and successful CI workflows before
main can advance, and reject force pushes.
The pinned Checkov 3.2.403 scan is a blocking CI gate. The reviewed
configuration reports 101 passed checks, 0 failed checks, and 31 explicitly
skipped checks.
Each accepted exception is attached to its Terraform resource with its policy ID and rationale. The exceptions fall into three groups:
- Deliberate same-day tradeoffs: seven-day log retention, no RDS backups, deletion protection, final snapshot, or Multi-AZ.
- Persistent-environment controls not implemented: customer-managed KMS keys, VPC flow logs, EKS secret encryption, RDS enhanced monitoring, and Secrets Manager rotation.
- Static-analysis limitations: Checkov cannot prove the conditional EKS public endpoint default or the current support status of the pinned EKS version.
An unlisted Checkov finding fails CI. Accepted exceptions document the disposable environment's boundaries; they are not a general production security pass.
- The validation ALB listener uses HTTP rather than ACM-managed TLS.
- The validation RDS instance disables backups and deletion protection to support same-day teardown.
- The AWS values enable default-deny and scoped frontend, backend, and migration NetworkPolicies. Enforcement depends on a NetworkPolicy-capable CNI.
- Workloads use non-root execution, runtime-default seccomp, dropped capabilities, no privilege escalation, and read-only root filesystems.
- Pod Security Admission is a namespace-level control. Namespace provisioning
must apply the
restrictedenforce/audit/warn labels before Helm deployment. - Application pods do not use dedicated workload IRSA roles in the completed run.
- The retained run records cover controlled, short-lived runs. They do not establish long-window SLO compliance, capacity limits, or managed AWS recovery behavior.
- add ACM TLS and HTTPS-only ALB listener rules
- add AWS WAF for public endpoint protection
- encrypt EKS secrets, ECR repositories, logs, and application secrets with customer-managed KMS keys where the threat model requires them
- enable VPC flow logs and tighter security-group egress
- enable RDS backup retention, deletion protection, and final snapshots
- enable RDS enhanced monitoring and Performance Insights
- move database secret sync to External Secrets Operator with IRSA
- add Secrets Manager rotation
- verify the selected CNI enforces NetworkPolicy and review database subnet CIDRs for each environment
- manage Pod Security Admission labels through namespace provisioning policy
- separate CI roles for image publishing, deployment, and secret reads
- enable CloudTrail, GuardDuty, and AWS Config for persistent account-level monitoring