openapi: 3.0.0 info: title: Harbor Scanner Adapter API description: | ## Overview This API must be implemented in order to register a new artifact scanner in [Harbor](https://goharbor.io) registry. The [/scan](#operation/AcceptScanRequest) and [/scan/{scan_request_id}/report](#operation/GetScanReport) operations are responsible for the actual scanning and return a scan report that is visible in the Harbor web console. The [/scan](#operation/AcceptScanRequest) operation is asynchronous. It should enqueue the job for processing a scan request and return the identifier. This allows Harbor to poll a corresponding scan report with the [/scan/{scan_request_id}/report](#operation/GetScanReport) operation. Harbor will call the [/scan/{scan_request_id}/report](#operation/GetScanReport) operation periodically until it returns 200 or 500 status codes. The [/metadata](#operation/GetMetadata) operation allows a Harbor admin to configure and register a scanner and discover its capabilities. ## Capabilities | Capability Type | Supported consumed MIME types | Supported produced MIME types | | --------------- | ----------------------------- | ----------------------------- | | vulnerability | `application/vnd.oci.image.manifest.v1+json`
`application/vnd.docker.distribution.manifest.v2+json` | `application/vnd.scanner.adapter.vuln.report.harbor+json; version=1.0`
`application/vnd.security.vulnerability.report; version=1.1`
`application/vnd.scanner.adapter.vuln.report.raw`| | sbom | `application/vnd.oci.image.manifest.v1+json`
`application/vnd.docker.distribution.manifest.v2+json` | `application/vnd.security.sbom.report+json; version=1.0` | contact: email: cncf-harbor-maintainers@lists.cncf.io license: name: Apache 2.0 url: http://www.apache.org/licenses/LICENSE-2.0.html version: "1.2" servers: - url: /api/v1 security: - BasicAuth: [] - BearerAuth: [] paths: /metadata: get: tags: - Scanner summary: Get scanner metadata description: | Used to fetch scanner's metadata and capabilities. The operation is invoked to build an index of scanners capable of analysing a given type of artifacts and making sure that scan reports can be parsed and rendered. operationId: GetMetadata responses: 200: description: Scanner's metadata and capabilities content: "application/vnd.scanner.adapter.metadata+json; version=1.1": schema: $ref: '#/components/schemas/ScannerAdapterMetadata' "application/vnd.scanner.adapter.metadata+json; version=1.0": schema: $ref: '#/components/schemas/ScannerAdapterMetadata' 500: description: Internal server error content: "application/vnd.scanner.adapter.error+json; version=1.0": schema: $ref: '#/components/schemas/ErrorResponse' /scan: post: tags: - Scanner summary: Accept artifact scanning request description: | A non-blocking operation which enqueues a scan job and returns immediately. It returns a unique identifier which can be used to poll for generated scan reports by Harbor. operationId: AcceptScanRequest requestBody: description: | Contains data required to pull the given artifact and save it for scanning in the file system or any other location accessible to the scanner. content: "application/vnd.scanner.adapter.scan.request+json; version=1.1": schema: $ref: '#/components/schemas/ScanRequest' "application/vnd.scanner.adapter.scan.request+json; version=1.0": schema: $ref: '#/components/schemas/ScanRequest' responses: 202: description: Scan request accepted content: "application/vnd.scanner.adapter.scan.response+json; version=1.0": schema: $ref: "#/components/schemas/ScanResponse" 400: description: Received invalid JSON or the wrong type of JSON values content: "application/vnd.scanner.adapter.error+json; version=1.0": schema: $ref: "#/components/schemas/ErrorResponse" 422: description: Received invalid field content: "application/vnd.scanner.adapter.error+json; version=1.0": schema: $ref: "#/components/schemas/ErrorResponse" 500: description: Internal server error content: "application/vnd.scanner.adapter.error+json; version=1.0": schema: $ref: '#/components/schemas/ErrorResponse' 501: description: The scanner has no capability to handle the scan request content: "application/vnd.scanner.adapter.error+json; version=1.0": schema: $ref: '#/components/schemas/ErrorResponse' /scan/{scan_request_id}/report: get: tags: - Scanner summary: Get scan report description: | Get a scan report for the given scan request identifier. Clients will periodically poll this operation and check `$response.status` until its value equals `200` or `500`. operationId: GetScanReport parameters: - name: scan_request_id in: path description: The identifier of the corresponding scan request required: true style: simple explode: false schema: $ref: '#/components/schemas/ScanRequestId' - name: Accept in: header schema: type: string example: "application/vnd.security.vulnerability.report; version=1.1" - name: sbom_media_type in: query description: media_type specifies the format of SBOM to be retrieved from the scanner adapter, it should either SPDX SBOM or CycloneDX required: false schema: type: string enum: - application/spdx+json - application/vnd.cyclonedx+json responses: 200: description: Scan report content: "application/vnd.scanner.adapter.vuln.report.harbor+json; version=1.0": schema: $ref: '#/components/schemas/HarborVulnerabilityReport' "application/vnd.security.vulnerability.report; version=1.1": schema: $ref: '#/components/schemas/HarborVulnerabilityReport' "application/vnd.scanner.adapter.vuln.report.raw": schema: type: string example: | { "vendor_specific": "vulnerabilities_report" } "application/vnd.security.sbom.report+json; version=1.0": schema: $ref: '#/components/schemas/HarborSbomReport' 302: description: Status indicating the scan report is being generated and the request should be retried. headers: Refresh-After: description: Indicates the interval after which the request should be retried. schema: type: integer 400: description: Bad request from the client to query report of a "/scan" request. For example, querying SBOM generation report, but not passing query parameter (?sbom_media_type=xxx), or the key/value of the query parameter is not valid, it should return 400. content: "application/vnd.scanner.adapter.error+json; version=1.0": schema: $ref: '#/components/schemas/ErrorResponse' 404: description: Cannot find the corresponding scan request identifier 500: description: Internal server error content: "application/vnd.scanner.adapter.error+json; version=1.0": schema: $ref: '#/components/schemas/ErrorResponse' 501: description: The scanner has no capability to handle the mime type content: "application/vnd.scanner.adapter.error+json; version=1.0": schema: $ref: '#/components/schemas/ErrorResponse' components: schemas: Scanner: type: object properties: name: type: string description: The name of the scanner. example: Trivy vendor: type: string description: The name of the scanner's provider. example: Aqua Security version: type: string description: The version of the scanner. example: 0.4.0 description: | Basic scanner properties such as name, vendor, and version. ScannerAdapterMetadata: required: - scanner - capabilities type: object properties: scanner: $ref: '#/components/schemas/Scanner' capabilities: type: array items: $ref: '#/components/schemas/ScannerCapability' example: | [ { "type": "vulnerability", "consumes_mime_types": [ "application/vnd.oci.image.manifest.v1+json", "application/vnd.docker.distribution.manifest.v2+json" ], "produces_mime_types": [ "application/vnd.scanner.adapter.vuln.report.harbor+json; version=1.0" ] }, { "type": "sbom", "consumes_mime_types": [ "application/vnd.oci.image.manifest.v1+json", "application/vnd.docker.distribution.manifest.v2+json" ], "produces_mime_types": [ "application/vnd.security.sbom.report+json; version=1.0" ], "additional_attributes": { "sbom_media_types": [ "application/spdx+json", "application/vnd.cyclonedx+json" ] } } ] properties: $ref: "#/components/schemas/ScannerProperties" description: | Represents metadata of a Scanner Adapter which allows Harbor to lookup a scanner capabilities of scanning a given Artifact stored in its registry and making sure that it can interpret a returned result. ScannerProperties: type: object additionalProperties: type: string example: "harbor.scanner-adapter/scanner-type": "os-package-vulnerability" "harbor.scanner-adapter/vulnerability-database-updated-at": "2019-08-13T08:16:33.345Z" description: | A set of custom properties that can further describe capabilities of a given scanner. ScannerCapability: description: | Capability consists of the set of recognized artifact MIME types and the set of scanner report MIME types. For example, a scanner capable of analyzing Docker images and producing a vulnerabilities report recognizable by Harbor web console might be represented with the following capability: - consumes MIME types: - `application/vnd.oci.image.manifest.v1+json` - `application/vnd.docker.distribution.manifest.v2+json` - produces MIME types: - `application/vnd.scanner.adapter.vuln.report.harbor+json; version=1.0` For example, a scanner capable of analyzing artifacts and producing a sbom report recognizable by Harbor might be represented with the following capability: - type: sbom - consumes MIME types: - `application/vnd.oci.image.manifest.v1+json` - `application/vnd.docker.distribution.manifest.v2+json` - produces MIME types: - `application/vnd.security.sbom.report+json; version=1.0` required: - consumes_mime_types - produces_mime_types type: object properties: type: type: string enum: - vulnerability - sbom description: | The type of the capability, for example, 'vulnerability' represents analyzing the artifact then producing the vulnerabilities report, 'sbom' represents generating the corresponding sbom for the artifact which be scanned. In order to the backward and forward compatible, the field is optional, we think it's a original 'vulnerability' scan if no such field. consumes_mime_types: type: array items: type: string description: | The set of MIME types of the artifacts supported by the scanner to produce the reports specified in the "produces_mime_types". A given mime type should only be present in one capability item. example: - "application/vnd.oci.image.manifest.v1+json" - "application/vnd.docker.distribution.manifest.v2+json" produces_mime_types: type: array items: type: string description: | The set of MIME types of reports generated by the scanner for the consumes_mime_types of the same capability record. example: - "application/vnd.scanner.adapter.vuln.report.harbor+json; version=1.0" additional_attributes: type: object descriptions: The additional attributes for scanner capabilities. If the type is sbom, then it returns supported media types of the SBOM format. example: | { "sbom_media_types": [ "application/spdx+json", "application/vnd.cyclonedx+json" ] } ScanRequest: required: - registry - artifact type: object properties: registry: $ref: '#/components/schemas/Registry' artifact: $ref: '#/components/schemas/Artifact' enabled_capabilities: type: array description: Enable which capabilities supported by scanner, for backward compatibility, without this field scanner can be considered to enable all capabilities by default. items: type: object required: - type properties: type: type: string enum: - vulnerability - sbom description: The type of the scan capability. example: sbom produces_mime_types: type: array items: type: string description: | The set of MIME types of reports generated by the scanner for the consumes_mime_types of the same capability record, it is a subset or fullset of the produces_mime_types of the capability returned by the metadata API, used for client to fine grained control of the expected report type. It's a optional field, only applied when client needs to customize it, otherwise the scanner can think it's a fullset as before behavior if without this field. example: - "application/vnd.security.sbom.report+json; version=1.0" parameters: oneOf: - $ref: '#/components/schemas/SbomParameters' nullable: true description: The additional parameters for the scan request, for the SBOM type, harbor will carry with `sbom_media_types` to specify the expected formats for SBOM content. example: | { "sbom_media_types": [ "application/spdx+json", "application/vnd.cyclonedx+json" ] } ScanResponse: required: - id properties: id: $ref: '#/components/schemas/ScanRequestId' ScanRequestId: description: | A unique identifier returned by the [/scan](#/operation/AcceptScanRequest] operations. The format of the identifier is not imposed but it should be unique enough to prevent collisons when polling for scan reports. type: string example: "3fa85f64-5717-4562-b3fc-2c963f66afa6" SbomParameters: type: object properties: sbom_media_types: type: array items: type: string enum: - application/spdx+json - application/vnd.cyclonedx+json Registry: type: object properties: url: type: string description: A base URL or the Docker Registry v2 API. format: url example: https://core.harbor.domain authorization: type: string description: | An optional value of the HTTP Authorization header sent with each request to the Docker Registry v2 API. It's used to exchange Base64 encoded robot account credentials to a short lived JWT access token which allows the underlying scanner to pull the artifact from the Docker Registry. example: "Basic BASE64_ENCODED_CREDENTIALS" Artifact: type: object properties: repository: type: string description: The name of the Docker Registry repository containing the artifact. example: library/mongo digest: type: string description: The artifact's digest, consisting of an algorithm and hex portion. example: "sha256:6c3c624b58dbbcd3c0dd82b4c53f04194d1247c6eebdaab7c610cf7d66709b3b" tag: type: string description: The artifact's tag example: "3.14-xenial" mime_type: type: string description: The MIME type of the artifact. example: "application/vnd.docker.distribution.manifest.v2+json" HarborVulnerabilityReport: type: object properties: generated_at: type: string format: 'date-time' artifact: $ref: '#/components/schemas/Artifact' scanner: $ref: '#/components/schemas/Scanner' severity: $ref: "#/components/schemas/Severity" vulnerabilities: type: array items: $ref: '#/components/schemas/VulnerabilityItem' VulnerabilityItem: type: object properties: id: type: string description: The unique identifier of the vulnerability. example: CVE-2017-8283 package: type: string description: | An operating system package containing the vulnerability. example: dpkg version: type: string description: | The version of the package containing the vulnerability. example: 1.17.27 fix_version: type: string description: | The version of the package containing the fix if available. example: 1.18.0 severity: $ref: "#/components/schemas/Severity" description: type: string description: | The detailed description of the vulnerability. example: | dpkg-source in dpkg 1.3.0 through 1.18.23 is able to use a non-GNU patch program and does not offer a protection mechanism for blank-indented diff hunks, which allows remote attackers to conduct directory traversal attacks via a crafted Debian source package, as demonstrated by using of dpkg-source on NetBSD. links: type: array items: type: string format: uri description: | The list of links to the upstream databases with the full description of the vulnerability. format: uri example: - https://security-tracker.debian.org/tracker/CVE-2017-8283 preferred_cvss: $ref: "#/components/schemas/CVSSDetails" cwe_ids: type: array items: type: string example: - CWE-476 description: | The Common Weakness Enumeration Identifiers associated with this vulnerability. vendor_attributes: type: object additionalProperties: true Severity: type: string description: | A standard scale for measuring the severity of a vulnerability. * `Unknown` - either a security problem that has not been assigned to a priority yet or a priority that the scanner did not recognize. * `Negligible` - technically a security problem, but is only theoretical in nature, requires a very special situation, has almost no install base, or does no real damage. * `Low` - a security problem, but is hard to exploit due to environment, requires a user-assisted attack, a small install base, or does very little damage. * `Medium` - a real security problem, and is exploitable for many people. Includes network daemon denial of service attacks, cross-site scripting, and gaining user privileges. * `High` - a real problem, exploitable for many people in a default installation. Includes serious remote denial of service, local root privilege escalations, or data loss. * `Critical` - a world-burning problem, exploitable for nearly all people in a default installation. Includes remote root privilege escalations, or massive data loss. example: Low enum: - Unknown - Negligible - Low - Medium - High - Critical HarborSbomReport: type: object properties: generated_at: type: string format: 'date-time' description: 'The time of the report generated.' artifact: $ref: '#/components/schemas/Artifact' scanner: $ref: '#/components/schemas/Scanner' vendor_attributes: type: object additionalProperties: true description: 'The additional attributes of the vendor.' media_type: type: string enum: - application/spdx+json - application/vnd.cyclonedx+json description: 'The format of the sbom data.' sbom: type: object additionalProperties: true description: 'The raw data of the sbom generated by the scanner.' ErrorResponse: type: object properties: error: $ref: "#/components/schemas/Error" Error: type: object properties: message: type: string example: "Some unexpected error" CVSSDetails: type: object properties: score_v3: type: number format: float description: | The CVSS 3.0 score for the vulnerability. example: 3.2 score_v2: type: number format: float description: | The CVSS 2.0 score for the vulnerability. vector_v3: type: string description: | The CVSS 3.0 vector for the vulnerability. example: CVSS:3.0/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N vector_v2: type: string description: | The CVSS 2.0 vector for the vulnerability. The string is of the form AV:L/AC:M/Au:N/C:P/I:N/A:N example: AV:N/AC:L/Au:N/C:N/I:N/A:P securitySchemes: BasicAuth: type: http scheme: basic BearerAuth: type: http scheme: bearer