IaCの問題はGPTの力で直す。Checkovの --openai-api-keyオプションで修正方法を教えてもらおう！

## はじめに
NTTテクノクロス株式会社の渡邉洋平です。

久しぶりにCheckovを使うにあたって、`checkov help`を叩くと……なんか凄そうなオプションが生えている。

```bash
  --openai-api-key OPENAI_API_KEY
                        Add an OpenAI API key to enhance finding guidelines by
                        sending violated policies and resource code to OpenAI
                        to request remediation guidance. This will use your
                        OpenAI credits. Set your number of findings that will
                        receive enhanced guidelines using
                        CKV_OPENAI_MAX_FINDINGS [env var: CKV_OPENAI_API_KEY]
```

これ、IaCの静的解析 × ChatGPTでは？！ ということで、今回はこの`--openai-api-key`オプションを調べてみました。

## Checkov ?

Bridgecrew社が開発したOSSな静的解析ツールがCheckov。Terraform、Cloudformation、Kubernetesなどの、いわゆるIaCフレームワークによるテンプレートを、数百の組み込みポリシーに基づいて評価できるのが特徴です。

読むより、実際に使う様子を見た方がイメージが湧きますね。

昔の記事で簡単に作ったDockerfileがあったので、Checkovで解析してみます。

https://qiita.com/watany/items/7b0054949360da7ebdd1#%E3%83%93%E3%83%AB%E3%83%89%E3%83%87%E3%83%97%E3%83%AD%E3%82%A4%E7%AD%89


<details><summary>チェック対象のDockerfile</summary>

```Dockerfile: Dockerfile
FROM golang:1.13.5-stretch as build
RUN go get \
  github.com/aws/aws-sdk-go/aws \
  github.com/aws/aws-sdk-go/aws/session \
  github.com/aws/aws-sdk-go/service/s3 
COPY . /work
WORKDIR /work
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o main main.go

FROM python:3.7.6-stretch as release
RUN pip install boto3
COPY --from=build /work/main /usr/local/bin/main
COPY --from=build /work/main.py /usr/local/bin/main.py
WORKDIR /usr/local/bin/
```

</details>


<details><summary>Checkovでのチェック結果</summary>

```bash
checkov -f Dockerfile
[ dockerfile framework ]: 100%|████████████████████|[1/1], Current File Scanned=Dockerfile
[ secrets framework ]: 100%|████████████████████|[1/1], Current File Scanned=Dockerfile

       _               _              
   ___| |__   ___  ___| | _______   __
  / __| '_ \ / _ \/ __| |/ / _ \ \ / /
 | (__| | | |  __/ (__|   < (_) \ V / 
  \___|_| |_|\___|\___|_|\_\___/ \_/  
                                      
By bridgecrew.io | version: 2.3.296 

dockerfile scan results:

Passed checks: 53, Failed checks: 2, Skipped checks: 0

Check: CKV_DOCKER_11: "Ensure From Alias are unique for multistage builds."
        PASSED for resource: Dockerfile.
        File: Dockerfile:1-14
        Guide: https://docs.paloaltonetworks.com/content/techdocs/en_US/prisma/prisma-cloud/prisma-cloud-code-security-policy-reference/docker-policies/docker-policy-index/ensure-docker-from-alias-is-unique-for-multistage-builds.html
Check: CKV_DOCKER_7: "Ensure the base image uses a non latest version tag"
        PASSED for resource: Dockerfile.FROM
        File: Dockerfile:10-10
        Guide: https://docs.paloaltonetworks.com/content/techdocs/en_US/prisma/prisma-cloud/prisma-cloud-code-security-policy-reference/docker-policies/docker-policy-index/ensure-the-base-image-uses-a-non-latest-version-tag.html
Check: CKV_DOCKER_9: "Ensure that APT isn't used"
        PASSED for resource: Dockerfile.
        File: Dockerfile:1-14
        Guide: https://docs.paloaltonetworks.com/content/techdocs/en_US/prisma/prisma-cloud/prisma-cloud-code-security-policy-reference/docker-policies/docker-policy-index/ensure-docker-apt-is-not-used.html
Check: CKV_DOCKER_5: "Ensure update instructions are not use alone in the Dockerfile"
        PASSED for resource: Dockerfile.
        File: Dockerfile:1-14
        Guide: https://docs.paloaltonetworks.com/content/techdocs/en_US/prisma/prisma-cloud/prisma-cloud-code-security-policy-reference/docker-policies/docker-policy-index/ensure-update-instructions-are-not-used-alone-in-the-dockerfile.html
Check: CKV_DOCKER_10: "Ensure that WORKDIR values are absolute paths"
        PASSED for resource: Dockerfile.
        File: Dockerfile:1-14
        Guide: https://docs.paloaltonetworks.com/content/techdocs/en_US/prisma/prisma-cloud/prisma-cloud-code-security-policy-reference/docker-policies/docker-policy-index/ensure-docker-workdir-values-are-absolute-paths.html
Check: CKV2_DOCKER_14: "Ensure that certificate validation isn't disabled for git by setting the environment variable 'GIT_SSL_NO_VERIFY' to any value"
        PASSED for resource: Dockerfile.RUN
        File: Dockerfile:2-5
Check: CKV2_DOCKER_14: "Ensure that certificate validation isn't disabled for git by setting the environment variable 'GIT_SSL_NO_VERIFY' to any value"
        PASSED for resource: Dockerfile.RUN
        File: Dockerfile:8-8
Check: CKV2_DOCKER_14: "Ensure that certificate validation isn't disabled for git by setting the environment variable 'GIT_SSL_NO_VERIFY' to any value"
        PASSED for resource: Dockerfile.RUN
        File: Dockerfile:11-11
Check: CKV2_DOCKER_6: "Ensure that certificate validation isn't disabled with the NODE_TLS_REJECT_UNAUTHORIZED environmnet variable"
        PASSED for resource: Dockerfile.RUN
        File: Dockerfile:2-5
Check: CKV2_DOCKER_6: "Ensure that certificate validation isn't disabled with the NODE_TLS_REJECT_UNAUTHORIZED environmnet variable"
        PASSED for resource: Dockerfile.RUN
        File: Dockerfile:8-8
Check: CKV2_DOCKER_6: "Ensure that certificate validation isn't disabled with the NODE_TLS_REJECT_UNAUTHORIZED environmnet variable"
        PASSED for resource: Dockerfile.RUN
        File: Dockerfile:11-11
Check: CKV2_DOCKER_12: "Ensure that certificate validation isn't disabled for npm via the 'NPM_CONFIG_STRICT_SSL' environmnet variable"
        PASSED for resource: Dockerfile.RUN
        File: Dockerfile:2-5
Check: CKV2_DOCKER_12: "Ensure that certificate validation isn't disabled for npm via the 'NPM_CONFIG_STRICT_SSL' environmnet variable"
        PASSED for resource: Dockerfile.RUN
        File: Dockerfile:8-8
Check: CKV2_DOCKER_12: "Ensure that certificate validation isn't disabled for npm via the 'NPM_CONFIG_STRICT_SSL' environmnet variable"
        PASSED for resource: Dockerfile.RUN
        File: Dockerfile:11-11
Check: CKV2_DOCKER_16: "Ensure that certificate validation isn't disabled with pip via the 'PIP_TRUSTED_HOST' environment variable"
        PASSED for resource: Dockerfile.RUN
        File: Dockerfile:2-5
Check: CKV2_DOCKER_16: "Ensure that certificate validation isn't disabled with pip via the 'PIP_TRUSTED_HOST' environment variable"
        PASSED for resource: Dockerfile.RUN
        File: Dockerfile:8-8
Check: CKV2_DOCKER_16: "Ensure that certificate validation isn't disabled with pip via the 'PIP_TRUSTED_HOST' environment variable"
        PASSED for resource: Dockerfile.RUN
        File: Dockerfile:11-11
Check: CKV2_DOCKER_5: "Ensure that certificate validation isn't disabled with the PYTHONHTTPSVERIFY environmnet variable"
        PASSED for resource: Dockerfile.RUN
        File: Dockerfile:2-5
Check: CKV2_DOCKER_5: "Ensure that certificate validation isn't disabled with the PYTHONHTTPSVERIFY environmnet variable"
        PASSED for resource: Dockerfile.RUN
        File: Dockerfile:8-8
Check: CKV2_DOCKER_5: "Ensure that certificate validation isn't disabled with the PYTHONHTTPSVERIFY environmnet variable"
        PASSED for resource: Dockerfile.RUN
        File: Dockerfile:11-11
Check: CKV2_DOCKER_7: "Ensure that packages with untrusted or missing signatures are not used by apk via the '--allow-untrusted' option"
        PASSED for resource: Dockerfile.RUN
        File: Dockerfile:2-5
Check: CKV2_DOCKER_7: "Ensure that packages with untrusted or missing signatures are not used by apk via the '--allow-untrusted' option"
        PASSED for resource: Dockerfile.RUN
        File: Dockerfile:8-8
Check: CKV2_DOCKER_7: "Ensure that packages with untrusted or missing signatures are not used by apk via the '--allow-untrusted' option"
        PASSED for resource: Dockerfile.RUN
        File: Dockerfile:11-11
Check: CKV2_DOCKER_8: "Ensure that packages with untrusted or missing signatures are not used by apt-get via the '--allow-unauthenticated' option"
        PASSED for resource: Dockerfile.RUN
        File: Dockerfile:2-5
Check: CKV2_DOCKER_8: "Ensure that packages with untrusted or missing signatures are not used by apt-get via the '--allow-unauthenticated' option"
        PASSED for resource: Dockerfile.RUN
        File: Dockerfile:8-8
Check: CKV2_DOCKER_8: "Ensure that packages with untrusted or missing signatures are not used by apt-get via the '--allow-unauthenticated' option"
        PASSED for resource: Dockerfile.RUN
        File: Dockerfile:11-11
Check: CKV2_DOCKER_11: "Ensure that the '--force-yes' option is not used, as it disables signature validation and allows packages to be downgraded which can leave the system in a broken or inconsistent state"
        PASSED for resource: Dockerfile.RUN
        File: Dockerfile:2-5
Check: CKV2_DOCKER_11: "Ensure that the '--force-yes' option is not used, as it disables signature validation and allows packages to be downgraded which can leave the system in a broken or inconsistent state"
        PASSED for resource: Dockerfile.RUN
        File: Dockerfile:8-8
Check: CKV2_DOCKER_11: "Ensure that the '--force-yes' option is not used, as it disables signature validation and allows packages to be downgraded which can leave the system in a broken or inconsistent state"
        PASSED for resource: Dockerfile.RUN
        File: Dockerfile:11-11
Check: CKV2_DOCKER_13: "Ensure that certificate validation isn't disabled for npm or yarn by setting the option strict-ssl to false"
        PASSED for resource: Dockerfile.RUN
        File: Dockerfile:2-5
Check: CKV2_DOCKER_13: "Ensure that certificate validation isn't disabled for npm or yarn by setting the option strict-ssl to false"
        PASSED for resource: Dockerfile.RUN
        File: Dockerfile:8-8
Check: CKV2_DOCKER_13: "Ensure that certificate validation isn't disabled for npm or yarn by setting the option strict-ssl to false"
        PASSED for resource: Dockerfile.RUN
        File: Dockerfile:11-11
Check: CKV2_DOCKER_4: "Ensure that certificate validation isn't disabled with the pip '--trusted-host' option"
        PASSED for resource: Dockerfile.RUN
        File: Dockerfile:2-5
Check: CKV2_DOCKER_4: "Ensure that certificate validation isn't disabled with the pip '--trusted-host' option"
        PASSED for resource: Dockerfile.RUN
        File: Dockerfile:8-8
Check: CKV2_DOCKER_4: "Ensure that certificate validation isn't disabled with the pip '--trusted-host' option"
        PASSED for resource: Dockerfile.RUN
        File: Dockerfile:11-11
Check: CKV2_DOCKER_10: "Ensure that packages with untrusted or missing signatures are not used by rpm via the '--nodigest', '--nosignature', '--noverify', or '--nofiledigest' options"
        PASSED for resource: Dockerfile.RUN
        File: Dockerfile:2-5
Check: CKV2_DOCKER_10: "Ensure that packages with untrusted or missing signatures are not used by rpm via the '--nodigest', '--nosignature', '--noverify', or '--nofiledigest' options"
        PASSED for resource: Dockerfile.RUN
        File: Dockerfile:8-8
Check: CKV2_DOCKER_10: "Ensure that packages with untrusted or missing signatures are not used by rpm via the '--nodigest', '--nosignature', '--noverify', or '--nofiledigest' options"
        PASSED for resource: Dockerfile.RUN
        File: Dockerfile:11-11
Check: CKV2_DOCKER_2: "Ensure that certificate validation isn't disabled with curl"
        PASSED for resource: Dockerfile.RUN
        File: Dockerfile:2-5
Check: CKV2_DOCKER_2: "Ensure that certificate validation isn't disabled with curl"
        PASSED for resource: Dockerfile.RUN
        File: Dockerfile:8-8
Check: CKV2_DOCKER_2: "Ensure that certificate validation isn't disabled with curl"
        PASSED for resource: Dockerfile.RUN
        File: Dockerfile:11-11
Check: CKV2_DOCKER_3: "Ensure that certificate validation isn't disabled with wget"
        PASSED for resource: Dockerfile.RUN
        File: Dockerfile:2-5
Check: CKV2_DOCKER_3: "Ensure that certificate validation isn't disabled with wget"
        PASSED for resource: Dockerfile.RUN
        File: Dockerfile:8-8
Check: CKV2_DOCKER_3: "Ensure that certificate validation isn't disabled with wget"
        PASSED for resource: Dockerfile.RUN
        File: Dockerfile:11-11
Check: CKV2_DOCKER_1: "Ensure that sudo isn't used"
        PASSED for resource: Dockerfile.RUN
        File: Dockerfile:2-5
Check: CKV2_DOCKER_1: "Ensure that sudo isn't used"
        PASSED for resource: Dockerfile.RUN
        File: Dockerfile:8-8
Check: CKV2_DOCKER_1: "Ensure that sudo isn't used"
        PASSED for resource: Dockerfile.RUN
        File: Dockerfile:11-11
Check: CKV2_DOCKER_15: "Ensure that the yum and dnf package managers are not configured to disable SSL certificate validation via the 'sslverify' configuration option"
        PASSED for resource: Dockerfile.RUN
        File: Dockerfile:2-5
Check: CKV2_DOCKER_15: "Ensure that the yum and dnf package managers are not configured to disable SSL certificate validation via the 'sslverify' configuration option"
        PASSED for resource: Dockerfile.RUN
        File: Dockerfile:8-8
Check: CKV2_DOCKER_15: "Ensure that the yum and dnf package managers are not configured to disable SSL certificate validation via the 'sslverify' configuration option"
        PASSED for resource: Dockerfile.RUN
        File: Dockerfile:11-11
Check: CKV2_DOCKER_9: "Ensure that packages with untrusted or missing GPG signatures are not used by dnf, tdnf, or yum via the '--nogpgcheck' option"
        PASSED for resource: Dockerfile.RUN
        File: Dockerfile:2-5
Check: CKV2_DOCKER_9: "Ensure that packages with untrusted or missing GPG signatures are not used by dnf, tdnf, or yum via the '--nogpgcheck' option"
        PASSED for resource: Dockerfile.RUN
        File: Dockerfile:8-8
Check: CKV2_DOCKER_9: "Ensure that packages with untrusted or missing GPG signatures are not used by dnf, tdnf, or yum via the '--nogpgcheck' option"
        PASSED for resource: Dockerfile.RUN
        File: Dockerfile:11-11
Check: CKV_DOCKER_2: "Ensure that HEALTHCHECK instructions have been added to container images"
        FAILED for resource: Dockerfile.
        File: Dockerfile:1-14
        Guide: https://docs.paloaltonetworks.com/content/techdocs/en_US/prisma/prisma-cloud/prisma-cloud-code-security-policy-reference/docker-policies/docker-policy-index/ensure- hat-healthcheck-instructions-have-been-added-to-container-images.html

                1  | FROM golang:1.13.5-stretch as build
                2  | RUN go get \
                3  |   github.com/aws/aws-sdk-go/aws \
                4  |   github.com/aws/aws-sdk-go/aws/session \
                5  |   github.com/aws/aws-sdk-go/service/s3 
                6  | COPY . /work
                7  | WORKDIR /work
                8  | RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o main main.go
                9  | 
                10 | FROM python:3.7.6-stretch as release
                11 | RUN pip install boto3
                12 | COPY --from=build /work/main /usr/local/bin/main
                13 | COPY --from=build /work/main.py /usr/local/bin/main.py
                14 | WORKDIR /usr/local/bin/
Check: CKV_DOCKER_3: "Ensure that a user for the container has been created"
        FAILED for resource: Dockerfile.
        File: Dockerfile:1-14
        Guide: https://docs.paloaltonetworks.com/content/techdocs/en_US/prisma/prisma-cloud/prisma-cloud-code-security-policy-reference/docker-policies/docker-policy-index/ensure-that-a-user-for-the-container-has-been-created.html

                1  | FROM golang:1.13.5-stretch as build
                2  | RUN go get \
                3  |   github.com/aws/aws-sdk-go/aws \
                4  |   github.com/aws/aws-sdk-go/aws/session \
                5  |   github.com/aws/aws-sdk-go/service/s3 
                6  | COPY . /work
                7  | WORKDIR /work
                8  | RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o main main.go
                9  | 
                10 | FROM python:3.7.6-stretch as release
                11 | RUN pip install boto3
                12 | COPY --from=build /work/main /usr/local/bin/main
                13 | COPY --from=build /work/main.py /usr/local/bin/main.py
                14 | WORKDIR /usr/local/bin/
```

</details>

このチェックでは、2件FAILEDが出てしまいました。(以下抜粋)

```bash
Check: CKV_DOCKER_2: "Ensure that HEALTHCHECK instructions have been added to container images"
        FAILED for resource: Dockerfile.
        File: Dockerfile:1-14
        Guide: https://docs.paloaltonetworks.com/content/techdocs/en_US/prisma/prisma-cloud/prisma-cloud-code-security-policy-reference/docker-policies/docker-policy-index/ensure- hat-healthcheck-instructions-have-been-added-to-container-images.html

Check: CKV_DOCKER_3: "Ensure that a user for the container has been created"
        FAILED for resource: Dockerfile.
        File: Dockerfile:1-14
        Guide: https://docs.paloaltonetworks.com/content/techdocs/en_US/prisma/prisma-cloud/prisma-cloud-code-security-policy-reference/docker-policies/docker-policy-index/ensure-that-a-user-for-the-container-has-been-created.html
```

## Checkov × ChatGPT

調べたところ、CheckovGPTと書かれた、公式のページを見つけられた。

https://docs.bridgecrew.io/changelog/checkovgpt

- 有効なOpenAI APIキーを、オプション`--openai-api-key` or 環境変数`CKV_OPENAI_API_KEY`に含めると、修正方法のガイドが出てくる。
- 以下の環境変数で、オプションも指定できる。
    - CKV_OPENAI_MAX_FINDINGS：フレームワークごとに追加する詳細なガイドラインの数。
    - CKV_OPENAI_MAX_TOKENS：詳細なガイドラインを生成するために使用するトークンの最大数。
    - CKV_OPENAI_MODEL：使用するチャット完了モデルのID。デフォルトはgpt-3.5-turbo。

基本的な利用イメージが分かったので早速使ってみよう。

## 使ってみる

以下のようにシンプルにオプションを追加するだけで、

```bash
checkov -f Dockerfile --openai-api-key sk-xxxxxxxx
```

チェック結果に、Detailsの項が追加されている！！
英語ではあるが具体的な解説が載っているので、これに従うだけでDockerfileを改善できそうだ。

```bash
Check: CKV_DOCKER_2: "Ensure that HEALTHCHECK instructions have been added to container images"
        FAILED for resource: Dockerfile.
        Details: The following text is AI generated and should be treated as a suggestion.
                 
                 The given Dockerfile is used to build a container image.
                 The first stage of the Dockerfile uses the golang:1.13.5-stretch base image to build a Go application.
                 The second stage of the Dockerfile uses the python:3.7.6-stretch base image to create a release image that includes the Go application built in the first stage.
                 
                 However, the Dockerfile violates the Checkov policy 'Ensure that HEALTHCHECK instructions have been added to container images'.
                 A HEALTHCHECK instruction is used to check the status of a container and ensure that it is running correctly.
                 It is recommended to include a HEALTHCHECK instruction in the Dockerfile to ensure that the container is healthy and running as expected.
                 
                 To fix the violation, we need to add a HEALTHCHECK instruction to the Dockerfile.
                 The HEALTHCHECK instruction should be added to the second stage of the Dockerfile, after the WORKDIR instruction.
                 The HEALTHCHECK instruction should check the status of the Go application using an appropriate command.
                 For example, the following HEALTHCHECK instruction can be added to the Dockerfile:
                 
                 HEALTHCHECK --interval=30s --timeout=10s CMD curl --fail http://localhost:8080/health || exit 1.
                 
                 This command checks the status of the Go application every 30 seconds and times out after 10 seconds.
                 If the application is not running correctly, the command will exit with a status code of 1, indicating that the container is unhealthy.
        File: Dockerfile:1-14
        Guide: https://docs.paloaltonetworks.com/content/techdocs/en_US/prisma/prisma-cloud/prisma-cloud-code-security-policy-reference/docker-policies/docker-policy-index/ensure-that-healthcheck-instructions-have-been-added-to-container-images.html

                1  | FROM golang:1.13.5-stretch as build
                2  | RUN go get \
                3  |   github.com/aws/aws-sdk-go/aws \
                4  |   github.com/aws/aws-sdk-go/aws/session \
                5  |   github.com/aws/aws-sdk-go/service/s3 
                6  | COPY . /work
                7  | WORKDIR /work
                8  | RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o main main.go
                9  | 
                10 | FROM python:3.7.6-stretch as release
                11 | RUN pip install boto3
                12 | COPY --from=build /work/main /usr/local/bin/main
                13 | COPY --from=build /work/main.py /usr/local/bin/main.py
                14 | WORKDIR /usr/local/bin/
Check: CKV_DOCKER_3: "Ensure that a user for the container has been created"
        FAILED for resource: Dockerfile.
        Details: The following text is AI generated and should be treated as a suggestion.
                 
                 The given Dockerfile is used to build a container image.
                 The image is built in two stages.
                 In the first stage, it uses the golang:1.13.5-stretch base image to build a binary file named "main" using the Go programming language.
                 In the second stage, it uses the python:3.7.6-stretch base image to create a new image that includes the "main" binary file and a Python script named "main.py".
                 
                 However, the given Dockerfile violates the Checkov policy 'Ensure that a user for the container has been created'.
                 This policy ensures that a non-root user is created and used in the container to reduce the risk of privilege escalation attacks.
                 
                 To fix this, we can add a USER instruction to the Dockerfile to create a non-root user.
                 Here's an updated version of the Dockerfile:
                 
                 FROM golang:1.13.5-stretch as build
                 RUN go get \
                   github.com/aws/aws-sdk-go/aws \
                   github.com/aws/aws-sdk-go/aws/session \
                   github.com/aws/aws-sdk-go/service/s3 
                 COPY . /work
                 WORKDIR /work
                 RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o main main.go
                 
                 FROM python:3.7.6-stretch as release
                 RUN useradd -m myuser
                 USER myuser
                 RUN pip install boto3
                 COPY --from=build /work/main /usr/local/bin/main
                 COPY --from=build /work/main.py /usr/local/bin/main.py
                 WORKDIR /usr/local/bin/
                 
                 In this updated version, we added a new instruction `useradd -m myuser` to create a new user named "myuser".
                 We also added the `USER myuser` instruction to switch to the newly created user.
                 This ensures that the container runs with a non-root user, which reduces the risk of privilege escalation attacks.
        File: Dockerfile:1-14
        Guide: https://docs.paloaltonetworks.com/content/techdocs/en_US/prisma/prisma-cloud/prisma-cloud-code-security-policy-reference/docker-policies/docker-policy-index/ensure-that-a-user-for-the-container-has-been-created.html

                1  | FROM golang:1.13.5-stretch as build
                2  | RUN go get \
                3  |   github.com/aws/aws-sdk-go/aws \
                4  |   github.com/aws/aws-sdk-go/aws/session \
                5  |   github.com/aws/aws-sdk-go/service/s3 
                6  | COPY . /work
                7  | WORKDIR /work
                8  | RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o main main.go
                9  | 
                10 | FROM python:3.7.6-stretch as release
                11 | RUN pip install boto3
                12 | COPY --from=build /work/main /usr/local/bin/main
                13 | COPY --from=build /work/main.py /usr/local/bin/main.py
                14 | WORKDIR /usr/local/bin/

```

## 修正してみる

せっかく修正提案をもらったのだから、実際に直してみよう。

```Dockerfile:Dockerfile
FROM golang:1.13.5-stretch as build
RUN go get \
 github.com/aws/aws-sdk-go/aws \
 github.com/aws/aws-sdk-go/aws/session \
 github.com/aws/aws-sdk-go/service/s3 
COPY . /work
WORKDIR /work
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o main main.go

FROM python:3.7.6-stretch as release
# 追加
RUN useradd -m myuser
USER myuser
RUN pip install boto3
COPY --from=build /work/main /usr/local/bin/main
COPY --from=build /work/main.py /usr/local/bin/main.py
WORKDIR /usr/local/bin/
# 追加
HEALTHCHECK --interval=30s --timeout=10s CMD curl --fail http://localhost:8080/health || exit 1.
```

おおっ、修正後はチェックが全部通ったぞ。適切なコメントを貰えていたようだ。

```bash
checkov -f Dockerfile --openai-api-key sk-xxxxxxxx
[ dockerfile framework ]: 100%|████████████████████|[1/1], Current File Scanned=Dockerfile
[ secrets framework ]: 100%|████████████████████|[1/1], Current File Scanned=Dockerfile

       _               _              
   ___| |__   ___  ___| | _______   __
  / __| '_ \ / _ \/ __| |/ / _ \ \ / /
 | (__| | | |  __/ (__|   < (_) \ V / 
  \___|_| |_|\___|\___|_|\_\___/ \_/  
                                      
By bridgecrew.io | version: 2.3.296 

dockerfile scan results:

Passed checks: 72, Failed checks: 0, Skipped checks: 0
```

### Dockerfile以外でも

Dockerfile以外でも動くことを確認したいので、CloudFormation/Terraformで試してみる。


<details><summary>CloudFormationのサンプル</summary>

Lambdaを作るだけ。

```yaml
AWSTemplateFormatVersion: '2010-09-09'
Resources:
  AppendItemToListFunction:
    Type: AWS::Lambda::Function
    Properties:
      Handler: index.handler
      Role: !GetAtt LambdaExecutionRole.Arn
      Code:
        ZipFile: !Sub |
          var response = require('cfn-response');
          exports.handler = function(event, context) {
             var responseData = {Value: event.ResourceProperties.List};
             responseData.Value.push(event.ResourceProperties.AppendedItem);
             response.send(event, context, response.SUCCESS, responseData);
          };
      Runtime: nodejs14.x
  LambdaExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
        - Effect: Allow
          Principal:
            Service:
            - lambda.amazonaws.com
          Action:
          - sts:AssumeRole
      Path: "/"
      Policies:
      - PolicyName: root
        PolicyDocument:
          Version: '2012-10-17'
          Statement:
          - Effect: Allow
            Action:
            - logs:*
            Resource: arn:aws:logs:*:*:*
```
</details>


<details><summary>CloudFormationのChatGPT回答(抜粋)</summary>

```bash
Check: CKV_AWS_116: "Ensure that AWS Lambda function is configured for a Dead Letter Queue(DLQ)"
	FAILED for resource: AWS::Lambda::Function.AppendItemToListFunction
	Details: The following text is AI generated and should be treated as a suggestion.
	         
	         The code provided is a CloudFormation template that creates an AWS Lambda function.
	         However, it does not configure a Dead Letter Queue (DLQ) for the Lambda function.
	         A DLQ is a queue that receives events that could not be processed by the Lambda function due to errors or other issues.
	         It is important to configure a DLQ for Lambda functions to ensure that any failed events are not lost and can be retried later.
	         
	         To fix this issue, you can add a DeadLetterConfig property to the Lambda function's Properties section, as shown below:
	         
	         AppendItemToListFunction:
	           Type: AWS::Lambda::Function
	           Properties:
	             Handler: index.handler
	             Role: !GetAtt LambdaExecutionRole.Arn
	             Code:
	               ZipFile: !Sub |
	                 var response = require('cfn-response');
	                 exports.handler = function(event, context) {
	                    var responseData = {Value: event.ResourceProperties.List};
	                    responseData.Value.push(event.ResourceProperties.AppendedItem);
	                    response.send(event, context, response.SUCCESS, responseData);
	                 };
	             Runtime: nodejs14.x
	             DeadLetterConfig:
	               TargetArn: !GetAtt MyDLQ.Arn
	         
	         In this example, the TargetArn property specifies the ARN of the DLQ that should receive failed events.
	         You will need to replace `MyDLQ` with the name of your actual DLQ resource.
	File: /test.yaml:3-16
	Guide: https://docs.paloaltonetworks.com/content/techdocs/en_US/prisma/prisma-cloud/prisma-cloud-code-security-policy-reference/aws-policies/aws-general-policies/ensure-that-aws-lambda-function-is-configured-for-a-dead-letter-queue-dlq.html

		3  |   AppendItemToListFunction:
		4  |     Type: AWS::Lambda::Function
		5  |     Properties:
		6  |       Handler: index.handler
		7  |       Role: !GetAtt LambdaExecutionRole.Arn
		8  |       Code:
		9  |         ZipFile: !Sub |
		10 |           var response = require('cfn-response');
		11 |           exports.handler = function(event, context) {
		12 |              var responseData = {Value: event.ResourceProperties.List};
		13 |              responseData.Value.push(event.ResourceProperties.AppendedItem);
		14 |              response.send(event, context, response.SUCCESS, responseData);
		15 |           };
		16 |       Runtime: nodejs14.x

Check: CKV_AWS_115: "Ensure that AWS Lambda function is configured for function-level concurrent execution limit"
	FAILED for resource: AWS::Lambda::Function.AppendItemToListFunction
	Details: The following text is AI generated and should be treated as a suggestion.
	         
	         The checkov policy 'Ensure that AWS Lambda function is configured for function-level concurrent execution limit' requires that AWS Lambda functions should be configured with a function-level concurrent execution limit to prevent excessive usage of resources and potential performance issues.
	         
	         The provided code does not include any configuration for function-level concurrent execution limit.
	         To fix this, you can add the `ReservedConcurrentExecutions` property to the `Properties` section of the AWS::Lambda::Function resource.
	         
	         For example, to set a limit of 100 concurrent executions, you can add the following line to the `Properties` section:
	         
	         ReservedConcurrentExecutions: 100
	         
	         The updated code would look like this:
	         
	         AppendItemToListFunction:
	           Type: AWS::Lambda::Function
	           Properties:
	             Handler: index.handler
	             Role: !GetAtt LambdaExecutionRole.Arn
	             Code:
	               ZipFile: !Sub |
	                 var response = require('cfn-response');
	                 exports.handler = function(event, context) {
	                    var responseData = {Value: event.ResourceProperties.List};
	                    responseData.Value.push(event.ResourceProperties.AppendedItem);
	                    response.send(event, context, response.SUCCESS, responseData);
	                 };
	             Runtime: nodejs14.x
	             ReservedConcurrentExecutions: 100
	File: /test.yaml:3-16
	Guide: https://docs.paloaltonetworks.com/content/techdocs/en_US/prisma/prisma-cloud/prisma-cloud-code-security-policy-reference/aws-policies/aws-general-policies/ensure-that-aws-lambda-function-is-configured-for-function-level-concurrent-execution-limit.html

		3  |   AppendItemToListFunction:
		4  |     Type: AWS::Lambda::Function
		5  |     Properties:
		6  |       Handler: index.handler
		7  |       Role: !GetAtt LambdaExecutionRole.Arn
		8  |       Code:
		9  |         ZipFile: !Sub |
		10 |           var response = require('cfn-response');
		11 |           exports.handler = function(event, context) {
		12 |              var responseData = {Value: event.ResourceProperties.List};
		13 |              responseData.Value.push(event.ResourceProperties.AppendedItem);
		14 |              response.send(event, context, response.SUCCESS, responseData);
		15 |           };
		16 |       Runtime: nodejs14.x

Check: CKV_AWS_117: "Ensure that AWS Lambda function is configured inside a VPC"
	FAILED for resource: AWS::Lambda::Function.AppendItemToListFunction
	Details: The following text is AI generated and should be treated as a suggestion.
	         
	         The given CloudFormation code creates an AWS Lambda function named "AppendItemToListFunction".
	         However, it does not specify any VPC configuration for the Lambda function.
	         This means that the Lambda function will run outside of any VPC, which can pose a security risk as it will have access to the internet and other AWS resources that are not necessarily intended to be accessed by the function.
	         
	         To fix this, we need to add the VpcConfig property to the Lambda function's Properties section.
	         The VpcConfig property specifies the VPC and subnets that the Lambda function should be deployed in.
	         Here's an updated version of the code that includes the VpcConfig property:
	         
	         AppendItemToListFunction:
	           Type: AWS::Lambda::Function
	           Properties:
	             Handler: index.handler
	             Role: !GetAtt LambdaExecutionRole.Arn
	             Code:
	               ZipFile: !Sub |
	                 var response = require('cfn-response');
	                 exports.handler = function(event, context) {
	                    var responseData = {Value: event.ResourceProperties.List};
	                    responseData.Value.push(event.ResourceProperties.AppendedItem);
	                    response.send(event, context, response.SUCCESS, responseData);
	                 };
	             Runtime: nodejs14.x
	             VpcConfig:
	               SecurityGroupIds:
	                 - sg-0123456789abcdef
	               SubnetIds:
	                 - subnet-0123456789abcdef
	                 - subnet-0123456789abcdee
	         
	         In this example, we have specified a VPC with two subnets and a security group.
	         You will need to replace the subnet and security group IDs with the ones that you want to use.
	File: /test.yaml:3-16
	Guide: https://docs.paloaltonetworks.com/content/techdocs/en_US/prisma/prisma-cloud/prisma-cloud-code-security-policy-reference/aws-policies/aws-general-policies/ensure-that-aws-lambda-function-is-configured-inside-a-vpc-1.html

		3  |   AppendItemToListFunction:
		4  |     Type: AWS::Lambda::Function
		5  |     Properties:
		6  |       Handler: index.handler
		7  |       Role: !GetAtt LambdaExecutionRole.Arn
		8  |       Code:
		9  |         ZipFile: !Sub |
		10 |           var response = require('cfn-response');
		11 |           exports.handler = function(event, context) {
		12 |              var responseData = {Value: event.ResourceProperties.List};
		13 |              responseData.Value.push(event.ResourceProperties.AppendedItem);
		14 |              response.send(event, context, response.SUCCESS, responseData);
		15 |           };
		16 |       Runtime: nodejs14.x
```

</details>

<details><summary>Terraformのサンプル</summary>

CloudFormationを元にChatGPTから作ってもらった。※Inlineあたりがちょっと変なのはご愛敬

```hcl
provider "aws" {
  region = "ap-northeast-1" 
}

resource "aws_iam_role" "lambda_execution_role" {
  name               = "LambdaExecutionRole"
  assume_role_policy = jsonencode({
    Version = "2012-10-17",
    Statement = [
      {
        Effect    = "Allow",
        Action    = "sts:AssumeRole",
        Principal = {
          Service = "lambda.amazonaws.com"
        }
      }
    ]
  })
  path = "/"
}

resource "aws_iam_role_policy" "lambda_execution_policy" {
  name   = "LambdaExecutionPolicy"
  role   = aws_iam_role.lambda_execution_role.id
  policy = jsonencode({
    Version = "2012-10-17",
    Statement = [
      {
        Effect   = "Allow",
        Action   = "logs:*",
        Resource = "arn:aws:logs:*:*:*"
      }
    ]
  })
}

resource "aws_lambda_function" "append_item_to_list" {
  function_name = "AppendItemToListFunction"

  handler = "index.handler"
  role    = aws_iam_role.lambda_execution_role.arn

  runtime = "nodejs14.x"

  inline_code = <<-EOF
    var response = require('cfn-response');
    exports.handler = function(event, context) {
      var responseData = {Value: event.ResourceProperties.List};
      responseData.Value.push(event.ResourceProperties.AppendedItem);
      response.send(event, context, response.SUCCESS, responseData);
    };
  EOF
}

output "lambda_function_arn" {
  value = aws_lambda_function.append_item_to_list.arn
}
```
</details>


<details><summary>TerraformのChatGPT回答(抜粋)</summary>

```bash
Check: CKV_AWS_272: "Ensure AWS Lambda function is configured to validate code-signing"
	FAILED for resource: aws_lambda_function.append_item_to_list
	Details: The following text is AI generated and should be treated as a suggestion.
	         
	         The given code creates an AWS Lambda function named "AppendItemToListFunction" using Terraform.
	         The function is written in Node.js and takes an input event, appends a new item to a list, and returns the updated list as a response.
	         
	         However, the code violates the Checkov policy "Ensure AWS Lambda function is configured to validate code-signing".
	         This policy requires that the Lambda function is configured to validate code-signing to ensure that only authorized code is executed.
	         
	         To fix this, we need to add the code-signing configuration to the Lambda function.
	         Code-signing allows you to verify the integrity of the code running in your Lambda function and ensure that it has not been tampered with.
	         
	         Here's an updated version of the code that includes code-signing configuration:
	         
	         resource "aws_lambda_function" "append_item_to_list" {
	           function_name = "AppendItemToListFunction"
	         
	           handler = "index.handler"
	           role    = aws_iam_role.lambda_execution_role.arn
	         
	           runtime = "nodejs14.x"
	         
	           inline_code = <<-EOF
	             var response = require('cfn-response');
	             exports.handler = function(event, context) {
	               var responseData = {Value: event.ResourceProperties.List};
	               responseData.Value.push(event.ResourceProperties.AppendedItem);
	               response.send(event, context, response.SUCCESS, responseData);
	             };
	           EOF
	         
	           source_code_hash = base64sha256(filebase64sha256("${path.module}/index.js"))
	           
	           environment {
	             variables = {
	               AWS_LAMBDA_EXECUTOR = "arn:aws:lambda:us-east-1:123456789012:executor:sha256:1234567890abcdef"
	             }
	           }
	           
	           tracing_config {
	             mode = "Active"
	           }
	           
	           vpc_config {
	             subnet_ids = ["subnet-12345678"]
	             security_group_ids = ["sg-12345678"]
	           }
	           
	           filesystem_config {
	             destination_path = "/mnt/data"
	             source_path = "/mnt/data"
	             mode = "rw"
	           }
	           
	           code_signing_config_arn = aws_lambda_code_signing_config.example.arn
	         }
	         
	         resource "aws_lambda_code_signing_config" "example" {
	           description = "Example code signing configuration"
	           
	           allowed_publishers {
	             signing_profile_version_arn = "arn:aws:signer:us-east-1:123456789012:signing-profiles/example-profile/12345678-1234-1234-123
	File: /test.hcl:37-53

		37 | resource "aws_lambda_function" "append_item_to_list" {
		38 |   function_name = "AppendItemToListFunction"
		39 | 
		40 |   handler = "index.handler"
		41 |   role    = aws_iam_role.lambda_execution_role.arn
		42 | 
		43 |   runtime = "nodejs14.x"
		44 | 
		45 |   inline_code = <<-EOF
		46 |     var response = require('cfn-response');
		47 |     exports.handler = function(event, context) {
		48 |       var responseData = {Value: event.ResourceProperties.List};
		49 |       responseData.Value.push(event.ResourceProperties.AppendedItem);
		50 |       response.send(event, context, response.SUCCESS, responseData);
		51 |     };
		52 |   EOF
		53 | }

Check: CKV_AWS_116: "Ensure that AWS Lambda function is configured for a Dead Letter Queue(DLQ)"
	FAILED for resource: aws_lambda_function.append_item_to_list
	Details: The following text is AI generated and should be treated as a suggestion.
	         
	         The code provided creates an AWS Lambda function without configuring a Dead Letter Queue (DLQ).
	         A DLQ is a queue that receives messages from a source queue or subscription when any of the following events occur:
	         
	         - The message is not successfully processed by a consumer.
	         - The message is not consumed within the visibility timeout period.
	         
	         By configuring a DLQ, you can ensure that messages are not lost and can be processed later.
	         
	         To fix the code, you need to add a `dead_letter_config` block to the `aws_lambda_function` resource.
	         Here's an example:
	         
	         resource "aws_lambda_function" "append_item_to_list" {
	           function_name = "AppendItemToListFunction"
	         
	           handler = "index.handler"
	           role    = aws_iam_role.lambda_execution_role.arn
	         
	           runtime = "nodejs14.x"
	         
	           inline_code = <<-EOF
	             var response = require('cfn-response');
	             exports.handler = function(event, context) {
	               var responseData = {Value: event.ResourceProperties.List};
	               responseData.Value.push(event.ResourceProperties.AppendedItem);
	               response.send(event, context, response.SUCCESS, responseData);
	             };
	           EOF
	         
	           dead_letter_config {
	             target_arn = aws_sqs_queue.dlq.arn
	           }
	         }
	         
	         In this example, we added a `dead_letter_config` block that specifies the ARN of an SQS queue that will serve as the DLQ.
	         You will need to replace `aws_sqs_queue.dlq.arn` with the ARN of your own DLQ.
	File: /test.hcl:37-53
	Guide: https://docs.paloaltonetworks.com/content/techdocs/en_US/prisma/prisma-cloud/prisma-cloud-code-security-policy-reference/aws-policies/aws-general-policies/ensure-that-aws-lambda-function-is-configured-for-a-dead-letter-queue-dlq.html

		37 | resource "aws_lambda_function" "append_item_to_list" {
		38 |   function_name = "AppendItemToListFunction"
		39 | 
		40 |   handler = "index.handler"
		41 |   role    = aws_iam_role.lambda_execution_role.arn
		42 | 
		43 |   runtime = "nodejs14.x"
		44 | 
		45 |   inline_code = <<-EOF
		46 |     var response = require('cfn-response');
		47 |     exports.handler = function(event, context) {
		48 |       var responseData = {Value: event.ResourceProperties.List};
		49 |       responseData.Value.push(event.ResourceProperties.AppendedItem);
		50 |       response.send(event, context, response.SUCCESS, responseData);
		51 |     };
		52 |   EOF
		53 | }

Check: CKV_AWS_115: "Ensure that AWS Lambda function is configured for function-level concurrent execution limit"
	FAILED for resource: aws_lambda_function.append_item_to_list
	Details: The following text is AI generated and should be treated as a suggestion.
	         
	         The AWS Lambda function in the code snippet does not have a function-level concurrent execution limit set.
	         This means that multiple invocations of the function can run concurrently, which can lead to resource contention and potential performance issues.
	         
	         To fix this, we need to add a `reserved_concurrent_executions` parameter to the `aws_lambda_function` resource block.
	         This parameter sets a limit on the number of concurrent executions of the function.
	         
	         For example, we can set the limit to 10 concurrent executions by adding the following line to the resource block:
	         
	         reserved_concurrent_executions = 10
	         
	         This will ensure that the Lambda function is configured for function-level concurrent execution limit and will limit the number of concurrent executions to 10.
	File: /test.hcl:37-53
	Guide: https://docs.paloaltonetworks.com/content/techdocs/en_US/prisma/prisma-cloud/prisma-cloud-code-security-policy-reference/aws-policies/aws-general-policies/ensure-that-aws-lambda-function-is-configured-for-function-level-concurrent-execution-limit.html

		37 | resource "aws_lambda_function" "append_item_to_list" {
		38 |   function_name = "AppendItemToListFunction"
		39 | 
		40 |   handler = "index.handler"
		41 |   role    = aws_iam_role.lambda_execution_role.arn
		42 | 
		43 |   runtime = "nodejs14.x"
		44 | 
		45 |   inline_code = <<-EOF
		46 |     var response = require('cfn-response');
		47 |     exports.handler = function(event, context) {
		48 |       var responseData = {Value: event.ResourceProperties.List};
		49 |       responseData.Value.push(event.ResourceProperties.AppendedItem);
		50 |       response.send(event, context, response.SUCCESS, responseData);
		51 |     };
		52 |   EOF
		53 | }

Check: CKV_AWS_117: "Ensure that AWS Lambda function is configured inside a VPC"
	FAILED for resource: aws_lambda_function.append_item_to_list
	Details: The following text is AI generated and should be treated as a suggestion.
	         
	         The given code creates an AWS Lambda function without configuring it inside a VPC.
	         This means that the Lambda function will not have access to resources inside a VPC, such as databases or other services that are not publicly accessible.
	         This can be a security risk as it may expose sensitive data to the public internet.
	         
	         To fix this, we need to configure the Lambda function inside a VPC.
	         We can do this by adding a `vpc_config` block to the `aws_lambda_function` resource.
	         This block specifies the VPC and subnets that the Lambda function should be deployed in.
	         
	         We also need to ensure that the VPC has the necessary security groups and network ACLs configured to allow the Lambda function to access the resources it needs.
	         
	         Once the VPC configuration is added, we can run the Checkov policy again to ensure that the Lambda function is now compliant with the policy.
	File: /test.hcl:37-53
	Guide: https://docs.paloaltonetworks.com/content/techdocs/en_US/prisma/prisma-cloud/prisma-cloud-code-security-policy-reference/aws-policies/aws-general-policies/ensure-that-aws-lambda-function-is-configured-inside-a-vpc-1.html

		37 | resource "aws_lambda_function" "append_item_to_list" {
		38 |   function_name = "AppendItemToListFunction"
		39 | 
		40 |   handler = "index.handler"
		41 |   role    = aws_iam_role.lambda_execution_role.arn
		42 | 
		43 |   runtime = "nodejs14.x"
		44 | 
		45 |   inline_code = <<-EOF
		46 |     var response = require('cfn-response');
		47 |     exports.handler = function(event, context) {
		48 |       var responseData = {Value: event.ResourceProperties.List};
		49 |       responseData.Value.push(event.ResourceProperties.AppendedItem);
		50 |       response.send(event, context, response.SUCCESS, responseData);
		51 |     };
		52 |   EOF
		53 | }

Check: CKV_AWS_50: "X-ray tracing is enabled for Lambda"
	FAILED for resource: aws_lambda_function.append_item_to_list
	Details: The following text is AI generated and should be treated as a suggestion.
	         
	         The issue with the code is that it enables X-ray tracing for the Lambda function, which violates the Checkov policy.
	         X-ray tracing is a feature that allows you to trace requests made to your application and identify performance issues.
	         However, it can also be a security risk as it can expose sensitive information about your application.
	         
	         To fix this issue, you can disable X-ray tracing for the Lambda function by adding the following configuration block to the resource:
	         
	         tracing_config {
	           mode = "PassThrough"
	         }
	         
	         This will set the tracing mode to "PassThrough", which means that X-ray tracing will be disabled for the Lambda function.
	         The updated code will look like this:
	         
	         resource "aws_lambda_function" "append_item_to_list" {
	           function_name = "AppendItemToListFunction"
	         
	           handler = "index.handler"
	           role    = aws_iam_role.lambda_execution_role.arn
	         
	           runtime = "nodejs14.x"
	         
	           tracing_config {
	             mode = "PassThrough"
	           }
	         
	           inline_code = <<-EOF
	             var response = require('cfn-response');
	             exports.handler = function(event, context) {
	               var responseData = {Value: event.ResourceProperties.List};
	               responseData.Value.push(event.ResourceProperties.AppendedItem);
	               response.send(event, context, response.SUCCESS, responseData);
	             };
	           EOF
	         }
	         
	         This will ensure that X-ray tracing is disabled for the Lambda function and will comply with the Checkov policy.
	File: /test.hcl:37-53
	Guide: https://docs.paloaltonetworks.com/content/techdocs/en_US/prisma/prisma-cloud/prisma-cloud-code-security-policy-reference/aws-policies/aws-serverless-policies/bc-aws-serverless-4.html

		37 | resource "aws_lambda_function" "append_item_to_list" {
		38 |   function_name = "AppendItemToListFunction"
		39 | 
		40 |   handler = "index.handler"
		41 |   role    = aws_iam_role.lambda_execution_role.arn
		42 | 
		43 |   runtime = "nodejs14.x"
		44 | 
		45 |   inline_code = <<-EOF
		46 |     var response = require('cfn-response');
		47 |     exports.handler = function(event, context) {
		48 |       var responseData = {Value: event.ResourceProperties.List};
		49 |       responseData.Value.push(event.ResourceProperties.AppendedItem);
		50 |       response.send(event, context, response.SUCCESS, responseData);
		51 |     };
		52 |   EOF
		53 | }

```
</details>


### CheckovはOpenAI-APIをどう使ってる？

Release Noteを見ると、OpenAI Integrationはv2.3.140から利用できることがわかる。


https://github.com/bridgecrewio/checkov/releases/tag/2.3.140

具体的には、以下のPull Requestで導入された模様。

https://github.com/bridgecrewio/checkov/pull/4782

おそらくメインの処理は[このコード](https://github.com/bridgecrewio/checkov/blob/main/checkov/common/output/ai.py
)で実施されていそう。GitHubのコードを埋め込めなさそうなのでコードを転記してみた。
```python:checkov/blob/main/checkov/common/output/ai.py 抜粋
    async def _chat_complete(self, record: Record) -> None:
        if not record.code_block:
            # no need to ask OpenAI about guidelines, if we have no code blocks
            return

        completion = await openai.ChatCompletion.acreate(  # type:ignore[no-untyped-call]
            model=OPENAI_MODEL,
            messages=[
                {"role": "system", "content": "You are a security tool"},
                {
                    "role": "user",
                    "content": "".join(
                        [
                            f"fix following code, which violates checkov policy '{record.check_name}':\n",
                            *[line for _, line in record.code_block],
                        ]
                    ),
                },
                {"role": "user", "content": "Explain"},
            ],
            temperature=0,
            max_tokens=OPENAI_MAX_TOKENS,
        )
        logging.info(f"OpenAI request consumed {completion.usage.total_tokens} tokens")
```

CheckovのチェックでNGになったIaCテンプレートのコードブロックを、openaiのライブラリでAPIに渡して問い合わせている様子がわかる。

ChatGPTの規約上、APIからの学習は行わないと明言されているが、テンプレートの性質によっては気を付けたい。

> OpenAI will not use data submitted by customers via our API to train or improve our models, unless you explicitly decide to share your data with us for this purpose. You can opt-in to share data.

https://openai.com/policies/api-data-usage-policies



## まとめ

ということで、静的解析ツールをかけた時によくある「で、結局どうすればいいの？」を、CheckovのOpenAI連携オプションで解決できそうなことがわかりました。IaCテンプレートを高速で開発しながら、品質を高めるのに良い機能ですね。