Anchore Enforce - Compliance Management
What is a policy?
A policy is composed of a set of rules that are used to perform an evaluation
on a source repository or container image. These rules include—but are not
limited to—checks on security, known vulnerabilities, configuration file
contents, the presence of credentials, manifest changes, exposed ports, or any
user defined checks.
Policies can be deployed site wide, or customized to run against specific
sources, container images, or categories of application. For additional
information, refer to the Policy
concepts section.
Once a policy has been applied to a source repository or image container, it can
return one of two results:
A policy includes the following elements:
Rule Sets
A policy is made up from a set of rules that are used to perform an evaluation on a source repository or container image. These policies can be deployed site wide or customized for specific source repositories, container images, or categories of applications. A policy may contain one or more named rule sets.
Policy rule checks are made up of gates and triggers. A gate is a set of policy checks against broad categories like vulnerabilities, secret scans, licenses, and so forth. It will include one or more triggers, which are checks specific to the gate category. For additional information, refer to the Policy Rules concepts section.
The policy additionally specifies the following action results:
- STOP: Critical error that should stop the deployment by failing the policy evaluation.
- WARN: Issue a warning.
- GO: Okay to proceed.
The result of an evaluation will be based on the actions configured in your rule set.
If you are creating a policy rule for a source repository, only vulnerabilities checks are available.
Allowlists
An allowlist contains one or more exceptions that can be used during policy
evaluations, such as allowing a CVE to be excluded. A policy may contain multiple allowlists.
Mappings
A policy mapping defines which policies and allowlists should be used to
perform the policy evaluation of a given source repository or container image.
A policy may contain multiple mappings including wildcard mappings that
apply to multiple elements.
Allowed Images
An allowed images list defines one or more images that will always pass policy
evaluation regardless of any policy violations. Allowed images can be
specified by name, image ID, or image digest. A policy contains a
single list of allowed images.
Denied Images
A denied images list defines one or more images that will always fail policy
evaluation. Denied images can be specified by name, image ID, or image digest.
A policy contains a single list of denied images.
Listing Policies
The Policies tab contains a table
that lists the policies defined within an account.
Note: A lock icon next to the policy name indicates that the policy cannot
be deleted. Policy rules that are used by policy mappings in the policy (which
will be listed under the Mappings column entry within the Edit option) cannot be deleted
until they are removed from every associated mapping.
Policies can also be managed directly using the REST API or the anchorectl policy
command. It is recommended that any policy configuration be handled via UI and not AnchoreCTL
# anchorectl policy list
✔ Fetched policies
┌────────────────┬──────────────────────────────────────┬────────┬──────────────────────┐
│ NAME │ POLICY ID │ ACTIVE │ UPDATED │
├────────────────┼──────────────────────────────────────┼────────┼──────────────────────┤
│ Default policy │ 2c53a13c-1765-11e8-82ef-23527761d060 │ true │ 2023-10-25T20:39:28Z │
│ devteam1policy │ da8208a2-c8ae-4cf2-a25b-a52b0cdcd789 │ false │ 2023-10-25T20:47:16Z │
└────────────────┴──────────────────────────────────────┴────────┴──────────────────────┘
** times are reported in UTC
Using the policy get
command, summary or detailed information about a policy can be retrieved. The policy is referenced using its unique POLICY ID.
# anchorectl policy get 2c53a13c-1765-11e8-82ef-23527761d060
✔ Fetched policy
Name: Default policy
ID: 2c53a13c-1765-11e8-82ef-23527761d060
Comment: Default policy
Policies:
- artifactType: image
comment: System default policy
id: 48e6f7d6-1765-11e8-b5f9-8b6f228548b6
name: DefaultPolicy
rules:
- action: STOP
gate: dockerfile
id: ce7b8000-829b-4c27-8122-69cd59018400
params:
- name: ports
value: "22"
- name: type
value: denylist
trigger: exposed_ports
...
...
The policy can be downloaded in JSON format by passing the --detail
parameter.
# anchorectl policy get 2c53a13c-1765-11e8-82ef-23527761d060 --detail -o json-raw > policy.json
✔ Fetched policy
The Tools dropdown menu in the Actions column provides options to:
- Edit the policy
- Copy the policy
- Download the policy as a JSON document
- Delete the policy (if it is not being used by any policy mapping)
The Edit button provides options to view and edit:
- Rule Sets
- Allowlists
- Mappings
- Allowed/Denied Images
1 - Allowed / Denied Images
Introduction
You can add or edit allowed or denied images for your policy rules.
The Allowed / Denied Images tab is split into the following two sub tabs:
Allowed Images: A list of images which will always pass policy evaluation irrespective of any policies that are mapped to them.
Denied Images: A list if images which will always fail policy evaluation irrespective of any policies that are mapped to them.
Add an Allowed or Denied Image to a Policy
If you do not have any allowed or denied images in your policy, click Let’s add one! to add them.
The workflow for adding Allowed or Denied Images is identical.
Images can be referenced in one of the following ways:
By Name: including the registry, repository and tag. For example: docker.io/library/centos:latest
The name does not have to be unique but it is recommended that the identifier is descriptive.
By Image ID: including the full image ID. For example: e934aafc22064b7322c0250f1e32e5ce93b2d19b356f4537f5864bd102e8531f
The full Image ID should be entered. This will be a 64 hex characters. There are a variety of ways to retrieve the ID of an image including using the AnchoreCTL, Anchore UI, and Docker command.
By Image Digest: including the registry, repository and image digest of the image. For example: docker.io/library/centos@sha256:989b936d56b1ace20ddf855a301741e52abca38286382cba7f44443210e96d16
Click OK to add the Allowed or Denied Image item to your policy.
See the following sections for more details about the Name, Image ID, and Image Digest.
For most use cases, it is recommended that the image digest is used to reference the image since an image name is ambiguous. Over time different images may be tagged with the same name.
If an image appears on both the Allowed Images and Denied Images lists, then the Denied Image takes precedence and the image will be failed.
The Allowed Images list will show a list of any allowed images defined by the system includes the following fields:
Allowlist Name
A user friendly name to identify the image(s).
Type
Describes how the image has been specified. By Name, ID, or Digest.
Image
The specification used to define the image.
Actions
The actions you can set for the allowed image.
The button can be used to copy the image specification into the clipboard.
An existing image may be deleted using the or edited by pressed the button.
Adding an Image by Image ID
The full Image ID should be entered. This will be a 64 hex characters. There are a variety of ways to retrieve the ID of an image including using the AnchoreCTL, Anchore UI and Docker command.
Using AnchoreCTL
$ anchorectl image get library/debian:latest | grep ID
ID: 8626492fecd368469e92258dfcafe055f636cb9cbc321a5865a98a0a6c99b8dd
Using Docker CLI
$ docker images --no-trunc debian:latest
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/debian latest sha256:8626492fecd368469e92258dfcafe055f636cb9cbc321a5865a98a0a6c99b8dd 3 days ago 101 MB
By default the docker CLI displays a short ID, the long ID is required and it can be displayed by using the –no-trunc parameter.
Note: The algorithm (sha256:) should not be entered into the Image ID field.
Adding an Image by Digest
When adding an image by Digest the following fields are required:
Registry. For example: docker.io
Repository. For example: library/debian
Digest. For example: sha256:de3eac83cd481c04c5d6c7344cd7327625a1d8b2540e82a8231b5675cef0ae5f
The full identifier for this image is: docker.io/library/debian@sha256:de3eac83cd481c04c5d6c7344cd7327625a1d8b2540e82a8231b5675cef0ae5f
Note: The tag is not used when referencing an image by digest.
There are a variety of ways to retrieve the digest of an image including using the AnchoreCTL, Anchore UI, and Docker command.
Using AnchoreCTL
$ anchorectl image get library/debian:latest | grep Digest
Digest: sha256:7df746b3af67bbe182a8082a230dbe1483ea1e005c24c19471a6c42a4af6fa82
Using Docker CLI
$ docker images --digests debian
REPOSITORY TAG DIGEST IMAGE ID CREATED SIZE
docker.io/debian latest sha256:de3eac83cd481c04c5d6c7344cd7327625a1d8b2540e82a8231b5675cef0ae5f 8626492fecd3 1 days ago 101 MB
Note: Unlike the Image ID entry, the algorithm (sha256:) is required.
Adding an Image by Name
When adding an image by Name, the following fields are required:
Note: Wild cards are supported, so to trust all images from docker.io you would enter docker.io in the Registry field, and add a * in the Repository and Tag fields.
2 - Allowlists
Introduction
An allowlist contains one or more exceptions that can be used during policy
evaluation. For example allowing a CVE to be excluded from policy evaluation.
The Allowlist tab shows a list of allowlists present in the policy.
Allowlists are an optional element of the policy, and a policy may
contain multiple instances.
Add a New Allowlist
Click Add New Allowlist to create a new, empty allowlist.
Add a name for the allowlist. A name is required and should be unique.
Optional: Add a description. A description is recommended. Often the
description is updated as new entries are added to the allowlist to explain
any background. For example “Updated to account for false positive in glibc
library”.
Upload or Paste an Allowlist
If you have a JSON document containing an existing allowlist, then you can
upload it into Anchore Enterprise.
Click Import Allowlist to upload an allowlist. You can also
manually edit the allowlist in the native JSON format.
Drag an allowlist file into the dropzone. Or, you can click the “Add a
Local File” button and load it from a local filesystem.
Click OK to upload the allowlist. The system will perform a validation
for the allowlist. Only validated allowlists may be stored by Anchore
Enterprise.
Example allowlist:
{
"id": "allowlist1",
"name": "My First Allowlist",
"comment": "A allowlist for my first try",
"version": "2",
"items": [
{
"gate": "vulnerabilities",
"trigger_id": "CVE-2018-0737+*",
"id": "rule1",
"expires_on": "2019-12-30T12:00:00Z"
}
]
}
Copying a Allowlists
You can copy an existing allowlist, give it a new name, and use it for a policy
evaluation.
From the Tools drop down, select Copy Allowlist.
Enter a unique name for the allowlist.
Optional: Add a description. This is recommended. Often the description is
updated as new entries are added to the allowlist to explain any background.
Downloading Allowlists
You can download an existing allowlists as a JSON file. From the Tools drop
down, click Download to JSON.
Editing Allowlists
The Allowlists editor allows new allowlist entries to be created, and existing
entries to be edited or removed.
The components:
- Gate: The gate the allowlist matches from (ensures trigger_ids are not matched in the wrong context).
- Trigger Id: The specific trigger result to match and allowlist. This id is gate/trigger specific as each trigger may have its own trigger_id format. We’ll use the most common for this example: the CVE trigger ids produced by the vulnerability->package gate-trigger. The trigger_id specified may include wildcards for partial matches.
- id: an identifier for the rule, must only be unique within the allowlist object itself.
- Expires On: (optional) specifies when a particular allowlist item expires. This is an RFC3339 date-time string. If the rule matches, but is expired, the policy engine will NOT allowlist according to that match.
The allowlist is processed if it is specified in the mapping rule that was matched during policy evaluation and is applied to the results of the policy evaluation defined in that same mapping rule. If a allowlist item matches a specific policy trigger output, then the action for that output is set to go and the policy evaluation result notes that the trigger output was matched for a allowlist item by associating it with the allowlist id and item id of the match.
Choose an allowlist to edit, then click Edit.
Anchore Enterprise supports allowlisting any policy trigger, however the Allowlists editor currently supports only adding Anchore Security checks, allowing vulnerabilities to be allowlisted.
Choose a gate for the allowlist, for example, vulnerabilities.
A vulnerabilities allowlists entry includes two elements: A CVE / Vulnerability Identifier and a Package.
Enter a CVE / Vulnerability Identifier. The CVE/Vulnerability Identifier
field contains the vulnerability that should be matched by the allowlists.
This can include wildcards.
For example: CVE-2017-7246. This format should match the format of the CVEs
shown in the image vulnerabilities report. Wildcards are supported, however,
care should be taken with using wildcards to prevent allowlisting too many
vulnerabilities.
Enter a package. The package name field contains the package that should be
matched with a vulnerability. For example libc-bin.
Wildcards are also supported within the Package name field.
An allowlists entry may include entries for both the CVE and Package field
to specify an exact match, for example: Vulnerability: CVE-2005-2541
Package: tar.
In other cases, wildcards may be used where a multiple packages may match a
vulnerability. For example, where multiple packages are built from the same
source. Vulnerability: CVE-2017-9000 Package: bind-*
In this example the packages bind-utils, bind-libs and bind-license will all
be allowlisted for CVE-2017-9000.
Special care should be taken with wildcards in the CVE / Vulnerability
Identifier field. In most cases a specific vulnerability identifier will be
entered. In some exceptional cases a wild card in this field may be
appropriate.
A good example of a valid use case for a wildcard in the CVE / Vulnerability
Identifier field is the bind-license package. This package include a single
copyright text file and is included by default in all CentOS:7 images.
CVEs that are reported against the Bind project are typically applied to all
packages built from the Bind source package. So when a CVE is found in Bind
it is common to see a CVE reported against the bind-license package. To
address this use case it is useful to add an allowlists entry for any
vulnerability (*) to the bind-license package.
Optional: Click to edit an allowlist.
Optional: Click Remove to delete an allowlist.
Ensure that all changes are saved before exiting out of the Edit Allowlists
Items Page. At that point the edits will be sent to Anchore Enterprise.
3 - Managing Policies
Policies
The Policy tab displays a list of policies that are loaded in the
system. Each policy has a unique name, unique ID (UUID), and an optional
description.
Anchore Enterprise supports multiple policies. AnchoreCTL, API, and CI/CD
plugins support specifying a policy when requesting an source repository or
container image evaluation. For example, the development team may use a
different set of policy checks than the operations team. In this case, the
development team would specify their policy ID as part of their policy
evaluation request.
If no policy ID is specified, then Anchore Enterprise will use the active policy
which can be considered as the default policy. Only one policy can be set as
default/active at any time. This policy will be highlighted with a green ribbon.
Note: Policies which are not marked as Active can still be explicitly
requested as part of a policy evaluation.
If multiple users are accessing Policies, or if policies are
being added or removed through the API or AnchoreCTL, then you may update the list of policies by clicking on the Refresh the Policy List button.
The following command can be run to list policies using AnchoreCTL:
# anchorectl policy list
Adding and Editing Policies
You can add a new policy with custom rule rests within the Policies tab.
Click Create New Policy and provide a name and description.
Click Add New Rule Set and select Source Repository if you want the new policy to apply to a source, or select Container Image to have the policy apply to an image.
You can configure each rule set under the Edit option. Start by selecting an item from the Gate dropdown list, where each item represents a category of policy checks.
Note: If you are creating a policy rule for a source repository, only
vulnerabilities are available.
After selecting a gate item, hover over the (i) indicator next to
Gate to see additional descriptive details about the gate you have
selected.
Click the Triggers drop down and select a specific check that you want
associated with this item, such as package, vulnerability data unavailable,
and so on. Triggers may have parameters, some of which may be optional.
If any optional parameters are associated with the trigger you select, these
will also be displayed in an additional field where they can be added or
removed. Optional parameters are described in more detail in the next
section.
Select an action to apply to the policy rule. Choose STOP, WARN, or
GO. The action options are only displayed once all required parameters
have been provided, or if no mandatory parameters are required. Once an
action has been selected, the rule is added to the main list of rules
contained in the policy.
Click Save and Close.
# anchorectl policy add --input /path/to/policy/policy.json
Note: Adding a policy will not automatically make it active. You will need to activate the policy using the activate command.
The policy activate
command can be used to activate a policy. The policy is referenced using its unique POLICY ID which can be retrieved using the policy list
command.
# anchorectl policy activate 2c53a13c-1765-11e8-82ef-23527761d061
✔ Activate policy
┌─────────────────┬──────────────────────────────────────┬────────┬──────────────────────┐
│ NAME │ POLICY ID │ ACTIVE │ UPDATED │
├─────────────────┼──────────────────────────────────────┼────────┼──────────────────────┤
│ Default policy │ 2c53a13c-1765-11e8-82ef-23527761d061 │ true │ 2023-10-25T20:50:17Z │
└─────────────────┴──────────────────────────────────────┴────────┴──────────────────────┘
Upload a Policy
If you have a JSON document containing an existing policy, then you can
upload it into Anchore Enterprise.
Click Add a Local File to upload or paste a valid policy JSON.
You can drag a policy file into the dropzone. Or, you can click
the “Add a Local File” button to add from the local file system.
Click OK to perform a validation on a policy. Only validated policies may
be stored by Anchore Enterprise.
Note: The following command can be run to add policies using AnchoreCTL
# anchorectl policy add --input /path/to/my/policy/bundle.json
Copy an Existing Policy
If you already have a policy that you would like to use as a base for
another policy, you can make a copy of it, give it a new name, and then work
with the policies, mappings, allowlists, and allowed or denied images.
From the Tools list, select Copy Policy.
Enter a unique name for the copy of the policy.
Optional: You can add a description to explain the new policy. This is
recommended.
Click OK to copy the policy.
Download a Policy
From the Tools menu, select Download to JSON.
The JSON file is downloaded just like any other downloaded file to your
computer. Save the downloaded JSON file to your location of choice.
Note: Use the following command to download a policy using AnchoreCTL.
The policy must be referenced by its UUID. For example:
# anchorectl policy get 4c1627b0-3cd7-4d0f-97da-00be5aa835f4 --detail > policy.json
Delete a Policy
If you no longer use a policy, you can delete it. An active (default)
policy cannot be deleted. To delete the active policy first you must mark
another policy as active.
From the Tools menu, select Delete Policy.
Click Yes to confirm that you want to delete the policy.
*Warning: Once the policy is deleted, you cannot recover it.
Note: Use the following command to delete a policy using AnchoreCTL.
The policy must be referenced by its UUID. For example:
# anchorectl policy delete 4c1627b0-3cd7-4d0f-97da-00be5aa835f4
Example Gate Configuration
The following example shows a sophisticated policy check. The metadata
gate has
a single trigger that allows checks to be performed against various attributes
of an image, including image size, architecture, and operating system
distribution:
The Attribute parameter drop-down includes a number of attributes taken from
image metadata, including the operating system distribution, number of layers,
and architecture of the image (AMD64, ARM, and so forth).
Once an attribute has been selected, the Check dropdown is used to create a
comparison expression.
The type of comparison varies based on the attribute. For example the numeric
comparison operators such as >
, <
, >=
would be relevant for numeric field
such as size, while other operators such as not in
may be useful for querying
data field such as distro
.
In this example, by entering rhel centos oracle
in the Value field, our
rule will check that the distro (that is, the operating system) under analysis
is not RHEL, Centos, or Oracle.
Optional Parameters
If a trigger has optional parameters, they will be automatically displayed in
the policy editor, and an editable field next to the Triggers drop-down will
show all the current selections.
You can remove unneeded optional parameters by clicking the X button
associated with each entry in the Optional Parameters list, or by clicking
the X button within each associated parameter block.
If an optional parameter is removed, it can be reapplied to the rule by clicking
the Optional Parameters field and selecting it from the resulting dropdown
list.
4 - Policy Mappings
Introduction
The Mapping feature of the Policy Editor creates rules that define which
policies and allowlists should be used to perform the policy evaluation of a
source repository or container image based on the registry, repository name,
and tag of the image.
The policy editor lets you set up different policies that will be used on
different images based on the use case. For example the policy applied to a
web-facing service may have different security and operational best
practices rules than a database backend service.
A mapping has:
- Registry - The registry url to match, including wildcards (e.g. ‘docker.io’, ‘quay.io’, ‘gcr.io’, ‘*’)
- Repository - The repository name to match, including wildcards (e.g. ’library/nginx’, ‘mydockerhubusername/myrepositoryname’, ’library/*’, ‘*’)
- Image - The way to select an image that matches the registry and repository filters
- type: how to reference the image and the expected format of the ‘value’ property
- “tag” - just the tag name itself (the part after the ‘:’ in a docker pull string: e.g. nginx:latest -> ’latest’ is the tag name)
- “id” - the image id
- “digest” - the image digest (e.g. sha256@abc123)
- value: the value to match against, including wildcards
For example:
Field | Example | Description |
---|
Registry | registry.example.com | Apply mapping to the registry.example.com |
Repository | anchore/web\* | Map any repository starting with web in the anchore namespace |
Tag | * | Map any tag |
In this example,an image named registry.example.com/anchore/webapi:latest
would match this mapping, and so the policy and allowlist configured for this
mapping would be applied.
Unlike other parts of the policy, Mappings are evaluated in order and will halt on the first matching rule. This is important to understand when combined with wildcard matches since it enables sophisticated matching behavior.
Note: The trusted images and denylisted images lists take precedence over
the mapping. See Allowed / Denied Images for
details.
It is recommended that a final catch-all mapping is applied to ensure that all
images are mapped to a policy. This catch-all mapping should specify wildcards
in the registry, repository, and tag fields.
4.1 - Container Image Mapping
Introduction
The container image policy mapping editor creates rules that define which
policies and allowlists should be used to perform the policy evaluation of an
image based on the registry, repository name, and tag of the image.
Create a New Image Container Mapping
From the Policies screen, click Mappings.
Under Container Images, click on the “Let’s add one!” button.
From the Add New Container Image Mapping dialog, add a name for the mapping, the policy for which the mapping will apply (added automatically), a registry, a repository, and a tag. You can optionally add an allowlist for the mapping.
Note Once you have created your first mapping, any mapping that is created afterwards will contain an additional optional field called Position. Image evaluation is performed sequentially from top to bottom. The system will stop at the first match, so the order or position of the mapping is important.
Field | Description |
---|
Name | A unique name to describe the mapping. For example: “Mapping for webapps”. |
Position | Set the order for the new mapping. |
Rule Sets | Rule Sets in the policy to be used for evaluation. A drop down will be displayed allowing selection of a single policy. |
Allowlist(s) | Optional: The allowlist(s) to be applied to the image evaluation. Multiple allowlists may be applied to the same image. |
Registry | The name of the registry to match. Note the name should exactly match the name used to submit the image or repo for analysis. For example: foo.example.com:5000 is different to foo.example.com . Wildcards are supported. A single * would specify any registry. |
Repository | The name of the repository, optionally including namespace. For example: webapp/foo . Wildcards are supported. A single * would specify any repository. Partial names with wildcards are supported. For example: web*/* . |
Tag | Tags mapped by this rule. For example: latest . Wildcard are supported. A single * would match any tag. Partial names with wildcards are supported. For example: 2018* . |
Click OK to create the new mapping.
It is recommended that a final catch-all mapping is applied to ensure that all container images are mapped to a policy. This catch-all mapping should specify wildcards in the registry, repository, and tag fields.
Using the policy editor, you can set up different policies that will be used on different images based on use case. For example the policy applied to a web facing service may have different security and operational best practices rules than a database backend service.
Mappings are set up based on the registry, repository, and tag of an image. Each field supports wildcards. For example:
Field | Example | Description |
---|
Registry | registry.example.com | Apply mapping to the registry.example.com |
Repository | anchore/web\* | Map any repository starting with web in the anchore namespace |
Tag | * | Map any tag |
In this example, an imaged named registry.example.com/anchore/webapi:latest would match this mapping, so the policy and allowlist configured for this mapping would be applied.
The mappings are applied in order, from top to bottom and the system will stop at the first match.
Note: The allowed images and denied images lists take precedence over the mapping. See Allowed / Denied Images for details.
4.2 - Source Repository Mapping
The source repository policy mapping editor creates rules that define which policies and allowlists should be used to perform the policy evaluation of a source repository based on the host, and repository name.
Organizations can set up multiple policies that will be used on different source repositories based on use case. For example the policy applied to a web facing service may have different security and operational best practices rules than a database backend service.
Mappings are set up based on the Host and Repository of a source repository. Each field supports wildcards.
Create a Source Repository Mapping
From the Policies screen, click Mappings.
Under Source Repositories, click on the “Let’s add one!” button.
From the Add New Source Repository Mapping dialog, add a name for the
mapping, choose the policy for which the mapping will apply, a host (such as github.com
), and a repository. You can optionally add an allowlist for the mapping.
Note Once you have created your first mapping, any mapping that is created afterwards will contain an additional optional field called Position. Image evaluation is performed sequentially from top to bottom. The system will stop at the first match, so the order or position of the mapping is important.
Field | Description |
---|
Name | A unique name to describe the mapping. |
Position | Optional: Set the order for the new mapping. |
Policies | Name of policy to use for evaluation. A drop down will be displayed allowing selection of a single policy. |
Allowlist(s) | Optional: The allowlist(s) to be applied to the source repository evaluation. Multiple allowlists may be applied to the same source |
Host | The name of the source host to match. For example: github.com . |
Repository | The name of the source repository, optionally including namespace. For example: webapp/foo . Wildcards are supported. A single * would specify any repository. Partial names with wildcards are supported. For example: web*/* . |
- Click OK to create the new mapping.
4.3 - Policy Mappings Example
Mappings in the policy are a set of rules, evaluated in order, that describe matches on an image, id, digest, or tag and the corresponding sets of policies and allowlists to apply to any image that matches the rule’s criteria.
Policies can contain one or more mapping rules that are used to determine which rule_sets and allowlists apply to a given image. They match images on the registry and repository, and finally be one of id, digest, or tag.
Examples
Example 1, all images match a single catch-all rule:
[
{
"registry": "*",
"repository": "*",
"image": { "type": "tag", "value": "*"},
"rule_set_ids": ["defaultpolicy"],
"allowlist_ids": ["defaultallowlist"]
}
]
Example 2, all “official” images from DockerHub are evaluated against officialspolicy and officialsallowlist (made up names for this example), while all others from DockerHub will be evaluated against defaultpolicy and defaultallowlist , and private GCR images will be evaluated against gcrpolicy and gcrallowlist:
[
{
"registry": "docker.io",
"repository": "library/*",
"image": { "type": "tag", "value": "*"},
"rule_set_ids": [ "officialspolicy"],
"allowlist_ids": [ "officialsallowlist"]
},
{
"registry": "gcr.io",
"repository": "*",
"image": { "type": "tag", "value": "*"},
"rule_set_ids": [ "gcrpolicy"],
"allowlist_ids": [ "gcrallowlist"]
},
{
"registry": "*",
"repository": "*",
"image": { "type": "tag", "value": "*"},
"rule_set_ids": [ "defaultpolicy"],
"allowlist_ids": [ "defaultallowlist"]
}
]
Example 3, all images from a unknown registry will be evaluated against defaultpolicy and defaultallowlist, and an internal registry’s images will be evaluated against a different set (internalpolicy and internalallowlist):
[
{
"registry": "myregistry.mydomain.com:5000",
"repository": "*",
"image": { "type": "tag", "value": "*"},
"policy_ids": [ "internalpolicy"],
"allowlist_ids": [ "internalallowlist"]
},
{
"registry": "*",
"repository": "*",
"image": { "type": "tag", "value": "*"},
"policy_ids": [ "defaultpolicy"],
"allowlist_ids": [ "defaultallowlist"]
}
]
Using Multiple Policies and Allowlists
The result of the evaluation of the mapping section of a policy is the list of rule sets and allowlists that will be used for actually evaluating the image. Because multiple rule sets and allowlists can be specified in each mapping rule, you can use granular rule sets and allowlists and then combine them in the mapping rules.
Examples of schemes to use for how to split-up policies include:
- Different policies for different types of checks such that each policy only uses one or two gates (e.g. vulnerabilities, packages, dockerfile)
- Different policies for web servers, another for database servers, another for logging infrastructure, etc.
- Different policies for different parts of the stack: os-packages vs. application package
5 - Policy Gates
In this section of the document, we list and describe the current gates (and related triggers and parameters) that are supported within Anchore policy.
Getting Started
Before diving into the specifics of Policy Rule Sets and Gates, navigate to the Policies tab in order to create a new Policy.
Once a Policy has been created, you can start creating Rule Sets that define the Policy. When adding a new Rule Set, you will be prompted to select either “Source Repository” or “Container Images” that will define the source type of the Rule Set.
Note Currently, only the Vulnerabilities Gate and the following Triggers are available for Source Repository Rule Sets:
- Denylist
- Package
- Stale Feed Data
Components of a Policy Rule Set
A gate is a collection of checks that are logically grouped to provide a broader context for policy evaluations. It is the first step a user must set when creating a rule.
Once a gate has been selected, a list of associated triggers for the selecteed gate is provided. A trigger defines a specific condition to check within the context of the gate.
Once a trigger has been selected, a list of associated parameters are provided to customize the matched behavior of the rule. Please note that a trigger may contain both a required and optional paramater. Required paramaters must be configured in order to save a rule.
Finally, the last step in the process is to configure the action for every matched instance of a trigger. The available actions are “STOP”, “WARN”, and “GO”.
Note Please click here for more detailed information on the architectural framework of a policy rule set.
The final policy evaluation against an image SBOM will result in a failure if and only if at least one rule within any rule set in the active policy has been triggered with a “STOP” action.
Rule actions are set per rule and cannot interfere with other rules in the same policy. For example, if we create a policy with the same identical rule but with different actions (STOP and WARN), each rule will be evaluated independently resulting in a duplicate finding with the same trigger ID.
Note Please click here to learn more about Anchore’s policies.
5.1 - Gate: ancestry
Introduction
The “ancestry” gate gives users the ability to construct policy rules against an image’s ancestry, specifically the base and ancestor images. This gate becomes useful when a user needs to quickly identify if an image SBOM is not part of an organization’s approved set of base and/or ancestor images.
Base images is referred to the image that a given image was built from. It serves as a template for developers to create a standardized environment on top of which they can build their custom images (often referred to as a “golden” image).
Ancestor images is referred to the chain of images built from other images.
Note To understand the concept of base and ancestor images more, please click here.
Example Use-case
Scenario 1
Goal: Fail a policy evaluation if an image is not part of a list of approved base images.
Example rule set configuration in Anchore Enterprise
Gate: ancestry
Trigger: allowed base image digest
Required Parameters: base digest = “SHA256:abcdef123456”
Recommendation (Optional): The image is not derived from an approved base image. Remediation required.
Action: STOP
Reference: ancestry
Trigger Name | Description | Parameter | Description | Example |
---|
allowed_base_image_digest | Checks to see if base image is approved | base_digest | List of approved base image digests. | sha256:123abc |
allowed_base_image_tag | Checks to see if base image is approved | base_tag | List of approved base image tags. | docker.io/nginx:latest |
denylist_ancestor_image_digest | Triggers if any of the ancestor images have the provided image digest(s) | ancestor_digest | List of ancestor image digests to check for. Accepts comma separated list of digests. | sha256:123abc |
denylist_ancestor_image_tag | Triggers if any of the ancestor images have the provided image tag(s) | ancestor_tag | List of denied image tags to check the ancestry for. Accepts comma separated list of tags. | docker.io/nginx:latest |
no_ancestors_analyzed | Checks to see if the image has a known ancestor | | | |
5.2 - Gate: distro
Introduction
The “distro” gate is solely intended to deny an image that is running on a specific distro. This is especially useful if a user wants to create a rule that can quickly discover any image SBOMs containing a specific version of a distro that is denied in their organization.
Example Use-case
Scenario 1
Goal: Create a rule that results in a STOP action for images that are running below Debian version 9.
Example rule set configuration in Anchore Enterprise
Gate: distro
Trigger: deny
Required Parameters: distro = “debian”, version = “9”, check = “<”
Recommendations (optional): “Image is running on an old version of Debian. Update required.”
Action: STOP
Reference: distro
Trigger Name | Description | Parameter | Description | Example |
---|
deny | Triggers if the image distro and version match the criteria | distro | Name of the distribution to match | debian |
deny | Triggers if the image distro and version match the criteria | version | Version of distribution to compare against | 9 |
deny | Triggers if the image distro and version match the criteria | check | The comparison to use in the evaluation | < |
5.3 - Gate: dockerfile
Introduction
The “dockerfile” gate allows users to perform checks against a dockerfile or docker history for an image SBOM. This gate is especially useful when a user wants to create policy checks against not only the content, but the construction of an image SBOM.
The data that is collected by this gate depends on whether or not a dockerfile is provided by the user at the time of analysis. If a dockerfile is not provided, Anchore will collect the data from the layer history encoded in the image SBOM (docker history).
Note For further details in regards to the dockerfile gate, please see Policy Gate: dockerfile
Example Use-cases
Scenario 1
Goal: Create a rule that results in a STOP action for username “root” found in an image SBOM’s dockerfile “USER” line.
Example rule set configuration in Anchore Enterprise
Gate: dockerfile
Trigger: effective_user
Required Parameters: users = “root”, type = “denylist”
Recommendations (optional): “The username “root” is found in USER line. Fix required.”
Action: STOP
Scenario 2
Goal: Create a rule that results in a WARN action for usernames “nginx” or “jenkins” not found in an image SBOM’s dockerfile “USER” line.
Example rule set configuration in Anchore Enterprise
Gate: dockerfile
Trigger: effective_user
Required Parameters: users = “nginx,jenkins”, type = “allowlist”
Action: WARN
Scenario 3
Goal: Create a rule that results in a STOP action for any exposed AWS key environment variable found in an image SBOM’s dockerfile.
Example rule set configuration in Anchore Enterprise
Gate: dockerfile
Trigger: instruction
Required Parameters: instruction = “env”, check = “like”
Optional Parameters: value = “AWS_.*KEY”
Recommendations (optional): “AWS environment variable key found, Removal required.”
Action: STOP
Reference: dockerfile
Trigger Name | Description | Parameter | Description | Example |
---|
instruction | Triggers if any directives in the list are found to match the described condition in the dockerfile. | instruction | The Dockerfile instruction to check. | from |
instruction | Triggers if any directives in the list are found to match the described condition in the dockerfile. | check | The type of check to perform. | = |
instruction | Triggers if any directives in the list are found to match the described condition in the dockerfile. | value | The value to check the dockerfile instruction against. | scratch |
instruction | Triggers if any directives in the list are found to match the described condition in the dockerfile. | actual_dockerfile_only | Only evaluate against a user-provided dockerfile, skip evaluation on inferred/guessed dockerfiles. Default is False. | true |
effective_user | Checks if the effective user matches the provided user names, either as a allowlist or blocklist depending on the type parameter setting. | users | User names to check against as the effective user (last user entry) in the images history. | root,docker |
effective_user | Checks if the effective user matches the provided user names, either as a allowlist or blocklist depending on the type parameter setting. | type | How to treat the provided user names. | denylist |
exposed_ports | Evaluates the set of ports exposed. Allows configuring allowlist or blocklist behavior. If type=allowlist, then any ports found exposed that are not in the list will cause the trigger to fire. If type=denylist, then any ports exposed that are in the list will cause the trigger to fire. | ports | List of port numbers. | 80,8080,8088 |
exposed_ports | Evaluates the set of ports exposed. Allows configuring allowlist or blocklist behavior. If type=allowlist, then any ports found exposed that are not in the list will cause the trigger to fire. If type=denylist, then any ports exposed that are in the list will cause the trigger to fire. | type | Whether to use port list as a allowlist or denylist. | denylist |
exposed_ports | Evaluates the set of ports exposed. Allows configuring allowlist or blocklist behavior. If type=allowlist, then any ports found exposed that are not in the list will cause the trigger to fire. If type=denylist, then any ports exposed that are in the list will cause the trigger to fire. | actual_dockerfile_only | Only evaluate against a user-provided dockerfile, skip evaluation on inferred/guessed dockerfiles. Default is False. | true |
no_dockerfile_provided | Triggers if anchore analysis was performed without supplying the actual image Dockerfile. | | | |
5.4 - Gate: files
Introduction
The “files” gate performs checks against the files in an analyzed image SBOM and is useful when users need to create policies that trigger against any matched file content, names and/or attributes.
Note The “files” gate differs from the “retrieved_files” gate. The “files” gate searches against the files present in an image SBOM whereas the “retrieved_files” gate utilizes Anchore’s cataloger capability and checks against files that are provided and stored by the user before analysis.
Example Use-cases
Scenario 1
Goal: Create a rule that results in a STOP action for any file name that contains “.pem”, which may include information such as the public certificate or even an entire certificate chain (public key, private key, and root certificates) of an image SBOM.
Example rule set configuration in Anchore Enterprise
Gate: files
Trigger: name match
Required Parameters: regex = “.*\.pem”
Recommendations (optional): “Filename with “.pem” found - Remediation required.”
Action: STOP
Scenario 2
Goal: Create a rule that results in a STOP action for any file that matches against regex string “.*password.*” in an image SBOM.
Note In order to use this gate, the analyzer_config.yaml file for your Anchore deployment must have specific regex strings configured under the content_search section as the rule will only check against regex strings that appear in this list. Please use the optional parameter “regex name” if you want to specify a single string for your policy rule. If this paramater is not configured, then every regex string stored in the content_search section in the analyzer_config.yaml will be checked against.
Example rule set configuration in Anchore Enterprise
Gate: files
Trigger: content regex match
Optional Parameters: regex name = “ABC”
Recommendations (optional): “Regex string “.*password.*” found in file. Fix required.”
Action: STOP
analyzer_config.yaml file
Reference: files
Trigger Name | Description | Parameter | Description | Example |
---|
content_regex_match | Triggers for each file where the content search analyzer has found a match using configured regexes in the analyzer_config.yaml “content_search” section. If the parameter is set, the trigger will only fire for files that matched the named regex. Refer to your analyzer_config.yaml for the regex values. | regex_name | Regex string that also appears in the FILECHECK_CONTENTMATCH analyzer parameter in analyzer configuration, to limit the check to. If set, will only fire trigger when the specific named regex was found in a file. | .password. |
name_match | Triggers if a file exists in the container that has a filename that matches the provided regex. This does have a performance impact on policy evaluation. | regex | Regex to apply to file names for match. | .*.pem |
attribute_match | Triggers if a filename exists in the container that has attributes that match those which are provided . This check has a performance impact on policy evaluation. | filename | Filename to check against provided checksum. | /etc/passwd |
attribute_match | Triggers if a filename exists in the container that has attributes that match those which are provided . This check has a performance impact on policy evaluation. | checksum_algorithm | Checksum algorithm | sha256 |
attribute_match | Triggers if a filename exists in the container that has attributes that match those which are provided . This check has a performance impact on policy evaluation. | checksum | Checksum of file. | 832cd0f75b227d13aac82b1f70b7f90191a4186c151f9db50851d209c45ede11 |
attribute_match | Triggers if a filename exists in the container that has attributes that match those which are provided . This check has a performance impact on policy evaluation. | checksum_match | Checksum operation to perform. | equals |
attribute_match | Triggers if a filename exists in the container that has attributes that match those which are provided . This check has a performance impact on policy evaluation. | mode | File mode of file. | 00644 |
attribute_match | Triggers if a filename exists in the container that has attributes that match those which are provided . This check has a performance impact on policy evaluation. | mode_op | File mode operation to perform. | equals |
attribute_match | Triggers if a filename exists in the container that has attributes that match those which are provided . This check has a performance impact on policy evaluation. | skip_missing | If set to true, do not fire this trigger if the file is not present. If set to false, fire this trigger ignoring the other parameter settings. | true |
suid_or_guid_set | Fires for each file found to have suid or sgid bit set. | | | |
5.5 - Gate: image_source_drift
Introduction
The “image source drift” gate allows users to perform checks against the difference between an image source repo SBOM and the build image SBOM. The difference operates by “contains” relationships where the analyzed image SBOM is the base “target” and the source revisions are the “source” for calculation.
Example Use-cases
Scenario 1
Goal: Create a rule that results in a STOP action for missing packages in an image SBOM that were supposed to be present based from the image source SBOM.
Example rule set configuration in Anchore Enterprise
Gate: image source drift
Trigger: package removed
Action: STOP
Scenario 2
Goal: Create a rule that results in a STOP action for npm packages found in an image SBOM with versions lower than the ones specified in the image source SBOM.
Example rule set configuration in Anchore Enterprise
Gate: image source drift
Trigger: package downgraded
Optional Paramaters: package types = “npm”
Action: STOP
Reference: image_source_drift
Trigger Name | Description | Parameter | Description | Example |
---|
package_downgraded | Checks to see if any packages have a lower version in the built image than specified in the input source sboms | package_types | Types of package to filter by | java,npm |
package_removed | Checks to see if any packages are not installed that were expected based on the image’s related input source sboms | package_types | Types of package to filter by | java,npm |
no_related_sources | Checks to see if there are any source sboms related to the image. Findings indicate that the image does not have a source sbom to detect drift against | | | |
5.6 - Gate: licenses
Introduction
The “licenses” gate allows users to perform checks against found licenses in an image SBOM and perform different policy actions with available triggers.
Note The license names are normalized in Syft before the data is pulled into Anchore Enterprise
Example Use-case
Scenario 1
Goal: Create a rule that results in a STOP action for any “GNU packages” that are running on General Public License (GPL) version 2 or later.
Example rule set configuration in Anchore Enterprise
Gate: licenses
Trigger: denylist exact match
Required Parameters: licenses = “GPLv2+”
Action: STOP
Reference: licenses
Trigger Name | Description | Parameter | Description | Example |
---|
denylist_exact_match | Triggers if the evaluated image has a package installed with software distributed under the specified (exact match) license(s). | licenses | List of license names to denylist exactly. | GPLv2+,GPL-3+,BSD-2-clause |
denylist_exact_match | Triggers if the evaluated image has a package installed with software distributed under the specified (exact match) license(s). | package_type | Only trigger for specific package type. | all |
denylist_partial_match | triggers if the evaluated image has a package installed with software distributed under the specified (substring match) license(s) | licenses | List of strings to do substring match for denylist. | LGPL,BSD |
denylist_partial_match | triggers if the evaluated image has a package installed with software distributed under the specified (substring match) license(s) | package_type | Only trigger for specific package type. | all |
5.7 - Gate: malware
Introduction
The “malware” gate allows users to detect malware in an iamge SBOM through the use of ClamAV.
ClamAV is an open-source antivirus toolkit and can be used to detect various kinds of malicious threats on a system. Anchore pulls malware data from ClamAV and provides users the capability to create policy rules that triggers against malwares through the “malware” gate.
However, ClamAV has a limitation for the size of files that it can scan for a single image SBOM. Currently, the maximum allowable size of file that ClamAV can scan is 4GB. Additionally, utilizing the “malware” gate will impact analysis/scanning time as each analyzer service for the “malware” gate runs a malware signature update before analyzing each image SBOM. The duration of this latency depends on the size and number of files the image SBOM contains.
Note For detailed information about malware scanning, please click here
Example Use-case
Scenario 1
Goal: Create a rule that results in a STOP action if malware is detected on an image SBOM.
Example rule set configuration in Anchore Enterprise
Gate: malware
Trigger: scans
Action: STOP
Reference: malware
Trigger | Description | Parameters |
---|
scans | Triggers if any malware scanner has found any matches in the image. | |
scan_not_run | Triggers if no scan was found for the image. | |
5.8 - Gate: metadata
Introduction
The “metadata” gate provides users a variety of attributes to create policy rules that check against image SBOM metadata. Currently, the following attributes are provided in the “metadata” gate for policy rule creation:
- size
- architecture
- os type
- distro
- distro version
- like distro
- layer count
Example Use-case
Scenario 1
Goal: Create a rule that results in a STOP action for an image SBOM containing alpine OS.
Example rule set configuration in Anchore Enterprise
Gate: metadata
Trigger: attribute
Required Parameters: attribute = “os type”, check = “=”, value = “alpine”
Action: STOP
Trigger Name | Description | Parameter | Description | Example |
---|
attribute | Triggers if a named image metadata value matches the given condition. | attribute | Attribute name to be checked. | size |
attribute | Triggers if a named image metadata value matches the given condition. | check | The operation to perform the evaluation. | > |
attribute | Triggers if a named image metadata value matches the given condition. | value | Value used in comparison. | 1073741824 |
5.9 - Gate: packages
Introduction
The “packages” gate allows users to perform checks against the packages discovered in an image SBOM.
Example Use-cases
Scenario 1
Goal: Create a rule that results in a STOP action if libssl packages are not found in an image SBOM.
Example rule set configuration in Anchore Enterprise
Gate: packages
Trigger: required package
Required Parameters: name = “libssl”
Action: STOP
Scenario 2
Goal: Create a rule that results in a STOP action if libssl-dev packages are found in an image SBOM but running on a version other than 1.1.1-1ubuntu2.1~18.04.23.
Example rule set configuration in Anchore Enterprise
Gate: packages
Trigger: metadata
Optional Parameters: name = “libssl-dev”, name comparison = “=”, version = “1.1.1-1ubuntu2.1~18.04.23”, version comparison = “!=”
Action: STOP
Reference: packages
Trigger Name | Description | Parameter | Description | Example |
---|
required_package | Triggers if the specified package and optionally a specific version is not found in the image. | name | Name of package that must be found installed in image. | libssl |
required_package | Triggers if the specified package and optionally a specific version is not found in the image. | version | Optional version of package for exact version match. | 1.10.3rc3 |
required_package | Triggers if the specified package and optionally a specific version is not found in the image. | version_match_type | The type of comparison to use for version if a version is provided. | exact |
verify | Check package integrity against package db in the image. Triggers for changes or removal or content in all or the selected “dirs” parameter if provided, and can filter type of check with the “check_only” parameter. | only_packages | List of package names to limit verification. | libssl,openssl |
verify | Check package integrity against package db in the image. Triggers for changes or removal or content in all or the selected “dirs” parameter if provided, and can filter type of check with the “check_only” parameter. | only_directories | List of directories to limit checks so as to avoid checks on all dir. | /usr,/var/lib |
verify | Check package integrity against package db in the image. Triggers for changes or removal or content in all or the selected “dirs” parameter if provided, and can filter type of check with the “check_only” parameter. | check | Check to perform instead of all. | changed |
denylist | Triggers if the evaluated image has a package installed that matches the named package optionally with a specific version as well. | name | Package name to denylist. | openssh-server |
denylist | Triggers if the evaluated image has a package installed that matches the named package optionally with a specific version as well. | version | Specific version of package to denylist. | 1.0.1 |
metadata | Triggers on a package type comparison. | type | The type of package. | rpm |
metadata | Triggers on a package name comparison. | name | The name of the package. Wildcards are supported. | *ssl |
metadata | Triggers on a package version comparison. | version | The version of the package. Wildcards are supported. | *fips |
5.10 - Gate: passwd_file
Introduction
The “passwd_file” gate allows users to perform checks against /etc/passwd files with the retrieve_files cataloger. For more information about cataloger scans, please click here.
Example Use-case
Scenario 1
Goal: Create a rule that results in a STOP action for username “foobar” that is found in /etc/passwd in values.yaml file.
Note In order to use this gate, the values.yaml file for your Anchore deployment must have usernames configured for deny listing.
Example rule set configuration in Anchore Enterprise
Gate: passwd file
Trigger: denylist usernames
Required Parameters: user names = “foobar”
Action: STOP
Reference: passwd_file
Trigger Name | Description | Parameter | Description | Example |
---|
content_not_available | Triggers if the /etc/passwd file is not present/stored in the evaluated image. | | | |
denylist_usernames | Triggers if specified username is found in the /etc/passwd file | user_names | List of usernames that will cause the trigger to fire if found in /etc/passwd. | daemon,ftp |
denylist_userids | Triggers if specified user id is found in the /etc/passwd file | user_ids | List of userids (numeric) that will cause the trigger to fire if found in /etc/passwd. | 0,1 |
denylist_groupids | Triggers if specified group id is found in the /etc/passwd file | group_ids | List of groupids (numeric) that will cause the trigger ot fire if found in /etc/passwd. | 999,20 |
denylist_shells | Triggers if specified login shell for any user is found in the /etc/passwd file | shells | List of shell commands to denylist. | /bin/bash,/bin/zsh |
denylist_full_entry | Triggers if entire specified passwd entry is found in the /etc/passwd file. | entry | Full entry to match in /etc/passwd. | ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin |
5.11 - Gate: retrieved_files
Introduction
The “retrieved_files” gate allows users to check against the content and/or presence of files retrieved at the time of analysis for an image SBOM. The intent of this gate is to allow users to utilize the retrieve_files cataloger in order to create policy rules from a configured file list. However, the usage of this gate depends on running the retrieve_files cataloger which will require more resrouces and time to perform analysis on the image SBOM. For more information about cataloger scans, please click here.
Note The “retrieved_files” gate differs from the “files” gate. The “retrieved_files” gate utilizes Anchore’s cataloger capability and checks against files that are provided and stored by the user, while the “files” gate checks against the files present in the analyzed image SBOM (ie file content, file names, filesystem attributes)
Example Use-case
Scenario 1
Goal: Create a rule that results in a STOP action if the regex “SSIEnabled” is not found in the content of the file in the path /etc/httpd.conf.
Example rule set configuration in Anchore Enterprise
Gate: retrieved files
Trigger: content regex
Required Parameters: path = “/etc/httpd.conf”, check = “no match”, regex = “SSIEnabled”
Action: STOP
Reference: retrieved_files
Trigger Name | Description | Parameter | Description | Example |
---|
content_not_available | Triggers if the specified file is not present/stored in the evaluated image. | path | The path of the file to verify has been retrieved during analysis | /etc/httpd.conf |
content_regex | Evaluation of regex on retrieved file content | path | The path of the file to verify has been retrieved during analysis | /etc/httpd.conf |
content_regex | Evaluation of regex on retrieved file content | check | The type of check to perform with the regex | match |
content_regex | Evaluation of regex on retrieved file content | regex | The regex to evaluate against the content of the file | .SSlEnabled. |
5.12 - Gate: secret_scans
Introduction
The “secret_scans” gate allows users to perform checks against secrets and content found in an image SBOM using configured regexes found in the “secret_search” section of the analyzer_config.yaml file.
In order to use this gate effectively, ensure that regexes are properly configured in the analyzer_config.yaml file in the Anchore deployment. By default, the following names are made available in the “secret_search” section:
AWS_ACCESS_KEY
AWS_SECRET_KEY
PRIV_KEY
DOCKER_AUTH
API_KEY
Example Use-case
Scenario 1
Goal: Create a rule that results in a STOP action for disclosed AWS access key regex strings (that includes “/etc/.*) in an image SBOM.
Note In order to use this gate, the analyzer_config.yaml file for your Anchore deployment must have regexps named and configured.
If none of the optional parameters are used for the policy rule, by default, all regexp_match that are configured in the analyzer_config.yaml file will be checked.*
Example rule set configuration in Anchore Enterprise
Gate: secret scans
Trigger: content regex checks
Optional Parameters: content regex name = “AWS_ACCESS_KEY”, filename regex = “/etc/.*”, match type = “found”
Action: STOP
Reference: secret_scans
Trigger Name | Description | Parameter | Description | Example |
---|
content_regex_checks | Triggers if the secret content search analyzer has found any matches with the configured and named regexes. Checks can be configured to trigger if a match is found or is not found (selected using match_type parameter). Matches are filtered by the content_regex_name and filename_regex if they are set. The content_regex_name shoud be a value from the “secret_search” section of the analyzer_config.yaml. | content_regex_name | Name of content regexps configured in the analyzer that match if found in the image, instead of matching all. Names available by default are: [‘AWS_ACCESS_KEY’, ‘AWS_SECRET_KEY’, ‘PRIV_KEY’, ‘DOCKER_AUTH’, ‘API_KEY’]. | AWS_ACCESS_KEY |
content_regex_checks | Triggers if the secret content search analyzer has found any matches with the configured and named regexes. Checks can be configured to trigger if a match is found or is not found (selected using match_type parameter). Matches are filtered by the content_regex_name and filename_regex if they are set. The content_regex_name shoud be a value from the “secret_search” section of the analyzer_config.yaml. | filename_regex | Regexp to filter the content matched files by. | /etc/.* |
content_regex_checks | Triggers if the secret content search analyzer has found any matches with the configured and named regexes. Checks can be configured to trigger if a match is found or is not found (selected using match_type parameter). Matches are filtered by the content_regex_name and filename_regex if they are set. The content_regex_name shoud be a value from the “secret_search” section of the analyzer_config.yaml. | match_type | Set to define the type of match - trigger if match is found (default) or not found. | found |
5.13 - Gate: tag_drift
Introduction
If evaluating by image tag, the “tag_drift” gate allows users to perform checks against packages that have been changed (added, removed, modified) on an image SBOM from the tag’s previous image SBOM.
Example Use-case
Scenario 1
Goal: Create a rule that results in a STOP action for any packages that have been modified in an evaluated image tag’s SBOM from the tag’s previous evaluation results.
Example rule set configuration in Anchore Enterprise
Gate: tag drift
Trigger: packages modified
Action: STOP
Reference: tag_drift
Gate: Tag Drift
Compares the SBOM from the evaluated image’s tag and the tag’s previous image, if found. Provides triggers to detect packages added, removed or modified.
Trigger Name | Description | Parameter | Description | Example |
---|
packages_added | Checks to see if any packages have been added. | package_type | Package type to filter for only specific types. If ommitted, then all types are evaluated. | apk |
packages_removed | Checks to see if any packages have been removed. | package_type | Package type to filter for only specific types. If ommitted, then all types are evaluated. | apk |
packages_modified | Checks to see if any packages have been modified. | package_type | Package type to filter for only specific types. If ommitted, then all types are evaluated. | apk |
5.14 - Gate: vulnerabilities
Introduction
The “vulnerabilities” gate provides users the ability to use either a single or combination of triggers and attributes that match against vulnerability metadata to create policies for the vulnerabilities discovered in an image SBOM.
Note Currently, only the following Triggers are available for Source Repository Rule Sets:
- Denylist
- Package
- Stale Feed Data
Example Use-cases
Scenario 1
Goal: Create a rule that results in a STOP action for every critical vulnerability.
Example rule set configuration in Anchore Enterprise
Gate: vulnerabilities
Trigger: package
Required Parameters: package type = “all”
Optional Parameters: severity comparison = “=”, severity = “critical”
Recommendations (optional): “Remediation is required for critical vulnerabilities.”
Action: STOP
Scenario 2
Goal: Create a rule that results in a STOP action for every vulnerability that is a part of CISA’s KEV list.
Example rule set configuration in Anchore Enterprise
Gate: vulnerabilities
Trigger: kev list
Recommendations (optional): “This vulnerability is part of CISA’s Known Exploited Vulnerability (KEV) catalogue. Remediation is required.”
Action: STOP
Scenario 3
Goal: Create a rule that results in a WARN action for every critical vulnerability with a fix that will not be addressed by a vendor.
Example rule set configuration in Anchore Enterprise
Gate: vulnerabilities
Trigger: package
Required Parameters: package type = “all”
Optional Parameters: severity comparison = “=”, severity = “critical”, vendor only = “false”
Recommendations (optional): “Even though this is a critical vulnerability, the vendor indicates that a fix will not be addressed.”
Action: WARN
Reference: vulnerabilities
Trigger Name | Description | Parameter | Description | Example |
---|
package | Triggers if a found vulnerability in an image meets the comparison criteria. | package_type | Only trigger for specific package type. | all |
package | Triggers if a found vulnerability in an image meets the comparison criteria. | severity_comparison | The type of comparison to perform for severity evaluation. | > |
package | Triggers if a found vulnerability in an image meets the comparison criteria. | severity | Severity to compare against. | high |
package | Triggers if a found vulnerability in an image meets the comparison criteria. | cvss_v3_base_score_comparison | The type of comparison to perform for CVSS v3 base score evaluation. | > |
package | Triggers if a found vulnerability in an image meets the comparison criteria. | cvss_v3_base_score | CVSS v3 base score to compare against. | None |
package | Triggers if a found vulnerability in an image meets the comparison criteria. | cvss_v3_exploitability_score_comparison | The type of comparison to perform for CVSS v3 exploitability sub score evaluation. | > |
package | Triggers if a found vulnerability in an image meets the comparison criteria. | cvss_v3_exploitability_score | CVSS v3 exploitability sub score to compare against. | None |
package | Triggers if a found vulnerability in an image meets the comparison criteria. | cvss_v3_impact_score_comparison | The type of comparison to perform for CVSS v3 impact sub score evaluation. | > |
package | Triggers if a found vulnerability in an image meets the comparison criteria. | cvss_v3_impact_score | CVSS v3 impact sub score to compare against. | None |
package | Triggers if a found vulnerability in an image meets the comparison criteria. | fix_available | If present, the fix availability for the vulnerability record must match the value of this parameter. | true |
package | Triggers if a found vulnerability in an image meets the comparison criteria. | vendor_only | If True, an available fix for this CVE must not be explicitly marked as wont be addressed by the vendor | true |
package | Triggers if a found vulnerability in an image meets the comparison criteria. | max_days_since_creation | A grace period, in days, for a vulnerability match to be present after which the vulnerability is a policy violation. Uses the date the match was first found for the given image. | 7 |
package | Triggers if a found vulnerability in an image meets the comparison criteria. | max_days_since_fix | If provided (only evaluated when fix_available option is also set to true), the fix first observed time must be older than the days provided, to trigger. | 30 |
package | Triggers if a found vulnerability in an image meets the comparison criteria. | vendor_cvss_v3_base_score_comparison | The type of comparison to perform for vendor specified CVSS v3 base score evaluation. | > |
package | Triggers if a found vulnerability in an image meets the comparison criteria. | vendor_cvss_v3_base_score | Vendor CVSS v3 base score to compare against. | None |
package | Triggers if a found vulnerability in an image meets the comparison criteria. | vendor_cvss_v3_exploitability_score_comparison | The type of comparison to perform for vendor specified CVSS v3 exploitability sub score evaluation. | > |
package | Triggers if a found vulnerability in an image meets the comparison criteria. | vendor_cvss_v3_exploitability_score | Vendor CVSS v3 exploitability sub score to compare against. | None |
package | Triggers if a found vulnerability in an image meets the comparison criteria. | vendor_cvss_v3_impact_score_comparison | The type of comparison to perform for vendor specified CVSS v3 impact sub score evaluation. | > |
package | Triggers if a found vulnerability in an image meets the comparison criteria. | vendor_cvss_v3_impact_score | Vendor CVSS v3 impact sub score to compare against. | None |
package | Triggers if a found vulnerability in an image meets the comparison criteria. | package_path_exclude | The regex to evaluate against the package path to exclude vulnerabilities | .test.jar |
package | Triggers if a found vulnerability in an image meets the comparison criteria. | inherited_from_base | If true, only show vulns inherited from the base, if false than only show vulns not inherited from the base. Don’t specify to include vulns from the base image and the current image. See Base Images for more details. | True |
denylist | Triggers if any of a list of specified vulnerabilities has been detected in the image. | vulnerability_ids | List of vulnerability IDs, will cause the trigger to fire if any are detected. | CVE-2019-1234 |
denylist | Triggers if any of a list of specified vulnerabilities has been detected in the image. | vendor_only | If set to True, discard matches against this vulnerability if vendor has marked as will not fix in the vulnerability record. | True |
stale_feed_data | Triggers if the CVE data is older than the window specified by the parameter MAXAGE (unit is number of days). | max_days_since_sync | Fire the trigger if the last sync was more than this number of days ago. | 10 |
vulnerability_data_unavailable | Triggers if vulnerability data is unavailable for the image’s distro packages such as rpms or dpkg. Non-OS packages like npms and java are not considered in this evaluation | None | None | None |
kev_list_data_missing | Triggers if the KEV list data has not been synced. | None | None | None |
kev_list | Triggers if any vulns are on the KEV list. | None | None | None |
5.15 - Gate: always
Introduction
The “always” gate is intended for testing purposes and is advised against actual policy usage. The “always” gate only has one trigger that if it is part of a rule set, the policy evaluation will automatically result with the configured action (in most cases, “STOP”). This is especially useful when users want to test mappings and allowlists because they can use this rule in combination with other rules in a single rule set without having to manually create dedicated policies for running tests.
The gate will always trigger with the configured action if it is included inside an active policy.
Reference: always
Trigger Name | Description | Parameter | Description | Example |
---|
always | Fires if present in a policy being evaluated. Useful for things like deny-listing images or testing mappings and allowlists by using this trigger in combination with policy mapping rules. | | | |
6 - Policy Packs
Introduction
Anchore Enterprise provides pre-built policy packs to scan for the following compliance frameworks:
6.1 - FedRAMP
Throughout this guide, we break down the deployment and configuration of the FedRAMP policy with the following sections:
Current FedRAMP policy pack version: Anchore FedRAMP v5 Checks v20241001
Introduction
FedRAMP (Federal Risk and Authorization Management Program) is a standardized approach for assessing, authorizing, and monitoring cloud service providers (CSPs) that provide service to federal agencies. Through a rigorous and comprehensive process, FedRAMP ensures that CSPs meet security standards by providing a baseline set of security controls in order to enhance the overall security for federal information systems.
Anchore’s FedRAMP policy validates whether container images scanned by Anchore Enterprise are compliant with the FedRAMP Vulnerability Scanning Requirements and also validates them against FedRAMP controls specified in NIST 800-53 Rev 5 and NIST 800-190.
Anchore’s FedRAMP policy only checks for specification requirements relevant to software supply chain security.
Anchore’s FedRAMP policy checks for the following specifications:
- AC-6(10) ACCESS CONTROL: Prevent Non-Privileged Users from Executing Privileged Functions
- CM-2(2), CM-3(1), CM-6 CONFIGURATION MANAGEMENT: Baseline Configuration | Configure Systems and Components for High-risk Areas
- CM-10 CONFIGURATION MANAGEMENT: Software Usage Restrictions
- CM-5(5) CONFIGURATION MANAGEMENT: Access Restrictions for Change | Privilege Limitation for Production and Operation
- CM-7(1) CONFIGURATION MANAGEMENT: Least Functionality - Network Port Exposure Checks
- CM-7(5), CM-8(3) CONFIGURATION MANAGEMENT: Least Functionality - Container Image Build Content Checks
- IA-05(7) IDENTIFICATION AND AUTHENTICATION: Authenticator Management | No Embedded Unencrypted Static Authenticators
- RA-5, SI-02(2) RISK ASSESSMENT: Vulnerability Monitoring and Scanning
- SC-5 SYSTEM AND COMMUNICATIONS PROTECTION: Denial-of-Service Protection
Enabling the FedRAMP Policy
If you are an Anchore Enterprise customer, you will receive an email, which includes a json file for the specific FedRAMP policy that comes with your service.
Navigate to the Policies tab in Anchore Enterprise and click on the ‘Import Policy’.
Drag and drop, or paste the .json file to import the policy into Anchore Enterprise.
Or run the following command using AnchoreCTL
# anchorectl policy add --input FedRAMP_policy_pack_json_file
✔ Added policy
Name: Anchore FedRAMP v5 Checks
Policy Id: 1346c770-c49b-46be-b8f0-961ee40afbc3
Active: false
Updated: 2024-05-01T21:09:41Z
After a successful import, the FedRAMP policy will be available in the Policies tab.
Or run the following command using AnchoreCTL
# anchorectl policy list
✔ Fetched policies
┌───────────────────────────┬──────────────────────────────────────┬────────┬──────────────────────┐
│ NAME │ POLICY ID │ ACTIVE │ UPDATED │
├───────────────────────────┼──────────────────────────────────────┼────────┼──────────────────────┤
│ Default policy │ 2c53a13c-1765-11e8-82ef-23527761d060 │ true │ 2024-04-25T18:21:54Z │
│ Anchore FedRAMP v5 Checks │ 1346c770-c49b-46be-b8f0-961ee40afbc3 │ false │ 2024-04-25T18:23:10Z │
└───────────────────────────┴──────────────────────────────────────┴────────┴──────────────────────┘
In order to activate the FedRAMP policy, simply click on the circle under ‘Active’.
Once activated, you will see that the FedRAMP policy is highlighted in green.
Or run the following command using AnchoreCTL
# anchorectl policy activate 1346c770-c49b-46be-b8f0-961ee40afbc3
✔ Activate policy
Name: Anchore FedRAMP v5 Checks
Policy Id: 1346c770-c49b-46be-b8f0-961ee40afbc3
Active: true
Updated: 2024-04-25T18:30:24Z
Navigate to the Image tab in Anchore Enterprise and you will now be able to evaluate an image with the FedRAMP policy.
Or run the following command using AnchoreCTL
As an example, we will add a centos image and evaluate it using the FedRAMP policy. please give it some time for Anchore to analyze the image when added
# anchorectl image add docker.io/centos:latest --wait
✔ Added Image docker.io/centos:latest
✔ Analyzed Image docker.io/centos:latest
Image:
status: analyzed (active)
tag: docker.io/centos:latest
digest: sha256:a1801b843b1bfaf77c501e7a6d3f709401a1e0c83863037fa3aab063a7fdb9dc
id: 5d0da3dc976460b72c77d94c8a1ad043720b0416bfc16c52c45d4847e53fadb6
distro: centos@8 (amd64)
layers: 1
To apply the active FedRAMP policy and see all the details of violation:
#anchorectl image check docker.io/centos:latest --detail
To apply the active FedRAMP policy and get a simple pass/fail check:
#anchorectl image check -f docker.io/centos:latest
✔ Evaluated against policy [failed] docker.io/centos:latest
Tag: docker.io/centos:latest
Digest: sha256:a1801b843b1bfaf77c501e7a6d3f709401a1e0c83863037fa3aab063a7fdb9dc
Policy ID: 1346c770-c49b-46be-b8f0-961ee40afbc3
Last Evaluation: 2024-04-25T18:40:15Z
Evaluation: fail
Final Action: stop
Reason: policy_evaluation
error: 1 error occurred:
* failed policies:
Configuring Rule Sets for the FedRAMP Policy
Some of the control specifications need configuration based on the user’s environment. The control specifications are represented by ‘Rule Sets’ in Anchore Enterprise. Navigate to the Policies tab and click on the ‘Edit’ under ‘Actions’.
It is recommended all configuration changes to rule sets be done in the Anchore Enterprise UI.
You will be able to view all the FedRAMP specifications Anchore analyzes for. Under each Rule Set, please edit the ones that require configuration.
As an example, a user may need to change the port configuration for CM-7(1) CONFIGURATION MANAGEMENT, which checks for network port exposures.
Make sure to go through each of the Rule Sets to configure all applicable specifications. Save and close.
The following rule sets MUST be configured before using the FedRAMP policy:
- CM-2(2), CM-3(1), CM-6 CONFIGURATION MANAGEMENT: Baseline Configuration | Configure Systems and Components for High-risk Areas
- CM-10 CONFIGURATION MANAGEMENT: Software Usage Restrictions
- CM-5(5) CONFIGURATION MANAGEMENT: Access Restrictions for Change | Privilege Limitation for Production and Operation
- CM-7(1) CONFIGURATION MANAGEMENT: Least Functionality - Network Port Exposure Checks
- CM-7(5), CM-8(3) CONFIGURATION MANAGEMENT: Least Functionality - Container Image Build Content Checks
6.2 - NIST
Throughout this guide, we break down the deployment and configuration of the NIST policy with the following sections:
Current NIST 800-53 policy pack version: Anchore NIST 800-53 v20240901
Introduction
The National Institute of Standards and Technology (NIST) is a non-regulatory agency of the U.S Commerce Department that provides industry standards and guidelines to help federal agencies meet requirements set by the Federal Information Security Management Act (FISMA).
Anchore Enterprise scans for the following NIST policies:
Anchore also covers NIST 800-218 (SSDF) with the SSDF Attestation Form Guide and Evidence document, which includes evidence-based artifacts for an official SSDF Attestation Form submission. To learn more, click here.
NIST 800-53 provides guidelines to ensure the security of information systems used within the federal government. In order to maintain the integrity, confidentiality and security of federal information systems, NIST 800-53 provides a catalogue of controls in order for federal agencies to meet industry standard and compliance.
Anchore checks for the following control specifications in the NIST 800-53 policy:
- AC-6(10) Container Image Must Have Permissions Removed from Executables that Allow a User to Execute Software at Higher Privileges
- CM-6(b) Confidential Data Checks
- CM-7(1b) Network Port Exposure Checks
- CM-7(a) Container Image Build Content Checks
- IA-5(2a) Base Image Checks
- IA-5(7) Embedded Credentials
- RA-5 Software Vulnerability Checks
- SC-5 Image Checks
- SC-8(2) Base Image Checks
- SI-2(6) Image Software Update/Layer Checks
NIST 800-190 provides guidelines to ensure the security of application containers used within the federal government. In order to maintain the integrity, confidentiality and security of federal application containers, NIST 800-190 provides a catalogue of controls in order for federal agencies to meet industry standard and compliance.
Anchore checks for the following control specifications in the NIST 800-190 policy:
- 3.1.1 Image Vulnerabilities
- 3.1.2 Image Configuration Defects
- 3.1.3 Embedded Malware
- 3.1.4 Embedded Clear Text Secrets
Enabling the NIST Policy
For this walkthrough, we will be using the NIST 800-53 policy for demonstration.
If you are an Anchore Enterprise customer, you will receive an email, which includes a json file for the NIST 800-53 policy that comes with your service.
Navigate to the Policies tab in Anchore Enterprise and click on the ‘Import Policy’.
Drag and drop, or paste the .json file to import the policy into Anchore Enterprise.
Or run the following command using AnchoreCTL
# anchorectl policy add --input NIST_800_53_policy_pack.json
✔ Added policy
Name: NIST 800-53
Policy Id: 5-NIST-800-53-policy
Active: false
Updated: 2024-05-01T21:05:36Z
After a successful import, the NIST 800-53 policy will be available in the Policies tab.
Or run the following command using AnchoreCTL
# anchorectl policy list
✔ Fetched policies
┌────────────────┬──────────────────────────────────────┬────────┬──────────────────────┐
│ NAME │ POLICY ID │ ACTIVE │ UPDATED │
├────────────────┼──────────────────────────────────────┼────────┼──────────────────────┤
│ Default policy │ 2c53a13c-1765-11e8-82ef-23527761d060 │ true │ 2024-05-01T21:03:55Z │
│ NIST 800-53 │ 5-NIST-800-53-policy │ false │ 2024-05-01T21:05:36Z │
└────────────────┴──────────────────────────────────────┴────────┴──────────────────────┘
In order to activate the NIST 800-53 policy, simply click on the circle under ‘Active’.
Once activated, you will see that the NIST 800-53 policy is highlighted in green.
Or run the following command using AnchoreCTL
# anchorectl policy activate 5-NIST-800-53-policy
✔ Activate policy
Name: NIST 800-53
Policy Id: 5-NIST-800-53-policy
Active: true
Updated: 2024-05-01T21:15:43Z
Navigate to the Image tab in Anchore Enterprise and you will now be able to evaluate an image with the NIST 800-53 policy.
Or run the following command using AnchoreCTL
As an example, we will add a centos image and evaluate it using the NIST 800-53 policy. please give it some time for Anchore to analyze the image when added
# anchorectl image add docker.io/centos:latest --wait
✔ Added Image docker.io/centos:latest
✔ Analyzed Image docker.io/centos:latest
Image:
status: analyzed (active)
tag: docker.io/centos:latest
digest: sha256:a1801b843b1bfaf77c501e7a6d3f709401a1e0c83863037fa3aab063a7fdb9dc
id: 5d0da3dc976460b72c77d94c8a1ad043720b0416bfc16c52c45d4847e53fadb6
distro: centos@8 (amd64)
layers: 1
To apply the active NIST 800-53 policy and see all the details of violation:
#anchorectl image check docker.io/centos:latest --detail
To apply the active NIST 800-53 policy and get a simple pass/fail check:
#anchorectl image check -f docker.io/centos:latest
✔ Evaluated against policy [failed] docker.io/centos:latest
Tag: docker.io/centos:latest
Digest: sha256:a1801b843b1bfaf77c501e7a6d3f709401a1e0c83863037fa3aab063a7fdb9dc
Policy ID: 5-NIST-800-53-policy
Last Evaluation: 2024-05-01T21:17:51Z
Evaluation: fail
Final Action: stop
Reason: denylisted
error: 1 error occurred:
* failed policies:
Configuring Rule Sets for the NIST 800-53 Policy
Some of the control specifications need configuration based on the user’s environment. The control specifications are represented by ‘Rule Sets’ in Anchore Enterprise. Navigate to the Policies tab and click on the ‘Edit’ under ‘Actions’.
It is recommended all configuration changes to rule sets be done in the Anchore Enterprise UI.
You will be able to view all the NIST 800-53 specifications Anchore analyzes for.
As an example, a user may need to change the port configuration for CM-7(1b): Network Port Exposure Checks, which checks for network port exposures.
Make sure to go through each of the Rule Sets to configure all applicable specifications. Save and close.
The following rule sets MUST be configured before using the NIST 800-53 policy:
- CM-6(b) Confidential Data Checks
- CM-7(1b) Network Port Exposure Checks
- CM-7(a) Container Image Build Content Checks
6.2.1 - SSDF
In February 2021, The National Institute of Standards and Technology (NIST) created NIST SP 800-218, otherwise known as Secure Software Development Framework (SSDF), in response to a new executive order mandated by the federal government.
SSDF provides a comprehensive set of guidelines aimed at integrating security into the software development lifecycle, thereby enhancing the security posture of software products from inception to deployment. To verify and validate that organizations meet the controls needed to be SSDF compliant, CISA created an official SSDF Attestation Form that allows organizations to verify and attest that they adhere to the SSDF guidelines and comply with a subset of security controls.
Purpose
Anchore provides a downloadable document that serves as an evidence attachment for the SSDF Attestation Form. The document makes the assumption Anchore Enterprise is used in the organization’s environment and is configured to scan the software that is in scope for the SSDF Attestation Form.
The SSDF Attestation Form consists of three sections that must be completed. Sections I and II cover organization-specific details, whereas Section III lists requirements against various security controls. The intent of this document is to provide guidance for first time applicants and help organizations save time collecting evidence required for Section III of the SSDF Attestation Form.
Download
Detailed instructions to complete the form can be found on page 1. This document uses the official SSDF Attestation Form as its base template. Once completed, the document can be directly attached to an SSDF Attestation Form submission. Click below to obtain the form:
Additional Resources
- SSDF Attestation 101: A practical guide for Software Producers - Download eBook
- Using the Common Form for SSDF Attestation: What Software Producers Need to Know - Read blog
- Automate NIST compliance and SSDF attestation with Anchore Enterprise - Learn more
If you want to contact one of our experts, please contact us.
6.3 - CIS
Throughout this guide, we break down the deployment and configuration of the CIS policy with the following sections:
Current CIS policy pack version: Anchore CIS Docker Benchmark V1.6.0 v20241001
Introduction
The Center for Internet Security (CIS) provides prescriptive configuration recommendations for a variety of software vendors. Anchore’s CIS policy pack is based off of the CIS Docker 1.6 Benchmark and validates a subset of security and compliance checks against container images deployed on Docker version 1.6.
Anchore checks for the following control specifications in the CIS policy:
- 4.1 Ensure that a user for the container has been created
- 4.2 Ensure that containers use only trusted base
- 4.3 Ensure that unnecessary packages are not installed in the container
- 4.4 Ensure images are scanned and rebuilt to include security patches
- 4.6 Ensure that HEALTHCHECK instructions have been added to container images
- 4.7 Ensure update instructions are not used alone in Dockerfiles
- 4.8 Ensure setuid and setgid permissions are removed
- 4.9 Ensure that COPY is used instead of ADD in Dockerfiles
- 4.10 Ensure secrets are not stored in Dockerfiles
- 4.11 Ensure only verified packages are installed
- 5.8 Ensure privileged ports are not mapped within containers
Enabling the CIS Policy
For this walkthrough, we will be using the IronBank policy for demonstration.
If you are an Anchore Enterprise customer, you will receive an email, which includes a json file for the IronBank policy that comes with your service.
Navigate to the Policies tab in Anchore Enterprise and click on the ‘Import Policy’.
Drag and drop, or paste the .json file to import the policy into Anchore Enterprise.
Or run the following command using AnchoreCTL
# anchorectl policy add --input anchore_dod_iron_bank_security_policies_09212022.json
✔ Added policy
Name: anchore_dod_iron_bank_security_policies_09212022
Policy Id: 5-DoD-Iron-Bank-Docker
Active: false
Updated: 2024-05-03T21:42:53Z
After a successful import, the IronBank policy will be available in the Policies tab.
Or run the following command using AnchoreCTL
# anchorectl policy list
✔ Fetched policies
┌──────────────────────────────────────────────────┬──────────────────────────────────────┬────────┬──────────────────────┐
│ NAME │ POLICY ID │ ACTIVE │ UPDATED │
├──────────────────────────────────────────────────┼──────────────────────────────────────┼────────┼──────────────────────┤
│ Default policy │ 2c53a13c-1765-11e8-82ef-23527761d060 │ true │ 2024-05-03T22:04:08Z │
│ anchore_dod_iron_bank_security_policies_09212022 │ 5-DoD-Iron-Bank-Docker │ false │ 2024-05-03T22:04:08Z │
└──────────────────────────────────────────────────┴──────────────────────────────────────┴────────┴──────────────────────┘
In order to activate the IronBank policy, simply click on the circle under ‘Active’.
Once activated, you will see that the IronBank policy is highlighted in green.
Or run the following command using AnchoreCTL
# anchorectl policy activate 5-DoD-Iron-Bank-Docker
✔ Activate policy
Name: anchore_dod_iron_bank_security_policies_09212022
Policy Id: 5-DoD-Iron-Bank-Docker
Active: true
Updated: 2024-05-03T22:07:54Z
Navigate to the Image tab in Anchore Enterprise and you will now be able to evaluate an image with the IronBank policy.
Or run the following command using AnchoreCTL
As an example, we will add a centos image and evaluate it using the IronBank policy. please give it some time for Anchore to analyze the image when added
# anchorectl image add docker.io/centos:latest --wait
✔ Added Image docker.io/centos:latest
✔ Analyzed Image docker.io/centos:latest
Image:
status: analyzed (active)
tag: docker.io/centos:latest
digest: sha256:a1801b843b1bfaf77c501e7a6d3f709401a1e0c83863037fa3aab063a7fdb9dc
id: 5d0da3dc976460b72c77d94c8a1ad043720b0416bfc16c52c45d4847e53fadb6
distro: centos@8 (amd64)
layers: 1
To apply the active IronBank policy and see all the details of violation:
#anchorectl image check docker.io/centos:latest --detail
To apply the active IronBank policy and get a simple pass/fail check:
#anchorectl image check -f docker.io/centos:latest
✔ Evaluated against policy [failed] docker.io/centos:latest
Tag: docker.io/centos:latest
Digest: sha256:a1801b843b1bfaf77c501e7a6d3f709401a1e0c83863037fa3aab063a7fdb9dc
Policy ID: 5-DoD-Iron-Bank-Docker
Last Evaluation: 2024-05-03T22:08:52Z
Evaluation: fail
Final Action: stop
Reason: policy_evaluation
Configuring Rule Sets for the CIS Policy
Some of the control specifications need configuration based on the user’s environment. The control specifications are represented by ‘Rule Sets’ in Anchore Enterprise. Navigate to the Policies tab and click on the ‘Edit’ under ‘Actions’.
It is recommended all configuration changes to rule sets be done in the Anchore Enterprise UI.
The following rule sets MUST be configured before using the CIS policy:
- 4.2 Ensure that containers use only trusted base
- 4.3 Ensure that unnecessary packages are not installed in the container
- 5.8 Ensure privileged ports are not mapped within containers
6.4 - DoD
Throughout this guide, we break down the deployment and configuration of the DoD policy with the following sections:
Current IronBank policy pack version: Anchore DoD Iron Bank v20241001
Current DISA policy pack version: Anchore DISA Image Creation and Hardening Guide v20241001
Introduction
Anchore Enterprise scans for the following DoD policies:
- DISA Image Creation and Deployment Guide
- IronBank
Being part of the Department of Defense (DoD), Defense Information Systems Administration (DISA) is the agency that provides IT and communications support to both the US government and federal organizations. The DISA Image Creation and Deployment Guide Policy provides security and compliance checks that align with specific NIST 800-53 and NIST 800-190 security controls and requirements as described in the DoD Container Image Creation and Deployment Guide.
Anchore checks for the following control specifications in the DISA policy:
- AC6(10) Container Image Must Have Permissions Removed from Executables that Allow a User to Execute Software at Higher Privileges
- CM-6(b) Confidential Data Checks
- CM-7(1b) Network Port Exposure Checks
- CM-7(a) Container Image Build Content Checks
- IA-5(2a) Base Image Checks
- IA-5(7) Embedded Credentials
- RA-5 Software Vulnerability Checks
- SC-5 Image Checks
- SC-8(2) Base Image Checks
- SI-2(6) Image Software Update/Layer Checks
The DoD IronBank policy validates images against DoD security and compliance requirements in alignment with U.S. Air Force security standards at Platform One and IronBank. The IronBank policy has been written in accordance to the following DoD documentation.
- Dockerfile Checks
- User Checks
- File Checks
- Istio Checks
- Software Checks
- Transfer Protocol Checks
- Node.js Checks
- Etcd Checks
- Snort Checks
- Jenkins Checks
- Grafana Checks
- UBI7 Checks
- Chef Checks
- Sonarqube Checks
- Prometheus Checks
- Postgres Checks
- Nginx Checks
- OpenJDK Checks
- Twistlock Checks
- Keycloak Checks
- Fluentd Checks
- Elasticsearch Checks
- Kibana Checks
- Redis Checks
- Apache HTTP Checks
- Apache Tomcat Checks
Enabling the DoD Policy
For this walkthrough, we will be using the IronBank policy for demonstration.
If you are an Anchore Enterprise customer, you will receive an email, which includes a json file for the IronBank policy that comes with your service.
Navigate to the Policies tab in Anchore Enterprise and click on the ‘Import Policy’.
Drag and drop, or paste the .json file to import the policy into Anchore Enterprise.
Or run the following command using AnchoreCTL
# anchorectl policy add --input anchore_dod_iron_bank_security_policies_09212022.json
✔ Added policy
Name: anchore_dod_iron_bank_security_policies_09212022
Policy Id: 5-DoD-Iron-Bank-Docker
Active: false
Updated: 2024-05-03T21:42:53Z
After a successful import, the IronBank policy will be available in the Policies tab.
Or run the following command using AnchoreCTL
# anchorectl policy list
✔ Fetched policies
┌──────────────────────────────────────────────────┬──────────────────────────────────────┬────────┬──────────────────────┐
│ NAME │ POLICY ID │ ACTIVE │ UPDATED │
├──────────────────────────────────────────────────┼──────────────────────────────────────┼────────┼──────────────────────┤
│ Default policy │ 2c53a13c-1765-11e8-82ef-23527761d060 │ true │ 2024-05-03T22:04:08Z │
│ anchore_dod_iron_bank_security_policies_09212022 │ 5-DoD-Iron-Bank-Docker │ false │ 2024-05-03T22:04:08Z │
└──────────────────────────────────────────────────┴──────────────────────────────────────┴────────┴──────────────────────┘
In order to activate the IronBank policy, simply click on the circle under ‘Active’.
Once activated, you will see that the IronBank policy is highlighted in green.
Or run the following command using AnchoreCTL
# anchorectl policy activate 5-DoD-Iron-Bank-Docker
✔ Activate policy
Name: anchore_dod_iron_bank_security_policies_09212022
Policy Id: 5-DoD-Iron-Bank-Docker
Active: true
Updated: 2024-05-03T22:07:54Z
Navigate to the Image tab in Anchore Enterprise and you will now be able to evaluate an image with the IronBank policy.
Or run the following command using AnchoreCTL
As an example, we will add a centos image and evaluate it using the IronBank policy. please give it some time for Anchore to analyze the image when added
# anchorectl image add docker.io/centos:latest --wait
✔ Added Image docker.io/centos:latest
✔ Analyzed Image docker.io/centos:latest
Image:
status: analyzed (active)
tag: docker.io/centos:latest
digest: sha256:a1801b843b1bfaf77c501e7a6d3f709401a1e0c83863037fa3aab063a7fdb9dc
id: 5d0da3dc976460b72c77d94c8a1ad043720b0416bfc16c52c45d4847e53fadb6
distro: centos@8 (amd64)
layers: 1
To apply the active IronBank policy and see all the details of violation:
#anchorectl image check docker.io/centos:latest --detail
To apply the active IronBank policy and get a simple pass/fail check:
#anchorectl image check -f docker.io/centos:latest
✔ Evaluated against policy [failed] docker.io/centos:latest
Tag: docker.io/centos:latest
Digest: sha256:a1801b843b1bfaf77c501e7a6d3f709401a1e0c83863037fa3aab063a7fdb9dc
Policy ID: 5-DoD-Iron-Bank-Docker
Last Evaluation: 2024-05-03T22:08:52Z
Evaluation: fail
Final Action: stop
Reason: policy_evaluation
Configuring Rule Sets for the DoD Policy
Some of the control specifications need configuration based on the user’s environment. The control specifications are represented by ‘Rule Sets’ in Anchore Enterprise. Navigate to the Policies tab and click on the ‘Edit’ under ‘Actions’.
It is recommended all configuration changes to rule sets be done in the Anchore Enterprise UI.
The IronBank policy does not need any configuration changes for the Rule Sets. However, the DISA policy will need configuration changes for certain specifications.
As an example, a user may need to change the port configuration for CM-7(1b): Network Port Exposure Checks, which checks for network port exposures.
Make sure to go through each of the Rule Sets to configure all applicable specifications. Save and close.
The following rule sets MUST be configured before using the DISA policy pack:
- CM-6(b) Confidential Data Checks
- CM-7(1b) Network Port Exposure Checks
- CM-7(a) Container Image Build Content Checks
6.5 - Secure
The default Secure policy pack comes included (and enabled) in every fresh deployment of Anchore Enterprise.
Current Secure policy pack version: Anchore Enterprise - Secure v20241001
Introduction
Anchore’s default Secure policy pack includes standard vulnerability and system-level checks and can be used against an image SBOM for policy compliance based on the policy actions configured in each rule. All the rules that are configured by default can (and should) be adjusted acccording to an organization’s security policy.
Anchore checks for the following control specifications in the Secure policy:
- Feed Data not available Fail if feed data is unavailable
- Outdated Feed Data Warn if feed data is more than 2 days old. This value can be adjusted based on internal requirements (Available for both Container and Source)
- Warn on low and moderate with fixes Warn when there are low and medium severity vulnerabilities found that also have a fix present (Available for both Container and Source)
- Warn on week old Important Warn when there are important severity vulnerabilities found that are more than a week old (Available for both Container and Source)
“Important” indicates the severity of a vulnerability. By default, it is set to “High” but this can be configured in the policy rule set - Fail on criticals Fail when there are critical severity vulnerabilities present (Available for both Container and Source)
7 - Testing Policies
Introduction
The Evaluation Preview feature allows you to perform a test evaluation on an image to verify the mapping, policies and allowlists used to evaluate an image.
To test an image you should enter the name of the image, optionally including the registry if the image is not stored on docker.io In the example below an evaluate was requested for library/debian:latest because no registry was specified the default, docker.io registry was used.
Here we can see that the image was evaluated against the policy named “anchore_security_only” and failed, resulting in a STOP action.
Clicking the “View Policy Test Details” will show a more detailed report.
The image was evaluated using the mapping named and the evaluation failed as the image was found in a denylist.
The next line explains that the image had been denylisted by the Deny CentOS denylist rule, however if the image was not denylisted, it would only have produced a WARN instead of a failure.
The subsequent table lists the policy checks that resulted in any Warn or Stop (failure) checks.
The policy checks are performed on images already analyzed and recorded in Anchore Enterprise. If an image has been added to the system but has not yet completed analysis, then the system will display the following error:
If the evaluation test is re-run after a few minutes, the image will likely have completed analysis and a policy evaluation result will be returned.
If the image specified has not been analyzed by the system and has not been submitted for analysis, then the following error message will be displayed.
7.1 - Policy Gate: dockerfile
Introduction
This article reviews the “dockerfile” gate and its triggers. The dockerfile gate allows users to perform checks on the content of the dockerfile or docker history for an image and make policy actions based on the construction of an image, not just its content. This is particularly useful for enforcing best practices or metadata inclusion (e.g. labels) on images.
Anchore is either given a dockerfile or infers one from the docker image layer history. There are implications to what data is available and what it means depending on these differing sources, so first, we’ll cover the input data for the gate and how it impacts the triggers and parameters used.
The “dockerfile”
The data that this gate operates on can come from two different sources:
- The actual dockerfile used to build an image, as provided by the user at the time of running
anchorectl image add <img ref> --dockerfile <filename>
or the corresponding API call to: POST /images?dockerfile= - The history from layers as encoded in the image itself (see
docker history <img>
for this output)
All images have data from history available, but data from the actual dockerfile is only available when a user provides it. This also means that any images analyzed by the tag watcher functionality will not have an actual dockerfile.
The FROM line
In the actual dockerfile, the FROM instruction is preserved and available as used to build the image, however in the history data, the FROM line will always be the very first FROM instruction used to build the image and all of its dependent based image. Thus, for most images, the value in the history will be omitted and Anchore will automatically infer a FROM scratch line, which is logically inserted for this gate if the dockerfile/history does not contain an explicit FROM entry.
For example, using the docker.io/jenkins/jenkins image:
IMAGE CREATED CREATED BY SIZE COMMENT
sha256:3b9c9666a66e53473c05a3c69eb2cb888a8268f76935eecc7530653cddc28981 11 hours ago /bin/sh -c #(nop) COPY file:3a15c25533fd87983edc33758f62af7b543ccc3ce9dd570e473eb0702f5f298e in /usr/local/bin/install-plugins.sh 8.79kB
<missing> 11 hours ago /bin/sh -c #(nop) COPY file:f97999fac8a63cf8b635a54ea84a2bc95ae3da4d81ab55267c92b28b502d8812 in /usr/local/bin/plugins.sh 3.96kB
<missing> 11 hours ago /bin/sh -c #(nop) ENTRYPOINT ["/sbin/tini" "--" "/usr/local/bin/jenkins.sh"] 0B
<missing> 11 hours ago /bin/sh -c #(nop) COPY file:dc942ca949bb159f81bbc954773b3491e433d2d3e3ef90bac80ecf48a313c9c9 in /bin/tini 529B
<missing> 11 hours ago /bin/sh -c #(nop) COPY file:a8f986413b77bf4d88562b9d3a0dce98ab6e75403192aa4d4153fb41f450843d in /usr/local/bin/jenkins.sh 1.45kB
<missing> 11 hours ago /bin/sh -c #(nop) COPY file:55594d9d2aed007553a6743a43039b1a48b30527f8fb991ad93e1fd5b1298f60 in /usr/local/bin/jenkins-support 6.12kB
<missing> 11 hours ago /bin/sh -c #(nop) USER jenkins 0B
<missing> 11 hours ago /bin/sh -c #(nop) ENV COPY_REFERENCE_FILE_LOG=/var/jenkins_home/copy_reference_file.log 0B
<missing> 11 hours ago /bin/sh -c #(nop) EXPOSE 50000 0B
<missing> 11 hours ago /bin/sh -c #(nop) EXPOSE 8080 0B
<missing> 11 hours ago |9 JENKINS_SHA=e026221efcec9528498019b6c1581cca70fe9c3f6b10303777d85c6699bca0e4 JENKINS_URL=https://repo.jenkins-ci.org/public/org/jenkins-ci/main/jenkins-war/2.161/jenkins-war-2.161.war TINI_VERSION=v0.16.1 agent_port=50000 gid=1000 group=jenkins http_port=8080 uid=1000 user=jenkins /bin/sh -c chown -R ${user} "$JENKINS_HOME" /usr/share/jenkins/ref 328B
<missing> 11 hours ago /bin/sh -c #(nop) ENV JENKINS_INCREMENTALS_REPO_MIRROR=https://repo.jenkins-ci.org/incrementals 0B
<missing> 11 hours ago /bin/sh -c #(nop) ENV JENKINS_UC_EXPERIMENTAL=https://updates.jenkins.io/experimental 0B
<missing> 11 hours ago /bin/sh -c #(nop) ENV JENKINS_UC=https://updates.jenkins.io 0B
<missing> 11 hours ago |9 JENKINS_SHA=e026221efcec9528498019b6c1581cca70fe9c3f6b10303777d85c6699bca0e4 JENKINS_URL=https://repo.jenkins-ci.org/public/org/jenkins-ci/main/jenkins-war/2.161/jenkins-war-2.161.war TINI_VERSION=v0.16.1 agent_port=50000 gid=1000 group=jenkins http_port=8080 uid=1000 user=jenkins /bin/sh -c curl -fsSL ${JENKINS_URL} -o /usr/share/jenkins/jenkins.war && echo "${JENKINS_SHA} /usr/share/jenkins/jenkins.war" | sha256sum -c - 76MB
<missing> 11 hours ago /bin/sh -c #(nop) ARG JENKINS_URL=https://repo.jenkins-ci.org/public/org/jenkins-ci/main/jenkins-war/2.161/jenkins-war-2.161.war 0B
<missing> 11 hours ago /bin/sh -c #(nop) ARG JENKINS_SHA=5bb075b81a3929ceada4e960049e37df5f15a1e3cfc9dc24d749858e70b48919 0B
<missing> 11 hours ago /bin/sh -c #(nop) ENV JENKINS_VERSION=2.161 0B
<missing> 11 hours ago /bin/sh -c #(nop) ARG JENKINS_VERSION 0B
<missing> 11 hours ago /bin/sh -c #(nop) COPY file:c84b91c835048a52bb864c1f4662607c56befe3c4b1520b0ea94633103a4554f in /usr/share/jenkins/ref/init.groovy.d/tcp-slave-agent-port.groovy 328B
<missing> 11 hours ago |7 TINI_VERSION=v0.16.1 agent_port=50000 gid=1000 group=jenkins http_port=8080 uid=1000 user=jenkins /bin/sh -c curl -fsSL https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini-static-$(dpkg --print-architecture) -o /sbin/tini && curl -fsSL https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini-static-$(dpkg --print-architecture).asc -o /sbin/tini.asc && gpg --no-tty --import ${JENKINS_HOME}/tini_pub.gpg && gpg --verify /sbin/tini.asc && rm -rf /sbin/tini.asc /root/.gnupg && chmod +x /sbin/tini 866kB
<missing> 11 hours ago /bin/sh -c #(nop) COPY file:653491cb486e752a4c2b4b407a46ec75646a54eabb597634b25c7c2b82a31424 in /var/jenkins_home/tini_pub.gpg 7.15kB
<missing> 11 hours ago /bin/sh -c #(nop) ARG TINI_VERSION=v0.16.1 0B
<missing> 11 hours ago |6 agent_port=50000 gid=1000 group=jenkins http_port=8080 uid=1000 user=jenkins /bin/sh -c mkdir -p /usr/share/jenkins/ref/init.groovy.d 0B
<missing> 11 hours ago /bin/sh -c #(nop) VOLUME [/var/jenkins_home] 0B
<missing> 11 hours ago |6 agent_port=50000 gid=1000 group=jenkins http_port=8080 uid=1000 user=jenkins /bin/sh -c mkdir -p $JENKINS_HOME && chown ${uid}:${gid} $JENKINS_HOME && groupadd -g ${gid} ${group} && useradd -d "$JENKINS_HOME" -u ${uid} -g ${gid} -m -s /bin/bash ${user} 328kB
<missing> 11 hours ago /bin/sh -c #(nop) ENV JENKINS_SLAVE_AGENT_PORT=50000 0B
<missing> 11 hours ago /bin/sh -c #(nop) ENV JENKINS_HOME=/var/jenkins_home 0B
<missing> 11 hours ago /bin/sh -c #(nop) ARG JENKINS_HOME=/var/jenkins_home 0B
<missing> 11 hours ago /bin/sh -c #(nop) ARG agent_port=50000 0B
<missing> 11 hours ago /bin/sh -c #(nop) ARG http_port=8080 0B
<missing> 11 hours ago /bin/sh -c #(nop) ARG gid=1000 0B
<missing> 11 hours ago /bin/sh -c #(nop) ARG uid=1000 0B
<missing> 11 hours ago /bin/sh -c #(nop) ARG group=jenkins 0B
<missing> 11 hours ago /bin/sh -c #(nop) ARG user=jenkins 0B
<missing> 11 hours ago /bin/sh -c apt-get update && apt-get install -y git curl && rm -rf /var/lib/apt/lists/* 0B
<missing> 3 weeks ago /bin/sh -c set -ex; if [ ! -d /usr/share/man/man1 ]; then mkdir -p /usr/share/man/man1; fi; apt-get update; apt-get install -y --no-install-recommends openjdk-8-jdk="$JAVA_DEBIAN_VERSION" ; rm -rf /var/lib/apt/lists/*; [ "$(readlink -f "$JAVA_HOME")" = "$(docker-java-home)" ]; update-alternatives --get-selections | awk -v home="$(readlink -f "$JAVA_HOME")" 'index($3, home) == 1 { $2 = "manual"; print | "update-alternatives --set-selections" }'; update-alternatives --query java | grep -q 'Status: manual' 348MB
<missing> 3 weeks ago /bin/sh -c #(nop) ENV JAVA_DEBIAN_VERSION=8u181-b13-2~deb9u1 0B
<missing> 3 weeks ago /bin/sh -c #(nop) ENV JAVA_VERSION=8u181 0B
<missing> 3 weeks ago /bin/sh -c #(nop) ENV JAVA_HOME=/docker-java-home 0B
<missing> 3 weeks ago /bin/sh -c ln -svT "/usr/lib/jvm/java-8-openjdk-$(dpkg --print-architecture)" /docker-java-home 33B
<missing> 3 weeks ago /bin/sh -c { echo '#!/bin/sh'; echo 'set -e'; echo; echo 'dirname "$(dirname "$(readlink -f "$(which javac || which java)")")"'; } > /usr/local/bin/docker-java-home && chmod +x /usr/local/bin/docker-java-home 87B
<missing> 3 weeks ago /bin/sh -c #(nop) ENV LANG=C.UTF-8 0B
<missing> 3 weeks ago /bin/sh -c apt-get update && apt-get install -y --no-install-recommends bzip2 unzip xz-utils && rm -rf /var/lib/apt/lists/* 2.21MB
<missing> 3 weeks ago /bin/sh -c apt-get update && apt-get install -y --no-install-recommends bzr git mercurial openssh-client subversion procps && rm -rf /var/lib/apt/lists/* 142MB
<missing> 3 weeks ago /bin/sh -c set -ex; if ! command -v gpg > /dev/null; then apt-get update; apt-get install -y --no-install-recommends gnupg dirmngr ; rm -rf /var/lib/apt/lists/*; fi 7.81MB
<missing> 3 weeks ago /bin/sh -c apt-get update && apt-get install -y --no-install-recommends ca-certificates curl netbase wget && rm -rf /var/lib/apt/lists/* 23.2MB
<missing> 3 weeks ago /bin/sh -c #(nop) CMD ["bash"] 0B
<missing> 3 weeks ago /bin/sh -c #(nop) ADD file:da71baf0d22cb2ede91c5e3ff959607e47459a9d7bda220a62a3da362b0e59ea in / 101MB
Where the actual dockerfile for that image is:
FROM openjdk:8-jdk-stretch
RUN apt-get update && apt-get install -y git curl && rm -rf /var/lib/apt/lists/*
ARG user=jenkins
ARG group=jenkins
ARG uid=1000
ARG gid=1000
ARG http_port=8080
ARG agent_port=50000
ARG JENKINS_HOME=/var/jenkins_home
ENV JENKINS_HOME $JENKINS_HOME
ENV JENKINS_SLAVE_AGENT_PORT ${agent_port}
# Jenkins is run with user `jenkins`, uid = 1000
# If you bind mount a volume from the host or a data container,
# ensure you use the same uid
RUN mkdir -p $JENKINS_HOME \
&& chown ${uid}:${gid} $JENKINS_HOME \
&& groupadd -g ${gid} ${group} \
&& useradd -d "$JENKINS_HOME" -u ${uid} -g ${gid} -m -s /bin/bash ${user}
# Jenkins home directory is a volume, so configuration and build history
# can be persisted and survive image upgrades
VOLUME $JENKINS_HOME
# `/usr/share/jenkins/ref/` contains all reference configuration we want
# to set on a fresh new installation. Use it to bundle additional plugins
# or config file with your custom jenkins Docker image.
RUN mkdir -p /usr/share/jenkins/ref/init.groovy.d
# Use tini as subreaper in Docker container to adopt zombie processes
ARG TINI_VERSION=v0.16.1
COPY tini_pub.gpg ${JENKINS_HOME}/tini_pub.gpg
RUN curl -fsSL https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini-static-$(dpkg --print-architecture) -o /sbin/tini \
&& curl -fsSL https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini-static-$(dpkg --print-architecture).asc -o /sbin/tini.asc \
&& gpg --no-tty --import ${JENKINS_HOME}/tini_pub.gpg \
&& gpg --verify /sbin/tini.asc \
&& rm -rf /sbin/tini.asc /root/.gnupg \
&& chmod +x /sbin/tini
COPY init.groovy /usr/share/jenkins/ref/init.groovy.d/tcp-slave-agent-port.groovy
# jenkins version being bundled in this docker image
ARG JENKINS_VERSION
ENV JENKINS_VERSION ${JENKINS_VERSION:-2.121.1}
# jenkins.war checksum, download will be validated using it
ARG JENKINS_SHA=5bb075b81a3929ceada4e960049e37df5f15a1e3cfc9dc24d749858e70b48919
# Can be used to customize where jenkins.war get downloaded from
ARG JENKINS_URL=https://repo.jenkins-ci.org/public/org/jenkins-ci/main/jenkins-war/${JENKINS_VERSION}/jenkins-war-${JENKINS_VERSION}.war
# could use ADD but this one does not check Last-Modified header neither does it allow to control checksum
# see https://github.com/docker/docker/issues/8331
RUN curl -fsSL ${JENKINS_URL} -o /usr/share/jenkins/jenkins.war \
&& echo "${JENKINS_SHA} /usr/share/jenkins/jenkins.war" | sha256sum -c -
ENV JENKINS_UC https://updates.jenkins.io
ENV JENKINS_UC_EXPERIMENTAL=https://updates.jenkins.io/experimental
ENV JENKINS_INCREMENTALS_REPO_MIRROR=https://repo.jenkins-ci.org/incrementals
RUN chown -R ${user} "$JENKINS_HOME" /usr/share/jenkins/ref
# for main web interface:
EXPOSE ${http_port}
# will be used by attached slave agents:
EXPOSE ${agent_port}
ENV COPY_REFERENCE_FILE_LOG $JENKINS_HOME/copy_reference_file.log
USER ${user}
COPY jenkins-support /usr/local/bin/jenkins-support
COPY jenkins.sh /usr/local/bin/jenkins.sh
COPY tini-shim.sh /bin/tini
ENTRYPOINT ["/sbin/tini", "--", "/usr/local/bin/jenkins.sh"]
# from a derived Dockerfile, can use `RUN plugins.sh active.txt` to setup /usr/share/jenkins/ref/plugins from a support bundle
COPY plugins.sh /usr/local/bin/plugins.sh
COPY install-plugins.sh /usr/local/bin/install-plugins.sh
Anchore will detect the history/dockerfile as this, if not explicitly provided (note order is reversed from docker history output, so it reads in same order as actual dockerfile):
[
{
"Size" : 45323792,
"Tags" : [],
"Comment" : "",
"Id" : "sha256:cd8eada9c7bb496eb685fc6d2198c33db7cb05daf0fde42e4cf5bf0127cbdf38",
"Created" : "2018-12-28T23:29:37.981962131Z",
"CreatedBy" : "/bin/sh -c #(nop) ADD file:da71baf0d22cb2ede91c5e3ff959607e47459a9d7bda220a62a3da362b0e59ea in / "
},
{
"Size" : 0,
"Tags" : [],
"Comment" : "",
"Id" : "<missing>",
"Created" : "2018-12-28T23:29:38.226681736Z",
"CreatedBy" : "/bin/sh -c #(nop) CMD [\"bash\"]"
},
{
"Size" : 10780911,
"Comment" : "",
"Tags" : [],
"CreatedBy" : "/bin/sh -c apt-get update && apt-get install -y --no-install-recommends \t\tca-certificates \t\tcurl \t\tnetbase \t\twget \t&& rm -rf /var/lib/apt/lists/*",
"Created" : "2018-12-29T00:04:28.920875483Z",
"Id" : "sha256:c2677faec825930a8844845f55454ee0495ceb5bea9fc904d5b3125de863dc1d"
},
{
"Comment" : "",
"Tags" : [],
"Size" : 4340024,
"CreatedBy" : "/bin/sh -c set -ex; \tif ! command -v gpg > /dev/null; then \t\tapt-get update; \t\tapt-get install -y --no-install-recommends \t\t\tgnupg \t\t\tdirmngr \t\t; \t\trm -rf /var/lib/apt/lists/*; \tfi",
"Created" : "2018-12-29T00:04:34.642152001Z",
"Id" : "sha256:fcce419a96b1219a265bf7a933d66b585a6f8d73448533f3833c73ad49fb5e88"
},
{
"Size" : 50062697,
"Tags" : [],
"Comment" : "",
"Id" : "sha256:045b51e26e750443c84216071a1367a7aae0b76245800629dc04934628b4b1ea",
"CreatedBy" : "/bin/sh -c apt-get update && apt-get install -y --no-install-recommends \t\tbzr \t\tgit \t\tmercurial \t\topenssh-client \t\tsubversion \t\t\t\tprocps \t&& rm -rf /var/lib/apt/lists/*",
"Created" : "2018-12-29T00:04:59.676112605Z"
},
... <truncated for brevity> ...
{
"Tags" : [],
"Comment" : "",
"Size" : 0,
"Id" : "<missing>",
"CreatedBy" : "/bin/sh -c #(nop) ENTRYPOINT [\"/sbin/tini\" \"--\" \"/usr/local/bin/jenkins.sh\"]",
"Created" : "2019-01-21T08:56:30.737221895Z"
},
{
"Size" : 1549,
"Tags" : [],
"Comment" : "",
"Id" : "sha256:283cd3aba8691a3b9d22d923de66243b105758e74de7d9469fe55a6a58aeee30",
"Created" : "2019-01-21T08:56:32.015667468Z",
"CreatedBy" : "/bin/sh -c #(nop) COPY file:f97999fac8a63cf8b635a54ea84a2bc95ae3da4d81ab55267c92b28b502d8812 in /usr/local/bin/plugins.sh "
},
{
"Comment" : "",
"Tags" : [],
"Size" : 3079,
"Created" : "2019-01-21T08:56:33.158854485Z",
"CreatedBy" : "/bin/sh -c #(nop) COPY file:3a15c25533fd87983edc33758f62af7b543ccc3ce9dd570e473eb0702f5f298e in /usr/local/bin/install-plugins.sh ",
"Id" : "sha256:b0ce8ab5a5a7da5d762f25af970f4423b98437a8318cb9852c3f21354cbf914f"
}
]
NOTE: Anchore processes the leading /bin/sh commands, so you do not have to include those in any trigger param config if using the docker history output.
The actual_dockerfile_only Parameter
The actual vs history impacts the semantics of the dockerfile gate’s triggers. To allow explicit control of the differences, most triggers in this gate includes a parameter: actual_dockerfile_only that if set to true or false will ensure the trigger check is only done on the source of data specified. If actual_dockerfile_only = true, then the trigger will evaluate only if an actual dockerfile is available for the image and will skip evaluation if not. If actual_dockerfile_only is false or omitted, then the trigger will run on the actual dockerfile if available, or the history data if the dockerfile was not provided.
Differences in data between Docker History and actual Dockerfile
With Actual Dockerfile:
- FROM line is preserved, so the parent tag of the image is easily available
- Instruction checks are all against instructions created during the build for that exact image, not any parent images
- When the actual_dockerfile_only parameter is set to true, all instructions from the parent image are ignored in policy processing. This may have some unexpected consequences depending on how your images are structured and layered (e.g. golden base images that establish common patterns of volumes, labels, healthchecks)
- COPY/ADD instructions will maintain the actual values used
- Multistage-builds in that specific dockerfile will be visible with multiple FROM lines in the output
With Docker History data, when no dockerfile is provided:
- FROM line is not accurate, and will nearly always default to ‘FROM scratch’
- Instructions are processed from all layers in the image
- COPY and ADD instructions are transformed into SHAs rather than the actual file path/name used at build-time
- Multi-stage builds are not tracked with multiple FROM lines, only the copy operations between the phases
Trigger: instruction
This trigger evaluates instructions found in the “dockerfile”.
Parameters
actual_dockerfile_only (optional): See above
instruction: The dockerfile instruction to check against. One of:
- ADD
- ARG
- COPY
- CMD
- ENTRYPOINT
- ENV
- EXPOSE
- FROM
- HEALTHCHECK
- LABEL
- MAINTAINER
- ONBUILD
- USER
- RUN
- SHELL
- STOPSIGNAL
- VOLUME
- WORKDIR
check: The comparison/evaluation to perform. One of: =, != , exists, not_exists, like, not_like, in, not_in.
value (optional): A string value to compare against, if applicable.
Examples
- Ensure an image has a HEALTHCHECK defined in the image (warn if not found).
{
"gate": "dockerfile",
"trigger": "instruction",
"action": "warn",
"parameters": [
{
"name": "instruction",
"value": "HEALTHCHECK"
},
{
"name": "check",
"value": "not_exists"
}
]
}
- Check for AWS environment variables set.
{
"gate": "dockerfile",
"trigger": "instruction",
"action": "stop",
"parameters": [
{
"name": "instruction",
"value": "ENV"
},
{
"name": "check",
"value": "like"
},
{
"name": "value",
"value": "AWS_.*KEY"
}
]
}
Trigger: effective_user
This trigger processes all USER
directives in the dockerfile or history to determine which user will be used to run the container by default (assuming no user is set explicitly at runtime). The detected value is then subject to a allowlist or denylist filter depending on the configured parameters. Typically, this is used for denylisting the root user.
Parameters
actual_dockerfile_only (optional): See above
users: A string with a comma delimited list of username to check for.
type: The type of check to perform. One of: ‘denylist’ or ‘allowlist’. This determines how the value of the ‘users’ parameter is interpreted.
Examples
- Denylist root user.
{
"gate": "dockerfile",
"trigger": "effective_user",
"action": "stop",
"parameters": [
{
"name": "users",
"value": "root"
},
{
"name": "type",
"value": "denylist"
}
]
}
- Denylist root user but only if set in actual dockerfile, not inherited from parent image.
{
"gate": "dockerfile",
"trigger": "effective_user",
"action": "stop",
"parameters": [
{
"name": "users",
"value": "root"
},
{
"name": "type",
"value": "denylist"
},
{
"name": "actual_dockerfile_only",
"value": "true"
}
]
}
- Warn if the user is not either “nginx” or “jenkins”.
{
"gate": "dockerfile",
"trigger": "effective_user",
"action": "warn",
"parameters": [
{
"name": "users",
"value": "nginx,jenkins"
},
{
"name": "type",
"value": "allowlist"
}
]
}
Trigger: exposed_ports
This trigger processes the set of EXPOSE
directives in the dockerfile/history to determine the set of ports that are defined to be exposed (since it can span multiple directives). It performs checks on that set to denylist/allowlist them based on parameter settings.
Parameters
actual_dockerfile_only (optional): See above
ports: String of comma delimited port numbers to be checked.
type: The type of check to perform. One of: ‘denylist’ or ‘allowlist’. This determines how the value of the ‘users’ parameter is interpreted.
Examples
- Allow only ports 80 and 443. Trigger will fire on any port defined to be exposed that is not 80 or 443.
{
"gate": "dockerfile",
"trigger": "exposed_ports",
"action": "warn",
"parameters": [
{
"name": "ports",
"value": "80,443"
},
{
"name": "type",
"value": "allowlist"
}
]
}
- Denylist ports 21 (ftp), 22 (ssh), and 53 (dns) . Trigger will fire a match on ports 21, 22, 53 if found in EXPOSE directives.
{
"gate": "dockerfile",
"trigger": "exposed_ports",
"action": "warn",
"parameters": [
{
"name": "ports",
"value": "21,22,53"
},
{
"name": "type",
"value": "denylist"
}
]
}
Trigger: no_dockerfile_provided
This trigger allows checks on the way the image was added, firing if the dockerfile was not explicitly provided at analysis time. This is useful in identifying and qualifying other trigger matches.
Parameters
None
Examples
- Raise a warning if no dockerfile was provided at analysis time .
{
"gate": "dockerfile",
"trigger": "no_dockerfile_provided",
"action": "warn",
"parameters": []
}
7.2 - Evaluating Images Against Policies
Introduction
The evaluate
command can be used to evaluate a given image for policy compliance.
The image to be evaluated can be in the following format:
- Image Digest
- Image ID
- registry/repo:tag
Using the Evaluate command
# anchorectl image check docker.io/debian:latest
✔ Evaluated against policy [failed] docker.io/debian:latest
Tag: docker.io/debian:latest
Digest: sha256:0fcb5a38077422c4e70c5c43be21831193ff4559d143e27d8d5721e7a814bdcc
Policy ID: 2c53a13c-1765-11e8-82ef-23527761d060
Last Evaluation: 2023-10-25T20:34:43Z
Evaluation: fail
By default, only the summary of the evaluation is shown. Passing the --detail
parameter will show the policy checks that raised warnings or errors.
# anchorectl image check docker.io/debian:latest --detail
✔ Evaluated against policy [failed] docker.io/debian:latest
Tag: docker.io/debian:latest
Digest: sha256:0fcb5a38077422c4e70c5c43be21831193ff4559d143e27d8d5721e7a814bdcc
Policy ID: 2c53a13c-1765-11e8-82ef-23527761d060
Last Evaluation: 2023-10-25T20:35:05Z
Evaluation: fail
Final Action: stop
Reason: policy_evaluation
Policy Evaluation Details:
┌─────────────────┬─────────────┬────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┬────────┐
│ GATE │ TRIGGER │ DESCRIPTION │ STATUS │
├─────────────────┼─────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┼────────┤
│ dockerfile │ instruction │ Dockerfile directive 'HEALTHCHECK' not found, matching condition 'not_exists' check │ warn │
│ vulnerabilities │ package │ MEDIUM Vulnerability found in os package type (dpkg) - libgnutls30 (CVE-2011-3389 - https://security-tracker.debian.org/tracker/CVE-2011-3389) │ warn │
│ vulnerabilities │ package │ CRITICAL Vulnerability found in os package type (dpkg) - zlib1g (CVE-2022-37434 - https://security-tracker.debian.org/tracker/CVE-2022-37434) │ stop │
└─────────────────┴─────────────┴────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┴────────┘
In this example we specified library/repo:tag which could be ambiguous. At the time of writing the image Digest for library/debian:latest
was sha256:0fc.....
however previously different images may have been tagged as library/debian:latest
. The --history
parameter can be passed to show historic evaluations based on previous images or previous policies.
Anchore supports allowlisting and denylisting images by their name, ID or digest. A denylist or allowlist takes precedence over any policy checks. For example if an image is explicitly listed as denylisted then even if all the individual policy checks pass the image will still fail evaluation.
# anchorectl image check docker.io/debian:latest --detail
✔ Evaluated against policy [failed] docker.io/debian:latest
Tag: docker.io/debian:latest
Digest: sha256:0fcb5a38077422c4e70c5c43be21831193ff4559d143e27d8d5721e7a814bdcc
Policy ID: 2c53a13c-1765-11e8-82ef-23527761d060
Last Evaluation: 2023-10-25T20:39:36Z
Evaluation: fail
Final Action: stop
Reason: denylisted
Policy Evaluation Details:
┌─────────────────┬─────────────┬────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┬────────┐
│ GATE │ TRIGGER │ DESCRIPTION │ STATUS │
├─────────────────┼─────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┼────────┤
│ dockerfile │ instruction │ Dockerfile directive 'HEALTHCHECK' not found, matching condition 'not_exists' check │ warn │
│ vulnerabilities │ package │ MEDIUM Vulnerability found in os package type (dpkg) - libgnutls30 (CVE-2011-3389 - https://security-tracker.debian.org/tracker/CVE-2011-3389) │ warn │
└─────────────────┴─────────────┴────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┴────────┘
In this example even though the image only had one policy check that raised a warning the image fails policy evaluation since it is present on a denylist.
Evaluating status based on Digest or ID
Performing an evaluation on an image specified by name is not recommended since an image name is ambiguous. For example the tag docker.io/library/centos:latest
refers to whatever image has the tag library/centos:latest
at the time of evaluation. At any point in time another image may be tagged as library/centos:latest
.
It is recommended that images are referenced by their Digest. For example at the time of writing the digest of the ‘current’ library/centos:latest image is sha256:191c883e479a7da2362b2d54c0840b2e8981e5ab62e11ab925abf8808d3d5d44
If the image to be evaluated is specified by Image ID or Image Digest then the --tag
parameter must be added. Policies are mapped to images based on registry/repo:tag so since an Image ID may may to multiple different names we must specify the name user in the evaluation.
For example - referencing by Image Digest:
# anchorectl image check docker.io/debian@sha256:0fcb5a38077422c4e70c5c43be21831193ff4559d143e27d8d5721e7a814bdcc --detail --tag docker.io/debian:latest
✔ Evaluated against policy [failed] docker.io/debian@sha256:0fcb5a38077422c4e70c5c43be21831193ff4559d143e27d8d5721e7a814bdcc
Tag: docker.io/debian:latest
Digest: sha256:0fcb5a38077422c4e70c5c43be21831193ff4559d143e27d8d5721e7a814bdcc
Policy ID: 2c53a13c-1765-11e8-82ef-23527761d060
Last Evaluation: 2023-10-25T20:44:24Z
Evaluation: fail
Final Action: stop
Reason: denylisted
Policy Evaluation Details:
┌─────────────────┬─────────────┬────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┬────────┐
│ GATE │ TRIGGER │ DESCRIPTION │ STATUS │
├─────────────────┼─────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┼────────┤
│ dockerfile │ instruction │ Dockerfile directive 'HEALTHCHECK' not found, matching condition 'not_exists' check │ warn │
│ vulnerabilities │ package │ MEDIUM Vulnerability found in os package type (dpkg) - libgnutls30 (CVE-2011-3389 - https://security-tracker.debian.org/tracker/CVE-2011-3389) │ warn │
│ vulnerabilities │ package │ CRITICAL Vulnerability found in os package type (dpkg) - zlib1g (CVE-2022-37434 - https://security-tracker.debian.org/tracker/CVE-2022-37434) │ stop │
└─────────────────┴─────────────┴────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┴────────┘
For example - referencing by image ID:
# anchorectl image check dd8bae8d259fed93eb54b3bca0adeb647fc07f6ef16745c8ed4144ada4d51a95 --detail --tag docker.io/debian:latest
✔ Evaluated against policy [failed] dd8bae8d259fed93eb54b3bca0adeb647fc07f6ef16745c8ed4144ada4d51a95
Tag: docker.io/debian:latest
Digest: sha256:0fcb5a38077422c4e70c5c43be21831193ff4559d143e27d8d5721e7a814bdcc
Policy ID: 2c53a13c-1765-11e8-82ef-23527761d060
Last Evaluation: 2023-10-25T20:45:20Z
Evaluation: fail
Final Action: stop
Reason: denylisted
Policy Evaluation Details:
┌─────────────────┬─────────────┬────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┬────────┐
│ GATE │ TRIGGER │ DESCRIPTION │ STATUS │
├─────────────────┼─────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┼────────┤
│ dockerfile │ instruction │ Dockerfile directive 'HEALTHCHECK' not found, matching condition 'not_exists' check │ warn │
│ vulnerabilities │ package │ MEDIUM Vulnerability found in os package type (dpkg) - libgnutls30 (CVE-2011-3389 - https://security-tracker.debian.org/tracker/CVE-2011-3389) │ warn │
│ vulnerabilities │ package │ CRITICAL Vulnerability found in os package type (dpkg) - zlib1g (CVE-2022-37434 - https://security-tracker.debian.org/tracker/CVE-2022-37434) │ stop │
└─────────────────┴─────────────┴────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┴────────┘
7.3 - SBOM Drift
Software bill of materials (SBOM) drift is understanding how SBOMs change over time, and is a key part of managing your SBOMs. The nature of changes themselves may give early warning into unexpected behavior or intrusion into the build system that a review without context from previous builds would not easily be able to identify.
To do this, you set triggers for policy violations on changes in the SBOM between images with the same tag so that it can detect drift over time between builds of your images.
Gate: tag_drift
The triggers are:
- packages_added
- packages_removed
- packages_modified
The “tag_drift” gate compares the SBOMs from the image being evaluated as input, and the SBOM of the image that precedes the input image with the requested tag provided for policy evaluation. The triggers in this gate evaluate the result to determine if packages were added, removed, or modified.
Trigger: packages_added
This trigger warns if a package was added to the SBOM.
Parameters
Optional parameter: “package_type”
Example
Raise a warning if packages were added.
{
"action": "WARN",
"gate": "tag_drift",
"trigger": "packages_added",
"params": [],
"id": "1ba3461f-b9db-4a6c-ac88-329d38e08df5"
}
Trigger: packages_removed
This trigger warns if a package was deleted from the SBOM.
Parameters
Optional parameter: “package_type”
Example
Raise a warning if packages were deleted.
{
"action": "WARN",
"gate": "tag_drift",
"trigger": "packages_removed",
"params": [],
"id": "de05d77b-1f93-4df4-a65d-57d9042b1f3a"
}
Trigger: packages_modified
This trigger warns if a package was changed in the SBOM.
Parameters
Optional parameter: “package_type”
Example
Raise a warning if packages were changed.
{
"action": "WARN",
"gate": "tag_drift",
"trigger": "packages_modified",
"params": [],
"id": "1168b0ac-df6c-4715-8077-2cb3e016cf63"
}