Skip to content

Hardening Manifest

Overview

Because contributors cannot generate their own pipelines, contributors will need a hardening_manifest.yaml file in their repository to go through the hardening process. The hardening manifest contains important information such as: the name of the image, build arguments for the container, labels for the container, a list of software dependencies, and the maintainers for the container. This hardening manifest file provides a common format for the tools surrounding the Iron Bank to source relevant information from.

The hardening_manifest.yaml provides details about the container that is built. It also enables contributors to download private artifacts which are not located in the standard dependency systems (e.g. Red Hat Universal Base Image dependencies). The artifacts are acquired and then made available for the Dockerfile when the pipeline is run. It also allows pulling a different file types (including Docker images and files directly from S3 buckets) so that contributors may, for example, use a multi-stage build approach.

The file should be in the root of the project and should include the following sections.

Example
hardening_manifest.yaml
apiVersion: v1

    # The repository name in registry1, excluding /ironbank/
    name: "opensource/memcached/memcached"

    # List of tags to push for the repository in registry1
    # The most specific version should be the first tag and will be shown
    # on ironbank.dso.mil
    tags:
    - "1.6.15"
    - "latest"

    # Build args passed to Dockerfile ARGs
    args:
      BASE_IMAGE: "redhat/ubi/ubi9"
      BASE_TAG: "9.3"

    # Docker image labels
    labels:
      org.opencontainers.image.title: "memcached"
      # Human-readable description of the software packaged in the image
      org.opencontainers.image.description: "Free & open source, high-performance, distributed memory object caching system,"
      # License(s) under which contained software is distributed
      org.opencontainers.image.licenses: "BSD"
      # URL to find more information on the image
      org.opencontainers.image.url: "https://memcached.org/"
      # Name of the distributing entity, organization or individual
      org.opencontainers.image.vendor: "Danga Interactive"
      org.opencontainers.image.version: "1.6.15"
      # Keywords to help with search (ex. "cicd,gitops,golang")
      mil.dso.ironbank.image.keywords: "memory,cache,caching"
      # This value can be "opensource" or "commercial"
      mil.dso.ironbank.image.type: "opensource"
      # Product the image belongs to for grouping multiple images
      mil.dso.ironbank.product.name: "memcached"

    # List of resources to make available to the offline build context
    resources:
    - url: "https://github.com/memcached/memcached/archive/1.6.15.tar.gz"
      filename: "memcached.tar.gz"
      validation:
        type: sha256
        value: 4b7e83155bc4fd4103a30dc7f49de024f06978cde10e0df74e5c6f8a04e389a5

    # List of project maintainers
    maintainers:
    - email: "email@example.com"
      # The name of the current container owner
      name: "First Last"
      # The gitlab username of the current container owner
      username: "example.username"
      cht_member: true
    ```

## Schema

### name

The `name` section in the hardening_manifest.yaml file is a string which provides the repository name/path that will show up in registry1 for the current container.

### tags

The `tags` section in the hardening_manifest.yaml file provides all the tags the image should be tagged with. The first tag in the list will be the authoritative tag used to reference the image so it should be the most specific tag. The list can contain more broad tags and it should contain the `latest` tag as the last element in the list.

For example ubi9 could be tagged with `9.3` as the authoritative tag, `9` as a broader tag, and `latest` as the most broad tag and the last tag in the list.

```yaml
tags:
  - "9.3"
  - "9"
  - "latest"

args

The args section in the hardening_manifest.yaml file provides build arguments to the container build. It contains the BASE_IMAGE and BASE_TAG arguments along with any other build arguments you wish to provide.

labels

The labels section in the hardening_manifest.yaml file provides the standard OCI labels along with some custom ironbank labels. These are all baked into the image for use on the frontend.

Label Description
org.opencontainers.image.title Name of the image
org.opencontainers.image.description Human-readable description of the software packaged in the image
org.opencontainers.image.licenses License(s) under which contained software is distributed
org.opencontainers.image.url URL to find more information on the image
org.opencontainers.image.vendor Name of the distributing entity, organization or individual
org.opencontainers.image.version Authoritative version of the software
mil.dso.ironbank.image.keywords Keywords to help with search (ex. "cicd,gitops,golang")
mil.dso.ironbank.image.type This value can be "opensource" or "commercial"
mil.dso.ironbank.product.name Product the image belongs to for grouping multiple images

resources

The resources section in the hardening_manifest.yaml file defines all of the dependencies for the container. Each dependency must include:

  1. File URL - a direct link to the resource being downloaded
  2. Desired file name - the staging name for the build context (to be referenced by the Dockerfile)
  3. The validation method - a means to verify that the resource which is being downloaded is in fact the intended resource; supported validation types: sha256, sha512

For example:

resources:
  - url: "https://s3.amazonaws.com/path/to/your/package-1.0.0.tar.gz"
    filename: "package-1.0.0.tar.gz"
    validation:
      type: "sha256"
      value: "3d6b4cfca92067edd5c860c212ff5153d1e162b8791408bc671900309eb555ec" # must be lowercase

You can also use images from valid Docker image registries such as docker.io quay.io gcr.io k8s.io etc... For example

resources:
- tag: bitnami/kubectl:1.27.3
  url: docker://docker.io/bitnami/kubectl@sha256:df4773de390caa4a75d150d78d5096a5108796f27e2d5a1542e534b0d8899fac

It is important for contributors to be aware of the way in which the resources included in the hardening_manifest.yaml file can impact the container hardening process. While there are no restrictions on the types of resources that can be drawn in for use in the Dockerfile build or even on the location where the resources are acquired from, downloading resources from less-than-reputable sources or ones with vulnerabilities can result in the user having to mitigate more findings generated by the scans or risk a container being not hosted by Iron Bank.

Currently, basic and aws authentication methods are available to retrieve external resources. x509 authentication will be included in the future as an authentication method. You will need to at least include the SHA checksum associated with the downloaded resource in order to allow for verification within the pipeline.

See Resource Credentials for additional instructions.

Utilizing hardening_manifest.yaml artifacts in the Dockerfile

Once the hardening_manifest.yaml file has been set up correctly, contributors can utilize the artifacts when performing the build of their Dockerfile. The pipeline downloads the specified artifact, verifies that the artifact is the same one that the contributor is expecting to be downloaded by comparing the checksum values provided by the contributor and the checksum calculated on the downloaded artifact. The artifact(s) will then be passed to the build stage if the values match. Otherwise, the pipeline will fail at this stage.

To use a downloaded artifact, add a COPY command to the Dockerfile. The artifact is copied over from the host environment to the container for use in the build. For example, if the artifact file name you chose was dependencyX.tar.gz, you may choose to set this as an argument in the Dockerfile and reference it by a variable name, before copying the artifact to your desired location. See below:

ARG IMPORTANT_DEPENDENCY=dependencyX.tar.gz
COPY ["${IMPORTANT_DEPENDENCY}", "/some/dir"]
RUN tar -zxvf /some/dir/${IMPORTANT_DEPENDENCY}

maintainers

The maintainers section in the hardening_manifest.yaml file provides contact information for the individuals in charge of maintaining the image. It should include the name, email, and gitlab username for all the individuals maintaining the image. There is also a boolean cht_member field which should only be present (and marked true) if the individual is a member of the container hardening team.

This section will be used to contact contributors in the event of new findings, automatically assign Gitlab issues, bug reports, and more. Please ensure that all members listed in maintainers section are up-to-date.

Resource Credentials

Members frequently require resources that are only available to authenticated users. Examples of this include Docker containers inside of private registries, artifacts in private S3 buckets, and other resources retrieved over HTTP behind auth walls. To facilitate building containers in the Repo1 pipeline using these resources, valid credentials to be used in the artifact gathering process may be provided on a subgroup (to DSOP) or project level.

Warning

Artifacts downloaded from authenticated sources are not protected since they are available in the CI pipeline which is open to the public.

Note

Credentials provided at the subgroup level will be inherited by any folders and projects within the subgroup.

Requesting Credentials

If you are needing to use credentials in your project to access private resources in the hardening_manifest.yaml, you will need to open a new issue in the corresponding project in repo1. DO NOT include any sensitive information in this issue. Once we have reviewed your request, we will then reach out via Mattermost IL4/5 or send a DoD Safe drop off request. Once we have the required information we will create the variables for you in repo1 so the credential ID can then be added to the hardening_manifest.yaml.

Supported Credentials

  • Basic: Username and Password used for getting resources whose url fields begin with either docker:// or http[s]://
  • S3: AWS Access Key ID and AWS Secret Access Keys used for getting resources whose url fields begin with s3://

If you are using Basic Authentication (HTTP or HTTPS) then we will need the username, the password and the ID for the credentials.

An example would be User – gitlab, Password – gitlabpassword and the ID – some-id After we have created these variables the hardening_manifest.yaml would look something like this.

auth:
  type: basic
  id: some-id

If you are using S3 credentials then we will need the S3 access key, secret key and ID.

For a particular resource, add the following fields to the resource map in hardening_manifest.yaml:

  • The type field in your resource auth map should be set to S3
  • The id field will be ID you provide.
  • There is an additional region field included for the S3 resource whose value is the AWS region in which the s3 bucket exists (e.g. us-west-1)
auth:
  type: s3
  id: some-id
  region: us-west-1