// Module included in the following assemblies: // // * security/container_security/security-container-content.adoc :_mod-docs-content-type: REFERENCE [id="security-container-content-external-scanning_{context}"] = Integrating external scanning {product-title} makes use of link:https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/[object annotations] to extend functionality. External tools, such as vulnerability scanners, can annotate image objects with metadata to summarize results and control pod execution. This section describes the recognized format of this annotation so it can be reliably used in consoles to display useful data to users. [id="security-image-metadata_{context}"] == Image metadata There are different types of image quality data, including package vulnerabilities and open source software (OSS) license compliance. Additionally, there may be more than one provider of this metadata. To that end, the following annotation format has been reserved: ---- quality.images.openshift.io/.: {} ---- .Annotation key format [option="header"] |=== |Component |Description |Acceptable values |`qualityType` |Metadata type |`vulnerability` + `license` + `operations` + `policy` |`providerId` |Provider ID string |`openscap` + `redhatcatalog` + `redhatinsights` + `blackduck` + `jfrog` |=== [id="security-example-annotation-keys_{context}"] === Example annotation keys ---- quality.images.openshift.io/vulnerability.blackduck: {} quality.images.openshift.io/vulnerability.jfrog: {} quality.images.openshift.io/license.blackduck: {} quality.images.openshift.io/vulnerability.openscap: {} ---- The value of the image quality annotation is structured data that must adhere to the following format: .Annotation value format [option="header"] |=== |Field |Required? |Description |Type |`name` |Yes |Provider display name |String |`timestamp` |Yes |Scan timestamp |String |`description` |No |Short description |String |`reference` |Yes |URL of information source or more details. Required so user may validate the data. |String |`scannerVersion` |No |Scanner version |String |`compliant` |No |Compliance pass or fail |Boolean |`summary` |No |Summary of issues found |List (see table below) |=== The `summary` field must adhere to the following format: .Summary field value format [option="header"] |=== |Field |Description |Type |`label` |Display label for component (for example, "critical," "important," "moderate," "low," or "health") |String |`data` |Data for this component (for example, count of vulnerabilities found or score) |String |`severityIndex` |Component index allowing for ordering and assigning graphical representation. The value is range `0..3` where `0` = low. |Integer |`reference` |URL of information source or more details. Optional. |String |=== [id="security-example-annotation-values_{context}"] === Example annotation values This example shows an OpenSCAP annotation for an image with vulnerability summary data and a compliance boolean: .OpenSCAP annotation [source,json] ---- { "name": "OpenSCAP", "description": "OpenSCAP vulnerability score", "timestamp": "2016-09-08T05:04:46Z", "reference": "https://www.open-scap.org/930492", "compliant": true, "scannerVersion": "1.2", "summary": [ { "label": "critical", "data": "4", "severityIndex": 3, "reference": null }, { "label": "important", "data": "12", "severityIndex": 2, "reference": null }, { "label": "moderate", "data": "8", "severityIndex": 1, "reference": null }, { "label": "low", "data": "26", "severityIndex": 0, "reference": null } ] } ---- This example shows the link:https://catalog.redhat.com/software/containers/explore[Container images section of the Red Hat Ecosystem Catalog] annotation for an image with health index data with an external URL for additional details: .Red Hat Ecosystem Catalog annotation [source,json] ---- { "name": "Red Hat Ecosystem Catalog", "description": "Container health index", "timestamp": "2016-09-08T05:04:46Z", "reference": "https://access.redhat.com/errata/RHBA-2016:1566", "compliant": null, "scannerVersion": "1.2", "summary": [ { "label": "Health index", "data": "B", "severityIndex": 1, "reference": null } ] } ---- [id="security-annotating-image-objects_{context}"] == Annotating image objects While image stream objects are what an end user of {product-title} operates against, image objects are annotated with security metadata. Image objects are cluster-scoped, pointing to a single image that may be referenced by many image streams and tags. [id="security-example-annotate-CLI_{context}"] === Example annotate CLI command Replace `` with an image digest, for example `sha256:401e359e0f45bfdcf004e258b72e253fd07fba8cc5c6f2ed4f4608fb119ecc2`: [source,terminal] ---- $ oc annotate image \ quality.images.openshift.io/vulnerability.redhatcatalog='{ \ "name": "Red Hat Ecosystem Catalog", \ "description": "Container health index", \ "timestamp": "2020-06-01T05:04:46Z", \ "compliant": null, \ "scannerVersion": "1.2", \ "reference": "https://access.redhat.com/errata/RHBA-2020:2347", \ "summary": "[ \ { "label": "Health index", "data": "B", "severityIndex": 1, "reference": null } ]" }' ---- [id="controlling-pod-execution_{context}"] == Controlling pod execution Use the `images.openshift.io/deny-execution` image policy to programmatically control if an image can be run. [id="security-controlling-pod-execution-example-annotation_{context}"] === Example annotation [source,yaml] ---- annotations: images.openshift.io/deny-execution: true ---- [id="security-integration-reference_{context}"] == Integration reference In most cases, external tools such as vulnerability scanners develop a script or plugin that watches for image updates, performs scanning, and annotates the associated image object with the results. Typically this automation calls the {product-title} {product-version} REST APIs to write the annotation. See {product-title} REST APIs for general information on the REST APIs. [id="security-integration-reference-example-api-call_{context}"] === Example REST API call The following example call using `curl` overrides the value of the annotation. Be sure to replace the values for ``, ``, ``, and ``. .Patch API call [source,terminal] ---- $ curl -X PATCH \ -H "Authorization: Bearer " \ -H "Content-Type: application/merge-patch+json" \ https://:6443/apis/image.openshift.io/v1/images/ \ --data '{ }' ---- The following is an example of `PATCH` payload data: .Patch call data [source,terminal] ---- { "metadata": { "annotations": { "quality.images.openshift.io/vulnerability.redhatcatalog": "{ 'name': 'Red Hat Ecosystem Catalog', 'description': 'Container health index', 'timestamp': '2020-06-01T05:04:46Z', 'compliant': null, 'reference': 'https://access.redhat.com/errata/RHBA-2020:2347', 'summary': [{'label': 'Health index', 'data': '4', 'severityIndex': 1, 'reference': null}] }" } } } ---- ifdef::openshift-origin[] [NOTE] ==== Due to the complexity of this API call and challenges with escaping characters, an API developer tool such as link:https://www.getpostman.com/[Postman] may assist in creating API calls. ==== endif::[]