-
Notifications
You must be signed in to change notification settings - Fork 56
Guides
Practical, scenario-specific guidance for deploying and operating Innovation Sandbox on AWS (ISB). For official, comprehensive documentation, see the Implementation Guide.
This guide covers deploying Innovation Sandbox on AWS in an environment managed by Landing Zone Accelerator on AWS (LZA). LZA is an AWS Solution that automates the deployment of a secure, scalable, multi-account AWS environment based on AWS best practices and common compliance frameworks such as the CCCS Medium Cloud Profile.
This guide outlines the necessary adaptations to have Innovation Sandbox on AWS work over an LZA environment. It does not address any template-specific approach; the guidance applies regardless of which LZA configuration template you use.
This guide assumes you are already familiar with both Innovation Sandbox on AWS and Landing Zone Accelerator on AWS, including how to modify LZA configuration files and run the LZA pipeline.
LZA manages account placement through accounts-config.yaml and expects accounts to remain in their configured OU. Innovation Sandbox moves accounts between nested OUs (Entry, Active, Frozen, etc.) as part of the sandbox account lifecycle, which causes drift from LZA's perspective.
To avoid this, you need to tell LZA to ignore the AccountPool OU and all its nested OUs.
In organization-config.yaml:
organizationalUnits:
# ... your existing OUs ...
- name: "Innovation Sandbox"
- name: "Innovation Sandbox/<namespace>_InnovationSandboxAccountPool"
ignore: true
- name: "Innovation Sandbox/<namespace>_InnovationSandboxAccountPool/Entry"
ignore: true
- name: "Innovation Sandbox/<namespace>_InnovationSandboxAccountPool/Active"
ignore: true
- name: "Innovation Sandbox/<namespace>_InnovationSandboxAccountPool/Frozen"
ignore: true
- name: "Innovation Sandbox/<namespace>_InnovationSandboxAccountPool/Available"
ignore: true
- name: "Innovation Sandbox/<namespace>_InnovationSandboxAccountPool/Quarantine"
ignore: true
- name: "Innovation Sandbox/<namespace>_InnovationSandboxAccountPool/CleanUp"
ignore: true
- name: "Innovation Sandbox/<namespace>_InnovationSandboxAccountPool/Exit"
ignore: trueReplace <namespace> with the namespace you will use for your Innovation Sandbox deployment.
This configuration creates an "Innovation Sandbox" OU that is managed by LZA, with a nested OU structure that LZA will ignore. The Innovation Sandbox OU remains LZA-managed, meaning you can continue using LZA features to apply policies to the entire ISB deployment, but be careful which policies you activate there.
Important
Two-stage deployment
Because the nested OUs are created by the ISB AccountPool stack (not by LZA), you must do this in two stages:
- First, add only the "Innovation Sandbox" parent OU to
organization-config.yamland run the LZA pipeline. - Deploy the AccountPool stack (see below), which creates the nested OUs.
- Then go back to
organization-config.yaml, add all the nested OUs withignore: true, and run the LZA pipeline again.
When deploying the AccountPool stack, use the Innovation Sandbox OU ID (created by LZA in step 1) as the Parent OU ID parameter.
Innovation Sandbox requires a Hub account for its CloudFront distribution, API, and other services. Use LZA to create and manage this account.
In accounts-config.yaml:
workloadAccounts:
# ... your existing accounts ...
- name: "Innovation Sandbox Hub"
description: "(NON-PRODUCTION) Innovation Sandbox Hub Account"
email: "<unique-email>@example.com"
organizationalUnit: "Innovation Sandbox"Deploy the four Innovation Sandbox stacks as follows:
| Stack | Deploy In | Key Considerations |
|---|---|---|
| AccountPool | LZA management account (root) | Namespace must match the ignored OU names. Hub account ID is the account LZA created. Parent OU ID is the Innovation Sandbox OU created by LZA. ISB managed regions should match LZA enabled regions. Do not enable Control Tower registration on the AccountPool OU or its nested OUs. |
| IDC | LZA management account (root) | Same as standard deployment. |
| Data | Innovation Sandbox Hub account | Created by LZA in step 2. |
| Compute | Innovation Sandbox Hub account | Created by LZA in step 2. |
Important
After the AccountPool stack creates the nested OUs, go back to organization-config.yaml, add all the nested OUs with ignore: true, and run the LZA pipeline again (as described in section 1).
Sandbox accounts used by Innovation Sandbox should not be managed by LZA, as LZA would create unwanted resources within them.
Create the sandbox accounts manually using AWS Organizations:
- In the AWS Organizations console, create the accounts directly in the Entry OU that the AccountPool stack created.
- After creation, remove the Quarantine SCP that LZA automatically attaches to new accounts.
Do not add these accounts to any LZA configuration file.
LZA reverts changes to SCPs that it does not manage. Even though the AccountPool nested OUs are set to ignore, LZA still removes SCPs that Innovation Sandbox deploys on them.
To work around this, recreate the ISB SCPs in the LZA configuration so that LZA manages them. In organization-config.yaml:
serviceControlPolicies:
# ... your existing SCPs ...
- name: InnovationSandboxProtectISBResourcesScp
description: "SCP for Innovation Sandbox to protect ISB control plane resources."
policy: service-control-policies/isb/InnovationSandboxProtectISBResourcesScp.json
type: customerManaged
deploymentTargets:
organizationalUnits:
- "Innovation Sandbox/<namespace>_InnovationSandboxAccountPool"
- name: InnovationSandboxAwsNukeSupportedServicesScp
description: "SCP to allow only services supported by AWS Nuke clean workflow."
policy: service-control-policies/isb/InnovationSandboxAwsNukeSupportedServicesScp.json
type: customerManaged
deploymentTargets:
organizationalUnits:
- "Innovation Sandbox/<namespace>_InnovationSandboxAccountPool"
- name: InnovationSandboxLimitRegionsScp
description: "SCP for Innovation Sandbox to limit use of AWS Regions."
policy: service-control-policies/isb/InnovationSandboxLimitRegionsScp.json
type: customerManaged
deploymentTargets:
organizationalUnits:
- "Innovation Sandbox/<namespace>_InnovationSandboxAccountPool"
- name: InnovationSandboxRestrictionsScp
description: "SCP to add restrictions for security, isolation, cost and operations."
policy: service-control-policies/isb/InnovationSandboxRestrictionsScp.json
type: customerManaged
deploymentTargets:
organizationalUnits:
- "Innovation Sandbox/<namespace>_InnovationSandboxAccountPool"
- name: InnovationSandboxWriteProtectionScp
description: "SCP for Innovation Sandbox to restrict create or modify actions."
policy: service-control-policies/isb/InnovationSandboxWriteProtectionScp.json
type: customerManaged
deploymentTargets:
organizationalUnits:
- "Innovation Sandbox/<namespace>_InnovationSandboxAccountPool/CleanUp"
- "Innovation Sandbox/<namespace>_InnovationSandboxAccountPool/Entry"
- "Innovation Sandbox/<namespace>_InnovationSandboxAccountPool/Exit"
- "Innovation Sandbox/<namespace>_InnovationSandboxAccountPool/Quarantine"The JSON policy files must be copied from the SCPs that the ISB AccountPool stack created and placed in your LZA configuration repository under service-control-policies/isb/.
Note
Keeping SCPs in sync
If you update Innovation Sandbox to a newer version, the SCPs may change. You will need a mechanism to keep the LZA repository's SCP JSON files in sync with the ones deployed by ISB.
Innovation Sandbox uses AWS Nuke to clean up sandbox accounts when leases expire. By default, Nuke may attempt to remove resources that LZA deployed into sandbox accounts (CloudFormation stacks, IAM roles, etc.).
To prevent this, update the Nuke configuration in the ISB Hub account:
- In the Hub account, open AWS AppConfig
- Find the
InnovationSandboxData-Config-NukeConfigHostedConfigurationconfiguration profile - Edit the hosted configuration to add filters that protect LZA and Control Tower resources
Add the following filters to the accounts > filters section:
accounts:
# ... existing config ...
filters:
CloudFormationStack:
# ... existing filters ...
- type: glob
value: "AWSAccelerator-*"
- type: glob
value: "StackSet-AWSControlTowerBP-*"
IAMRole:
# ... existing filters ...
- type: glob
value: "AWSAccelerator-*"
IAMRolePolicy:
# ... existing filters ...
- property: "role:RoleName"
type: glob
value: "AWSAccelerator-*"
IAMRolePolicyAttachment:
# ... existing filters ...
- property: RoleName
type: glob
value: "AWSAccelerator-*"
LambdaFunction:
# ... existing filters ...
- type: glob
value: "AWSAccelerator-*"
CloudWatchLogsLogGroup:
# ... existing filters ...
- type: contains
value: "AWSAccelerator-"
SNSSubscription:
# ... existing filters ...
- property: "ARN"
type: contains
value: "aws-accelerator"
SNSTopic:
# ... existing filters ...
- type: glob
value: "aws-accelerator-*"
# Add the following resource types at the end of the config:
AWSBackupPlan:
- property: "ID"
type: glob
value: "orgs/*"
AWSBackupSelection:
- property: "PlanID"
type: glob
value: "orgs/*"
GuardDutyDetector:
- property: "DetectorID"
type: exact
value: "<your-detector-id>"
SecurityHub:
- property: "Arn"
type: glob
value: "*:hub/default"Note
Environment-specific values
The GuardDutyDetector filter requires your environment's specific detector ID. Find it in the GuardDuty console of one of your sandbox accounts, or via aws guardduty list-detectors.
For additional Nuke configuration optimizations, refer to the Innovation Sandbox Implementation Guide.
Innovation Sandbox does not require AWS Control Tower, but the two can coexist in the same AWS Organization. This guide covers what to expect and the recommended configuration.
- Account movement causes drift. ISB moves sandbox accounts between its nested OUs (Entry, Available, Active, Frozen, CleanUp, Quarantine, Exit) as part of normal lifecycle operations. If those OUs are enrolled in Control Tower, every move is flagged as governance drift.
- ISB enforces its own SCPs. The solution attaches and manages its own SCPs on the nested OUs. Control Tower governance on the same OUs would conflict with this.
-
Cleanup already protects Control Tower resources. ISB's default AWS Nuke configuration ships with filters that exclude Control Tower resources (
aws-controltower-*CloudTrail trails,AWSControlTower*CloudFormation stacks and IAM roles), so account recycling does not delete Control Tower baselines.
You have three options, in order of preference:
- Enroll the parent OU, but not the nested OUs (recommended). Register the ISB parent OU with Control Tower but leave the account pool's nested OUs unenrolled. Preventive controls (SCP-based guardrails) defined on the parent OU are inherited by the nested OUs, while account movement between unenrolled nested OUs generates no drift.
- Leave all ISB OUs outside Control Tower. Simplest to operate; govern the sandbox environment entirely through ISB's SCPs plus any custom SCPs you attach.
- Enroll everything and ignore drift. Workable but noisy; drift notifications lose their signal value.
Note
Cost tip: Sandbox account resources change constantly and are never production workloads. Avoid enabling AWS Config recording in sandbox accounts; configuration item churn from constant resource creation and cleanup generates cost without governance benefit.
Control Tower's Account Factory can be used to create the sandbox account pool. Note that any baseline resources it provisions into those accounts will be deleted by AWS Nuke during recycling unless you add them to the Nuke exclusion filters (the Control Tower defaults above are already excluded).
If you use Organizations-integrated services that create resources in member accounts through trusted access (AWS Config, Security Hub, GuardDuty, Amazon Inspector, Resource Explorer), AWS Nuke will not have permission to delete those resources and cleanup will fail. Exclude the resource types in the AWS Nuke configuration (AppConfig in the Hub account):
resource-types:
excludes:
- S3Object # Let the S3Bucket deletion remove all objects instead (optimization)
- ConfigServiceConfigurationRecorder
- ConfigServiceDeliveryChannel
- SecurityHub
- GuardDutyDetector
- ResourceExplorer2Index
- Inspector2Customers deploying Innovation Sandbox may need to prevent sandbox users from accessing or exfiltrating data from production environments or other organizational units. Traditional resource-level policies (bucket policies, IAM role trust policies) fall short here because they can be modified by resource owners, creating gaps in your security posture. A common scenario is a production S3 bucket whose policy grants access to all accounts in the organization to enable cross-account collaboration; that policy inadvertently includes sandbox accounts, since they live in the same organization. A developer with administrative permissions in a sandbox shouldn't be able to exploit such policies to cross organizational security boundaries, even accidentally.
What's needed are enforceable, organization-level controls that create security boundaries sandbox users cannot bypass, even with administrative permissions in their own accounts. This is also what makes broad sandbox permissions safe to grant in the first place: when the organization can demonstrate enforceable boundaries against data exfiltration, it can confidently give builders powerful AWS environments while keeping organizational risk contained.
AWS Organizations provides two complementary mechanisms that operate at this level and cannot be circumvented by account-level permissions or resource policies: Resource Control Policies (RCPs) to protect resources at the target level, and Service Control Policies (SCPs) to restrict actions at the caller level. Both layer on top of the SCPs that ISB deploys by default.
RCPs protect resources from unauthorized access by evaluating requests at the target resource level, independently of what the resource's own policy allows.
How: Attach RCPs to the OUs containing resources you want to protect from sandbox access. For example, deny S3, STS, and KMS actions originating from principals in the sandbox OUs, using the principal's organizational path.
Sample RCP that protects resources in non-sandbox OUs from requests originating in a sandbox OU:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyAccessFromSandboxOU",
"Effect": "Deny",
"Principal": "*",
"Action": [
"s3:*",
"sts:*",
"kms:*"
],
"Resource": "*",
"Condition": {
"ForAnyValue:StringLike": {
"aws:PrincipalOrgPaths": [
"<org-id>/<root-id>/<sandbox-ou-id>/*"
]
},
"Bool": {
"aws:PrincipalIsAWSService": "false"
}
}
}
]
}Replace <org-id>/<root-id>/<sandbox-ou-id>/* with your organization's path to the sandbox OU (for example, o-a1b2c3d4e5/r-f6g7/ou-f6g7-8h9i0j1k/*).
This policy denies S3, STS, and KMS actions on resources when the request originates from principals in the sandbox OU. It uses aws:PrincipalOrgPaths to identify requests from the sandbox OU and includes an exception for AWS service principals (aws:PrincipalIsAWSService: false) so AWS services can still operate on the resources. When attached to a target OU (e.g., Workloads), this RCP prevents sandbox users from accessing protected resources regardless of bucket policies, IAM permissions, or role trust policies.
SCPs restrict what actions principals inside an account can perform, regardless of the IAM permissions granted within the account. Where RCPs protect the target, SCPs constrain the caller.
How: Attach an SCP to the sandbox OU that denies actions targeting resources outside an allowed set of OUs, using the target resource's organizational path.
Sample SCP that restricts sandbox users from accessing resources outside designated organizational boundaries:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyAccessOutsideMyBoundary",
"Effect": "Deny",
"Action": [
"s3:*",
"sts:*"
],
"Resource": "*",
"Condition": {
"ForAllValues:StringNotLike": {
"aws:ResourceOrgPaths": [
"<org-id>/<root-id>/<workloads-ou-id>/*",
"<org-id>/<root-id>/<security-ou-id>/*"
]
}
}
}
]
}This policy denies S3 and STS actions unless the target resource belongs to the specified OUs (and their sub-OUs). It uses aws:ResourceOrgPaths with ForAllValues:StringNotLike to evaluate the target resource's location: if the resource is outside the allowed OUs, the action is denied. When attached to a sandbox OU, this SCP creates a perimeter that prevents sandbox users from reaching resources in production or other non-sandbox OUs, regardless of their IAM permissions or what the target resource's policies allow.
Note
When adding custom SCPs, attach them as separate policies to the OUs rather than editing the ISB-managed SCPs. Separate policies survive ISB stack updates. See the FAQ section on SCPs and guardrails for details.
Many teams experiment and build prototypes in ISB but struggle to transition successful experiments into production systems. The goal is to experiment freely in the sandbox, validate the concept, and then move proven work into production without losing momentum or starting over. Two primary migration patterns have emerged.
A critical step before any transition is a security evaluation while still in the sandbox. Tools like AWS Security Agent can assess the prototype's security posture, identify vulnerabilities, and determine exactly which data sources, APIs, and tools the workload requires in production. ISB's isolated nature makes it a good environment for this analysis: teams can test access patterns, evaluate permissions, and refine security controls without touching production systems or exposing sensitive data.
Extract the prototype code from the sandbox and commit it to a centralized code repository, then deploy through your standard CI/CD pipeline into production environments.
- Strengths: Standard version control and team collaboration, strong governance, clean separation between environments, scales well for larger multi-team efforts
- Trade-offs: Requires code refactoring and migration effort
Use ISB's Eject Account feature to remove the entire sandbox account from ISB management and move it into a development OU, preserving all existing resources and configuration. See the FAQ's lifecycle section for the mechanics of ejection.
- Strengths: Fastest path, no rebuild, all deployed infrastructure retained
- Trade-offs: Governance controls must be retrofitted onto the account (your standard OU guardrails, access management, compliance tooling), and the pattern scales less well for larger, multi-team scenarios
The right choice depends on prototype complexity, timeline, governance requirements, and long-term scale.
Practical tips for deployment and configuration.
A brand-new account has artificially low Lambda concurrency limits that may block deployment. Request a quota increase, or wait until the limit is automatically lifted (about 24 hours).
ISB requires groups with specific names. The solution creates local instances of these groups in IAM Identity Center at deployment, but when federating you need to create groups with the same names in your upstream identity provider and ensure they sync to Identity Center:
<NAMESPACE>_IsbAdminsGroup<NAMESPACE>_IsbManagersGroup<NAMESPACE>_IsbUsersGroup
Where NAMESPACE is the value of the Namespace parameter in your ISB IDC stack.
ISB expects a Subject SAML attribute populated with the user's email, as described in the implementation guide. When setting up federation with an upstream identity provider, ensure federation populates the email value for your users in Identity Center. If it is missing, users cannot log in to the application. See the Identity Center attribute mapping documentation for details.
- Configure Entra ID / Identity Center federation with SCIM automatic provisioning, per the documentation
- Create the three ISB groups as above, add users to them, and assign those groups to your AWS Identity Center enterprise application in Entra ID
- If you have scoped SCIM provisioning down to specific groups, make sure the scoping filter includes the ISB groups (Enterprise Applications > Identity Center application > Attribute Mapping > Source Object Scope)
- Ensure the user's email value passes from Entra ID to Identity Center: configure the attribute mapping under Enterprise Applications > Identity Center application > Provisioning > Attribute Mapping
- Users see ISB in their AWS access portal but get a "No access" error? Check that the user has a valid email in Entra ID (User > Edit Properties > Contact Information) and that it successfully populates the Primary Email field in Identity Center