OCL Examples

OCL Examples

This page provides worked examples of writing OCL rules for Approved Controls, using AWS IAM policy attachments as the example. The same patterns apply to any Approved control that uses OCL.

IAM Policy Attachments

The Policy Attachments > Approved controls check the managed policies attached to an IAM user, group, or role, and can detach any that are not approved. Each is a composite policy control. For example, for roles:

AWS > IAM > Role > Policy Attachments > Approved
AWS > IAM > Role > Policy Attachments > Approved > Rules
AWS > IAM > Role > Policy Attachments > Approved > Compiled Rules

Equivalent policy types exist for users (AWS > IAM > User > Policy Attachments > Approved > *) and groups (AWS > IAM > Group > Policy Attachments > Approved > *).

The control evaluates each attached managed policy against the OCL in Approved > Compiled Rules. Each item contains the policy name and ARN:

{
  "PolicyName": "AWSCloudShellFullAccess",
  "PolicyArn": "arn:aws:iam::aws:policy/AWSCloudShellFullAccess"
}

Your rules in Approved > Rules can match on either field using the Turbot Guardrails filter syntax.

Reject Specific Policies by Name

To unapprove specific policies and allow everything else, list REJECT rules before a default APPROVE *:

# Reject the AWS managed AWSCloudShellFullAccess policy
REJECT $.PolicyName:AWSCloudShellFullAccess

# Approve all other policies
APPROVE *

Multiple values joined with a comma act as an "OR" condition, so you can reject several policies in one rule:

# Reject overly permissive policies
REJECT $.PolicyName:AWSCloudShellFullAccess,AdministratorAccess

# Approve all other policies
APPROVE *

Match with Regular Expressions

Text matches are exact and case-sensitive. For pattern matching, delimit the value with / characters:

# Reject any policy whose name starts with legacy_
REJECT $.PolicyName:/^legacy_/

# Reject any policy with "admin" in the name, case-insensitive
REJECT $.PolicyName:/admin/i

# Approve all other policies
APPROVE *

You can match on the ARN instead, for example to reject all AWS managed policies while allowing customer managed policies:

# Reject AWS managed policies
REJECT $.PolicyArn:/^arn:aws:iam::aws:policy\//

# Approve all other policies
APPROVE *

Approve Only Specific Policies

To implement an allowlist instead, list APPROVE rules before a default REJECT *:

# Approve the AWS managed ReadOnlyAccess policy
APPROVE $.PolicyName:ReadOnlyAccess

# Approve customer managed policies with the acme_ prefix
APPROVE $.PolicyName:/^acme_/

# Reject all other policies
REJECT *

[!NOTE] The Approved control evaluates Approved > Compiled Rules, not Approved > Rules directly. Guardrails prepends APPROVE rules for any policies listed in the Policy > Required > Compiled Items policy for the resource, and rules are processed in order with the first match winning. As a result, a required policy (such as a Turbot lockdown policy) is always approved, even if your rules would reject it. Check the Compiled Rules policy value on the resource to see the full rule set that the control evaluates.

Check and Enforce

The Approved > Rules policy only defines which attachments are approved. The Approved policy controls what happens to unapproved attachments:

Terraform Example

This policy pack detaches the AWS managed AWSCloudShellFullAccess policy from all IAM roles:

resource "turbot_policy_pack" "remove_cloudshell_full_access" {
  title       = "Enforce Removal of CloudShell Full Access Policy for AWS IAM Roles"
  description = "Automatically removes the AWSCloudShellFullAccess policy from IAM roles."
}

# AWS > IAM > Role > Policy Attachments > Approved
resource "turbot_policy_setting" "role_policy_attachments_approved" {
  resource = turbot_policy_pack.remove_cloudshell_full_access.id
  type     = "tmod:@turbot/aws-iam#/policy/types/rolePolicyAttachmentsApproved"
  value    = "Enforce: Delete unapproved"
}

# AWS > IAM > Role > Policy Attachments > Approved > Rules
resource "turbot_policy_setting" "role_policy_attachments_approved_rules" {
  resource = turbot_policy_pack.remove_cloudshell_full_access.id
  type     = "tmod:@turbot/aws-iam#/policy/types/rolePolicyAttachmentsApprovedRules"
  value    = <<-EOT
    # Reject AWS managed AWSCloudShellFullAccess policy
    REJECT $.PolicyName:AWSCloudShellFullAccess
    # Approve all other policies
    APPROVE *
  EOT
}

To apply the same rules to users and groups, add settings for the userPolicyAttachmentsApproved, userPolicyAttachmentsApprovedRules, groupPolicyAttachmentsApproved, and groupPolicyAttachmentsApprovedRules policy types.