> For the complete documentation index, see [llms.txt](https://docs.codeocean.com/admin-guide/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.codeocean.com/admin-guide/deployment-guide/protecting-code-ocean-stack-and-its-resources.md).

# Protecting Code Ocean Stack and its Resources

## CloudFormation Stack Termination Protection

We recommend enabling termination protection on the CloudFormation stack of your Code Ocean deployment. You can execute the following command via CloudShell (alternatively, it can also be done via AWS CloudFormation console):

```
aws cloudformation update-termination-protection \
  --stack-name <your-stack-name> \
  --enable-termination-protection
```

## Critical Resources Protection using an SCP

We recommend creating an AWS Organizations Service Control Policy (SCP) that denies deletion actions on Code Ocean stack’s protected resources, and attaching it to the Code Ocean account. This prevents accidental deletions of critical and unrecoverable cloud resources—whether by human error or automated processes (e.g., garbage collectors or other governance tools).

### Code Ocean Stack's Protected Resources

Critical resources in your Code Ocean stack are tagged with `codeocean:protected=true`, for example:

* Data EBS volume for the services instance
* All the application's S3 buckets
* KMS backup key
* AWS Backup vault
* Secrets in AWS Secrets Manager:
  * Analytics RDS instance password
  * Elasticache Redis cluster auth token

### AWS Organizations SCP policy

Save this JSON as `scp-codeocean-protected-resources.json` and use it to deny delete operations on any resource with the `codeocean:protected=true` tag and your Code Ocean deployment S3 buckets:

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DenyDeletionOfProtectedTaggedResources",
      "Effect": "Deny",
      "Action": [
        "ec2:DeleteVolume",
        "secretsmanager:DeleteSecret",
        "kms:ScheduleKeyDeletion",
        "backup:DeleteBackupVault"
      ],
      "Resource": "*",
      "Condition": {
        "StringEquals": {
          "aws:ResourceTag/codeocean:protected": "true"
        }
      }
    },
    {
      "Sid": "DenyDeletionOfCodeOceanBuckets",
      "Effect": "Deny",
      "Action": [
        "s3:DeleteBucket"
      ],
      "Resource": "arn:aws:s3:::[STACK_NAME]-s3*bucket-*" // Here you should replace [STACK_NAME] with your Code Ocean deployment stack name. Alternatively, you can scope down to specific bucket ARNs.
    }
  ]
}
```

### Creating and attaching the SCP

1. Upload the policy file

   In AWS CloudShell (in your master account), click Actions → Upload file, and select `scp-codeocean-protected-resources.json`.
2. Create the SCP and capture its ID:

   ```bash
   policy_id=$(
     aws organizations create-policy \
       --content file://scp-codeocean-protected-resources.json \
       --name "ProtectCodeOceanResources" \
       --description "Protects Code Ocean stack’s protected resources" \
       --type SERVICE_CONTROL_POLICY \
       --query 'Policy.PolicySummary.Id' \
       --output text
   )
   echo "Created policy with ID: $policy_id"
   ```
3. Attach the SCP to the target account:

   ```bash
   aws organizations attach-policy \
     --policy-id $policy_id \
     --target-id 123456789012 # AWS account ID of Code Ocean deployment
   ```
4. Verify the attachment:

   ```bash
   aws organizations list-targets-for-policy \
     --policy-id $policy_id \
     --output table
   ```

## Removing Protection

{% hint style="info" %}
Warning: Deleting the stack or its protected resources is irreversible and cannot be recovered.
{% endhint %}

If you wish to delete the stack, any or all of the protected resources:

1. Disable CFN stack termination protection:

   ```
   aws cloudformation update-termination-protection \
     --stack-name <your-stack-name> \
     --no-enable-termination-protection
   ```
2. To delete a specific protected resource, you can either delete its `codeocean:protected` tag or change the tag value to `false`
3. To delete all protected resources, you can detach the SCP from the target account:

   ```
   aws organizations detach-policy \
     --policy-id <scp-id> \
     --target-id <account-id>
   ```
