Metadata-Version: 1.2
Name: clair-cicd
Version: 1.0.2
Summary: Clair CI/CD
Home-page: https://github.com/simonsdave/clair-cicd
Author: Dave Simons
Author-email: simonsdave@gmail.com
Maintainer: Dave Simons
Maintainer-email: simonsdave@gmail.com
License: MIT
Download-URL: https://github.com/simonsdave/clair-cicd/tarball/v1.0.2
Description: clair-cicd
        ==========
        
        |Maintained| |MIT license| |PythonVersions| |status| |PyPI|
        |Requirements| |CircleCI| |codecov|
        |docker-simonsdave/clair-cicd-database|
        |docker-simonsdave/clair-cicd-clair|
        
        `Clair <https://github.com/coreos/clair>`__, `released by CoreOS in Nov
        ’16 <https://coreos.com/blog/vulnerability-analysis-for-containers/>`__,
        is a very effective tool for statically analyzing docker images to
        determine which known vulnerabilities exist in the images. Integrating
        Clair into a CI/CD pipeline:
        
        1. is complex (believe this is partly a documentation challenge)
        2. creates performance problems (building the Clair required Postgres
           database of vulnerabilities is slow)
        3. in and of itself is insufficient from a risk assessment point of view
           because once vulnerabilities are identified there’s a lack of
           prescriptive guidance on how to act on the identified vulnerabilities
        
        This repo was created to address the above challenges.
        
        Background
        ----------
        
        The roots of this repo center around the following beliefs:
        
        -  when inserted into a CI/CD pipeline
           `Clair <https://github.com/coreos/clair>`__ can be a very effective
           foundation for the automated assessment of Docker image vulnerability
           risk
        -  services should be run in Docker containers and thus CI/CD pipelines
           should be focused on the automated generation, assessment and
           ultimately deployment of Docker images
        -  understanding and assessing the risk profile of services is important
           ie. security is important
        -  Docker images should **not** be pushed to a Docker registry until
           their risk profile is understood (this is an important one)
        -  the CI/CD pipeline has to be fast. how fast? ideally < 5 minutes
           between code commit and automated (CD) deployment begins rolling out
           a change
        -  there should be a clear division of responsibilities between those
           who create a docker image (service engineer) and those who determine
           the risk of vulnerabilities in a docker image (security analyst)
        -  the risk assessment process should generate evidence which can be
           used to understand the risk assessment decision
        
        Key Participants
        ----------------
        
        -  service engineer - responsible for implementing a service that is
           packaged in a docker image
        -  security analyst - responsible for defining whitelists which are
           consumed by ``clair_cicd`` to influence Docker image risk assessment
           decisions
        
        How to Use
        ----------
        
        Getting Started
        ~~~~~~~~~~~~~~~
        
        To start using ``clair-cicd``, a service engineer inserts a single line
        of code into a service’s CI pipeline. The single line of code runs the
        shell script
        `assess-image-risk.sh <https://github.com/simonsdave/clair-cicd/blob/release-1.0.2/bin/assess-image-risk.sh>`__.
        Part of the CI pipeline’s responsibility is to build the docker image
        and then push that docker image to a docker registry. The single line of
        ``clair-cicd`` code should appear after the docker image is built and
        tested but before the docker image is pushed to a docker registry.
        
        In this simple case,
        `assess-image-risk.sh <https://github.com/simonsdave/clair-cicd/blob/release-1.0.2/bin/assess-image-risk.sh>`__
        returns a zero exit status if the docker image contains no known
        vulnerabilities above a medium severity. If the docker image contains
        any known vulnerabilities with a severity higher than medium,
        `assess-image-risk.sh <https://github.com/simonsdave/clair-cicd/blob/release-1.0.2/bin/assess-image-risk.sh>`__
        returns a non-zero exit status and the build fails ie. the build should
        fail before the docker image is pushed to a docker registry.
        
        The example illustrates what’s described about for the `alpine:3.4
        docker image <https://hub.docker.com/_/alpine?tab=tags>`__.
        
        .. code:: bash
        
           ~> curl -s -L \
             https://raw.githubusercontent.com/simonsdave/clair-cicd/master/bin/assess-image-risk.sh | \
             bash -s -- alpine:3.4
           ~> echo $?
           0
           ~>
        
        Understanding the Risk Assessment Decision
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        
        To understand how ``assess-image-risk.sh`` is making its risk assessment
        decision try using the ``-v`` flag.
        
        .. code:: bash
        
           ~> curl -s -L \
             https://raw.githubusercontent.com/simonsdave/clair-cicd/master/bin/assess-image-risk.sh | \
             bash -s -- -v alpine:3.4
           2020-01-12 16:43:35 pulling clair database image 'simonsdave/clair-cicd-database:latest'
           2020-01-12 16:44:17 successfully pulled clair database image
           2020-01-12 16:44:17 starting clair database container 'clair-db-c1dbb5f93ae98755'
           2020-01-12 16:44:23 waiting for database server in container 'clair-db-c1dbb5f93ae98755' to start ...........................
           2020-01-12 16:44:54 successfully started clair database container
           2020-01-12 16:44:54 clair configuration in '/var/folders/7x/rr443kj575s8zz54jrbrp4jc0000gn/T/tmp.ElAlhGNl'
           2020-01-12 16:44:59 pulling clair image 'simonsdave/clair-cicd-clair:latest'
           2020-01-12 16:45:13 successfully pulled clair image 'simonsdave/clair-cicd-clair:latest'
           2020-01-12 16:45:13 starting clair container 'clair-e9573ae537134fa0'
           2020-01-12 16:45:15 successfully started clair container 'clair-e9573ae537134fa0'
           2020-01-12 16:45:15 saving docker image 'alpine:3.4' to '/tmp/tmp.IaNHCH'
           2020-01-12 16:45:16 successfully saved docker image 'alpine:3.4'
           2020-01-12 16:45:16 starting to create clair layers
           2020-01-12 16:45:16 creating clair layer '378cb6b4a17e08c366cebd813d218f60889848387fa61a56ac054ca027a4890d'
           2020-01-12 16:45:16 successfully created clair layer '378cb6b4a17e08c366cebd813d218f60889848387fa61a56ac054ca027a4890d'
           2020-01-12 16:45:16 done creating clair layers
           2020-01-12 16:45:16 starting to get vulnerabilities for clair layers
           2020-01-12 16:45:16 saving vulnerabilities to directory '/tmp/tmp.MDncHN'
           2020-01-12 16:45:16 getting vulnerabilities for layer '378cb6b4a17e08c366cebd813d218f60889848387fa61a56ac054ca027a4890d'
           2020-01-12 16:45:16 successfully got vulnerabilities for layer '378cb6b4a17e08c366cebd813d218f60889848387fa61a56ac054ca027a4890d'
           2020-01-12 16:45:16 done getting vulnerabilities for clair layers
           2020-01-12 21:45:17 INFO io:89 Looking for vulnerabilities in directory '/tmp/tmp.MDncHN'
           2020-01-12 21:45:17 INFO io:95 Found 1 files with vulnerabilities in directory '/tmp/tmp.MDncHN'
           2020-01-12 21:45:17 INFO io:104 Looking for vulnerabilities in '/tmp/tmp.MDncHN/378cb6b4a17e08c366cebd813d218f60889848387fa61a56ac054ca027a4890d.json'
           2020-01-12 21:45:17 INFO io:122 Found 0 vulnerabilities in '/tmp/tmp.MDncHN/378cb6b4a17e08c366cebd813d218f60889848387fa61a56ac054ca027a4890d.json'
           2020-01-12 21:45:17 INFO io:133 Found 0 vulnerabilities in 1 files in directory '/tmp/tmp.MDncHN'
           2020-01-12 21:45:17 INFO assessor:19 Assessment starts
           2020-01-12 21:45:17 INFO assessor:26 Assessment ends - pass
           ~> echo $?
           0
           ~>
        
        Adding a Vulnerability Whitelist
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        
        In the above examples a default vulnerability whitelist was used. When
        specified as a JSON doc, this whitelist would be:
        
        .. code:: json
        
           {
             "ignoreSevertiesAtOrBelow": "medium"
           }
        
        By default,
        `assess-image-risk.sh <https://github.com/simonsdave/clair-cicd/blob/release-1.0.2/bin/assess-image-risk.sh>`__
        returns a non-zero exit status if any vulnerabilities are identified in
        the image with a severity higher than medium. The medium is derived from
        the default vulnerability whitelist.
        
        The example below illustrate how to specify a vulnerability whitelist
        and with a severity other than medium. Note the use of the ``json://``
        prefix to indicate this is an inline whitelist.
        
        .. code:: bash
        
           ~> curl -s -L \
             https://raw.githubusercontent.com/simonsdave/clair-cicd/master/bin/assess-image-risk.sh | \
             bash -s -- -v --whitelist 'json://{"ignoreSevertiesAtOrBelow": "negligible"}' ubuntu:18.04
           2020-01-12 16:46:56 pulling clair database image 'simonsdave/clair-cicd-database:latest'
           2020-01-12 16:46:58 successfully pulled clair database image
           2020-01-12 16:46:58 starting clair database container 'clair-db-3b0811925f7e8bc2'
           2020-01-12 16:46:59 waiting for database server in container 'clair-db-3b0811925f7e8bc2' to start .............................
           2020-01-12 16:47:32 successfully started clair database container
           2020-01-12 16:47:32 clair configuration in '/var/folders/7x/rr443kj575s8zz54jrbrp4jc0000gn/T/tmp.BXCs3Giy'
           2020-01-12 16:47:34 pulling clair image 'simonsdave/clair-cicd-clair:latest'
           2020-01-12 16:47:36 successfully pulled clair image 'simonsdave/clair-cicd-clair:latest'
           2020-01-12 16:47:36 starting clair container 'clair-fc579c71e7daba57'
           2020-01-12 16:47:38 successfully started clair container 'clair-fc579c71e7daba57'
           2020-01-12 16:47:38 saving docker image 'ubuntu:18.04' to '/tmp/tmp.lPDhNd'
           2020-01-12 16:47:43 successfully saved docker image 'ubuntu:18.04'
           2020-01-12 16:47:43 starting to create clair layers
           2020-01-12 16:47:43 creating clair layer 'cc59b0ca1cf21d77c81a98138703008daa167b1ab1a115849d498dba64e738dd'
           2020-01-12 16:47:43 successfully created clair layer 'cc59b0ca1cf21d77c81a98138703008daa167b1ab1a115849d498dba64e738dd'
           2020-01-12 16:47:43 creating clair layer '27a911bb510bf1e9458437f0f44216fd38fd08c462ed7aa026d91aab8c054e54'
           2020-01-12 16:47:44 successfully created clair layer '27a911bb510bf1e9458437f0f44216fd38fd08c462ed7aa026d91aab8c054e54'
           2020-01-12 16:47:44 creating clair layer 'd80735acaa72040a0a98ca3ae6891f9abb4e2f5d627b4099c4fefdc3ce1e696e'
           2020-01-12 16:47:44 successfully created clair layer 'd80735acaa72040a0a98ca3ae6891f9abb4e2f5d627b4099c4fefdc3ce1e696e'
           2020-01-12 16:47:44 creating clair layer '1ee34a985f7aef86436a5519f5ad83f866a74c7d9a0c22e47c4213ee9cb64e6d'
           2020-01-12 16:47:44 successfully created clair layer '1ee34a985f7aef86436a5519f5ad83f866a74c7d9a0c22e47c4213ee9cb64e6d'
           2020-01-12 16:47:44 done creating clair layers
           2020-01-12 16:47:44 starting to get vulnerabilities for clair layers
           2020-01-12 16:47:44 saving vulnerabilities to directory '/tmp/tmp.dkfgmI'
           2020-01-12 16:47:44 getting vulnerabilities for layer 'cc59b0ca1cf21d77c81a98138703008daa167b1ab1a115849d498dba64e738dd'
           2020-01-12 16:47:44 successfully got vulnerabilities for layer 'cc59b0ca1cf21d77c81a98138703008daa167b1ab1a115849d498dba64e738dd'
           2020-01-12 16:47:44 getting vulnerabilities for layer '27a911bb510bf1e9458437f0f44216fd38fd08c462ed7aa026d91aab8c054e54'
           2020-01-12 16:47:44 successfully got vulnerabilities for layer '27a911bb510bf1e9458437f0f44216fd38fd08c462ed7aa026d91aab8c054e54'
           2020-01-12 16:47:44 getting vulnerabilities for layer 'd80735acaa72040a0a98ca3ae6891f9abb4e2f5d627b4099c4fefdc3ce1e696e'
           2020-01-12 16:47:44 successfully got vulnerabilities for layer 'd80735acaa72040a0a98ca3ae6891f9abb4e2f5d627b4099c4fefdc3ce1e696e'
           2020-01-12 16:47:44 getting vulnerabilities for layer '1ee34a985f7aef86436a5519f5ad83f866a74c7d9a0c22e47c4213ee9cb64e6d'
           2020-01-12 16:47:44 successfully got vulnerabilities for layer '1ee34a985f7aef86436a5519f5ad83f866a74c7d9a0c22e47c4213ee9cb64e6d'
           2020-01-12 16:47:44 done getting vulnerabilities for clair layers
           2020-01-12 21:47:45 INFO io:89 Looking for vulnerabilities in directory '/tmp/tmp.dkfgmI'
           2020-01-12 21:47:45 INFO io:95 Found 4 files with vulnerabilities in directory '/tmp/tmp.dkfgmI'
           2020-01-12 21:47:45 INFO io:104 Looking for vulnerabilities in '/tmp/tmp.dkfgmI/27a911bb510bf1e9458437f0f44216fd38fd08c462ed7aa026d91aab8c054e54.json'
           2020-01-12 21:47:45 INFO io:122 Found 33 vulnerabilities in '/tmp/tmp.dkfgmI/27a911bb510bf1e9458437f0f44216fd38fd08c462ed7aa026d91aab8c054e54.json'
           2020-01-12 21:47:45 INFO io:104 Looking for vulnerabilities in '/tmp/tmp.dkfgmI/cc59b0ca1cf21d77c81a98138703008daa167b1ab1a115849d498dba64e738dd.json'
           2020-01-12 21:47:45 INFO io:122 Found 33 vulnerabilities in '/tmp/tmp.dkfgmI/cc59b0ca1cf21d77c81a98138703008daa167b1ab1a115849d498dba64e738dd.json'
           2020-01-12 21:47:45 INFO io:104 Looking for vulnerabilities in '/tmp/tmp.dkfgmI/1ee34a985f7aef86436a5519f5ad83f866a74c7d9a0c22e47c4213ee9cb64e6d.json'
           2020-01-12 21:47:45 INFO io:122 Found 33 vulnerabilities in '/tmp/tmp.dkfgmI/1ee34a985f7aef86436a5519f5ad83f866a74c7d9a0c22e47c4213ee9cb64e6d.json'
           2020-01-12 21:47:45 INFO io:104 Looking for vulnerabilities in '/tmp/tmp.dkfgmI/d80735acaa72040a0a98ca3ae6891f9abb4e2f5d627b4099c4fefdc3ce1e696e.json'
           2020-01-12 21:47:45 INFO io:122 Found 33 vulnerabilities in '/tmp/tmp.dkfgmI/d80735acaa72040a0a98ca3ae6891f9abb4e2f5d627b4099c4fefdc3ce1e696e.json'
           2020-01-12 21:47:45 INFO io:133 Found 33 vulnerabilities in 4 files in directory '/tmp/tmp.dkfgmI'
           2020-01-12 21:47:45 INFO assessor:19 Assessment starts
           2020-01-12 21:47:45 INFO assessor:34 Assessing vulnerability CVE-2018-11236 - start
           2020-01-12 21:47:45 INFO assessor:52 Vulnerability CVE-2018-11236 @ severity medium greater than whitelist severity @ negligible - fail
           2020-01-12 21:47:45 INFO assessor:36 Assessing vulnerability CVE-2018-11236 - finish
           2020-01-12 21:47:45 INFO assessor:23 Assessment ends - fail
           ~> echo $?
           1
           ~>
        
        The above is an example of an inline whitelist. It’s also possible to
        specify a whitelist in a file. The example below illustrates the usage.
        Note use of the ``file://`` prefix to indicate the whitelist is
        contained in a file.
        
        .. code:: bash
        
           ~> cat whitelist.json
           {
             "ignoreSevertiesAtOrBelow": "medium"
           }
           ~> curl -s -L \
             https://raw.githubusercontent.com/simonsdave/clair-cicd/master/bin/assess-image-risk.sh | \
             bash -s -- -v --whitelist file://whitelist.json alpine:3.4
           2020-01-12 16:48:41 pulling clair database image 'simonsdave/clair-cicd-database:latest'
           2020-01-12 16:48:42 successfully pulled clair database image
           2020-01-12 16:48:42 starting clair database container 'clair-db-191152e37b864e4b'
           2020-01-12 16:48:43 waiting for database server in container 'clair-db-191152e37b864e4b' to start .............................
           2020-01-12 16:49:16 successfully started clair database container
           2020-01-12 16:49:16 clair configuration in '/var/folders/7x/rr443kj575s8zz54jrbrp4jc0000gn/T/tmp.GdlBNmiG'
           2020-01-12 16:49:19 pulling clair image 'simonsdave/clair-cicd-clair:latest'
           2020-01-12 16:49:20 successfully pulled clair image 'simonsdave/clair-cicd-clair:latest'
           2020-01-12 16:49:20 starting clair container 'clair-747d1c50606fba7e'
           2020-01-12 16:49:21 successfully started clair container 'clair-747d1c50606fba7e'
           2020-01-12 16:49:22 saving docker image 'alpine:3.4' to '/tmp/tmp.Eldkbe'
           2020-01-12 16:49:23 successfully saved docker image 'alpine:3.4'
           2020-01-12 16:49:23 starting to create clair layers
           2020-01-12 16:49:23 creating clair layer '378cb6b4a17e08c366cebd813d218f60889848387fa61a56ac054ca027a4890d'
           2020-01-12 16:49:23 successfully created clair layer '378cb6b4a17e08c366cebd813d218f60889848387fa61a56ac054ca027a4890d'
           2020-01-12 16:49:23 done creating clair layers
           2020-01-12 16:49:23 starting to get vulnerabilities for clair layers
           2020-01-12 16:49:23 saving vulnerabilities to directory '/tmp/tmp.pCOhlL'
           2020-01-12 16:49:23 getting vulnerabilities for layer '378cb6b4a17e08c366cebd813d218f60889848387fa61a56ac054ca027a4890d'
           2020-01-12 16:49:23 successfully got vulnerabilities for layer '378cb6b4a17e08c366cebd813d218f60889848387fa61a56ac054ca027a4890d'
           2020-01-12 16:49:23 done getting vulnerabilities for clair layers
           2020-01-12 21:49:23 INFO io:89 Looking for vulnerabilities in directory '/tmp/tmp.pCOhlL'
           2020-01-12 21:49:23 INFO io:95 Found 1 files with vulnerabilities in directory '/tmp/tmp.pCOhlL'
           2020-01-12 21:49:23 INFO io:104 Looking for vulnerabilities in '/tmp/tmp.pCOhlL/378cb6b4a17e08c366cebd813d218f60889848387fa61a56ac054ca027a4890d.json'
           2020-01-12 21:49:23 INFO io:122 Found 0 vulnerabilities in '/tmp/tmp.pCOhlL/378cb6b4a17e08c366cebd813d218f60889848387fa61a56ac054ca027a4890d.json'
           2020-01-12 21:49:23 INFO io:133 Found 0 vulnerabilities in 1 files in directory '/tmp/tmp.pCOhlL'
           2020-01-12 21:49:23 INFO assessor:19 Assessment starts
           2020-01-12 21:49:23 INFO assessor:26 Assessment ends - pass
           ~> echo $?
           0
           ~>
        
        Whitelists can also contain vulnerabilities. The example below
        illustrates this capability. If you add the ``-v`` (verbose) flag to
        ``assess-image-risk.sh`` you see exactly how the vulnerabilities impact
        the risk assessment with statements like
        ``Vulnerability CVE-2019-13627 in whitelist - pass``
        
        .. code:: bash
        
           ~> curl -s -L \
             https://raw.githubusercontent.com/simonsdave/clair-cicd/master/bin/assess-image-risk.sh | \
             bash -s -- --whitelist 'json://{"ignoreSevertiesAtOrBelow":"low"}' ubuntu:18.04
           ~> echo $?
           1
           ~> cat whitelist.json
           {
             "ignoreSevertiesAtOrBelow": "low",
             "vulnerabilities": [
               { "cveId": "CVE-2018-20839", "rationale": "reason #1" },
               { "cveId": "CVE-2019-5188", "rationale": "reason #2" },
               { "cveId": "CVE-2018-11236", "rationale": "reason #3" },
               { "cveId": "CVE-2019-13627", "rationale": "reason #4" },
               { "cveId": "CVE-2019-13050", "rationale": "reason #5" },
               { "cveId": "CVE-2018-11237", "rationale": "reason #6" },
               { "cveId": "CVE-2018-19591", "rationale": "reason #7" }
             ]
           }
           ~> curl -s -L \
             https://raw.githubusercontent.com/simonsdave/clair-cicd/master/bin/assess-image-risk.sh | \
             bash -s -- --whitelist 'file://whitelist.json' ubuntu:18.04
           ~> echo $?
           0
           ~>
        
        Responsibilities
        ^^^^^^^^^^^^^^^^
        
        -  maintained by security analyst **not** service engineer
        -  checked into source code control and appropriate change management
           processes are used to make changes (code reviews, feature branches,
           etc)
        
        How it Works + Requirements/Assumptions
        ---------------------------------------
        
        There are 3 moving pieces:
        
        1. `assess-image-risk.sh <https://github.com/simonsdave/clair-cicd/blob/release-1.0.2/bin/assess-image-risk.sh>`__
           is bash script which does the heavy lifting to co-ordinate the
           interaction of the 2 other moving pieces
        2. `Clair’s <https://github.com/coreos/clair>`__ vulnerability database
           which is packaged inside the docker image
           `simonsdave/clair-database <https://hub.docker.com/r/simonsdave/clair-database/>`__
           - a `CircleCI <https://circleci.com/>`__ cron job is used to rebuild
           `simonsdave/clair-database <https://hub.docker.com/r/simonsdave/clair-database/>`__
           3 days per week to ensure the vulnerability database is current
        3. a set of Python and Bash risk assessment scripts packaged in the
           `simonsdave/clair-cicd-clair <https://hub.docker.com/r/simonsdave/clair-cicd-clair/>`__
           docker image which is based on the docker image
           `quay.io/coreos/clair <https://quay.io/repository/coreos/clair>`__
           which packages up `Clair <https://github.com/coreos/clair>`__
        
        From the samples at the start of this doc you’ll see the approach of
        curl’ing the latest release of
        `assess-image-risk.sh <https://github.com/simonsdave/clair-cicd/blob/release-1.0.2/bin/assess-image-risk.sh>`__
        into a localy run bash shell.
        `assess-image-risk.sh <https://github.com/simonsdave/clair-cicd/blob/release-1.0.2/bin/assess-image-risk.sh>`__
        then spins up a container using the
        `simonsdave/clair-database <https://hub.docker.com/r/simonsdave/clair-database/>`__.
        Another container is then run using
        `simonsdave/clair-cicd-clair <https://hub.docker.com/r/simonsdave/clair-cicd-clair/>`__
        with the
        `simonsdave/clair-cicd-clair <https://hub.docker.com/r/simonsdave/clair-cicd-clair/>`__
        container being able to talk with the
        `simonsdave/clair-database <https://hub.docker.com/r/simonsdave/clair-database/>`__
        container. Once the
        `simonsdave/clair-cicd-clair <https://hub.docker.com/r/simonsdave/clair-cicd-clair/>`__
        container is running,
        `assess-image-risk.sh <https://github.com/simonsdave/clair-cicd/blob/release-1.0.2/bin/assess-image-risk.sh>`__
        docker exec’s `this bash
        script <dockerfiles/clair/assess-image-risk.sh>`__ which does the actual
        risk assessment.
        
        Armed with the understanding of how ``clair-cicd`` works you’ll
        appreciate that the ability to execute
        `assess-image-risk.sh <https://github.com/simonsdave/clair-cicd/blob/release-1.0.2/bin/assess-image-risk.sh>`__
        is what defines the requirements for the execution environment.
        `assess-image-risk.sh <https://github.com/simonsdave/clair-cicd/blob/release-1.0.2/bin/assess-image-risk.sh>`__
        is a bash script used to launch the risk assessment process and as such
        it’s this script which defines the bulk of the assumptions/requirements
        for ``clair-cicd`` - the script uses docker, sed and openssl so all
        these need to be available in the environment running ``clair-cicd``
        
        References
        ----------
        
        -  `29 Jan ’20 - What Is DevSecOps, and How Is It Different from
           DevOps? <https://research.g2.com/insights/what-is-devsecops-and-how-is-it-different-from-devops>`__
        -  `1 Oct ’18 - Baking Compliance in your CI/CD
           Pipeline <https://thenewstack.io/baking-compliance-in-your-ci-cd-pipeline>`__
        -  `11 Sep ’18 - What is
           DevSecOps? <https://medium.com/@aditi.chaudhry92/what-is-devsecops-cb14cfd457b2>`__
        -  `20 Jun ’18 - Where in the DevOps cycle do you do
           security? <https://opensource.com/article/18/6/where-cycle-security-devops>`__
        -  `8 May ’18 - DevSecOps: 7 habits of strong security
           organizations <https://enterprisersproject.com/article/2018/5/devsecops-7-habits-strong-security-organizations>`__
        -  `18 Apr ’18 - The Cloudcast #343 - Container Vulnerability
           Scanning <http://www.thecloudcast.net/2018/04/the-cloudcast-343-container.html>`__
        -  `21 Feb ’18 - Automated Compliance Testing Tool Accelerates
           DevSecOps <https://www.securityweek.com/automated-compliance-testing-tool-accelerates-devsecops>`__
        -  `20 Feb ’18 - 6 Requirements for Achieving
           DevSecOps <https://securityboulevard.com/2018/02/6-requirements-for-achieving-devsecops/>`__
        -  `22 Jan ’18 - DevOps and Security: How to Overcome Cultural
           Challenges and Transform to True
           DevSecOps <https://thenewstack.io/devops-security-overcome-cultural-challenges-transform-true-devsecops/>`__
        -  `15 Jan ’18 - Why DevSecOps matters to IT
           leaders <https://enterprisersproject.com/article/2018/1/why-devsecops-matters-it-leaders>`__
        -  `27 Nov ’17 - What is vulnerability management? Processes and
           software for prioritizing
           threats <https://www.csoonline.com/article/3238080/vulnerabilities/what-is-vulnerability-management-processes-and-software-for-prioritizing-threats.html>`__
        -  `23 Oct ’17 - The Ten Cybersecurity
           Commandments <http://www.securityweek.com/ten-cybersecurity-commandments>`__
        -  `9 Oct ’17 - 10 layers of Linux container
           security <https://opensource.com/article/17/10/10-layers-container-security>`__
        -  `5 Oct ’17 - How to Maintain Security when Rolling out
           DevOps <https://www.informationweek.com/devops/how-to-maintain-security-when-rolling-out-devops/a/d-id/1330047?imm_mid=0f71d7&cmp=em-webops-na-na-newsltr_security_20171010_length_control>`__
        -  `26 Jan ’17 - DevOps and Separation of
           Duties <https://www.newcontext.com/devops-and-separation-of-duties/>`__
        -  `26 Jul ’16 - Injecting security into Continuous
           Delivery <https://www.oreilly.com/learning/injecting-security-into-continuous-delivery>`__
        -  `5 Jun ’16 - <— Shifting Security to the
           Left <http://www.devsecops.org/blog/2016/5/20/-security>`__
        -  `Five Secrets and Two Common “Gotchas” of Vulnerability
           Scanning <https://www.kennasecurity.com/resources/secrets-gotchas-of-vuln-scanning>`__
        
        .. |Maintained| image:: https://img.shields.io/maintenance/yes/2020.svg
        .. |MIT license| image:: http://img.shields.io/badge/license-MIT-brightgreen.svg
           :target: http://opensource.org/licenses/MIT
        .. |PythonVersions| image:: https://img.shields.io/pypi/pyversions/clair-cicd.svg?style=flat
        .. |status| image:: https://img.shields.io/pypi/status/clair-cicd.svg?style=flat
        .. |PyPI| image:: https://img.shields.io/pypi/v/clair-cicd.svg?style=flat
           :target: https://pypi.python.org/pypi/clair-cicd
        .. |Requirements| image:: https://requires.io/github/simonsdave/clair-cicd/requirements.svg?branch=release-1.0.2
           :target: https://requires.io/github/simonsdave/clair-cicd/requirements/?branch=release-1.0.2
        .. |CircleCI| image:: https://circleci.com/gh/simonsdave/clair-cicd/tree/release-1.0.2.svg?style=shield
           :target: https://circleci.com/gh/simonsdave/clair-cicd/tree/release-1.0.2
        .. |codecov| image:: https://codecov.io/gh/simonsdave/clair-cicd/branch/release-1.0.2/graph/badge.svg
           :target: https://codecov.io/gh/simonsdave/clair-cicd/branch/release-1.0.2
        .. |docker-simonsdave/clair-cicd-database| image:: https://img.shields.io/badge/docker-simonsdave%2Fclair%20cicd%20database-blue.svg
           :target: https://hub.docker.com/r/simonsdave/clair-cicd-database/
        .. |docker-simonsdave/clair-cicd-clair| image:: https://img.shields.io/badge/docker-simonsdave%2Fclair%20cicd%20clair-blue.svg
           :target: https://hub.docker.com/r/simonsdave/clair-cicd-clair/
        
Keywords: development,tools
Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: Natural Language :: English
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Topic :: Software Development :: Libraries :: Python Modules
