This is the multi-page printable view of this section. Click here to print.

Return to the regular view of this page.

Base and Parent Images

A Docker or OCI image is composed of layers. These layers may be inherited from another image or created during the build of a specific image as defined by the instructions in a Dockerfile or other build process.

The ancestry of an image shows the image’s parent image(s) and base image. As defined by the Docker documentation, a parent of an image is the image used to start the build of the current image, typically the image identified in the FROM directive in the Dockerfile. If the parent image is SCRATCH then the image is considered a base image.

Anchore Enterprise provides an API call to retrieve all parents and bases of an image. This call dynamically computes the ancestry set using images that have already been analyzed by the system and returns a list of image digests and their respective layers. The ancestry computation is done by matching exact layer digests between the requested image and other images in the system.

If an image X is a parent of image Y, then image X’s layers will be the first N layers of image Y where N in the number of layers in image X.

A case where an image may have multiple results in its ancestry is as follows:

A base distro image, for example debian:10

FROM scratch
...

An application container image from that debian image, for example a node.js image let’s call mynode:latest

FROM debian:10

# Install nodejs

The application image itself built from the framework container, let’s call it myapp:v1

FROM mynode:latest
COPY ./app /
...

In this case, the parent image of myapp:v1 is mynode:latest and its base is debian:10. Anchore will return each of those images with their matching layers in the API call. See the API docs for more information on the specifics of the GET /v2/images/{digest}/ancestors API call itself.

The returned images can be used for subsequent calls to the base image comparison APIs for vulnerabilities and policy evaluations allowing you to determine which findings for an image are inherited from a specific parent or base image.

Comparing an Image with its Base or Parent

Anchore Enterprise provides a mechanism to compare the policy checks and security vulnerabilities of an image with those of a base image. This allows clients to

  • filter out results that are inherited from a base image and focus on the results relevant to the application image
  • reverse the focus and examine the base image for policy check violations and vulnerabilities which could be a deciding factor in choosing the base image for the application

To read more about the base comparison features, jump to

1 - Compare Base Image Policy Checks

This feature provides a mechanism to compare the policy checks for an image with those of a base image. You can read more about base images and how to find them here. Base comparison uses the same policy and tag to evaluate both images to ensure a fair comparison. The API yields a response similar to the policy checks API with an additional element within each triggered gate check to indicate whether the result is inherited from the base image.

Usage

This functionality is currently available via the Enterprise UI and API. Watch this space as we add base comparison support in other tools.

API

Refer to API Access section for the API specification. The API route for base comparison is GET /enterprise/images/{imageDigest}/check. This API exposes similar path and query parameters as image policy check API GET /images/{imageDigest}/check plus an optional query parameter for supplying the digest of the base image. If the base digest is omitted, the system falls back to evaluating image policy checks without comparing the results to the base image.

Example request using curl to retrieve policy check for an image digest sha256:xyz and tag p/q:r and compare the results to a base image digest sha256:abc

curl -X GET -u {username:password} "http://{servername:port}/v2/images/sha256:xyz/check?tag=p/q:r&base_digest=sha256:abc"

Example output:

[
  {
    "sha256:xyz": {
      "p/q:r": [
        {
          "detail": {
            "result": {
              "base_image_digest": "sha256:abc",
              "result": {
                "123": {
                  "result": {
                    "final_action": "stop",
                    "header": [
                      "Image_Id",
                      "Repo_Tag",
                      "Trigger_Id",
                      "Gate",
                      "Trigger",
                      "Check_Output",
                      "Gate_Action",
                      "Whitelisted",
                      "Policy_Id",
                      "Inherited_From_Base"
                    ],
                    "row_count": 2,
                    "rows": [
                      [
                        "123",
                        "p/q:r",
                        "41cb7cdf04850e33a11f80c42bf660b3",
                        "dockerfile",
                        "instruction",
                        "Dockerfile directive 'HEALTHCHECK' not found, matching condition 'not_exists' check",
                        "warn",
                        false,
                        "48e6f7d6-1765-11e8-b5f9-8b6f228548b6",
                        true
                      ],
                      [
                        "123",
                        "p/q:r",
                        "CVE-2019-5435+curl",
                        "vulnerabilities",
                        "package",
                        "MEDIUM Vulnerability found in os package type (APKG) - curl (CVE-2019-5435 - http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-5435)",
                        "warn",
                        false,
                        "48e6f7d6-1765-11e8-b5f9-8b6f228548b6",
                        false
                      ]
                    ]
                  }
                },
                ...
              },
              ...
            },
            ...
          },
          ...
        }
      ]
    }
  }
]

Note that header element Inherited_From_Base is a new column in the API response added to support base comparison. The corresponding row element in each item of rows uses a boolean value to indicate whether the gate result is present in the base image. In the above example

  • Dockerfile directive 'HEALTHCHECK' not found, matching condition 'not_exists' check is triggered by both images and hence Inherited_From_Base column is marked true
  • MEDIUM Vulnerability found in os package type (APKG) - curl (CVE-2019-5435 - http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-5435) is not triggered by the base image and therefore the value of Inherited_From_Base column is false

2 - Compare Base Image Security Vulnerabilities

This feature provides a mechanism to compare the security vulnerabilities detected in an image with those of a base image. You can read more about base images and how to find them here. The API yields a response similar to vulnerabilities API with an additional element within each result to indicate whether the result is inherited from the base image.

Usage

This functionality is currently available via the Enterprise UI and API. Watch this space as we add base comparison support in other tools.

API

Refer to API Access section for the API specification. The API route for base comparison is GET /enterprise/images/{imageDigest}/vuln/{vtype}. This API exposes similar path and query parameters as the security vulnerabilities API GET /images/{imageDigest}/vuln/{vtype} plus an optional query parameter for supplying the digest of the base image. If the base digest is omitted, the system falls back to retrieving security vulnerabilities in the image without comparing the results to the base image.

Example request using curl to retrieve security vulnerabilities for an image digest sha:xyz and compare the results to a base image digest sha256:abc

curl -X GET -u {username:password} "http://{servername:port}/v2/images/sha256:xyz/vuln/all?base_digest=sha256:abc"

Example output:

{
  "base_digest": "sha256:abc",
  "image_digest": "sha256:xyz",
  "vulnerability_type": "all",
  "vulnerabilities": [
    {
      "feed": "vulnerabilities",
      "feed_group": "alpine:3.12",
      "fix": "7.62.0-r0",
      "inherited_from_base": true,
      "nvd_data": [
        {
          "cvss_v2": {
            "base_score": 6.4,
            "exploitability_score": 10.0,
            "impact_score": 4.9
          },
          "cvss_v3": {
            "base_score": 9.1,
            "exploitability_score": 3.9,
            "impact_score": 5.2
          },
          "id": "CVE-2018-16842"
        }
      ],
      "package": "libcurl-7.61.1-r3",
      "package_cpe": "None",
      "package_cpe23": "None",
      "package_name": "libcurl",
      "package_path": "pkgdb",
      "package_type": "APKG",
      "package_version": "7.61.1-r3",
      "severity": "Medium",
      "url": "http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-16842",
      "vendor_data": [],
      "vuln": "CVE-2018-16842"
    },
    {
      "feed": "vulnerabilities",
      "feed_group": "alpine:3.12",
      "fix": "2.4.46-r0",
      "inherited_from_base": false,
      "nvd_data": [
        {
          "cvss_v2": {
            "base_score": 5.0,
            "exploitability_score": 10.0,
            "impact_score": 2.9
          },
          "cvss_v3": {
            "base_score": 7.5,
            "exploitability_score": 3.9,
            "impact_score": 3.6
          },
          "id": "CVE-2020-9490"
        }
      ],
      "package": "apache2-2.4.43-r0",
      "package_cpe": "None",
      "package_cpe23": "None",
      "package_name": "apache2",
      "package_path": "pkgdb",
      "package_type": "APKG",
      "package_version": "2.4.43-r0",
      "severity": "Medium",
      "url": "http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-9490",
      "vendor_data": [],
      "vuln": "CVE-2020-9490"
    }
  ]
}

Note that inherited_from_base is a new element in the API response added to support base comparison. The assigned boolean value indicates whether the exact vulnerability is present in the base image. In the above example

  • CVE-2018-16842 affects libcurl-7.61.1-r3 package in both images, hence inherited_from_base is marked true
  • CVE-2019-5482 affects apache2-2.4.43-r0 package does not affect the base image and therefore inherited_from_base is set to false