Cloud Security Assessment

Production-grade guide to cloud security assessment covering architecture patterns, implementation strategies, testing approaches, and operational best practices for enterprise engineering teams.

Cloud Security Assessment is a structured evaluation of a cloud environment’s security posture, performed to identify risks, validate controls, and ensure alignment with security policies. It matters when onboarding new services, responding to a security incident, preparing for compliance audits, or planning a cloud migration. The assessment is not a one-off audit but a repeatable process applied across accounts, regions, and workloads.

Defining the Assessment Scope

A Cloud Security Assessment begins with identifying what to evaluate. The scope is defined by three dimensions: cloud provider, service footprint, and organizational requirements.

The assessment must cover all cloud accounts, especially in multi-account setups. For AWS, this means identifying all AWS accounts, their trust relationships (via IAM roles), and which services are enabled in each. The AWS CLI command aws sts get-caller-identity returns the current account ID and region, which can be used to filter results across accounts.

For each account, list all running resources: EC2 instances, S3 buckets, RDS databases, EKS clusters, Lambda functions, and VPCs. Use aws ec2 describe-instances, aws s3 list-buckets, and aws rds describe-db-instances to gather baseline inventory. A common failure is assuming that "all resources are in the account" without cross-referencing AWS Resource Groups or CloudFormation stacks.

The scope includes not only infrastructure but also network and application layers. A service running on EKS must be evaluated for pod security, network policies, ingress controllers, and Helm chart configurations. The assessment must include all CI/CD pipelines, particularly those deploying to cloud environments. Each pipeline’s yaml file should be examined for secrets, build steps, and deployment triggers.

Validating Identity and Access

Access controls are the foundation of cloud security. The assessment must verify that identity is properly configured and enforced across all services.

All cloud accounts should have a central identity provider (IdP) integrated via SAML or OIDC. The assessment checks that each account has at least one IAM role for cross-account access, and that roles are assumed with a well-defined trust policy. For example, an S3 bucket in account A should be accessible by a Lambda function in account B via an IAM role with a trust policy like:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "lambda.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

The assessment validates that all services use least-privilege roles. For a Lambda function, the assessment checks the roleArn in the function configuration, then retrieves the role’s policy document using aws iam get-role-policy.

A frequent failure is confusing Policy and PermissionsBoundary. A role may have a managed policy attached (Policy), but the PermissionsBoundary limits the maximum permissions, even if the attached policy grants more. The assessment must verify that both are in use and that boundaries are aligned with organizational standards.

The assessment also checks for federated access. For example, users authenticated via Okta should be able to assume roles in AWS with a sessionDuration of 1 hour or more. The assessment uses aws sts assume-role with --duration-seconds 3600 and validates that the returned credentials include the SessionToken.

Evaluating Network Security

Network configuration is often under-evaluated. The assessment must verify that network boundaries are properly defined and enforced.

For each VPC, the assessment checks the following:

Use aws ec2 describe-security-groups and aws ec2 describe-network-acls to gather all rules. A common mistake is assuming that security groups are sufficient, but neglecting network ACLs for coarse-grained filtering.

The assessment checks that all public-facing services use Application Load Balancers (ALBs) or Network Load Balancers (NLBs) with HTTPS listeners. Each ALB should have at least one listener with HTTPS, and the listener must have a certificate attached via ACM.

For EKS clusters, the assessment validates that NetworkPolicy is enabled and that all pods are assigned to namespaces with specific policies. Use kubectl get networkpolicy and kubectl describe networkpolicy to verify that pods are isolated from each other, and that ingress/egress rules are applied.

A sharp edge: security groups allow traffic between instances in the same VPC, but do not enforce ingress/egress at the pod level. The assessment must identify where network policies are missing, and where security groups are redundant or misaligned.

Assessing Data Protection

Data security is evaluated across storage, encryption, and access.

All S3 buckets must have versioning enabled, server-side encryption (SSE-S3 or SSE-KMS), and bucket policies that define access. Use aws s3api get-bucket-versioning and aws s3api get-bucket-encryption to verify encryption. The assessment checks that each bucket has a bucket policy that allows access from specific IAM roles or AWS accounts.

For RDS databases, the assessment verifies that encryption is enabled at rest and in transit. Use aws rds describe-db-instances and check the StorageEncrypted and StorageType fields. The assessment also checks that backup encryption is enabled, and that automated snapshots are retained for at least 90 days.

For EKS, the assessment checks that secrets are managed via Kubernetes Secrets and that sensitive data is encrypted at rest. Use kubectl get secrets and kubectl describe secret to verify that secrets are created with type: kubernetes.io/tls, type: kubernetes.io/dockerconfigjson, or type: opaque.

A critical failure mode: encryption keys are not rotated. The assessment checks AWS KMS key rotation schedules using aws kms list-keys and aws kms describe-key. It verifies that each key has AutomaticRotationEnabled: true.

The assessment also validates that data is encrypted in transit. For RDS, it checks that requireSSL is enabled. For EKS, it checks that the cluster’s API server is configured with --tls-cert-file and --tls-private-key-file, and that clients use HTTPS with client certificates.

Validating Runtime and Configuration Security

The assessment evaluates how infrastructure and applications are configured and deployed.

For EC2 instances, the assessment checks that all instances use Amazon Machine Images (AMIs) with consistent configuration. Use aws ec2 describe-images and verify that the ImageId matches a known, hardened AMI. The assessment checks that instances are configured via user data scripts, and that the scripts are versioned and tested.

For EKS clusters, the assessment validates that Helm charts are used for deployments. It checks that each chart has a values.yaml file, and that the chart version is recorded in Chart.yaml. Use helm list --all-namespaces and helm get values <release-name> to verify configuration.

The assessment checks that all services use configuration files that are versioned and applied through CI/CD. For example, a Node.js application should have a config.json file in the container image, and the docker run command should mount environment variables from a .env file.

A common failure: configuration files are not loaded at runtime. The assessment uses docker inspect <container> and kubectl describe pod <pod-name> to verify that environment variables and mounted volumes are correctly applied.

The assessment also checks that all services have health checks and readiness probes. For EKS, it uses kubectl get pod <pod-name> -o yaml and verifies the livenessProbe and readinessProbe fields. For EC2, it checks that Auto Scaling Groups have launch configurations with HealthCheckType: EC2.

Mapping Findings to Security Controls

The final step is to map all findings to a security control framework, such as CIS AWS Foundations Benchmark or ISO 27001.

The assessment produces a report listing each finding with:

The assessment uses a standard format: a JSON file per resource, with a top-level assessment object. For example, a report for an S3 bucket is stored as assessment/s3/my-app-data.json:

{
  "resource": "s3/my-app-data",
  "controls": [
    {
      "control": "CIS-1.1",
      "title": "Ensure all S3 buckets are versioned",
      "result": "pass",
      "evidence": {
        "command": "aws s3api get-bucket-versioning --bucket my-app-data",
        "output": {
          "Status": "Enabled",
          "MfaDelete": "Disabled"
        }
      },
      "risk": "low"
    },
    {
      "control": "CIS-1.3",
      "title": "Ensure S3 buckets are encrypted",
      "result": "fail",
      "evidence": {
        "command": "aws s3api get-bucket-encryption --bucket my-app-data",
        "output": {
          "ServerSideEncryptionConfiguration": {
            "Rules": [
              {
                "ApplyServerSideEncryptionByDefault": {
                  "SSEAlgorithm": "AES256"
                }
              }
            ]
          }
        }
      },
      "risk": "medium"
    }
  ]
}

The assessment uses jq to process and summarize results:

jq -r '
  .[] | 
  select(.result == "fail") | 
  .control + " - " + .title
' assessment/*.json

This produces a list of failed controls, which can be used to prioritize remediation.

Identifying Common Failure Modes

The assessment reveals recurring issues that silently degrade security.

One common failure: IAM roles are created but not assigned to services. The assessment checks that every EC2 instance has IAMInstanceProfile defined, and that the profile is attached to the instance via aws ec2 describe-instances.

Another: security groups allow full 0.0.0.0/0 access to all ports. The assessment checks that each security group has at least one rule with CidrBlock: 0.0.0.0/0, and that the FromPort and ToPort are specified.

A sharp edge: encryption keys are created but not used. The assessment checks that each S3 bucket uses a KMS key, but fails to verify that the key is used for encryption. The command aws s3api get-bucket-encryption --bucket my-app-data returns a ServerSideEncryptionConfiguration, but the assessment must also verify that the SSEAlgorithm is aws:kms and that KMSMasterKeyID is set.

Another: CI/CD pipelines use secrets in plain text. The assessment checks that secrets are stored in a secrets manager (e.g., AWS Secrets Manager, HashiCorp Vault), and that the pipeline retrieves them via API calls. It validates that the AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are loaded from a secrets manager, and not hardcoded in the pipeline YAML.

The assessment also identifies misconfigurations in Kubernetes. For example, a pod may have hostNetwork: true, but the network policy does not allow traffic from the host. The assessment uses kubectl get pod <pod-name> -o yaml and checks spec.hostNetwork and spec.containers[].securityContext.

Finally, the assessment checks that all logs are centralized. It verifies that CloudWatch Logs, EKS audit logs, and application logs are sent to a central logging service (e.g., Elasticsearch, Loki, or Splunk). The assessment uses aws logs describe-log-groups and checks that each log group has a retention policy of at least 30 days.

Summary

A Cloud Security Assessment is not a checklist but a process of discovery. It begins with a clear scope, validates identity and access, evaluates network and data protection, and checks runtime configuration. The findings are mapped to security controls, and common failure modes are identified. The assessment is repeatable, consistent, and grounded in real tooling and data flows—proving that the cloud environment is not just running, but secure.

This page was rewritten on 16 October 2026. It replaced a templated version that was not specific to its own title. How these pages are written and checked. If anything here is wrong, tell us at [email protected] and we will correct it.