AWS SCPs

Mapping AWS SCPs to SOC 2 CC6: A Practical Reference

Maya Soren
SOC 2 and AWS SCP compliance mapping concept

SOC 2 Type II audits surface the same question repeatedly: "Where is the evidence that your access controls are enforced, not just documented?" For teams running workloads on AWS, Service Control Policies are the answer to a meaningful subset of CC6 — but only if you've written them to map to specific criteria.

This is a working reference, not a compliance playbook. We're not claiming that SCPs alone get you to SOC 2 readiness. We're saying that CC6 has a cluster of logical access controls where SCPs are the right enforcement mechanism, and those mappings are concrete enough to document and test.

CC6 Scope in Brief

CC6 (Logical and Physical Access Controls) is the broadest common criteria category in SOC 2. It covers how an organization restricts access to information, systems, and infrastructure. The sub-criteria most relevant to AWS environment controls are:

  • CC6.1 — Logical access security software, infrastructure, and architectures are implemented to protect against threats from sources outside its system boundaries
  • CC6.2 — Prior to issuing system credentials and granting system access, the entity registers and authorizes new internal and external users
  • CC6.3 — The entity authorizes, modifies, or removes access to data, software, functions, and other protected information assets based on approved and documented access requests and the results of access reviews
  • CC6.6 — Logical access security measures restrict access to information assets, including those in the cloud, to authorized users, internal and external components, and program output
  • CC6.7 — The entity restricts the transmission of information to authorized external parties and protects the confidentiality and integrity of information transmitted over public networks

CC6.1 and CC6.6 have the most direct SCP analogs. CC6.3 is partially addressable through SCPs combined with IAM controls. CC6.7 maps to network-level SCPs around VPC endpoints and public access restrictions.

The SCP-to-CC6 Mapping

CC6.1 — Restricting access from outside system boundaries

This criterion asks whether access from outside your defined system boundary is restricted. For AWS, that boundary is usually the account or OU level. Two SCP patterns address this directly.

First, deny access from outside approved regions — this prevents resources from being created (and therefore accessed) in regions your organization hasn't approved:

{
  "Sid": "DenyUnapprovedRegions",
  "Effect": "Deny",
  "NotAction": [
    "iam:*",
    "organizations:*",
    "support:*",
    "sts:*",
    "cloudfront:*",
    "route53:*"
  ],
  "Resource": "*",
  "Condition": {
    "StringNotEquals": {
      "aws:RequestedRegion": [
        "us-east-1",
        "us-west-2"
      ]
    }
  }
}

Second, deny public access to S3 at the org level — prevents workload owners from accidentally opening data-plane access to the public internet:

{
  "Sid": "DenyS3PublicAccess",
  "Effect": "Deny",
  "Action": [
    "s3:PutBucketPublicAccessBlock",
    "s3:DeletePublicAccessBlock"
  ],
  "Resource": "*",
  "Condition": {
    "StringNotEquals": {
      "s3:DataAccessPointArn": "arn:aws:*"
    }
  }
}

For audit evidence, you document these SCPs, show they're attached to the relevant OUs, and provide a test showing the denied actions actually fail. That's your CC6.1 control evidence for the AWS boundary.

CC6.3 — Access modification and removal based on approved requests

SCPs can't enforce the approval workflow itself (that's an IAM Access Analyzer or identity governance problem), but they can enforce that privilege escalation paths are blocked at the org level. The most important pattern here is preventing IAM role creation with admin access, or attaching AdministratorAccess managed policies without a permission boundary:

{
  "Sid": "DenyAdminRoleWithoutBoundary",
  "Effect": "Deny",
  "Action": [
    "iam:CreateRole",
    "iam:AttachRolePolicy"
  ],
  "Resource": "*",
  "Condition": {
    "ArnNotLike": {
      "iam:PermissionsBoundary": "arn:aws:iam::*:policy/OrgApprovedBoundary"
    }
  }
}

The audit evidence here is: any IAM role created in the org must have an approved permission boundary. That boundary policy is what your access reviewers actually control. The SCP is the enforcement mechanism that makes the process real rather than advisory.

We should be clear: this SCP controls the constraint, not the approval workflow. CC6.3 requires both — the workflow plus the technical control. The SCP handles the technical half.

CC6.6 — Restricting logical access to authorized users

This is where SCPs do some of their most auditor-visible work. The criterion requires evidence that access to cloud infrastructure is restricted to authorized parties. Two SCPs are directly relevant:

Deny use of root account credentials (except for specific organizational actions):

{
  "Sid": "DenyRootAccountActions",
  "Effect": "Deny",
  "Action": "*",
  "Resource": "*",
  "Condition": {
    "StringLike": {
      "aws:PrincipalArn": [
        "arn:aws:iam::*:root"
      ]
    }
  }
}

Require MFA for sensitive IAM actions — not a substitute for identity governance, but a meaningful control layer:

{
  "Sid": "DenyIAMActionsWithoutMFA",
  "Effect": "Deny",
  "Action": [
    "iam:CreateUser",
    "iam:DeleteUser",
    "iam:CreateAccessKey",
    "iam:UpdateAccessKey"
  ],
  "Resource": "*",
  "Condition": {
    "BoolIfExists": {
      "aws:MultiFactorAuthPresent": "false"
    }
  }
}

CC6.7 — Restricting transmission to authorized external parties

The data exfiltration prevention patterns belong here. Require VPC endpoints for S3 and deny S3 access from outside your org's VPCs — this is the most concrete CC6.7 SCP:

{
  "Sid": "DenyS3AccessOutsideOrgVPCs",
  "Effect": "Deny",
  "Action": "s3:*",
  "Resource": "*",
  "Condition": {
    "StringNotEquals": {
      "aws:PrincipalOrgID": "o-xxxxxxxxxxxx"
    },
    "Bool": {
      "aws:ViaAWSService": "false"
    }
  }
}

This is narrow in scope — it doesn't address all of CC6.7 (which also covers encryption in transit and authorized external sharing workflows). But it closes the most auditor-visible gap: uncontrolled S3 data access from outside the org.

What the Mapping Doesn't Cover

SCPs are account-level guardrails. They don't address several things CC6 also requires:

  • Physical access controls — CC6 technically includes physical access to data centers. AWS covers this through their own SOC 2 compliance. For a SaaS team running on AWS, you reference AWS's physical controls rather than mapping them yourself.
  • User access reviews — CC6.3 requires periodic reviews of who has access. SCPs don't perform access reviews; IAM Access Analyzer or an identity governance tool does that work.
  • Access provisioning workflows — CC6.2 requires that access is granted through an approved workflow. SCPs enforce constraints on the outcome, but the workflow itself needs ticketing or SCIM or another mechanism.
  • Monitoring and alerting — CC6 also includes detection of unauthorized access attempts. CloudTrail + Security Hub handles that layer; SCPs are preventive, not detective.

We think of SCPs as handling the "prevent the bad thing from being technically possible" layer. CC6 also needs a "detect when someone tried" layer and a "prove the workflow was followed" layer. Those are separate problems.

Building the Evidence Package

Auditors reviewing CC6 need specific artifacts. For the SCP-addressable controls, that means:

1. SCP inventory with OU attachment evidence. A list of every SCP in your org, which OUs it's attached to, and what it denies. The AWS Organizations console and CLI both export this:

aws organizations list-policies --filter SERVICE_CONTROL_POLICY \
  --query 'Policies[*].{Id:Id,Name:Name,Description:Description}' \
  --output table

aws organizations list-targets-for-policy \
  --policy-id p-xxxxxxxxxxxx \
  --query 'Targets[*].{TargetId:TargetId,Type:Type,Name:Name}' \
  --output table

2. Test evidence showing SCPs actually block the denied actions. Run a test in a sandboxed account where you attempt the denied action and capture the AccessDenied response with the SCP denial reason. Store this as a screenshot or CLI output in your evidence repository.

3. Change history. CloudTrail captures SCP attach/detach events under organizations.amazonaws.com. Auditors will ask when policies were modified and who modified them. Having 90 days of CloudTrail evidence ready is the minimum.

4. Gap documentation. Document explicitly what CC6 sub-criteria your SCPs address and which ones are addressed by other controls. A single-page control mapping table that cross-references CC6 criteria to specific SCP IDs, IAM policies, and operational procedures is what makes a CC6 review go smoothly.

SCP Evaluation Gotchas That Affect Audit Evidence

Two behaviors catch teams off guard when they're building this evidence package.

First: SCPs don't apply to the management account. If your auditor asks "is this control applied to all accounts in your org," the truthful answer is "all member accounts." The management account is outside SCP scope by design. Document this boundary explicitly rather than letting an auditor discover it.

Second: SCP denials are additive. If you have multiple SCPs attached to an OU, all deny statements apply independently. A principal needs explicit allow in an SCP only when you have a full-deny SCP and then need to carve out exceptions. Most teams don't run full-deny SCPs — they run deny-specific-actions SCPs, which layer without conflict. Make sure your evidence package tests each SCP independently, not just the combined outcome.

One pattern we've seen cause audit friction: a team writes an SCP that denies iam:CreateRole without the MFA condition, then deploys an automation pipeline that creates roles using a service role (which doesn't use MFA). The SCP blocks the automation. They add an exception condition. The exception condition is what the auditor reads — and an exception condition with an overly broad principal can negate the CC6.3 control. Write conditions tightly and test them before your evidence freeze date.

A Realistic Starting Set

If you're building this from scratch and your audit is in the next two quarters, the five SCPs that give you the most CC6 coverage are:

  1. Region restriction (CC6.1) — attach at root or top-level production OU
  2. Deny root account usage (CC6.6) — attach at root, all member accounts
  3. Deny admin role creation without permission boundary (CC6.3) — attach at all non-sandbox OUs
  4. Deny S3 public access modification (CC6.6, CC6.7) — attach at root
  5. Deny VPC resource creation in unapproved configurations (CC6.1) — scope to your network OU

These five don't complete your CC6 coverage — you still need access reviews, provisioning workflows, and monitoring controls. But they represent the SCP layer's practical contribution to the audit, and each one is testable with a CLI call before your evidence lock date.

The pattern we look for when evaluating a team's SCP posture: are the SCPs tested? Not just attached — actually tested with an access-denied response captured? Attached and untested is the same problem as the one you're trying to solve.

More from the blog

All articles