CircleCI Field Guide
GitHub Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage
Edit page

Restrict Unauthorised Images

Some customers want to ban images that are not from their specific authorised image registry e.g. ECR

Image restriction policy

This policy will produce a hard fail if a user attempts to use an image from an unknown or unauthorised ECR. This also included images that are referenced within orbs. This ensures that image use is controlled, and enables customers to use only approved image registries.

What’s particularly useful here is that it shows how to restrict access to an item that only appears within compiled config files, by making use of input._compiled_

package org

import future.keywords

policy_name["restrict_public_ecr_docker_image"]

# UUID for project to apply rule to
in_scope_projects := {"2b7bda05-573f-4b4c-9e4f-4cc346cefbb2"}

enable_rule["check_pipeline_docker_image"] {
  in_scope_projects[data.meta.project_id] # Only enable this rule for the specific project
}

hard_fail["check_pipeline_docker_image"]

# Checks images that are within a config file. Also checks images that are referenced within orbs, by using `input._compiled_` 
check_pipeline_docker_image[reason] {
    image := input.executors[_].docker[_].image
    not startswith(image, "11111111.dkr.ecr.us-east-1.amazonaws.com")
    reason := sprintf("The docker image '%v' is not a valid image. Please use a valid ECR image from the private ECR repository.", [image])
} {
    image := input.executors[_].docker.image
    not startswith(image, "11111111.dkr.ecr.us-east-1.amazonaws.com")
    reason := sprintf("The docker image '%v' is not a valid image. Please use a valid ECR image from the private ECR repository.", [image])
} {
    image := input.jobs[_].docker[_].image
    not startswith(image, "11111111.dkr.ecr.us-east-1.amazonaws.com")
    reason := sprintf("The docker image '%v' is not a valid image. Please use a valid ECR image from the private ECR repository.", [image])
} {
    image := input.jobs[_].docker.image
    not startswith(image, "11111111.dkr.ecr.us-east-1.amazonaws.com")
    reason := sprintf("The docker image '%v' is not a valid image. Please use a valid ECR image from the private ECR repository.", [image])
} {
    image := input._compiled_.executors[_].docker[_].image
    not startswith(image, "11111111.dkr.ecr.us-east-1.amazonaws.com")
    reason := sprintf("The docker image '%v' is not a valid image. Please use a valid ECR image from the private ECR repository.", [image])
} {
    image := input._compiled_.executors[_].docker.image
    not startswith(image, "11111111.dkr.ecr.us-east-1.amazonaws.com")
    reason := sprintf("The docker image '%v' is not a valid image. Please use a valid ECR image from the private ECR repository.", [image])
} {
    image := input._compiled_.jobs[_].docker[_].image
    not startswith(image, "11111111.dkr.ecr.us-east-1.amazonaws.com")
    reason := sprintf("The docker image '%v' is not a valid image. Please use a valid ECR image from the private ECR repository.", [image])
} {
    image := input._compiled_.jobs[_].docker.image
    not startswith(image, "11111111.dkr.ecr.us-east-1.amazonaws.com")
    reason := sprintf("The docker image '%v' is not a valid image. Please use a valid ECR image from the private ECR repository.", [image])
}

Testing this policy

As this policy will also be applied to compiled config, it is important to include tests for this. Here is an example test file to use

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46

test_ban_image:
  input:
    version: 2.1
    jobs:
      build:
        docker:
          - image: 11111111.dkr.ecr.us-east-1.amazonaws.com
        working_directory: /tmp
  meta:
    project_id: 2b7bda05-573f-4b4c-9e4f-4cc346cefbb2
  decision: &root
    status: PASS
    enabled_rules: [check_pipeline_docker_image]
  cases:
    wrong_version:
      input:
        version: 2.1
        jobs:
          build:
            docker:
              - image: cimg/node:18.7.0
      meta:
        project_id: 2b7bda05-573f-4b4c-9e4f-4cc346cefbb2
      decision:
        <<: *root
        status: HARD_FAIL
        hard_failures:
          - rule: check_pipeline_docker_image
            reason: The docker image 'cimg/node:18.7.0' is not a valid image. Please use a valid ECR image from a personal ECR repository.
    wrong_version_compiled:
      input:
        _compiled_:
          version: 2.1
          jobs:
            build:
              docker:
                - image: cimg/node:18.7.0
      meta:
        project_id: 2b7bda05-573f-4b4c-9e4f-4cc346cefbb2
      decision:
        <<: *root
        status: HARD_FAIL
        hard_failures:
          - rule: check_pipeline_docker_image
            reason: The docker image 'cimg/node:18.7.0' is not a valid image. Please use a valid ECR image from a personal ECR repository.