Write Custom Policies

Define Properties

Use properties to define the values for settings that policies check against.

Properties are an optional method of defining the ideal values for checks. Instead of defining a value in the check itself, you can define it in a property and reference that property in the check. Multiple checks in a policy can share a single property.

This policy does not use properties. It checks that you have strong IAM policies in AWS:

policies:
  - uid: no-properties-example
    name: Example policy without properties
    version: '1.0.0'
    authors:
      - name: Lunalectric
        email: security@lunalectric.com
    groups:
      - title: group01
        checks:
          - uid: aws-iam-01
            title: Require long passwords
            mql: aws.iam.passwordPolicy.minimumPasswordLength >= 8

          - uid: aws-iam-02
            title: Require uppercase characters
            mql: aws.iam.passwordPolicy.requireUppercaseCharacters == true

          - uid: aws-iam-03
            title: Limit password age
            mql: aws.iam.passwordPolicy.maxPasswordAge <= 90

The no-properties-example policy above performs three checks:

  • Line 13 checks whether the minimum password length is set to 8 or higher.

  • Line 17 checks whether uppercase letters are required in passwords.

  • Line 21 checks whether passwords expire after 90 or fewer days.

In each of these lines, the ideal value that the policy checks against is in the check itself.

An alternate way to structure these checks is to put all the ideal values in properties. You define properties separately from the checks themselves, similar to defining variables in code.

This policy shows how you can use properties to achieve the same results as the no-properties-example policy:

policies:
  - uid: example-with-properties
    name: Example policy using properties
    version: '1.0.0'
    authors:
      - name: Lunalectric
        email: security@lunalectric.com
    props:
      - uid: passwordMinLength
        title: Minimum password length
        mql: '8'

      - uid: passwordUppercase
        title: Whether to require at least one uppercase character in passwords
        mql: 'true'

      - uid: passwordMaxAge
        title: Maximum time that a user can go without changing their password
        mql: '90'
    groups:
      - title: group01
        checks:
          - uid: aws-iam-01
            title: Require long passwords
            mql: aws.iam.passwordPolicy.minimumPasswordLength >= props.passwordMinLength

          - uid: aws-iam-02
            title: Require uppercase character
            mql: aws.iam.passwordPolicy.requireUppercaseCharacters == props.passwordUppercase

          - uid: aws-iam-03
            title: Require password rotation
            mql: aws.iam.passwordPolicy.maxPasswordAge <= props.passwordMaxAge

In the example-with-properties policy above, the three checks reference properties for the ideal values they check against. The policy's props section (beginning on line 8) assigns a value to each property. Each check refers to a property by its uid, prefixed with props. (for example, props.passwordMinLength).

Define properties inside the policy, as in this example, or on an individual query. cnspec policy lint rejects properties defined at the top level of a bundle (rule bundle-global-props-deprecated).

Tip: To check for errors in the policy bundles you write, run cnspec policy lint BUNDLE-NAME.mql.yaml. For BUNDLE-NAME, substitute the name of your file.

Use one property for multiple checks

Multiple checks in a policy can share a single property. This makes updates easier when your organization's requirements change.

For example, suppose you create a policy that checks IAM best practices across multiple platforms. The platforms are different, but your company's minimum password length requirement is the same on each one. Instead of repeating the minimum password length value in every check, point every password length check to one property. When the requirement changes, you update one value.

Next steps

On this page