[
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "content": "---\nname: Bug report\nabout: Tell us about a problem you are experiencing\n---\n\n**Overview**\n\n[A clear and concise description of what the bug is] \n\n**How did you run kube-bench?**\n\n[Please specify exactly how you ran kube-bench, including details of command parameters and/or job file that you used to run it]\n\n**What happened?**\n\n[Please include output from the report to illustrate the problem. If possible please supply logs generated with the `-v 3` parameter.]\n\n**What did you expect to happen:**\n\n[Please describe what you expected to happen differently.]\n\n**Environment** \n\n[What is your version of kube-bench? (run `kube-bench version`)]\n\n[What is your version of Kubernetes? (run `kubectl version` or `oc version` on OpenShift.)]\n\n**Running processes**\n\n[Please include the output from running `ps -eaf | grep kube` on the affected node. This will allow us to check what Kubernetes processes are running, and how this compares to what kube-bench detected.]\n\n**Configuration files**\n\n[If kube-bench is reporting an issue related to the settings defined in a config file, please attach the file, or include an extract showing the settings that are being detected incorrectly.]\n\n**Anything else you would like to add:**\n\n[Miscellaneous information that will assist in solving the issue.]\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/config.yml",
    "content": "---\nblank_issues_enabled: false\ncontact_links:\n  - name: Feature request\n    url: https://github.com/aquasecurity/kube-bench/discussions/new?category_id=19113743\n    about: Share ideas for new features\n  - name: Ask a question\n    url: https://github.com/aquasecurity/kube-bench/discussions/new?category_id=19113742\n    about: Ask questions and discuss with other community members\n"
  },
  {
    "path": ".github/dependabot.yml",
    "content": "---\nversion: 2\nupdates:\n  - package-ecosystem: gomod\n    directory: /\n    schedule:\n      interval: weekly\n  - package-ecosystem: github-actions\n    directory: /\n    schedule:\n      interval: weekly\n  - package-ecosystem: docker\n    directory: /\n    schedule:\n      interval: weekly\n"
  },
  {
    "path": ".github/workflows/build.yml",
    "content": "---\nname: Build\non:\n  push:\n    branches:\n      - main\n    paths-ignore:\n      - \"*.md\"\n      - \"LICENSE\"\n      - \"NOTICE\"\n  pull_request:\n    paths-ignore:\n      - \"*.md\"\n      - \"LICENSE\"\n      - \"NOTICE\"\nenv:\n  KIND_VERSION: \"v0.11.1\"\n  KIND_IMAGE: \"kindest/node:v1.21.1@sha256:69860bda5563ac81e3c0057d654b5253219618a22ec3a346306239bba8cfa1a6\"\n\njobs:\n  lint:\n    name: Lint\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v6\n      - name: Setup Go\n        uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0\n        with:\n          go-version-file: go.mod\n      - name: yaml-lint\n        uses: ibiqlik/action-yamllint@v3\n      - name: Setup golangci-lint\n        uses: golangci/golangci-lint-action@v8\n        with:\n          version: v2.5.0\n          args: --verbose --timeout 2m\n  unit:\n    name: Unit tests\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v6\n      - name: Setup Go\n        uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0\n        with:\n          go-version-file: go.mod\n      - name: Run unit tests\n        run: make tests\n      - name: Upload code coverage\n        uses: codecov/codecov-action@v5\n        with:\n          file: ./coverage.txt\n  e2e:\n    name: E2e tests\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v6\n      - name: Setup Go\n        uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0\n        with:\n          go-version-file: go.mod\n      - name: Setup Kubernetes cluster (KIND)\n        uses: engineerd/setup-kind@v0.6.2\n        with:\n          version: ${{ env.KIND_VERSION }}\n          image: ${{ env.KIND_IMAGE }}\n          name: kube-bench\n      - name: Test connection to Kubernetes cluster\n        run: |\n          kubectl cluster-info\n          kubectl describe node\n      - name: Run integration tests\n        run: |\n          make integration-test\n      - name: Compare output with expected output\n        uses: GuillaumeFalourd/diff-action@v1\n        with:\n          first_file_path: ./test.data\n          second_file_path: integration/testdata/Expected_output.data\n          expected_result: PASSED\n  release:\n    name: Release snapshot\n    runs-on: ubuntu-latest\n    needs: [e2e, unit]\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v6\n        with:\n          fetch-depth: 0\n      - name: Setup Go\n        uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0\n        with:\n          go-version-file: go.mod\n      - name: Dry-run release snapshot\n        uses: goreleaser/goreleaser-action@v7\n        with:\n          distribution: goreleaser\n          version: v1.7.0\n          args: release --snapshot --skip-publish --rm-dist\n"
  },
  {
    "path": ".github/workflows/mkdocs-deploy.yaml",
    "content": "---\n# This is a manually triggered workflow to build and publish the MkDocs from the\n# main branch to GitHub pages at https://aquasecurity.github.io/kube-bench.\nname: Deploy documentation\n\non:\n  workflow_dispatch:\n    inputs:\n      version:\n        description: Version to be deployed\n        required: true\n\njobs:\n  deploy:\n    name: Deploy documentation\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout main\n        uses: actions/checkout@v6\n        with:\n          fetch-depth: 0\n          persist-credentials: true\n      - uses: actions/setup-python@v6\n        with:\n          python-version: 3.x\n      - run: |\n          pip install git+https://${GH_TOKEN}@github.com/squidfunk/mkdocs-material-insiders.git\n          pip install mike\n          pip install mkdocs-macros-plugin\n        env:\n          # Note: It is not the same as ${{ secrets.GITHUB_TOKEN }} !\n          GH_TOKEN: ${{ secrets.MKDOCS_AQUA_BOT }}\n      - run: |\n          git config user.name \"aqua-bot\"\n          git config user.email \"aqua-bot@users.noreply.github.com\"\n      - run: |\n          mike deploy --push --update-aliases ${{ github.event.inputs.version }} latest\n"
  },
  {
    "path": ".github/workflows/publish.yml",
    "content": "---\nname: Publish\non:\n  workflow_dispatch:\n  push:\n    tags:\n      - \"v*\"\nenv:\n  ALIAS: aquasecurity\n  DOCKERHUB_ALIAS: aquasec\n  REP: kube-bench\n\njobs:\n  publish:\n    name: Publish\n    runs-on: ubuntu-latest\n    steps:\n      - name: Check Out Repo\n        uses: actions/checkout@v6\n      - name: Set up QEMU\n        uses: docker/setup-qemu-action@v4\n      - name: Set up Docker Buildx\n        id: buildx\n        uses: docker/setup-buildx-action@v4\n      - name: Cache Docker layers\n        uses: actions/cache@v5\n        with:\n          path: /tmp/.buildx-cache\n          key: ${{ runner.os }}-buildxarch-${{ github.sha }}\n          restore-keys: |\n            ${{ runner.os }}-buildxarch-\n      - name: Login to Docker Hub\n        uses: docker/login-action@v4\n        with:\n          username: ${{ secrets.DOCKERHUB_USER }}\n          password: ${{ secrets.DOCKERHUB_TOKEN }}\n      - name: Login to ECR\n        uses: docker/login-action@v4\n        with:\n          registry: public.ecr.aws\n          username: ${{ secrets.ECR_ACCESS_KEY_ID }}\n          password: ${{ secrets.ECR_SECRET_ACCESS_KEY }}\n      - name: Get version\n        id: get_version\n        uses: crazy-max/ghaction-docker-meta@v5\n        with:\n          images: ${{ env.REP }}\n          tag-semver: |\n            {{version}}\n      - name: Extract variables from makefile (kubectl)\n        id: extract_vars\n        run: |\n          echo \"KUBECTL_VERSION=$(grep -oP '^KUBECTL_VERSION\\s*\\?=\\s*\\K.*' makefile)\" >> $GITHUB_ENV\n      - name: Build and push - Docker/ECR\n        id: docker_build\n        uses: docker/build-push-action@v7\n        with:\n          context: .\n          platforms: linux/amd64,linux/arm64,linux/ppc64le,linux/s390x\n          builder: ${{ steps.buildx.outputs.name }}\n          push: true\n          build-args: |\n            KUBEBENCH_VERSION=${{ steps.get_version.outputs.version }}\n            KUBECTL_VERSION=${{ env.KUBECTL_VERSION }}\n          tags: |\n            ${{ env.DOCKERHUB_ALIAS }}/${{ env.REP }}:${{ steps.get_version.outputs.version }}\n            public.ecr.aws/${{ env.ALIAS }}/${{ env.REP }}:${{ steps.get_version.outputs.version }}\n            ${{ env.DOCKERHUB_ALIAS }}/${{ env.REP }}:latest\n            public.ecr.aws/${{ env.ALIAS }}/${{ env.REP }}:latest\n          cache-from: type=local,src=/tmp/.buildx-cache/release\n          cache-to: type=local,mode=max,dest=/tmp/.buildx-cache/release\n\n      - name: Build and push ubi image - Docker/ECR\n        id: docker_build_ubi\n        uses: docker/build-push-action@v7\n        with:\n          context: .\n          platforms: linux/amd64,linux/arm64,linux/ppc64le,linux/s390x\n          builder: ${{ steps.buildx.outputs.name }}\n          push: true\n          file: Dockerfile.ubi\n          build-args: |\n            KUBEBENCH_VERSION=${{ steps.get_version.outputs.version }}\n            KUBECTL_VERSION=${{ env.KUBECTL_VERSION }}\n          tags: |\n            ${{ env.DOCKERHUB_ALIAS }}/${{ env.REP }}:${{ steps.get_version.outputs.version }}-ubi\n            public.ecr.aws/${{ env.ALIAS }}/${{ env.REP }}:${{ steps.get_version.outputs.version }}-ubi\n          cache-from: type=local,src=/tmp/.buildx-cache/release\n          cache-to: type=local,mode=max,dest=/tmp/.buildx-cache/release\n      - name: Image digest\n        run: echo ${{ steps.docker_build.outputs.digest }}\n\n      - name: Build and push fips ubi image - Docker/ECR\n        id: docker_build_fips_ubi\n        uses: docker/build-push-action@v7\n        with:\n          context: .\n          platforms: linux/amd64,linux/arm64,linux/ppc64le,linux/s390x\n          builder: ${{ steps.buildx.outputs.name }}\n          push: true\n          file: Dockerfile.fips.ubi\n          build-args: |\n            KUBEBENCH_VERSION=${{ steps.get_version.outputs.version }}\n            KUBECTL_VERSION=${{ env.KUBECTL_VERSION }}\n          tags: |\n            ${{ env.DOCKERHUB_ALIAS }}/${{ env.REP }}:${{ steps.get_version.outputs.version }}-ubi-fips\n            public.ecr.aws/${{ env.ALIAS }}/${{ env.REP }}:${{ steps.get_version.outputs.version }}-ubi-fips\n          cache-from: type=local,src=/tmp/.buildx-cache/release\n          cache-to: type=local,mode=max,dest=/tmp/.buildx-cache/release\n      - name: Image digest\n        run: echo ${{ steps.docker_build.outputs.digest }}\n"
  },
  {
    "path": ".github/workflows/release.yml",
    "content": "---\nname: Release\non:\n  push:\n    tags:\n      - \"v*\"\nenv:\n  KIND_VERSION: \"v0.11.1\"\n  KIND_IMAGE: \"kindest/node:v1.21.1@sha256:69860bda5563ac81e3c0057d654b5253219618a22ec3a346306239bba8cfa1a6\"\n\njobs:\n  release:\n    name: Release\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v6\n        with:\n          fetch-depth: 0\n      - name: Setup Go\n        uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0\n        with:\n          go-version-file: go.mod\n      - name: Run unit tests\n        run: make tests\n      - name: Setup Kubernetes cluster (KIND)\n        uses: engineerd/setup-kind@v0.6.2\n        with:\n          version: ${{ env.KIND_VERSION }}\n          image: ${{ env.KIND_IMAGE }}\n          name: kube-bench\n      - name: Test connection to Kubernetes cluster\n        run: |\n          kubectl cluster-info\n          kubectl describe node\n      - name: Run integration tests\n        run: |\n          make integration-test\n      - name: Compare output with expected output\n        uses: GuillaumeFalourd/diff-action@v1\n        with:\n          first_file_path: ./test.data\n          second_file_path: integration/testdata/Expected_output.data\n          expected_result: PASSED\n      - name: Release\n        uses: goreleaser/goreleaser-action@v7\n        with:\n          distribution: goreleaser\n          version: v1.7.0\n          args: release --rm-dist\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n"
  },
  {
    "path": ".gitignore",
    "content": "kube-bench\n*.swp\nvendor\ndist\n.vscode/\nhack/kind.test.yaml\ncoverage.txt\n\n.idea/\n\n# Directory junk file\n.DS_Store\nthumbs.db\n/kubeconfig.kube-bench\n/test.data\n*.iml"
  },
  {
    "path": ".golangci.yaml",
    "content": "version: \"2\"\nlinters:\n  default: none\n  enable:\n    - gocyclo\n    - govet\n    - misspell\n  exclusions:\n    generated: lax\n    presets:\n      - comments\n      - common-false-positives\n      - legacy\n      - std-error-handling\n    paths:\n      - third_party$\n      - builtin$\n      - examples$\nformatters:\n  enable:\n    - gofmt\n    - goimports\n  exclusions:\n    generated: lax\n    paths:\n      - third_party$\n      - builtin$\n      - examples$\n"
  },
  {
    "path": ".goreleaser.yml",
    "content": "---\nproject_name: kube-bench\nenv:\n  - GO111MODULE=on\n  - CGO_ENABLED=0\n  - KUBEBENCH_CFG=/etc/kube-bench/cfg\nbuilds:\n  - main: .\n    binary: kube-bench\n    tags:\n      - osusergo\n      - netgo\n      - static_build\n    goos:\n      - linux\n      - darwin\n    goarch:\n      - amd64\n      - arm\n      - arm64\n      - ppc64le\n      - s390x\n    goarm:\n      - 6\n      - 7\n    ldflags:\n      - \"-s\"\n      - \"-w\"\n      - \"-extldflags '-static'\"\n      - \"-X github.com/aquasecurity/kube-bench/cmd.KubeBenchVersion={{.Version}}\"\n      - \"-X github.com/aquasecurity/kube-bench/cmd.cfgDir={{.Env.KUBEBENCH_CFG}}\"\n# Archive customization\narchives:\n  - id: default\n    format: tar.gz\n    name_template: '{{ .Binary }}_{{.Version}}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{.Arm }}{{ end }}'\n    files:\n      - \"cfg/**/*\"\n      - \"cfg/config.yaml\"\nnfpms:\n  -\n    vendor: Aqua Security\n    description: \"The Kubernetes Bench for Security is a Go application that checks whether Kubernetes is deployed according to security best practices\"\n    maintainer: Yoav Rotem <yoav.rotem@aquasec.com>\n    license: Apache-2.0\n    homepage: https://github.com/aquasecurity/kube-bench\n    file_name_template: '{{ .Binary }}_{{.Version}}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{.Arm }}{{ end }}'\n    contents:\n      - src: \"cfg/**/*\"\n        dst: \"/etc/kube-bench/cfg\"\n      - src: \"cfg/config.yaml\"\n        dst: \"/etc/kube-bench/cfg/config.yaml\"\n    formats:\n      - deb\n      - rpm\nchangelog:\n  sort: asc\n  filters:\n    exclude:\n      - '^docs'\n      - '^test'\n      - '^release'\n"
  },
  {
    "path": ".yamllint.yaml",
    "content": "---\nextends: default\n\nrules:\n  line-length: disable\n  truthy: disable\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "Thank you for taking an interest in contributing to kube-bench !\n\n## Contributing, bug reporting, openning issues and starting discussions\n\n### Issues\n\n- Feel free to open an issue for any reason as long as you make it clear if the issue is about a bug/feature/question/comment.\n- Please spend some time giving due diligence to the issue tracker. Your issue might be a duplicate. If it is, please add your comment to the existing issue.\n- Remember, users might be searching for your issue in the future. So please give it a meaningful title to help others.\n- The issue should clearly explain the reason for opening the proposal if you have any, along with any relevant technical information.\n- For questions and bug reports, please include the following information:\n  - version of kube-bench you are running (from kube-bench version) along with the command line options you are using.\n  - version of Kubernetes you are running (from kubectl version or oc version for Openshift).\n  - Verbose log output, by setting the `-v 3` command line option.\n\n### Bugs\n\nIf you think you have found a bug please follow the instructions below.\n\n- Open a [new bug](https://github.com/aquasecurity/kube-bench/issues/new?assignees=&labels=&template=bug_report.md) if a duplicate doesn't already exist.\n- Make sure to give as much information as possible in the following questions\n  - Overview\n  - How did you run kube-bench?\n  - What happened?\n  - What did you expect to happen\n  - Environment\n  - Running processes\n  - Configuration files\n  - Anything else you would like to add\n- Set `-v 3` command line option and save the log output. Please paste this into your issue.\n\n\n### Features\n\nWe also use the GitHub discussions to track feature requests. If you have an idea to make kube-bench even more awesome follow the steps below.\n\n- Open a [new discussion](https://github.com/aquasecurity/kube-bench/discussions/new?category_id=19113743) if a duplicate doesn't already exist.\n- Remember users might be searching for your discussion in the future, so please give it a meaningful title to helps others.\n- Clearly define the use case, using concrete examples. For example, I type `this` and kube-bench does `that`.\n- If you would like to include a technical design for your feature please feel free to do so.\n\n### Questions\n\nWe also use the GitHub discussions to Q&A.\n\n- Open a [new discussion](https://github.com/aquasecurity/kube-bench/discussions/new) if a duplicate doesn't already exist.\n- Remember users might be searching for your discussion in the future, so please give it a meaningful title to helps others.\n\n\n### Pull Requests\n\nWe welcome pull requests!\n- Every Pull Request should have an associated Issue, unless you are fixing a trivial documentation issue.\n- We will not accept changes to LICENSE, NOTICE or CONTRIBUTING from outside the Aqua Security team. Please raise an Issue if you believe there is a problem with any of these files. \n- Your PR is more likely to be accepted if it focuses on just one change.\n- Describe what the PR does. There's no convention enforced, but please try to be concise and descriptive. Treat the PR description as a commit message. Titles that start with \"fix\"/\"add\"/\"improve\"/\"remove\" are good examples.\n- Please add the associated Issue in the PR description.\n- Please include a comment with the results before and after your change.\n- There's no need to add or tag reviewers.\n- If a reviewer commented on your code or asked for changes, please remember to mark the discussion as resolved after you address it. PRs with unresolved issues should not be merged (even if the comment is unclear or requires no action from your side).\n- Please include a comment with the results before and after your change.\n- Your PR is more likely to be accepted if it includes tests (We have not historically been very strict about tests, but we would like to improve this!).\n- You're welcome to submit a draft PR if you would like early feedback on an idea or an approach.\n- Happy coding!\n\n## Testing locally with kind\n\nOur makefile contains targets to test your current version of kube-bench inside a [Kind](https://kind.sigs.k8s.io/) cluster. This can be very handy if you don't want to run a real Kubernetes cluster for development purposes.\n\nFirst, you'll need to create the cluster using `make kind-test-cluster` this will create a new cluster if it cannot be found on your machine. By default, the cluster is named `kube-bench` but you can change the name by using the environment variable `KIND_PROFILE`.\n\n*If kind cannot be found on your system the target will try to install it using `go get`*\n\nNext, you'll have to build the kube-bench docker image using `make build-docker`, then we will be able to push the docker image to the cluster using `make kind-push`.\n\nFinally, we can use the `make kind-run` target to run the current version of kube-bench in the cluster and follow the logs of pods created. (Ctrl+C to exit)\n\nEvery time you want to test a change, you'll need to rebuild the docker image and push it to cluster before running it again. ( `make build-docker kind-push kind-run` )\n\nTo run the STIG tests locally execute the following: `make build-docker kind-push kind-run-stig`\n"
  },
  {
    "path": "Dockerfile",
    "content": "FROM golang:1.26.1 AS build\nWORKDIR /go/src/github.com/aquasecurity/kube-bench/\nCOPY makefile makefile\nCOPY go.mod go.sum ./\nCOPY main.go .\nCOPY check/ check/\nCOPY cmd/ cmd/\nCOPY internal/ internal/\nARG KUBEBENCH_VERSION\nRUN make build && cp kube-bench /go/bin/kube-bench\n\n# Add kubectl to run policies checks\nARG KUBECTL_VERSION TARGETARCH\nRUN wget -O /usr/local/bin/kubectl \"https://dl.k8s.io/release/v${KUBECTL_VERSION}/bin/linux/${TARGETARCH}/kubectl\"\nRUN wget -O kubectl.sha256 \"https://dl.k8s.io/release/v${KUBECTL_VERSION}/bin/linux/${TARGETARCH}/kubectl.sha256\"\n\n# Verify kubectl sha256sum\nRUN /bin/bash -c 'echo \"$(<kubectl.sha256)  /usr/local/bin/kubectl\" | sha256sum -c -'\n\nRUN chmod +x /usr/local/bin/kubectl\n\nFROM alpine:3.23.3 AS run\nWORKDIR /opt/kube-bench/\n# add GNU ps for -C, -o cmd, --no-headers support and add findutils to get GNU xargs\n# https://github.com/aquasecurity/kube-bench/issues/109\n# https://github.com/aquasecurity/kube-bench/issues/1656\nRUN apk --no-cache add procps findutils\n\n# Upgrading apk-tools to remediate CVE-2021-36159 - https://snyk.io/vuln/SNYK-ALPINE314-APKTOOLS-1533752\n# https://github.com/aquasecurity/kube-bench/issues/943\nRUN apk --no-cache upgrade apk-tools\n\n# Openssl is used by OpenShift tests\n# https://github.com/aquasecurity/kube-bench/issues/535\n# Ensuring that we update/upgrade before installing openssl, to mitigate CVE-2021-3711 and CVE-2021-3712\nRUN apk update && apk upgrade && apk --no-cache add openssl\n\n# Add glibc for running oc command \nRUN wget -q -O /etc/apk/keys/sgerrand.rsa.pub https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub\nRUN apk add gcompat\nRUN apk add jq\n\n# Add bash for running helper scripts\nRUN apk add bash\n\nENV PATH=$PATH:/usr/local/mount-from-host/bin:/go/bin\n\nCOPY --from=build /go/bin/kube-bench /usr/local/bin/kube-bench\nCOPY --from=build /usr/local/bin/kubectl /usr/local/bin/kubectl\nCOPY entrypoint.sh .\nCOPY cfg/ cfg/\nCOPY helper_scripts/check_files_owner_in_dir.sh /go/bin/\nRUN chmod a+x /go/bin/check_files_owner_in_dir.sh\nENTRYPOINT [\"./entrypoint.sh\"]\nCMD [\"install\"]\n\n# Build-time metadata as defined at http://label-schema.org\nARG BUILD_DATE\nARG VCS_REF\nARG KUBEBENCH_VERSION\n\nLABEL org.label-schema.build-date=$BUILD_DATE \\\n      org.label-schema.name=\"kube-bench\" \\\n      org.label-schema.vendor=\"Aqua Security Software Ltd.\" \\\n      org.label-schema.version=$KUBEBENCH_VERSION \\\n      org.label-schema.release=$KUBEBENCH_VERSION \\\n      org.label-schema.summary=\"Aqua security server\" \\\n      org.label-schema.maintainer=\"admin@aquasec.com\" \\\n      org.label-schema.description=\"Run the CIS Kubernetes Benchmark tests\" \\\n      org.label-schema.url=\"https://github.com/aquasecurity/kube-bench\" \\\n      org.label-schema.vcs-ref=$VCS_REF \\\n      org.label-schema.vcs-url=\"https://github.com/aquasecurity/kube-bench\" \\\n      org.label-schema.schema-version=\"1.0\"\n"
  },
  {
    "path": "Dockerfile.fips.ubi",
    "content": "FROM golang:1.26.1 AS build\nWORKDIR /go/src/github.com/aquasecurity/kube-bench/\nCOPY makefile makefile\nCOPY go.mod go.sum ./\nCOPY main.go .\nCOPY check/ check/\nCOPY cmd/ cmd/\nCOPY internal/ internal/\nARG KUBEBENCH_VERSION\nRUN make build-fips && cp kube-bench /go/bin/kube-bench\n\n# Add kubectl to run policies checks\nARG KUBECTL_VERSION TARGETARCH\nRUN wget -O /usr/local/bin/kubectl \"https://dl.k8s.io/release/v${KUBECTL_VERSION}/bin/linux/${TARGETARCH}/kubectl\"\nRUN wget -O kubectl.sha256 \"https://dl.k8s.io/release/v${KUBECTL_VERSION}/bin/linux/${TARGETARCH}/kubectl.sha256\"\n# Verify kubectl sha256sum\nRUN /bin/bash -c 'echo \"$(<kubectl.sha256)  /usr/local/bin/kubectl\" | sha256sum -c -'\nRUN chmod +x /usr/local/bin/kubectl\n\n\n# ubi8-minimal base image for build with ubi standards\nFROM registry.access.redhat.com/ubi9/ubi-minimal as run\n\nRUN microdnf install -y yum findutils openssl \\\n  && yum -y update-minimal --security --sec-severity=Moderate --sec-severity=Important --sec-severity=Critical \\\n  && yum update -y \\\n  && yum install -y glibc \\\n  && yum update -y glibc \\\n  && yum install -y procps \\\n  && yum update -y procps \\\n  && yum install jq -y \\\n  && yum clean all \\\n  && microdnf remove yum || rpm -e -v yum \\\n  && microdnf clean all\n\nWORKDIR /opt/kube-bench/\n\nENV PATH=$PATH:/usr/local/mount-from-host/bin \n\nCOPY LICENSE /licenses/LICENSE\nCOPY --from=build /go/bin/kube-bench /usr/local/bin/kube-bench\nCOPY --from=build /usr/local/bin/kubectl /usr/local/bin/kubectl\nCOPY entrypoint.sh .\nCOPY cfg/ cfg/\nCOPY helper_scripts/check_files_owner_in_dir.sh /go/bin\nENTRYPOINT [\"./entrypoint.sh\"]\nCMD [\"install\"]\n\n\n# Build-time metadata as defined at http://label-schema.org\nARG BUILD_DATE\nARG VCS_REF\nARG KUBEBENCH_VERSION\n\nLABEL org.label-schema.build-date=$BUILD_DATE \\\n      org.label-schema.name=\"kube-bench\" \\\n      org.label-schema.vendor=\"Aqua Security Software Ltd.\" \\\n      org.label-schema.version=$KUBEBENCH_VERSION \\\n      org.label-schema.release=$KUBEBENCH_VERSION \\\n      org.label-schema.summary=\"Aqua security server\" \\\n      org.label-schema.maintainer=\"admin@aquasec.com\" \\\n      org.label-schema.description=\"Run the CIS Kubernetes Benchmark tests\" \\\n      org.label-schema.url=\"https://github.com/aquasecurity/kube-bench\" \\\n      org.label-schema.vcs-ref=$VCS_REF \\\n      org.label-schema.vcs-url=\"https://github.com/aquasecurity/kube-bench\" \\\n      org.label-schema.schema-version=\"1.0\"\n"
  },
  {
    "path": "Dockerfile.ubi",
    "content": "FROM golang:1.26.1 AS build\nWORKDIR /go/src/github.com/aquasecurity/kube-bench/\nCOPY makefile makefile\nCOPY go.mod go.sum ./\nCOPY main.go .\nCOPY check/ check/\nCOPY cmd/ cmd/\nCOPY internal/ internal/\nARG KUBEBENCH_VERSION\nRUN make build && cp kube-bench /go/bin/kube-bench\n\n# Add kubectl to run policies checks\nARG KUBECTL_VERSION TARGETARCH\nRUN wget -O /usr/local/bin/kubectl \"https://dl.k8s.io/release/v${KUBECTL_VERSION}/bin/linux/${TARGETARCH}/kubectl\"\nRUN wget -O kubectl.sha256 \"https://dl.k8s.io/release/v${KUBECTL_VERSION}/bin/linux/${TARGETARCH}/kubectl.sha256\"\n# Verify kubectl sha256sum\nRUN /bin/bash -c 'echo \"$(<kubectl.sha256)  /usr/local/bin/kubectl\" | sha256sum -c -'\nRUN chmod +x /usr/local/bin/kubectl\n\n\n# ubi8-minimal base image for build with ubi standards\nFROM registry.access.redhat.com/ubi9/ubi-minimal as run\n\nRUN microdnf install -y yum findutils openssl \\\n  && yum -y update-minimal --security --sec-severity=Moderate --sec-severity=Important --sec-severity=Critical \\\n  && yum update -y \\\n  && yum install -y glibc \\\n  && yum update -y glibc \\\n  && yum install -y procps \\\n  && yum update -y procps \\\n  && yum install jq -y \\\n  && yum clean all \\\n  && microdnf remove yum || rpm -e -v yum \\\n  && microdnf clean all\n\nWORKDIR /opt/kube-bench/\n\nENV PATH=$PATH:/usr/local/mount-from-host/bin\n\nCOPY LICENSE /licenses/LICENSE\nCOPY --from=build /go/bin/kube-bench /usr/local/bin/kube-bench\nCOPY --from=build /usr/local/bin/kubectl /usr/local/bin/kubectl\nCOPY entrypoint.sh .\nCOPY cfg/ cfg/\nCOPY helper_scripts/check_files_owner_in_dir.sh /go/bin\nENTRYPOINT [\"./entrypoint.sh\"]\nCMD [\"install\"]\n\n\n# Build-time metadata as defined at http://label-schema.org\nARG BUILD_DATE\nARG VCS_REF\nARG KUBEBENCH_VERSION\n\nLABEL org.label-schema.build-date=$BUILD_DATE \\\n      org.label-schema.description=\"Run the CIS Kubernetes Benchmark tests\" \\\n      org.label-schema.url=\"https://github.com/aquasecurity/kube-bench\" \\\n      org.label-schema.vcs-ref=$VCS_REF \\\n      org.label-schema.vcs-url=\"https://github.com/aquasecurity/kube-bench\" \\\n      org.label-schema.schema-version=\"1.0\" \\\n      vendor=\"Aqua Security Software Ltd.\" \\\n      maintainer=\"Aqua Security Software Ltd.\" \\\n      version=$KUBEBENCH_VERSION \\\n      release=$KUBEBENCH_VERSION \\\n      summary=\"Aqua Security Kube-bench.\" \\\n      description=\"Run the CIS Kubernetes Benchmark tests\""
  },
  {
    "path": "LICENSE",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "NOTICE",
    "content": "kube-bench\nCopyright 2017-2019 Aqua Security Software Ltd. \n\nThis product includes software developed by Aqua Security (https://aquasec.com).\n\n"
  },
  {
    "path": "OWNERS",
    "content": "approvers:\n - lizrice\n - jerbia\n"
  },
  {
    "path": "README.md",
    "content": "[![GitHub Release][release-img]][release]\n[![Downloads][download]][release]\n[![Docker Pulls][docker-pull]][docker]\n[![Go Report Card][report-card-img]][report-card]\n[![Build Status](https://github.com/aquasecurity/kube-bench/workflows/Build/badge.svg?branch=main)](https://github.com/aquasecurity/kube-bench/actions)\n[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://github.com/aquasecurity/kube-bench/blob/main/LICENSE)\n[![Coverage Status][cov-img]][cov]\n\n[download]: https://img.shields.io/github/downloads/aquasecurity/kube-bench/total?logo=github\n[release-img]: https://img.shields.io/github/release/aquasecurity/kube-bench.svg?logo=github\n[release]: https://github.com/aquasecurity/kube-bench/releases\n[docker-pull]: https://img.shields.io/docker/pulls/aquasec/kube-bench?logo=docker&label=docker%20pulls%20%2F%20kube-bench\n[docker]: https://hub.docker.com/r/aquasec/kube-bench\n[cov-img]: https://codecov.io/github/aquasecurity/kube-bench/branch/main/graph/badge.svg\n[cov]: https://codecov.io/github/aquasecurity/kube-bench\n[report-card-img]: https://goreportcard.com/badge/github.com/aquasecurity/kube-bench\n[report-card]: https://goreportcard.com/report/github.com/aquasecurity/kube-bench\n\n<img src=\"docs/images/kube-bench.png\" width=\"200\" alt=\"kube-bench logo\">\n\nkube-bench is a tool that checks whether Kubernetes is deployed securely by running the checks documented in the [CIS Kubernetes Benchmark](https://www.cisecurity.org/benchmark/kubernetes/).\n\nTests are configured with YAML files, making this tool easy to update as test specifications evolve.\n\n![Kubernetes Bench for Security](/docs/images/output.png \"Kubernetes Bench for Security\")\n\n## CIS Scanning as part of Trivy and the Trivy Operator\n\n[Trivy](https://github.com/aquasecurity/trivy), the all in one cloud native security scanner, can be deployed as a [Kubernetes Operator](https://github.com/aquasecurity/trivy-operator) inside a cluster.\nBoth, the [Trivy CLI](https://github.com/aquasecurity/trivy), and the [Trivy Operator](https://github.com/aquasecurity/trivy-operator) support CIS Kubernetes Benchmark scanning among several other features.\n\n## Quick start\n\nThere are multiple ways to run kube-bench.\nYou can run kube-bench inside a pod, but it will need access to the host's PID namespace in order to check the running processes, as well as access to some directories on the host where config files and other files are stored.\n\nThe supplied `job.yaml` [file](job.yaml) can be applied to run the tests as a job. For example:\n\n```bash\n$ kubectl apply -f job.yaml\njob.batch/kube-bench created\n\n$ kubectl get pods\nNAME                      READY   STATUS              RESTARTS   AGE\nkube-bench-j76s9   0/1     ContainerCreating   0          3s\n\n# Wait for a few seconds for the job to complete\n$ kubectl get pods\nNAME                      READY   STATUS      RESTARTS   AGE\nkube-bench-j76s9   0/1     Completed   0          11s\n\n# The results are held in the pod's logs\nkubectl logs kube-bench-j76s9\n[INFO] 1 Master Node Security Configuration\n[INFO] 1.1 API Server\n...\n```\nFor more information and different ways to run kube-bench see [documentation](docs/running.md)\n### Please Note\n\n1. kube-bench implements the [CIS Kubernetes Benchmark](https://www.cisecurity.org/benchmark/kubernetes/) as closely as possible. Please raise issues here if kube-bench is not correctly implementing the test as described in the Benchmark. To report issues in the Benchmark itself (for example, tests that you believe are inappropriate), please join the [CIS community](https://cisecurity.org).\n\n1. There is not a one-to-one mapping between releases of Kubernetes and releases of the CIS benchmark. See [CIS Kubernetes Benchmark support](docs/platforms.md#cis-kubernetes-benchmark-support) to see which releases of Kubernetes are covered by different releases of the benchmark.\n\n\nBy default, kube-bench will determine the test set to run based on the Kubernetes version running on the machine.\n- see the following documentation on [Running kube-bench](docs/running.md#running-kube-bench) for more details.\n\n\n## Contributing\nKindly read [Contributing](CONTRIBUTING.md) before contributing. \nWe welcome PRs and issue reports.\n\n## Roadmap\n\nGoing forward we plan to release updates to kube-bench to add support for new releases of the CIS Benchmark. Note that these are not released as frequently as Kubernetes releases.\n"
  },
  {
    "path": "cfg/ack-1.0/config.yaml",
    "content": "---\n## Version-specific settings that override the values in cfg/config.yaml\n"
  },
  {
    "path": "cfg/ack-1.0/controlplane.yaml",
    "content": "---\ncontrols:\nversion: \"ack-1.0\"\nid: 3\ntext: \"Control Plane Configuration\"\ntype: \"controlplane\"\ngroups:\n  - id: 3.1\n    text: \"Authentication and Authorization\"\n    checks:\n      - id: 3.1.1\n        text: \"Revoke client certificate when possible leakage (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Kubernetes provides the option to use client certificates for user authentication.\n          ACK issues kubeconfig with its client certificates as the user credentials for connecing to target cluster.\n          User should revoke his/her issued kubeconfig when possible leakage.\n        scored: false\n\n  - id: 3.2\n    text: \"Logging\"\n    checks:\n      - id: 3.2.1\n        text: \"Ensure that a minimal audit policy is created (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-policy-file\"\n        remediation: |\n          Create an audit policy file for your cluster.\n        scored: false\n\n      - id: 3.2.2\n        text: \"Ensure that the audit policy covers key security concerns (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Consider modification of the audit policy in use on the cluster to include these items, at a\n          minimum.\n        scored: false\n"
  },
  {
    "path": "cfg/ack-1.0/etcd.yaml",
    "content": "---\ncontrols:\nversion: \"ack-1.0\"\nid: 2\ntext: \"Etcd Node Configuration\"\ntype: \"etcd\"\ngroups:\n  - id: 2\n    text: \"Etcd Node Configuration Files\"\n    checks:\n      - id: 2.1\n        text: \"Ensure that the --cert-file and --key-file arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--cert-file\"\n              env: \"ETCD_CERT_FILE\"\n            - flag: \"--key-file\"\n              env: \"ETCD_KEY_FILE\"\n        remediation: |\n          Follow the etcd service documentation and configure TLS encryption.\n          Then, edit the etcd pod specification file /etc/kubernetes/manifests/etcd.yaml\n          on the master node and set the below parameters.\n          --cert-file=</path/to/ca-file>\n          --key-file=</path/to/key-file>\n        scored: true\n\n      - id: 2.2\n        text: \"Ensure that the --client-cert-auth argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--client-cert-auth\"\n              env: \"ETCD_CLIENT_CERT_AUTH\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and set the below parameter.\n          --client-cert-auth=\"true\"\n        scored: true\n\n      - id: 2.3\n        text: \"Ensure that the --auto-tls argument is not set to true (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--auto-tls\"\n              env: \"ETCD_AUTO_TLS\"\n              set: false\n            - flag: \"--auto-tls\"\n              env: \"ETCD_AUTO_TLS\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and either remove the --auto-tls parameter or set it to false.\n            --auto-tls=false\n        scored: true\n\n      - id: 2.4\n        text: \"Ensure that the --peer-cert-file and --peer-key-file arguments are\n        set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--peer-cert-file\"\n              env: \"ETCD_PEER_CERT_FILE\"\n            - flag: \"--peer-key-file\"\n              env: \"ETCD_PEER_KEY_FILE\"\n        remediation: |\n          Follow the etcd service documentation and configure peer TLS encryption as appropriate\n          for your etcd cluster.\n          Then, edit the etcd pod specification file $etcdconf on the\n          master node and set the below parameters.\n          --peer-client-file=</path/to/peer-cert-file>\n          --peer-key-file=</path/to/peer-key-file>\n        scored: true\n\n      - id: 2.5\n        text: \"Ensure that the --peer-client-cert-auth argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--peer-client-cert-auth\"\n              env: \"ETCD_PEER_CLIENT_CERT_AUTH\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and set the below parameter.\n          --peer-client-cert-auth=true\n        scored: true\n\n      - id: 2.6\n        text: \"Ensure that the --peer-auto-tls argument is not set to true (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--peer-auto-tls\"\n              env: \"ETCD_PEER_AUTO_TLS\"\n              set: false\n            - flag: \"--peer-auto-tls\"\n              env: \"ETCD_PEER_AUTO_TLS\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and either remove the --peer-auto-tls parameter or set it to false.\n          --peer-auto-tls=false\n        scored: true\n\n      - id: 2.7\n        text: \"Ensure that a unique Certificate Authority is used for etcd (Manual)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--trusted-ca-file\"\n              env: \"ETCD_TRUSTED_CA_FILE\"\n        remediation: |\n          [Manual test]\n          Follow the etcd documentation and create a dedicated certificate authority setup for the\n          etcd service.\n          Then, edit the etcd pod specification file $etcdconf on the\n          master node and set the below parameter.\n          --trusted-ca-file=</path/to/ca-file>\n        scored: false\n"
  },
  {
    "path": "cfg/ack-1.0/managedservices.yaml",
    "content": "---\ncontrols:\nversion: \"ack-1.0\"\nid: 6\ntext: \"Managed Services\"\ntype: \"managedservices\"\ngroups:\n  - id: 6.1\n    text: \"Image Registry and Image Scanning\"\n    checks:\n      - id: 6.1.1\n        text: \"Ensure Image Vulnerability Scanning using ACR image scanning or a third party provider (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Ensure Image Vulnerability Scanning using ACR image scanning or a third party provider by follow the ACR document: https://www.alibabacloud.com/help/doc-detail/160146.htm\n        scored: false\n\n      - id: 6.1.2\n        text: \"Minimize user access to ACR (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Minimize user access to ACR by follow the ACR document to setup network access control: https://www.alibabacloud.com/help/doc-detail/142179.htm\n          And follow the ACR document to setup Resource Access Management (RAM) policies for ACR: https://www.alibabacloud.com/help/doc-detail/144229.htm\n        scored: false\n\n      - id: 6.1.3\n        text: \"Minimize cluster access to read-only for ACR (Manual)\"\n        type: \"manual\"\n        remediation: Minimize cluster access to read-only for ACR\n        scored: false\n\n      - id: 6.1.4\n        text: \"Minimize Container Registries to only those approved (Manual)\"\n        type: \"manual\"\n        remediation: Minimize Container Registries to only those approved\n        scored: false\n\n  - id: 6.2\n    text: \"Key Management Service (KMS)\"\n    checks:\n      - id: 6.2.1\n        text: \"Ensure Kubernetes Secrets are encrypted using keys managed in KMS (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Ensure Kubernetes Secrets are encrypted using keys managed in KMS by follow The ACK document: https://www.alibabacloud.com/help/zh/doc-detail/177372.htm\n        scored: false\n\n  - id: 6.3\n    text: \"Cluster Networking\"\n    checks:\n      - id: 6.3.1\n        text: \"Restrict Access to the Control Plane Endpoint (Manual)\"\n        type: \"manual\"\n        remediation: Restrict Access to the Control Plane Endpoint\n        scored: false\n\n      - id: 6.3.2\n        text: \"Ensure clusters are created with Private Endpoint Enabled and Public Access Disabled (Manual)\"\n        type: \"manual\"\n        remediation: Ensure clusters are created with Private Endpoint Enabled and Public Access Disabled\n        scored: false\n\n      - id: 6.3.3\n        text: \"Ensure clusters are created with Private Nodes (Manual)\"\n        type: \"manual\"\n        remediation: Ensure clusters are created with Private Nodes\n        scored: false\n\n      - id: 6.3.4\n        text: \"Ensure Network Policy is Enabled and set as appropriate (Manual)\"\n        type: \"manual\"\n        remediation: Ensure Network Policy is Enabled and set as appropriate\n        scored: false\n\n      - id: 6.3.5\n        text: \"Encrypt traffic to HTTPS load balancers with TLS certificates (Manual)\"\n        type: \"manual\"\n        remediation: Encrypt traffic to HTTPS load balancers with TLS certificates\n        scored: false\n\n  - id: 6.4\n    text: \"Storage\"\n    checks:\n      - id: 6.4.1\n        text: \"Enable data disk encryption for Alibaba Cloud Disks (Manual)\"\n        type: \"manual\"\n        remediation: Enable data disk encryption for Alibaba Cloud Disks\n        scored: false\n\n  - id: 6.5\n    text: \"Logging\"\n    checks:\n      - id: 6.5.1\n        text: \"Ensure Cluster Auditing is Enabled (Manual)\"\n        type: \"manual\"\n        remediation: Ensure Cluster Auditing is Enabled\n        scored: false\n\n  - id: 6.6\n    text: \"Other Cluster Configurations\"\n    checks:\n      - id: 6.6.1\n        text: \"Ensure Pod Security Policy is Enabled and set as appropriate (Manual)\"\n        type: \"manual\"\n        remediation: Ensure Pod Security Policy is Enabled and set as appropriate\n        scored: false\n\n      - id: 6.6.2\n        text: \"Enable Cloud Security Center (Manual)\"\n        type: \"manual\"\n        remediation: Enable Cloud Security Center\n        scored: false\n\n      - id: 6.6.3\n        text: \"Consider ACK Sandboxed-Container for running untrusted workloads (Manual)\"\n        type: \"manual\"\n        remediation: Consider ACK Sandboxed-Container for running untrusted workloads\n\n      - id: 6.6.4\n        text: \"Consider ACK TEE-based when running confidential computing (Manual)\"\n        type: \"manual\"\n        remediation: Consider ACK TEE-based when running confidential computing\n\n      - id: 6.6.5\n        text: \"Consider use service account token volume projection (Manual)\"\n        type: \"manual\"\n        remediation: Consider use service account token volume projection\n"
  },
  {
    "path": "cfg/ack-1.0/master.yaml",
    "content": "---\ncontrols:\nversion: \"ack-1.0\"\nid: 1\ntext: \"Master Node Security Configuration\"\ntype: \"master\"\ngroups:\n  - id: 1.1\n    text: \"Master Node Configuration Files\"\n    checks:\n      - id: 1.1.1\n        text: \"Ensure that the API server pod specification file permissions are set to 644 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $apiserverconf; then stat -c permissions=%a $apiserverconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the\n          master node.\n          For example, chmod 644 $apiserverconf\n        scored: true\n\n      - id: 1.1.2\n        text: \"Ensure that the API server pod specification file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $apiserverconf; then stat -c %U:%G $apiserverconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chown root:root $apiserverconf\n        scored: true\n\n      - id: 1.1.3\n        text: \"Ensure that the controller manager pod specification file permissions are set to 644 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerconf; then stat -c permissions=%a $controllermanagerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chmod 644 $controllermanagerconf\n        scored: true\n\n      - id: 1.1.4\n        text: \"Ensure that the controller manager pod specification file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerconf; then stat -c %U:%G $controllermanagerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chown root:root $controllermanagerconf\n        scored: true\n\n      - id: 1.1.5\n        text: \"Ensure that the scheduler pod specification file permissions are set to 644 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerconf; then stat -c permissions=%a $schedulerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chmod 644 $schedulerconf\n        scored: true\n\n      - id: 1.1.6\n        text: \"Ensure that the scheduler pod specification file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerconf; then stat -c %U:%G $schedulerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chown root:root $schedulerconf\n        scored: true\n\n      - id: 1.1.7\n        text: \"Ensure that the etcd service file permissions are set to 644 or more restrictive (Automated)\"\n        audit: |\n          stat -c permissions=%a /usr/lib/systemd/system/etcd.service || \\\n          if test -e $etcdconf; then find $etcdconf -name '*etcd*' | xargs stat -c permissions=%a; fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chmod 644 $etcdconf\n        scored: true\n\n      - id: 1.1.8\n        text: \"Ensure that the etcd service file ownership is set to root:root (Automated)\"\n        audit: |\n          stat -c %U:%G /usr/lib/systemd/system/etcd.service || \\\n          if test -e $etcdconf; then find $etcdconf -name '*etcd*' | xargs stat -c %U:%G; fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chown root:root $etcdconf\n        scored: true\n\n      - id: 1.1.9\n        text: \"Ensure that the Container Network Interface file permissions are set to 644 or more restrictive (Manual)\"\n        audit: \"stat -c permissions=%a <path/to/cni/files>\"\n        type: \"manual\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chmod 644 <path/to/cni/files>\n        scored: false\n\n      - id: 1.1.10\n        text: \"Ensure that the Container Network Interface file ownership is set to root:root (Manual)\"\n        audit: \"stat -c %U:%G <path/to/cni/files>\"\n        type: \"manual\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chown root:root <path/to/cni/files>\n        scored: false\n\n      - id: 1.1.11\n        text: \"Ensure that the etcd data directory permissions are set to 700 or more restrictive (Automated)\"\n        audit: |\n          stat -c permissions=%a /var/lib/etcd/data.etcd || \\\n          ps -ef | grep $etcdbin | grep -- --data-dir | sed 's%.*data-dir[= ]\\([^ ]*\\).*%\\1%' | xargs stat -c permissions=%a\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"700\"\n        remediation: |\n          On the etcd server node, get the etcd data directory, passed as an argument --data-dir,\n          from the below command:\n          ps -ef | grep etcd\n          Run the below command (based on the etcd data directory found above). For example,\n          chmod 700 /var/lib/etcd\n        scored: true\n\n      - id: 1.1.12\n        text: \"Ensure that the etcd data directory ownership is set to etcd:etcd (Automated)\"\n        audit: |\n          stat -c %U:%G /var/lib/etcd/data.etcd || \\\n          ps -ef | grep $etcdbin | grep -- --data-dir | sed 's%.*data-dir[= ]\\([^ ]*\\).*%\\1%' | xargs stat -c %U:%G\n        tests:\n          test_items:\n            - flag: \"etcd:etcd\"\n        remediation: |\n          On the etcd server node, get the etcd data directory, passed as an argument --data-dir,\n          from the below command:\n          ps -ef | grep etcd\n          Run the below command (based on the etcd data directory found above).\n          For example, chown etcd:etcd /var/lib/etcd\n        scored: true\n\n      - id: 1.1.13\n        text: \"Ensure that the admin.conf file permissions are set to 644 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e /etc/kubernetes/admin.conf; then stat -c permissions=%a /etc/kubernetes/admin.conf; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chmod 644 /etc/kubernetes/admin.conf\n        scored: true\n\n      - id: 1.1.14\n        text: \"Ensure that the admin.conf file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e /etc/kubernetes/admin.conf; then stat -c %U:%G /etc/kubernetes/admin.conf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chown root:root /etc/kubernetes/admin.conf\n        scored: true\n\n      - id: 1.1.15\n        text: \"Ensure that the scheduler.conf file permissions are set to 644 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerkubeconfig; then stat -c permissions=%a $schedulerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chmod 644 $schedulerkubeconfig\n        scored: true\n\n      - id: 1.1.16\n        text: \"Ensure that the scheduler.conf file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerkubeconfig; then stat -c %U:%G $schedulerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chown root:root $schedulerkubeconfig\n        scored: true\n\n      - id: 1.1.17\n        text: \"Ensure that the controller-manager.conf file permissions are set to 644 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerkubeconfig; then stat -c permissions=%a $controllermanagerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chmod 644 $controllermanagerkubeconfig\n        scored: true\n\n      - id: 1.1.18\n        text: \"Ensure that the controller-manager.conf file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerkubeconfig; then stat -c %U:%G $controllermanagerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chown root:root $controllermanagerkubeconfig\n        scored: true\n\n      - id: 1.1.19\n        text: \"Ensure that the Kubernetes PKI directory and file ownership is set to root:root (Automated)\"\n        audit: \"find /etc/kubernetes/pki/ | xargs stat -c %U:%G\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chown -R root:root /etc/kubernetes/pki/\n        scored: true\n\n      - id: 1.1.20\n        text: \"Ensure that the Kubernetes PKI certificate file permissions are set to 644 or more restrictive (Manual)\"\n        audit: \"find /etc/kubernetes/pki -name '*.crt' | xargs stat -c permissions=%a\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chmod -R 644 /etc/kubernetes/pki/*.crt\n        scored: false\n\n      - id: 1.1.21\n        text: \"Ensure that the Kubernetes PKI key file permissions are set to 600 (Manual)\"\n        audit: \"find /etc/kubernetes/pki -name '*.key' | xargs stat -c permissions=%a\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chmod -R 600 /etc/kubernetes/pki/*.key\n        scored: false\n\n  - id: 1.2\n    text: \"API Server\"\n    checks:\n      - id: 1.2.1\n        text: \"Ensure that the --basic-auth-file argument is not set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--basic-auth-file\"\n              set: false\n        remediation: |\n          Follow the documentation and configure alternate mechanisms for authentication. Then,\n          edit the API server pod specification file $apiserverconf\n          on the master node and remove the --basic-auth-file=<filename> parameter.\n        scored: true\n\n      - id: 1.2.2\n        text: \"Ensure that the --token-auth-file parameter is not set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--token-auth-file\"\n              set: false\n        remediation: |\n          Follow the documentation and configure alternate mechanisms for authentication. Then,\n          edit the API server pod specification file $apiserverconf\n          on the master node and remove the --token-auth-file=<filename> parameter.\n        scored: true\n\n      - id: 1.2.3\n        text: \"Ensure that the --kubelet-https argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--kubelet-https\"\n              compare:\n                op: eq\n                value: true\n            - flag: \"--kubelet-https\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and remove the --kubelet-https parameter.\n        scored: true\n\n      - id: 1.2.4\n        text: \"Ensure that the --kubelet-client-certificate and --kubelet-client-key arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--kubelet-client-certificate\"\n            - flag: \"--kubelet-client-key\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection between the\n          apiserver and kubelets. Then, edit API server pod specification file\n          $apiserverconf on the master node and set the\n          kubelet client certificate and key parameters as below.\n          --kubelet-client-certificate=<path/to/client-certificate-file>\n          --kubelet-client-key=<path/to/client-key-file>\n        scored: true\n\n      - id: 1.2.5\n        text: \"Ensure that the --authorization-mode argument is not set to AlwaysAllow (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: nothave\n                value: \"AlwaysAllow\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and set the --authorization-mode parameter to values other than AlwaysAllow.\n          One such example could be as below.\n          --authorization-mode=RBAC\n        scored: true\n\n      - id: 1.2.6\n        text: \"Ensure that the --authorization-mode argument includes Node (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: has\n                value: \"Node\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and set the --authorization-mode parameter to a value that includes Node.\n          --authorization-mode=Node,RBAC\n        scored: true\n\n      - id: 1.2.7\n        text: \"Ensure that the --authorization-mode argument includes RBAC (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: has\n                value: \"RBAC\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and set the --authorization-mode parameter to a value that includes RBAC,\n          for example:\n          --authorization-mode=Node,RBAC\n        scored: true\n\n      - id: 1.2.8\n        text: \"Ensure that the admission control plugin EventRateLimit is set (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"EventRateLimit\"\n        remediation: |\n          Follow the Kubernetes documentation and set the desired limits in a configuration file.\n          Then, edit the API server pod specification file $apiserverconf\n          and set the below parameters.\n          --enable-admission-plugins=...,EventRateLimit,...\n          --admission-control-config-file=<path/to/configuration/file>\n        scored: false\n\n      - id: 1.2.9\n        text: \"Ensure that the admission control plugin AlwaysAdmit is not set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: nothave\n                value: AlwaysAdmit\n            - flag: \"--enable-admission-plugins\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and either remove the --enable-admission-plugins parameter, or set it to a\n          value that does not include AlwaysAdmit.\n        scored: true\n\n      - id: 1.2.10\n        text: \"Ensure that the admission control plugin AlwaysPullImages is set (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"AlwaysPullImages\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and set the --enable-admission-plugins parameter to include\n          AlwaysPullImages.\n          --enable-admission-plugins=...,AlwaysPullImages,...\n        scored: false\n\n      - id: 1.2.11\n        text: \"Ensure that the admission control plugin SecurityContextDeny is set if PodSecurityPolicy is not used (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"SecurityContextDeny\"\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"PodSecurityPolicy\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and set the --enable-admission-plugins parameter to include\n          SecurityContextDeny, unless PodSecurityPolicy is already in place.\n          --enable-admission-plugins=...,SecurityContextDeny,...\n        scored: false\n\n      - id: 1.2.12\n        text: \"Ensure that the admission control plugin ServiceAccount is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--disable-admission-plugins\"\n              compare:\n                op: nothave\n                value: \"ServiceAccount\"\n            - flag: \"--disable-admission-plugins\"\n              set: false\n        remediation: |\n          Follow the documentation and create ServiceAccount objects as per your environment.\n          Then, edit the API server pod specification file $apiserverconf\n          on the master node and ensure that the --disable-admission-plugins parameter is set to a\n          value that does not include ServiceAccount.\n        scored: true\n\n      - id: 1.2.13\n        text: \"Ensure that the admission control plugin NamespaceLifecycle is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--disable-admission-plugins\"\n              compare:\n                op: nothave\n                value: \"NamespaceLifecycle\"\n            - flag: \"--disable-admission-plugins\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and set the --disable-admission-plugins parameter to\n          ensure it does not include NamespaceLifecycle.\n        scored: true\n\n      - id: 1.2.14\n        text: \"Ensure that the admission control plugin PodSecurityPolicy is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"PodSecurityPolicy\"\n        remediation: |\n          Follow the documentation and create Pod Security Policy objects as per your environment.\n          Then, edit the API server pod specification file $apiserverconf\n          on the master node and set the --enable-admission-plugins parameter to a\n          value that includes PodSecurityPolicy:\n          --enable-admission-plugins=...,PodSecurityPolicy,...\n          Then restart the API Server.\n        scored: true\n\n      - id: 1.2.15\n        text: \"Ensure that the admission control plugin NodeRestriction is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"NodeRestriction\"\n        remediation: |\n          Follow the Kubernetes documentation and configure NodeRestriction plug-in on kubelets.\n          Then, edit the API server pod specification file $apiserverconf\n          on the master node and set the --enable-admission-plugins parameter to a\n          value that includes NodeRestriction.\n          --enable-admission-plugins=...,NodeRestriction,...\n        scored: true\n\n      - id: 1.2.16\n        text: \"Ensure that the --insecure-bind-address argument is not set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--insecure-bind-address\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and remove the --insecure-bind-address parameter.\n        scored: true\n\n      - id: 1.2.17\n        text: \"Ensure that the --insecure-port argument is set to 0 (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--insecure-port\"\n              compare:\n                op: eq\n                value: 0\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and set the below parameter.\n          --insecure-port=0\n        scored: true\n\n      - id: 1.2.18\n        text: \"Ensure that the --secure-port argument is not set to 0 (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--secure-port\"\n              compare:\n                op: gt\n                value: 0\n            - flag: \"--secure-port\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and either remove the --secure-port parameter or\n          set it to a different (non-zero) desired port.\n        scored: true\n\n      - id: 1.2.19\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and set the below parameter.\n          --profiling=false\n        scored: true\n\n      - id: 1.2.20\n        text: \"Ensure that the --audit-log-path argument is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-path\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and set the --audit-log-path parameter to a suitable path and\n          file where you would like audit logs to be written, for example:\n          --audit-log-path=/var/log/apiserver/audit.log\n        scored: true\n\n      - id: 1.2.21\n        text: \"Ensure that the --audit-log-maxage argument is set to 30 or as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxage\"\n              compare:\n                op: gte\n                value: 30\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and set the --audit-log-maxage parameter to 30 or as an appropriate number of days:\n          --audit-log-maxage=30\n        scored: true\n\n      - id: 1.2.22\n        text: \"Ensure that the --audit-log-maxbackup argument is set to 10 or as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxbackup\"\n              compare:\n                op: gte\n                value: 10\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and set the --audit-log-maxbackup parameter to 10 or to an appropriate\n          value.\n          --audit-log-maxbackup=10\n        scored: true\n\n      - id: 1.2.23\n        text: \"Ensure that the --audit-log-maxsize argument is set to 100 or as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxsize\"\n              compare:\n                op: gte\n                value: 100\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and set the --audit-log-maxsize parameter to an appropriate size in MB.\n          For example, to set it as 100 MB:\n          --audit-log-maxsize=100\n        scored: true\n\n      - id: 1.2.24\n        text: \"Ensure that the --request-timeout argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        type: manual\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          and set the below parameter as appropriate and if needed.\n          For example,\n          --request-timeout=300s\n        scored: true\n\n      - id: 1.2.25\n        text: \"Ensure that the --service-account-lookup argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--service-account-lookup\"\n              set: false\n            - flag: \"--service-account-lookup\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and set the below parameter.\n          --service-account-lookup=true\n          Alternatively, you can delete the --service-account-lookup parameter from this file so\n          that the default takes effect.\n        scored: true\n\n      - id: 1.2.26\n        text: \"Ensure that the --service-account-key-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--service-account-key-file\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and set the --service-account-key-file parameter\n          to the public key file for service accounts:\n          --service-account-key-file=<filename>\n        scored: true\n\n      - id: 1.2.27\n        text: \"Ensure that the --etcd-certfile and --etcd-keyfile arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--etcd-certfile\"\n            - flag: \"--etcd-keyfile\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection between the apiserver and etcd.\n          Then, edit the API server pod specification file $apiserverconf\n          on the master node and set the etcd certificate and key file parameters.\n          --etcd-certfile=<path/to/client-certificate-file>\n          --etcd-keyfile=<path/to/client-key-file>\n        scored: true\n\n      - id: 1.2.28\n        text: \"Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--tls-cert-file\"\n            - flag: \"--tls-private-key-file\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection on the apiserver.\n          Then, edit the API server pod specification file $apiserverconf\n          on the master node and set the TLS certificate and private key file parameters.\n          --tls-cert-file=<path/to/tls-certificate-file>\n          --tls-private-key-file=<path/to/tls-key-file>\n        scored: true\n\n      - id: 1.2.29\n        text: \"Ensure that the --client-ca-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--client-ca-file\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection on the apiserver.\n          Then, edit the API server pod specification file $apiserverconf\n          on the master node and set the client certificate authority file.\n          --client-ca-file=<path/to/client-ca-file>\n        scored: true\n\n      - id: 1.2.30\n        text: \"Ensure that the --etcd-cafile argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--etcd-cafile\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection between the apiserver and etcd.\n          Then, edit the API server pod specification file $apiserverconf\n          on the master node and set the etcd certificate authority file parameter.\n          --etcd-cafile=<path/to/ca-file>\n        scored: true\n\n      - id: 1.2.31\n        text: \"Ensure that the --encryption-provider-config argument is set as appropriate (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--encryption-provider-config\"\n        remediation: |\n          Follow the Kubernetes documentation and configure a EncryptionConfig file.\n          Then, edit the API server pod specification file $apiserverconf\n          on the master node and set the --encryption-provider-config parameter to the path of that file: --encryption-provider-config=</path/to/EncryptionConfig/File>\n        scored: false\n\n      - id: 1.2.32\n        text: \"Ensure that encryption providers are appropriately configured (Manual)\"\n        audit: |\n          ENCRYPTION_PROVIDER_CONFIG=$(ps -ef | grep $apiserverbin | grep -- --encryption-provider-config | sed 's%.*encryption-provider-config[= ]\\([^ ]*\\).*%\\1%')\n          if test -e $ENCRYPTION_PROVIDER_CONFIG; then grep -A1 'providers:' $ENCRYPTION_PROVIDER_CONFIG | tail -n1 | grep -o \"[A-Za-z]*\" | sed 's/^/provider=/'; fi\n        tests:\n          test_items:\n            - flag: \"provider\"\n              compare:\n                op: valid_elements\n                value: \"aescbc,kms,secretbox\"\n        remediation: |\n          Follow the Kubernetes documentation and configure a EncryptionConfig file.\n          In this file, choose aescbc, kms or secretbox as the encryption provider.\n        scored: false\n\n      - id: 1.2.33\n        text: \"Ensure that the API Server only makes use of Strong Cryptographic Ciphers (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--tls-cipher-suites\"\n              compare:\n                op: valid_elements\n                value: \"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\"\n        remediation: |\n          Edit the API server pod specification file /etc/kubernetes/manifests/kube-apiserver.yaml\n          on the master node and set the below parameter.\n          --tls-cipher-suites=TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM\n          _SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM\n          _SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM\n          _SHA384\n        scored: false\n\n  - id: 1.3\n    text: \"Controller Manager\"\n    checks:\n      - id: 1.3.1\n        text: \"Ensure that the --terminated-pod-gc-threshold argument is set as appropriate (Manual)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--terminated-pod-gc-threshold\"\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the master node and set the --terminated-pod-gc-threshold to an appropriate threshold,\n          for example:\n          --terminated-pod-gc-threshold=10\n        scored: false\n\n      - id: 1.3.2\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the master node and set the below parameter.\n          --profiling=false\n        scored: true\n\n      - id: 1.3.3\n        text: \"Ensure that the --use-service-account-credentials argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--use-service-account-credentials\"\n              compare:\n                op: noteq\n                value: false\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the master node to set the below parameter.\n          --use-service-account-credentials=true\n        scored: true\n\n      - id: 1.3.4\n        text: \"Ensure that the --service-account-private-key-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--service-account-private-key-file\"\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the master node and set the --service-account-private-key-file parameter\n          to the private key file for service accounts.\n          --service-account-private-key-file=<filename>\n        scored: true\n\n      - id: 1.3.5\n        text: \"Ensure that the --root-ca-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--root-ca-file\"\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the master node and set the --root-ca-file parameter to the certificate bundle file`.\n          --root-ca-file=<path/to/file>\n        scored: true\n\n      - id: 1.3.6\n        text: \"Ensure that the RotateKubeletServerCertificate argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--feature-gates\"\n              compare:\n                op: nothave\n                value: \"RotateKubeletServerCertificate=false\"\n              set: true\n            - flag: \"--feature-gates\"\n              set: false\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the master node and set the --feature-gates parameter to include RotateKubeletServerCertificate=true.\n          --feature-gates=RotateKubeletServerCertificate=true\n        scored: true\n\n      - id: 1.3.7\n        text: \"Ensure that the --bind-address argument is set to 127.0.0.1 (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--bind-address\"\n              compare:\n                op: eq\n                value: \"127.0.0.1\"\n            - flag: \"--bind-address\"\n              set: false\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the master node and ensure the correct value for the --bind-address parameter\n        scored: true\n\n  - id: 1.4\n    text: \"Scheduler\"\n    checks:\n      - id: 1.4.1\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: \"/bin/ps -ef | grep $schedulerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the Scheduler pod specification file $schedulerconf file\n          on the master node and set the below parameter.\n          --profiling=false\n        scored: true\n\n      - id: 1.4.2\n        text: \"Ensure that the --bind-address argument is set to 127.0.0.1 (Automated)\"\n        audit: \"/bin/ps -ef | grep $schedulerbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--bind-address\"\n              compare:\n                op: eq\n                value: \"127.0.0.1\"\n            - flag: \"--bind-address\"\n              set: false\n        remediation: |\n          Edit the Scheduler pod specification file $schedulerconf\n          on the master node and ensure the correct value for the --bind-address parameter\n        scored: true\n"
  },
  {
    "path": "cfg/ack-1.0/node.yaml",
    "content": "---\ncontrols:\nversion: \"ack-1.0\"\nid: 4\ntext: \"Worker Node Security Configuration\"\ntype: \"node\"\ngroups:\n  - id: 4.1\n    text: \"Worker Node Configuration Files\"\n    checks:\n      - id: 4.1.1\n        text: \"Ensure that the kubelet service file permissions are set to 644 or more restrictive (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletsvc; then stat -c permissions=%a $kubeletsvc; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chmod 644 $kubeletsvc\n        scored: true\n\n      - id: 4.1.2\n        text: \"Ensure that the kubelet service file ownership is set to root:root (Automated)\"\n        audit: '/bin/sh -c \"if test -e $kubeletsvc; then stat -c %U:%G $kubeletsvc; else echo \\\"File not found\\\"; fi\"'\n        tests:\n          bin_op: or\n          test_items:\n            - flag: root:root\n            - flag: \"File not found\"\n        remediation: |\n            Run the below command (based on the file location on your system) on the each worker node.\n            For example,\n            chown root:root $kubeletsvc\n        scored: true\n\n      - id: 4.1.3\n        text: \"If proxy kubeconfig file exists ensure permissions are set to 644 or more restrictive (Manual)\"\n        audit: '/bin/sh -c ''if test -e $proxykubeconfig; then stat -c permissions=%a $proxykubeconfig; fi'' '\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chmod 644 $proxykubeconfig\n        scored: false\n\n      - id: 4.1.4\n        text: \"If proxy kubeconfig file exists ensure ownership is set to root:root (Manual)\"\n        audit: '/bin/sh -c ''if test -e $proxykubeconfig; then stat -c %U:%G $proxykubeconfig; fi'' '\n        tests:\n          bin_op: or\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example, chown root:root $proxykubeconfig\n        scored: false\n\n      - id: 4.1.5\n        text: \"Ensure that the --kubeconfig kubelet.conf file permissions are set to 644 or more restrictive (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletkubeconfig; then stat -c permissions=%a $kubeletkubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chmod 644 $kubeletkubeconfig\n        scored: true\n\n      - id: 4.1.6\n        text: \"Ensure that the --kubeconfig kubelet.conf file ownership is set to root:root (Manual)\"\n        audit: '/bin/sh -c ''if test -e $kubeletkubeconfig; then stat -c %U:%G $kubeletkubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chown root:root $kubeletkubeconfig\n        scored: false\n\n      - id: 4.1.7\n        text: \"Ensure that the certificate authorities file permissions are set to 644 or more restrictive (Manual)\"\n        audit: |\n          CAFILE=$(ps -ef | grep kubelet | grep -v apiserver | grep -- --client-ca-file= | awk -F '--client-ca-file=' '{print $2}' | awk '{print $1}' | uniq)\n          if test -z $CAFILE; then CAFILE=$kubeletcafile; fi\n          if test -e $CAFILE; then stat -c permissions=%a $CAFILE; fi\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the following command to modify the file permissions of the\n          --client-ca-file chmod 644 <filename>\n        scored: false\n\n      - id: 4.1.8\n        text: \"Ensure that the client certificate authorities file ownership is set to root:root (Manual)\"\n        audit: |\n          CAFILE=$(ps -ef | grep kubelet | grep -v apiserver | grep -- --client-ca-file= | awk -F '--client-ca-file=' '{print $2}' | awk '{print $1}' | uniq)\n          if test -z $CAFILE; then CAFILE=$kubeletcafile; fi\n          if test -e $CAFILE; then stat -c %U:%G $CAFILE; fi\n        tests:\n          test_items:\n            - flag: root:root\n              compare:\n                op: eq\n                value: root:root\n        remediation: |\n          Run the following command to modify the ownership of the --client-ca-file.\n          chown root:root <filename>\n        scored: false\n\n      - id: 4.1.9\n        text: \"Ensure that the kubelet --config configuration file has permissions set to 644 or more restrictive (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletconf; then stat -c permissions=%a $kubeletconf; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the following command (using the config file location identified in the Audit step)\n          chmod 644 $kubeletconf\n        scored: true\n\n      - id: 4.1.10\n        text: \"Ensure that the kubelet --config configuration file ownership is set to root:root (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletconf; then stat -c %U:%G $kubeletconf; fi'' '\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the following command (using the config file location identified in the Audit step)\n          chown root:root $kubeletconf\n        scored: true\n\n  - id: 4.2\n    text: \"Kubelet\"\n    checks:\n      - id: 4.2.1\n        text: \"Ensure that the anonymous-auth argument is set to false (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: \"--anonymous-auth\"\n              path: '{.authentication.anonymous.enabled}'\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          If using a Kubelet config file, edit the file to set authentication: anonymous: enabled to\n          false.\n          If using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --anonymous-auth=false\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.2\n        text: \"Ensure that the --authorization-mode argument is not set to AlwaysAllow (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --authorization-mode\n              path: '{.authorization.mode}'\n              compare:\n                op: nothave\n                value: AlwaysAllow\n        remediation: |\n          If using a Kubelet config file, edit the file to set authorization: mode to Webhook. If\n          using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_AUTHZ_ARGS variable.\n          --authorization-mode=Webhook\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.3\n        text: \"Ensure that the --client-ca-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --client-ca-file\n              path: '{.authentication.x509.clientCAFile}'\n        remediation: |\n          If using a Kubelet config file, edit the file to set authentication: x509: clientCAFile to\n          the location of the client CA file.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_AUTHZ_ARGS variable.\n          --client-ca-file=<path/to/client-ca-file>\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.4\n        text: \"Ensure that the --read-only-port argument is set to 0 (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--read-only-port\"\n              path: '{.readOnlyPort}'\n              compare:\n                op: eq\n                value: 0\n            - flag: \"--read-only-port\"\n              path: '{.readOnlyPort}'\n              set: false\n        remediation: |\n          If using a Kubelet config file, edit the file to set readOnlyPort to 0.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --read-only-port=0\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.5\n        text: \"Ensure that the --streaming-connection-idle-timeout argument is not set to 0 (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --streaming-connection-idle-timeout\n              path: '{.streamingConnectionIdleTimeout}'\n              compare:\n                op: noteq\n                value: 0\n            - flag: --streaming-connection-idle-timeout\n              path: '{.streamingConnectionIdleTimeout}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to set streamingConnectionIdleTimeout to a\n          value other than 0.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --streaming-connection-idle-timeout=5m\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.6\n        text: \"Ensure that the --protect-kernel-defaults argument is set to true (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --protect-kernel-defaults\n              path: '{.protectKernelDefaults}'\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          If using a Kubelet config file, edit the file to set protectKernelDefaults: true.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --protect-kernel-defaults=true\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.7\n        text: \"Ensure that the --make-iptables-util-chains argument is set to true (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --make-iptables-util-chains\n              path: '{.makeIPTablesUtilChains}'\n              compare:\n                op: eq\n                value: true\n            - flag: --make-iptables-util-chains\n              path: '{.makeIPTablesUtilChains}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to set makeIPTablesUtilChains: true.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          remove the --make-iptables-util-chains argument from the\n          KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.8\n        text: \"Ensure that the --event-qps argument is set to 0 or a level which ensures appropriate event capture (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --event-qps\n              path: '{.eventRecordQPS}'\n              compare:\n                op: eq\n                value: 0\n        remediation: |\n          If using a Kubelet config file, edit the file to set eventRecordQPS: to an appropriate level.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.9\n        text: \"Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --tls-cert-file\n              path: '{.tlsCertFile}'\n            - flag: --tls-private-key-file\n              path: '{.tlsPrivateKeyFile}'\n        remediation: |\n          If using a Kubelet config file, edit the file to set tlsCertFile to the location\n          of the certificate file to use to identify this Kubelet, and tlsPrivateKeyFile\n          to the location of the corresponding private key file.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameters in KUBELET_CERTIFICATE_ARGS variable.\n          --tls-cert-file=<path/to/tls-certificate-file>\n          --tls-private-key-file=<path/to/tls-key-file>\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.10\n        text: \"Ensure that the Kubelet only makes use of Strong Cryptographic Ciphers (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --tls-cipher-suites\n              path: '{range .tlsCipherSuites[:]}{}{'',''}{end}'\n              compare:\n                op: valid_elements\n                value: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\n        remediation: |\n          If using a Kubelet config file, edit the file to set tlsCipherSuites: to\n          TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\n          or to a subset of these values.\n          If using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the --tls-cipher-suites parameter as follows, or to a subset of these values.\n          --tls-cipher-suites=TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n"
  },
  {
    "path": "cfg/ack-1.0/policies.yaml",
    "content": "---\ncontrols:\nversion: \"ack-1.0\"\nid: 5\ntext: \"Kubernetes Policies\"\ntype: \"policies\"\ngroups:\n  - id: 5.1\n    text: \"RBAC and Service Accounts\"\n    checks:\n      - id: 5.1.1\n        text: \"Ensure that the cluster-admin role is only used where required (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Identify all clusterrolebindings to the cluster-admin role. Check if they are used and\n          if they need this role or if they could use a role with fewer privileges.\n          Where possible, first bind users to a lower privileged role and then remove the\n          clusterrolebinding to the cluster-admin role :\n          kubectl delete clusterrolebinding [name]\n        scored: false\n\n      - id: 5.1.2\n        text: \"Minimize access to secrets (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove get, list and watch access to secret objects in the cluster.\n        scored: false\n\n      - id: 5.1.3\n        text: \"Minimize wildcard use in Roles and ClusterRoles (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible replace any use of wildcards in clusterroles and roles with specific\n          objects or actions.\n        scored: false\n\n      - id: 5.1.4\n        text: \"Minimize access to create pods (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove create access to pod objects in the cluster.\n        scored: false\n\n      - id: 5.1.5\n        text: \"Ensure that default service accounts are not actively used. (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Create explicit service accounts wherever a Kubernetes workload requires specific access\n          to the Kubernetes API server.\n          Modify the configuration of each default service account to include this value\n          automountServiceAccountToken: false\n        scored: false\n\n      - id: 5.1.6\n        text: \"Ensure that Service Account Tokens are only mounted where necessary (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Modify the definition of pods and service accounts which do not need to mount service\n          account tokens to disable it.\n        scored: false\n\n  - id: 5.2\n    text: \"Pod Security Policies\"\n    checks:\n      - id: 5.2.1\n        text: \"Minimize the admission of privileged containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that\n          the .spec.privileged field is omitted or set to false.\n        scored: false\n\n      - id: 5.2.2\n        text: \"Minimize the admission of containers wishing to share the host process ID namespace (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that the\n          .spec.hostPID field is omitted or set to false.\n        scored: false\n\n      - id: 5.2.3\n        text: \"Minimize the admission of containers wishing to share the host IPC namespace (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that the\n          .spec.hostIPC field is omitted or set to false.\n        scored: false\n\n      - id: 5.2.4\n        text: \"Minimize the admission of containers wishing to share the host network namespace (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that the\n          .spec.hostNetwork field is omitted or set to false.\n        scored: false\n\n      - id: 5.2.5\n        text: \"Minimize the admission of containers with allowPrivilegeEscalation (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that the\n          .spec.allowPrivilegeEscalation field is omitted or set to false.\n        scored: false\n\n      - id: 5.2.6\n        text: \"Minimize the admission of root containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that the\n          .spec.runAsUser.rule is set to either MustRunAsNonRoot or MustRunAs with the range of\n          UIDs not including 0.\n        scored: false\n\n      - id: 5.2.7\n        text: \"Minimize the admission of containers with the NET_RAW capability (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that the\n          .spec.requiredDropCapabilities is set to include either NET_RAW or ALL.\n        scored: false\n\n      - id: 5.2.8\n        text: \"Minimize the admission of containers with added capabilities (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that allowedCapabilities is not present in PSPs for the cluster unless\n          it is set to an empty array.\n        scored: false\n\n      - id: 5.2.9\n        text: \"Minimize the admission of containers with capabilities assigned (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Review the use of capabilites in applications runnning on your cluster. Where a namespace\n          contains applications which do not require any Linux capabities to operate consider adding\n          a PSP which forbids the admission of containers which do not drop all capabilities.\n        scored: false\n\n  - id: 5.3\n    text: \"Network Policies and CNI\"\n    checks:\n      - id: 5.3.1\n        text: \"Ensure that the CNI in use supports Network Policies (Manual)\"\n        type: \"manual\"\n        remediation: |\n          If the CNI plugin in use does not support network policies, consideration should be given to\n          making use of a different plugin, or finding an alternate mechanism for restricting traffic\n          in the Kubernetes cluster.\n        scored: false\n\n      - id: 5.3.2\n        text: \"Ensure that all Namespaces have Network Policies defined (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the documentation and create NetworkPolicy objects as you need them.\n        scored: false\n\n  - id: 5.4\n    text: \"Secrets Management\"\n    checks:\n      - id: 5.4.1\n        text: \"Prefer using secrets as files over secrets as environment variables (Manual)\"\n        type: \"manual\"\n        remediation: |\n          if possible, rewrite application code to read secrets from mounted secret files, rather than\n          from environment variables.\n        scored: false\n\n      - id: 5.4.2\n        text: \"Consider external secret storage (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Refer to the secrets management options offered by your cloud provider or a third-party\n          secrets management solution.\n        scored: false\n\n  - id: 5.5\n    text: \"Extensible Admission Control\"\n    checks:\n      - id: 5.5.1\n        text: \"Configure Image Provenance using ImagePolicyWebhook admission controller (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and setup image provenance.\n        scored: false\n\n  - id: 5.6\n    text: \"General Policies\"\n    checks:\n      - id: 5.6.1\n        text: \"Create administrative boundaries between resources using namespaces (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the documentation and create namespaces for objects in your deployment as you need\n          them.\n        scored: false\n\n      - id: 5.6.2\n        text: \"Ensure that the seccomp profile is set to docker/default in your pod definitions (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Seccomp is an alpha feature currently. By default, all alpha features are disabled. So, you\n          would need to enable alpha features in the apiserver by passing \"--feature-\n          gates=AllAlpha=true\" argument.\n          Edit the /etc/kubernetes/apiserver file on the master node and set the KUBE_API_ARGS\n          parameter to \"--feature-gates=AllAlpha=true\"\n          KUBE_API_ARGS=\"--feature-gates=AllAlpha=true\"\n          Based on your system, restart the kube-apiserver service. For example:\n          systemctl restart kube-apiserver.service\n          Use annotations to enable the docker/default seccomp profile in your pod definitions. An\n          example is as below:\n          apiVersion: v1\n          kind: Pod\n          metadata:\n            name: trustworthy-pod\n            annotations:\n              seccomp.security.alpha.kubernetes.io/pod: docker/default\n          spec:\n            containers:\n              - name: trustworthy-container\n                image: sotrustworthy:latest\n        scored: false\n\n      - id: 5.6.3\n        text: \"Apply Security Context to Your Pods and Containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and apply security contexts to your pods. For a\n          suggested list of security contexts, you may refer to the CIS Security Benchmark for Docker\n          Containers.\n        scored: false\n\n      - id: 5.6.4\n        text: \"The default namespace should not be used (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that namespaces are created to allow for appropriate segregation of Kubernetes\n          resources and that all new resources are created in a specific namespace.\n        scored: false\n"
  },
  {
    "path": "cfg/aks-1.0/config.yaml",
    "content": "---\n## Version-specific settings that override the values in cfg/config.yaml\n"
  },
  {
    "path": "cfg/aks-1.0/controlplane.yaml",
    "content": "---\ncontrols:\nversion: \"aks-1.0\"\nid: 2\ntext: \"Control Plane Configuration\"\ntype: \"controlplane\"\ngroups:\n  - id: 2.1\n    text: \"Logging\"\n    checks:\n      - id: 2.1.1\n        text: \"Enable audit Logs\"\n        type: \"manual\"\n        remediation: |\n          Azure audit logs are enabled and managed in the Azure portal. To enable log collection for\n          the Kubernetes master components in your AKS cluster, open the Azure portal in a web\n          browser and complete the following steps:\n          1. Select the resource group for your AKS cluster, such as myResourceGroup. Don't\n             select the resource group that contains your individual AKS cluster resources, such\n             as MC_myResourceGroup_myAKSCluster_eastus.\n          2. On the left-hand side, choose Diagnostic settings.\n          3. Select your AKS cluster, such as myAKSCluster, then choose to Add diagnostic setting.\n          4. Enter a name, such as myAKSClusterLogs, then select the option to Send to Log Analytics.\n          5. Select an existing workspace or create a new one. If you create a workspace, provide\n             a workspace name, a resource group, and a location.\n          6. In the list of available logs, select the logs you wish to enable. For this example,\n             enable the kube-audit and kube-audit-admin logs. Common logs include the kube-\n             apiserver, kube-controller-manager, and kube-scheduler. You can return and change\n             the collected logs once Log Analytics workspaces are enabled.\n          7. When ready, select Save to enable collection of the selected logs.\n        scored: false\n"
  },
  {
    "path": "cfg/aks-1.0/managedservices.yaml",
    "content": "---\ncontrols:\nversion: \"aks-1.0\"\nid: 5\ntext: \"Managed Services\"\ntype: \"managedservices\"\ngroups:\n  - id: 5.1\n    text: \"Image Registry and Image Scanning\"\n    checks:\n      - id: 5.1.1\n        text: \"Ensure Image Vulnerability Scanning using Azure Defender image scanning or a third party provider (Manual)\"\n        type: \"manual\"\n        remediation: \"No remediation\"\n        scored: false\n\n      - id: 5.1.2\n        text: \"Minimize user access to Azure Container Registry (ACR) (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Azure Container Registry\n          If you use Azure Container Registry (ACR) as your container image store, you need to grant\n          permissions to the service principal for your AKS cluster to read and pull images. Currently,\n          the recommended configuration is to use the az aks create or az aks update command to\n          integrate with a registry and assign the appropriate role for the service principal. For\n          detailed steps, see Authenticate with Azure Container Registry from Azure Kubernetes\n          Service.\n          To avoid needing an Owner or Azure account administrator role, you can configure a\n          service principal manually or use an existing service principal to authenticate ACR from\n          AKS. For more information, see ACR authentication with service principals or Authenticate\n          from Kubernetes with a pull secret.\n        scored: false\n\n      - id: 5.1.3\n        text: \"Minimize cluster access to read-only for Azure Container Registry (ACR) (Manual)\"\n        type: \"manual\"\n        remediation: \"No remediation\"\n        scored: false\n\n      - id: 5.1.4\n        text: \"Minimize Container Registries to only those approved (Manual)\"\n        type: \"manual\"\n        remediation: \"No remediation\"\n        scored: false\n\n  - id: 5.2\n    text: \"Access and identity options for Azure Kubernetes Service (AKS)\"\n    checks:\n      - id: 5.2.1\n        text: \"Prefer using dedicated AKS Service Accounts (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Azure Active Directory integration\n          The security of AKS clusters can be enhanced with the integration of Azure Active Directory\n          (AD). Built on decades of enterprise identity management, Azure AD is a multi-tenant,\n          cloud-based directory, and identity management service that combines core directory\n          services, application access management, and identity protection. With Azure AD, you can\n          integrate on-premises identities into AKS clusters to provide a single source for account\n          management and security.\n          Azure Active Directory integration with AKS clusters\n          With Azure AD-integrated AKS clusters, you can grant users or groups access to Kubernetes\n          resources within a namespace or across the cluster. To obtain a kubectl configuration\n          context, a user can run the az aks get-credentials command. When a user then interacts\n          with the AKS cluster with kubectl, they're prompted to sign in with their Azure AD\n          credentials. This approach provides a single source for user account management and\n          password credentials. The user can only access the resources as defined by the cluster\n          administrator.\n          Azure AD authentication is provided to AKS clusters with OpenID Connect. OpenID Connect\n          is an identity layer built on top of the OAuth 2.0 protocol. For more information on OpenID\n          Connect, see the Open ID connect documentation. From inside of the Kubernetes cluster,\n          Webhook Token Authentication is used to verify authentication tokens. Webhook token\n          authentication is configured and managed as part of the AKS cluster.\n        scored: false\n\n  - id: 5.3\n    text: \"Key Management Service (KMS)\"\n    checks:\n      - id: 5.3.1\n        text: \"Ensure Kubernetes Secrets are encrypted (Manual)\"\n        type: \"manual\"\n        remediation: \"No remediation\"\n        scored: false\n\n  - id: 5.4\n    text: \"Cluster Networking\"\n    checks:\n      - id: 5.4.1\n        text: \"Restrict Access to the Control Plane Endpoint (Manual)\"\n        type: \"manual\"\n        remediation: \"No remediation\"\n        scored: false\n\n      - id: 5.4.2\n        text: \"Ensure clusters are created with Private Endpoint Enabled and Public Access Disabled (Manual)\"\n        type: \"manual\"\n        remediation: \"No remediation\"\n        scored: false\n\n      - id: 5.4.3\n        text: \"Ensure clusters are created with Private Nodes (Manual)\"\n        type: \"manual\"\n        remediation: \"No remediation\"\n        scored: false\n\n      - id: 5.4.4\n        text: \"Ensure Network Policy is Enabled and set as appropriate (Manual)\"\n        type: \"manual\"\n        remediation: \"No remediation\"\n        scored: false\n\n      - id: 5.4.5\n        text: \"Encrypt traffic to HTTPS load balancers with TLS certificates (Manual)\"\n        type: \"manual\"\n        remediation: \"No remediation\"\n        scored: false\n\n\n  - id: 5.5\n    text: \"Authentication and Authorization\"\n    checks:\n      - id: 5.5.1\n        text: \"Manage Kubernetes RBAC users with Azure AD (Manual)\"\n        type: \"manual\"\n        remediation: \"No remediation\"\n        scored: false\n      - id: 5.5.2\n        text: \"Use Azure RBAC for Kubernetes Authorization (Manual)\"\n        type: \"manual\"\n        remediation: \"No remediation\"\n        scored: false\n\n  - id: 5.6\n    text: \"Other Cluster Configurations\"\n    checks:\n      - id: 5.6.1\n        text: \"Restrict untrusted workloads (Manual)\"\n        type: \"manual\"\n        remediation: \"No remediation\"\n        scored: false\n      - id: 5.6.2\n        text: \"Hostile multi-tenant workloads (Manual)\"\n        type: \"manual\"\n        remediation: \"No remediation\"\n        scored: false\n"
  },
  {
    "path": "cfg/aks-1.0/master.yaml",
    "content": "---\ncontrols:\nversion: \"aks-1.0\"\nid: 1\ntext: \"Control Plane Components\"\ntype: \"master\"\n"
  },
  {
    "path": "cfg/aks-1.0/node.yaml",
    "content": "---\ncontrols:\nversion: \"aks-1.0\"\nid: 3\ntext: \"Worker Node Security Configuration\"\ntype: \"node\"\ngroups:\n  - id: 3.1\n    text: \"Worker Node Configuration Files\"\n    checks:\n      - id: 3.1.1\n        text: \"Ensure that the kubeconfig file permissions are set to 644 or more restrictive (Manual)\"\n        audit: '/bin/sh -c ''if test -e $kubeletkubeconfig; then stat -c permissions=%a $kubeletkubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chmod 644 $kubeletkubeconfig\n        scored: false\n\n      - id: 3.1.2\n        text: \"Ensure that the kubelet kubeconfig file ownership is set to root:root (Manual)\"\n        audit: '/bin/sh -c ''if test -e $kubeletkubeconfig; then stat -c %U:%G $kubeletkubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chown root:root $kubeletkubeconfig\n        scored: false\n\n      - id: 3.1.3\n        text: \"Ensure that the kubelet configuration file has permissions set to 644 or more restrictive (Manual)\"\n        audit: '/bin/sh -c ''if test -e $kubeletconf; then stat -c permissions=%a $kubeletconf; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the following command (using the config file location identified in the Audit step)\n          chmod 644 $kubeletconf\n        scored: false\n\n      - id: 3.1.4\n        text: \"Ensure that the kubelet configuration file ownership is set to root:root (Manual)\"\n        audit: '/bin/sh -c ''if test -e $kubeletconf; then stat -c %U:%G $kubeletconf; fi'' '\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the following command (using the config file location identified in the Audit step)\n          chown root:root $kubeletconf\n        scored: false\n\n  - id: 3.2\n    text: \"Kubelet\"\n    checks:\n      - id: 3.2.1\n        text: \"Ensure that the --anonymous-auth argument is set to false (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: \"--anonymous-auth\"\n              path: '{.authentication.anonymous.enabled}'\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          If using a Kubelet config file, edit the file to set authentication: anonymous: enabled to\n          false.\n          If using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --anonymous-auth=false\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 3.2.2\n        text: \"Ensure that the --authorization-mode argument is not set to AlwaysAllow (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --authorization-mode\n              path: '{.authorization.mode}'\n              compare:\n                op: nothave\n                value: AlwaysAllow\n        remediation: |\n          If using a Kubelet config file, edit the file to set authorization: mode to Webhook. If\n          using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_AUTHZ_ARGS variable.\n          --authorization-mode=Webhook\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 3.2.3\n        text: \"Ensure that the --client-ca-file argument is set as appropriate (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --client-ca-file\n              path: '{.authentication.x509.clientCAFile}'\n              set: true\n        remediation: |\n          If using a Kubelet config file, edit the file to set authentication: x509: clientCAFile to\n          the location of the client CA file.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_AUTHZ_ARGS variable.\n          --client-ca-file=<path/to/client-ca-file>\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 3.2.4\n        text: \"Ensure that the --read-only-port argument is set to 0 (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: \"--read-only-port\"\n              path: '{.readOnlyPort}'\n              set: true\n              compare:\n                op: eq\n                value: 0\n        remediation: |\n          If using a Kubelet config file, edit the file to set readOnlyPort to 0.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --read-only-port=0\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 3.2.5\n        text: \"Ensure that the --streaming-connection-idle-timeout argument is not set to 0 (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --streaming-connection-idle-timeout\n              path: '{.streamingConnectionIdleTimeout}'\n              set: true\n              compare:\n                op: noteq\n                value: 0\n            - flag: --streaming-connection-idle-timeout\n              path: '{.streamingConnectionIdleTimeout}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to set streamingConnectionIdleTimeout to a\n          value other than 0.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --streaming-connection-idle-timeout=5m\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 3.2.6\n        text: \"Ensure that the --protect-kernel-defaults argument is set to true (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --protect-kernel-defaults\n              path: '{.protectKernelDefaults}'\n              set: true\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          If using a Kubelet config file, edit the file to set protectKernelDefaults: true.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --protect-kernel-defaults=true\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 3.2.7\n        text: \"Ensure that the --make-iptables-util-chains argument is set to true (Manual) \"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --make-iptables-util-chains\n              path: '{.makeIPTablesUtilChains}'\n              set: true\n              compare:\n                op: eq\n                value: true\n            - flag: --make-iptables-util-chains\n              path: '{.makeIPTablesUtilChains}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to set makeIPTablesUtilChains: true.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          remove the --make-iptables-util-chains argument from the\n          KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 3.2.8\n        text: \"Ensure that the --hostname-override argument is not set (Manual)\"\n        # This is one of those properties that can only be set as a command line argument.\n        # To check if the property is set as expected, we need to parse the kubelet command\n        # instead reading the Kubelet Configuration file.\n        audit: \"/bin/ps -fC $kubeletbin \"\n        tests:\n          test_items:\n            - flag: --hostname-override\n              set: false\n        remediation: |\n          Edit the kubelet service file $kubeletsvc\n          on each worker node and remove the --hostname-override argument from the\n          KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 3.2.9\n        text: \"Ensure that the --event-qps argument is set to 0 or a level which ensures appropriate event capture (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --event-qps\n              path: '{.eventRecordQPS}'\n              set: true\n              compare:\n                op: eq\n                value: 0\n        remediation: |\n          If using a Kubelet config file, edit the file to set eventRecordQPS: to an appropriate level.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 3.2.10\n        text: \"Ensure that the --rotate-certificates argument is not set to false (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --rotate-certificates\n              path: '{.rotateCertificates}'\n              set: true\n              compare:\n                op: eq\n                value: true\n            - flag: --rotate-certificates\n              path: '{.rotateCertificates}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to add the line rotateCertificates: true or\n          remove it altogether to use the default value.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          remove --rotate-certificates=false argument from the KUBELET_CERTIFICATE_ARGS\n          variable.\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 3.2.11\n        text: \"Ensure that the RotateKubeletServerCertificate argument is set to true (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: RotateKubeletServerCertificate\n              path: '{.featureGates.RotateKubeletServerCertificate}'\n              set: true\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Edit the kubelet service file $kubeletsvc\n          on each worker node and set the below parameter in KUBELET_CERTIFICATE_ARGS variable.\n          --feature-gates=RotateKubeletServerCertificate=true\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n"
  },
  {
    "path": "cfg/aks-1.0/policies.yaml",
    "content": "---\ncontrols:\nversion: \"aks-1.0\"\nid: 4\ntext: \"Policies\"\ntype: \"policies\"\ngroups:\n  - id: 4.1\n    text: \"RBAC and Service Accounts\"\n    checks:\n      - id: 4.1.1\n        text: \"Ensure that the cluster-admin role is only used where required (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Identify all clusterrolebindings to the cluster-admin role. Check if they are used and\n          if they need this role or if they could use a role with fewer privileges.\n          Where possible, first bind users to a lower privileged role and then remove the\n          clusterrolebinding to the cluster-admin role :\n          kubectl delete clusterrolebinding [name]\n        scored: false\n\n      - id: 4.1.2\n        text: \"Minimize access to secrets (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove get, list and watch access to secret objects in the cluster.\n        scored: false\n\n      - id: 4.1.3\n        text: \"Minimize wildcard use in Roles and ClusterRoles (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible replace any use of wildcards in clusterroles and roles with specific\n          objects or actions.\n        scored: false\n\n      - id: 4.1.4\n        text: \"Minimize access to create pods (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove create access to pod objects in the cluster.\n        scored: false\n\n      - id: 4.1.5\n        text: \"Ensure that default service accounts are not actively used. (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Create explicit service accounts wherever a Kubernetes workload requires specific access\n          to the Kubernetes API server.\n          Modify the configuration of each default service account to include this value\n          automountServiceAccountToken: false\n        scored: false\n\n      - id: 4.1.6\n        text: \"Ensure that Service Account Tokens are only mounted where necessary (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Modify the definition of pods and service accounts which do not need to mount service\n          account tokens to disable it.\n        scored: false\n\n  - id: 4.2\n    text: \"Pod Security Policies\"\n    checks:\n      - id: 4.2.1\n        text: \"Minimize the admission of privileged containers (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that\n          the .spec.privileged field is omitted or set to false.\n        scored: false\n\n      - id: 4.2.2\n        text: \"Minimize the admission of containers wishing to share the host process ID namespace (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that the\n          .spec.hostPID field is omitted or set to false.\n        scored: false\n\n      - id: 4.2.3\n        text: \"Minimize the admission of containers wishing to share the host IPC namespace (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that the\n          .spec.hostIPC field is omitted or set to false.\n        scored: false\n\n      - id: 4.2.4\n        text: \"Minimize the admission of containers wishing to share the host network namespace (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that the\n          .spec.hostNetwork field is omitted or set to false.\n        scored: false\n\n      - id: 4.2.5\n        text: \"Minimize the admission of containers with allowPrivilegeEscalation (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that the\n          .spec.allowPrivilegeEscalation field is omitted or set to false.\n        scored: false\n\n      - id: 4.2.6\n        text: \"Minimize the admission of root containers (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that the\n          .spec.runAsUser.rule is set to either MustRunAsNonRoot or MustRunAs with the range of\n          UIDs not including 0.\n        scored: false\n\n      - id: 4.2.7\n        text: \"Minimize the admission of containers with the NET_RAW capability (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that the\n          .spec.requiredDropCapabilities is set to include either NET_RAW or ALL.\n        scored: false\n\n      - id: 4.2.8\n        text: \"Minimize the admission of containers with added capabilities (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that allowedCapabilities is not present in PSPs for the cluster unless\n          it is set to an empty array.\n        scored: false\n\n      - id: 4.2.9\n        text: \"Minimize the admission of containers with capabilities assigned (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Review the use of capabilities in applications running on your cluster. Where a namespace\n          contains applications which do not require any Linux capabities to operate consider adding\n          a PSP which forbids the admission of containers which do not drop all capabilities.\n        scored: false\n\n  - id: 4.3\n    text: \"Azure Policy / OPA\"\n    checks: []\n\n  - id: 4.4\n    text: \"CNI Plugin\"\n    checks:\n      - id: 4.4.1\n        text: \"Ensure that the latest CNI version is used (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Review the documentation of AWS CNI plugin, and ensure latest CNI version is used.\n        scored: false\n\n      - id: 4.4.2\n        text: \"Ensure that all Namespaces have Network Policies defined (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the documentation and create NetworkPolicy objects as you need them.\n        scored: false\n\n  - id: 4.5\n    text: \"Secrets Management\"\n    checks:\n      - id: 4.5.1\n        text: \"Prefer using secrets as files over secrets as environment variables (Manual)\"\n        type: \"manual\"\n        remediation: |\n          If possible, rewrite application code to read secrets from mounted secret files, rather than\n          from environment variables.\n        scored: false\n\n      - id: 4.5.2\n        text: \"Consider external secret storage (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Refer to the secrets management options offered by your cloud provider or a third-party\n          secrets management solution.\n        scored: false\n\n  - id: 4.6\n    text: \"Extensible Admission Control\"\n    checks:\n      - id: 4.6.1\n        text: \"Verify that admission controllers are working as expected (Manual)\"\n        type: \"manual\"\n        remediation: \"No remediation\"\n        scored: false\n\n  - id: 4.7\n    text: \"General Policies\"\n    checks:\n      - id: 4.7.1\n        text: \"Create administrative boundaries between resources using namespaces (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the documentation and create namespaces for objects in your deployment as you need\n          them.\n        scored: false\n\n      - id: 4.7.2\n        text: \"Apply Security Context to Your Pods and Containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and apply security contexts to your pods. For a\n          suggested list of security contexts, you may refer to the CIS Security Benchmark for Docker\n          Containers.\n        scored: false\n\n      - id: 4.7.3\n        text: \"The default namespace should not be used (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that namespaces are created to allow for appropriate segregation of Kubernetes\n          resources and that all new resources are created in a specific namespace.\n        scored: false\n"
  },
  {
    "path": "cfg/aks-1.7/config.yaml",
    "content": "---\n## Version-specific settings that override the values in cfg/config.yaml\n"
  },
  {
    "path": "cfg/aks-1.7/controlplane.yaml",
    "content": "---\ncontrols:\nversion: \"aks-1.7\"\nid: 2\ntext: \"Control Plane Configuration\"\ntype: \"controlplane\"\ngroups:\n  - id: 2.1\n    text: \"Logging\"\n    checks:\n      - id: 2.1.1\n        text: \"Enable audit Logs\"\n        type: \"manual\"\n        remediation: |\n          Azure audit logs are enabled and managed in the Azure portal. To enable log collection for\n          the Kubernetes master components in your AKS cluster, open the Azure portal in a web\n          browser and complete the following steps:\n          1. Select the resource group for your AKS cluster, such as myResourceGroup. Don't\n             select the resource group that contains your individual AKS cluster resources, such\n             as MC_myResourceGroup_myAKSCluster_eastus.\n          2. On the left-hand side, choose Diagnostic settings.\n          3. Select your AKS cluster, such as myAKSCluster, then choose to Add diagnostic setting.\n          4. Enter a name, such as myAKSClusterLogs, then select the option to Send to Log Analytics.\n          5. Select an existing workspace or create a new one. If you create a workspace, provide\n             a workspace name, a resource group, and a location.\n          6. In the list of available logs, select the logs you wish to enable. For this example,\n             enable the kube-audit and kube-audit-admin logs. Common logs include the kube-\n             apiserver, kube-controller-manager, and kube-scheduler. You can return and change\n             the collected logs once Log Analytics workspaces are enabled.\n          7. When ready, select Save to enable collection of the selected logs.\n        scored: false\n"
  },
  {
    "path": "cfg/aks-1.7/managedservices.yaml",
    "content": "---\ncontrols:\nversion: \"aks-1.7\"\nid: 5\ntext: \"Managed Services\"\ntype: \"managedservices\"\ngroups:\n  - id: 5.1\n    text: \"Image Registry and Image Scanning\"\n    checks:\n      - id: 5.1.1\n        text: \"Ensure Image Vulnerability Scanning using Microsoft Defender for Cloud (MDC) image scanning or a third party provider (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Enable MDC for Container Registries by running the following Azure CLI command:\n          az security pricing create --name ContainerRegistry --tier Standard\n          Alternatively, use the following command to enable image scanning for your container registry:\n          az resource update --ids /subscriptions/{subscription-id}/resourceGroups/{resource-group-name}/providers/Microsoft.ContainerRegistry/registries/{registry-name} --set properties.enabled=true\n          Replace `subscription-id`, `resource-group-name`, and `registry-name` with the correct values for your environment.\n          Please note that enabling MDC for Container Registries will incur additional costs, so be sure to review the pricing information provided in the Azure documentation before enabling it.\n        scored: false\n\n      - id: 5.1.2\n        text: \"Minimize user access to Azure Container Registry (ACR) (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Azure Container Registry\n          If you use Azure Container Registry (ACR) as your container image store, you need to grant\n          permissions to the service principal for your AKS cluster to read and pull images. Currently,\n          the recommended configuration is to use the az aks create or az aks update command to\n          integrate with a registry and assign the appropriate role for the service principal. For\n          detailed steps, see Authenticate with Azure Container Registry from Azure Kubernetes\n          Service.\n          To avoid needing an Owner or Azure account administrator role, you can configure a\n          service principal manually or use an existing service principal to authenticate ACR from\n          AKS. For more information, see ACR authentication with service principals or Authenticate\n          from Kubernetes with a pull secret.\n        scored: false\n\n      - id: 5.1.3\n        text: \"Minimize cluster access to read-only for Azure Container Registry (ACR) (Manual)\"\n        type: \"manual\"\n        remediation: \"No remediation\"\n        scored: false\n\n      - id: 5.1.4\n        text: \"Minimize Container Registries to only those approved (Manual)\"\n        type: \"manual\"\n        remediation: |\n          If you are using **Azure Container Registry**, you can restrict access using firewall rules as described in the official documentation:\n          https://docs.microsoft.com/en-us/azure/container-registry/container-registry-firewall-access-rules\n          For other non-AKS repositories, you can use **admission controllers** or **Azure Policy** to enforce registry access restrictions.\n          Limiting or locking down egress traffic to specific container registries is also recommended. For more information, refer to:\n          https://docs.microsoft.com/en-us/azure/aks/limit-egress-traffic\n        scored: false\n\n\n  - id: 5.2\n    text: \"Access and identity options for Azure Kubernetes Service (AKS)\"\n    checks:\n      - id: 5.2.1\n        text: \"Prefer using dedicated AKS Service Accounts (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Azure Active Directory integration\n          The security of AKS clusters can be enhanced with the integration of Azure Active Directory\n          (AD). Built on decades of enterprise identity management, Azure AD is a multi-tenant,\n          cloud-based directory, and identity management service that combines core directory\n          services, application access management, and identity protection. With Azure AD, you can\n          integrate on-premises identities into AKS clusters to provide a single source for account\n          management and security.\n          Azure Active Directory integration with AKS clusters\n          With Azure AD-integrated AKS clusters, you can grant users or groups access to Kubernetes\n          resources within a namespace or across the cluster. To obtain a kubectl configuration\n          context, a user can run the az aks get-credentials command. When a user then interacts\n          with the AKS cluster with kubectl, they're prompted to sign in with their Azure AD\n          credentials. This approach provides a single source for user account management and\n          password credentials. The user can only access the resources as defined by the cluster\n          administrator.\n          Azure AD authentication is provided to AKS clusters with OpenID Connect. OpenID Connect\n          is an identity layer built on top of the OAuth 2.0 protocol. For more information on OpenID\n          Connect, see the Open ID connect documentation. From inside of the Kubernetes cluster,\n          Webhook Token Authentication is used to verify authentication tokens. Webhook token\n          authentication is configured and managed as part of the AKS cluster.\n        scored: false\n\n\n  - id: 5.3\n    text: \"Key Management Service (KMS)\"\n    checks:\n      - id: 5.3.1\n        text: \"Ensure Kubernetes Secrets are encrypted (Manual)\"\n        type: \"manual\"\n        remediation: \"No remediation\"\n        scored: false\n\n\n  - id: 5.4\n    text: \"Cluster Networking\"\n    checks:\n      - id: 5.4.1\n        text: \"Restrict Access to the Control Plane Endpoint (Manual)\"\n        type: \"manual\"\n        remediation: |\n          By enabling private endpoint access to the Kubernetes API server, all communication between your nodes and the API server stays within your VPC. You can also limit the IP addresses that can access your API server from the internet, or completely disable internet access to the API server.\n          With this in mind, you can update your cluster accordingly using the AKS CLI to ensure that Private Endpoint Access is enabled.\n          If you choose to also enable Public Endpoint Access then you should also configure a list of allowable CIDR blocks, resulting in restricted access from the internet. If you specify no CIDR blocks, then the public API server endpoint is able to receive and process requests from all IP addresses by defaulting to ['0.0.0.0/0'].\n          Example:\n          az aks update --name ${CLUSTER_NAME} --resource-group ${RESOURCE_GROUP} --api-server-access-profile enablePrivateCluster=true --api-server-access-profile authorizedIpRanges=192.168.1.0/24\n        scored: false\n\n      - id: 5.4.2\n        text: \"Ensure clusters are created with Private Endpoint Enabled and Public Access Disabled (Manual)\"\n        type: \"manual\"\n        remediation: |\n          To use a private endpoint, create a new private endpoint in your virtual network, then create a link between your virtual network and a new private DNS zone.\n          You can also restrict access to the public endpoint by enabling only specific CIDR blocks to access it. For example:\n          az aks update --name ${CLUSTER_NAME} --resource-group ${RESOURCE_GROUP} --api-server-access-profile enablePublicFqdn=false\n          This command disables the public API endpoint for your AKS cluster.\n        scored: false\n\n      - id: 5.4.3\n        text: \"Ensure clusters are created with Private Nodes (Manual)\"\n        type: \"manual\"\n        remediation: |\n          To create a private cluster, use the following command:\n          az aks create \\\n          --resource-group <private-cluster-resource-group> \\\n          --name <private-cluster-name> \\\n          --load-balancer-sku standard \\\n          --enable-private-cluster \\\n          --network-plugin azure \\\n          --vnet-subnet-id <subnet-id> \\\n          --docker-bridge-address <docker-bridge-address> \\\n          --dns-service-ip <dns-service-ip> \\\n          --service-cidr <service-cidr>\n          Ensure that --enable-private-cluster flag is set to enable private nodes in your cluster.\n        scored: false\n\n      - id: 5.4.4\n        text: \"Ensure Network Policy is Enabled and set as appropriate (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Utilize Calico or another network policy engine to segment and isolate your traffic.\n          Enable network policies on your AKS cluster by following the Azure documentation or using the `az aks` CLI to enable the network policy add-on.\n        scored: false\n\n\n      - id: 5.4.5\n        text: \"Encrypt traffic to HTTPS load balancers with TLS certificates (Manual)\"\n        type: \"manual\"\n        remediation: \"No remediation\"\n        scored: false\n\n\n  - id: 5.5\n    text: \"Authentication and Authorization\"\n    checks:\n      - id: 5.5.1\n        text: \"Manage Kubernetes RBAC users with Azure AD (Manual)\"\n        type: \"manual\"\n        remediation: \"No remediation\"\n        scored: false\n\n      - id: 5.5.2\n        text: \"Use Azure RBAC for Kubernetes Authorization (Manual)\"\n        type: \"manual\"\n        remediation: \"No remediation\"\n        scored: false\n"
  },
  {
    "path": "cfg/aks-1.7/master.yaml",
    "content": "---\ncontrols:\nversion: \"aks-1.7\"\nid: 1\ntext: \"Control Plane Components\"\ntype: \"master\"\n"
  },
  {
    "path": "cfg/aks-1.7/node.yaml",
    "content": "---\ncontrols:\nversion: \"aks-1.7\"\nid: 3\ntext: \"Worker Node Security Configuration\"\ntype: \"node\"\ngroups:\n  - id: 3.1\n    text: \"Worker Node Configuration Files\"\n    checks:\n      - id: 3.1.1\n        text: \"Ensure that the kubeconfig file permissions are set to 644 or more restrictive (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletkubeconfig; then stat -c permissions=%a $kubeletkubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chmod 644 $kubeletkubeconfig\n        scored: true\n\n      - id: 3.1.2\n        text: \"Ensure that the kubelet kubeconfig file ownership is set to root:root (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletkubeconfig; then stat -c %U:%G $kubeletkubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chown root:root $kubeletkubeconfig\n        scored: true\n\n      - id: 3.1.3\n        text: \"Ensure that the azure.json file has permissions set to 644 or more restrictive (Automated)\"\n        audit: '/bin/sh -c ''if test -e /etc/kubernetes/azure.json; then stat -c permissions=%a /etc/kubernetes/azure.json; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the following command (using the config file location identified in the Audit step)\n          chmod 644 $kubeletconf\n        scored: true\n\n      - id: 3.1.4\n        text: \"Ensure that the azure.json file ownership is set to root:root (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletconf; then stat -c %U:%G $kubeletconf; fi'' '\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the following command (using the config file location identified in the Audit step)\n          chown root:root $kubeletconf\n        scored: true\n\n\n  - id: 3.2\n    text: \"Kubelet\"\n    checks:\n      - id: 3.2.1\n        text: \"Ensure that the --anonymous-auth argument is set to false (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: \"--anonymous-auth\"\n              path: '{.authentication.anonymous.enabled}'\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          If using a Kubelet config file, edit the file to set authentication: anonymous: enabled to\n          false.\n          If using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --anonymous-auth=false\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 3.2.2\n        text: \"Ensure that the --authorization-mode argument is not set to AlwaysAllow (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --authorization-mode\n              path: '{.authorization.mode}'\n              compare:\n                op: nothave\n                value: AlwaysAllow\n        remediation: |\n          If using a Kubelet config file, edit the file to set authorization: mode to Webhook. If\n          using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_AUTHZ_ARGS variable.\n          --authorization-mode=Webhook\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 3.2.3\n        text: \"Ensure that the --client-ca-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --client-ca-file\n              path: '{.authentication.x509.clientCAFile}'\n              set: true\n        remediation: |\n          If using a Kubelet config file, edit the file to set authentication: x509: clientCAFile to\n          the location of the client CA file.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_AUTHZ_ARGS variable.\n          --client-ca-file=<path/to/client-ca-file>\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 3.2.4\n        text: \"Ensure that the --read-only-port is secured (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: \"--read-only-port\"\n              path: '{.readOnlyPort}'\n              set: true\n              compare:\n                op: eq\n                value: 0\n        remediation: |\n          If using a Kubelet config file, edit the file to set readOnlyPort to 0.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --read-only-port=0\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 3.2.5\n        text: \"Ensure that the --streaming-connection-idle-timeout argument is not set to 0 (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --streaming-connection-idle-timeout\n              path: '{.streamingConnectionIdleTimeout}'\n              set: true\n              compare:\n                op: noteq\n                value: 0\n            - flag: --streaming-connection-idle-timeout\n              path: '{.streamingConnectionIdleTimeout}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to set streamingConnectionIdleTimeout to a\n          value other than 0.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --streaming-connection-idle-timeout=5m\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 3.2.6\n        text: \"Ensure that the --make-iptables-util-chains argument is set to true (Automated) \"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --make-iptables-util-chains\n              path: '{.makeIPTablesUtilChains}'\n              set: true\n              compare:\n                op: eq\n                value: true\n            - flag: --make-iptables-util-chains\n              path: '{.makeIPTablesUtilChains}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to set makeIPTablesUtilChains: true.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          remove the --make-iptables-util-chains argument from the\n          KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n\n      - id: 3.2.7\n        text: \"Ensure that the --eventRecordQPS argument is set to 0 or a level which ensures appropriate event capture (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --event-qps\n              path: '{.eventRecordQPS}'\n              set: true\n              compare:\n                op: eq\n                value: 0\n        remediation: |\n          If using a Kubelet config file, edit the file to set the 'eventRecordQPS' value to an appropriate level (e.g., 5).\n          If using executable arguments, check the Kubelet service file `$kubeletsvc` on each worker node, and add the following parameter to the `KUBELET_ARGS` variable:\n          --eventRecordQPS=5\n          Ensure that there is no conflicting `--eventRecordQPS` setting in the service file that overrides the config file.\n          After making the changes, restart the Kubelet service:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n          systemctl status kubelet -l\n        scored: true\n\n\n      - id: 3.2.8\n        text: \"Ensure that the --rotate-certificates argument is not set to false (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --rotate-certificates\n              path: '{.rotateCertificates}'\n              set: true\n              compare:\n                op: eq\n                value: true\n            - flag: --rotate-certificates\n              path: '{.rotateCertificates}'\n              set: false\n          bin_op: or\n        remediation: |\n          If modifying the Kubelet config file, edit the `kubelet-config.json` file located at `/etc/kubernetes/kubelet/kubelet-config.json` and set the following parameter to `true`:\n          \"rotateCertificates\": true\n          Ensure that the Kubelet service file located at `/etc/systemd/system/kubelet.service.d/10-kubelet-args.conf` does not define the `--rotate-certificates` argument as `false`, as this would override the config file.\n          If using executable arguments, add the following line to the `KUBELET_CERTIFICATE_ARGS` variable:\n          --rotate-certificates=true\n          After making the necessary changes, restart the Kubelet service:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n          systemctl status kubelet -l\n        scored: true\n\n      - id: 3.2.9\n        text: \"Ensure that the RotateKubeletServerCertificate argument is set to true (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: RotateKubeletServerCertificate\n              path: '{.featureGates.RotateKubeletServerCertificate}'\n              set: true\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Edit the kubelet service file $kubeletsvc\n          on each worker node and set the below parameter in KUBELET_CERTIFICATE_ARGS variable.\n          --feature-gates=RotateKubeletServerCertificate=true\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n"
  },
  {
    "path": "cfg/aks-1.7/policies.yaml",
    "content": "---\ncontrols:\nversion: \"aks-1.7\"\nid: 4\ntext: \"Policies\"\ntype: \"policies\"\ngroups:\n  - id: 4.1\n    text: \"RBAC and Service Accounts\"\n    checks:\n      - id: 4.1.1\n        text: \"Ensure that the cluster-admin role is only used where required (Automated)\"\n        audit: |\n          kubectl get clusterrolebindings -o json | jq -r '\n            .items[]\n            | select(.roleRef.name == \"cluster-admin\")\n            | .subjects[]?\n            | select(.kind != \"Group\" or (.name != \"system:masters\" and .name != \"system:nodes\"))\n            | \"FOUND_CLUSTER_ADMIN_BINDING\"\n          ' || echo \"NO_CLUSTER_ADMIN_BINDINGS\"\n        tests:\n          test_items:\n            - flag: \"NO_CLUSTER_ADMIN_BINDINGS\"\n              set: true\n              compare:\n                op: eq\n                value: \"NO_CLUSTER_ADMIN_BINDINGS\"\n        remediation: |\n          Identify all clusterrolebindings to the cluster-admin role using:\n\n            kubectl get clusterrolebindings --no-headers | grep cluster-admin\n\n          Review if each of them actually needs this role. If not, remove the binding:\n\n            kubectl delete clusterrolebinding <binding-name>\n\n          Where possible, assign a less privileged ClusterRole.\n        scored: true\n\n      - id: 4.1.2\n        text: \"Minimize access to secrets (Automated)\"\n        audit: |\n          count=$(kubectl get roles --all-namespaces -o json | jq '\n            .items[]\n            | select(.rules[]?\n              | (.resources[]? == \"secrets\")\n              and ((.verbs[]? == \"get\") or (.verbs[]? == \"list\") or (.verbs[]? == \"watch\"))\n            )' | wc -l)\n\n          if [ \"$count\" -gt 0 ]; then\n            echo \"SECRETS_ACCESS_FOUND\"\n          fi\n        tests:\n          test_items:\n            - flag: \"SECRETS_ACCESS_FOUND\"\n              set: false\n        remediation: |\n          Identify all roles that grant access to secrets via get/list/watch verbs.\n          Use `kubectl edit role -n <namespace> <name>` to remove these permissions.\n          Alternatively, create a new least-privileged role that excludes secret access.\n        scored: true\n\n      - id: 4.1.3\n        text: \"Minimize wildcard use in Roles and ClusterRoles (Automated)\"\n        audit: |\n          wildcards=$(kubectl get roles --all-namespaces -o json | jq '\n            .items[] | select(\n              .rules[]? | (.verbs[]? == \"*\" or .resources[]? == \"*\" or .apiGroups[]? == \"*\")\n            )' | wc -l)\n\n          wildcards_clusterroles=$(kubectl get clusterroles -o json | jq '\n            .items[] | select(\n              .rules[]? | (.verbs[]? == \"*\" or .resources[]? == \"*\" or .apiGroups[]? == \"*\")\n            )' | wc -l)\n\n          total=$((wildcards + wildcards_clusterroles))\n\n          if [ \"$total\" -gt 0 ]; then\n            echo \"wildcards_present\"\n          fi\n        tests:\n          test_items:\n            - flag: wildcards_present\n              set: false\n        remediation: |\n          Identify roles and clusterroles using wildcards (*) in 'verbs', 'resources', or 'apiGroups'.\n          Replace wildcards with specific values to enforce least privilege access.\n          Use `kubectl edit role -n <namespace> <name>` or `kubectl edit clusterrole <name>` to update.\n        scored: true\n\n\n      - id: 4.1.4\n        text: \"Minimize access to create pods (Automated)\"\n        audit: |\n          echo \"🔹 Roles and ClusterRoles with 'create' access on 'pods':\"\n          access=$(kubectl get roles,clusterroles -A -o json | jq '\n            [.items[] |\n              select(\n                .rules[]? |\n                (.resources[]? == \"pods\" and .verbs[]? == \"create\")\n              )\n            ] | length')\n\n          if [ \"$access\" -gt 0 ]; then\n            echo \"pods_create_access\"\n          fi\n        tests:\n          test_items:\n            - flag: pods_create_access\n              set: false\n        remediation: |\n          Review all roles and clusterroles that have \"create\" permission on \"pods\".\n\n          🔒 Where possible, remove or restrict this permission to only required service accounts.\n\n          🛠 Use:\n            - `kubectl edit role -n <namespace> <role>`\n            - `kubectl edit clusterrole <name>`\n\n          ✅ Apply least privilege principle across the cluster.\n        scored: true\n\n\n      - id: 4.1.5\n        text: \"Ensure that default service accounts are not actively used (Automated)\"\n        audit: |\n          echo \"🔹 Default Service Accounts with automountServiceAccountToken enabled:\"\n          default_sa_count=$(kubectl get serviceaccounts --all-namespaces -o json | jq '\n            [.items[] | select(.metadata.name == \"default\" and (.automountServiceAccountToken != false))] | length')\n          if [ \"$default_sa_count\" -gt 0 ]; then\n            echo \"default_sa_not_auto_mounted\"\n          fi\n\n          echo \"\\n🔹 Pods using default ServiceAccount:\"\n          pods_using_default_sa=$(kubectl get pods --all-namespaces -o json | jq '\n            [.items[] | select(.spec.serviceAccountName == \"default\")] | length')\n          if [ \"$pods_using_default_sa\" -gt 0 ]; then\n            echo \"default_sa_used_in_pods\"\n          fi\n        tests:\n          test_items:\n            - flag: default_sa_not_auto_mounted\n              set: false\n            - flag: default_sa_used_in_pods\n              set: false\n        remediation: |\n          1. Avoid using default service accounts for workloads.\n          2. Set `automountServiceAccountToken: false` on all default SAs:\n             kubectl patch serviceaccount default -n <namespace> -p '{\"automountServiceAccountToken\": false}'\n          3. Use custom service accounts with only the necessary permissions.\n        scored: true\n\n\n      - id: 4.1.6\n        text: \"Ensure that Service Account Tokens are only mounted where necessary (Automated)\"\n        audit: |\n          echo \"🔹 Pods with automountServiceAccountToken enabled:\"\n          pods_with_token_mount=$(kubectl get pods --all-namespaces -o json | jq '\n            [.items[] | select(.spec.automountServiceAccountToken != false)] | length')\n\n          if [ \"$pods_with_token_mount\" -gt 0 ]; then\n            echo \"automountServiceAccountToken\"\n          fi\n        tests:\n          test_items:\n            - flag: automountServiceAccountToken\n              set: false\n        remediation: |\n          Pods that do not need access to the Kubernetes API should not mount service account tokens.\n\n          ✅ To disable token mounting in a pod definition:\n          ```yaml\n          spec:\n            automountServiceAccountToken: false\n          ```\n\n          ✅ Or patch an existing pod's spec (recommended via workload template):\n          Patch not possible for running pods — update the deployment YAML or recreate pods with updated spec.\n        scored: true\n\n\n  - id: 4.2\n    text: \"Pod Security Policies\"\n    checks:\n      - id: 4.2.1\n        text: \"Minimize the admission of privileged containers (Automated)\"\n        audit: |\n          kubectl get pods --all-namespaces -o json | \\\n            jq -r 'if any(.items[]?.spec.containers[]?; .securityContext?.privileged == true) then \"PRIVILEGED_FOUND\" else \"NO_PRIVILEGED\" end'\n        tests:\n          test_items:\n            - flag: \"NO_PRIVILEGED\"\n              set: true\n              compare:\n                op: eq\n                value: \"NO_PRIVILEGED\"\n        remediation: |\n          Add a Pod Security Admission (PSA) policy to each namespace in the cluster to restrict the admission of privileged containers.\n          To enforce a restricted policy for a specific namespace, use the following command:\n          kubectl label --overwrite ns NAMESPACE pod-security.kubernetes.io/enforce=restricted\n          You can also enforce PSA for all namespaces:\n          kubectl label --overwrite ns --all pod-security.kubernetes.io/warn=baseline\n          Additionally, review the namespaces that should be excluded (e.g., `kube-system`, `gatekeeper-system`, `azure-arc`, `azure-extensions-usage-system`) and adjust your filtering if necessary.\n          To enable Pod Security Policies, refer to the detailed documentation for Kubernetes and Azure integration at:\n          https://learn.microsoft.com/en-us/azure/governance/policy/concepts/policy-for-kubernetes\n        scored: true\n\n      - id: 4.2.2\n        text: \"Minimize the admission of containers wishing to share the host process ID namespace (Automated)\"\n        audit: |\n          kubectl get pods --all-namespaces -o json | \\\n            jq -r 'if any(.items[]?; .spec.hostPID == true) then \"HOSTPID_FOUND\" else \"NO_HOSTPID\" end'\n        tests:\n          test_items:\n            - flag: \"NO_HOSTPID\"\n              set: true\n              compare:\n                op: eq\n                value: \"NO_HOSTPID\"\n\n        remediation: |\n          Add a policy to each namespace in the cluster that restricts the admission of containers with hostPID. For namespaces that need it, ensure RBAC controls limit access to a specific service account.\n          You can label your namespaces as follows to restrict or enforce the policy:\n          kubectl label --overwrite ns NAMESPACE pod-security.kubernetes.io/enforce=restricted\n          You can also use the following to warn about policies:\n          kubectl label --overwrite ns --all pod-security.kubernetes.io/warn=baseline\n          For more information, refer to the official Kubernetes and Azure documentation on policies:\n          https://learn.microsoft.com/en-us/azure/governance/policy/concepts/policy-for-kubernetes\n        scored: true\n\n      - id: 4.2.3\n        text: \"Minimize the admission of containers wishing to share the host IPC namespace (Automated)\"\n        audit: |\n          kubectl get pods --all-namespaces -o json | jq -r 'if any(.items[]?; .spec.hostIPC == true) then \"HOSTIPC_FOUND\" else \"NO_HOSTIPC\" end'\n        tests:\n          test_items:\n            - flag: \"NO_HOSTIPC\"\n              set: true\n              compare:\n                op: eq\n                value: \"NO_HOSTIPC\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the admission of hostIPC containers.\n          You can label your namespaces as follows to restrict or enforce the policy:\n          kubectl label --overwrite ns NAMESPACE pod-security.kubernetes.io/enforce=restricted\n          You can also use the following to warn about policies:\n          kubectl label --overwrite ns --all pod-security.kubernetes.io/warn=baseline\n          For more information, refer to the official Kubernetes and Azure documentation on policies:\n          https://learn.microsoft.com/en-us/azure/governance/policy/concepts/policy-for-kubernetes\n        scored: true\n\n      - id: 4.2.4\n        text: \"Minimize the admission of containers wishing to share the host network namespace (Automated)\"\n        audit: |\n          kubectl get pods --all-namespaces -o json | jq -r 'if any(.items[]?; .spec.hostNetwork == true) then \"HOSTNETWORK_FOUND\" else \"NO_HOSTNETWORK\" end'\n        tests:\n          test_items:\n            - flag: \"NO_HOSTNETWORK\"\n              set: true\n              compare:\n                op: eq\n                value: \"NO_HOSTNETWORK\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the admission of hostNetwork containers.\n          You can label your namespaces as follows to restrict or enforce the policy:\n          kubectl label --overwrite ns NAMESPACE pod-security.kubernetes.io/enforce=restricted\n          You can also use the following to warn about policies:\n          kubectl label --overwrite ns --all pod-security.kubernetes.io/warn=baseline\n          For more information, refer to the official Kubernetes and Azure documentation on policies:\n          https://learn.microsoft.com/en-us/azure/governance/policy/concepts/policy-for-kubernetes\n        scored: true\n\n      - id: 4.2.5\n        text: \"Minimize the admission of containers with allowPrivilegeEscalation (Automated)\"\n        audit: |\n          kubectl get pods --all-namespaces -o json | \\\n            jq -r 'if any(.items[]?.spec.containers[]?; .securityContext?.allowPrivilegeEscalation == true) then \"ALLOWPRIVILEGEESCALTION_FOUND\" else \"NO_ALLOWPRIVILEGEESCALTION\" end'\n        tests:\n          test_items:\n            - flag: \"NO_ALLOWPRIVILEGEESCALTION\"\n              set: true\n              compare:\n                op: eq\n                value: \"NO_ALLOWPRIVILEGEESCALTION\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the admission of containers with .spec.allowPrivilegeEscalation set to true.\n          You can label your namespaces as follows to restrict or enforce the policy:\n          kubectl label --overwrite ns NAMESPACE pod-security.kubernetes.io/enforce=restricted\n          You can also use the following to warn about policies:\n          kubectl label --overwrite ns --all pod-security.kubernetes.io/warn=baseline\n          For more information, refer to the official Kubernetes and Azure documentation on policies:\n          https://learn.microsoft.com/en-us/azure/governance/policy/concepts/policy-for-kubernetes\n        scored: true\n\n\n  - id: 4.3\n    text: \"Azure Policy / OPA\"\n    checks: []\n\n\n  - id: 4.4\n    text: \"CNI Plugin\"\n    checks:\n      - id: 4.4.1\n        text: \"Ensure latest CNI version is used (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Review the documentation of AWS CNI plugin, and ensure latest CNI version is used.\n        scored: false\n\n      - id: 4.4.2\n        text: \"Ensure that all Namespaces have Network Policies defined (Automated)\"\n        audit: |\n          ns_without_np=$(comm -23 \\\n            <(kubectl get ns -o jsonpath='{.items[*].metadata.name}' | tr ' ' '\\n' | sort) \\\n            <(kubectl get networkpolicy --all-namespaces -o jsonpath='{.items[*].metadata.namespace}' | tr ' ' '\\n' | sort))\n          if [ -z \"$ns_without_np\" ]; then echo \"ALL_NAMESPACES_HAVE_NETWORKPOLICIES\"; else echo \"MISSING_NETWORKPOLICIES\"; fi\n        tests:\n          test_items:\n            - flag: \"ALL_NAMESPACES_HAVE_NETWORKPOLICIES\"\n              set: true\n              compare:\n                op: eq\n                value: \"ALL_NAMESPACES_HAVE_NETWORKPOLICIES\"\n        remediation: |\n          Define at least one NetworkPolicy in each namespace to control pod-level traffic. Example:\n\n          kubectl apply -n <namespace> -f - <<EOF\n          apiVersion: networking.k8s.io/v1\n          kind: NetworkPolicy\n          metadata:\n            name: default-deny-all\n          spec:\n            podSelector: {}\n            policyTypes:\n              - Ingress\n              - Egress\n          EOF\n\n          This denies all traffic unless explicitly allowed. Review and adjust policies per namespace as needed.\n        scored: true\n\n\n  - id: 4.5\n    text: \"Secrets Management\"\n    checks:\n      - id: 4.5.1\n        text: \"Prefer using secrets as files over secrets as environment variables (Automated)\"\n        audit: |\n          output=$(kubectl get all --all-namespaces -o jsonpath='{range .items[?(@..secretKeyRef)]} {.kind} {.metadata.name} {\"\\n\"}{end}')\n          if [ -z \"$output\" ]; then echo \"NO_ENV_SECRET_REFERENCES\"; else echo \"ENV_SECRET_REFERENCES_FOUND\"; fi\n        tests:\n          test_items:\n            - flag: \"NO_ENV_SECRET_REFERENCES\"\n              set: true\n              compare:\n                op: eq\n                value: \"NO_ENV_SECRET_REFERENCES\"\n        remediation: |\n          Refactor application deployments to mount secrets as files instead of passing them as environment variables.\n          Avoid using `envFrom` or `env` with `secretKeyRef` in container specs.\n        scored: true\n\n\n      - id: 4.5.2\n        text: \"Consider external secret storage (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Refer to the secrets management options offered by your cloud provider or a third-party\n          secrets management solution.\n        scored: false\n\n\n  - id: 4.6\n    text: \"General Policies\"\n    checks:\n      - id: 4.6.1\n        text: \"Create administrative boundaries between resources using namespaces (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the documentation and create namespaces for objects in your deployment as you need\n          them.\n        scored: false\n\n      - id: 4.6.2\n        text: \"Apply Security Context to Your Pods and Containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and apply security contexts to your pods. For a\n          suggested list of security contexts, you may refer to the CIS Security Benchmark for Docker\n          Containers.\n        scored: false\n\n      - id: 4.6.3\n        text: \"The default namespace should not be used (Automated)\"\n        audit: |\n          output=$(kubectl get all -n default --no-headers 2>/dev/null | grep -v '^service\\s\\+kubernetes\\s' || true)\n          if [ -z \"$output\" ]; then echo \"DEFAULT_NAMESPACE_UNUSED\"; else echo \"DEFAULT_NAMESPACE_IN_USE\"; fi\n        tests:\n          test_items:\n            - flag: \"DEFAULT_NAMESPACE_UNUSED\"\n              set: true\n              compare:\n                op: eq\n                value: \"DEFAULT_NAMESPACE_UNUSED\"\n        remediation: |\n          Avoid using the default namespace for user workloads.\n          - Create separate namespaces for your applications and infrastructure components.\n          - Move any user-defined resources out of the default namespace.\n\n          Example to create a namespace:\n          kubectl create namespace my-namespace\n\n          Example to move resources:\n          kubectl get deployment my-app -n default -o yaml | sed 's/namespace: default/namespace: my-namespace/' | kubectl apply -f -\n          kubectl delete deployment my-app -n default\n        scored: true\n"
  },
  {
    "path": "cfg/aks-1.8/config.yaml",
    "content": "---\n## Version-specific settings that override the values in cfg/config.yaml\n"
  },
  {
    "path": "cfg/aks-1.8/controlplane.yaml",
    "content": "---\ncontrols:\nversion: \"aks-1.8\"\nid: 2\ntext: \"Control Plane Configuration\"\ntype: \"controlplane\"\ngroups:\n  - id: 2.1\n    text: \"Logging\"\n    checks:\n      - id: 2.1.1\n        text: \"Enable audit Logs\"\n        type: \"manual\"\n        remediation: |\n          Azure audit logs are enabled and managed in the Azure portal. To enable log collection for\n          the Kubernetes master components in your AKS cluster, open the Azure portal in a web\n          browser and complete the following steps:\n          1. Select the resource group for your AKS cluster, such as myResourceGroup. Don't\n             select the resource group that contains your individual AKS cluster resources, such\n             as MC_myResourceGroup_myAKSCluster_eastus.\n          2. On the left-hand side, choose Diagnostic settings.\n          3. Select your AKS cluster, such as myAKSCluster, then choose to Add diagnostic setting.\n          4. Enter a name, such as myAKSClusterLogs, then select the option to Send to Log Analytics.\n          5. Select an existing workspace or create a new one. If you create a workspace, provide\n             a workspace name, a resource group, and a location.\n          6. In the list of available logs, select the logs you wish to enable. For this example,\n             enable the kube-audit and kube-audit-admin logs. Common logs include the kube-\n             apiserver, kube-controller-manager, and kube-scheduler. You can return and change\n             the collected logs once Log Analytics workspaces are enabled.\n          7. When ready, select Save to enable collection of the selected logs.\n        scored: false\n"
  },
  {
    "path": "cfg/aks-1.8/managedservices.yaml",
    "content": "---\ncontrols:\nversion: \"aks-1.8\"\nid: 5\ntext: \"Managed Services\"\ntype: \"managedservices\"\ngroups:\n  - id: 5.1\n    text: \"Image Registry and Image Scanning\"\n    checks:\n      - id: 5.1.1\n        text: \"Ensure Image Vulnerability Scanning using Microsoft Defender for Cloud (MDC) image scanning or a third party provider (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Enable MDC for Container Registries by running the following Azure CLI command:\n          az security pricing create --name ContainerRegistry --tier Standard\n          Alternatively, use the following command to enable image scanning for your container registry:\n          az resource update --ids /subscriptions/{subscription-id}/resourceGroups/{resource-group-name}/providers/Microsoft.ContainerRegistry/registries/{registry-name} --set properties.enabled=true\n          Replace `subscription-id`, `resource-group-name`, and `registry-name` with the correct values for your environment.\n          Please note that enabling MDC for Container Registries will incur additional costs, so be sure to review the pricing information provided in the Azure documentation before enabling it.\n        scored: false\n\n      - id: 5.1.2\n        text: \"Minimize user access to Azure Container Registry (ACR) (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Azure Container Registry\n          If you use Azure Container Registry (ACR) as your container image store, you need to grant\n          permissions to the service principal for your AKS cluster to read and pull images. Currently,\n          the recommended configuration is to use the az aks create or az aks update command to\n          integrate with a registry and assign the appropriate role for the service principal. For\n          detailed steps, see Authenticate with Azure Container Registry from Azure Kubernetes\n          Service.\n          To avoid needing an Owner or Azure account administrator role, you can configure a\n          service principal manually or use an existing service principal to authenticate ACR from\n          AKS. For more information, see ACR authentication with service principals or Authenticate\n          from Kubernetes with a pull secret.\n        scored: false\n\n      - id: 5.1.3\n        text: \"Minimize cluster access to read-only for Azure Container Registry (ACR) (Manual)\"\n        type: \"manual\"\n        remediation: \"No remediation\"\n        scored: false\n\n      - id: 5.1.4\n        text: \"Minimize Container Registries to only those approved (Manual)\"\n        type: \"manual\"\n        remediation: |\n          If you are using **Azure Container Registry**, you can restrict access using firewall rules as described in the official documentation:\n          https://docs.microsoft.com/en-us/azure/container-registry/container-registry-firewall-access-rules\n          For other non-AKS repositories, you can use **admission controllers** or **Azure Policy** to enforce registry access restrictions.\n          Limiting or locking down egress traffic to specific container registries is also recommended. For more information, refer to:\n          https://docs.microsoft.com/en-us/azure/aks/limit-egress-traffic\n        scored: false\n\n\n  - id: 5.2\n    text: \"Access and identity options for Azure Kubernetes Service (AKS)\"\n    checks:\n      - id: 5.2.1\n        text: \"Prefer using dedicated AKS Service Accounts (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Azure Active Directory integration\n          The security of AKS clusters can be enhanced with the integration of Azure Active Directory\n          (AD). Built on decades of enterprise identity management, Azure AD is a multi-tenant,\n          cloud-based directory, and identity management service that combines core directory\n          services, application access management, and identity protection. With Azure AD, you can\n          integrate on-premises identities into AKS clusters to provide a single source for account\n          management and security.\n          Azure Active Directory integration with AKS clusters\n          With Azure AD-integrated AKS clusters, you can grant users or groups access to Kubernetes\n          resources within a namespace or across the cluster. To obtain a kubectl configuration\n          context, a user can run the az aks get-credentials command. When a user then interacts\n          with the AKS cluster with kubectl, they're prompted to sign in with their Azure AD\n          credentials. This approach provides a single source for user account management and\n          password credentials. The user can only access the resources as defined by the cluster\n          administrator.\n          Azure AD authentication is provided to AKS clusters with OpenID Connect. OpenID Connect\n          is an identity layer built on top of the OAuth 2.0 protocol. For more information on OpenID\n          Connect, see the Open ID connect documentation. From inside of the Kubernetes cluster,\n          Webhook Token Authentication is used to verify authentication tokens. Webhook token\n          authentication is configured and managed as part of the AKS cluster.\n        scored: false\n\n\n  - id: 5.3\n    text: \"Key Management Service (KMS)\"\n    checks:\n      - id: 5.3.1\n        text: \"Ensure Kubernetes Secrets are encrypted (Manual)\"\n        type: \"manual\"\n        remediation: \"No remediation\"\n        scored: false\n\n\n  - id: 5.4\n    text: \"Cluster Networking\"\n    checks:\n      - id: 5.4.1\n        text: \"Restrict Access to the Control Plane Endpoint (Manual)\"\n        type: \"manual\"\n        remediation: |\n          By enabling private endpoint access to the Kubernetes API server, all communication between your nodes and the API server stays within your VPC. You can also limit the IP addresses that can access your API server from the internet, or completely disable internet access to the API server.\n          With this in mind, you can update your cluster accordingly using the AKS CLI to ensure that Private Endpoint Access is enabled.\n          If you choose to also enable Public Endpoint Access then you should also configure a list of allowable CIDR blocks, resulting in restricted access from the internet. If you specify no CIDR blocks, then the public API server endpoint is able to receive and process requests from all IP addresses by defaulting to ['0.0.0.0/0'].\n          Example:\n          az aks update --name ${CLUSTER_NAME} --resource-group ${RESOURCE_GROUP} --api-server-access-profile enablePrivateCluster=true --api-server-access-profile authorizedIpRanges=192.168.1.0/24\n        scored: false\n\n      - id: 5.4.2\n        text: \"Ensure clusters are created with Private Endpoint Enabled and Public Access Disabled (Manual)\"\n        type: \"manual\"\n        remediation: |\n          To use a private endpoint, create a new private endpoint in your virtual network, then create a link between your virtual network and a new private DNS zone.\n          You can also restrict access to the public endpoint by enabling only specific CIDR blocks to access it. For example:\n          az aks update --name ${CLUSTER_NAME} --resource-group ${RESOURCE_GROUP} --api-server-access-profile enablePublicFqdn=false\n          This command disables the public API endpoint for your AKS cluster.\n        scored: false\n\n      - id: 5.4.3\n        text: \"Ensure clusters are created with Private Nodes (Manual)\"\n        type: \"manual\"\n        remediation: |\n          To create a private cluster, use the following command:\n          az aks create \\\n          --resource-group <private-cluster-resource-group> \\\n          --name <private-cluster-name> \\\n          --load-balancer-sku standard \\\n          --enable-private-cluster \\\n          --network-plugin azure \\\n          --vnet-subnet-id <subnet-id> \\\n          --docker-bridge-address <docker-bridge-address> \\\n          --dns-service-ip <dns-service-ip> \\\n          --service-cidr <service-cidr>\n          Ensure that --enable-private-cluster flag is set to enable private nodes in your cluster.\n        scored: false\n\n      - id: 5.4.4\n        text: \"Ensure Network Policy is Enabled and set as appropriate (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Utilize Calico or another network policy engine to segment and isolate your traffic.\n          Enable network policies on your AKS cluster by following the Azure documentation or using the `az aks` CLI to enable the network policy add-on.\n        scored: false\n\n\n      - id: 5.4.5\n        text: \"Encrypt traffic to HTTPS load balancers with TLS certificates (Manual)\"\n        type: \"manual\"\n        remediation: \"No remediation\"\n        scored: false\n\n\n  - id: 5.5\n    text: \"Authentication and Authorization\"\n    checks:\n      - id: 5.5.1\n        text: \"Manage Kubernetes RBAC users with Azure AD (Manual)\"\n        type: \"manual\"\n        remediation: \"No remediation\"\n        scored: false\n\n      - id: 5.5.2\n        text: \"Use Azure RBAC for Kubernetes Authorization (Manual)\"\n        type: \"manual\"\n        remediation: \"No remediation\"\n        scored: false\n"
  },
  {
    "path": "cfg/aks-1.8/master.yaml",
    "content": "---\ncontrols:\nversion: \"aks-1.8\"\nid: 1\ntext: \"Control Plane Components\"\ntype: \"master\"\n"
  },
  {
    "path": "cfg/aks-1.8/node.yaml",
    "content": "---\ncontrols:\nversion: \"aks-1.8\"\nid: 3\ntext: \"Worker Node Security Configuration\"\ntype: \"node\"\ngroups:\n  - id: 3.1\n    text: \"Worker Node Configuration Files\"\n    checks:\n      - id: 3.1.1\n        text: \"Ensure that the kubeconfig file permissions are set to 644 or more restrictive (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletkubeconfig; then stat -c permissions=%a $kubeletkubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on each worker node.\n          For example:\n            chmod 644 $kubeletkubeconfig\n        scored: true\n\n      - id: 3.1.2\n        text: \"Ensure that the kubelet kubeconfig file ownership is set to root:root (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletkubeconfig; then stat -c %U:%G $kubeletkubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the below command (based on the file location on your system) on each worker node.\n          For example:\n            chown root:root $kubeletkubeconfig\n        scored: true\n\n      - id: 3.1.3\n        text: \"Ensure that the azure.json file has permissions set to 644 or more restrictive (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletconf; then stat -c permissions=%a $kubeletconf; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the following command on each worker node:\n            chmod 644 $azurejson\n        scored: true\n\n      - id: 3.1.4\n        text: \"Ensure that the azure.json file ownership is set to root:root (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletconf; then stat -c %U:%G $kubeletconf; fi'' '\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the following command on each worker node:\n            chown root:root $azurejson\n        scored: true\n\n\n  - id: 3.2\n    text: \"Kubelet\"\n    checks:\n      - id: 3.2.1\n        text: \"Ensure that the --anonymous-auth argument is set to false (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: \"--anonymous-auth\"\n              path: '{.authentication.anonymous.enabled}'\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          If using a Kubelet config file, edit the file to set authentication: anonymous: enabled to\n          false.\n          If using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --anonymous-auth=false\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 3.2.2\n        text: \"Ensure that the --authorization-mode argument is not set to AlwaysAllow (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: \"--anonymous-auth\"\n              path: '{.authorization.mode}'\n              compare:\n                op: nothave\n                value: AlwaysAllow\n        remediation: |\n          If using a Kubelet config file, edit the file to set authorization: mode to Webhook. If\n          using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_AUTHZ_ARGS variable.\n          --authorization-mode=Webhook\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 3.2.3\n        text: \"Ensure that the --client-ca-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --client-ca-file\n              path: '{.authentication.x509.clientCAFile}'\n              set: true\n        remediation: |\n          If using a Kubelet config file, edit the file to set authentication: x509: clientCAFile to\n          the location of the client CA file.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_AUTHZ_ARGS variable.\n          --client-ca-file=<path/to/client-ca-file>\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 3.2.4\n        text: \"Ensure that the --read-only-port is secured (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: \"--read-only-port\"\n              path: '{.readOnlyPort}'\n              set: true\n              compare:\n                op: eq\n                value: 0\n        remediation: |\n          If using a Kubelet config file, edit the file to set readOnlyPort to 0.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --read-only-port=0\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 3.2.5\n        text: \"Ensure that the --streaming-connection-idle-timeout argument is not set to 0 (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --streaming-connection-idle-timeout\n              path: '{.streamingConnectionIdleTimeout}'\n              set: true\n              compare:\n                op: noteq\n                value: 0\n            - flag: --streaming-connection-idle-timeout\n              path: '{.streamingConnectionIdleTimeout}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to set streamingConnectionIdleTimeout to a\n          value other than 0.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --streaming-connection-idle-timeout=5m\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 3.2.6\n        text: \"Ensure that the --make-iptables-util-chains argument is set to true (Automated) \"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --make-iptables-util-chains\n              path: '{.makeIPTablesUtilChains}'\n              set: true\n              compare:\n                op: eq\n                value: true\n            - flag: --make-iptables-util-chains\n              path: '{.makeIPTablesUtilChains}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to set makeIPTablesUtilChains: true.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          remove the --make-iptables-util-chains argument from the\n          KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n\n      - id: 3.2.7\n        text: \"Ensure that the --eventRecordQPS argument is set to 0 or a level which ensures appropriate event capture (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --event-qps\n              path: '{.eventRecordQPS}'\n              set: true\n              compare:\n                op: eq\n                value: 0\n        remediation: |\n          If using a Kubelet config file, edit the file to set the 'eventRecordQPS' value to an appropriate level (e.g., 5).\n          If using executable arguments, check the Kubelet service file `$kubeletsvc` on each worker node, and add the following parameter to the `KUBELET_ARGS` variable:\n          --eventRecordQPS=5\n          Ensure that there is no conflicting `--eventRecordQPS` setting in the service file that overrides the config file.\n          After making the changes, restart the Kubelet service:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n          systemctl status kubelet -l\n        scored: true\n\n\n      - id: 3.2.8\n        text: \"Ensure that the --rotate-certificates argument is not set to false (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --rotate-certificates\n              path: '{.rotateCertificates}'\n              set: true\n              compare:\n                op: eq\n                value: true\n            - flag: --rotate-certificates\n              path: '{.rotateCertificates}'\n              set: false\n          bin_op: or\n        remediation: |\n          If modifying the Kubelet config file, edit the `kubelet-config.json` file located at `/etc/kubernetes/kubelet/kubelet-config.json` and set the following parameter to `true`:\n          \"rotateCertificates\": true\n          Ensure that the Kubelet service file located at `/etc/systemd/system/kubelet.service.d/10-kubelet-args.conf` does not define the `--rotate-certificates` argument as `false`, as this would override the config file.\n          If using executable arguments, add the following line to the `KUBELET_CERTIFICATE_ARGS` variable:\n          --rotate-certificates=true\n          After making the necessary changes, restart the Kubelet service:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n          systemctl status kubelet -l\n        scored: true\n\n      - id: 3.2.9\n        text: \"Ensure that the RotateKubeletServerCertificate argument is set to true (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: RotateKubeletServerCertificate\n              path: '{.featureGates.RotateKubeletServerCertificate}'\n              set: true\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Edit the kubelet service file $kubeletsvc\n          on each worker node and set the below parameter in KUBELET_CERTIFICATE_ARGS variable.\n          --feature-gates=RotateKubeletServerCertificate=true\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n"
  },
  {
    "path": "cfg/aks-1.8/policies.yaml",
    "content": "---\ncontrols:\nversion: \"aks-1.8\"\nid: 4\ntext: \"Policies\"\ntype: \"policies\"\ngroups:\n  - id: 4.1\n    text: \"RBAC and Service Accounts\"\n    checks:\n      - id: 4.1.1\n        text: \"Ensure that the cluster-admin role is only used where required (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Identify all clusterrolebindings to the cluster-admin role using:\n            kubectl get clusterrolebindings --no-headers | grep cluster-admin\n          Review if each of them actually needs this role. If not, remove the binding:\n            kubectl delete clusterrolebinding <binding-name>\n          Where possible, assign a less privileged ClusterRole.\n        scored: true\n\n      - id: 4.1.2\n        text: \"Minimize access to secrets (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Identify all roles that grant access to secrets via get/list/watch verbs.\n          Use `kubectl edit role -n <namespace> <name>` to remove these permissions.\n          Alternatively, create a new least-privileged role that excludes secret access.\n        scored: true\n\n      - id: 4.1.3\n        text: \"Minimize wildcard use in Roles and ClusterRoles (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Identify roles and clusterroles using wildcards (*) in 'verbs', 'resources', or 'apiGroups'.\n          Replace wildcards with specific values to enforce least privilege access.\n          Use `kubectl edit role -n <namespace> <name>` or `kubectl edit clusterrole <name>` to update.\n        scored: true\n\n      - id: 4.1.4\n        text: \"Minimize access to create pods (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Review all roles and clusterroles that have \"create\" permission on \"pods\".\n           Where possible, remove or restrict this permission to only required service accounts.\n          Use:\n            - `kubectl edit role -n <namespace> <role>`\n            - `kubectl edit clusterrole <name>`\n          Apply least privilege principle across the cluster.\n        scored: true\n\n      - id: 4.1.5\n        text: \"Ensure that default service accounts are not actively used (Manual)\"\n        type: \"manual\"\n        remediation: |\n          1. Avoid using default service accounts for workloads.\n          2. Set `automountServiceAccountToken: false` on all default SAs:\n             kubectl patch serviceaccount default -n <namespace> -p '{\"automountServiceAccountToken\": false}'\n          3. Use custom service accounts with only the necessary permissions.\n        scored: true\n\n      - id: 4.1.6\n        text: \"Ensure that Service Account Tokens are only mounted where necessary (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Pods that do not need access to the Kubernetes API should not mount service account tokens.\n          To disable token mounting in a pod definition:\n          ```yaml\n          spec:\n            automountServiceAccountToken: false\n          ```\n          Or patch an existing pod's spec (recommended via workload template):\n          Patch not possible for running pods — update the deployment YAML or recreate pods with updated spec.\n        scored: true\n\n      - id: 4.1.7\n        text: \"Limit use of the Bind, Impersonate and Escalate permissions in the Kubernetes cluster (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Review ClusterRoles and Roles that grant the bind, impersonate, or escalate verbs.\n          These permissions should only be granted where they are strictly required for cluster operation.\n          Remove these privileges from non-system users and service accounts where possible.\n          Take care not to remove required permissions from Kubernetes system roles such as\n          system:masters or clusterrole-aggregation-controller, as this may impact cluster functionality.\n        scored: false\n\n      - id: 4.1.8\n        text: \"Minimize access to create Persistent Volumes (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Review ClusterRoles and Roles that grant create access to PersistentVolume resources.\n          Creation of PersistentVolumes should be limited to trusted administrators only.\n          Where possible, remove create permissions on PersistentVolume objects from non-administrative\n          users and service accounts to reduce the risk of privilege escalation via hostPath volumes.\n        scored: false\n\n      - id: 4.1.9\n        text: \"Minimize access to the proxy sub-resource of Nodes (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Review ClusterRoles and Roles that grant access to the proxy sub-resource of Node objects.\n          Limit access to this sub-resource to trusted administrators only.\n          Removing unnecessary access reduces the risk of privilege escalation via the kubelet API\n          and ensures cluster security controls, like audit logging and admission control, remain effective.\n        scored: false\n\n      - id: 4.1.10\n        text: \"Minimize access to the approval sub-resource of CertificateSigningRequests objects (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Review ClusterRoles and Roles that grant access to update the approval sub-resource of CertificateSigningRequests (CSR) objects.\n          Limit this access to trusted administrators only.\n          Removing unnecessary access reduces the risk of privilege escalation via approval of high-privileged certificates,\n          which could allow creation of new cluster-admin level users.\n        scored: false\n\n      - id: 4.1.11\n        text: \"Minimize access to webhook configuration objects (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Review ClusterRoles and Roles that grant access to create, modify, or delete\n          validatingwebhookconfigurations or mutatingwebhookconfigurations.\n          Limit this access to trusted administrators only.\n          Removing unnecessary access reduces the risk of privilege escalation or disruption\n          of cluster operations via malicious or misconfigured webhooks.\n        scored: false\n\n      - id: 4.1.12\n        text: \"Minimize access to the service account token creation (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Review ClusterRoles and Roles that grant access to create the token sub-resource of ServiceAccount objects.\n          Limit this access to trusted administrators only.\n          Removing unnecessary access reduces the risk of privilege escalation or persistent unauthorized access\n          to the cluster via service account tokens.\n        scored: false\n\n  - id: 4.2\n    text: \"Pod Security Policies\"\n    checks:\n      - id: 4.2.1\n        text: \"Minimize the admission of privileged containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add a Pod Security Admission (PSA) policy to each namespace in the cluster to restrict the admission of privileged containers.\n          To enforce a restricted policy for a specific namespace, use the following command:\n          kubectl label --overwrite ns NAMESPACE pod-security.kubernetes.io/enforce=restricted\n          You can also enforce PSA for all namespaces:\n          kubectl label --overwrite ns --all pod-security.kubernetes.io/warn=baseline\n          Additionally, review the namespaces that should be excluded (e.g., `kube-system`, `gatekeeper-system`, `azure-arc`, `azure-extensions-usage-system`) and adjust your filtering if necessary.\n          To enable Pod Security Policies, refer to the detailed documentation for Kubernetes and Azure integration at:\n          https://learn.microsoft.com/en-us/azure/governance/policy/concepts/policy-for-kubernetes\n        scored: false\n\n      - id: 4.2.2\n        text: \"Minimize the admission of containers wishing to share the host process ID namespace (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add a policy to each namespace in the cluster that restricts the admission of containers with hostPID. For namespaces that need it, ensure RBAC controls limit access to a specific service account.\n          You can label your namespaces as follows to restrict or enforce the policy:\n          kubectl label --overwrite ns NAMESPACE pod-security.kubernetes.io/enforce=restricted\n          You can also use the following to warn about policies:\n          kubectl label --overwrite ns --all pod-security.kubernetes.io/warn=baseline\n          For more information, refer to the official Kubernetes and Azure documentation on policies:\n          https://learn.microsoft.com/en-us/azure/governance/policy/concepts/policy-for-kubernetes\n        scored: false\n\n      - id: 4.2.3\n        text: \"Minimize the admission of containers wishing to share the host IPC namespace (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the admission of hostIPC containers.\n          You can label your namespaces as follows to restrict or enforce the policy:\n          kubectl label --overwrite ns NAMESPACE pod-security.kubernetes.io/enforce=restricted\n          You can also use the following to warn about policies:\n          kubectl label --overwrite ns --all pod-security.kubernetes.io/warn=baseline\n          For more information, refer to the official Kubernetes and Azure documentation on policies:\n          https://learn.microsoft.com/en-us/azure/governance/policy/concepts/policy-for-kubernetes\n        scored: false\n\n      - id: 4.2.4\n        text: \"Minimize the admission of containers wishing to share the host network namespace (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the admission of hostNetwork containers.\n          You can label your namespaces as follows to restrict or enforce the policy:\n          kubectl label --overwrite ns NAMESPACE pod-security.kubernetes.io/enforce=restricted\n          You can also use the following to warn about policies:\n          kubectl label --overwrite ns --all pod-security.kubernetes.io/warn=baseline\n          For more information, refer to the official Kubernetes and Azure documentation on policies:\n          https://learn.microsoft.com/en-us/azure/governance/policy/concepts/policy-for-kubernetes\n        scored: false\n\n      - id: 4.2.5\n        text: \"Minimize the admission of containers with allowPrivilegeEscalation (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the admission of containers with .spec.allowPrivilegeEscalation set to true.\n          You can label your namespaces as follows to restrict or enforce the policy:\n          kubectl label --overwrite ns NAMESPACE pod-security.kubernetes.io/enforce=restricted\n          You can also use the following to warn about policies:\n          kubectl label --overwrite ns --all pod-security.kubernetes.io/warn=baseline\n          For more information, refer to the official Kubernetes and Azure documentation on policies:\n          https://learn.microsoft.com/en-us/azure/governance/policy/concepts/policy-for-kubernetes\n        scored: false\n\n\n  - id: 4.3\n    text: \"Azure Policy / OPA\"\n    checks: []\n\n\n  - id: 4.4\n    text: \"CNI Plugin\"\n    checks:\n      - id: 4.4.1\n        text: \"Ensure latest CNI version is used (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Review the documentation of AWS CNI plugin, and ensure latest CNI version is used.\n        scored: false\n\n      - id: 4.4.2\n        text: \"Ensure that all Namespaces have Network Policies defined (Automated)\"\n        type: \"skip\"\n        audit: |\n          ns_without_np=$(comm -23 \\\n            <(kubectl get ns -o jsonpath='{.items[*].metadata.name}' | tr ' ' '\\n' | sort) \\\n            <(kubectl get networkpolicy --all-namespaces -o jsonpath='{.items[*].metadata.namespace}' | tr ' ' '\\n' | sort))\n          if [ -z \"$ns_without_np\" ]; then echo \"ALL_NAMESPACES_HAVE_NETWORKPOLICIES\"; else echo \"MISSING_NETWORKPOLICIES\"; fi\n        tests:\n          test_items:\n            - flag: \"ALL_NAMESPACES_HAVE_NETWORKPOLICIES\"\n              set: true\n              compare:\n                op: eq\n                value: \"ALL_NAMESPACES_HAVE_NETWORKPOLICIES\"\n        remediation: |\n          Define at least one NetworkPolicy in each namespace to control pod-level traffic. Example:\n\n          kubectl apply -n <namespace> -f - <<EOF\n          apiVersion: networking.k8s.io/v1\n          kind: NetworkPolicy\n          metadata:\n            name: default-deny-all\n          spec:\n            podSelector: {}\n            policyTypes:\n              - Ingress\n              - Egress\n          EOF\n\n          This denies all traffic unless explicitly allowed. Review and adjust policies per namespace as needed.\n        scored: true\n\n  - id: 4.5\n    text: \"Secrets Management\"\n    checks:\n      - id: 4.5.1\n        text: \"Prefer using secrets as files over secrets as environment variables (Automated)\"\n        type: \"skip\"\n        audit: |\n          output=$(kubectl get all --all-namespaces -o jsonpath='{range .items[?(@..secretKeyRef)]} {.kind} {.metadata.name} {\"\\n\"}{end}')\n          if [ -z \"$output\" ]; then echo \"NO_ENV_SECRET_REFERENCES\"; else echo \"ENV_SECRET_REFERENCES_FOUND\"; fi\n        tests:\n          test_items:\n            - flag: \"NO_ENV_SECRET_REFERENCES\"\n              set: true\n              compare:\n                op: eq\n                value: \"NO_ENV_SECRET_REFERENCES\"\n        remediation: |\n          Refactor application deployments to mount secrets as files instead of passing them as environment variables.\n          Avoid using `envFrom` or `env` with `secretKeyRef` in container specs.\n        scored: true\n\n\n      - id: 4.5.2\n        text: \"Consider external secret storage (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Refer to the secrets management options offered by your cloud provider or a third-party\n          secrets management solution.\n        scored: false\n\n\n  - id: 4.6\n    text: \"General Policies\"\n    checks:\n      - id: 4.6.1\n        text: \"Create administrative boundaries between resources using namespaces (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the documentation and create namespaces for objects in your deployment as you need\n          them.\n        scored: false\n\n      - id: 4.6.2\n        text: \"Apply Security Context to Your Pods and Containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and apply security contexts to your pods. For a\n          suggested list of security contexts, you may refer to the CIS Security Benchmark for Docker\n          Containers.\n        scored: false\n\n      - id: 4.6.3\n        text: \"The default namespace should not be used (Automated)\"\n        audit: |\n          output=$(kubectl get all -n default --no-headers 2>/dev/null | grep -v '^service\\s\\+kubernetes\\s' || true)\n          if [ -z \"$output\" ]; then echo \"DEFAULT_NAMESPACE_UNUSED\"; else echo \"DEFAULT_NAMESPACE_IN_USE\"; fi\n        tests:\n          test_items:\n            - flag: \"DEFAULT_NAMESPACE_UNUSED\"\n              set: true\n              compare:\n                op: eq\n                value: \"DEFAULT_NAMESPACE_UNUSED\"\n        remediation: |\n          Avoid using the default namespace for user workloads.\n          - Create separate namespaces for your applications and infrastructure components.\n          - Move any user-defined resources out of the default namespace.\n\n          Example to create a namespace:\n          kubectl create namespace my-namespace\n\n          Example to move resources:\n          kubectl get deployment my-app -n default -o yaml | sed 's/namespace: default/namespace: my-namespace/' | kubectl apply -f -\n          kubectl delete deployment my-app -n default\n        scored: true\n"
  },
  {
    "path": "cfg/cis-1.10/config.yaml",
    "content": "---\n## Version-specific settings that override the values in cfg/config.yaml\n"
  },
  {
    "path": "cfg/cis-1.10/controlplane.yaml",
    "content": "---\ncontrols:\nversion: \"cis-1.10\"\nid: 3\ntext: \"Control Plane Configuration\"\ntype: \"controlplane\"\ngroups:\n  - id: 3.1\n    text: \"Authentication and Authorization\"\n    checks:\n      - id: 3.1.1\n        text: \"Client certificate authentication should not be used for users (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Alternative mechanisms provided by Kubernetes such as the use of OIDC should be\n          implemented in place of client certificates.\n        scored: false\n\n      - id: 3.1.2\n        text: \"Service account token authentication should not be used for users (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Alternative mechanisms provided by Kubernetes such as the use of OIDC should be implemented\n          in place of service account tokens.\n        scored: false\n\n      - id: 3.1.3\n        text: \"Bootstrap token authentication should not be used for users (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Alternative mechanisms provided by Kubernetes such as the use of OIDC should be implemented\n          in place of bootstrap tokens.\n        scored: false\n\n  - id: 3.2\n    text: \"Logging\"\n    checks:\n      - id: 3.2.1\n        text: \"Ensure that a minimal audit policy is created (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-policy-file\"\n              set: true\n        remediation: |\n          Create an audit policy file for your cluster.\n        scored: false\n\n      - id: 3.2.2\n        text: \"Ensure that the audit policy covers key security concerns (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Review the audit policy provided for the cluster and ensure that it covers\n          at least the following areas,\n          - Access to Secrets managed by the cluster. Care should be taken to only\n            log Metadata for requests to Secrets, ConfigMaps, and TokenReviews, in\n            order to avoid risk of logging sensitive data.\n          - Modification of Pod and Deployment objects.\n          - Use of `pods/exec`, `pods/portforward`, `pods/proxy` and `services/proxy`.\n          For most requests, minimally logging at the Metadata level is recommended\n          (the most basic level of logging).\n        scored: false\n"
  },
  {
    "path": "cfg/cis-1.10/etcd.yaml",
    "content": "---\ncontrols:\nversion: \"cis-1.10\"\nid: 2\ntext: \"Etcd Node Configuration\"\ntype: \"etcd\"\ngroups:\n  - id: 2\n    text: \"Etcd Node Configuration\"\n    checks:\n      - id: 2.1\n        text: \"Ensure that the --cert-file and --key-file arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--cert-file\"\n              env: \"ETCD_CERT_FILE\"\n            - flag: \"--key-file\"\n              env: \"ETCD_KEY_FILE\"\n        remediation: |\n          Follow the etcd service documentation and configure TLS encryption.\n          Then, edit the etcd pod specification file /etc/kubernetes/manifests/etcd.yaml\n          on the master node and set the below parameters.\n          --cert-file=</path/to/ca-file>\n          --key-file=</path/to/key-file>\n        scored: true\n\n      - id: 2.2\n        text: \"Ensure that the --client-cert-auth argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--client-cert-auth\"\n              env: \"ETCD_CLIENT_CERT_AUTH\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and set the below parameter.\n          --client-cert-auth=\"true\"\n        scored: true\n\n      - id: 2.3\n        text: \"Ensure that the --auto-tls argument is not set to true (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--auto-tls\"\n              env: \"ETCD_AUTO_TLS\"\n              set: false\n            - flag: \"--auto-tls\"\n              env: \"ETCD_AUTO_TLS\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and either remove the --auto-tls parameter or set it to false.\n            --auto-tls=false\n        scored: true\n\n      - id: 2.4\n        text: \"Ensure that the --peer-cert-file and --peer-key-file arguments are\n        set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--peer-cert-file\"\n              env: \"ETCD_PEER_CERT_FILE\"\n            - flag: \"--peer-key-file\"\n              env: \"ETCD_PEER_KEY_FILE\"\n        remediation: |\n          Follow the etcd service documentation and configure peer TLS encryption as appropriate\n          for your etcd cluster.\n          Then, edit the etcd pod specification file $etcdconf on the\n          master node and set the below parameters.\n          --peer-client-file=</path/to/peer-cert-file>\n          --peer-key-file=</path/to/peer-key-file>\n        scored: true\n\n      - id: 2.5\n        text: \"Ensure that the --peer-client-cert-auth argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--peer-client-cert-auth\"\n              env: \"ETCD_PEER_CLIENT_CERT_AUTH\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and set the below parameter.\n          --peer-client-cert-auth=true\n        scored: true\n\n      - id: 2.6\n        text: \"Ensure that the --peer-auto-tls argument is not set to true (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--peer-auto-tls\"\n              env: \"ETCD_PEER_AUTO_TLS\"\n              set: false\n            - flag: \"--peer-auto-tls\"\n              env: \"ETCD_PEER_AUTO_TLS\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and either remove the --peer-auto-tls parameter or set it to false.\n          --peer-auto-tls=false\n        scored: true\n\n      - id: 2.7\n        text: \"Ensure that a unique Certificate Authority is used for etcd (Manual)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--trusted-ca-file\"\n              env: \"ETCD_TRUSTED_CA_FILE\"\n        remediation: |\n          [Manual test]\n          Follow the etcd documentation and create a dedicated certificate authority setup for the\n          etcd service.\n          Then, edit the etcd pod specification file $etcdconf on the\n          master node and set the below parameter.\n          --trusted-ca-file=</path/to/ca-file>\n        scored: false\n"
  },
  {
    "path": "cfg/cis-1.10/master.yaml",
    "content": "---\ncontrols:\nversion: \"cis-1.10\"\nid: 1\ntext: \"Control Plane Security Configuration\"\ntype: \"master\"\ngroups:\n  - id: 1.1\n    text: \"Control Plane Node Configuration Files\"\n    checks:\n      - id: 1.1.1\n        text: \"Ensure that the API server pod specification file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $apiserverconf; then stat -c permissions=%a $apiserverconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the\n          control plane node.\n          For example, chmod 600 $apiserverconf\n        scored: true\n\n      - id: 1.1.2\n        text: \"Ensure that the API server pod specification file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $apiserverconf; then stat -c %U:%G $apiserverconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chown root:root $apiserverconf\n        scored: true\n\n      - id: 1.1.3\n        text: \"Ensure that the controller manager pod specification file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerconf; then stat -c permissions=%a $controllermanagerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chmod 600 $controllermanagerconf\n        scored: true\n\n      - id: 1.1.4\n        text: \"Ensure that the controller manager pod specification file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerconf; then stat -c %U:%G $controllermanagerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chown root:root $controllermanagerconf\n        scored: true\n\n      - id: 1.1.5\n        text: \"Ensure that the scheduler pod specification file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerconf; then stat -c permissions=%a $schedulerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chmod 600 $schedulerconf\n        scored: true\n\n      - id: 1.1.6\n        text: \"Ensure that the scheduler pod specification file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerconf; then stat -c %U:%G $schedulerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chown root:root $schedulerconf\n        scored: true\n\n      - id: 1.1.7\n        text: \"Ensure that the etcd pod specification file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $etcdconf; then find $etcdconf -name '*etcd*' | xargs stat -c permissions=%a; fi'\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod 600 $etcdconf\n        scored: true\n\n      - id: 1.1.8\n        text: \"Ensure that the etcd pod specification file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $etcdconf; then find $etcdconf -name '*etcd*' | xargs stat -c %U:%G; fi'\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root $etcdconf\n        scored: true\n\n      - id: 1.1.9\n        text: \"Ensure that the Container Network Interface file permissions are set to 600 or more restrictive (Manual)\"\n        audit: |\n          ps -ef | grep $kubeletbin | grep -- --cni-conf-dir | sed 's%.*cni-conf-dir[= ]\\([^ ]*\\).*%\\1%' | xargs -I{} find {} -mindepth 1 | xargs --no-run-if-empty stat -c permissions=%a\n          find /var/lib/cni/networks -type f 2> /dev/null | xargs --no-run-if-empty stat -c permissions=%a\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chmod 600 <path/to/cni/files>\n        scored: false\n\n      - id: 1.1.10\n        text: \"Ensure that the Container Network Interface file ownership is set to root:root (Manual)\"\n        audit: |\n          ps -ef | grep $kubeletbin | grep -- --cni-conf-dir | sed 's%.*cni-conf-dir[= ]\\([^ ]*\\).*%\\1%' | xargs -I{} find {} -mindepth 1 | xargs --no-run-if-empty stat -c %U:%G\n          find /var/lib/cni/networks -type f 2> /dev/null | xargs --no-run-if-empty stat -c %U:%G\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root <path/to/cni/files>\n        scored: false\n\n      - id: 1.1.11\n        text: \"Ensure that the etcd data directory permissions are set to 700 or more restrictive (Automated)\"\n        audit: |\n          DATA_DIR=''\n          for d in $(ps -ef | grep $etcdbin | grep -- --data-dir | sed 's%.*data-dir[= ]\\([^ ]*\\).*%\\1%'); do\n            if test -d \"$d\"; then DATA_DIR=\"$d\"; fi\n          done\n          if ! test -d \"$DATA_DIR\"; then DATA_DIR=$etcddatadir; fi\n          stat -c permissions=%a \"$DATA_DIR\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"700\"\n        remediation: |\n          On the etcd server node, get the etcd data directory, passed as an argument --data-dir,\n          from the command 'ps -ef | grep etcd'.\n          Run the below command (based on the etcd data directory found above). For example,\n          chmod 700 /var/lib/etcd\n        scored: true\n\n      - id: 1.1.12\n        text: \"Ensure that the etcd data directory ownership is set to etcd:etcd (Automated)\"\n        audit: |\n          DATA_DIR=''\n          for d in $(ps -ef | grep $etcdbin | grep -- --data-dir | sed 's%.*data-dir[= ]\\([^ ]*\\).*%\\1%'); do\n            if test -d \"$d\"; then DATA_DIR=\"$d\"; fi\n          done\n          if ! test -d \"$DATA_DIR\"; then DATA_DIR=$etcddatadir; fi\n          stat -c %U:%G \"$DATA_DIR\"\n        tests:\n          test_items:\n            - flag: \"etcd:etcd\"\n        remediation: |\n          On the etcd server node, get the etcd data directory, passed as an argument --data-dir,\n          from the command 'ps -ef | grep etcd'.\n          Run the below command (based on the etcd data directory found above).\n          For example, chown etcd:etcd /var/lib/etcd\n        scored: true\n\n      - id: 1.1.13\n        text: \"Ensure that the default administrative credential file permissions are set to 600 (Automated)\"\n        audit: |\n         for adminconf in /etc/kubernetes/admin.conf /etc/kubernetes/super-admin.conf; do if test -e $adminconf; then stat -c \"permissions=%a %n\" $adminconf; fi; done\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chmod 600 /etc/kubernetes/admin.conf\n          On Kubernetes 1.29+ the super-admin.conf file should also be modified, if present.\n          For example, chmod 600 /etc/kubernetes/super-admin.conf\n        scored: true\n\n      - id: 1.1.14\n        text: \"Ensure that the default administrative credential file ownership is set to root:root (Automated)\"\n        audit: |\n         for adminconf in /etc/kubernetes/admin.conf /etc/kubernetes/super-admin.conf; do if test -e $adminconf; then stat -c \"ownership=%U:%G %n\" $adminconf; fi; done\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"ownership\"\n              compare:\n                op: eq\n                value: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chown root:root /etc/kubernetes/admin.conf\n          On Kubernetes 1.29+ the super-admin.conf file should also be modified, if present.\n          For example, chown root:root /etc/kubernetes/super-admin.conf\n        scored: true\n\n      - id: 1.1.15\n        text: \"Ensure that the scheduler.conf file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerkubeconfig; then stat -c permissions=%a $schedulerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod 600 $schedulerkubeconfig\n        scored: true\n\n      - id: 1.1.16\n        text: \"Ensure that the scheduler.conf file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerkubeconfig; then stat -c %U:%G $schedulerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root $schedulerkubeconfig\n        scored: true\n\n      - id: 1.1.17\n        text: \"Ensure that the controller-manager.conf file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerkubeconfig; then stat -c permissions=%a $controllermanagerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod 600 $controllermanagerkubeconfig\n        scored: true\n\n      - id: 1.1.18\n        text: \"Ensure that the controller-manager.conf file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerkubeconfig; then stat -c %U:%G $controllermanagerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root $controllermanagerkubeconfig\n        scored: true\n\n      - id: 1.1.19\n        text: \"Ensure that the Kubernetes PKI directory and file ownership is set to root:root (Automated)\"\n        audit: \"find /etc/kubernetes/pki/ | xargs stat -c %U:%G\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown -R root:root /etc/kubernetes/pki/\n        scored: true\n\n      - id: 1.1.20\n        text: \"Ensure that the Kubernetes PKI certificate file permissions are set to 600 or more restrictive (Manual)\"\n        audit: \"find /etc/kubernetes/pki/ -name '*.crt' | xargs stat -c permissions=%a\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod -R 600 /etc/kubernetes/pki/*.crt\n        scored: false\n\n      - id: 1.1.21\n        text: \"Ensure that the Kubernetes PKI key file permissions are set to 600 (Manual)\"\n        audit: \"find /etc/kubernetes/pki/ -name '*.key' | xargs stat -c permissions=%a\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod -R 600 /etc/kubernetes/pki/*.key\n        scored: false\n\n  - id: 1.2\n    text: \"API Server\"\n    checks:\n      - id: 1.2.1\n        text: \"Ensure that the --anonymous-auth argument is set to false (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--anonymous-auth\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the below parameter.\n          --anonymous-auth=false\n        scored: false\n\n      - id: 1.2.2\n        text: \"Ensure that the --token-auth-file parameter is not set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--token-auth-file\"\n              set: false\n        remediation: |\n          Follow the documentation and configure alternate mechanisms for authentication. Then,\n          edit the API server pod specification file $apiserverconf\n          on the control plane node and remove the --token-auth-file=<filename> parameter.\n        scored: true\n\n      - id: 1.2.3\n        text: \"Ensure that the --DenyServiceExternalIPs is set (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"DenyServiceExternalIPs\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and add the `DenyServiceExternalIPs` plugin\n          to the enabled admission plugins, as such --enable-admission-plugin=DenyServiceExternalIPs.\n        scored: false\n\n      - id: 1.2.4\n        text: \"Ensure that the --kubelet-client-certificate and --kubelet-client-key arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--kubelet-client-certificate\"\n            - flag: \"--kubelet-client-key\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection between the\n          apiserver and kubelets. Then, edit API server pod specification file\n          $apiserverconf on the control plane node and set the\n          kubelet client certificate and key parameters as below.\n          --kubelet-client-certificate=<path/to/client-certificate-file>\n          --kubelet-client-key=<path/to/client-key-file>\n        scored: true\n\n      - id: 1.2.5\n        text: \"Ensure that the --kubelet-certificate-authority argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--kubelet-certificate-authority\"\n        remediation: |\n          Follow the Kubernetes documentation and setup the TLS connection between\n          the apiserver and kubelets. Then, edit the API server pod specification file\n          $apiserverconf on the control plane node and set the\n          --kubelet-certificate-authority parameter to the path to the cert file for the certificate authority.\n          --kubelet-certificate-authority=<ca-string>\n        scored: true\n\n      - id: 1.2.6\n        text: \"Ensure that the --authorization-mode argument is not set to AlwaysAllow (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: nothave\n                value: \"AlwaysAllow\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --authorization-mode parameter to values other than AlwaysAllow.\n          One such example could be as below.\n          --authorization-mode=RBAC\n        scored: true\n\n      - id: 1.2.7\n        text: \"Ensure that the --authorization-mode argument includes Node (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: has\n                value: \"Node\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --authorization-mode parameter to a value that includes Node.\n          --authorization-mode=Node,RBAC\n        scored: true\n\n      - id: 1.2.8\n        text: \"Ensure that the --authorization-mode argument includes RBAC (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: has\n                value: \"RBAC\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --authorization-mode parameter to a value that includes RBAC,\n          for example `--authorization-mode=Node,RBAC`.\n        scored: true\n\n      - id: 1.2.9\n        text: \"Ensure that the admission control plugin EventRateLimit is set (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"EventRateLimit\"\n        remediation: |\n          Follow the Kubernetes documentation and set the desired limits in a configuration file.\n          Then, edit the API server pod specification file $apiserverconf\n          and set the below parameters.\n          --enable-admission-plugins=...,EventRateLimit,...\n          --admission-control-config-file=<path/to/configuration/file>\n        scored: false\n\n      - id: 1.2.10\n        text: \"Ensure that the admission control plugin AlwaysAdmit is not set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: nothave\n                value: AlwaysAdmit\n            - flag: \"--enable-admission-plugins\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and either remove the --enable-admission-plugins parameter, or set it to a\n          value that does not include AlwaysAdmit.\n        scored: true\n\n      - id: 1.2.11\n        text: \"Ensure that the admission control plugin AlwaysPullImages is set (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"AlwaysPullImages\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --enable-admission-plugins parameter to include\n          AlwaysPullImages.\n          --enable-admission-plugins=...,AlwaysPullImages,...\n        scored: false\n\n      - id: 1.2.12\n        text: \"Ensure that the admission control plugin ServiceAccount is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--disable-admission-plugins\"\n              compare:\n                op: nothave\n                value: \"ServiceAccount\"\n            - flag: \"--disable-admission-plugins\"\n              set: false\n        remediation: |\n          Follow the documentation and create ServiceAccount objects as per your environment.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and ensure that the --disable-admission-plugins parameter is set to a\n          value that does not include ServiceAccount.\n        scored: true\n\n      - id: 1.2.13\n        text: \"Ensure that the admission control plugin NamespaceLifecycle is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--disable-admission-plugins\"\n              compare:\n                op: nothave\n                value: \"NamespaceLifecycle\"\n            - flag: \"--disable-admission-plugins\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --disable-admission-plugins parameter to\n          ensure it does not include NamespaceLifecycle.\n        scored: true\n\n      - id: 1.2.14\n        text: \"Ensure that the admission control plugin NodeRestriction is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"NodeRestriction\"\n        remediation: |\n          Follow the Kubernetes documentation and configure NodeRestriction plug-in on kubelets.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --enable-admission-plugins parameter to a\n          value that includes NodeRestriction.\n          --enable-admission-plugins=...,NodeRestriction,...\n        scored: true\n\n      - id: 1.2.15\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the below parameter.\n          --profiling=false\n        scored: true\n\n      - id: 1.2.16\n        text: \"Ensure that the --audit-log-path argument is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-path\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --audit-log-path parameter to a suitable path and\n          file where you would like audit logs to be written, for example,\n          --audit-log-path=/var/log/apiserver/audit.log\n        scored: true\n\n      - id: 1.2.17\n        text: \"Ensure that the --audit-log-maxage argument is set to 30 or as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxage\"\n              compare:\n                op: gte\n                value: 30\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --audit-log-maxage parameter to 30\n          or as an appropriate number of days, for example,\n          --audit-log-maxage=30\n        scored: true\n\n      - id: 1.2.18\n        text: \"Ensure that the --audit-log-maxbackup argument is set to 10 or as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxbackup\"\n              compare:\n                op: gte\n                value: 10\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --audit-log-maxbackup parameter to 10 or to an appropriate\n          value. For example,\n          --audit-log-maxbackup=10\n        scored: true\n\n      - id: 1.2.19\n        text: \"Ensure that the --audit-log-maxsize argument is set to 100 or as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxsize\"\n              compare:\n                op: gte\n                value: 100\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --audit-log-maxsize parameter to an appropriate size in MB.\n          For example, to set it as 100 MB, --audit-log-maxsize=100\n        scored: true\n\n      - id: 1.2.20\n        text: \"Ensure that the --request-timeout argument is set as appropriate (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        type: manual\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          and set the below parameter as appropriate and if needed.\n          For example, --request-timeout=300s\n        scored: false\n\n      - id: 1.2.21\n        text: \"Ensure that the --service-account-lookup argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--service-account-lookup\"\n              set: false\n            - flag: \"--service-account-lookup\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the below parameter.\n          --service-account-lookup=true\n          Alternatively, you can delete the --service-account-lookup parameter from this file so\n          that the default takes effect.\n        scored: true\n\n      - id: 1.2.22\n        text: \"Ensure that the --service-account-key-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--service-account-key-file\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --service-account-key-file parameter\n          to the public key file for service accounts. For example,\n          --service-account-key-file=<filename>\n        scored: true\n\n      - id: 1.2.23\n        text: \"Ensure that the --etcd-certfile and --etcd-keyfile arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--etcd-certfile\"\n            - flag: \"--etcd-keyfile\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection between the apiserver and etcd.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the etcd certificate and key file parameters.\n          --etcd-certfile=<path/to/client-certificate-file>\n          --etcd-keyfile=<path/to/client-key-file>\n        scored: true\n\n      - id: 1.2.24\n        text: \"Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--tls-cert-file\"\n            - flag: \"--tls-private-key-file\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection on the apiserver.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the TLS certificate and private key file parameters.\n          --tls-cert-file=<path/to/tls-certificate-file>\n          --tls-private-key-file=<path/to/tls-key-file>\n        scored: true\n\n      - id: 1.2.25\n        text: \"Ensure that the --client-ca-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--client-ca-file\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection on the apiserver.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the client certificate authority file.\n          --client-ca-file=<path/to/client-ca-file>\n        scored: true\n\n      - id: 1.2.26\n        text: \"Ensure that the --etcd-cafile argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--etcd-cafile\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection between the apiserver and etcd.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the etcd certificate authority file parameter.\n          --etcd-cafile=<path/to/ca-file>\n        scored: true\n\n      - id: 1.2.27\n        text: \"Ensure that the --encryption-provider-config argument is set as appropriate (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--encryption-provider-config\"\n        remediation: |\n          Follow the Kubernetes documentation and configure a EncryptionConfig file.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --encryption-provider-config parameter to the path of that file.\n          For example, --encryption-provider-config=</path/to/EncryptionConfig/File>\n        scored: false\n\n      - id: 1.2.28\n        text: \"Ensure that encryption providers are appropriately configured (Manual)\"\n        audit: |\n          ENCRYPTION_PROVIDER_CONFIG=$(ps -ef | grep $apiserverbin | grep -- --encryption-provider-config | sed 's%.*encryption-provider-config[= ]\\([^ ]*\\).*%\\1%')\n          if test -e $ENCRYPTION_PROVIDER_CONFIG; then grep -A1 'providers:' $ENCRYPTION_PROVIDER_CONFIG | tail -n1 | grep -o \"[A-Za-z]*\" | sed 's/^/provider=/'; fi\n        tests:\n          test_items:\n            - flag: \"provider\"\n              compare:\n                op: valid_elements\n                value: \"aescbc,kms,secretbox\"\n        remediation: |\n          Follow the Kubernetes documentation and configure a EncryptionConfig file.\n          In this file, choose aescbc, kms or secretbox as the encryption provider.\n        scored: false\n\n      - id: 1.2.29\n        text: \"Ensure that the API Server only makes use of Strong Cryptographic Ciphers (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--tls-cipher-suites\"\n              compare:\n                op: valid_elements\n                value: \"TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,TLS_CHACHA20_POLY1305_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256\"\n        remediation: |\n          Edit the API server pod specification file /etc/kubernetes/manifests/kube-apiserver.yaml\n          on the control plane node and set the below parameter.\n          --tls-cipher-suites=TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,TLS_CHACHA20_POLY1305_SHA256,\n          TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,\n          TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,\n          TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,\n          TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,\n          TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256\n        scored: false\n\n  - id: 1.3\n    text: \"Controller Manager\"\n    checks:\n      - id: 1.3.1\n        text: \"Ensure that the --terminated-pod-gc-threshold argument is set as appropriate (Manual)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--terminated-pod-gc-threshold\"\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the --terminated-pod-gc-threshold to an appropriate threshold,\n          for example, --terminated-pod-gc-threshold=10\n        scored: false\n\n      - id: 1.3.2\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the below parameter.\n          --profiling=false\n        scored: true\n\n      - id: 1.3.3\n        text: \"Ensure that the --use-service-account-credentials argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--use-service-account-credentials\"\n              compare:\n                op: noteq\n                value: false\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node to set the below parameter.\n          --use-service-account-credentials=true\n        scored: true\n\n      - id: 1.3.4\n        text: \"Ensure that the --service-account-private-key-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--service-account-private-key-file\"\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the --service-account-private-key-file parameter\n          to the private key file for service accounts.\n          --service-account-private-key-file=<filename>\n        scored: true\n\n      - id: 1.3.5\n        text: \"Ensure that the --root-ca-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--root-ca-file\"\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the --root-ca-file parameter to the certificate bundle file`.\n          --root-ca-file=<path/to/file>\n        scored: true\n\n      - id: 1.3.6\n        text: \"Ensure that the RotateKubeletServerCertificate argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--feature-gates\"\n              compare:\n                op: nothave\n                value: \"RotateKubeletServerCertificate=false\"\n              set: true\n            - flag: \"--feature-gates\"\n              set: false\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the --feature-gates parameter to include RotateKubeletServerCertificate=true.\n          --feature-gates=RotateKubeletServerCertificate=true\n        scored: true\n\n      - id: 1.3.7\n        text: \"Ensure that the --bind-address argument is set to 127.0.0.1 (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--bind-address\"\n              compare:\n                op: eq\n                value: \"127.0.0.1\"\n            - flag: \"--bind-address\"\n              set: false\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and ensure the correct value for the --bind-address parameter\n        scored: true\n\n  - id: 1.4\n    text: \"Scheduler\"\n    checks:\n      - id: 1.4.1\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: \"/bin/ps -ef | grep $schedulerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the Scheduler pod specification file $schedulerconf file\n          on the control plane node and set the below parameter.\n          --profiling=false\n        scored: true\n\n      - id: 1.4.2\n        text: \"Ensure that the --bind-address argument is set to 127.0.0.1 (Automated)\"\n        audit: \"/bin/ps -ef | grep $schedulerbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--bind-address\"\n              compare:\n                op: eq\n                value: \"127.0.0.1\"\n            - flag: \"--bind-address\"\n              set: false\n        remediation: |\n          Edit the Scheduler pod specification file $schedulerconf\n          on the control plane node and ensure the correct value for the --bind-address parameter\n        scored: true\n"
  },
  {
    "path": "cfg/cis-1.10/node.yaml",
    "content": "---\ncontrols:\nversion: \"cis-1.10\"\nid: 4\ntext: \"Worker Node Security Configuration\"\ntype: \"node\"\ngroups:\n  - id: 4.1\n    text: \"Worker Node Configuration Files\"\n    checks:\n      - id: 4.1.1\n        text: \"Ensure that the kubelet service file permissions are set to 600 or more restrictive (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletsvc; then stat -c permissions=%a $kubeletsvc; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example, chmod 600 $kubeletsvc\n        scored: true\n\n      - id: 4.1.2\n        text: \"Ensure that the kubelet service file ownership is set to root:root (Automated)\"\n        audit: '/bin/sh -c \"if test -e $kubeletsvc; then stat -c %U:%G $kubeletsvc; else echo \\\"File not found\\\"; fi\"'\n        tests:\n          bin_op: or\n          test_items:\n            - flag: root:root\n            - flag: \"File not found\"\n        remediation: |\n            Run the below command (based on the file location on your system) on the each worker node.\n            For example,\n            chown root:root $kubeletsvc\n        scored: true\n\n      - id: 4.1.3\n        text: \"If proxy kubeconfig file exists ensure permissions are set to 600 or more restrictive (Manual)\"\n        audit: '/bin/sh -c ''if test -e $proxykubeconfig; then stat -c permissions=%a $proxykubeconfig; fi'' '\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"permissions\"\n              set: true\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chmod 600 $proxykubeconfig\n        scored: false\n\n      - id: 4.1.4\n        text: \"If proxy kubeconfig file exists ensure ownership is set to root:root (Manual)\"\n        audit: '/bin/sh -c ''if test -e $proxykubeconfig; then stat -c %U:%G $proxykubeconfig; fi'' '\n        tests:\n          bin_op: or\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example, chown root:root $proxykubeconfig\n        scored: false\n\n      - id: 4.1.5\n        text: \"Ensure that the --kubeconfig kubelet.conf file permissions are set to 600 or more restrictive (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletkubeconfig; then stat -c permissions=%a $kubeletkubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chmod 600 $kubeletkubeconfig\n        scored: true\n\n      - id: 4.1.6\n        text: \"Ensure that the --kubeconfig kubelet.conf file ownership is set to root:root (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletkubeconfig; then stat -c %U:%G $kubeletkubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chown root:root $kubeletkubeconfig\n        scored: true\n\n      - id: 4.1.7\n        text: \"Ensure that the certificate authorities file permissions are set to 600 or more restrictive (Manual)\"\n        audit: |\n          CAFILE=$(ps -ef | grep kubelet | grep -v apiserver | grep -- --client-ca-file= | awk -F '--client-ca-file=' '{print $2}' | awk '{print $1}' | uniq)\n          if test -z $CAFILE; then CAFILE=$kubeletcafile; fi\n          if test -e $CAFILE; then stat -c permissions=%a $CAFILE; fi\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the following command to modify the file permissions of the\n          --client-ca-file chmod 600 <filename>\n        scored: false\n\n      - id: 4.1.8\n        text: \"Ensure that the client certificate authorities file ownership is set to root:root (Manual)\"\n        audit: |\n          CAFILE=$(ps -ef | grep kubelet | grep -v apiserver | grep -- --client-ca-file= | awk -F '--client-ca-file=' '{print $2}' | awk '{print $1}' | uniq)\n          if test -z $CAFILE; then CAFILE=$kubeletcafile; fi\n          if test -e $CAFILE; then stat -c %U:%G $CAFILE; fi\n        tests:\n          test_items:\n            - flag: root:root\n              compare:\n                op: eq\n                value: root:root\n        remediation: |\n          Run the following command to modify the ownership of the --client-ca-file.\n          chown root:root <filename>\n        scored: false\n\n      - id: 4.1.9\n        text: \"If the kubelet config.yaml configuration file is being used validate permissions set to 600 or more restrictive (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletconf; then stat -c permissions=%a $kubeletconf; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the following command (using the config file location identified in the Audit step)\n          chmod 600 $kubeletconf\n        scored: true\n\n      - id: 4.1.10\n        text: \"If the kubelet config.yaml configuration file is being used validate file ownership is set to root:root (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletconf; then stat -c %U:%G $kubeletconf; fi'' '\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the following command (using the config file location identified in the Audit step)\n          chown root:root $kubeletconf\n        scored: true\n\n  - id: 4.2\n    text: \"Kubelet\"\n    checks:\n      - id: 4.2.1\n        text: \"Ensure that the --anonymous-auth argument is set to false (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: \"--anonymous-auth\"\n              path: '{.authentication.anonymous.enabled}'\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          If using a Kubelet config file, edit the file to set `authentication: anonymous: enabled` to\n          `false`.\n          If using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          `--anonymous-auth=false`\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.2\n        text: \"Ensure that the --authorization-mode argument is not set to AlwaysAllow (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --authorization-mode\n              path: '{.authorization.mode}'\n              compare:\n                op: nothave\n                value: AlwaysAllow\n        remediation: |\n          If using a Kubelet config file, edit the file to set `authorization.mode` to Webhook. If\n          using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_AUTHZ_ARGS variable.\n          --authorization-mode=Webhook\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.3\n        text: \"Ensure that the --client-ca-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --client-ca-file\n              path: '{.authentication.x509.clientCAFile}'\n        remediation: |\n          If using a Kubelet config file, edit the file to set `authentication.x509.clientCAFile` to\n          the location of the client CA file.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_AUTHZ_ARGS variable.\n          --client-ca-file=<path/to/client-ca-file>\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.4\n        text: \"Verify that the --read-only-port argument is set to 0 (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--read-only-port\"\n              path: '{.readOnlyPort}'\n              compare:\n                op: eq\n                value: 0\n            - flag: \"--read-only-port\"\n              path: '{.readOnlyPort}'\n              set: false\n        remediation: |\n          If using a Kubelet config file, edit the file to set `readOnlyPort` to 0.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --read-only-port=0\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.5\n        text: \"Ensure that the --streaming-connection-idle-timeout argument is not set to 0 (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --streaming-connection-idle-timeout\n              path: '{.streamingConnectionIdleTimeout}'\n              compare:\n                op: noteq\n                value: 0\n            - flag: --streaming-connection-idle-timeout\n              path: '{.streamingConnectionIdleTimeout}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to set `streamingConnectionIdleTimeout` to a\n          value other than 0.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --streaming-connection-idle-timeout=5m\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.6\n        text: \"Ensure that the --make-iptables-util-chains argument is set to true (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --make-iptables-util-chains\n              path: '{.makeIPTablesUtilChains}'\n              compare:\n                op: eq\n                value: true\n            - flag: --make-iptables-util-chains\n              path: '{.makeIPTablesUtilChains}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to set `makeIPTablesUtilChains` to `true`.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          remove the --make-iptables-util-chains argument from the\n          KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.7\n        text: \"Ensure that the --hostname-override argument is not set (Manual)\"\n        # This is one of those properties that can only be set as a command line argument.\n        # To check if the property is set as expected, we need to parse the kubelet command\n        # instead reading the Kubelet Configuration file.\n        audit: \"/bin/ps -fC $kubeletbin\"\n        tests:\n          test_items:\n            - flag: --hostname-override\n              set: false\n        remediation: |\n          Edit the kubelet service file $kubeletsvc\n          on each worker node and remove the --hostname-override argument from the\n          KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.8\n        text: \"Ensure that the eventRecordQPS argument is set to a level which ensures appropriate event capture (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --event-qps\n              path: '{.eventRecordQPS}'\n              compare:\n                op: gte\n                value: 0\n            - flag: --event-qps\n              path: '{.eventRecordQPS}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to set `eventRecordQPS` to an appropriate level.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.9\n        text: \"Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --tls-cert-file\n              path: '{.tlsCertFile}'\n            - flag: --tls-private-key-file\n              path: '{.tlsPrivateKeyFile}'\n        remediation: |\n          If using a Kubelet config file, edit the file to set `tlsCertFile` to the location\n          of the certificate file to use to identify this Kubelet, and `tlsPrivateKeyFile`\n          to the location of the corresponding private key file.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameters in KUBELET_CERTIFICATE_ARGS variable.\n          --tls-cert-file=<path/to/tls-certificate-file>\n          --tls-private-key-file=<path/to/tls-key-file>\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.10\n        text: \"Ensure that the --rotate-certificates argument is not set to false (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --rotate-certificates\n              path: '{.rotateCertificates}'\n              compare:\n                op: eq\n                value: true\n            - flag: --rotate-certificates\n              path: '{.rotateCertificates}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to add the line `rotateCertificates` to `true` or\n          remove it altogether to use the default value.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          remove --rotate-certificates=false argument from the KUBELET_CERTIFICATE_ARGS\n          variable.\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.11\n        text: \"Verify that the RotateKubeletServerCertificate argument is set to true (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: RotateKubeletServerCertificate\n              path: '{.featureGates.RotateKubeletServerCertificate}'\n              compare:\n                op: nothave\n                value: false\n            - flag: RotateKubeletServerCertificate\n              path: '{.featureGates.RotateKubeletServerCertificate}'\n              set: false\n        remediation: |\n          Edit the kubelet service file $kubeletsvc\n          on each worker node and set the below parameter in KUBELET_CERTIFICATE_ARGS variable.\n          --feature-gates=RotateKubeletServerCertificate=true\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.12\n        text: \"Ensure that the Kubelet only makes use of Strong Cryptographic Ciphers (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --tls-cipher-suites\n              path: '{range .tlsCipherSuites[:]}{}{'',''}{end}'\n              compare:\n                op: valid_elements\n                value: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\n        remediation: |\n          If using a Kubelet config file, edit the file to set `tlsCipherSuites` to\n          TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\n          or to a subset of these values.\n          If using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the --tls-cipher-suites parameter as follows, or to a subset of these values.\n          --tls-cipher-suites=TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.13\n        text: \"Ensure that a limit is set on pod PIDs (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --pod-max-pids\n              path: '{.podPidsLimit}'\n        remediation: |\n          Decide on an appropriate level for this parameter and set it,\n          either via the --pod-max-pids command line parameter or the PodPidsLimit configuration file setting.\n        scored: false\n\n  - id: 4.3\n    text: \"kube-proxy\"\n    checks:\n      - id: 4.3.1\n        text: \"Ensure that the kube-proxy metrics service is bound to localhost (Automated)\"\n        audit: \"/bin/ps -fC $proxybin\"\n        audit_config: \"/bin/sh -c 'if test -e $proxykubeconfig; then cat $proxykubeconfig; fi'\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--metrics-bind-address\"\n              path: '{.metricsBindAddress}'\n              compare:\n                op: has\n                value: \"127.0.0.1\"\n            - flag: \"--metrics-bind-address\"\n              path: '{.metricsBindAddress}'\n              set: false\n        remediation: |\n           Modify or remove any values which bind the metrics service to a non-localhost address.\n           The default value is 127.0.0.1:10249.\n        scored: true\n"
  },
  {
    "path": "cfg/cis-1.10/policies.yaml",
    "content": "---\ncontrols:\nversion: \"cis-1.10\"\nid: 5\ntext: \"Kubernetes Policies\"\ntype: \"policies\"\ngroups:\n  - id: 5.1\n    text: \"RBAC and Service Accounts\"\n    checks:\n      - id: 5.1.1\n        text: \"Ensure that the cluster-admin role is only used where required (Automated)\"\n        audit: |\n          kubectl get clusterrolebindings -o=custom-columns=NAME:.metadata.name,ROLE:.roleRef.name,SUBJECT:.subjects[*].name --no-headers | while read -r role_name role_binding subject\n          do\n            if [[ \"${role_name}\" != \"cluster-admin\" && \"${role_binding}\" == \"cluster-admin\" ]]; then\n              is_compliant=\"false\"\n            else\n              is_compliant=\"true\"\n            fi;\n            echo \"**role_name: ${role_name} role_binding: ${role_binding} subject: ${subject} is_compliant: ${is_compliant}\"\n          done\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"is_compliant\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Identify all clusterrolebindings to the cluster-admin role. Check if they are used and\n          if they need this role or if they could use a role with fewer privileges.\n          Where possible, first bind users to a lower privileged role and then remove the\n          clusterrolebinding to the cluster-admin role : kubectl delete clusterrolebinding [name]\n          Condition: is_compliant is false if rolename is not cluster-admin and rolebinding is cluster-admin.\n        scored: false\n\n      - id: 5.1.2\n        text: \"Minimize access to secrets (Automated)\"\n        audit: \"echo \\\"canGetListWatchSecretsAsSystemAuthenticated: $(kubectl auth can-i get,list,watch secrets --all-namespaces --as=system:authenticated)\\\"\"\n        tests:\n          test_items:\n            - flag: \"canGetListWatchSecretsAsSystemAuthenticated\"\n              compare:\n                op: eq\n                value: no\n        remediation: |\n          Where possible, remove get, list and watch access to Secret objects in the cluster.\n        scored: false\n\n      - id: 5.1.3\n        text: \"Minimize wildcard use in Roles and ClusterRoles (Automated)\"\n        audit: |\n          # Check Roles\n          kubectl get roles --all-namespaces -o custom-columns=ROLE_NAMESPACE:.metadata.namespace,ROLE_NAME:.metadata.name --no-headers | while read -r role_namespace role_name\n          do\n            role_rules=$(kubectl get role -n \"${role_namespace}\" \"${role_name}\" -o=json | jq -c '.rules')\n            if echo \"${role_rules}\" | grep -q \"\\[\\\"\\*\\\"\\]\"; then\n              role_is_compliant=\"false\"\n            else\n              role_is_compliant=\"true\"\n            fi;\n            echo \"**role_name: ${role_name} role_namespace: ${role_namespace} role_rules: ${role_rules} role_is_compliant: ${role_is_compliant}\"\n          done\n\n          # Check ClusterRoles\n          kubectl get clusterroles -o custom-columns=CLUSTERROLE_NAME:.metadata.name --no-headers | while read -r clusterrole_name\n          do\n            clusterrole_rules=$(kubectl get clusterrole \"${clusterrole_name}\" -o=json | jq -c '.rules')\n            if echo \"${clusterrole_rules}\" | grep -q \"\\[\\\"\\*\\\"\\]\"; then\n              clusterrole_is_compliant=\"false\"\n            else\n              clusterrole_is_compliant=\"true\"\n            fi;\n          echo \"**clusterrole_name: ${clusterrole_name} clusterrole_rules: ${clusterrole_rules} clusterrole_is_compliant: ${clusterrole_is_compliant}\"\n          done\n        use_multiple_values: true\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"role_is_compliant\"\n              compare:\n                op: eq\n                value: true\n              set: true\n            - flag: \"clusterrole_is_compliant\"\n              compare:\n                op: eq\n                value: true\n              set: true\n        remediation: |\n          Where possible replace any use of wildcards [\"*\"] in roles and clusterroles with specific\n          objects or actions.\n          Condition: role_is_compliant is false if [\"*\"] is found in rules.\n          Condition: clusterrole_is_compliant is false if [\"*\"] is found in rules.\n        scored: false\n\n      - id: 5.1.4\n        text: \"Minimize access to create pods (Automated)\"\n        audit: |\n          echo \"canCreatePodsAsSystemAuthenticated: $(kubectl auth can-i create pods --all-namespaces --as=system:authenticated)\"\n        tests:\n          test_items:\n            - flag: \"canCreatePodsAsSystemAuthenticated\"\n              compare:\n                op: eq\n                value: no\n        remediation: |\n          Where possible, remove create access to pod objects in the cluster.\n        scored: false\n      - id: 5.1.5\n        text: \"Ensure that default service accounts are not actively used (Automated)\"\n        audit: |\n          kubectl get serviceaccount --all-namespaces --field-selector metadata.name=default -o=json | jq -r '.items[] | \" namespace: \\(.metadata.namespace), kind: \\(.kind), name: \\(.metadata.name), automountServiceAccountToken: \\(.automountServiceAccountToken | if . == null then \"notset\" else . end )\"' | xargs -L 1\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"automountServiceAccountToken\"\n              compare:\n                op: eq\n                value: false\n              set: true\n        remediation: |\n          Create explicit service accounts wherever a Kubernetes workload requires specific access\n          to the Kubernetes API server.\n          Modify the configuration of each default service account to include this value\n          `automountServiceAccountToken: false`.\n        scored: false\n\n      - id: 5.1.6\n        text: \"Ensure that Service Account Tokens are only mounted where necessary (Automated)\"\n        audit: |\n          kubectl get pods --all-namespaces -o custom-columns=POD_NAMESPACE:.metadata.namespace,POD_NAME:.metadata.name,POD_SERVICE_ACCOUNT:.spec.serviceAccount,POD_IS_AUTOMOUNTSERVICEACCOUNTTOKEN:.spec.automountServiceAccountToken --no-headers | while read -r pod_namespace pod_name pod_service_account pod_is_automountserviceaccounttoken\n          do\n            # Retrieve automountServiceAccountToken's value for ServiceAccount and Pod, set to notset if null or <none>.\n            svacc_is_automountserviceaccounttoken=$(kubectl get serviceaccount -n \"${pod_namespace}\" \"${pod_service_account}\" -o json | jq -r '.automountServiceAccountToken' | sed -e 's/<none>/notset/g' -e 's/null/notset/g')\n            pod_is_automountserviceaccounttoken=$(echo \"${pod_is_automountserviceaccounttoken}\" | sed -e 's/<none>/notset/g' -e 's/null/notset/g')\n            if [ \"${svacc_is_automountserviceaccounttoken}\" = \"false\" ] && ( [ \"${pod_is_automountserviceaccounttoken}\" = \"false\" ] || [ \"${pod_is_automountserviceaccounttoken}\" = \"notset\" ] ); then\n              is_compliant=\"true\"\n            elif [ \"${svacc_is_automountserviceaccounttoken}\" = \"true\" ] && [ \"${pod_is_automountserviceaccounttoken}\" = \"false\" ]; then\n              is_compliant=\"true\"\n            else\n              is_compliant=\"false\"\n            fi\n            echo \"**namespace: ${pod_namespace} pod_name: ${pod_name} service_account: ${pod_service_account} pod_is_automountserviceaccounttoken: ${pod_is_automountserviceaccounttoken} svacc_is_automountServiceAccountToken: ${svacc_is_automountserviceaccounttoken} is_compliant: ${is_compliant}\"\n          done\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"is_compliant\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Modify the definition of ServiceAccounts and Pods which do not need to mount service\n          account tokens to disable it, with `automountServiceAccountToken: false`.\n          If both the ServiceAccount and the Pod's .spec specify a value for automountServiceAccountToken, the Pod spec takes precedence.\n          Condition: Pod is_compliant to true when\n            - ServiceAccount is automountServiceAccountToken: false and Pod is automountServiceAccountToken: false or notset\n            - ServiceAccount is automountServiceAccountToken: true notset and Pod is automountServiceAccountToken: false\n        scored: false\n\n      - id: 5.1.7\n        text: \"Avoid use of system:masters group (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Remove the system:masters group from all users in the cluster.\n        scored: false\n\n      - id: 5.1.8\n        text: \"Limit use of the Bind, Impersonate and Escalate permissions in the Kubernetes cluster (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove the impersonate, bind and escalate rights from subjects.\n        scored: false\n\n      - id: 5.1.9\n        text: \"Minimize access to create persistent volumes (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove create access to PersistentVolume objects in the cluster.\n        scored: false\n\n      - id: 5.1.10\n        text: \"Minimize access to the proxy sub-resource of nodes (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove access to the proxy sub-resource of node objects.\n        scored: false\n\n      - id: 5.1.11\n        text: \"Minimize access to the approval sub-resource of certificatesigningrequests objects (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove access to the approval sub-resource of certificatesigningrequests objects.\n        scored: false\n\n      - id: 5.1.12\n        text: \"Minimize access to webhook configuration objects (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove access to the validatingwebhookconfigurations or mutatingwebhookconfigurations objects\n        scored: false\n\n      - id: 5.1.13\n        text: \"Minimize access to the service account token creation (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove access to the token sub-resource of serviceaccount objects.\n        scored: false\n\n  - id: 5.2\n    text: \"Pod Security Standards\"\n    checks:\n      - id: 5.2.1\n        text: \"Ensure that the cluster has at least one active policy control mechanism in place (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that either Pod Security Admission or an external policy control system is in place\n          for every namespace which contains user workloads.\n        scored: false\n\n      - id: 5.2.2\n        text: \"Minimize the admission of privileged containers (Manual)\"\n        audit: |\n          kubectl get pods --all-namespaces -o custom-columns=POD_NAME:.metadata.name,POD_NAMESPACE:.metadata.namespace --no-headers | while read -r pod_name pod_namespace\n          do\n            # Retrieve container(s) for each Pod.\n            kubectl get pod \"${pod_name}\" --namespace \"${pod_namespace}\" -o json | jq -c '.spec.containers[]' | while read -r container\n            do\n              # Retrieve container's name.\n              container_name=$(echo ${container} | jq -r '.name')\n              # Retrieve container's .securityContext.privileged value.\n              container_privileged=$(echo ${container} | jq -r '.securityContext.privileged' | sed -e 's/null/notset/g')\n              if [ \"${container_privileged}\" = \"false\" ] || [ \"${container_privileged}\" = \"notset\" ] ; then\n                echo \"***pod_name: ${pod_name} container_name: ${container_name} pod_namespace: ${pod_namespace} is_container_privileged: ${container_privileged} is_compliant: true\"\n              else\n                echo \"***pod_name: ${pod_name} container_name: ${container_name} pod_namespace: ${pod_namespace} is_container_privileged: ${container_privileged} is_compliant: false\"\n              fi\n            done\n          done\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"is_compliant\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of privileged containers.\n          Audit: the audit list all pods' containers to retrieve their .securityContext.privileged value.\n          Condition: is_compliant is false if container's `.securityContext.privileged` is set to `true`.\n          Default: by default, there are no restrictions on the creation of privileged containers.\n        scored: false\n\n      - id: 5.2.3\n        text: \"Minimize the admission of containers wishing to share the host process ID namespace (Manual)\"\n        audit: |\n          kubectl get pods --all-namespaces -o custom-columns=POD_NAME:.metadata.name,POD_NAMESPACE:.metadata.namespace --no-headers | while read -r pod_name pod_namespace\n          do\n            # Retrieve spec.hostPID for each pod.\n            pod_hostpid=$(kubectl get pod \"${pod_name}\" --namespace \"${pod_namespace}\" -o jsonpath='{.spec.hostPID}' 2>/dev/null)\n            if [ -z \"${pod_hostpid}\" ]; then\n              pod_hostpid=\"false\"\n              echo \"***pod_name: ${pod_name} pod_namespace: ${pod_namespace} is_pod_hostpid: ${pod_hostpid} is_compliant: true\"\n            else\n              echo \"***pod_name: ${pod_name} pod_namespace: ${pod_namespace} is_pod_hostpid: ${pod_hostpid} is_compliant: false\"\n            fi\n          done\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"is_compliant\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of `hostPID` containers.\n          Audit: the audit retrieves each Pod' spec.hostPID.\n          Condition: is_compliant is false if Pod's spec.hostPID is set to `true`.\n          Default: by default, there are no restrictions on the creation of hostPID containers.\n        scored: false\n\n      - id: 5.2.4\n        text: \"Minimize the admission of containers wishing to share the host IPC namespace (Manual)\"\n        audit: |\n          kubectl get pods --all-namespaces -o custom-columns=POD_NAME:.metadata.name,POD_NAMESPACE:.metadata.namespace --no-headers | while read -r pod_name pod_namespace\n          do\n            # Retrieve spec.hostIPC for each pod.\n            pod_hostipc=$(kubectl get pod \"${pod_name}\" --namespace \"${pod_namespace}\" -o jsonpath='{.spec.hostIPC}' 2>/dev/null)\n            if [ -z \"${pod_hostipc}\" ]; then\n              pod_hostipc=\"false\"\n              echo \"***pod_name: ${pod_name} pod_namespace: ${pod_namespace} is_pod_hostipc: ${pod_hostipc} is_compliant: true\"\n            else\n              echo \"***pod_name: ${pod_name} pod_namespace: ${pod_namespace} is_pod_hostipc: ${pod_hostipc} is_compliant: false\"\n            fi\n          done\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"is_compliant\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of `hostIPC` containers.\n          Audit: the audit retrieves each Pod' spec.IPC.\n          Condition: is_compliant is false if Pod's spec.hostIPC is set to `true`.\n          Default: by default, there are no restrictions on the creation of hostIPC containers.\n        scored: false\n\n      - id: 5.2.5\n        text: \"Minimize the admission of containers wishing to share the host network namespace (Manual)\"\n        audit: |\n          kubectl get pods --all-namespaces -o custom-columns=POD_NAME:.metadata.name,POD_NAMESPACE:.metadata.namespace --no-headers | while read -r pod_name pod_namespace\n          do\n            # Retrieve spec.hostNetwork for each pod.\n            pod_hostnetwork=$(kubectl get pod \"${pod_name}\" --namespace \"${pod_namespace}\" -o jsonpath='{.spec.hostNetwork}' 2>/dev/null)\n            if [ -z \"${pod_hostnetwork}\" ]; then\n              pod_hostnetwork=\"false\"\n              echo \"***pod_name: ${pod_name} pod_namespace: ${pod_namespace} is_pod_hostnetwork: ${pod_hostnetwork} is_compliant: true\"\n            else\n              echo \"***pod_name: ${pod_name} pod_namespace: ${pod_namespace} is_pod_hostnetwork: ${pod_hostnetwork} is_compliant: false\"\n            fi\n          done\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"is_compliant\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of `hostNetwork` containers.\n          Audit: the audit retrieves each Pod' spec.hostNetwork.\n          Condition: is_compliant is false if Pod's spec.hostNetwork is set to `true`.\n          Default: by default, there are no restrictions on the creation of hostNetwork containers.\n        scored: false\n\n      - id: 5.2.6\n        text: \"Minimize the admission of containers with allowPrivilegeEscalation (Manual)\"\n        audit: |\n          kubectl get pods --all-namespaces -o custom-columns=POD_NAME:.metadata.name,POD_NAMESPACE:.metadata.namespace --no-headers | while read -r pod_name pod_namespace\n          do\n            # Retrieve container(s) for each Pod.\n            kubectl get pod \"${pod_name}\" --namespace \"${pod_namespace}\" -o json | jq -c '.spec.containers[]' | while read -r container\n            do\n              # Retrieve container's name\n              container_name=$(echo ${container} | jq -r '.name')\n              # Retrieve container's .securityContext.allowPrivilegeEscalation\n              container_allowprivesc=$(echo ${container} | jq -r '.securityContext.allowPrivilegeEscalation' | sed -e 's/null/notset/g')\n              if [ \"${container_allowprivesc}\" = \"false\" ] || [ \"${container_allowprivesc}\" = \"notset\" ]; then\n                echo \"***pod_name: ${pod_name} container_name: ${container_name} pod_namespace: ${pod_namespace} is_container_allowprivesc: ${container_allowprivesc} is_compliant: true\"\n              else\n                echo \"***pod_name: ${pod_name} container_name: ${container_name} pod_namespace: ${pod_namespace} is_container_allowprivesc: ${container_allowprivesc} is_compliant: false\"\n              fi\n            done\n          done\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"is_compliant\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers with `.securityContext.allowPrivilegeEscalation` set to `true`.\n          Audit: the audit retrieves each Pod's container(s) `.securityContext.allowPrivilegeEscalation`.\n          Condition: is_compliant is false if container's `.securityContext.allowPrivilegeEscalation` is set to `true`.\n          Default: If notset, privilege escalation is allowed (default to true). However if PSP/PSA is used with a `restricted` profile,\n          privilege escalation is explicitly disallowed unless configured otherwise.\n        scored: false\n\n      - id: 5.2.7\n        text: \"Minimize the admission of root containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Create a policy for each namespace in the cluster, ensuring that either `MustRunAsNonRoot`\n          or `MustRunAs` with the range of UIDs not including 0, is set.\n        scored: false\n\n      - id: 5.2.8\n        text: \"Minimize the admission of containers with the NET_RAW capability (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers with the `NET_RAW` capability.\n        scored: false\n\n      - id: 5.2.9\n        text: \"Minimize the admission of containers with added capabilities (Manual)\"\n        audit: |\n          kubectl get pods --all-namespaces -o custom-columns=POD_NAME:.metadata.name,POD_NAMESPACE:.metadata.namespace --no-headers | while read -r pod_name pod_namespace\n          do\n            # Retrieve container(s) for each Pod.\n            kubectl get pod \"${pod_name}\" --namespace \"${pod_namespace}\" -o json | jq -c '.spec.containers[]' | while read -r container\n            do\n              # Retrieve container's name\n              container_name=$(echo ${container} | jq -r '.name')\n              # Retrieve container's added capabilities\n              container_caps_add=$(echo ${container} | jq -r '.securityContext.capabilities.add' | sed -e 's/null/notset/g')\n              # Set is_compliant to true by default.\n              is_compliant=true\n              caps_list=\"\"\n              if [ \"${container_caps_add}\" != \"notset\" ]; then\n                # Loop through all caps and append caps_list, then set is_compliant to false.\n                for cap in $(echo \"${container_caps_add}\" | jq -r '.[]'); do\n                caps_list+=\"${cap},\"\n                is_compliant=false\n                done\n                # Remove trailing comma for the last list member.\n                caps_list=${caps_list%,}\n              fi\n              if [ \"${is_compliant}\" = true ]; then\n                echo \"***pod_name: ${pod_name} container_name: ${container_name} pod_namespace: ${pod_namespace} container_caps_add: ${container_caps_add} is_compliant: true\"\n              else\n                echo \"***pod_name: ${pod_name} container_name: ${container_name} pod_namespace: ${pod_namespace} container_caps_add: ${caps_list} is_compliant: false\"\n              fi\n            done\n          done\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"is_compliant\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Ensure that `allowedCapabilities` is not present in policies for the cluster unless\n          it is set to an empty array.\n          Audit: the audit retrieves each Pod's container(s) added capabilities.\n          Condition: is_compliant is false if added capabilities are added for a given container.\n          Default: Containers run with a default set of capabilities as assigned by the Container Runtime.\n        scored: false\n\n      - id: 5.2.10\n        text: \"Minimize the admission of containers with capabilities assigned (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Review the use of capabilites in applications running on your cluster. Where a namespace\n          contains applications which do not require any Linux capabities to operate consider adding\n          a PSP which forbids the admission of containers which do not drop all capabilities.\n        scored: false\n\n      - id: 5.2.11\n        text: \"Minimize the admission of Windows HostProcess containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers that have `.securityContext.windowsOptions.hostProcess` set to `true`.\n        scored: false\n\n      - id: 5.2.12\n        text: \"Minimize the admission of HostPath volumes (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers with `hostPath` volumes.\n        scored: false\n\n      - id: 5.2.13\n        text: \"Minimize the admission of containers which use HostPorts (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers which use `hostPort` sections.\n        scored: false\n\n  - id: 5.3\n    text: \"Network Policies and CNI\"\n    checks:\n      - id: 5.3.1\n        text: \"Ensure that the CNI in use supports NetworkPolicies (Manual)\"\n        type: \"manual\"\n        remediation: |\n          If the CNI plugin in use does not support network policies, consideration should be given to\n          making use of a different plugin, or finding an alternate mechanism for restricting traffic\n          in the Kubernetes cluster.\n        scored: false\n\n      - id: 5.3.2\n        text: \"Ensure that all Namespaces have NetworkPolicies defined (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the documentation and create NetworkPolicy objects as you need them.\n        scored: false\n\n  - id: 5.4\n    text: \"Secrets Management\"\n    checks:\n      - id: 5.4.1\n        text: \"Prefer using Secrets as files over Secrets as environment variables (Manual)\"\n        type: \"manual\"\n        remediation: |\n          If possible, rewrite application code to read Secrets from mounted secret files, rather than\n          from environment variables.\n        scored: false\n\n      - id: 5.4.2\n        text: \"Consider external secret storage (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Refer to the Secrets management options offered by your cloud provider or a third-party\n          secrets management solution.\n        scored: false\n\n  - id: 5.5\n    text: \"Extensible Admission Control\"\n    checks:\n      - id: 5.5.1\n        text: \"Configure Image Provenance using ImagePolicyWebhook admission controller (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and setup image provenance.\n        scored: false\n\n  - id: 5.7\n    text: \"General Policies\"\n    checks:\n      - id: 5.7.1\n        text: \"Create administrative boundaries between resources using namespaces (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the documentation and create namespaces for objects in your deployment as you need\n          them.\n        scored: false\n\n      - id: 5.7.2\n        text: \"Ensure that the seccomp profile is set to docker/default in your Pod definitions (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Use `securityContext` to enable the docker/default seccomp profile in your pod definitions.\n          An example is as below:\n            securityContext:\n              seccompProfile:\n                type: RuntimeDefault\n        scored: false\n\n      - id: 5.7.3\n        text: \"Apply SecurityContext to your Pods and Containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and apply SecurityContexts to your Pods. For a\n          suggested list of SecurityContexts, you may refer to the CIS Security Benchmark for Docker\n          Containers.\n        scored: false\n\n      - id: 5.7.4\n        text: \"The default namespace should not be used (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that namespaces are created to allow for appropriate segregation of Kubernetes\n          resources and that all new resources are created in a specific namespace.\n        scored: false\n"
  },
  {
    "path": "cfg/cis-1.11/config.yaml",
    "content": "---\n## Version-specific settings that override the values in cfg/config.yaml\n"
  },
  {
    "path": "cfg/cis-1.11/controlplane.yaml",
    "content": "---\ncontrols:\nversion: \"cis-1.11\"\nid: 3\ntext: \"Control Plane Configuration\"\ntype: \"controlplane\"\ngroups:\n  - id: 3.1\n    text: \"Authentication and Authorization\"\n    checks:\n      - id: 3.1.1\n        text: \"Client certificate authentication should not be used for users (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Alternative mechanisms provided by Kubernetes such as the use of OIDC should be\n          implemented in place of client certificates.\n        scored: false\n\n      - id: 3.1.2\n        text: \"Service account token authentication should not be used for users (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Alternative mechanisms provided by Kubernetes such as the use of OIDC should be implemented\n          in place of service account tokens.\n        scored: false\n\n      - id: 3.1.3\n        text: \"Bootstrap token authentication should not be used for users (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Alternative mechanisms provided by Kubernetes such as the use of OIDC should be implemented\n          in place of bootstrap tokens.\n        scored: false\n\n  - id: 3.2\n    text: \"Logging\"\n    checks:\n      - id: 3.2.1\n        text: \"Ensure that a minimal audit policy is created (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-policy-file\"\n              set: true\n        remediation: |\n          Create an audit policy file for your cluster.\n        scored: false\n\n      - id: 3.2.2\n        text: \"Ensure that the audit policy covers key security concerns (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Review the audit policy provided for the cluster and ensure that it covers\n          at least the following areas,\n          - Access to Secrets managed by the cluster. Care should be taken to only\n            log Metadata for requests to Secrets, ConfigMaps, and TokenReviews, in\n            order to avoid risk of logging sensitive data.\n          - Modification of Pod and Deployment objects.\n          - Use of `pods/exec`, `pods/portforward`, `pods/proxy` and `services/proxy`.\n          For most requests, minimally logging at the Metadata level is recommended\n          (the most basic level of logging).\n        scored: false\n"
  },
  {
    "path": "cfg/cis-1.11/etcd.yaml",
    "content": "---\ncontrols:\nversion: \"cis-1.11\"\nid: 2\ntext: \"Etcd Node Configuration\"\ntype: \"etcd\"\ngroups:\n  - id: 2\n    text: \"Etcd Node Configuration\"\n    checks:\n      - id: 2.1\n        text: \"Ensure that the --cert-file and --key-file arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--cert-file\"\n              env: \"ETCD_CERT_FILE\"\n            - flag: \"--key-file\"\n              env: \"ETCD_KEY_FILE\"\n        remediation: |\n          Follow the etcd service documentation and configure TLS encryption.\n          Then, edit the etcd pod specification file /etc/kubernetes/manifests/etcd.yaml\n          on the master node and set the below parameters.\n          --cert-file=</path/to/ca-file>\n          --key-file=</path/to/key-file>\n        scored: true\n\n      - id: 2.2\n        text: \"Ensure that the --client-cert-auth argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--client-cert-auth\"\n              env: \"ETCD_CLIENT_CERT_AUTH\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and set the below parameter.\n          --client-cert-auth=\"true\"\n        scored: true\n\n      - id: 2.3\n        text: \"Ensure that the --auto-tls argument is not set to true (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--auto-tls\"\n              env: \"ETCD_AUTO_TLS\"\n              set: false\n            - flag: \"--auto-tls\"\n              env: \"ETCD_AUTO_TLS\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and either remove the --auto-tls parameter or set it to false.\n            --auto-tls=false\n        scored: true\n\n      - id: 2.4\n        text: \"Ensure that the --peer-cert-file and --peer-key-file arguments are\n        set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--peer-cert-file\"\n              env: \"ETCD_PEER_CERT_FILE\"\n            - flag: \"--peer-key-file\"\n              env: \"ETCD_PEER_KEY_FILE\"\n        remediation: |\n          Follow the etcd service documentation and configure peer TLS encryption as appropriate\n          for your etcd cluster.\n          Then, edit the etcd pod specification file $etcdconf on the\n          master node and set the below parameters.\n          --peer-client-file=</path/to/peer-cert-file>\n          --peer-key-file=</path/to/peer-key-file>\n        scored: true\n\n      - id: 2.5\n        text: \"Ensure that the --peer-client-cert-auth argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--peer-client-cert-auth\"\n              env: \"ETCD_PEER_CLIENT_CERT_AUTH\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and set the below parameter.\n          --peer-client-cert-auth=true\n        scored: true\n\n      - id: 2.6\n        text: \"Ensure that the --peer-auto-tls argument is not set to true (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--peer-auto-tls\"\n              env: \"ETCD_PEER_AUTO_TLS\"\n              set: false\n            - flag: \"--peer-auto-tls\"\n              env: \"ETCD_PEER_AUTO_TLS\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and either remove the --peer-auto-tls parameter or set it to false.\n          --peer-auto-tls=false\n        scored: true\n\n      - id: 2.7\n        text: \"Ensure that a unique Certificate Authority is used for etcd (Manual)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--trusted-ca-file\"\n              env: \"ETCD_TRUSTED_CA_FILE\"\n        remediation: |\n          [Manual test]\n          Follow the etcd documentation and create a dedicated certificate authority setup for the\n          etcd service.\n          Then, edit the etcd pod specification file $etcdconf on the\n          master node and set the below parameter.\n          --trusted-ca-file=</path/to/ca-file>\n        scored: false\n"
  },
  {
    "path": "cfg/cis-1.11/master.yaml",
    "content": "---\ncontrols:\nversion: \"cis-1.11\"\nid: 1\ntext: \"Control Plane Security Configuration\"\ntype: \"master\"\ngroups:\n  - id: 1.1\n    text: \"Control Plane Node Configuration Files\"\n    checks:\n      - id: 1.1.1\n        text: \"Ensure that the API server pod specification file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $apiserverconf; then stat -c permissions=%a $apiserverconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the\n          control plane node.\n          For example, chmod 600 $apiserverconf\n        scored: true\n\n      - id: 1.1.2\n        text: \"Ensure that the API server pod specification file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $apiserverconf; then stat -c %U:%G $apiserverconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chown root:root $apiserverconf\n        scored: true\n\n      - id: 1.1.3\n        text: \"Ensure that the controller manager pod specification file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerconf; then stat -c permissions=%a $controllermanagerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chmod 600 $controllermanagerconf\n        scored: true\n\n      - id: 1.1.4\n        text: \"Ensure that the controller manager pod specification file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerconf; then stat -c %U:%G $controllermanagerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chown root:root $controllermanagerconf\n        scored: true\n\n      - id: 1.1.5\n        text: \"Ensure that the scheduler pod specification file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerconf; then stat -c permissions=%a $schedulerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chmod 600 $schedulerconf\n        scored: true\n\n      - id: 1.1.6\n        text: \"Ensure that the scheduler pod specification file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerconf; then stat -c %U:%G $schedulerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chown root:root $schedulerconf\n        scored: true\n\n      - id: 1.1.7\n        text: \"Ensure that the etcd pod specification file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $etcdconf; then find $etcdconf -name '*etcd*' | xargs stat -c permissions=%a; fi'\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod 600 $etcdconf\n        scored: true\n\n      - id: 1.1.8\n        text: \"Ensure that the etcd pod specification file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $etcdconf; then find $etcdconf -name '*etcd*' | xargs stat -c %U:%G; fi'\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root $etcdconf\n        scored: true\n\n      - id: 1.1.9\n        text: \"Ensure that the Container Network Interface file permissions are set to 600 or more restrictive (Manual)\"\n        audit: |\n          ps -ef | grep $kubeletbin | grep -- --cni-conf-dir | sed 's%.*cni-conf-dir[= ]\\([^ ]*\\).*%\\1%' | xargs -I{} find {} -mindepth 1 | xargs --no-run-if-empty stat -c permissions=%a\n          find /var/lib/cni/networks -type f 2> /dev/null | xargs --no-run-if-empty stat -c permissions=%a\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chmod 600 <path/to/cni/files>\n        scored: false\n\n      - id: 1.1.10\n        text: \"Ensure that the Container Network Interface file ownership is set to root:root (Manual)\"\n        audit: |\n          ps -ef | grep $kubeletbin | grep -- --cni-conf-dir | sed 's%.*cni-conf-dir[= ]\\([^ ]*\\).*%\\1%' | xargs -I{} find {} -mindepth 1 | xargs --no-run-if-empty stat -c %U:%G\n          find /var/lib/cni/networks -type f 2> /dev/null | xargs --no-run-if-empty stat -c %U:%G\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root <path/to/cni/files>\n        scored: false\n\n      - id: 1.1.11\n        text: \"Ensure that the etcd data directory permissions are set to 700 or more restrictive (Automated)\"\n        audit: |\n          DATA_DIR=''\n          for d in $(ps -ef | grep $etcdbin | grep -- --data-dir | sed 's%.*data-dir[= ]\\([^ ]*\\).*%\\1%'); do\n            if test -d \"$d\"; then DATA_DIR=\"$d\"; fi\n          done\n          if ! test -d \"$DATA_DIR\"; then DATA_DIR=$etcddatadir; fi\n          stat -c permissions=%a \"$DATA_DIR\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"700\"\n        remediation: |\n          On the etcd server node, get the etcd data directory, passed as an argument --data-dir,\n          from the command 'ps -ef | grep etcd'.\n          Run the below command (based on the etcd data directory found above). For example,\n          chmod 700 /var/lib/etcd\n        scored: true\n\n      - id: 1.1.12\n        text: \"Ensure that the etcd data directory ownership is set to etcd:etcd (Automated)\"\n        audit: |\n          DATA_DIR=''\n          for d in $(ps -ef | grep $etcdbin | grep -- --data-dir | sed 's%.*data-dir[= ]\\([^ ]*\\).*%\\1%'); do\n            if test -d \"$d\"; then DATA_DIR=\"$d\"; fi\n          done\n          if ! test -d \"$DATA_DIR\"; then DATA_DIR=$etcddatadir; fi\n          stat -c %U:%G \"$DATA_DIR\"\n        tests:\n          test_items:\n            - flag: \"etcd:etcd\"\n        remediation: |\n          On the etcd server node, get the etcd data directory, passed as an argument --data-dir,\n          from the command 'ps -ef | grep etcd'.\n          Run the below command (based on the etcd data directory found above).\n          For example, chown etcd:etcd /var/lib/etcd\n        scored: true\n\n      - id: 1.1.13\n        text: \"Ensure that the default administrative credential file permissions are set to 600 (Automated)\"\n        audit: |\n         for adminconf in /etc/kubernetes/admin.conf /etc/kubernetes/super-admin.conf; do if test -e $adminconf; then stat -c \"permissions=%a %n\" $adminconf; fi; done\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chmod 600 /etc/kubernetes/admin.conf\n          On Kubernetes 1.29+ the super-admin.conf file should also be modified, if present.\n          For example, chmod 600 /etc/kubernetes/super-admin.conf\n        scored: true\n\n      - id: 1.1.14\n        text: \"Ensure that the default administrative credential file ownership is set to root:root (Automated)\"\n        audit: |\n         for adminconf in /etc/kubernetes/admin.conf /etc/kubernetes/super-admin.conf; do if test -e $adminconf; then stat -c \"ownership=%U:%G %n\" $adminconf; fi; done\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"ownership\"\n              compare:\n                op: eq\n                value: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chown root:root /etc/kubernetes/admin.conf\n          On Kubernetes 1.29+ the super-admin.conf file should also be modified, if present.\n          For example, chown root:root /etc/kubernetes/super-admin.conf\n        scored: true\n\n      - id: 1.1.15\n        text: \"Ensure that the scheduler.conf file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerkubeconfig; then stat -c permissions=%a $schedulerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod 600 $schedulerkubeconfig\n        scored: true\n\n      - id: 1.1.16\n        text: \"Ensure that the scheduler.conf file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerkubeconfig; then stat -c %U:%G $schedulerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root $schedulerkubeconfig\n        scored: true\n\n      - id: 1.1.17\n        text: \"Ensure that the controller-manager.conf file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerkubeconfig; then stat -c permissions=%a $controllermanagerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod 600 $controllermanagerkubeconfig\n        scored: true\n\n      - id: 1.1.18\n        text: \"Ensure that the controller-manager.conf file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerkubeconfig; then stat -c %U:%G $controllermanagerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root $controllermanagerkubeconfig\n        scored: true\n\n      - id: 1.1.19\n        text: \"Ensure that the Kubernetes PKI directory and file ownership is set to root:root (Automated)\"\n        audit: \"find /etc/kubernetes/pki/ | xargs stat -c %U:%G\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown -R root:root /etc/kubernetes/pki/\n        scored: true\n\n      - id: 1.1.20\n        text: \"Ensure that the Kubernetes PKI certificate file permissions are set to 644 or more restrictive (Manual)\"\n        audit: \"find /etc/kubernetes/pki/ -name '*.crt' | xargs stat -c permissions=%a\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod -R 644 /etc/kubernetes/pki/*.crt\n        scored: false\n\n      - id: 1.1.21\n        text: \"Ensure that the Kubernetes PKI key file permissions are set to 600 (Manual)\"\n        audit: \"find /etc/kubernetes/pki/ -name '*.key' | xargs stat -c permissions=%a\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod -R 600 /etc/kubernetes/pki/*.key\n        scored: false\n\n  - id: 1.2\n    text: \"API Server\"\n    checks:\n      - id: 1.2.1\n        text: \"Ensure that the --anonymous-auth argument is set to false (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--anonymous-auth\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the below parameter.\n          --anonymous-auth=false\n        scored: false\n\n      - id: 1.2.2\n        text: \"Ensure that the --token-auth-file parameter is not set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--token-auth-file\"\n              set: false\n        remediation: |\n          Follow the documentation and configure alternate mechanisms for authentication. Then,\n          edit the API server pod specification file $apiserverconf\n          on the control plane node and remove the --token-auth-file=<filename> parameter.\n        scored: true\n\n      - id: 1.2.3\n        text: \"Ensure that the --DenyServiceExternalIPs is set (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"DenyServiceExternalIPs\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and add the `DenyServiceExternalIPs` plugin\n          to the enabled admission plugins, as such --enable-admission-plugin=DenyServiceExternalIPs.\n        scored: false\n\n      - id: 1.2.4\n        text: \"Ensure that the --kubelet-client-certificate and --kubelet-client-key arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--kubelet-client-certificate\"\n            - flag: \"--kubelet-client-key\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection between the\n          apiserver and kubelets. Then, edit API server pod specification file\n          $apiserverconf on the control plane node and set the\n          kubelet client certificate and key parameters as below.\n          --kubelet-client-certificate=<path/to/client-certificate-file>\n          --kubelet-client-key=<path/to/client-key-file>\n        scored: true\n\n      - id: 1.2.5\n        text: \"Ensure that the --kubelet-certificate-authority argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--kubelet-certificate-authority\"\n        remediation: |\n          Follow the Kubernetes documentation and setup the TLS connection between\n          the apiserver and kubelets. Then, edit the API server pod specification file\n          $apiserverconf on the control plane node and set the\n          --kubelet-certificate-authority parameter to the path to the cert file for the certificate authority.\n          --kubelet-certificate-authority=<ca-string>\n        scored: true\n\n      - id: 1.2.6\n        text: \"Ensure that the --authorization-mode argument is not set to AlwaysAllow (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: nothave\n                value: \"AlwaysAllow\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --authorization-mode parameter to values other than AlwaysAllow.\n          One such example could be as below.\n          --authorization-mode=RBAC\n        scored: true\n\n      - id: 1.2.7\n        text: \"Ensure that the --authorization-mode argument includes Node (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: has\n                value: \"Node\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --authorization-mode parameter to a value that includes Node.\n          --authorization-mode=Node,RBAC\n        scored: true\n\n      - id: 1.2.8\n        text: \"Ensure that the --authorization-mode argument includes RBAC (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: has\n                value: \"RBAC\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --authorization-mode parameter to a value that includes RBAC,\n          for example `--authorization-mode=Node,RBAC`.\n        scored: true\n\n      - id: 1.2.9\n        text: \"Ensure that the admission control plugin EventRateLimit is set (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"EventRateLimit\"\n        remediation: |\n          Follow the Kubernetes documentation and set the desired limits in a configuration file.\n          Then, edit the API server pod specification file $apiserverconf\n          and set the below parameters.\n          --enable-admission-plugins=...,EventRateLimit,...\n          --admission-control-config-file=<path/to/configuration/file>\n        scored: false\n\n      - id: 1.2.10\n        text: \"Ensure that the admission control plugin AlwaysAdmit is not set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: nothave\n                value: AlwaysAdmit\n            - flag: \"--enable-admission-plugins\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and either remove the --enable-admission-plugins parameter, or set it to a\n          value that does not include AlwaysAdmit.\n        scored: true\n\n      - id: 1.2.11\n        text: \"Ensure that the admission control plugin AlwaysPullImages is set (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"AlwaysPullImages\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --enable-admission-plugins parameter to include\n          AlwaysPullImages.\n          --enable-admission-plugins=...,AlwaysPullImages,...\n        scored: false\n\n      - id: 1.2.12\n        text: \"Ensure that the admission control plugin ServiceAccount is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--disable-admission-plugins\"\n              compare:\n                op: nothave\n                value: \"ServiceAccount\"\n            - flag: \"--disable-admission-plugins\"\n              set: false\n        remediation: |\n          Follow the documentation and create ServiceAccount objects as per your environment.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and ensure that the --disable-admission-plugins parameter is set to a\n          value that does not include ServiceAccount.\n        scored: true\n\n      - id: 1.2.13\n        text: \"Ensure that the admission control plugin NamespaceLifecycle is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--disable-admission-plugins\"\n              compare:\n                op: nothave\n                value: \"NamespaceLifecycle\"\n            - flag: \"--disable-admission-plugins\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --disable-admission-plugins parameter to\n          ensure it does not include NamespaceLifecycle.\n        scored: true\n\n      - id: 1.2.14\n        text: \"Ensure that the admission control plugin NodeRestriction is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"NodeRestriction\"\n        remediation: |\n          Follow the Kubernetes documentation and configure NodeRestriction plug-in on kubelets.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --enable-admission-plugins parameter to a\n          value that includes NodeRestriction.\n          --enable-admission-plugins=...,NodeRestriction,...\n        scored: true\n\n      - id: 1.2.15\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the below parameter.\n          --profiling=false\n        scored: true\n\n      - id: 1.2.16\n        text: \"Ensure that the --audit-log-path argument is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-path\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --audit-log-path parameter to a suitable path and\n          file where you would like audit logs to be written, for example,\n          --audit-log-path=/var/log/apiserver/audit.log\n        scored: true\n\n      - id: 1.2.17\n        text: \"Ensure that the --audit-log-maxage argument is set to 30 or as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxage\"\n              compare:\n                op: gte\n                value: 30\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --audit-log-maxage parameter to 30\n          or as an appropriate number of days, for example,\n          --audit-log-maxage=30\n        scored: true\n\n      - id: 1.2.18\n        text: \"Ensure that the --audit-log-maxbackup argument is set to 10 or as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxbackup\"\n              compare:\n                op: gte\n                value: 10\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --audit-log-maxbackup parameter to 10 or to an appropriate\n          value. For example,\n          --audit-log-maxbackup=10\n        scored: true\n\n      - id: 1.2.19\n        text: \"Ensure that the --audit-log-maxsize argument is set to 100 or as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxsize\"\n              compare:\n                op: gte\n                value: 100\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --audit-log-maxsize parameter to an appropriate size in MB.\n          For example, to set it as 100 MB, --audit-log-maxsize=100\n        scored: true\n\n      - id: 1.2.20\n        text: \"Ensure that the --request-timeout argument is set as appropriate (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        type: manual\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          and set the below parameter as appropriate and if needed.\n          For example, --request-timeout=300s\n        scored: false\n\n      - id: 1.2.21\n        text: \"Ensure that the --service-account-lookup argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--service-account-lookup\"\n              set: false\n            - flag: \"--service-account-lookup\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the below parameter.\n          --service-account-lookup=true\n          Alternatively, you can delete the --service-account-lookup parameter from this file so\n          that the default takes effect.\n        scored: true\n\n      - id: 1.2.22\n        text: \"Ensure that the --service-account-key-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--service-account-key-file\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --service-account-key-file parameter\n          to the public key file for service accounts. For example,\n          --service-account-key-file=<filename>\n        scored: true\n\n      - id: 1.2.23\n        text: \"Ensure that the --etcd-certfile and --etcd-keyfile arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--etcd-certfile\"\n            - flag: \"--etcd-keyfile\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection between the apiserver and etcd.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the etcd certificate and key file parameters.\n          --etcd-certfile=<path/to/client-certificate-file>\n          --etcd-keyfile=<path/to/client-key-file>\n        scored: true\n\n      - id: 1.2.24\n        text: \"Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--tls-cert-file\"\n            - flag: \"--tls-private-key-file\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection on the apiserver.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the TLS certificate and private key file parameters.\n          --tls-cert-file=<path/to/tls-certificate-file>\n          --tls-private-key-file=<path/to/tls-key-file>\n        scored: true\n\n      - id: 1.2.25\n        text: \"Ensure that the --client-ca-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--client-ca-file\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection on the apiserver.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the client certificate authority file.\n          --client-ca-file=<path/to/client-ca-file>\n        scored: true\n\n      - id: 1.2.26\n        text: \"Ensure that the --etcd-cafile argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--etcd-cafile\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection between the apiserver and etcd.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the etcd certificate authority file parameter.\n          --etcd-cafile=<path/to/ca-file>\n        scored: true\n\n      - id: 1.2.27\n        text: \"Ensure that the --encryption-provider-config argument is set as appropriate (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--encryption-provider-config\"\n        remediation: |\n          Follow the Kubernetes documentation and configure a EncryptionConfig file.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --encryption-provider-config parameter to the path of that file.\n          For example, --encryption-provider-config=</path/to/EncryptionConfig/File>\n        scored: false\n\n      - id: 1.2.28\n        text: \"Ensure that encryption providers are appropriately configured (Manual)\"\n        audit: |\n          ENCRYPTION_PROVIDER_CONFIG=$(ps -ef | grep $apiserverbin | grep -- --encryption-provider-config | sed 's%.*encryption-provider-config[= ]\\([^ ]*\\).*%\\1%')\n          if test -e $ENCRYPTION_PROVIDER_CONFIG; then grep -A1 'providers:' $ENCRYPTION_PROVIDER_CONFIG | tail -n1 | grep -o \"[A-Za-z]*\" | sed 's/^/provider=/'; fi\n        tests:\n          test_items:\n            - flag: \"provider\"\n              compare:\n                op: valid_elements\n                value: \"aescbc,kms,secretbox\"\n        remediation: |\n          Follow the Kubernetes documentation and configure a EncryptionConfig file.\n          In this file, choose aescbc, kms or secretbox as the encryption provider.\n        scored: false\n\n      - id: 1.2.29\n        text: \"Ensure that the API Server only makes use of Strong Cryptographic Ciphers (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--tls-cipher-suites\"\n              compare:\n                op: valid_elements\n                value: \"TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,TLS_CHACHA20_POLY1305_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256\"\n        remediation: |\n          Edit the API server pod specification file /etc/kubernetes/manifests/kube-apiserver.yaml\n          on the control plane node and set the below parameter.\n          --tls-cipher-suites=TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,TLS_CHACHA20_POLY1305_SHA256,\n          TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,\n          TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,\n          TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,\n          TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,\n          TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256\n        scored: false\n\n      - id: 1.2.30\n        text: \"Ensure that the --service-account-extend-token-expiration parameter is set to false (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--service-account-extend-token-expiration\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the API server pod specification file /etc/kubernetes/manifests/kube-apiserver.yaml on the Control Plane node and set the --service-account-extend-token-expiration parameter to false.\n          `--service-account-extend-token-expiration=false`\n          By default, this parameter is set to true.\n        scored: true\n\n  - id: 1.3\n    text: \"Controller Manager\"\n    checks:\n      - id: 1.3.1\n        text: \"Ensure that the --terminated-pod-gc-threshold argument is set as appropriate (Manual)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--terminated-pod-gc-threshold\"\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the --terminated-pod-gc-threshold to an appropriate threshold,\n          for example, --terminated-pod-gc-threshold=10\n        scored: false\n\n      - id: 1.3.2\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the below parameter.\n          --profiling=false\n        scored: true\n\n      - id: 1.3.3\n        text: \"Ensure that the --use-service-account-credentials argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--use-service-account-credentials\"\n              compare:\n                op: noteq\n                value: false\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node to set the below parameter.\n          --use-service-account-credentials=true\n        scored: true\n\n      - id: 1.3.4\n        text: \"Ensure that the --service-account-private-key-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--service-account-private-key-file\"\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the --service-account-private-key-file parameter\n          to the private key file for service accounts.\n          --service-account-private-key-file=<filename>\n        scored: true\n\n      - id: 1.3.5\n        text: \"Ensure that the --root-ca-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--root-ca-file\"\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the --root-ca-file parameter to the certificate bundle file`.\n          --root-ca-file=<path/to/file>\n        scored: true\n\n      - id: 1.3.6\n        text: \"Ensure that the RotateKubeletServerCertificate argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--feature-gates\"\n              compare:\n                op: nothave\n                value: \"RotateKubeletServerCertificate=false\"\n              set: true\n            - flag: \"--feature-gates\"\n              set: false\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the --feature-gates parameter to include RotateKubeletServerCertificate=true.\n          --feature-gates=RotateKubeletServerCertificate=true\n        scored: true\n\n      - id: 1.3.7\n        text: \"Ensure that the --bind-address argument is set to 127.0.0.1 (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--bind-address\"\n              compare:\n                op: eq\n                value: \"127.0.0.1\"\n            - flag: \"--bind-address\"\n              set: false\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and ensure the correct value for the --bind-address parameter\n        scored: true\n\n  - id: 1.4\n    text: \"Scheduler\"\n    checks:\n      - id: 1.4.1\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: \"/bin/ps -ef | grep $schedulerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the Scheduler pod specification file $schedulerconf file\n          on the control plane node and set the below parameter.\n          --profiling=false\n        scored: true\n\n      - id: 1.4.2\n        text: \"Ensure that the --bind-address argument is set to 127.0.0.1 (Automated)\"\n        audit: \"/bin/ps -ef | grep $schedulerbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--bind-address\"\n              compare:\n                op: eq\n                value: \"127.0.0.1\"\n            - flag: \"--bind-address\"\n              set: false\n        remediation: |\n          Edit the Scheduler pod specification file $schedulerconf\n          on the control plane node and ensure the correct value for the --bind-address parameter\n        scored: true\n"
  },
  {
    "path": "cfg/cis-1.11/node.yaml",
    "content": "---\ncontrols:\nversion: \"cis-1.11\"\nid: 4\ntext: \"Worker Node Security Configuration\"\ntype: \"node\"\ngroups:\n  - id: 4.1\n    text: \"Worker Node Configuration Files\"\n    checks:\n      - id: 4.1.1\n        text: \"Ensure that the kubelet service file permissions are set to 600 or more restrictive (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletsvc; then stat -c permissions=%a $kubeletsvc; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example, chmod 600 $kubeletsvc\n        scored: true\n\n      - id: 4.1.2\n        text: \"Ensure that the kubelet service file ownership is set to root:root (Automated)\"\n        audit: '/bin/sh -c \"if test -e $kubeletsvc; then stat -c %U:%G $kubeletsvc; else echo \\\"File not found\\\"; fi\"'\n        tests:\n          bin_op: or\n          test_items:\n            - flag: root:root\n            - flag: \"File not found\"\n        remediation: |\n            Run the below command (based on the file location on your system) on the each worker node.\n            For example,\n            chown root:root $kubeletsvc\n        scored: true\n\n      - id: 4.1.3\n        text: \"If proxy kubeconfig file exists ensure permissions are set to 600 or more restrictive (Manual)\"\n        audit: '/bin/sh -c ''if test -e $proxykubeconfig; then stat -c permissions=%a $proxykubeconfig; fi'' '\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"permissions\"\n              set: true\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chmod 600 $proxykubeconfig\n        scored: false\n\n      - id: 4.1.4\n        text: \"If proxy kubeconfig file exists ensure ownership is set to root:root (Manual)\"\n        audit: '/bin/sh -c ''if test -e $proxykubeconfig; then stat -c %U:%G $proxykubeconfig; fi'' '\n        tests:\n          bin_op: or\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example, chown root:root $proxykubeconfig\n        scored: false\n\n      - id: 4.1.5\n        text: \"Ensure that the --kubeconfig kubelet.conf file permissions are set to 600 or more restrictive (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletkubeconfig; then stat -c permissions=%a $kubeletkubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chmod 600 $kubeletkubeconfig\n        scored: true\n\n      - id: 4.1.6\n        text: \"Ensure that the --kubeconfig kubelet.conf file ownership is set to root:root (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletkubeconfig; then stat -c %U:%G $kubeletkubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chown root:root $kubeletkubeconfig\n        scored: true\n\n      - id: 4.1.7\n        text: \"Ensure that the certificate authorities file permissions are set to 644 or more restrictive (Manual)\"\n        audit: |\n          CAFILE=$(ps -ef | grep kubelet | grep -v apiserver | grep -- --client-ca-file= | awk -F '--client-ca-file=' '{print $2}' | awk '{print $1}' | uniq)\n          if test -z $CAFILE; then CAFILE=$kubeletcafile; fi\n          if test -e $CAFILE; then stat -c permissions=%a $CAFILE; fi\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the following command to modify the file permissions of the\n          --client-ca-file chmod 644 <filename>\n        scored: false\n\n      - id: 4.1.8\n        text: \"Ensure that the client certificate authorities file ownership is set to root:root (Manual)\"\n        audit: |\n          CAFILE=$(ps -ef | grep kubelet | grep -v apiserver | grep -- --client-ca-file= | awk -F '--client-ca-file=' '{print $2}' | awk '{print $1}' | uniq)\n          if test -z $CAFILE; then CAFILE=$kubeletcafile; fi\n          if test -e $CAFILE; then stat -c %U:%G $CAFILE; fi\n        tests:\n          test_items:\n            - flag: root:root\n              compare:\n                op: eq\n                value: root:root\n        remediation: |\n          Run the following command to modify the ownership of the --client-ca-file.\n          chown root:root <filename>\n        scored: false\n\n      - id: 4.1.9\n        text: \"If the kubelet config.yaml configuration file is being used validate permissions set to 600 or more restrictive (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletconf; then stat -c permissions=%a $kubeletconf; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the following command (using the config file location identified in the Audit step)\n          chmod 600 $kubeletconf\n        scored: true\n\n      - id: 4.1.10\n        text: \"If the kubelet config.yaml configuration file is being used validate file ownership is set to root:root (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletconf; then stat -c %U:%G $kubeletconf; fi'' '\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the following command (using the config file location identified in the Audit step)\n          chown root:root $kubeletconf\n        scored: true\n\n  - id: 4.2\n    text: \"Kubelet\"\n    checks:\n      - id: 4.2.1\n        text: \"Ensure that the --anonymous-auth argument is set to false (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: \"--anonymous-auth\"\n              path: '{.authentication.anonymous.enabled}'\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          If using a Kubelet config file, edit the file to set `authentication: anonymous: enabled` to\n          `false`.\n          If using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          `--anonymous-auth=false`\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.2\n        text: \"Ensure that the --authorization-mode argument is not set to AlwaysAllow (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --authorization-mode\n              path: '{.authorization.mode}'\n              compare:\n                op: nothave\n                value: AlwaysAllow\n        remediation: |\n          If using a Kubelet config file, edit the file to set `authorization.mode` to Webhook. If\n          using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_AUTHZ_ARGS variable.\n          --authorization-mode=Webhook\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.3\n        text: \"Ensure that the --client-ca-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --client-ca-file\n              path: '{.authentication.x509.clientCAFile}'\n        remediation: |\n          If using a Kubelet config file, edit the file to set `authentication.x509.clientCAFile` to\n          the location of the client CA file.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_AUTHZ_ARGS variable.\n          --client-ca-file=<path/to/client-ca-file>\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.4\n        text: \"Verify that if defined, the --read-only-port argument is set to 0 (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--read-only-port\"\n              path: '{.readOnlyPort}'\n              compare:\n                op: eq\n                value: 0\n            - flag: \"--read-only-port\"\n              path: '{.readOnlyPort}'\n              set: false\n        remediation: |\n          If using a Kubelet config file, edit the file to set `readOnlyPort` to 0.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --read-only-port=0\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.5\n        text: \"Ensure that the --streaming-connection-idle-timeout argument is not set to 0 (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --streaming-connection-idle-timeout\n              path: '{.streamingConnectionIdleTimeout}'\n              compare:\n                op: noteq\n                value: 0\n            - flag: --streaming-connection-idle-timeout\n              path: '{.streamingConnectionIdleTimeout}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to set `streamingConnectionIdleTimeout` to a\n          value other than 0.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --streaming-connection-idle-timeout=5m\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.6\n        text: \"Ensure that the --make-iptables-util-chains argument is set to true (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --make-iptables-util-chains\n              path: '{.makeIPTablesUtilChains}'\n              compare:\n                op: eq\n                value: true\n            - flag: --make-iptables-util-chains\n              path: '{.makeIPTablesUtilChains}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to set `makeIPTablesUtilChains` to `true`.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          remove the --make-iptables-util-chains argument from the\n          KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.7\n        text: \"Ensure that the --hostname-override argument is not set (Manual)\"\n        # This is one of those properties that can only be set as a command line argument.\n        # To check if the property is set as expected, we need to parse the kubelet command\n        # instead reading the Kubelet Configuration file.\n        audit: \"/bin/ps -fC $kubeletbin\"\n        tests:\n          test_items:\n            - flag: --hostname-override\n              set: false\n        remediation: |\n          Edit the kubelet service file $kubeletsvc\n          on each worker node and remove the --hostname-override argument from the\n          KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.8\n        text: \"Ensure that the eventRecordQPS argument is set to a level which ensures appropriate event capture (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --event-qps\n              path: '{.eventRecordQPS}'\n              compare:\n                op: gte\n                value: 0\n            - flag: --event-qps\n              path: '{.eventRecordQPS}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to set `eventRecordQPS` to an appropriate level.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.9\n        text: \"Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --tls-cert-file\n              path: '{.tlsCertFile}'\n            - flag: --tls-private-key-file\n              path: '{.tlsPrivateKeyFile}'\n        remediation: |\n          If using a Kubelet config file, edit the file to set `tlsCertFile` to the location\n          of the certificate file to use to identify this Kubelet, and `tlsPrivateKeyFile`\n          to the location of the corresponding private key file.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameters in KUBELET_CERTIFICATE_ARGS variable.\n          --tls-cert-file=<path/to/tls-certificate-file>\n          --tls-private-key-file=<path/to/tls-key-file>\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.10\n        text: \"Ensure that the --rotate-certificates argument is not set to false (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --rotate-certificates\n              path: '{.rotateCertificates}'\n              compare:\n                op: eq\n                value: true\n            - flag: --rotate-certificates\n              path: '{.rotateCertificates}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to add the line `rotateCertificates` to `true` or\n          remove it altogether to use the default value.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          remove --rotate-certificates=false argument from the KUBELET_CERTIFICATE_ARGS\n          variable.\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.11\n        text: \"Verify that the RotateKubeletServerCertificate argument is set to true (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: RotateKubeletServerCertificate\n              path: '{.featureGates.RotateKubeletServerCertificate}'\n              compare:\n                op: nothave\n                value: false\n            - flag: RotateKubeletServerCertificate\n              path: '{.featureGates.RotateKubeletServerCertificate}'\n              set: false\n        remediation: |\n          Edit the kubelet service file $kubeletsvc\n          on each worker node and set the below parameter in KUBELET_CERTIFICATE_ARGS variable.\n          --feature-gates=RotateKubeletServerCertificate=true\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.12\n        text: \"Ensure that the Kubelet only makes use of Strong Cryptographic Ciphers (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --tls-cipher-suites\n              path: '{range .tlsCipherSuites[:]}{}{'',''}{end}'\n              compare:\n                op: valid_elements\n                value: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\n        remediation: |\n          If using a Kubelet config file, edit the file to set `tlsCipherSuites` to\n          TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\n          or to a subset of these values.\n          If using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the --tls-cipher-suites parameter as follows, or to a subset of these values.\n          --tls-cipher-suites=TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.13\n        text: \"Ensure that a limit is set on pod PIDs (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --pod-max-pids\n              path: '{.podPidsLimit}'\n        remediation: |\n          Decide on an appropriate level for this parameter and set it,\n          either via the --pod-max-pids command line parameter or the PodPidsLimit configuration file setting.\n        scored: false\n\n      - id: 4.2.14\n        text: \"Ensure that the --seccomp-default parameter is set to true (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --seccomp-default\n              path: '{.seccompDefault}'\n        remediation: |\n          Set the parameter, either via the --seccomp-default command line parameter or the\n          seccompDefault configuration file setting.\n          By default the seccomp profile is not enabled.\n        scored: false\n\n      - id: 4.2.15\n        text: \"Ensure that the --IPAddressDeny is set to any (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --IPAddressDeny\n              path: '{.IPAddressDeny}'\n        remediation: |\n         Configuring the setting IPAddressDeny=any will deny service to any IP address not specified in the complimentary setting IPAddressAllow configuration parameter (\n         IPAddressDeny=any\n         IPAddressAllow={{ kubelet_secure_addresses }}\n         *Note\n           kubelet_secure_addresses: \"localhost link-local {{ kube_pods_subnets |regex_replace(',', ' ') }} {{ kube_node_addresses }} {{ loadbalancer_apiserver.address | default('')\"\n         By default IPAddressDeny is not enabled.\n        scored: false\n\n  - id: 4.3\n    text: \"kube-proxy\"\n    checks:\n      - id: 4.3.1\n        text: \"Ensure that the kube-proxy metrics service is bound to localhost (Automated)\"\n        audit: \"/bin/ps -fC $proxybin\"\n        audit_config: \"/bin/sh -c 'if test -e $proxykubeconfig; then cat $proxykubeconfig; fi'\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--metrics-bind-address\"\n              path: '{.metricsBindAddress}'\n              compare:\n                op: has\n                value: \"127.0.0.1\"\n            - flag: \"--metrics-bind-address\"\n              path: '{.metricsBindAddress}'\n              set: false\n        remediation: |\n           Modify or remove any values which bind the metrics service to a non-localhost address.\n           The default value is 127.0.0.1:10249.\n        scored: true\n"
  },
  {
    "path": "cfg/cis-1.11/policies.yaml",
    "content": "---\ncontrols:\nversion: \"cis-1.11\"\nid: 5\ntext: \"Kubernetes Policies\"\ntype: \"policies\"\ngroups:\n  - id: 5.1\n    text: \"RBAC and Service Accounts\"\n    checks:\n      - id: 5.1.1\n        text: \"Ensure that the cluster-admin role is only used where required (Manual)\"\n        audit: |\n          kubectl get clusterrolebindings -o=custom-columns=NAME:.metadata.name,ROLE:.roleRef.name,SUBJECT:.subjects[*].name --no-headers | while read -r role_name role_binding subject\n          do\n            if [[ \"${role_name}\" != \"cluster-admin\" && \"${role_binding}\" == \"cluster-admin\" ]]; then\n              is_compliant=\"false\"\n            else\n              is_compliant=\"true\"\n            fi;\n            echo \"**role_name: ${role_name} role_binding: ${role_binding} subject: ${subject} is_compliant: ${is_compliant}\"\n          done\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"is_compliant\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Identify all clusterrolebindings to the cluster-admin role. Check if they are used and\n          if they need this role or if they could use a role with fewer privileges.\n          Where possible, first bind users to a lower privileged role and then remove the\n          clusterrolebinding to the cluster-admin role : kubectl delete clusterrolebinding [name]\n          Condition: is_compliant is false if rolename is not cluster-admin and rolebinding is cluster-admin.\n        scored: false\n\n      - id: 5.1.2\n        text: \"Minimize access to secrets (Manual)\"\n        audit: \"echo \\\"canGetListWatchSecretsAsSystemAuthenticated: $(kubectl auth can-i get,list,watch secrets --all-namespaces --as=system:authenticated)\\\"\"\n        tests:\n          test_items:\n            - flag: \"canGetListWatchSecretsAsSystemAuthenticated\"\n              compare:\n                op: eq\n                value: no\n        remediation: |\n          Where possible, remove get, list and watch access to Secret objects in the cluster.\n        scored: false\n\n      - id: 5.1.3\n        text: \"Minimize wildcard use in Roles and ClusterRoles (Manual)\"\n        audit: |\n          # Check Roles\n          kubectl get roles --all-namespaces -o custom-columns=ROLE_NAMESPACE:.metadata.namespace,ROLE_NAME:.metadata.name --no-headers | while read -r role_namespace role_name\n          do\n            role_rules=$(kubectl get role -n \"${role_namespace}\" \"${role_name}\" -o=json | jq -c '.rules')\n            if echo \"${role_rules}\" | grep -q \"\\[\\\"\\*\\\"\\]\"; then\n              role_is_compliant=\"false\"\n            else\n              role_is_compliant=\"true\"\n            fi;\n            echo \"**role_name: ${role_name} role_namespace: ${role_namespace} role_rules: ${role_rules} role_is_compliant: ${role_is_compliant}\"\n          done\n\n          # Check ClusterRoles\n          kubectl get clusterroles -o custom-columns=CLUSTERROLE_NAME:.metadata.name --no-headers | while read -r clusterrole_name\n          do\n            clusterrole_rules=$(kubectl get clusterrole \"${clusterrole_name}\" -o=json | jq -c '.rules')\n            if echo \"${clusterrole_rules}\" | grep -q \"\\[\\\"\\*\\\"\\]\"; then\n              clusterrole_is_compliant=\"false\"\n            else\n              clusterrole_is_compliant=\"true\"\n            fi;\n          echo \"**clusterrole_name: ${clusterrole_name} clusterrole_rules: ${clusterrole_rules} clusterrole_is_compliant: ${clusterrole_is_compliant}\"\n          done\n        use_multiple_values: true\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"role_is_compliant\"\n              compare:\n                op: eq\n                value: true\n              set: true\n            - flag: \"clusterrole_is_compliant\"\n              compare:\n                op: eq\n                value: true\n              set: true\n        remediation: |\n          Where possible replace any use of wildcards [\"*\"] in roles and clusterroles with specific\n          objects or actions.\n          Condition: role_is_compliant is false if [\"*\"] is found in rules.\n          Condition: clusterrole_is_compliant is false if [\"*\"] is found in rules.\n        scored: false\n\n      - id: 5.1.4\n        text: \"Minimize access to create pods (Manual)\"\n        audit: |\n          echo \"canCreatePodsAsSystemAuthenticated: $(kubectl auth can-i create pods --all-namespaces --as=system:authenticated)\"\n        tests:\n          test_items:\n            - flag: \"canCreatePodsAsSystemAuthenticated\"\n              compare:\n                op: eq\n                value: no\n        remediation: |\n          Where possible, remove create access to pod objects in the cluster.\n        scored: false\n\n      - id: 5.1.5\n        text: \"Ensure that default service accounts are not actively used (Manual)\"\n        audit: |\n          kubectl get serviceaccount --all-namespaces --field-selector metadata.name=default -o=json | jq -r '.items[] | \" namespace: \\(.metadata.namespace), kind: \\(.kind), name: \\(.metadata.name), automountServiceAccountToken: \\(.automountServiceAccountToken | if . == null then \"notset\" else . end )\"' | xargs -L 1\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"automountServiceAccountToken\"\n              compare:\n                op: eq\n                value: false\n              set: true\n        remediation: |\n          Create explicit service accounts wherever a Kubernetes workload requires specific access\n          to the Kubernetes API server.\n          Modify the configuration of each default service account to include this value\n          `automountServiceAccountToken: false`.\n        scored: false\n\n      - id: 5.1.6\n        text: \"Ensure that Service Account Tokens are only mounted where necessary (Manual)\"\n        audit: |\n          kubectl get pods --all-namespaces -o custom-columns=POD_NAMESPACE:.metadata.namespace,POD_NAME:.metadata.name,POD_SERVICE_ACCOUNT:.spec.serviceAccount,POD_IS_AUTOMOUNTSERVICEACCOUNTTOKEN:.spec.automountServiceAccountToken --no-headers | while read -r pod_namespace pod_name pod_service_account pod_is_automountserviceaccounttoken\n          do\n            # Retrieve automountServiceAccountToken's value for ServiceAccount and Pod, set to notset if null or <none>.\n            svacc_is_automountserviceaccounttoken=$(kubectl get serviceaccount -n \"${pod_namespace}\" \"${pod_service_account}\" -o json | jq -r '.automountServiceAccountToken' | sed -e 's/<none>/notset/g' -e 's/null/notset/g')\n            pod_is_automountserviceaccounttoken=$(echo \"${pod_is_automountserviceaccounttoken}\" | sed -e 's/<none>/notset/g' -e 's/null/notset/g')\n            if [ \"${svacc_is_automountserviceaccounttoken}\" = \"false\" ] && ( [ \"${pod_is_automountserviceaccounttoken}\" = \"false\" ] || [ \"${pod_is_automountserviceaccounttoken}\" = \"notset\" ] ); then\n              is_compliant=\"true\"\n            elif [ \"${svacc_is_automountserviceaccounttoken}\" = \"true\" ] && [ \"${pod_is_automountserviceaccounttoken}\" = \"false\" ]; then\n              is_compliant=\"true\"\n            else\n              is_compliant=\"false\"\n            fi\n            echo \"**namespace: ${pod_namespace} pod_name: ${pod_name} service_account: ${pod_service_account} pod_is_automountserviceaccounttoken: ${pod_is_automountserviceaccounttoken} svacc_is_automountServiceAccountToken: ${svacc_is_automountserviceaccounttoken} is_compliant: ${is_compliant}\"\n          done\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"is_compliant\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Modify the definition of ServiceAccounts and Pods which do not need to mount service\n          account tokens to disable it, with `automountServiceAccountToken: false`.\n          If both the ServiceAccount and the Pod's .spec specify a value for automountServiceAccountToken, the Pod spec takes precedence.\n          Condition: Pod is_compliant to true when\n            - ServiceAccount is automountServiceAccountToken: false and Pod is automountServiceAccountToken: false or notset\n            - ServiceAccount is automountServiceAccountToken: true notset and Pod is automountServiceAccountToken: false\n        scored: false\n\n      - id: 5.1.7\n        text: \"Avoid use of system:masters group (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Remove the system:masters group from all users in the cluster.\n        scored: false\n\n      - id: 5.1.8\n        text: \"Limit use of the Bind, Impersonate and Escalate permissions in the Kubernetes cluster (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove the impersonate, bind and escalate rights from subjects.\n        scored: false\n\n      - id: 5.1.9\n        text: \"Minimize access to create persistent volumes (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove create access to PersistentVolume objects in the cluster.\n        scored: false\n\n      - id: 5.1.10\n        text: \"Minimize access to the proxy sub-resource of nodes (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove access to the proxy sub-resource of node objects.\n        scored: false\n\n      - id: 5.1.11\n        text: \"Minimize access to the approval sub-resource of certificatesigningrequests objects (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove access to the approval sub-resource of certificatesigningrequests objects.\n        scored: false\n\n      - id: 5.1.12\n        text: \"Minimize access to webhook configuration objects (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove access to the validatingwebhookconfigurations or mutatingwebhookconfigurations objects\n        scored: false\n\n      - id: 5.1.13\n        text: \"Minimize access to the service account token creation (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove access to the token sub-resource of serviceaccount objects.\n        scored: false\n\n  - id: 5.2\n    text: \"Pod Security Standards\"\n    checks:\n      - id: 5.2.1\n        text: \"Ensure that the cluster has at least one active policy control mechanism in place (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that either Pod Security Admission or an external policy control system is in place\n          for every namespace which contains user workloads.\n        scored: false\n\n      - id: 5.2.2\n        text: \"Minimize the admission of privileged containers (Manual)\"\n        audit: |\n          kubectl get pods --all-namespaces -o custom-columns=POD_NAME:.metadata.name,POD_NAMESPACE:.metadata.namespace --no-headers | while read -r pod_name pod_namespace\n          do\n            # Retrieve container(s) for each Pod.\n            kubectl get pod \"${pod_name}\" --namespace \"${pod_namespace}\" -o json | jq -c '.spec.containers[]' | while read -r container\n            do\n              # Retrieve container's name.\n              container_name=$(echo ${container} | jq -r '.name')\n              # Retrieve container's .securityContext.privileged value.\n              container_privileged=$(echo ${container} | jq -r '.securityContext.privileged' | sed -e 's/null/notset/g')\n              if [ \"${container_privileged}\" = \"false\" ] || [ \"${container_privileged}\" = \"notset\" ] ; then\n                echo \"***pod_name: ${pod_name} container_name: ${container_name} pod_namespace: ${pod_namespace} is_container_privileged: ${container_privileged} is_compliant: true\"\n              else\n                echo \"***pod_name: ${pod_name} container_name: ${container_name} pod_namespace: ${pod_namespace} is_container_privileged: ${container_privileged} is_compliant: false\"\n              fi\n            done\n          done\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"is_compliant\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of privileged containers.\n          Audit: the audit list all pods' containers to retrieve their .securityContext.privileged value.\n          Condition: is_compliant is false if container's `.securityContext.privileged` is set to `true`.\n          Default: by default, there are no restrictions on the creation of privileged containers.\n        scored: false\n\n      - id: 5.2.3\n        text: \"Minimize the admission of containers wishing to share the host process ID namespace (Manual)\"\n        audit: |\n          kubectl get pods --all-namespaces -o custom-columns=POD_NAME:.metadata.name,POD_NAMESPACE:.metadata.namespace --no-headers | while read -r pod_name pod_namespace\n          do\n            # Retrieve spec.hostPID for each pod.\n            pod_hostpid=$(kubectl get pod \"${pod_name}\" --namespace \"${pod_namespace}\" -o jsonpath='{.spec.hostPID}' 2>/dev/null)\n            if [ -z \"${pod_hostpid}\" ]; then\n              pod_hostpid=\"false\"\n              echo \"***pod_name: ${pod_name} pod_namespace: ${pod_namespace} is_pod_hostpid: ${pod_hostpid} is_compliant: true\"\n            else\n              echo \"***pod_name: ${pod_name} pod_namespace: ${pod_namespace} is_pod_hostpid: ${pod_hostpid} is_compliant: false\"\n            fi\n          done\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"is_compliant\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of `hostPID` containers.\n          Audit: the audit retrieves each Pod' spec.hostPID.\n          Condition: is_compliant is false if Pod's spec.hostPID is set to `true`.\n          Default: by default, there are no restrictions on the creation of hostPID containers.\n        scored: false\n\n      - id: 5.2.4\n        text: \"Minimize the admission of containers wishing to share the host IPC namespace (Manual)\"\n        audit: |\n          kubectl get pods --all-namespaces -o custom-columns=POD_NAME:.metadata.name,POD_NAMESPACE:.metadata.namespace --no-headers | while read -r pod_name pod_namespace\n          do\n            # Retrieve spec.hostIPC for each pod.\n            pod_hostipc=$(kubectl get pod \"${pod_name}\" --namespace \"${pod_namespace}\" -o jsonpath='{.spec.hostIPC}' 2>/dev/null)\n            if [ -z \"${pod_hostipc}\" ]; then\n              pod_hostipc=\"false\"\n              echo \"***pod_name: ${pod_name} pod_namespace: ${pod_namespace} is_pod_hostipc: ${pod_hostipc} is_compliant: true\"\n            else\n              echo \"***pod_name: ${pod_name} pod_namespace: ${pod_namespace} is_pod_hostipc: ${pod_hostipc} is_compliant: false\"\n            fi\n          done\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"is_compliant\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of `hostIPC` containers.\n          Audit: the audit retrieves each Pod' spec.IPC.\n          Condition: is_compliant is false if Pod's spec.hostIPC is set to `true`.\n          Default: by default, there are no restrictions on the creation of hostIPC containers.\n        scored: false\n\n      - id: 5.2.5\n        text: \"Minimize the admission of containers wishing to share the host network namespace (Manual)\"\n        audit: |\n          kubectl get pods --all-namespaces -o custom-columns=POD_NAME:.metadata.name,POD_NAMESPACE:.metadata.namespace --no-headers | while read -r pod_name pod_namespace\n          do\n            # Retrieve spec.hostNetwork for each pod.\n            pod_hostnetwork=$(kubectl get pod \"${pod_name}\" --namespace \"${pod_namespace}\" -o jsonpath='{.spec.hostNetwork}' 2>/dev/null)\n            if [ -z \"${pod_hostnetwork}\" ]; then\n              pod_hostnetwork=\"false\"\n              echo \"***pod_name: ${pod_name} pod_namespace: ${pod_namespace} is_pod_hostnetwork: ${pod_hostnetwork} is_compliant: true\"\n            else\n              echo \"***pod_name: ${pod_name} pod_namespace: ${pod_namespace} is_pod_hostnetwork: ${pod_hostnetwork} is_compliant: false\"\n            fi\n          done\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"is_compliant\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of `hostNetwork` containers.\n          Audit: the audit retrieves each Pod' spec.hostNetwork.\n          Condition: is_compliant is false if Pod's spec.hostNetwork is set to `true`.\n          Default: by default, there are no restrictions on the creation of hostNetwork containers.\n        scored: false\n\n      - id: 5.2.6\n        text: \"Minimize the admission of containers with allowPrivilegeEscalation (Manual)\"\n        audit: |\n          kubectl get pods --all-namespaces -o custom-columns=POD_NAME:.metadata.name,POD_NAMESPACE:.metadata.namespace --no-headers | while read -r pod_name pod_namespace\n          do\n            # Retrieve container(s) for each Pod.\n            kubectl get pod \"${pod_name}\" --namespace \"${pod_namespace}\" -o json | jq -c '.spec.containers[]' | while read -r container\n            do\n              # Retrieve container's name\n              container_name=$(echo ${container} | jq -r '.name')\n              # Retrieve container's .securityContext.allowPrivilegeEscalation\n              container_allowprivesc=$(echo ${container} | jq -r '.securityContext.allowPrivilegeEscalation' | sed -e 's/null/notset/g')\n              if [ \"${container_allowprivesc}\" = \"false\" ] || [ \"${container_allowprivesc}\" = \"notset\" ]; then\n                echo \"***pod_name: ${pod_name} container_name: ${container_name} pod_namespace: ${pod_namespace} is_container_allowprivesc: ${container_allowprivesc} is_compliant: true\"\n              else\n                echo \"***pod_name: ${pod_name} container_name: ${container_name} pod_namespace: ${pod_namespace} is_container_allowprivesc: ${container_allowprivesc} is_compliant: false\"\n              fi\n            done\n          done\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"is_compliant\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers with `.securityContext.allowPrivilegeEscalation` set to `true`.\n          Audit: the audit retrieves each Pod's container(s) `.securityContext.allowPrivilegeEscalation`.\n          Condition: is_compliant is false if container's `.securityContext.allowPrivilegeEscalation` is set to `true`.\n          Default: If notset, privilege escalation is allowed (default to true). However if PSP/PSA is used with a `restricted` profile,\n          privilege escalation is explicitly disallowed unless configured otherwise.\n        scored: false\n\n      - id: 5.2.7\n        text: \"Minimize the admission of root containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Create a policy for each namespace in the cluster, ensuring that either `MustRunAsNonRoot`\n          or `MustRunAs` with the range of UIDs not including 0, is set.\n        scored: false\n\n      - id: 5.2.8\n        text: \"Minimize the admission of containers with the NET_RAW capability (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers with the `NET_RAW` capability.\n        scored: false\n\n      - id: 5.2.9\n        text: \"Minimize the admission of containers with added capabilities (Manual)\"\n        audit: |\n          kubectl get pods --all-namespaces -o custom-columns=POD_NAME:.metadata.name,POD_NAMESPACE:.metadata.namespace --no-headers | while read -r pod_name pod_namespace\n          do\n            # Retrieve container(s) for each Pod.\n            kubectl get pod \"${pod_name}\" --namespace \"${pod_namespace}\" -o json | jq -c '.spec.containers[]' | while read -r container\n            do\n              # Retrieve container's name\n              container_name=$(echo ${container} | jq -r '.name')\n              # Retrieve container's added capabilities\n              container_caps_add=$(echo ${container} | jq -r '.securityContext.capabilities.add' | sed -e 's/null/notset/g')\n              # Set is_compliant to true by default.\n              is_compliant=true\n              caps_list=\"\"\n              if [ \"${container_caps_add}\" != \"notset\" ]; then\n                # Loop through all caps and append caps_list, then set is_compliant to false.\n                for cap in $(echo \"${container_caps_add}\" | jq -r '.[]'); do\n                caps_list+=\"${cap},\"\n                is_compliant=false\n                done\n                # Remove trailing comma for the last list member.\n                caps_list=${caps_list%,}\n              fi\n              if [ \"${is_compliant}\" = true ]; then\n                echo \"***pod_name: ${pod_name} container_name: ${container_name} pod_namespace: ${pod_namespace} container_caps_add: ${container_caps_add} is_compliant: true\"\n              else\n                echo \"***pod_name: ${pod_name} container_name: ${container_name} pod_namespace: ${pod_namespace} container_caps_add: ${caps_list} is_compliant: false\"\n              fi\n            done\n          done\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"is_compliant\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Ensure that `allowedCapabilities` is not present in policies for the cluster unless\n          it is set to an empty array.\n          Audit: the audit retrieves each Pod's container(s) added capabilities.\n          Condition: is_compliant is false if added capabilities are added for a given container.\n          Default: Containers run with a default set of capabilities as assigned by the Container Runtime.\n        scored: false\n\n      - id: 5.2.10\n        text: \"Minimize the admission of containers with capabilities assigned (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Review the use of capabilites in applications running on your cluster. Where a namespace\n          contains applications which do not require any Linux capabities to operate consider adding\n          a PSP which forbids the admission of containers which do not drop all capabilities.\n        scored: false\n\n      - id: 5.2.11\n        text: \"Minimize the admission of Windows HostProcess containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers that have `.securityContext.windowsOptions.hostProcess` set to `true`.\n        scored: false\n\n      - id: 5.2.12\n        text: \"Minimize the admission of HostPath volumes (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers with `hostPath` volumes.\n        scored: false\n\n      - id: 5.2.13\n        text: \"Minimize the admission of containers which use HostPorts (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers which use `hostPort` sections.\n        scored: false\n\n  - id: 5.3\n    text: \"Network Policies and CNI\"\n    checks:\n      - id: 5.3.1\n        text: \"Ensure that the CNI in use supports NetworkPolicies (Manual)\"\n        type: \"manual\"\n        remediation: |\n          If the CNI plugin in use does not support network policies, consideration should be given to\n          making use of a different plugin, or finding an alternate mechanism for restricting traffic\n          in the Kubernetes cluster.\n        scored: false\n\n      - id: 5.3.2\n        text: \"Ensure that all Namespaces have NetworkPolicies defined (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the documentation and create NetworkPolicy objects as you need them.\n        scored: false\n\n  - id: 5.4\n    text: \"Secrets Management\"\n    checks:\n      - id: 5.4.1\n        text: \"Prefer using Secrets as files over Secrets as environment variables (Manual)\"\n        type: \"manual\"\n        remediation: |\n          If possible, rewrite application code to read Secrets from mounted secret files, rather than\n          from environment variables.\n        scored: false\n\n      - id: 5.4.2\n        text: \"Consider external secret storage (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Refer to the Secrets management options offered by your cloud provider or a third-party\n          secrets management solution.\n        scored: false\n\n  - id: 5.5\n    text: \"Extensible Admission Control\"\n    checks:\n      - id: 5.5.1\n        text: \"Configure Image Provenance using ImagePolicyWebhook admission controller (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and setup image provenance.\n        scored: false\n\n  - id: 5.6\n    text: \"General Policies\"\n    checks:\n      - id: 5.6.1\n        text: \"Create administrative boundaries between resources using namespaces (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the documentation and create namespaces for objects in your deployment as you need\n          them.\n        scored: false\n\n      - id: 5.6.2\n        text: \"Ensure that the seccomp profile is set to docker/default in your Pod definitions (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Use `securityContext` to enable the docker/default seccomp profile in your pod definitions.\n          An example is as below:\n            securityContext:\n              seccompProfile:\n                type: RuntimeDefault\n        scored: false\n\n      - id: 5.6.3\n        text: \"Apply SecurityContext to your Pods and Containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and apply SecurityContexts to your Pods. For a\n          suggested list of SecurityContexts, you may refer to the CIS Security Benchmark for Docker\n          Containers.\n        scored: false\n\n      - id: 5.6.4\n        text: \"The default namespace should not be used (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that namespaces are created to allow for appropriate segregation of Kubernetes\n          resources and that all new resources are created in a specific namespace.\n        scored: false\n"
  },
  {
    "path": "cfg/cis-1.12/config.yaml",
    "content": "---\n## Version-specific settings that override the values in cfg/config.yaml\n"
  },
  {
    "path": "cfg/cis-1.12/controlplane.yaml",
    "content": "---\ncontrols:\nversion: \"cis-1.12\"\nid: 3\ntext: \"Control Plane Configuration\"\ntype: \"controlplane\"\ngroups:\n  - id: 3.1\n    text: \"Authentication and Authorization\"\n    checks:\n      - id: 3.1.1\n        text: \"Client certificate authentication should not be used for users (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Alternative mechanisms provided by Kubernetes such as the use of OIDC should be\n          implemented in place of client certificates.\n        scored: false\n\n      - id: 3.1.2\n        text: \"Service account token authentication should not be used for users (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Alternative mechanisms provided by Kubernetes such as the use of OIDC should be implemented\n          in place of service account tokens.\n        scored: false\n\n      - id: 3.1.3\n        text: \"Bootstrap token authentication should not be used for users (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Alternative mechanisms provided by Kubernetes such as the use of OIDC should be implemented\n          in place of bootstrap tokens.\n        scored: false\n\n  - id: 3.2\n    text: \"Logging\"\n    checks:\n      - id: 3.2.1\n        text: \"Ensure that a minimal audit policy is created (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-policy-file\"\n              set: true\n        remediation: |\n          Create an audit policy file for your cluster.\n        scored: false\n\n      - id: 3.2.2\n        text: \"Ensure that the audit policy covers key security concerns (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Review the audit policy provided for the cluster and ensure that it covers\n          at least the following areas,\n          - Access to Secrets managed by the cluster. Care should be taken to only\n            log Metadata for requests to Secrets, ConfigMaps, and TokenReviews, in\n            order to avoid risk of logging sensitive data.\n          - Modification of Pod and Deployment objects.\n          - Use of `pods/exec`, `pods/portforward`, `pods/proxy` and `services/proxy`.\n          For most requests, minimally logging at the Metadata level is recommended\n          (the most basic level of logging).\n        scored: false\n"
  },
  {
    "path": "cfg/cis-1.12/etcd.yaml",
    "content": "---\ncontrols:\nversion: \"cis-1.12\"\nid: 2\ntext: \"Etcd Node Configuration\"\ntype: \"etcd\"\ngroups:\n  - id: 2\n    text: \"Etcd Node Configuration\"\n    checks:\n      - id: 2.1\n        text: \"Ensure that the --cert-file and --key-file arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--cert-file\"\n              env: \"ETCD_CERT_FILE\"\n            - flag: \"--key-file\"\n              env: \"ETCD_KEY_FILE\"\n        remediation: |\n          Follow the etcd service documentation and configure TLS encryption.\n          Then, edit the etcd pod specification file /etc/kubernetes/manifests/etcd.yaml\n          on the master node and set the below parameters.\n          --cert-file=</path/to/ca-file>\n          --key-file=</path/to/key-file>\n        scored: true\n\n      - id: 2.2\n        text: \"Ensure that the --client-cert-auth argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--client-cert-auth\"\n              env: \"ETCD_CLIENT_CERT_AUTH\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and set the below parameter.\n          --client-cert-auth=\"true\"\n        scored: true\n\n      - id: 2.3\n        text: \"Ensure that the --auto-tls argument is not set to true (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--auto-tls\"\n              env: \"ETCD_AUTO_TLS\"\n              set: false\n            - flag: \"--auto-tls\"\n              env: \"ETCD_AUTO_TLS\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and either remove the --auto-tls parameter or set it to false.\n            --auto-tls=false\n        scored: true\n\n      - id: 2.4\n        text: \"Ensure that the --peer-cert-file and --peer-key-file arguments are\n        set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--peer-cert-file\"\n              env: \"ETCD_PEER_CERT_FILE\"\n            - flag: \"--peer-key-file\"\n              env: \"ETCD_PEER_KEY_FILE\"\n        remediation: |\n          Follow the etcd service documentation and configure peer TLS encryption as appropriate\n          for your etcd cluster.\n          Then, edit the etcd pod specification file $etcdconf on the\n          master node and set the below parameters.\n          --peer-client-file=</path/to/peer-cert-file>\n          --peer-key-file=</path/to/peer-key-file>\n        scored: true\n\n      - id: 2.5\n        text: \"Ensure that the --peer-client-cert-auth argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--peer-client-cert-auth\"\n              env: \"ETCD_PEER_CLIENT_CERT_AUTH\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and set the below parameter.\n          --peer-client-cert-auth=true\n        scored: true\n\n      - id: 2.6\n        text: \"Ensure that the --peer-auto-tls argument is not set to true (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--peer-auto-tls\"\n              env: \"ETCD_PEER_AUTO_TLS\"\n              set: false\n            - flag: \"--peer-auto-tls\"\n              env: \"ETCD_PEER_AUTO_TLS\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and either remove the --peer-auto-tls parameter or set it to false.\n          --peer-auto-tls=false\n        scored: true\n\n      - id: 2.7\n        text: \"Ensure that a unique Certificate Authority is used for etcd (Manual)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--trusted-ca-file\"\n              env: \"ETCD_TRUSTED_CA_FILE\"\n        remediation: |\n          [Manual test]\n          Follow the etcd documentation and create a dedicated certificate authority setup for the\n          etcd service.\n          Then, edit the etcd pod specification file $etcdconf on the\n          master node and set the below parameter.\n          --trusted-ca-file=</path/to/ca-file>\n        scored: false\n"
  },
  {
    "path": "cfg/cis-1.12/master.yaml",
    "content": "---\ncontrols:\nversion: \"cis-1.12\"\nid: 1\ntext: \"Control Plane Security Configuration\"\ntype: \"master\"\ngroups:\n  - id: 1.1\n    text: \"Control Plane Node Configuration Files\"\n    checks:\n      - id: 1.1.1\n        text: \"Ensure that the API server pod specification file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $apiserverconf; then stat -c permissions=%a $apiserverconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the\n          control plane node.\n          For example, chmod 600 $apiserverconf\n        scored: true\n\n      - id: 1.1.2\n        text: \"Ensure that the API server pod specification file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $apiserverconf; then stat -c %U:%G $apiserverconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chown root:root $apiserverconf\n        scored: true\n\n      - id: 1.1.3\n        text: \"Ensure that the controller manager pod specification file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerconf; then stat -c permissions=%a $controllermanagerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chmod 600 $controllermanagerconf\n        scored: true\n\n      - id: 1.1.4\n        text: \"Ensure that the controller manager pod specification file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerconf; then stat -c %U:%G $controllermanagerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chown root:root $controllermanagerconf\n        scored: true\n\n      - id: 1.1.5\n        text: \"Ensure that the scheduler pod specification file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerconf; then stat -c permissions=%a $schedulerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chmod 600 $schedulerconf\n        scored: true\n\n      - id: 1.1.6\n        text: \"Ensure that the scheduler pod specification file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerconf; then stat -c %U:%G $schedulerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chown root:root $schedulerconf\n        scored: true\n\n      - id: 1.1.7\n        text: \"Ensure that the etcd pod specification file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $etcdconf; then find $etcdconf -name '*etcd*' | xargs stat -c permissions=%a; fi'\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod 600 $etcdconf\n        scored: true\n\n      - id: 1.1.8\n        text: \"Ensure that the etcd pod specification file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $etcdconf; then find $etcdconf -name '*etcd*' | xargs stat -c %U:%G; fi'\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root $etcdconf\n        scored: true\n\n      - id: 1.1.9\n        text: \"Ensure that the Container Network Interface file permissions are set to 600 or more restrictive (Manual)\"\n        audit: |\n          ps -ef | grep $kubeletbin | grep -- --cni-conf-dir | sed 's%.*cni-conf-dir[= ]\\([^ ]*\\).*%\\1%' | xargs -I{} find {} -mindepth 1 | xargs --no-run-if-empty stat -c permissions=%a\n          find /var/lib/cni/networks -type f 2> /dev/null | xargs --no-run-if-empty stat -c permissions=%a\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chmod 600 <path/to/cni/files>\n        scored: false\n\n      - id: 1.1.10\n        text: \"Ensure that the Container Network Interface file ownership is set to root:root (Manual)\"\n        audit: |\n          ps -ef | grep $kubeletbin | grep -- --cni-conf-dir | sed 's%.*cni-conf-dir[= ]\\([^ ]*\\).*%\\1%' | xargs -I{} find {} -mindepth 1 | xargs --no-run-if-empty stat -c %U:%G\n          find /var/lib/cni/networks -type f 2> /dev/null | xargs --no-run-if-empty stat -c %U:%G\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root <path/to/cni/files>\n        scored: false\n\n      - id: 1.1.11\n        text: \"Ensure that the etcd data directory permissions are set to 700 or more restrictive (Automated)\"\n        audit: |\n          DATA_DIR=''\n          for d in $(ps -ef | grep $etcdbin | grep -- --data-dir | sed 's%.*data-dir[= ]\\([^ ]*\\).*%\\1%'); do\n            if test -d \"$d\"; then DATA_DIR=\"$d\"; fi\n          done\n          if ! test -d \"$DATA_DIR\"; then DATA_DIR=$etcddatadir; fi\n          stat -c permissions=%a \"$DATA_DIR\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"700\"\n        remediation: |\n          On the etcd server node, get the etcd data directory, passed as an argument --data-dir,\n          from the command 'ps -ef | grep etcd'.\n          Run the below command (based on the etcd data directory found above). For example,\n          chmod 700 /var/lib/etcd\n        scored: true\n\n      - id: 1.1.12\n        text: \"Ensure that the etcd data directory ownership is set to etcd:etcd (Automated)\"\n        audit: |\n          DATA_DIR=''\n          for d in $(ps -ef | grep $etcdbin | grep -- --data-dir | sed 's%.*data-dir[= ]\\([^ ]*\\).*%\\1%'); do\n            if test -d \"$d\"; then DATA_DIR=\"$d\"; fi\n          done\n          if ! test -d \"$DATA_DIR\"; then DATA_DIR=$etcddatadir; fi\n          stat -c %U:%G \"$DATA_DIR\"\n        tests:\n          test_items:\n            - flag: \"etcd:etcd\"\n        remediation: |\n          On the etcd server node, get the etcd data directory, passed as an argument --data-dir,\n          from the command 'ps -ef | grep etcd'.\n          Run the below command (based on the etcd data directory found above).\n          For example, chown etcd:etcd /var/lib/etcd\n        scored: true\n\n      - id: 1.1.13\n        text: \"Ensure that the default administrative credential file permissions are set to 600 (Automated)\"\n        audit: |\n         for adminconf in /etc/kubernetes/admin.conf /etc/kubernetes/super-admin.conf; do if test -e $adminconf; then stat -c \"permissions=%a %n\" $adminconf; fi; done\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chmod 600 /etc/kubernetes/admin.conf\n          On Kubernetes 1.29+ the super-admin.conf file should also be modified, if present.\n          For example, chmod 600 /etc/kubernetes/super-admin.conf\n        scored: true\n\n      - id: 1.1.14\n        text: \"Ensure that the default administrative credential file ownership is set to root:root (Automated)\"\n        audit: |\n         for adminconf in /etc/kubernetes/admin.conf /etc/kubernetes/super-admin.conf; do if test -e $adminconf; then stat -c \"ownership=%U:%G %n\" $adminconf; fi; done\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"ownership\"\n              compare:\n                op: eq\n                value: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chown root:root /etc/kubernetes/admin.conf\n          On Kubernetes 1.29+ the super-admin.conf file should also be modified, if present.\n          For example, chown root:root /etc/kubernetes/super-admin.conf\n        scored: true\n\n      - id: 1.1.15\n        text: \"Ensure that the scheduler.conf file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerkubeconfig; then stat -c permissions=%a $schedulerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod 600 $schedulerkubeconfig\n        scored: true\n\n      - id: 1.1.16\n        text: \"Ensure that the scheduler.conf file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerkubeconfig; then stat -c %U:%G $schedulerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root $schedulerkubeconfig\n        scored: true\n\n      - id: 1.1.17\n        text: \"Ensure that the controller-manager.conf file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerkubeconfig; then stat -c permissions=%a $controllermanagerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod 600 $controllermanagerkubeconfig\n        scored: true\n\n      - id: 1.1.18\n        text: \"Ensure that the controller-manager.conf file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerkubeconfig; then stat -c %U:%G $controllermanagerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root $controllermanagerkubeconfig\n        scored: true\n\n      - id: 1.1.19\n        text: \"Ensure that the Kubernetes PKI directory and file ownership is set to root:root (Automated)\"\n        audit: \"find /etc/kubernetes/pki/ | xargs stat -c %U:%G\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown -R root:root /etc/kubernetes/pki/\n        scored: true\n\n      - id: 1.1.20\n        text: \"Ensure that the Kubernetes PKI certificate file permissions are set to 644 or more restrictive (Manual)\"\n        audit: \"find /etc/kubernetes/pki/ -name '*.crt' | xargs stat -c permissions=%a\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod -R 644 /etc/kubernetes/pki/*.crt\n        scored: false\n\n      - id: 1.1.21\n        text: \"Ensure that the Kubernetes PKI key file permissions are set to 600 (Manual)\"\n        audit: \"find /etc/kubernetes/pki/ -name '*.key' | xargs stat -c permissions=%a\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod -R 600 /etc/kubernetes/pki/*.key\n        scored: false\n\n  - id: 1.2\n    text: \"API Server\"\n    checks:\n      - id: 1.2.1\n        text: \"Ensure that the --anonymous-auth argument is set to false (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--anonymous-auth\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the below parameter.\n          --anonymous-auth=false\n        scored: false\n\n      - id: 1.2.2\n        text: \"Ensure that the --token-auth-file parameter is not set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--token-auth-file\"\n              set: false\n        remediation: |\n          Follow the documentation and configure alternate mechanisms for authentication. Then,\n          edit the API server pod specification file $apiserverconf\n          on the control plane node and remove the --token-auth-file=<filename> parameter.\n        scored: true\n\n      - id: 1.2.3\n        text: \"Ensure that the --DenyServiceExternalIPs is set (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"DenyServiceExternalIPs\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and add the `DenyServiceExternalIPs` plugin\n          to the enabled admission plugins, as such --enable-admission-plugin=DenyServiceExternalIPs.\n        scored: false\n\n      - id: 1.2.4\n        text: \"Ensure that the --kubelet-client-certificate and --kubelet-client-key arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--kubelet-client-certificate\"\n            - flag: \"--kubelet-client-key\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection between the\n          apiserver and kubelets. Then, edit API server pod specification file\n          $apiserverconf on the control plane node and set the\n          kubelet client certificate and key parameters as below.\n          --kubelet-client-certificate=<path/to/client-certificate-file>\n          --kubelet-client-key=<path/to/client-key-file>\n        scored: true\n\n      - id: 1.2.5\n        text: \"Ensure that the --kubelet-certificate-authority argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--kubelet-certificate-authority\"\n        remediation: |\n          Follow the Kubernetes documentation and setup the TLS connection between\n          the apiserver and kubelets. Then, edit the API server pod specification file\n          $apiserverconf on the control plane node and set the\n          --kubelet-certificate-authority parameter to the path to the cert file for the certificate authority.\n          --kubelet-certificate-authority=<ca-string>\n        scored: true\n\n      - id: 1.2.6\n        text: \"Ensure that the --authorization-mode argument is not set to AlwaysAllow (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: nothave\n                value: \"AlwaysAllow\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --authorization-mode parameter to values other than AlwaysAllow.\n          One such example could be as below.\n          --authorization-mode=RBAC\n        scored: true\n\n      - id: 1.2.7\n        text: \"Ensure that the --authorization-mode argument includes Node (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: has\n                value: \"Node\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --authorization-mode parameter to a value that includes Node.\n          --authorization-mode=Node,RBAC\n        scored: true\n\n      - id: 1.2.8\n        text: \"Ensure that the --authorization-mode argument includes RBAC (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: has\n                value: \"RBAC\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --authorization-mode parameter to a value that includes RBAC,\n          for example `--authorization-mode=Node,RBAC`.\n        scored: true\n\n      - id: 1.2.9\n        text: \"Ensure that the admission control plugin EventRateLimit is set (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"EventRateLimit\"\n        remediation: |\n          Follow the Kubernetes documentation and set the desired limits in a configuration file.\n          Then, edit the API server pod specification file $apiserverconf\n          and set the below parameters.\n          --enable-admission-plugins=...,EventRateLimit,...\n          --admission-control-config-file=<path/to/configuration/file>\n        scored: false\n\n      - id: 1.2.10\n        text: \"Ensure that the admission control plugin AlwaysAdmit is not set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: nothave\n                value: AlwaysAdmit\n            - flag: \"--enable-admission-plugins\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and either remove the --enable-admission-plugins parameter, or set it to a\n          value that does not include AlwaysAdmit.\n        scored: true\n\n      - id: 1.2.11\n        text: \"Ensure that the admission control plugin AlwaysPullImages is set (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"AlwaysPullImages\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --enable-admission-plugins parameter to include\n          AlwaysPullImages.\n          --enable-admission-plugins=...,AlwaysPullImages,...\n        scored: false\n\n      - id: 1.2.12\n        text: \"Ensure that the admission control plugin ServiceAccount is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--disable-admission-plugins\"\n              compare:\n                op: nothave\n                value: \"ServiceAccount\"\n            - flag: \"--disable-admission-plugins\"\n              set: false\n        remediation: |\n          Follow the documentation and create ServiceAccount objects as per your environment.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and ensure that the --disable-admission-plugins parameter is set to a\n          value that does not include ServiceAccount.\n        scored: true\n\n      - id: 1.2.13\n        text: \"Ensure that the admission control plugin NamespaceLifecycle is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--disable-admission-plugins\"\n              compare:\n                op: nothave\n                value: \"NamespaceLifecycle\"\n            - flag: \"--disable-admission-plugins\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --disable-admission-plugins parameter to\n          ensure it does not include NamespaceLifecycle.\n        scored: true\n\n      - id: 1.2.14\n        text: \"Ensure that the admission control plugin NodeRestriction is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"NodeRestriction\"\n        remediation: |\n          Follow the Kubernetes documentation and configure NodeRestriction plug-in on kubelets.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --enable-admission-plugins parameter to a\n          value that includes NodeRestriction.\n          --enable-admission-plugins=...,NodeRestriction,...\n        scored: true\n\n      - id: 1.2.15\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the below parameter.\n          --profiling=false\n        scored: true\n\n      - id: 1.2.16\n        text: \"Ensure that the --audit-log-path argument is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-path\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --audit-log-path parameter to a suitable path and\n          file where you would like audit logs to be written, for example,\n          --audit-log-path=/var/log/apiserver/audit.log\n        scored: true\n\n      - id: 1.2.17\n        text: \"Ensure that the --audit-log-maxage argument is set to 30 or as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxage\"\n              compare:\n                op: gte\n                value: 30\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --audit-log-maxage parameter to 30\n          or as an appropriate number of days, for example,\n          --audit-log-maxage=30\n        scored: true\n\n      - id: 1.2.18\n        text: \"Ensure that the --audit-log-maxbackup argument is set to 10 or as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxbackup\"\n              compare:\n                op: gte\n                value: 10\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --audit-log-maxbackup parameter to 10 or to an appropriate\n          value. For example,\n          --audit-log-maxbackup=10\n        scored: true\n\n      - id: 1.2.19\n        text: \"Ensure that the --audit-log-maxsize argument is set to 100 or as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxsize\"\n              compare:\n                op: gte\n                value: 100\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --audit-log-maxsize parameter to an appropriate size in MB.\n          For example, to set it as 100 MB, --audit-log-maxsize=100\n        scored: true\n\n      - id: 1.2.20\n        text: \"Ensure that the --request-timeout argument is set as appropriate (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        type: manual\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          and set the below parameter as appropriate and if needed.\n          For example, --request-timeout=300s\n        scored: false\n\n      - id: 1.2.21\n        text: \"Ensure that the --service-account-lookup argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--service-account-lookup\"\n              set: false\n            - flag: \"--service-account-lookup\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the below parameter.\n          --service-account-lookup=true\n          Alternatively, you can delete the --service-account-lookup parameter from this file so\n          that the default takes effect.\n        scored: true\n\n      - id: 1.2.22\n        text: \"Ensure that the --service-account-key-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--service-account-key-file\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --service-account-key-file parameter\n          to the public key file for service accounts. For example,\n          --service-account-key-file=<filename>\n        scored: true\n\n      - id: 1.2.23\n        text: \"Ensure that the --etcd-certfile and --etcd-keyfile arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--etcd-certfile\"\n            - flag: \"--etcd-keyfile\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection between the apiserver and etcd.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the etcd certificate and key file parameters.\n          --etcd-certfile=<path/to/client-certificate-file>\n          --etcd-keyfile=<path/to/client-key-file>\n        scored: true\n\n      - id: 1.2.24\n        text: \"Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--tls-cert-file\"\n            - flag: \"--tls-private-key-file\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection on the apiserver.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the TLS certificate and private key file parameters.\n          --tls-cert-file=<path/to/tls-certificate-file>\n          --tls-private-key-file=<path/to/tls-key-file>\n        scored: true\n\n      - id: 1.2.25\n        text: \"Ensure that the --client-ca-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--client-ca-file\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection on the apiserver.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the client certificate authority file.\n          --client-ca-file=<path/to/client-ca-file>\n        scored: true\n\n      - id: 1.2.26\n        text: \"Ensure that the --etcd-cafile argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--etcd-cafile\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection between the apiserver and etcd.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the etcd certificate authority file parameter.\n          --etcd-cafile=<path/to/ca-file>\n        scored: true\n\n      - id: 1.2.27\n        text: \"Ensure that the --encryption-provider-config argument is set as appropriate (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--encryption-provider-config\"\n        remediation: |\n          Follow the Kubernetes documentation and configure a EncryptionConfig file.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --encryption-provider-config parameter to the path of that file.\n          For example, --encryption-provider-config=</path/to/EncryptionConfig/File>\n        scored: false\n\n      - id: 1.2.28\n        text: \"Ensure that encryption providers are appropriately configured (Manual)\"\n        audit: |\n          ENCRYPTION_PROVIDER_CONFIG=$(ps -ef | grep $apiserverbin | grep -- --encryption-provider-config | sed 's%.*encryption-provider-config[= ]\\([^ ]*\\).*%\\1%')\n          if test -e $ENCRYPTION_PROVIDER_CONFIG; then grep -A1 'providers:' $ENCRYPTION_PROVIDER_CONFIG | tail -n1 | grep -o \"[A-Za-z]*\" | sed 's/^/provider=/'; fi\n        tests:\n          test_items:\n            - flag: \"provider\"\n              compare:\n                op: valid_elements\n                value: \"aescbc,kms,secretbox\"\n        remediation: |\n          Follow the Kubernetes documentation and configure a EncryptionConfig file.\n          In this file, choose aescbc, kms or secretbox as the encryption provider.\n        scored: false\n\n      - id: 1.2.29\n        text: \"Ensure that the API Server only makes use of Strong Cryptographic Ciphers (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--tls-cipher-suites\"\n              compare:\n                op: valid_elements\n                value: \"TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,TLS_CHACHA20_POLY1305_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256\"\n        remediation: |\n          Edit the API server pod specification file /etc/kubernetes/manifests/kube-apiserver.yaml\n          on the control plane node and set the below parameter.\n          --tls-cipher-suites=TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,\n          TLS_CHACHA20_POLY1305_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,\n          TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,\n          TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256\n        scored: false\n\n      - id: 1.2.30\n        text: \"Ensure that the --service-account-extend-token-expiration parameter is set to false (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--service-account-extend-token-expiration\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the API server pod specification file /etc/kubernetes/manifests/kube-apiserver.yaml on the Control Plane node and set the --service-account-extend-token-expiration parameter to false.\n          `--service-account-extend-token-expiration=false`\n          By default, this parameter is set to true.\n        scored: true\n\n  - id: 1.3\n    text: \"Controller Manager\"\n    checks:\n      - id: 1.3.1\n        text: \"Ensure that the --terminated-pod-gc-threshold argument is set as appropriate (Manual)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--terminated-pod-gc-threshold\"\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the --terminated-pod-gc-threshold to an appropriate threshold,\n          for example, --terminated-pod-gc-threshold=10\n        scored: false\n\n      - id: 1.3.2\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the below parameter.\n          --profiling=false\n        scored: true\n\n      - id: 1.3.3\n        text: \"Ensure that the --use-service-account-credentials argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--use-service-account-credentials\"\n              compare:\n                op: noteq\n                value: false\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node to set the below parameter.\n          --use-service-account-credentials=true\n        scored: true\n\n      - id: 1.3.4\n        text: \"Ensure that the --service-account-private-key-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--service-account-private-key-file\"\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the --service-account-private-key-file parameter\n          to the private key file for service accounts.\n          --service-account-private-key-file=<filename>\n        scored: true\n\n      - id: 1.3.5\n        text: \"Ensure that the --root-ca-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--root-ca-file\"\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the --root-ca-file parameter to the certificate bundle file`.\n          --root-ca-file=<path/to/file>\n        scored: true\n\n      - id: 1.3.6\n        text: \"Ensure that the RotateKubeletServerCertificate argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--feature-gates\"\n              compare:\n                op: nothave\n                value: \"RotateKubeletServerCertificate=false\"\n              set: true\n            - flag: \"--feature-gates\"\n              set: false\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the --feature-gates parameter to include RotateKubeletServerCertificate=true.\n          --feature-gates=RotateKubeletServerCertificate=true\n        scored: true\n\n      - id: 1.3.7\n        text: \"Ensure that the --bind-address argument is set to 127.0.0.1 (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--bind-address\"\n              compare:\n                op: eq\n                value: \"127.0.0.1\"\n            - flag: \"--bind-address\"\n              set: false\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and ensure the correct value for the --bind-address parameter\n        scored: true\n\n  - id: 1.4\n    text: \"Scheduler\"\n    checks:\n      - id: 1.4.1\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: \"/bin/ps -ef | grep $schedulerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the Scheduler pod specification file $schedulerconf file\n          on the control plane node and set the below parameter.\n          --profiling=false\n        scored: true\n\n      - id: 1.4.2\n        text: \"Ensure that the --bind-address argument is set to 127.0.0.1 (Automated)\"\n        audit: \"/bin/ps -ef | grep $schedulerbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--bind-address\"\n              compare:\n                op: eq\n                value: \"127.0.0.1\"\n            - flag: \"--bind-address\"\n              set: false\n        remediation: |\n          Edit the Scheduler pod specification file $schedulerconf\n          on the control plane node and ensure the correct value for the --bind-address parameter\n        scored: true\n"
  },
  {
    "path": "cfg/cis-1.12/node.yaml",
    "content": "---\ncontrols:\nversion: \"cis-1.12\"\nid: 4\ntext: \"Worker Node Security Configuration\"\ntype: \"node\"\ngroups:\n  - id: 4.1\n    text: \"Worker Node Configuration Files\"\n    checks:\n      - id: 4.1.1\n        text: \"Ensure that the kubelet service file permissions are set to 600 or more restrictive (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletsvc; then stat -c permissions=%a $kubeletsvc; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example, chmod 600 $kubeletsvc\n        scored: true\n\n      - id: 4.1.2\n        text: \"Ensure that the kubelet service file ownership is set to root:root (Automated)\"\n        audit: '/bin/sh -c \"if test -e $kubeletsvc; then stat -c %U:%G $kubeletsvc; else echo \\\"File not found\\\"; fi\"'\n        tests:\n          bin_op: or\n          test_items:\n            - flag: root:root\n            - flag: \"File not found\"\n        remediation: |\n            Run the below command (based on the file location on your system) on the each worker node.\n            For example,\n            chown root:root $kubeletsvc\n        scored: true\n\n      - id: 4.1.3\n        text: \"If proxy kubeconfig file exists ensure permissions are set to 600 or more restrictive (Manual)\"\n        audit: '/bin/sh -c ''if test -e $proxykubeconfig; then stat -c permissions=%a $proxykubeconfig; fi'' '\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"permissions\"\n              set: true\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chmod 600 $proxykubeconfig\n        scored: false\n\n      - id: 4.1.4\n        text: \"If proxy kubeconfig file exists ensure ownership is set to root:root (Manual)\"\n        audit: '/bin/sh -c ''if test -e $proxykubeconfig; then stat -c %U:%G $proxykubeconfig; fi'' '\n        tests:\n          bin_op: or\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example, chown root:root $proxykubeconfig\n        scored: false\n\n      - id: 4.1.5\n        text: \"Ensure that the --kubeconfig kubelet.conf file permissions are set to 600 or more restrictive (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletkubeconfig; then stat -c permissions=%a $kubeletkubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chmod 600 $kubeletkubeconfig\n        scored: true\n\n      - id: 4.1.6\n        text: \"Ensure that the --kubeconfig kubelet.conf file ownership is set to root:root (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletkubeconfig; then stat -c %U:%G $kubeletkubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chown root:root $kubeletkubeconfig\n        scored: true\n\n      - id: 4.1.7\n        text: \"Ensure that the certificate authorities file permissions are set to 644 or more restrictive (Manual)\"\n        audit: |\n          CAFILE=$(ps -ef | grep kubelet | grep -v apiserver | grep -- --client-ca-file= | awk -F '--client-ca-file=' '{print $2}' | awk '{print $1}' | uniq)\n          if test -z $CAFILE; then CAFILE=$kubeletcafile; fi\n          if test -e $CAFILE; then stat -c permissions=%a $CAFILE; fi\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the following command to modify the file permissions of the\n          --client-ca-file chmod 644 <filename>\n        scored: false\n\n      - id: 4.1.8\n        text: \"Ensure that the client certificate authorities file ownership is set to root:root (Manual)\"\n        audit: |\n          CAFILE=$(ps -ef | grep kubelet | grep -v apiserver | grep -- --client-ca-file= | awk -F '--client-ca-file=' '{print $2}' | awk '{print $1}' | uniq)\n          if test -z $CAFILE; then CAFILE=$kubeletcafile; fi\n          if test -e $CAFILE; then stat -c %U:%G $CAFILE; fi\n        tests:\n          test_items:\n            - flag: root:root\n              compare:\n                op: eq\n                value: root:root\n        remediation: |\n          Run the following command to modify the ownership of the --client-ca-file.\n          chown root:root <filename>\n        scored: false\n\n      - id: 4.1.9\n        text: \"If the kubelet config.yaml configuration file is being used validate permissions set to 600 or more restrictive (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletconf; then stat -c permissions=%a $kubeletconf; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the following command (using the config file location identified in the Audit step)\n          chmod 600 $kubeletconf\n        scored: true\n\n      - id: 4.1.10\n        text: \"If the kubelet config.yaml configuration file is being used validate file ownership is set to root:root (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletconf; then stat -c %U:%G $kubeletconf; fi'' '\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the following command (using the config file location identified in the Audit step)\n          chown root:root $kubeletconf\n        scored: true\n\n  - id: 4.2\n    text: \"Kubelet\"\n    checks:\n      - id: 4.2.1\n        text: \"Ensure that the --anonymous-auth argument is set to false (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: \"--anonymous-auth\"\n              path: '{.authentication.anonymous.enabled}'\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          If using a Kubelet config file, edit the file to set `authentication: anonymous: enabled` to\n          `false`.\n          If using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          `--anonymous-auth=false`\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.2\n        text: \"Ensure that the --authorization-mode argument is not set to AlwaysAllow (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --authorization-mode\n              path: '{.authorization.mode}'\n              compare:\n                op: nothave\n                value: AlwaysAllow\n        remediation: |\n          If using a Kubelet config file, edit the file to set `authorization.mode` to Webhook. If\n          using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_AUTHZ_ARGS variable.\n          --authorization-mode=Webhook\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.3\n        text: \"Ensure that the --client-ca-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --client-ca-file\n              path: '{.authentication.x509.clientCAFile}'\n        remediation: |\n          If using a Kubelet config file, edit the file to set `authentication.x509.clientCAFile` to\n          the location of the client CA file.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_AUTHZ_ARGS variable.\n          --client-ca-file=<path/to/client-ca-file>\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.4\n        text: \"Verify that if defined, the --read-only-port argument is set to 0 (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--read-only-port\"\n              path: '{.readOnlyPort}'\n              compare:\n                op: eq\n                value: 0\n            - flag: \"--read-only-port\"\n              path: '{.readOnlyPort}'\n              set: false\n        remediation: |\n          If using a Kubelet config file, edit the file to set `readOnlyPort` to 0.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --read-only-port=0\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.5\n        text: \"Ensure that the --streaming-connection-idle-timeout argument is not set to 0 (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --streaming-connection-idle-timeout\n              path: '{.streamingConnectionIdleTimeout}'\n              compare:\n                op: noteq\n                value: 0\n            - flag: --streaming-connection-idle-timeout\n              path: '{.streamingConnectionIdleTimeout}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to set `streamingConnectionIdleTimeout` to a\n          value other than 0.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --streaming-connection-idle-timeout=5m\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.6\n        text: \"Ensure that the --make-iptables-util-chains argument is set to true (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --make-iptables-util-chains\n              path: '{.makeIPTablesUtilChains}'\n              compare:\n                op: eq\n                value: true\n            - flag: --make-iptables-util-chains\n              path: '{.makeIPTablesUtilChains}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to set `makeIPTablesUtilChains` to `true`.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          remove the --make-iptables-util-chains argument from the\n          KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.7\n        text: \"Ensure that the --hostname-override argument is not set (Manual)\"\n        # This is one of those properties that can only be set as a command line argument.\n        # To check if the property is set as expected, we need to parse the kubelet command\n        # instead reading the Kubelet Configuration file.\n        audit: \"/bin/ps -fC $kubeletbin\"\n        tests:\n          test_items:\n            - flag: --hostname-override\n              set: false\n        remediation: |\n          Edit the kubelet service file $kubeletsvc\n          on each worker node and remove the --hostname-override argument from the\n          KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.8\n        text: \"Ensure that the eventRecordQPS argument is set to a level which ensures appropriate event capture (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --event-qps\n              path: '{.eventRecordQPS}'\n              compare:\n                op: gte\n                value: 0\n            - flag: --event-qps\n              path: '{.eventRecordQPS}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to set `eventRecordQPS` to an appropriate level.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.9\n        text: \"Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --tls-cert-file\n              path: '{.tlsCertFile}'\n            - flag: --tls-private-key-file\n              path: '{.tlsPrivateKeyFile}'\n        remediation: |\n          If using a Kubelet config file, edit the file to set `tlsCertFile` to the location\n          of the certificate file to use to identify this Kubelet, and `tlsPrivateKeyFile`\n          to the location of the corresponding private key file.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameters in KUBELET_CERTIFICATE_ARGS variable.\n          --tls-cert-file=<path/to/tls-certificate-file>\n          --tls-private-key-file=<path/to/tls-key-file>\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.10\n        text: \"Ensure that the --rotate-certificates argument is not set to false (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --rotate-certificates\n              path: '{.rotateCertificates}'\n              compare:\n                op: eq\n                value: true\n            - flag: --rotate-certificates\n              path: '{.rotateCertificates}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to add the line `rotateCertificates` to `true` or\n          remove it altogether to use the default value.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          remove --rotate-certificates=false argument from the KUBELET_CERTIFICATE_ARGS\n          variable.\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.11\n        text: \"Verify that the RotateKubeletServerCertificate argument is set to true (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: RotateKubeletServerCertificate\n              path: '{.featureGates.RotateKubeletServerCertificate}'\n              compare:\n                op: nothave\n                value: false\n            - flag: RotateKubeletServerCertificate\n              path: '{.featureGates.RotateKubeletServerCertificate}'\n              set: false\n        remediation: |\n          Edit the kubelet service file $kubeletsvc\n          on each worker node and set the below parameter in KUBELET_CERTIFICATE_ARGS variable.\n          --feature-gates=RotateKubeletServerCertificate=true\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.12\n        text: \"Ensure that the Kubelet only makes use of Strong Cryptographic Ciphers (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --tls-cipher-suites\n              path: '{range .tlsCipherSuites[:]}{}{'',''}{end}'\n              compare:\n                op: valid_elements\n                value: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384\n        remediation: |\n          If using a Kubelet config file, edit the file to set `tlsCipherSuites` to\n          TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384\n          or to a subset of these values.\n          If using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the --tls-cipher-suites parameter as follows, or to a subset of these values.\n          --tls-cipher-suites=TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.13\n        text: \"Ensure that a limit is set on pod PIDs (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --pod-max-pids\n              path: '{.podPidsLimit}'\n        remediation: |\n          Decide on an appropriate level for this parameter and set it,\n          either via the --pod-max-pids command line parameter or the PodPidsLimit configuration file setting.\n        scored: false\n\n      - id: 4.2.14\n        text: \"Ensure that the --seccomp-default parameter is set to true (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --seccomp-default\n              path: '{.seccompDefault}'\n        remediation: |\n          Set the parameter, either via the --seccomp-default command line parameter or the\n          seccompDefault configuration file setting.\n          By default the seccomp profile is not enabled.\n        scored: false\n\n  - id: 4.3\n    text: \"kube-proxy\"\n    checks:\n      - id: 4.3.1\n        text: \"Ensure that the kube-proxy metrics service is bound to localhost (Automated)\"\n        audit: \"/bin/ps -fC $proxybin\"\n        audit_config: \"/bin/sh -c 'if test -e $proxykubeconfig; then cat $proxykubeconfig; fi'\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--metrics-bind-address\"\n              path: '{.metricsBindAddress}'\n              compare:\n                op: has\n                value: \"127.0.0.1\"\n            - flag: \"--metrics-bind-address\"\n              path: '{.metricsBindAddress}'\n              set: false\n        remediation: |\n           Modify or remove any values which bind the metrics service to a non-localhost address.\n           The default value is 127.0.0.1:10249.\n        scored: true\n"
  },
  {
    "path": "cfg/cis-1.12/policies.yaml",
    "content": "---\ncontrols:\nversion: \"cis-1.12\"\nid: 5\ntext: \"Kubernetes Policies\"\ntype: \"policies\"\ngroups:\n  - id: 5.1\n    text: \"RBAC and Service Accounts\"\n    checks:\n      - id: 5.1.1\n        text: \"Ensure that the cluster-admin role is only used where required (Manual)\"\n        audit: |\n          kubectl get clusterrolebindings -o=custom-columns=NAME:.metadata.name,ROLE:.roleRef.name,SUBJECT:.subjects[*].name --no-headers | while read -r role_name role_binding subject\n          do\n            if [[ \"${role_name}\" != \"cluster-admin\" && \"${role_binding}\" == \"cluster-admin\" ]]; then\n              is_compliant=\"false\"\n            else\n              is_compliant=\"true\"\n            fi;\n            echo \"**role_name: ${role_name} role_binding: ${role_binding} subject: ${subject} is_compliant: ${is_compliant}\"\n          done\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"is_compliant\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Identify all clusterrolebindings to the cluster-admin role. Check if they are used and\n          if they need this role or if they could use a role with fewer privileges.\n          Where possible, first bind users to a lower privileged role and then remove the\n          clusterrolebinding to the cluster-admin role : kubectl delete clusterrolebinding [name]\n          Condition: is_compliant is false if rolename is not cluster-admin and rolebinding is cluster-admin.\n        scored: false\n\n      - id: 5.1.2\n        text: \"Minimize access to secrets (Manual)\"\n        audit: \"echo \\\"canGetListWatchSecretsAsSystemAuthenticated: $(kubectl auth can-i get,list,watch secrets --all-namespaces --as=system:authenticated)\\\"\"\n        tests:\n          test_items:\n            - flag: \"canGetListWatchSecretsAsSystemAuthenticated\"\n              compare:\n                op: eq\n                value: no\n        remediation: |\n          Where possible, remove get, list and watch access to Secret objects in the cluster.\n        scored: false\n\n      - id: 5.1.3\n        text: \"Minimize wildcard use in Roles and ClusterRoles (Manual)\"\n        audit: |\n          # Check Roles\n          kubectl get roles --all-namespaces -o custom-columns=ROLE_NAMESPACE:.metadata.namespace,ROLE_NAME:.metadata.name --no-headers | while read -r role_namespace role_name\n          do\n            role_rules=$(kubectl get role -n \"${role_namespace}\" \"${role_name}\" -o=json | jq -c '.rules')\n            if echo \"${role_rules}\" | grep -q \"\\[\\\"\\*\\\"\\]\"; then\n              role_is_compliant=\"false\"\n            else\n              role_is_compliant=\"true\"\n            fi;\n            echo \"**role_name: ${role_name} role_namespace: ${role_namespace} role_rules: ${role_rules} role_is_compliant: ${role_is_compliant}\"\n          done\n\n          # Check ClusterRoles\n          kubectl get clusterroles -o custom-columns=CLUSTERROLE_NAME:.metadata.name --no-headers | while read -r clusterrole_name\n          do\n            clusterrole_rules=$(kubectl get clusterrole \"${clusterrole_name}\" -o=json | jq -c '.rules')\n            if echo \"${clusterrole_rules}\" | grep -q \"\\[\\\"\\*\\\"\\]\"; then\n              clusterrole_is_compliant=\"false\"\n            else\n              clusterrole_is_compliant=\"true\"\n            fi;\n          echo \"**clusterrole_name: ${clusterrole_name} clusterrole_rules: ${clusterrole_rules} clusterrole_is_compliant: ${clusterrole_is_compliant}\"\n          done\n        use_multiple_values: true\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"role_is_compliant\"\n              compare:\n                op: eq\n                value: true\n              set: true\n            - flag: \"clusterrole_is_compliant\"\n              compare:\n                op: eq\n                value: true\n              set: true\n        remediation: |\n          Where possible replace any use of wildcards [\"*\"] in roles and clusterroles with specific\n          objects or actions.\n          Condition: role_is_compliant is false if [\"*\"] is found in rules.\n          Condition: clusterrole_is_compliant is false if [\"*\"] is found in rules.\n        scored: false\n\n      - id: 5.1.4\n        text: \"Minimize access to create pods (Manual)\"\n        audit: |\n          echo \"canCreatePodsAsSystemAuthenticated: $(kubectl auth can-i create pods --all-namespaces --as=system:authenticated)\"\n        tests:\n          test_items:\n            - flag: \"canCreatePodsAsSystemAuthenticated\"\n              compare:\n                op: eq\n                value: no\n        remediation: |\n          Where possible, remove create access to pod objects in the cluster.\n        scored: false\n\n      - id: 5.1.5\n        text: \"Ensure that default service accounts are not actively used (Manual)\"\n        audit: |\n          kubectl get serviceaccount --all-namespaces --field-selector metadata.name=default -o=json | jq -r '.items[] | \" namespace: \\(.metadata.namespace), kind: \\(.kind), name: \\(.metadata.name), automountServiceAccountToken: \\(.automountServiceAccountToken | if . == null then \"notset\" else . end )\"' | xargs -L 1\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"automountServiceAccountToken\"\n              compare:\n                op: eq\n                value: false\n              set: true\n        remediation: |\n          Create explicit service accounts wherever a Kubernetes workload requires specific access\n          to the Kubernetes API server.\n          Modify the configuration of each default service account to include this value\n          `automountServiceAccountToken: false`.\n        scored: false\n\n      - id: 5.1.6\n        text: \"Ensure that Service Account Tokens are only mounted where necessary (Manual)\"\n        audit: |\n          kubectl get pods --all-namespaces -o custom-columns=POD_NAMESPACE:.metadata.namespace,POD_NAME:.metadata.name,POD_SERVICE_ACCOUNT:.spec.serviceAccount,POD_IS_AUTOMOUNTSERVICEACCOUNTTOKEN:.spec.automountServiceAccountToken --no-headers | while read -r pod_namespace pod_name pod_service_account pod_is_automountserviceaccounttoken\n          do\n            # Retrieve automountServiceAccountToken's value for ServiceAccount and Pod, set to notset if null or <none>.\n            svacc_is_automountserviceaccounttoken=$(kubectl get serviceaccount -n \"${pod_namespace}\" \"${pod_service_account}\" -o json | jq -r '.automountServiceAccountToken' | sed -e 's/<none>/notset/g' -e 's/null/notset/g')\n            pod_is_automountserviceaccounttoken=$(echo \"${pod_is_automountserviceaccounttoken}\" | sed -e 's/<none>/notset/g' -e 's/null/notset/g')\n            if [ \"${svacc_is_automountserviceaccounttoken}\" = \"false\" ] && ( [ \"${pod_is_automountserviceaccounttoken}\" = \"false\" ] || [ \"${pod_is_automountserviceaccounttoken}\" = \"notset\" ] ); then\n              is_compliant=\"true\"\n            elif [ \"${svacc_is_automountserviceaccounttoken}\" = \"true\" ] && [ \"${pod_is_automountserviceaccounttoken}\" = \"false\" ]; then\n              is_compliant=\"true\"\n            else\n              is_compliant=\"false\"\n            fi\n            echo \"**namespace: ${pod_namespace} pod_name: ${pod_name} service_account: ${pod_service_account} pod_is_automountserviceaccounttoken: ${pod_is_automountserviceaccounttoken} svacc_is_automountServiceAccountToken: ${svacc_is_automountserviceaccounttoken} is_compliant: ${is_compliant}\"\n          done\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"is_compliant\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Modify the definition of ServiceAccounts and Pods which do not need to mount service\n          account tokens to disable it, with `automountServiceAccountToken: false`.\n          If both the ServiceAccount and the Pod's .spec specify a value for automountServiceAccountToken, the Pod spec takes precedence.\n          Condition: Pod is_compliant to true when\n            - ServiceAccount is automountServiceAccountToken: false and Pod is automountServiceAccountToken: false or notset\n            - ServiceAccount is automountServiceAccountToken: true notset and Pod is automountServiceAccountToken: false\n        scored: false\n\n      - id: 5.1.7\n        text: \"Avoid use of system:masters group (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Remove the system:masters group from all users in the cluster.\n        scored: false\n\n      - id: 5.1.8\n        text: \"Limit use of the Bind, Impersonate and Escalate permissions in the Kubernetes cluster (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove the impersonate, bind and escalate rights from subjects.\n        scored: false\n\n      - id: 5.1.9\n        text: \"Minimize access to create persistent volumes (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove create access to PersistentVolume objects in the cluster.\n        scored: false\n\n      - id: 5.1.10\n        text: \"Minimize access to the proxy sub-resource of nodes (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove access to the proxy sub-resource of node objects.\n        scored: false\n\n      - id: 5.1.11\n        text: \"Minimize access to the approval sub-resource of certificatesigningrequests objects (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove access to the approval sub-resource of certificatesigningrequests objects.\n        scored: false\n\n      - id: 5.1.12\n        text: \"Minimize access to webhook configuration objects (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove access to the validatingwebhookconfigurations or mutatingwebhookconfigurations objects\n        scored: false\n\n      - id: 5.1.13\n        text: \"Minimize access to the service account token creation (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove access to the token sub-resource of serviceaccount objects.\n        scored: false\n\n  - id: 5.2\n    text: \"Pod Security Standards\"\n    checks:\n      - id: 5.2.1\n        text: \"Ensure that the cluster has at least one active policy control mechanism in place (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that either Pod Security Admission or an external policy control system is in place\n          for every namespace which contains user workloads.\n        scored: false\n\n      - id: 5.2.2\n        text: \"Minimize the admission of privileged containers (Manual)\"\n        audit: |\n          kubectl get pods --all-namespaces -o custom-columns=POD_NAME:.metadata.name,POD_NAMESPACE:.metadata.namespace --no-headers | while read -r pod_name pod_namespace\n          do\n            # Retrieve container(s) for each Pod.\n            kubectl get pod \"${pod_name}\" --namespace \"${pod_namespace}\" -o json | jq -c '.spec.containers[]' | while read -r container\n            do\n              # Retrieve container's name.\n              container_name=$(echo ${container} | jq -r '.name')\n              # Retrieve container's .securityContext.privileged value.\n              container_privileged=$(echo ${container} | jq -r '.securityContext.privileged' | sed -e 's/null/notset/g')\n              if [ \"${container_privileged}\" = \"false\" ] || [ \"${container_privileged}\" = \"notset\" ] ; then\n                echo \"***pod_name: ${pod_name} container_name: ${container_name} pod_namespace: ${pod_namespace} is_container_privileged: ${container_privileged} is_compliant: true\"\n              else\n                echo \"***pod_name: ${pod_name} container_name: ${container_name} pod_namespace: ${pod_namespace} is_container_privileged: ${container_privileged} is_compliant: false\"\n              fi\n            done\n          done\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"is_compliant\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of privileged containers.\n          Audit: the audit list all pods' containers to retrieve their .securityContext.privileged value.\n          Condition: is_compliant is false if container's `.securityContext.privileged` is set to `true`.\n          Default: by default, there are no restrictions on the creation of privileged containers.\n        scored: false\n\n      - id: 5.2.3\n        text: \"Minimize the admission of containers wishing to share the host process ID namespace (Manual)\"\n        audit: |\n          kubectl get pods --all-namespaces -o custom-columns=POD_NAME:.metadata.name,POD_NAMESPACE:.metadata.namespace --no-headers | while read -r pod_name pod_namespace\n          do\n            # Retrieve spec.hostPID for each pod.\n            pod_hostpid=$(kubectl get pod \"${pod_name}\" --namespace \"${pod_namespace}\" -o jsonpath='{.spec.hostPID}' 2>/dev/null)\n            if [ -z \"${pod_hostpid}\" ]; then\n              pod_hostpid=\"false\"\n              echo \"***pod_name: ${pod_name} pod_namespace: ${pod_namespace} is_pod_hostpid: ${pod_hostpid} is_compliant: true\"\n            else\n              echo \"***pod_name: ${pod_name} pod_namespace: ${pod_namespace} is_pod_hostpid: ${pod_hostpid} is_compliant: false\"\n            fi\n          done\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"is_compliant\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of `hostPID` containers.\n          Audit: the audit retrieves each Pod' spec.hostPID.\n          Condition: is_compliant is false if Pod's spec.hostPID is set to `true`.\n          Default: by default, there are no restrictions on the creation of hostPID containers.\n        scored: false\n\n      - id: 5.2.4\n        text: \"Minimize the admission of containers wishing to share the host IPC namespace (Manual)\"\n        audit: |\n          kubectl get pods --all-namespaces -o custom-columns=POD_NAME:.metadata.name,POD_NAMESPACE:.metadata.namespace --no-headers | while read -r pod_name pod_namespace\n          do\n            # Retrieve spec.hostIPC for each pod.\n            pod_hostipc=$(kubectl get pod \"${pod_name}\" --namespace \"${pod_namespace}\" -o jsonpath='{.spec.hostIPC}' 2>/dev/null)\n            if [ -z \"${pod_hostipc}\" ]; then\n              pod_hostipc=\"false\"\n              echo \"***pod_name: ${pod_name} pod_namespace: ${pod_namespace} is_pod_hostipc: ${pod_hostipc} is_compliant: true\"\n            else\n              echo \"***pod_name: ${pod_name} pod_namespace: ${pod_namespace} is_pod_hostipc: ${pod_hostipc} is_compliant: false\"\n            fi\n          done\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"is_compliant\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of `hostIPC` containers.\n          Audit: the audit retrieves each Pod' spec.IPC.\n          Condition: is_compliant is false if Pod's spec.hostIPC is set to `true`.\n          Default: by default, there are no restrictions on the creation of hostIPC containers.\n        scored: false\n\n      - id: 5.2.5\n        text: \"Minimize the admission of containers wishing to share the host network namespace (Manual)\"\n        audit: |\n          kubectl get pods --all-namespaces -o custom-columns=POD_NAME:.metadata.name,POD_NAMESPACE:.metadata.namespace --no-headers | while read -r pod_name pod_namespace\n          do\n            # Retrieve spec.hostNetwork for each pod.\n            pod_hostnetwork=$(kubectl get pod \"${pod_name}\" --namespace \"${pod_namespace}\" -o jsonpath='{.spec.hostNetwork}' 2>/dev/null)\n            if [ -z \"${pod_hostnetwork}\" ]; then\n              pod_hostnetwork=\"false\"\n              echo \"***pod_name: ${pod_name} pod_namespace: ${pod_namespace} is_pod_hostnetwork: ${pod_hostnetwork} is_compliant: true\"\n            else\n              echo \"***pod_name: ${pod_name} pod_namespace: ${pod_namespace} is_pod_hostnetwork: ${pod_hostnetwork} is_compliant: false\"\n            fi\n          done\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"is_compliant\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of `hostNetwork` containers.\n          Audit: the audit retrieves each Pod' spec.hostNetwork.\n          Condition: is_compliant is false if Pod's spec.hostNetwork is set to `true`.\n          Default: by default, there are no restrictions on the creation of hostNetwork containers.\n        scored: false\n\n      - id: 5.2.6\n        text: \"Minimize the admission of containers with allowPrivilegeEscalation (Manual)\"\n        audit: |\n          kubectl get pods --all-namespaces -o custom-columns=POD_NAME:.metadata.name,POD_NAMESPACE:.metadata.namespace --no-headers | while read -r pod_name pod_namespace\n          do\n            # Retrieve container(s) for each Pod.\n            kubectl get pod \"${pod_name}\" --namespace \"${pod_namespace}\" -o json | jq -c '.spec.containers[]' | while read -r container\n            do\n              # Retrieve container's name\n              container_name=$(echo ${container} | jq -r '.name')\n              # Retrieve container's .securityContext.allowPrivilegeEscalation\n              container_allowprivesc=$(echo ${container} | jq -r '.securityContext.allowPrivilegeEscalation' | sed -e 's/null/notset/g')\n              if [ \"${container_allowprivesc}\" = \"false\" ] || [ \"${container_allowprivesc}\" = \"notset\" ]; then\n                echo \"***pod_name: ${pod_name} container_name: ${container_name} pod_namespace: ${pod_namespace} is_container_allowprivesc: ${container_allowprivesc} is_compliant: true\"\n              else\n                echo \"***pod_name: ${pod_name} container_name: ${container_name} pod_namespace: ${pod_namespace} is_container_allowprivesc: ${container_allowprivesc} is_compliant: false\"\n              fi\n            done\n          done\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"is_compliant\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers with `.securityContext.allowPrivilegeEscalation` set to `true`.\n          Audit: the audit retrieves each Pod's container(s) `.securityContext.allowPrivilegeEscalation`.\n          Condition: is_compliant is false if container's `.securityContext.allowPrivilegeEscalation` is set to `true`.\n          Default: If notset, privilege escalation is allowed (default to true). However if PSP/PSA is used with a `restricted` profile,\n          privilege escalation is explicitly disallowed unless configured otherwise.\n        scored: false\n\n      - id: 5.2.7\n        text: \"Minimize the admission of root containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Create a policy for each namespace in the cluster, ensuring that either `MustRunAsNonRoot`\n          or `MustRunAs` with the range of UIDs not including 0, is set.\n        scored: false\n\n      - id: 5.2.8\n        text: \"Minimize the admission of containers with the NET_RAW capability (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers with the `NET_RAW` capability.\n        scored: false\n\n      - id: 5.2.9\n        text: \"Minimize the admission of containers with capabilities assigned (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Review the use of capabilities in applications running on your cluster. Where a\n          namespace contains applications which do not require any Linux capabilities to operate\n          consider adding a policy which forbids the admission of containers which do not drop all\n          capabilities.\n        scored: false\n\n      - id: 5.2.10\n        text: \"Minimize the admission of Windows HostProcess containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers that have `.securityContext.windowsOptions.hostProcess` set to `true`.\n        scored: false\n\n      - id: 5.2.11\n        text: \"Minimize the admission of HostPath volumes (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers with `hostPath` volumes.\n        scored: false\n\n      - id: 5.2.12\n        text: \"Minimize the admission of containers which use HostPorts (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers which use `hostPort` sections.\n        scored: false\n\n  - id: 5.3\n    text: \"Network Policies and CNI\"\n    checks:\n      - id: 5.3.1\n        text: \"Ensure that the CNI in use supports NetworkPolicies (Manual)\"\n        type: \"manual\"\n        remediation: |\n          If the CNI plugin in use does not support network policies, consideration should be given to\n          making use of a different plugin, or finding an alternate mechanism for restricting traffic\n          in the Kubernetes cluster.\n        scored: false\n\n      - id: 5.3.2\n        text: \"Ensure that all Namespaces have NetworkPolicies defined (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the documentation and create NetworkPolicy objects as you need them.\n        scored: false\n\n  - id: 5.4\n    text: \"Secrets Management\"\n    checks:\n      - id: 5.4.1\n        text: \"Prefer using Secrets as files over Secrets as environment variables (Manual)\"\n        type: \"manual\"\n        remediation: |\n          If possible, rewrite application code to read Secrets from mounted secret files, rather than\n          from environment variables.\n        scored: false\n\n      - id: 5.4.2\n        text: \"Consider external secret storage (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Refer to the Secrets management options offered by your cloud provider or a third-party\n          secrets management solution.\n        scored: false\n\n  - id: 5.5\n    text: \"Extensible Admission Control\"\n    checks:\n      - id: 5.5.1\n        text: \"Configure Image Provenance using ImagePolicyWebhook admission controller (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and setup image provenance.\n        scored: false\n\n  - id: 5.6\n    text: \"General Policies\"\n    checks:\n      - id: 5.6.1\n        text: \"Create administrative boundaries between resources using namespaces (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the documentation and create namespaces for objects in your deployment as you need\n          them.\n        scored: false\n\n      - id: 5.6.2\n        text: \"Ensure that the seccomp profile is set to docker/default in your Pod definitions (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Use `securityContext` to enable the docker/default seccomp profile in your pod definitions.\n          An example is as below:\n            securityContext:\n              seccompProfile:\n                type: RuntimeDefault\n        scored: false\n\n      - id: 5.6.3\n        text: \"Apply SecurityContext to your Pods and Containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and apply SecurityContexts to your Pods. For a\n          suggested list of SecurityContexts, you may refer to the CIS Security Benchmark for Docker\n          Containers.\n        scored: false\n\n      - id: 5.6.4\n        text: \"The default namespace should not be used (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that namespaces are created to allow for appropriate segregation of Kubernetes\n          resources and that all new resources are created in a specific namespace.\n        scored: false\n"
  },
  {
    "path": "cfg/cis-1.20/config.yaml",
    "content": "---\n## Version-specific settings that override the values in cfg/config.yaml\n"
  },
  {
    "path": "cfg/cis-1.20/controlplane.yaml",
    "content": "---\ncontrols:\nversion: \"cis-1.20\"\nid: 3\ntext: \"Control Plane Configuration\"\ntype: \"controlplane\"\ngroups:\n  - id: 3.1\n    text: \"Authentication and Authorization\"\n    checks:\n      - id: 3.1.1\n        text: \"Client certificate authentication should not be used for users (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Alternative mechanisms provided by Kubernetes such as the use of OIDC should be\n          implemented in place of client certificates.\n        scored: false\n\n  - id: 3.2\n    text: \"Logging\"\n    checks:\n      - id: 3.2.1\n        text: \"Ensure that a minimal audit policy is created (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-policy-file\"\n              set: true\n        remediation: |\n          Create an audit policy file for your cluster.\n        scored: false\n\n      - id: 3.2.2\n        text: \"Ensure that the audit policy covers key security concerns (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Consider modification of the audit policy in use on the cluster to include these items, at a\n          minimum.\n        scored: false\n"
  },
  {
    "path": "cfg/cis-1.20/etcd.yaml",
    "content": "---\ncontrols:\nversion: \"cis-1.20\"\nid: 2\ntext: \"Etcd Node Configuration\"\ntype: \"etcd\"\ngroups:\n  - id: 2\n    text: \"Etcd Node Configuration Files\"\n    checks:\n      - id: 2.1\n        text: \"Ensure that the --cert-file and --key-file arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--cert-file\"\n              env: \"ETCD_CERT_FILE\"\n            - flag: \"--key-file\"\n              env: \"ETCD_KEY_FILE\"\n        remediation: |\n          Follow the etcd service documentation and configure TLS encryption.\n          Then, edit the etcd pod specification file /etc/kubernetes/manifests/etcd.yaml\n          on the master node and set the below parameters.\n          --cert-file=</path/to/ca-file>\n          --key-file=</path/to/key-file>\n        scored: true\n\n      - id: 2.2\n        text: \"Ensure that the --client-cert-auth argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--client-cert-auth\"\n              env: \"ETCD_CLIENT_CERT_AUTH\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and set the below parameter.\n          --client-cert-auth=\"true\"\n        scored: true\n\n      - id: 2.3\n        text: \"Ensure that the --auto-tls argument is not set to true (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--auto-tls\"\n              env: \"ETCD_AUTO_TLS\"\n              set: false\n            - flag: \"--auto-tls\"\n              env: \"ETCD_AUTO_TLS\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and either remove the --auto-tls parameter or set it to false.\n            --auto-tls=false\n        scored: true\n\n      - id: 2.4\n        text: \"Ensure that the --peer-cert-file and --peer-key-file arguments are\n        set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--peer-cert-file\"\n              env: \"ETCD_PEER_CERT_FILE\"\n            - flag: \"--peer-key-file\"\n              env: \"ETCD_PEER_KEY_FILE\"\n        remediation: |\n          Follow the etcd service documentation and configure peer TLS encryption as appropriate\n          for your etcd cluster.\n          Then, edit the etcd pod specification file $etcdconf on the\n          master node and set the below parameters.\n          --peer-client-file=</path/to/peer-cert-file>\n          --peer-key-file=</path/to/peer-key-file>\n        scored: true\n\n      - id: 2.5\n        text: \"Ensure that the --peer-client-cert-auth argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--peer-client-cert-auth\"\n              env: \"ETCD_PEER_CLIENT_CERT_AUTH\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and set the below parameter.\n          --peer-client-cert-auth=true\n        scored: true\n\n      - id: 2.6\n        text: \"Ensure that the --peer-auto-tls argument is not set to true (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--peer-auto-tls\"\n              env: \"ETCD_PEER_AUTO_TLS\"\n              set: false\n            - flag: \"--peer-auto-tls\"\n              env: \"ETCD_PEER_AUTO_TLS\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and either remove the --peer-auto-tls parameter or set it to false.\n          --peer-auto-tls=false\n        scored: true\n\n      - id: 2.7\n        text: \"Ensure that a unique Certificate Authority is used for etcd (Manual)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--trusted-ca-file\"\n              env: \"ETCD_TRUSTED_CA_FILE\"\n        remediation: |\n          [Manual test]\n          Follow the etcd documentation and create a dedicated certificate authority setup for the\n          etcd service.\n          Then, edit the etcd pod specification file $etcdconf on the\n          master node and set the below parameter.\n          --trusted-ca-file=</path/to/ca-file>\n        scored: false\n"
  },
  {
    "path": "cfg/cis-1.20/master.yaml",
    "content": "---\ncontrols:\nversion: \"cis-1.20\"\nid: 1\ntext: \"Master Node Security Configuration\"\ntype: \"master\"\ngroups:\n  - id: 1.1\n    text: \"Master Node Configuration Files\"\n    checks:\n      - id: 1.1.1\n        text: \"Ensure that the API server pod specification file permissions are set to 644 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $apiserverconf; then stat -c permissions=%a $apiserverconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the\n          master node.\n          For example, chmod 644 $apiserverconf\n        scored: true\n\n      - id: 1.1.2\n        text: \"Ensure that the API server pod specification file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $apiserverconf; then stat -c %U:%G $apiserverconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chown root:root $apiserverconf\n        scored: true\n\n      - id: 1.1.3\n        text: \"Ensure that the controller manager pod specification file permissions are set to 644 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerconf; then stat -c permissions=%a $controllermanagerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chmod 644 $controllermanagerconf\n        scored: true\n\n      - id: 1.1.4\n        text: \"Ensure that the controller manager pod specification file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerconf; then stat -c %U:%G $controllermanagerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chown root:root $controllermanagerconf\n        scored: true\n\n      - id: 1.1.5\n        text: \"Ensure that the scheduler pod specification file permissions are set to 644 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerconf; then stat -c permissions=%a $schedulerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chmod 644 $schedulerconf\n        scored: true\n\n      - id: 1.1.6\n        text: \"Ensure that the scheduler pod specification file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerconf; then stat -c %U:%G $schedulerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chown root:root $schedulerconf\n        scored: true\n\n      - id: 1.1.7\n        text: \"Ensure that the etcd pod specification file permissions are set to 644 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $etcdconf; then find $etcdconf -name '*etcd*' | xargs stat -c permissions=%a; fi'\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chmod 644 $etcdconf\n        scored: true\n\n      - id: 1.1.8\n        text: \"Ensure that the etcd pod specification file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $etcdconf; then find $etcdconf -name '*etcd*' | xargs stat -c %U:%G; fi'\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chown root:root $etcdconf\n        scored: true\n\n      - id: 1.1.9\n        text: \"Ensure that the Container Network Interface file permissions are set to 644 or more restrictive (Manual)\"\n        audit: |\n          ps -ef | grep $kubeletbin | grep -- --cni-conf-dir | sed 's%.*cni-conf-dir[= ]\\([^ ]*\\).*%\\1%' | xargs -I{} find {} -mindepth 1 | xargs --no-run-if-empty stat -c permissions=%a\n          find /var/lib/cni/networks -type f 2> /dev/null | xargs --no-run-if-empty stat -c permissions=%a\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chmod 644 <path/to/cni/files>\n        scored: false\n\n      - id: 1.1.10\n        text: \"Ensure that the Container Network Interface file ownership is set to root:root (Manual)\"\n        audit: |\n          ps -ef | grep $kubeletbin | grep -- --cni-conf-dir | sed 's%.*cni-conf-dir[= ]\\([^ ]*\\).*%\\1%' | xargs -I{} find {} -mindepth 1 | xargs --no-run-if-empty stat -c %U:%G\n          find /var/lib/cni/networks -type f 2> /dev/null | xargs --no-run-if-empty stat -c %U:%G\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chown root:root <path/to/cni/files>\n        scored: false\n\n      - id: 1.1.11\n        text: \"Ensure that the etcd data directory permissions are set to 700 or more restrictive (Automated)\"\n        audit: |\n          DATA_DIR=''\n          for d in $(ps -ef | grep $etcdbin | grep -- --data-dir | sed 's%.*data-dir[= ]\\([^ ]*\\).*%\\1%'); do\n            if test -d \"$d\"; then DATA_DIR=\"$d\"; fi\n          done\n          if ! test -d \"$DATA_DIR\"; then DATA_DIR=$etcddatadir; fi\n          stat -c permissions=%a \"$DATA_DIR\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"700\"\n        remediation: |\n          On the etcd server node, get the etcd data directory, passed as an argument --data-dir,\n          from the below command:\n          ps -ef | grep etcd\n          Run the below command (based on the etcd data directory found above). For example,\n          chmod 700 /var/lib/etcd\n        scored: true\n\n      - id: 1.1.12\n        text: \"Ensure that the etcd data directory ownership is set to etcd:etcd (Automated)\"\n        audit: |\n          DATA_DIR=''\n          for d in $(ps -ef | grep $etcdbin | grep -- --data-dir | sed 's%.*data-dir[= ]\\([^ ]*\\).*%\\1%'); do\n            if test -d \"$d\"; then DATA_DIR=\"$d\"; fi\n          done\n          if ! test -d \"$DATA_DIR\"; then DATA_DIR=$etcddatadir; fi\n          stat -c %U:%G \"$DATA_DIR\"\n        tests:\n          test_items:\n            - flag: \"etcd:etcd\"\n        remediation: |\n          On the etcd server node, get the etcd data directory, passed as an argument --data-dir,\n          from the below command:\n          ps -ef | grep etcd\n          Run the below command (based on the etcd data directory found above).\n          For example, chown etcd:etcd /var/lib/etcd\n        scored: true\n\n      - id: 1.1.13\n        text: \"Ensure that the admin.conf file permissions are set to 644 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e /etc/kubernetes/admin.conf; then stat -c permissions=%a /etc/kubernetes/admin.conf; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chmod 644 /etc/kubernetes/admin.conf\n        scored: true\n\n      - id: 1.1.14\n        text: \"Ensure that the admin.conf file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e /etc/kubernetes/admin.conf; then stat -c %U:%G /etc/kubernetes/admin.conf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chown root:root /etc/kubernetes/admin.conf\n        scored: true\n\n      - id: 1.1.15\n        text: \"Ensure that the scheduler.conf file permissions are set to 644 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerkubeconfig; then stat -c permissions=%a $schedulerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chmod 644 $schedulerkubeconfig\n        scored: true\n\n      - id: 1.1.16\n        text: \"Ensure that the scheduler.conf file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerkubeconfig; then stat -c %U:%G $schedulerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chown root:root $schedulerkubeconfig\n        scored: true\n\n      - id: 1.1.17\n        text: \"Ensure that the controller-manager.conf file permissions are set to 644 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerkubeconfig; then stat -c permissions=%a $controllermanagerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chmod 644 $controllermanagerkubeconfig\n        scored: true\n\n      - id: 1.1.18\n        text: \"Ensure that the controller-manager.conf file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerkubeconfig; then stat -c %U:%G $controllermanagerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chown root:root $controllermanagerkubeconfig\n        scored: true\n\n      - id: 1.1.19\n        text: \"Ensure that the Kubernetes PKI directory and file ownership is set to root:root (Automated)\"\n        audit: \"find /etc/kubernetes/pki/ | xargs stat -c %U:%G\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chown -R root:root /etc/kubernetes/pki/\n        scored: true\n\n      - id: 1.1.20\n        text: \"Ensure that the Kubernetes PKI certificate file permissions are set to 644 or more restrictive (Manual)\"\n        audit: \"find /etc/kubernetes/pki/ -name '*.crt' | xargs stat -c permissions=%a\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chmod -R 644 /etc/kubernetes/pki/*.crt\n        scored: false\n\n      - id: 1.1.21\n        text: \"Ensure that the Kubernetes PKI key file permissions are set to 600 (Manual)\"\n        audit: \"find /etc/kubernetes/pki/ -name '*.key' | xargs stat -c permissions=%a\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chmod -R 600 /etc/kubernetes/pki/*.key\n        scored: false\n\n  - id: 1.2\n    text: \"API Server\"\n    checks:\n      - id: 1.2.1\n        text: \"Ensure that the --anonymous-auth argument is set to false (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--anonymous-auth\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and set the below parameter.\n          --anonymous-auth=false\n        scored: false\n\n      - id: 1.2.2\n        text: \"Ensure that the --token-auth-file parameter is not set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--token-auth-file\"\n              set: false\n        remediation: |\n          Follow the documentation and configure alternate mechanisms for authentication. Then,\n          edit the API server pod specification file $apiserverconf\n          on the master node and remove the --token-auth-file=<filename> parameter.\n        scored: true\n\n      - id: 1.2.3\n        text: \"Ensure that the --kubelet-https argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--kubelet-https\"\n              compare:\n                op: eq\n                value: true\n            - flag: \"--kubelet-https\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and remove the --kubelet-https parameter.\n        scored: true\n\n      - id: 1.2.4\n        text: \"Ensure that the --kubelet-client-certificate and --kubelet-client-key arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--kubelet-client-certificate\"\n            - flag: \"--kubelet-client-key\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection between the\n          apiserver and kubelets. Then, edit API server pod specification file\n          $apiserverconf on the master node and set the\n          kubelet client certificate and key parameters as below.\n          --kubelet-client-certificate=<path/to/client-certificate-file>\n          --kubelet-client-key=<path/to/client-key-file>\n        scored: true\n\n      - id: 1.2.5\n        text: \"Ensure that the --kubelet-certificate-authority argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--kubelet-certificate-authority\"\n        remediation: |\n          Follow the Kubernetes documentation and setup the TLS connection between\n          the apiserver and kubelets. Then, edit the API server pod specification file\n          $apiserverconf on the master node and set the\n          --kubelet-certificate-authority parameter to the path to the cert file for the certificate authority.\n          --kubelet-certificate-authority=<ca-string>\n        scored: true\n\n      - id: 1.2.6\n        text: \"Ensure that the --authorization-mode argument is not set to AlwaysAllow (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: nothave\n                value: \"AlwaysAllow\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and set the --authorization-mode parameter to values other than AlwaysAllow.\n          One such example could be as below.\n          --authorization-mode=RBAC\n        scored: true\n\n      - id: 1.2.7\n        text: \"Ensure that the --authorization-mode argument includes Node (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: has\n                value: \"Node\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and set the --authorization-mode parameter to a value that includes Node.\n          --authorization-mode=Node,RBAC\n        scored: true\n\n      - id: 1.2.8\n        text: \"Ensure that the --authorization-mode argument includes RBAC (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: has\n                value: \"RBAC\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and set the --authorization-mode parameter to a value that includes RBAC,\n          for example:\n          --authorization-mode=Node,RBAC\n        scored: true\n\n      - id: 1.2.9\n        text: \"Ensure that the admission control plugin EventRateLimit is set (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"EventRateLimit\"\n        remediation: |\n          Follow the Kubernetes documentation and set the desired limits in a configuration file.\n          Then, edit the API server pod specification file $apiserverconf\n          and set the below parameters.\n          --enable-admission-plugins=...,EventRateLimit,...\n          --admission-control-config-file=<path/to/configuration/file>\n        scored: false\n\n      - id: 1.2.10\n        text: \"Ensure that the admission control plugin AlwaysAdmit is not set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: nothave\n                value: AlwaysAdmit\n            - flag: \"--enable-admission-plugins\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and either remove the --enable-admission-plugins parameter, or set it to a\n          value that does not include AlwaysAdmit.\n        scored: true\n\n      - id: 1.2.11\n        text: \"Ensure that the admission control plugin AlwaysPullImages is set (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"AlwaysPullImages\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and set the --enable-admission-plugins parameter to include\n          AlwaysPullImages.\n          --enable-admission-plugins=...,AlwaysPullImages,...\n        scored: false\n\n      - id: 1.2.12\n        text: \"Ensure that the admission control plugin SecurityContextDeny is set if PodSecurityPolicy is not used (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"SecurityContextDeny\"\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"PodSecurityPolicy\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and set the --enable-admission-plugins parameter to include\n          SecurityContextDeny, unless PodSecurityPolicy is already in place.\n          --enable-admission-plugins=...,SecurityContextDeny,...\n        scored: false\n\n      - id: 1.2.13\n        text: \"Ensure that the admission control plugin ServiceAccount is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--disable-admission-plugins\"\n              compare:\n                op: nothave\n                value: \"ServiceAccount\"\n            - flag: \"--disable-admission-plugins\"\n              set: false\n        remediation: |\n          Follow the documentation and create ServiceAccount objects as per your environment.\n          Then, edit the API server pod specification file $apiserverconf\n          on the master node and ensure that the --disable-admission-plugins parameter is set to a\n          value that does not include ServiceAccount.\n        scored: true\n\n      - id: 1.2.14\n        text: \"Ensure that the admission control plugin NamespaceLifecycle is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--disable-admission-plugins\"\n              compare:\n                op: nothave\n                value: \"NamespaceLifecycle\"\n            - flag: \"--disable-admission-plugins\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and set the --disable-admission-plugins parameter to\n          ensure it does not include NamespaceLifecycle.\n        scored: true\n\n      - id: 1.2.15\n        text: \"Ensure that the admission control plugin PodSecurityPolicy is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"PodSecurityPolicy\"\n        remediation: |\n          Follow the documentation and create Pod Security Policy objects as per your environment.\n          Then, edit the API server pod specification file $apiserverconf\n          on the master node and set the --enable-admission-plugins parameter to a\n          value that includes PodSecurityPolicy:\n          --enable-admission-plugins=...,PodSecurityPolicy,...\n          Then restart the API Server.\n        scored: true\n\n      - id: 1.2.16\n        text: \"Ensure that the admission control plugin NodeRestriction is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"NodeRestriction\"\n        remediation: |\n          Follow the Kubernetes documentation and configure NodeRestriction plug-in on kubelets.\n          Then, edit the API server pod specification file $apiserverconf\n          on the master node and set the --enable-admission-plugins parameter to a\n          value that includes NodeRestriction.\n          --enable-admission-plugins=...,NodeRestriction,...\n        scored: true\n\n      - id: 1.2.17\n        text: \"Ensure that the --insecure-bind-address argument is not set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--insecure-bind-address\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and remove the --insecure-bind-address parameter.\n        scored: true\n\n      - id: 1.2.18\n        text: \"Ensure that the --insecure-port argument is set to 0 (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--insecure-port\"\n              compare:\n                op: eq\n                value: 0\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and set the below parameter.\n          --insecure-port=0\n        scored: true\n\n      - id: 1.2.19\n        text: \"Ensure that the --secure-port argument is not set to 0 (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--secure-port\"\n              compare:\n                op: gt\n                value: 0\n            - flag: \"--secure-port\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and either remove the --secure-port parameter or\n          set it to a different (non-zero) desired port.\n        scored: true\n\n      - id: 1.2.20\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and set the below parameter.\n          --profiling=false\n        scored: true\n\n      - id: 1.2.21\n        text: \"Ensure that the --audit-log-path argument is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-path\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and set the --audit-log-path parameter to a suitable path and\n          file where you would like audit logs to be written, for example:\n          --audit-log-path=/var/log/apiserver/audit.log\n        scored: true\n\n      - id: 1.2.22\n        text: \"Ensure that the --audit-log-maxage argument is set to 30 or as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxage\"\n              compare:\n                op: gte\n                value: 30\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and set the --audit-log-maxage parameter to 30 or as an appropriate number of days:\n          --audit-log-maxage=30\n        scored: true\n\n      - id: 1.2.23\n        text: \"Ensure that the --audit-log-maxbackup argument is set to 10 or as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxbackup\"\n              compare:\n                op: gte\n                value: 10\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and set the --audit-log-maxbackup parameter to 10 or to an appropriate\n          value.\n          --audit-log-maxbackup=10\n        scored: true\n\n      - id: 1.2.24\n        text: \"Ensure that the --audit-log-maxsize argument is set to 100 or as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxsize\"\n              compare:\n                op: gte\n                value: 100\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and set the --audit-log-maxsize parameter to an appropriate size in MB.\n          For example, to set it as 100 MB:\n          --audit-log-maxsize=100\n        scored: true\n\n      - id: 1.2.25\n        text: \"Ensure that the --request-timeout argument is set as appropriate (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        type: manual\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          and set the below parameter as appropriate and if needed.\n          For example,\n          --request-timeout=300s\n        scored: false\n\n      - id: 1.2.26\n        text: \"Ensure that the --service-account-lookup argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--service-account-lookup\"\n              set: false\n            - flag: \"--service-account-lookup\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and set the below parameter.\n          --service-account-lookup=true\n          Alternatively, you can delete the --service-account-lookup parameter from this file so\n          that the default takes effect.\n        scored: true\n\n      - id: 1.2.27\n        text: \"Ensure that the --service-account-key-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--service-account-key-file\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and set the --service-account-key-file parameter\n          to the public key file for service accounts:\n          --service-account-key-file=<filename>\n        scored: true\n\n      - id: 1.2.28\n        text: \"Ensure that the --etcd-certfile and --etcd-keyfile arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--etcd-certfile\"\n            - flag: \"--etcd-keyfile\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection between the apiserver and etcd.\n          Then, edit the API server pod specification file $apiserverconf\n          on the master node and set the etcd certificate and key file parameters.\n          --etcd-certfile=<path/to/client-certificate-file>\n          --etcd-keyfile=<path/to/client-key-file>\n        scored: true\n\n      - id: 1.2.29\n        text: \"Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--tls-cert-file\"\n            - flag: \"--tls-private-key-file\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection on the apiserver.\n          Then, edit the API server pod specification file $apiserverconf\n          on the master node and set the TLS certificate and private key file parameters.\n          --tls-cert-file=<path/to/tls-certificate-file>\n          --tls-private-key-file=<path/to/tls-key-file>\n        scored: true\n\n      - id: 1.2.30\n        text: \"Ensure that the --client-ca-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--client-ca-file\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection on the apiserver.\n          Then, edit the API server pod specification file $apiserverconf\n          on the master node and set the client certificate authority file.\n          --client-ca-file=<path/to/client-ca-file>\n        scored: true\n\n      - id: 1.2.31\n        text: \"Ensure that the --etcd-cafile argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--etcd-cafile\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection between the apiserver and etcd.\n          Then, edit the API server pod specification file $apiserverconf\n          on the master node and set the etcd certificate authority file parameter.\n          --etcd-cafile=<path/to/ca-file>\n        scored: true\n\n      - id: 1.2.32\n        text: \"Ensure that the --encryption-provider-config argument is set as appropriate (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--encryption-provider-config\"\n        remediation: |\n          Follow the Kubernetes documentation and configure a EncryptionConfig file.\n          Then, edit the API server pod specification file $apiserverconf\n          on the master node and set the --encryption-provider-config parameter to the path of that file: --encryption-provider-config=</path/to/EncryptionConfig/File>\n        scored: false\n\n      - id: 1.2.33\n        text: \"Ensure that encryption providers are appropriately configured (Manual)\"\n        audit: |\n          ENCRYPTION_PROVIDER_CONFIG=$(ps -ef | grep $apiserverbin | grep -- --encryption-provider-config | sed 's%.*encryption-provider-config[= ]\\([^ ]*\\).*%\\1%')\n          if test -e $ENCRYPTION_PROVIDER_CONFIG; then grep -A1 'providers:' $ENCRYPTION_PROVIDER_CONFIG | tail -n1 | grep -o \"[A-Za-z]*\" | sed 's/^/provider=/'; fi\n        tests:\n          test_items:\n            - flag: \"provider\"\n              compare:\n                op: valid_elements\n                value: \"aescbc,kms,secretbox\"\n        remediation: |\n          Follow the Kubernetes documentation and configure a EncryptionConfig file.\n          In this file, choose aescbc, kms or secretbox as the encryption provider.\n        scored: false\n\n      - id: 1.2.34\n        text: \"Ensure that the API Server only makes use of Strong Cryptographic Ciphers (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--tls-cipher-suites\"\n              compare:\n                op: valid_elements\n                value: \"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\"\n        remediation: |\n          Edit the API server pod specification file /etc/kubernetes/manifests/kube-apiserver.yaml\n          on the master node and set the below parameter.\n          --tls-cipher-suites=TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM\n          _SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM\n          _SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM\n          _SHA384\n        scored: false\n\n  - id: 1.3\n    text: \"Controller Manager\"\n    checks:\n      - id: 1.3.1\n        text: \"Ensure that the --terminated-pod-gc-threshold argument is set as appropriate (Manual)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--terminated-pod-gc-threshold\"\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the master node and set the --terminated-pod-gc-threshold to an appropriate threshold,\n          for example:\n          --terminated-pod-gc-threshold=10\n        scored: false\n\n      - id: 1.3.2\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the master node and set the below parameter.\n          --profiling=false\n        scored: true\n\n      - id: 1.3.3\n        text: \"Ensure that the --use-service-account-credentials argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--use-service-account-credentials\"\n              compare:\n                op: noteq\n                value: false\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the master node to set the below parameter.\n          --use-service-account-credentials=true\n        scored: true\n\n      - id: 1.3.4\n        text: \"Ensure that the --service-account-private-key-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--service-account-private-key-file\"\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the master node and set the --service-account-private-key-file parameter\n          to the private key file for service accounts.\n          --service-account-private-key-file=<filename>\n        scored: true\n\n      - id: 1.3.5\n        text: \"Ensure that the --root-ca-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--root-ca-file\"\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the master node and set the --root-ca-file parameter to the certificate bundle file`.\n          --root-ca-file=<path/to/file>\n        scored: true\n\n      - id: 1.3.6\n        text: \"Ensure that the RotateKubeletServerCertificate argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--feature-gates\"\n              compare:\n                op: nothave\n                value: \"RotateKubeletServerCertificate=false\"\n              set: true\n            - flag: \"--feature-gates\"\n              set: false\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the master node and set the --feature-gates parameter to include RotateKubeletServerCertificate=true.\n          --feature-gates=RotateKubeletServerCertificate=true\n        scored: true\n\n      - id: 1.3.7\n        text: \"Ensure that the --bind-address argument is set to 127.0.0.1 (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--bind-address\"\n              compare:\n                op: eq\n                value: \"127.0.0.1\"\n            - flag: \"--bind-address\"\n              set: false\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the master node and ensure the correct value for the --bind-address parameter\n        scored: true\n\n  - id: 1.4\n    text: \"Scheduler\"\n    checks:\n      - id: 1.4.1\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: \"/bin/ps -ef | grep $schedulerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the Scheduler pod specification file $schedulerconf file\n          on the master node and set the below parameter.\n          --profiling=false\n        scored: true\n\n      - id: 1.4.2\n        text: \"Ensure that the --bind-address argument is set to 127.0.0.1 (Automated)\"\n        audit: \"/bin/ps -ef | grep $schedulerbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--bind-address\"\n              compare:\n                op: eq\n                value: \"127.0.0.1\"\n            - flag: \"--bind-address\"\n              set: false\n        remediation: |\n          Edit the Scheduler pod specification file $schedulerconf\n          on the master node and ensure the correct value for the --bind-address parameter\n        scored: true\n"
  },
  {
    "path": "cfg/cis-1.20/node.yaml",
    "content": "---\ncontrols:\nversion: \"cis-1.20\"\nid: 4\ntext: \"Worker Node Security Configuration\"\ntype: \"node\"\ngroups:\n  - id: 4.1\n    text: \"Worker Node Configuration Files\"\n    checks:\n      - id: 4.1.1\n        text: \"Ensure that the kubelet service file permissions are set to 644 or more restrictive (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletsvc; then stat -c permissions=%a $kubeletsvc; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chmod 644 $kubeletsvc\n        scored: true\n\n      - id: 4.1.2\n        text: \"Ensure that the kubelet service file ownership is set to root:root (Automated)\"\n        audit: '/bin/sh -c \"if test -e $kubeletsvc; then stat -c %U:%G $kubeletsvc; else echo \\\"File not found\\\"; fi\"'\n        tests:\n          bin_op: or\n          test_items:\n            - flag: root:root\n            - flag: \"File not found\"\n        remediation: |\n            Run the below command (based on the file location on your system) on the each worker node.\n            For example,\n            chown root:root $kubeletsvc\n        scored: true\n\n      - id: 4.1.3\n        text: \"If proxy kubeconfig file exists ensure permissions are set to 644 or more restrictive (Manual)\"\n        audit: '/bin/sh -c ''if test -e $proxykubeconfig; then stat -c permissions=%a $proxykubeconfig; fi'' '\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"permissions\"\n              set: true\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chmod 644 $proxykubeconfig\n        scored: false\n\n      - id: 4.1.4\n        text: \"If proxy kubeconfig file exists ensure ownership is set to root:root (Manual)\"\n        audit: '/bin/sh -c ''if test -e $proxykubeconfig; then stat -c %U:%G $proxykubeconfig; fi'' '\n        tests:\n          bin_op: or\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example, chown root:root $proxykubeconfig\n        scored: false\n\n      - id: 4.1.5\n        text: \"Ensure that the --kubeconfig kubelet.conf file permissions are set to 644 or more restrictive (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletkubeconfig; then stat -c permissions=%a $kubeletkubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chmod 644 $kubeletkubeconfig\n        scored: true\n\n      - id: 4.1.6\n        text: \"Ensure that the --kubeconfig kubelet.conf file ownership is set to root:root (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletkubeconfig; then stat -c %U:%G $kubeletkubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chown root:root $kubeletkubeconfig\n        scored: true\n\n      - id: 4.1.7\n        text: \"Ensure that the certificate authorities file permissions are set to 644 or more restrictive (Manual)\"\n        audit: |\n          CAFILE=$(ps -ef | grep kubelet | grep -v apiserver | grep -- --client-ca-file= | awk -F '--client-ca-file=' '{print $2}' | awk '{print $1}' | uniq)\n          if test -z $CAFILE; then CAFILE=$kubeletcafile; fi\n          if test -e $CAFILE; then stat -c permissions=%a $CAFILE; fi\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the following command to modify the file permissions of the\n          --client-ca-file chmod 644 <filename>\n        scored: false\n\n      - id: 4.1.8\n        text: \"Ensure that the client certificate authorities file ownership is set to root:root (Manual)\"\n        audit: |\n          CAFILE=$(ps -ef | grep kubelet | grep -v apiserver | grep -- --client-ca-file= | awk -F '--client-ca-file=' '{print $2}' | awk '{print $1}' | uniq)\n          if test -z $CAFILE; then CAFILE=$kubeletcafile; fi\n          if test -e $CAFILE; then stat -c %U:%G $CAFILE; fi\n        tests:\n          test_items:\n            - flag: root:root\n              compare:\n                op: eq\n                value: root:root\n        remediation: |\n          Run the following command to modify the ownership of the --client-ca-file.\n          chown root:root <filename>\n        scored: false\n\n      - id: 4.1.9\n        text: \"Ensure that the kubelet --config configuration file has permissions set to 644 or more restrictive (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletconf; then stat -c permissions=%a $kubeletconf; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the following command (using the config file location identified in the Audit step)\n          chmod 644 $kubeletconf\n        scored: true\n\n      - id: 4.1.10\n        text: \"Ensure that the kubelet --config configuration file ownership is set to root:root (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletconf; then stat -c %U:%G $kubeletconf; fi'' '\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the following command (using the config file location identified in the Audit step)\n          chown root:root $kubeletconf\n        scored: true\n\n  - id: 4.2\n    text: \"Kubelet\"\n    checks:\n      - id: 4.2.1\n        text: \"Ensure that the anonymous-auth argument is set to false (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: \"--anonymous-auth\"\n              path: '{.authentication.anonymous.enabled}'\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          If using a Kubelet config file, edit the file to set authentication: anonymous: enabled to\n          false.\n          If using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --anonymous-auth=false\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.2\n        text: \"Ensure that the --authorization-mode argument is not set to AlwaysAllow (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --authorization-mode\n              path: '{.authorization.mode}'\n              compare:\n                op: nothave\n                value: AlwaysAllow\n        remediation: |\n          If using a Kubelet config file, edit the file to set authorization: mode to Webhook. If\n          using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_AUTHZ_ARGS variable.\n          --authorization-mode=Webhook\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.3\n        text: \"Ensure that the --client-ca-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --client-ca-file\n              path: '{.authentication.x509.clientCAFile}'\n        remediation: |\n          If using a Kubelet config file, edit the file to set authentication: x509: clientCAFile to\n          the location of the client CA file.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_AUTHZ_ARGS variable.\n          --client-ca-file=<path/to/client-ca-file>\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.4\n        text: \"Ensure that the --read-only-port argument is set to 0 (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--read-only-port\"\n              path: '{.readOnlyPort}'\n              compare:\n                op: eq\n                value: 0\n            - flag: \"--read-only-port\"\n              path: '{.readOnlyPort}'\n              set: false\n        remediation: |\n          If using a Kubelet config file, edit the file to set readOnlyPort to 0.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --read-only-port=0\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.5\n        text: \"Ensure that the --streaming-connection-idle-timeout argument is not set to 0 (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --streaming-connection-idle-timeout\n              path: '{.streamingConnectionIdleTimeout}'\n              compare:\n                op: noteq\n                value: 0\n            - flag: --streaming-connection-idle-timeout\n              path: '{.streamingConnectionIdleTimeout}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to set streamingConnectionIdleTimeout to a\n          value other than 0.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --streaming-connection-idle-timeout=5m\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.6\n        text: \"Ensure that the --protect-kernel-defaults argument is set to true (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --protect-kernel-defaults\n              path: '{.protectKernelDefaults}'\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          If using a Kubelet config file, edit the file to set protectKernelDefaults: true.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --protect-kernel-defaults=true\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.7\n        text: \"Ensure that the --make-iptables-util-chains argument is set to true (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --make-iptables-util-chains\n              path: '{.makeIPTablesUtilChains}'\n              compare:\n                op: eq\n                value: true\n            - flag: --make-iptables-util-chains\n              path: '{.makeIPTablesUtilChains}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to set makeIPTablesUtilChains: true.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          remove the --make-iptables-util-chains argument from the\n          KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.8\n        text: \"Ensure that the --hostname-override argument is not set (Manual)\"\n        # This is one of those properties that can only be set as a command line argument.\n        # To check if the property is set as expected, we need to parse the kubelet command\n        # instead reading the Kubelet Configuration file.\n        audit: \"/bin/ps -fC $kubeletbin \"\n        tests:\n          test_items:\n            - flag: --hostname-override\n              set: false\n        remediation: |\n          Edit the kubelet service file $kubeletsvc\n          on each worker node and remove the --hostname-override argument from the\n          KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.9\n        text: \"Ensure that the --event-qps argument is set to 0 or a level which ensures appropriate event capture (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --event-qps\n              path: '{.eventRecordQPS}'\n              compare:\n                op: eq\n                value: 0\n        remediation: |\n          If using a Kubelet config file, edit the file to set eventRecordQPS: to an appropriate level.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.10\n        text: \"Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --tls-cert-file\n              path: '{.tlsCertFile}'\n            - flag: --tls-private-key-file\n              path: '{.tlsPrivateKeyFile}'\n        remediation: |\n          If using a Kubelet config file, edit the file to set tlsCertFile to the location\n          of the certificate file to use to identify this Kubelet, and tlsPrivateKeyFile\n          to the location of the corresponding private key file.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameters in KUBELET_CERTIFICATE_ARGS variable.\n          --tls-cert-file=<path/to/tls-certificate-file>\n          --tls-private-key-file=<path/to/tls-key-file>\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.11\n        text: \"Ensure that the --rotate-certificates argument is not set to false (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --rotate-certificates\n              path: '{.rotateCertificates}'\n              compare:\n                op: eq\n                value: true\n            - flag: --rotate-certificates\n              path: '{.rotateCertificates}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to add the line rotateCertificates: true or\n          remove it altogether to use the default value.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          remove --rotate-certificates=false argument from the KUBELET_CERTIFICATE_ARGS\n          variable.\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.12\n        text: \"Verify that the RotateKubeletServerCertificate argument is set to true (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: RotateKubeletServerCertificate\n              path: '{.featureGates.RotateKubeletServerCertificate}'\n              compare:\n                op: nothave\n                value: false\n            - flag: RotateKubeletServerCertificate\n              path: '{.featureGates.RotateKubeletServerCertificate}'\n              set: false\n        remediation: |\n          Edit the kubelet service file $kubeletsvc\n          on each worker node and set the below parameter in KUBELET_CERTIFICATE_ARGS variable.\n          --feature-gates=RotateKubeletServerCertificate=true\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.13\n        text: \"Ensure that the Kubelet only makes use of Strong Cryptographic Ciphers (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --tls-cipher-suites\n              path: '{range .tlsCipherSuites[:]}{}{'',''}{end}'\n              compare:\n                op: valid_elements\n                value: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\n        remediation: |\n          If using a Kubelet config file, edit the file to set tlsCipherSuites: to\n          TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\n          or to a subset of these values.\n          If using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the --tls-cipher-suites parameter as follows, or to a subset of these values.\n          --tls-cipher-suites=TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n"
  },
  {
    "path": "cfg/cis-1.20/policies.yaml",
    "content": "---\ncontrols:\nversion: \"cis-1.20\"\nid: 5\ntext: \"Kubernetes Policies\"\ntype: \"policies\"\ngroups:\n  - id: 5.1\n    text: \"RBAC and Service Accounts\"\n    checks:\n      - id: 5.1.1\n        text: \"Ensure that the cluster-admin role is only used where required (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Identify all clusterrolebindings to the cluster-admin role. Check if they are used and\n          if they need this role or if they could use a role with fewer privileges.\n          Where possible, first bind users to a lower privileged role and then remove the\n          clusterrolebinding to the cluster-admin role :\n          kubectl delete clusterrolebinding [name]\n        scored: false\n\n      - id: 5.1.2\n        text: \"Minimize access to secrets (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove get, list and watch access to secret objects in the cluster.\n        scored: false\n\n      - id: 5.1.3\n        text: \"Minimize wildcard use in Roles and ClusterRoles (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible replace any use of wildcards in clusterroles and roles with specific\n          objects or actions.\n        scored: false\n\n      - id: 5.1.4\n        text: \"Minimize access to create pods (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove create access to pod objects in the cluster.\n        scored: false\n\n      - id: 5.1.5\n        text: \"Ensure that default service accounts are not actively used. (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Create explicit service accounts wherever a Kubernetes workload requires specific access\n          to the Kubernetes API server.\n          Modify the configuration of each default service account to include this value\n          automountServiceAccountToken: false\n        scored: false\n\n      - id: 5.1.6\n        text: \"Ensure that Service Account Tokens are only mounted where necessary (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Modify the definition of pods and service accounts which do not need to mount service\n          account tokens to disable it.\n        scored: false\n\n      - id: 5.1.7\n        text: \"Avoid use of system:masters group (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Remove the system:masters group from all users in the cluster.\n        scored: false\n\n      - id: 5.1.8\n        text: \"Limit use of the Bind, Impersonate and Escalate permissions in the Kubernetes cluster (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove the impersonate, bind and escalate rights from subjects.\n        scored: false\n\n  - id: 5.2\n    text: \"Pod Security Policies\"\n    checks:\n      - id: 5.2.1\n        text: \"Minimize the admission of privileged containers (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that\n          the .spec.privileged field is omitted or set to false.\n        scored: false\n\n      - id: 5.2.2\n        text: \"Minimize the admission of containers wishing to share the host process ID namespace (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that the\n          .spec.hostPID field is omitted or set to false.\n        scored: false\n\n      - id: 5.2.3\n        text: \"Minimize the admission of containers wishing to share the host IPC namespace (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that the\n          .spec.hostIPC field is omitted or set to false.\n        scored: false\n\n      - id: 5.2.4\n        text: \"Minimize the admission of containers wishing to share the host network namespace (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that the\n          .spec.hostNetwork field is omitted or set to false.\n        scored: false\n\n      - id: 5.2.5\n        text: \"Minimize the admission of containers with allowPrivilegeEscalation (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that the\n          .spec.allowPrivilegeEscalation field is omitted or set to false.\n        scored: false\n\n      - id: 5.2.6\n        text: \"Minimize the admission of root containers (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that the\n          .spec.runAsUser.rule is set to either MustRunAsNonRoot or MustRunAs with the range of\n          UIDs not including 0.\n        scored: false\n\n      - id: 5.2.7\n        text: \"Minimize the admission of containers with the NET_RAW capability (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that the\n          .spec.requiredDropCapabilities is set to include either NET_RAW or ALL.\n        scored: false\n\n      - id: 5.2.8\n        text: \"Minimize the admission of containers with added capabilities (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that allowedCapabilities is not present in PSPs for the cluster unless\n          it is set to an empty array.\n        scored: false\n\n      - id: 5.2.9\n        text: \"Minimize the admission of containers with capabilities assigned (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Review the use of capabilites in applications running on your cluster. Where a namespace\n          contains applications which do not require any Linux capabities to operate consider adding\n          a PSP which forbids the admission of containers which do not drop all capabilities.\n        scored: false\n\n  - id: 5.3\n    text: \"Network Policies and CNI\"\n    checks:\n      - id: 5.3.1\n        text: \"Ensure that the CNI in use supports Network Policies (Manual)\"\n        type: \"manual\"\n        remediation: |\n          If the CNI plugin in use does not support network policies, consideration should be given to\n          making use of a different plugin, or finding an alternate mechanism for restricting traffic\n          in the Kubernetes cluster.\n        scored: false\n\n      - id: 5.3.2\n        text: \"Ensure that all Namespaces have Network Policies defined (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the documentation and create NetworkPolicy objects as you need them.\n        scored: false\n\n  - id: 5.4\n    text: \"Secrets Management\"\n    checks:\n      - id: 5.4.1\n        text: \"Prefer using secrets as files over secrets as environment variables (Manual)\"\n        type: \"manual\"\n        remediation: |\n          if possible, rewrite application code to read secrets from mounted secret files, rather than\n          from environment variables.\n        scored: false\n\n      - id: 5.4.2\n        text: \"Consider external secret storage (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Refer to the secrets management options offered by your cloud provider or a third-party\n          secrets management solution.\n        scored: false\n\n  - id: 5.5\n    text: \"Extensible Admission Control\"\n    checks:\n      - id: 5.5.1\n        text: \"Configure Image Provenance using ImagePolicyWebhook admission controller (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and setup image provenance.\n        scored: false\n\n  - id: 5.7\n    text: \"General Policies\"\n    checks:\n      - id: 5.7.1\n        text: \"Create administrative boundaries between resources using namespaces (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the documentation and create namespaces for objects in your deployment as you need\n          them.\n        scored: false\n\n      - id: 5.7.2\n        text: \"Ensure that the seccomp profile is set to docker/default in your pod definitions (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Use security context to enable the docker/default seccomp profile in your pod definitions.\n          An example is as below:\n            securityContext:\n              seccompProfile:\n                type: RuntimeDefault\n        scored: false\n\n      - id: 5.7.3\n        text: \"Apply Security Context to Your Pods and Containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and apply security contexts to your pods. For a\n          suggested list of security contexts, you may refer to the CIS Security Benchmark for Docker\n          Containers.\n        scored: false\n\n      - id: 5.7.4\n        text: \"The default namespace should not be used (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that namespaces are created to allow for appropriate segregation of Kubernetes\n          resources and that all new resources are created in a specific namespace.\n        scored: false\n"
  },
  {
    "path": "cfg/cis-1.23/config.yaml",
    "content": "---\n## Version-specific settings that override the values in cfg/config.yaml\n"
  },
  {
    "path": "cfg/cis-1.23/controlplane.yaml",
    "content": "---\ncontrols:\nversion: \"cis-1.23\"\nid: 3\ntext: \"Control Plane Configuration\"\ntype: \"controlplane\"\ngroups:\n  - id: 3.1\n    text: \"Authentication and Authorization\"\n    checks:\n      - id: 3.1.1\n        text: \"Client certificate authentication should not be used for users (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Alternative mechanisms provided by Kubernetes such as the use of OIDC should be\n          implemented in place of client certificates.\n        scored: false\n\n  - id: 3.2\n    text: \"Logging\"\n    checks:\n      - id: 3.2.1\n        text: \"Ensure that a minimal audit policy is created (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-policy-file\"\n              set: true\n        remediation: |\n          Create an audit policy file for your cluster.\n        scored: false\n\n      - id: 3.2.2\n        text: \"Ensure that the audit policy covers key security concerns (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Review the audit policy provided for the cluster and ensure that it covers\n          at least the following areas,\n          - Access to Secrets managed by the cluster. Care should be taken to only\n            log Metadata for requests to Secrets, ConfigMaps, and TokenReviews, in\n            order to avoid risk of logging sensitive data.\n          - Modification of Pod and Deployment objects.\n          - Use of `pods/exec`, `pods/portforward`, `pods/proxy` and `services/proxy`.\n          For most requests, minimally logging at the Metadata level is recommended\n          (the most basic level of logging).\n        scored: false\n"
  },
  {
    "path": "cfg/cis-1.23/etcd.yaml",
    "content": "---\ncontrols:\nversion: \"cis-1.23\"\nid: 2\ntext: \"Etcd Node Configuration\"\ntype: \"etcd\"\ngroups:\n  - id: 2\n    text: \"Etcd Node Configuration\"\n    checks:\n      - id: 2.1\n        text: \"Ensure that the --cert-file and --key-file arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--cert-file\"\n              env: \"ETCD_CERT_FILE\"\n            - flag: \"--key-file\"\n              env: \"ETCD_KEY_FILE\"\n        remediation: |\n          Follow the etcd service documentation and configure TLS encryption.\n          Then, edit the etcd pod specification file /etc/kubernetes/manifests/etcd.yaml\n          on the master node and set the below parameters.\n          --cert-file=</path/to/ca-file>\n          --key-file=</path/to/key-file>\n        scored: true\n\n      - id: 2.2\n        text: \"Ensure that the --client-cert-auth argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--client-cert-auth\"\n              env: \"ETCD_CLIENT_CERT_AUTH\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and set the below parameter.\n          --client-cert-auth=\"true\"\n        scored: true\n\n      - id: 2.3\n        text: \"Ensure that the --auto-tls argument is not set to true (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--auto-tls\"\n              env: \"ETCD_AUTO_TLS\"\n              set: false\n            - flag: \"--auto-tls\"\n              env: \"ETCD_AUTO_TLS\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and either remove the --auto-tls parameter or set it to false.\n            --auto-tls=false\n        scored: true\n\n      - id: 2.4\n        text: \"Ensure that the --peer-cert-file and --peer-key-file arguments are\n        set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--peer-cert-file\"\n              env: \"ETCD_PEER_CERT_FILE\"\n            - flag: \"--peer-key-file\"\n              env: \"ETCD_PEER_KEY_FILE\"\n        remediation: |\n          Follow the etcd service documentation and configure peer TLS encryption as appropriate\n          for your etcd cluster.\n          Then, edit the etcd pod specification file $etcdconf on the\n          master node and set the below parameters.\n          --peer-client-file=</path/to/peer-cert-file>\n          --peer-key-file=</path/to/peer-key-file>\n        scored: true\n\n      - id: 2.5\n        text: \"Ensure that the --peer-client-cert-auth argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--peer-client-cert-auth\"\n              env: \"ETCD_PEER_CLIENT_CERT_AUTH\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and set the below parameter.\n          --peer-client-cert-auth=true\n        scored: true\n\n      - id: 2.6\n        text: \"Ensure that the --peer-auto-tls argument is not set to true (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--peer-auto-tls\"\n              env: \"ETCD_PEER_AUTO_TLS\"\n              set: false\n            - flag: \"--peer-auto-tls\"\n              env: \"ETCD_PEER_AUTO_TLS\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and either remove the --peer-auto-tls parameter or set it to false.\n          --peer-auto-tls=false\n        scored: true\n\n      - id: 2.7\n        text: \"Ensure that a unique Certificate Authority is used for etcd (Manual)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--trusted-ca-file\"\n              env: \"ETCD_TRUSTED_CA_FILE\"\n        remediation: |\n          [Manual test]\n          Follow the etcd documentation and create a dedicated certificate authority setup for the\n          etcd service.\n          Then, edit the etcd pod specification file $etcdconf on the\n          master node and set the below parameter.\n          --trusted-ca-file=</path/to/ca-file>\n        scored: false\n"
  },
  {
    "path": "cfg/cis-1.23/master.yaml",
    "content": "---\ncontrols:\nversion: \"cis-1.23\"\nid: 1\ntext: \"Control Plane Security Configuration\"\ntype: \"master\"\ngroups:\n  - id: 1.1\n    text: \"Control Plane Node Configuration Files\"\n    checks:\n      - id: 1.1.1\n        text: \"Ensure that the API server pod specification file permissions are set to 644 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $apiserverconf; then stat -c permissions=%a $apiserverconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the\n          control plane node.\n          For example, chmod 644 $apiserverconf\n        scored: true\n\n      - id: 1.1.2\n        text: \"Ensure that the API server pod specification file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $apiserverconf; then stat -c %U:%G $apiserverconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chown root:root $apiserverconf\n        scored: true\n\n      - id: 1.1.3\n        text: \"Ensure that the controller manager pod specification file permissions are set to 644 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerconf; then stat -c permissions=%a $controllermanagerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chmod 644 $controllermanagerconf\n        scored: true\n\n      - id: 1.1.4\n        text: \"Ensure that the controller manager pod specification file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerconf; then stat -c %U:%G $controllermanagerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chown root:root $controllermanagerconf\n        scored: true\n\n      - id: 1.1.5\n        text: \"Ensure that the scheduler pod specification file permissions are set to 644 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerconf; then stat -c permissions=%a $schedulerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chmod 644 $schedulerconf\n        scored: true\n\n      - id: 1.1.6\n        text: \"Ensure that the scheduler pod specification file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerconf; then stat -c %U:%G $schedulerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chown root:root $schedulerconf\n        scored: true\n\n      - id: 1.1.7\n        text: \"Ensure that the etcd pod specification file permissions are set to 644 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $etcdconf; then find $etcdconf -name '*etcd*' | xargs stat -c permissions=%a; fi'\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod 644 $etcdconf\n        scored: true\n\n      - id: 1.1.8\n        text: \"Ensure that the etcd pod specification file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $etcdconf; then find $etcdconf -name '*etcd*' | xargs stat -c %U:%G; fi'\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root $etcdconf\n        scored: true\n\n      - id: 1.1.9\n        text: \"Ensure that the Container Network Interface file permissions are set to 644 or more restrictive (Manual)\"\n        audit: |\n          ps -ef | grep $kubeletbin | grep -- --cni-conf-dir | sed 's%.*cni-conf-dir[= ]\\([^ ]*\\).*%\\1%' | xargs -I{} find {} -mindepth 1 | xargs --no-run-if-empty stat -c permissions=%a\n          find /var/lib/cni/networks -type f 2> /dev/null | xargs --no-run-if-empty stat -c permissions=%a\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chmod 644 <path/to/cni/files>\n        scored: false\n\n      - id: 1.1.10\n        text: \"Ensure that the Container Network Interface file ownership is set to root:root (Manual)\"\n        audit: |\n          ps -ef | grep $kubeletbin | grep -- --cni-conf-dir | sed 's%.*cni-conf-dir[= ]\\([^ ]*\\).*%\\1%' | xargs -I{} find {} -mindepth 1 | xargs --no-run-if-empty stat -c %U:%G\n          find /var/lib/cni/networks -type f 2> /dev/null | xargs --no-run-if-empty stat -c %U:%G\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root <path/to/cni/files>\n        scored: false\n\n      - id: 1.1.11\n        text: \"Ensure that the etcd data directory permissions are set to 700 or more restrictive (Automated)\"\n        audit: |\n          DATA_DIR=''\n          for d in $(ps -ef | grep $etcdbin | grep -- --data-dir | sed 's%.*data-dir[= ]\\([^ ]*\\).*%\\1%'); do\n            if test -d \"$d\"; then DATA_DIR=\"$d\"; fi\n          done\n          if ! test -d \"$DATA_DIR\"; then DATA_DIR=$etcddatadir; fi\n          stat -c permissions=%a \"$DATA_DIR\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"700\"\n        remediation: |\n          On the etcd server node, get the etcd data directory, passed as an argument --data-dir,\n          from the command 'ps -ef | grep etcd'.\n          Run the below command (based on the etcd data directory found above). For example,\n          chmod 700 /var/lib/etcd\n        scored: true\n\n      - id: 1.1.12\n        text: \"Ensure that the etcd data directory ownership is set to etcd:etcd (Automated)\"\n        audit: |\n          DATA_DIR=''\n          for d in $(ps -ef | grep $etcdbin | grep -- --data-dir | sed 's%.*data-dir[= ]\\([^ ]*\\).*%\\1%'); do\n            if test -d \"$d\"; then DATA_DIR=\"$d\"; fi\n          done\n          if ! test -d \"$DATA_DIR\"; then DATA_DIR=$etcddatadir; fi\n          stat -c %U:%G \"$DATA_DIR\"\n        tests:\n          test_items:\n            - flag: \"etcd:etcd\"\n        remediation: |\n          On the etcd server node, get the etcd data directory, passed as an argument --data-dir,\n          from the command 'ps -ef | grep etcd'.\n          Run the below command (based on the etcd data directory found above).\n          For example, chown etcd:etcd /var/lib/etcd\n        scored: true\n\n      - id: 1.1.13\n        text: \"Ensure that the admin.conf file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e /etc/kubernetes/admin.conf; then stat -c permissions=%a /etc/kubernetes/admin.conf; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chmod 600 /etc/kubernetes/admin.conf\n        scored: true\n\n      - id: 1.1.14\n        text: \"Ensure that the admin.conf file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e /etc/kubernetes/admin.conf; then stat -c %U:%G /etc/kubernetes/admin.conf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chown root:root /etc/kubernetes/admin.conf\n        scored: true\n\n      - id: 1.1.15\n        text: \"Ensure that the scheduler.conf file permissions are set to 644 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerkubeconfig; then stat -c permissions=%a $schedulerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod 644 $schedulerkubeconfig\n        scored: true\n\n      - id: 1.1.16\n        text: \"Ensure that the scheduler.conf file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerkubeconfig; then stat -c %U:%G $schedulerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root $schedulerkubeconfig\n        scored: true\n\n      - id: 1.1.17\n        text: \"Ensure that the controller-manager.conf file permissions are set to 644 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerkubeconfig; then stat -c permissions=%a $controllermanagerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod 644 $controllermanagerkubeconfig\n        scored: true\n\n      - id: 1.1.18\n        text: \"Ensure that the controller-manager.conf file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerkubeconfig; then stat -c %U:%G $controllermanagerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root $controllermanagerkubeconfig\n        scored: true\n\n      - id: 1.1.19\n        text: \"Ensure that the Kubernetes PKI directory and file ownership is set to root:root (Automated)\"\n        audit: \"find /etc/kubernetes/pki/ | xargs stat -c %U:%G\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown -R root:root /etc/kubernetes/pki/\n        scored: true\n\n      - id: 1.1.20\n        text: \"Ensure that the Kubernetes PKI certificate file permissions are set to 644 or more restrictive (Manual)\"\n        audit: \"find /etc/kubernetes/pki/ -name '*.crt' | xargs stat -c permissions=%a\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod -R 644 /etc/kubernetes/pki/*.crt\n        scored: false\n\n      - id: 1.1.21\n        text: \"Ensure that the Kubernetes PKI key file permissions are set to 600 (Manual)\"\n        audit: \"find /etc/kubernetes/pki/ -name '*.key' | xargs stat -c permissions=%a\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod -R 600 /etc/kubernetes/pki/*.key\n        scored: false\n\n  - id: 1.2\n    text: \"API Server\"\n    checks:\n      - id: 1.2.1\n        text: \"Ensure that the --anonymous-auth argument is set to false (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--anonymous-auth\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the below parameter.\n          --anonymous-auth=false\n        scored: false\n\n      - id: 1.2.2\n        text: \"Ensure that the --token-auth-file parameter is not set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--token-auth-file\"\n              set: false\n        remediation: |\n          Follow the documentation and configure alternate mechanisms for authentication. Then,\n          edit the API server pod specification file $apiserverconf\n          on the control plane node and remove the --token-auth-file=<filename> parameter.\n        scored: true\n\n      - id: 1.2.3\n        text: \"Ensure that the --DenyServiceExternalIPs is not set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: nothave\n                value: \"DenyServiceExternalIPs\"\n            - flag: \"--enable-admission-plugins\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and remove the `DenyServiceExternalIPs`\n          from enabled admission plugins.\n        scored: true\n\n      - id: 1.2.4\n        text: \"Ensure that the --kubelet-https argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--kubelet-https\"\n              compare:\n                op: eq\n                value: true\n            - flag: \"--kubelet-https\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and remove the --kubelet-https parameter.\n        scored: true\n\n      - id: 1.2.5\n        text: \"Ensure that the --kubelet-client-certificate and --kubelet-client-key arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--kubelet-client-certificate\"\n            - flag: \"--kubelet-client-key\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection between the\n          apiserver and kubelets. Then, edit API server pod specification file\n          $apiserverconf on the control plane node and set the\n          kubelet client certificate and key parameters as below.\n          --kubelet-client-certificate=<path/to/client-certificate-file>\n          --kubelet-client-key=<path/to/client-key-file>\n        scored: true\n\n      - id: 1.2.6\n        text: \"Ensure that the --kubelet-certificate-authority argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--kubelet-certificate-authority\"\n        remediation: |\n          Follow the Kubernetes documentation and setup the TLS connection between\n          the apiserver and kubelets. Then, edit the API server pod specification file\n          $apiserverconf on the control plane node and set the\n          --kubelet-certificate-authority parameter to the path to the cert file for the certificate authority.\n          --kubelet-certificate-authority=<ca-string>\n        scored: true\n\n      - id: 1.2.7\n        text: \"Ensure that the --authorization-mode argument is not set to AlwaysAllow (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: nothave\n                value: \"AlwaysAllow\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --authorization-mode parameter to values other than AlwaysAllow.\n          One such example could be as below.\n          --authorization-mode=RBAC\n        scored: true\n\n      - id: 1.2.8\n        text: \"Ensure that the --authorization-mode argument includes Node (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: has\n                value: \"Node\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --authorization-mode parameter to a value that includes Node.\n          --authorization-mode=Node,RBAC\n        scored: true\n\n      - id: 1.2.9\n        text: \"Ensure that the --authorization-mode argument includes RBAC (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: has\n                value: \"RBAC\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --authorization-mode parameter to a value that includes RBAC,\n          for example `--authorization-mode=Node,RBAC`.\n        scored: true\n\n      - id: 1.2.10\n        text: \"Ensure that the admission control plugin EventRateLimit is set (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"EventRateLimit\"\n        remediation: |\n          Follow the Kubernetes documentation and set the desired limits in a configuration file.\n          Then, edit the API server pod specification file $apiserverconf\n          and set the below parameters.\n          --enable-admission-plugins=...,EventRateLimit,...\n          --admission-control-config-file=<path/to/configuration/file>\n        scored: false\n\n      - id: 1.2.11\n        text: \"Ensure that the admission control plugin AlwaysAdmit is not set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: nothave\n                value: AlwaysAdmit\n            - flag: \"--enable-admission-plugins\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and either remove the --enable-admission-plugins parameter, or set it to a\n          value that does not include AlwaysAdmit.\n        scored: true\n\n      - id: 1.2.12\n        text: \"Ensure that the admission control plugin AlwaysPullImages is set (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"AlwaysPullImages\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --enable-admission-plugins parameter to include\n          AlwaysPullImages.\n          --enable-admission-plugins=...,AlwaysPullImages,...\n        scored: false\n\n      - id: 1.2.13\n        text: \"Ensure that the admission control plugin SecurityContextDeny is set if PodSecurityPolicy is not used (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"SecurityContextDeny\"\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"PodSecurityPolicy\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --enable-admission-plugins parameter to include\n          SecurityContextDeny, unless PodSecurityPolicy is already in place.\n          --enable-admission-plugins=...,SecurityContextDeny,...\n        scored: false\n\n      - id: 1.2.14\n        text: \"Ensure that the admission control plugin ServiceAccount is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--disable-admission-plugins\"\n              compare:\n                op: nothave\n                value: \"ServiceAccount\"\n            - flag: \"--disable-admission-plugins\"\n              set: false\n        remediation: |\n          Follow the documentation and create ServiceAccount objects as per your environment.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and ensure that the --disable-admission-plugins parameter is set to a\n          value that does not include ServiceAccount.\n        scored: true\n\n      - id: 1.2.15\n        text: \"Ensure that the admission control plugin NamespaceLifecycle is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--disable-admission-plugins\"\n              compare:\n                op: nothave\n                value: \"NamespaceLifecycle\"\n            - flag: \"--disable-admission-plugins\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --disable-admission-plugins parameter to\n          ensure it does not include NamespaceLifecycle.\n        scored: true\n\n      - id: 1.2.16\n        text: \"Ensure that the admission control plugin NodeRestriction is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"NodeRestriction\"\n        remediation: |\n          Follow the Kubernetes documentation and configure NodeRestriction plug-in on kubelets.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --enable-admission-plugins parameter to a\n          value that includes NodeRestriction.\n          --enable-admission-plugins=...,NodeRestriction,...\n        scored: true\n\n      - id: 1.2.17\n        text: \"Ensure that the --secure-port argument is not set to 0 (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--secure-port\"\n              compare:\n                op: gt\n                value: 0\n            - flag: \"--secure-port\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and either remove the --secure-port parameter or\n          set it to a different (non-zero) desired port.\n        scored: true\n\n      - id: 1.2.18\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the below parameter.\n          --profiling=false\n        scored: true\n\n      - id: 1.2.19\n        text: \"Ensure that the --audit-log-path argument is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-path\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --audit-log-path parameter to a suitable path and\n          file where you would like audit logs to be written, for example,\n          --audit-log-path=/var/log/apiserver/audit.log\n        scored: true\n\n      - id: 1.2.20\n        text: \"Ensure that the --audit-log-maxage argument is set to 30 or as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxage\"\n              compare:\n                op: gte\n                value: 30\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --audit-log-maxage parameter to 30\n          or as an appropriate number of days, for example,\n          --audit-log-maxage=30\n        scored: true\n\n      - id: 1.2.21\n        text: \"Ensure that the --audit-log-maxbackup argument is set to 10 or as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxbackup\"\n              compare:\n                op: gte\n                value: 10\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --audit-log-maxbackup parameter to 10 or to an appropriate\n          value. For example,\n          --audit-log-maxbackup=10\n        scored: true\n\n      - id: 1.2.22\n        text: \"Ensure that the --audit-log-maxsize argument is set to 100 or as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxsize\"\n              compare:\n                op: gte\n                value: 100\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --audit-log-maxsize parameter to an appropriate size in MB.\n          For example, to set it as 100 MB, --audit-log-maxsize=100\n        scored: true\n\n      - id: 1.2.23\n        text: \"Ensure that the --request-timeout argument is set as appropriate (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        type: manual\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          and set the below parameter as appropriate and if needed.\n          For example, --request-timeout=300s\n        scored: false\n\n      - id: 1.2.24\n        text: \"Ensure that the --service-account-lookup argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--service-account-lookup\"\n              set: false\n            - flag: \"--service-account-lookup\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the below parameter.\n          --service-account-lookup=true\n          Alternatively, you can delete the --service-account-lookup parameter from this file so\n          that the default takes effect.\n        scored: true\n\n      - id: 1.2.25\n        text: \"Ensure that the --service-account-key-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--service-account-key-file\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --service-account-key-file parameter\n          to the public key file for service accounts. For example,\n          --service-account-key-file=<filename>\n        scored: true\n\n      - id: 1.2.26\n        text: \"Ensure that the --etcd-certfile and --etcd-keyfile arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--etcd-certfile\"\n            - flag: \"--etcd-keyfile\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection between the apiserver and etcd.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the etcd certificate and key file parameters.\n          --etcd-certfile=<path/to/client-certificate-file>\n          --etcd-keyfile=<path/to/client-key-file>\n        scored: true\n\n      - id: 1.2.27\n        text: \"Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--tls-cert-file\"\n            - flag: \"--tls-private-key-file\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection on the apiserver.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the TLS certificate and private key file parameters.\n          --tls-cert-file=<path/to/tls-certificate-file>\n          --tls-private-key-file=<path/to/tls-key-file>\n        scored: true\n\n      - id: 1.2.28\n        text: \"Ensure that the --client-ca-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--client-ca-file\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection on the apiserver.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the client certificate authority file.\n          --client-ca-file=<path/to/client-ca-file>\n        scored: true\n\n      - id: 1.2.29\n        text: \"Ensure that the --etcd-cafile argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--etcd-cafile\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection between the apiserver and etcd.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the etcd certificate authority file parameter.\n          --etcd-cafile=<path/to/ca-file>\n        scored: true\n\n      - id: 1.2.30\n        text: \"Ensure that the --encryption-provider-config argument is set as appropriate (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--encryption-provider-config\"\n        remediation: |\n          Follow the Kubernetes documentation and configure a EncryptionConfig file.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --encryption-provider-config parameter to the path of that file.\n          For example, --encryption-provider-config=</path/to/EncryptionConfig/File>\n        scored: false\n\n      - id: 1.2.31\n        text: \"Ensure that encryption providers are appropriately configured (Manual)\"\n        audit: |\n          ENCRYPTION_PROVIDER_CONFIG=$(ps -ef | grep $apiserverbin | grep -- --encryption-provider-config | sed 's%.*encryption-provider-config[= ]\\([^ ]*\\).*%\\1%')\n          if test -e $ENCRYPTION_PROVIDER_CONFIG; then grep -A1 'providers:' $ENCRYPTION_PROVIDER_CONFIG | tail -n1 | grep -o \"[A-Za-z]*\" | sed 's/^/provider=/'; fi\n        tests:\n          test_items:\n            - flag: \"provider\"\n              compare:\n                op: valid_elements\n                value: \"aescbc,kms,secretbox\"\n        remediation: |\n          Follow the Kubernetes documentation and configure a EncryptionConfig file.\n          In this file, choose aescbc, kms or secretbox as the encryption provider.\n        scored: false\n\n      - id: 1.2.32\n        text: \"Ensure that the API Server only makes use of Strong Cryptographic Ciphers (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--tls-cipher-suites\"\n              compare:\n                op: valid_elements\n                value: \"TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,TLS_CHACHA20_POLY1305_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,TLS_RSA_WITH_3DES_EDE_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_256_GCM_SHA384\"\n        remediation: |\n          Edit the API server pod specification file /etc/kubernetes/manifests/kube-apiserver.yaml\n          on the control plane node and set the below parameter.\n          --tls-cipher-suites=TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,TLS_CHACHA20_POLY1305_SHA256,\n          TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,\n          TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,\n          TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,\n          TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,\n          TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,\n          TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,TLS_RSA_WITH_3DES_EDE_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA,\n          TLS_RSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_256_GCM_SHA384\n        scored: false\n\n  - id: 1.3\n    text: \"Controller Manager\"\n    checks:\n      - id: 1.3.1\n        text: \"Ensure that the --terminated-pod-gc-threshold argument is set as appropriate (Manual)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--terminated-pod-gc-threshold\"\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the --terminated-pod-gc-threshold to an appropriate threshold,\n          for example, --terminated-pod-gc-threshold=10\n        scored: false\n\n      - id: 1.3.2\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the below parameter.\n          --profiling=false\n        scored: true\n\n      - id: 1.3.3\n        text: \"Ensure that the --use-service-account-credentials argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--use-service-account-credentials\"\n              compare:\n                op: noteq\n                value: false\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node to set the below parameter.\n          --use-service-account-credentials=true\n        scored: true\n\n      - id: 1.3.4\n        text: \"Ensure that the --service-account-private-key-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--service-account-private-key-file\"\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the --service-account-private-key-file parameter\n          to the private key file for service accounts.\n          --service-account-private-key-file=<filename>\n        scored: true\n\n      - id: 1.3.5\n        text: \"Ensure that the --root-ca-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--root-ca-file\"\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the --root-ca-file parameter to the certificate bundle file`.\n          --root-ca-file=<path/to/file>\n        scored: true\n\n      - id: 1.3.6\n        text: \"Ensure that the RotateKubeletServerCertificate argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--feature-gates\"\n              compare:\n                op: nothave\n                value: \"RotateKubeletServerCertificate=false\"\n              set: true\n            - flag: \"--feature-gates\"\n              set: false\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the --feature-gates parameter to include RotateKubeletServerCertificate=true.\n          --feature-gates=RotateKubeletServerCertificate=true\n        scored: true\n\n      - id: 1.3.7\n        text: \"Ensure that the --bind-address argument is set to 127.0.0.1 (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--bind-address\"\n              compare:\n                op: eq\n                value: \"127.0.0.1\"\n            - flag: \"--bind-address\"\n              set: false\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and ensure the correct value for the --bind-address parameter\n        scored: true\n\n  - id: 1.4\n    text: \"Scheduler\"\n    checks:\n      - id: 1.4.1\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: \"/bin/ps -ef | grep $schedulerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the Scheduler pod specification file $schedulerconf file\n          on the control plane node and set the below parameter.\n          --profiling=false\n        scored: true\n\n      - id: 1.4.2\n        text: \"Ensure that the --bind-address argument is set to 127.0.0.1 (Automated)\"\n        audit: \"/bin/ps -ef | grep $schedulerbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--bind-address\"\n              compare:\n                op: eq\n                value: \"127.0.0.1\"\n            - flag: \"--bind-address\"\n              set: false\n        remediation: |\n          Edit the Scheduler pod specification file $schedulerconf\n          on the control plane node and ensure the correct value for the --bind-address parameter\n        scored: true\n"
  },
  {
    "path": "cfg/cis-1.23/node.yaml",
    "content": "---\ncontrols:\nversion: \"cis-1.23\"\nid: 4\ntext: \"Worker Node Security Configuration\"\ntype: \"node\"\ngroups:\n  - id: 4.1\n    text: \"Worker Node Configuration Files\"\n    checks:\n      - id: 4.1.1\n        text: \"Ensure that the kubelet service file permissions are set to 644 or more restrictive (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletsvc; then stat -c permissions=%a $kubeletsvc; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example, chmod 644 $kubeletsvc\n        scored: true\n\n      - id: 4.1.2\n        text: \"Ensure that the kubelet service file ownership is set to root:root (Automated)\"\n        audit: '/bin/sh -c \"if test -e $kubeletsvc; then stat -c %U:%G $kubeletsvc; else echo \\\"File not found\\\"; fi\"'\n        tests:\n          bin_op: or\n          test_items:\n            - flag: root:root\n            - flag: \"File not found\"\n        remediation: |\n            Run the below command (based on the file location on your system) on the each worker node.\n            For example,\n            chown root:root $kubeletsvc\n        scored: true\n\n      - id: 4.1.3\n        text: \"If proxy kubeconfig file exists ensure permissions are set to 644 or more restrictive (Manual)\"\n        audit: '/bin/sh -c ''if test -e $proxykubeconfig; then stat -c permissions=%a $proxykubeconfig; fi'' '\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"permissions\"\n              set: true\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chmod 644 $proxykubeconfig\n        scored: false\n\n      - id: 4.1.4\n        text: \"If proxy kubeconfig file exists ensure ownership is set to root:root (Manual)\"\n        audit: '/bin/sh -c ''if test -e $proxykubeconfig; then stat -c %U:%G $proxykubeconfig; fi'' '\n        tests:\n          bin_op: or\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example, chown root:root $proxykubeconfig\n        scored: false\n\n      - id: 4.1.5\n        text: \"Ensure that the --kubeconfig kubelet.conf file permissions are set to 644 or more restrictive (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletkubeconfig; then stat -c permissions=%a $kubeletkubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chmod 644 $kubeletkubeconfig\n        scored: true\n\n      - id: 4.1.6\n        text: \"Ensure that the --kubeconfig kubelet.conf file ownership is set to root:root (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletkubeconfig; then stat -c %U:%G $kubeletkubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chown root:root $kubeletkubeconfig\n        scored: true\n\n      - id: 4.1.7\n        text: \"Ensure that the certificate authorities file permissions are set to 644 or more restrictive (Manual)\"\n        audit: |\n          CAFILE=$(ps -ef | grep kubelet | grep -v apiserver | grep -- --client-ca-file= | awk -F '--client-ca-file=' '{print $2}' | awk '{print $1}' | uniq)\n          if test -z $CAFILE; then CAFILE=$kubeletcafile; fi\n          if test -e $CAFILE; then stat -c permissions=%a $CAFILE; fi\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the following command to modify the file permissions of the\n          --client-ca-file chmod 644 <filename>\n        scored: false\n\n      - id: 4.1.8\n        text: \"Ensure that the client certificate authorities file ownership is set to root:root (Manual)\"\n        audit: |\n          CAFILE=$(ps -ef | grep kubelet | grep -v apiserver | grep -- --client-ca-file= | awk -F '--client-ca-file=' '{print $2}' | awk '{print $1}' | uniq)\n          if test -z $CAFILE; then CAFILE=$kubeletcafile; fi\n          if test -e $CAFILE; then stat -c %U:%G $CAFILE; fi\n        tests:\n          test_items:\n            - flag: root:root\n              compare:\n                op: eq\n                value: root:root\n        remediation: |\n          Run the following command to modify the ownership of the --client-ca-file.\n          chown root:root <filename>\n        scored: false\n\n      - id: 4.1.9\n        text: \"Ensure that the kubelet --config configuration file has permissions set to 644 or more restrictive (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletconf; then stat -c permissions=%a $kubeletconf; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the following command (using the config file location identified in the Audit step)\n          chmod 644 $kubeletconf\n        scored: true\n\n      - id: 4.1.10\n        text: \"Ensure that the kubelet --config configuration file ownership is set to root:root (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletconf; then stat -c %U:%G $kubeletconf; fi'' '\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the following command (using the config file location identified in the Audit step)\n          chown root:root $kubeletconf\n        scored: true\n\n  - id: 4.2\n    text: \"Kubelet\"\n    checks:\n      - id: 4.2.1\n        text: \"Ensure that the --anonymous-auth argument is set to false (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: \"--anonymous-auth\"\n              path: '{.authentication.anonymous.enabled}'\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          If using a Kubelet config file, edit the file to set `authentication: anonymous: enabled` to\n          `false`.\n          If using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          `--anonymous-auth=false`\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.2\n        text: \"Ensure that the --authorization-mode argument is not set to AlwaysAllow (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --authorization-mode\n              path: '{.authorization.mode}'\n              compare:\n                op: nothave\n                value: AlwaysAllow\n        remediation: |\n          If using a Kubelet config file, edit the file to set `authorization.mode` to Webhook. If\n          using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_AUTHZ_ARGS variable.\n          --authorization-mode=Webhook\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.3\n        text: \"Ensure that the --client-ca-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --client-ca-file\n              path: '{.authentication.x509.clientCAFile}'\n        remediation: |\n          If using a Kubelet config file, edit the file to set `authentication.x509.clientCAFile` to\n          the location of the client CA file.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_AUTHZ_ARGS variable.\n          --client-ca-file=<path/to/client-ca-file>\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.4\n        text: \"Ensure that the --read-only-port argument is set to 0 (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--read-only-port\"\n              path: '{.readOnlyPort}'\n              compare:\n                op: eq\n                value: 0\n            - flag: \"--read-only-port\"\n              path: '{.readOnlyPort}'\n              set: false\n        remediation: |\n          If using a Kubelet config file, edit the file to set `readOnlyPort` to 0.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --read-only-port=0\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.5\n        text: \"Ensure that the --streaming-connection-idle-timeout argument is not set to 0 (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --streaming-connection-idle-timeout\n              path: '{.streamingConnectionIdleTimeout}'\n              compare:\n                op: noteq\n                value: 0\n            - flag: --streaming-connection-idle-timeout\n              path: '{.streamingConnectionIdleTimeout}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to set `streamingConnectionIdleTimeout` to a\n          value other than 0.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --streaming-connection-idle-timeout=5m\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.6\n        text: \"Ensure that the --protect-kernel-defaults argument is set to true (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --protect-kernel-defaults\n              path: '{.protectKernelDefaults}'\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          If using a Kubelet config file, edit the file to set `protectKernelDefaults` to `true`.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --protect-kernel-defaults=true\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.7\n        text: \"Ensure that the --make-iptables-util-chains argument is set to true (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --make-iptables-util-chains\n              path: '{.makeIPTablesUtilChains}'\n              compare:\n                op: eq\n                value: true\n            - flag: --make-iptables-util-chains\n              path: '{.makeIPTablesUtilChains}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to set `makeIPTablesUtilChains` to `true`.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          remove the --make-iptables-util-chains argument from the\n          KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.8\n        text: \"Ensure that the --hostname-override argument is not set (Manual)\"\n        # This is one of those properties that can only be set as a command line argument.\n        # To check if the property is set as expected, we need to parse the kubelet command\n        # instead reading the Kubelet Configuration file.\n        audit: \"/bin/ps -fC $kubeletbin \"\n        tests:\n          test_items:\n            - flag: --hostname-override\n              set: false\n        remediation: |\n          Edit the kubelet service file $kubeletsvc\n          on each worker node and remove the --hostname-override argument from the\n          KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.9\n        text: \"Ensure that the --event-qps argument is set to 0 or a level which ensures appropriate event capture (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --event-qps\n              path: '{.eventRecordQPS}'\n              compare:\n                op: eq\n                value: 0\n        remediation: |\n          If using a Kubelet config file, edit the file to set `eventRecordQPS` to an appropriate level.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.10\n        text: \"Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --tls-cert-file\n              path: '{.tlsCertFile}'\n            - flag: --tls-private-key-file\n              path: '{.tlsPrivateKeyFile}'\n        remediation: |\n          If using a Kubelet config file, edit the file to set `tlsCertFile` to the location\n          of the certificate file to use to identify this Kubelet, and `tlsPrivateKeyFile`\n          to the location of the corresponding private key file.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameters in KUBELET_CERTIFICATE_ARGS variable.\n          --tls-cert-file=<path/to/tls-certificate-file>\n          --tls-private-key-file=<path/to/tls-key-file>\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.11\n        text: \"Ensure that the --rotate-certificates argument is not set to false (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --rotate-certificates\n              path: '{.rotateCertificates}'\n              compare:\n                op: eq\n                value: true\n            - flag: --rotate-certificates\n              path: '{.rotateCertificates}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to add the line `rotateCertificates` to `true` or\n          remove it altogether to use the default value.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          remove --rotate-certificates=false argument from the KUBELET_CERTIFICATE_ARGS\n          variable.\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.12\n        text: \"Verify that the RotateKubeletServerCertificate argument is set to true (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: RotateKubeletServerCertificate\n              path: '{.featureGates.RotateKubeletServerCertificate}'\n              compare:\n                op: nothave\n                value: false\n            - flag: RotateKubeletServerCertificate\n              path: '{.featureGates.RotateKubeletServerCertificate}'\n              set: false\n        remediation: |\n          Edit the kubelet service file $kubeletsvc\n          on each worker node and set the below parameter in KUBELET_CERTIFICATE_ARGS variable.\n          --feature-gates=RotateKubeletServerCertificate=true\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.13\n        text: \"Ensure that the Kubelet only makes use of Strong Cryptographic Ciphers (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --tls-cipher-suites\n              path: '{range .tlsCipherSuites[:]}{}{'',''}{end}'\n              compare:\n                op: valid_elements\n                value: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\n        remediation: |\n          If using a Kubelet config file, edit the file to set `tlsCipherSuites` to\n          TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\n          or to a subset of these values.\n          If using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the --tls-cipher-suites parameter as follows, or to a subset of these values.\n          --tls-cipher-suites=TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n"
  },
  {
    "path": "cfg/cis-1.23/policies.yaml",
    "content": "---\ncontrols:\nversion: \"cis-1.23\"\nid: 5\ntext: \"Kubernetes Policies\"\ntype: \"policies\"\ngroups:\n  - id: 5.1\n    text: \"RBAC and Service Accounts\"\n    checks:\n      - id: 5.1.1\n        text: \"Ensure that the cluster-admin role is only used where required (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Identify all clusterrolebindings to the cluster-admin role. Check if they are used and\n          if they need this role or if they could use a role with fewer privileges.\n          Where possible, first bind users to a lower privileged role and then remove the\n          clusterrolebinding to the cluster-admin role :\n          kubectl delete clusterrolebinding [name]\n        scored: false\n\n      - id: 5.1.2\n        text: \"Minimize access to secrets (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove get, list and watch access to Secret objects in the cluster.\n        scored: false\n\n      - id: 5.1.3\n        text: \"Minimize wildcard use in Roles and ClusterRoles (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible replace any use of wildcards in clusterroles and roles with specific\n          objects or actions.\n        scored: false\n\n      - id: 5.1.4\n        text: \"Minimize access to create pods (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove create access to pod objects in the cluster.\n        scored: false\n\n      - id: 5.1.5\n        text: \"Ensure that default service accounts are not actively used. (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Create explicit service accounts wherever a Kubernetes workload requires specific access\n          to the Kubernetes API server.\n          Modify the configuration of each default service account to include this value\n          automountServiceAccountToken: false\n        scored: false\n\n      - id: 5.1.6\n        text: \"Ensure that Service Account Tokens are only mounted where necessary (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Modify the definition of pods and service accounts which do not need to mount service\n          account tokens to disable it.\n        scored: false\n\n      - id: 5.1.7\n        text: \"Avoid use of system:masters group (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Remove the system:masters group from all users in the cluster.\n        scored: false\n\n      - id: 5.1.8\n        text: \"Limit use of the Bind, Impersonate and Escalate permissions in the Kubernetes cluster (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove the impersonate, bind and escalate rights from subjects.\n        scored: false\n\n  - id: 5.2\n    text: \"Pod Security Standards\"\n    checks:\n      - id: 5.2.1\n        text: \"Ensure that the cluster has at least one active policy control mechanism in place (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that either Pod Security Admission or an external policy control system is in place\n          for every namespace which contains user workloads.\n        scored: false\n\n      - id: 5.2.2\n        text: \"Minimize the admission of privileged containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of privileged containers.\n        scored: false\n\n      - id: 5.2.3\n        text: \"Minimize the admission of containers wishing to share the host process ID namespace (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of `hostPID` containers.\n        scored: false\n\n      - id: 5.2.4\n        text: \"Minimize the admission of containers wishing to share the host IPC namespace (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of `hostIPC` containers.\n        scored: false\n\n      - id: 5.2.5\n        text: \"Minimize the admission of containers wishing to share the host network namespace (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of `hostNetwork` containers.\n        scored: false\n\n      - id: 5.2.6\n        text: \"Minimize the admission of containers with allowPrivilegeEscalation (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers with `.spec.allowPrivilegeEscalation` set to `true`.\n        scored: false\n\n      - id: 5.2.7\n        text: \"Minimize the admission of root containers (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Create a policy for each namespace in the cluster, ensuring that either `MustRunAsNonRoot`\n          or `MustRunAs` with the range of UIDs not including 0, is set.\n        scored: false\n\n      - id: 5.2.8\n        text: \"Minimize the admission of containers with the NET_RAW capability (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers with the `NET_RAW` capability.\n        scored: false\n\n      - id: 5.2.9\n        text: \"Minimize the admission of containers with added capabilities (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that `allowedCapabilities` is not present in policies for the cluster unless\n          it is set to an empty array.\n        scored: false\n\n      - id: 5.2.10\n        text: \"Minimize the admission of containers with capabilities assigned (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Review the use of capabilites in applications running on your cluster. Where a namespace\n          contains applications which do not require any Linux capabities to operate consider adding\n          a PSP which forbids the admission of containers which do not drop all capabilities.\n        scored: false\n\n      - id: 5.2.11\n        text: \"Minimize the admission of Windows HostProcess containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers that have `.securityContext.windowsOptions.hostProcess` set to `true`.\n        scored: false\n\n      - id: 5.2.12\n        text: \"Minimize the admission of HostPath volumes (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers with `hostPath` volumes.\n        scored: false\n\n      - id: 5.2.13\n        text: \"Minimize the admission of containers which use HostPorts (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers which use `hostPort` sections.\n        scored: false\n\n  - id: 5.3\n    text: \"Network Policies and CNI\"\n    checks:\n      - id: 5.3.1\n        text: \"Ensure that the CNI in use supports NetworkPolicies (Manual)\"\n        type: \"manual\"\n        remediation: |\n          If the CNI plugin in use does not support network policies, consideration should be given to\n          making use of a different plugin, or finding an alternate mechanism for restricting traffic\n          in the Kubernetes cluster.\n        scored: false\n\n      - id: 5.3.2\n        text: \"Ensure that all Namespaces have NetworkPolicies defined (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the documentation and create NetworkPolicy objects as you need them.\n        scored: false\n\n  - id: 5.4\n    text: \"Secrets Management\"\n    checks:\n      - id: 5.4.1\n        text: \"Prefer using Secrets as files over Secrets as environment variables (Manual)\"\n        type: \"manual\"\n        remediation: |\n          If possible, rewrite application code to read Secrets from mounted secret files, rather than\n          from environment variables.\n        scored: false\n\n      - id: 5.4.2\n        text: \"Consider external secret storage (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Refer to the Secrets management options offered by your cloud provider or a third-party\n          secrets management solution.\n        scored: false\n\n  - id: 5.5\n    text: \"Extensible Admission Control\"\n    checks:\n      - id: 5.5.1\n        text: \"Configure Image Provenance using ImagePolicyWebhook admission controller (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and setup image provenance.\n        scored: false\n\n  - id: 5.7\n    text: \"General Policies\"\n    checks:\n      - id: 5.7.1\n        text: \"Create administrative boundaries between resources using namespaces (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the documentation and create namespaces for objects in your deployment as you need\n          them.\n        scored: false\n\n      - id: 5.7.2\n        text: \"Ensure that the seccomp profile is set to docker/default in your Pod definitions (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Use `securityContext` to enable the docker/default seccomp profile in your pod definitions.\n          An example is as below:\n            securityContext:\n              seccompProfile:\n                type: RuntimeDefault\n        scored: false\n\n      - id: 5.7.3\n        text: \"Apply SecurityContext to your Pods and Containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and apply SecurityContexts to your Pods. For a\n          suggested list of SecurityContexts, you may refer to the CIS Security Benchmark for Docker\n          Containers.\n        scored: false\n\n      - id: 5.7.4\n        text: \"The default namespace should not be used (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that namespaces are created to allow for appropriate segregation of Kubernetes\n          resources and that all new resources are created in a specific namespace.\n        scored: false\n"
  },
  {
    "path": "cfg/cis-1.24/config.yaml",
    "content": "---\n## Version-specific settings that override the values in cfg/config.yaml\n"
  },
  {
    "path": "cfg/cis-1.24/controlplane.yaml",
    "content": "---\ncontrols:\nversion: \"cis-1.24\"\nid: 3\ntext: \"Control Plane Configuration\"\ntype: \"controlplane\"\ngroups:\n  - id: 3.1\n    text: \"Authentication and Authorization\"\n    checks:\n      - id: 3.1.1\n        text: \"Client certificate authentication should not be used for users (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Alternative mechanisms provided by Kubernetes such as the use of OIDC should be\n          implemented in place of client certificates.\n        scored: false\n\n  - id: 3.2\n    text: \"Logging\"\n    checks:\n      - id: 3.2.1\n        text: \"Ensure that a minimal audit policy is created (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-policy-file\"\n              set: true\n        remediation: |\n          Create an audit policy file for your cluster.\n        scored: false\n\n      - id: 3.2.2\n        text: \"Ensure that the audit policy covers key security concerns (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Review the audit policy provided for the cluster and ensure that it covers\n          at least the following areas,\n          - Access to Secrets managed by the cluster. Care should be taken to only\n            log Metadata for requests to Secrets, ConfigMaps, and TokenReviews, in\n            order to avoid risk of logging sensitive data.\n          - Modification of Pod and Deployment objects.\n          - Use of `pods/exec`, `pods/portforward`, `pods/proxy` and `services/proxy`.\n          For most requests, minimally logging at the Metadata level is recommended\n          (the most basic level of logging).\n        scored: false\n"
  },
  {
    "path": "cfg/cis-1.24/etcd.yaml",
    "content": "---\ncontrols:\nversion: \"cis-1.24\"\nid: 2\ntext: \"Etcd Node Configuration\"\ntype: \"etcd\"\ngroups:\n  - id: 2\n    text: \"Etcd Node Configuration\"\n    checks:\n      - id: 2.1\n        text: \"Ensure that the --cert-file and --key-file arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--cert-file\"\n              env: \"ETCD_CERT_FILE\"\n            - flag: \"--key-file\"\n              env: \"ETCD_KEY_FILE\"\n        remediation: |\n          Follow the etcd service documentation and configure TLS encryption.\n          Then, edit the etcd pod specification file /etc/kubernetes/manifests/etcd.yaml\n          on the master node and set the below parameters.\n          --cert-file=</path/to/ca-file>\n          --key-file=</path/to/key-file>\n        scored: true\n\n      - id: 2.2\n        text: \"Ensure that the --client-cert-auth argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--client-cert-auth\"\n              env: \"ETCD_CLIENT_CERT_AUTH\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and set the below parameter.\n          --client-cert-auth=\"true\"\n        scored: true\n\n      - id: 2.3\n        text: \"Ensure that the --auto-tls argument is not set to true (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--auto-tls\"\n              env: \"ETCD_AUTO_TLS\"\n              set: false\n            - flag: \"--auto-tls\"\n              env: \"ETCD_AUTO_TLS\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and either remove the --auto-tls parameter or set it to false.\n            --auto-tls=false\n        scored: true\n\n      - id: 2.4\n        text: \"Ensure that the --peer-cert-file and --peer-key-file arguments are\n        set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--peer-cert-file\"\n              env: \"ETCD_PEER_CERT_FILE\"\n            - flag: \"--peer-key-file\"\n              env: \"ETCD_PEER_KEY_FILE\"\n        remediation: |\n          Follow the etcd service documentation and configure peer TLS encryption as appropriate\n          for your etcd cluster.\n          Then, edit the etcd pod specification file $etcdconf on the\n          master node and set the below parameters.\n          --peer-client-file=</path/to/peer-cert-file>\n          --peer-key-file=</path/to/peer-key-file>\n        scored: true\n\n      - id: 2.5\n        text: \"Ensure that the --peer-client-cert-auth argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--peer-client-cert-auth\"\n              env: \"ETCD_PEER_CLIENT_CERT_AUTH\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and set the below parameter.\n          --peer-client-cert-auth=true\n        scored: true\n\n      - id: 2.6\n        text: \"Ensure that the --peer-auto-tls argument is not set to true (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--peer-auto-tls\"\n              env: \"ETCD_PEER_AUTO_TLS\"\n              set: false\n            - flag: \"--peer-auto-tls\"\n              env: \"ETCD_PEER_AUTO_TLS\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and either remove the --peer-auto-tls parameter or set it to false.\n          --peer-auto-tls=false\n        scored: true\n\n      - id: 2.7\n        text: \"Ensure that a unique Certificate Authority is used for etcd (Manual)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--trusted-ca-file\"\n              env: \"ETCD_TRUSTED_CA_FILE\"\n        remediation: |\n          [Manual test]\n          Follow the etcd documentation and create a dedicated certificate authority setup for the\n          etcd service.\n          Then, edit the etcd pod specification file $etcdconf on the\n          master node and set the below parameter.\n          --trusted-ca-file=</path/to/ca-file>\n        scored: false\n"
  },
  {
    "path": "cfg/cis-1.24/master.yaml",
    "content": "---\ncontrols:\nversion: \"cis-1.24\"\nid: 1\ntext: \"Control Plane Security Configuration\"\ntype: \"master\"\ngroups:\n  - id: 1.1\n    text: \"Control Plane Node Configuration Files\"\n    checks:\n      - id: 1.1.1\n        text: \"Ensure that the API server pod specification file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $apiserverconf; then stat -c permissions=%a $apiserverconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the\n          control plane node.\n          For example, chmod 600 $apiserverconf\n        scored: true\n\n      - id: 1.1.2\n        text: \"Ensure that the API server pod specification file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $apiserverconf; then stat -c %U:%G $apiserverconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chown root:root $apiserverconf\n        scored: true\n\n      - id: 1.1.3\n        text: \"Ensure that the controller manager pod specification file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerconf; then stat -c permissions=%a $controllermanagerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chmod 600 $controllermanagerconf\n        scored: true\n\n      - id: 1.1.4\n        text: \"Ensure that the controller manager pod specification file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerconf; then stat -c %U:%G $controllermanagerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chown root:root $controllermanagerconf\n        scored: true\n\n      - id: 1.1.5\n        text: \"Ensure that the scheduler pod specification file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerconf; then stat -c permissions=%a $schedulerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chmod 600 $schedulerconf\n        scored: true\n\n      - id: 1.1.6\n        text: \"Ensure that the scheduler pod specification file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerconf; then stat -c %U:%G $schedulerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chown root:root $schedulerconf\n        scored: true\n\n      - id: 1.1.7\n        text: \"Ensure that the etcd pod specification file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $etcdconf; then find $etcdconf -name '*etcd*' | xargs stat -c permissions=%a; fi'\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod 600 $etcdconf\n        scored: true\n\n      - id: 1.1.8\n        text: \"Ensure that the etcd pod specification file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $etcdconf; then find $etcdconf -name '*etcd*' | xargs stat -c %U:%G; fi'\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root $etcdconf\n        scored: true\n\n      - id: 1.1.9\n        text: \"Ensure that the Container Network Interface file permissions are set to 600 or more restrictive (Manual)\"\n        audit: |\n          ps -ef | grep $kubeletbin | grep -- --cni-conf-dir | sed 's%.*cni-conf-dir[= ]\\([^ ]*\\).*%\\1%' | xargs -I{} find {} -mindepth 1 | xargs --no-run-if-empty stat -c permissions=%a\n          find /var/lib/cni/networks -type f 2> /dev/null | xargs --no-run-if-empty stat -c permissions=%a\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chmod 600 <path/to/cni/files>\n        scored: false\n\n      - id: 1.1.10\n        text: \"Ensure that the Container Network Interface file ownership is set to root:root (Manual)\"\n        audit: |\n          ps -ef | grep $kubeletbin | grep -- --cni-conf-dir | sed 's%.*cni-conf-dir[= ]\\([^ ]*\\).*%\\1%' | xargs -I{} find {} -mindepth 1 | xargs --no-run-if-empty stat -c %U:%G\n          find /var/lib/cni/networks -type f 2> /dev/null | xargs --no-run-if-empty stat -c %U:%G\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root <path/to/cni/files>\n        scored: false\n\n      - id: 1.1.11\n        text: \"Ensure that the etcd data directory permissions are set to 700 or more restrictive (Automated)\"\n        audit: |\n          DATA_DIR=''\n          for d in $(ps -ef | grep $etcdbin | grep -- --data-dir | sed 's%.*data-dir[= ]\\([^ ]*\\).*%\\1%'); do\n            if test -d \"$d\"; then DATA_DIR=\"$d\"; fi\n          done\n          if ! test -d \"$DATA_DIR\"; then DATA_DIR=$etcddatadir; fi\n          stat -c permissions=%a \"$DATA_DIR\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"700\"\n        remediation: |\n          On the etcd server node, get the etcd data directory, passed as an argument --data-dir,\n          from the command 'ps -ef | grep etcd'.\n          Run the below command (based on the etcd data directory found above). For example,\n          chmod 700 /var/lib/etcd\n        scored: true\n\n      - id: 1.1.12\n        text: \"Ensure that the etcd data directory ownership is set to etcd:etcd (Automated)\"\n        audit: |\n          DATA_DIR=''\n          for d in $(ps -ef | grep $etcdbin | grep -- --data-dir | sed 's%.*data-dir[= ]\\([^ ]*\\).*%\\1%'); do\n            if test -d \"$d\"; then DATA_DIR=\"$d\"; fi\n          done\n          if ! test -d \"$DATA_DIR\"; then DATA_DIR=$etcddatadir; fi\n          stat -c %U:%G \"$DATA_DIR\"\n        tests:\n          test_items:\n            - flag: \"etcd:etcd\"\n        remediation: |\n          On the etcd server node, get the etcd data directory, passed as an argument --data-dir,\n          from the command 'ps -ef | grep etcd'.\n          Run the below command (based on the etcd data directory found above).\n          For example, chown etcd:etcd /var/lib/etcd\n        scored: true\n\n      - id: 1.1.13\n        text: \"Ensure that the admin.conf file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e /etc/kubernetes/admin.conf; then stat -c permissions=%a /etc/kubernetes/admin.conf; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chmod 600 /etc/kubernetes/admin.conf\n        scored: true\n\n      - id: 1.1.14\n        text: \"Ensure that the admin.conf file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e /etc/kubernetes/admin.conf; then stat -c %U:%G /etc/kubernetes/admin.conf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chown root:root /etc/kubernetes/admin.conf\n        scored: true\n\n      - id: 1.1.15\n        text: \"Ensure that the scheduler.conf file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerkubeconfig; then stat -c permissions=%a $schedulerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod 600 $schedulerkubeconfig\n        scored: true\n\n      - id: 1.1.16\n        text: \"Ensure that the scheduler.conf file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerkubeconfig; then stat -c %U:%G $schedulerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root $schedulerkubeconfig\n        scored: true\n\n      - id: 1.1.17\n        text: \"Ensure that the controller-manager.conf file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerkubeconfig; then stat -c permissions=%a $controllermanagerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod 600 $controllermanagerkubeconfig\n        scored: true\n\n      - id: 1.1.18\n        text: \"Ensure that the controller-manager.conf file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerkubeconfig; then stat -c %U:%G $controllermanagerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root $controllermanagerkubeconfig\n        scored: true\n\n      - id: 1.1.19\n        text: \"Ensure that the Kubernetes PKI directory and file ownership is set to root:root (Automated)\"\n        audit: \"find /etc/kubernetes/pki/ | xargs stat -c %U:%G\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown -R root:root /etc/kubernetes/pki/\n        scored: true\n\n      - id: 1.1.20\n        text: \"Ensure that the Kubernetes PKI certificate file permissions are set to 600 or more restrictive (Manual)\"\n        audit: \"find /etc/kubernetes/pki/ -name '*.crt' | xargs stat -c permissions=%a\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod -R 600 /etc/kubernetes/pki/*.crt\n        scored: false\n\n      - id: 1.1.21\n        text: \"Ensure that the Kubernetes PKI key file permissions are set to 600 (Manual)\"\n        audit: \"find /etc/kubernetes/pki/ -name '*.key' | xargs stat -c permissions=%a\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod -R 600 /etc/kubernetes/pki/*.key\n        scored: false\n\n  - id: 1.2\n    text: \"API Server\"\n    checks:\n      - id: 1.2.1\n        text: \"Ensure that the --anonymous-auth argument is set to false (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--anonymous-auth\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the below parameter.\n          --anonymous-auth=false\n        scored: false\n\n      - id: 1.2.2\n        text: \"Ensure that the --token-auth-file parameter is not set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--token-auth-file\"\n              set: false\n        remediation: |\n          Follow the documentation and configure alternate mechanisms for authentication. Then,\n          edit the API server pod specification file $apiserverconf\n          on the control plane node and remove the --token-auth-file=<filename> parameter.\n        scored: true\n\n      - id: 1.2.3\n        text: \"Ensure that the --DenyServiceExternalIPs is not set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: nothave\n                value: \"DenyServiceExternalIPs\"\n            - flag: \"--enable-admission-plugins\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and remove the `DenyServiceExternalIPs`\n          from enabled admission plugins.\n        scored: true\n\n      - id: 1.2.4\n        text: \"Ensure that the --kubelet-client-certificate and --kubelet-client-key arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--kubelet-client-certificate\"\n            - flag: \"--kubelet-client-key\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection between the\n          apiserver and kubelets. Then, edit API server pod specification file\n          $apiserverconf on the control plane node and set the\n          kubelet client certificate and key parameters as below.\n          --kubelet-client-certificate=<path/to/client-certificate-file>\n          --kubelet-client-key=<path/to/client-key-file>\n        scored: true\n\n      - id: 1.2.5\n        text: \"Ensure that the --kubelet-certificate-authority argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--kubelet-certificate-authority\"\n        remediation: |\n          Follow the Kubernetes documentation and setup the TLS connection between\n          the apiserver and kubelets. Then, edit the API server pod specification file\n          $apiserverconf on the control plane node and set the\n          --kubelet-certificate-authority parameter to the path to the cert file for the certificate authority.\n          --kubelet-certificate-authority=<ca-string>\n        scored: true\n\n      - id: 1.2.6\n        text: \"Ensure that the --authorization-mode argument is not set to AlwaysAllow (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: nothave\n                value: \"AlwaysAllow\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --authorization-mode parameter to values other than AlwaysAllow.\n          One such example could be as below.\n          --authorization-mode=RBAC\n        scored: true\n\n      - id: 1.2.7\n        text: \"Ensure that the --authorization-mode argument includes Node (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: has\n                value: \"Node\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --authorization-mode parameter to a value that includes Node.\n          --authorization-mode=Node,RBAC\n        scored: true\n\n      - id: 1.2.8\n        text: \"Ensure that the --authorization-mode argument includes RBAC (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: has\n                value: \"RBAC\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --authorization-mode parameter to a value that includes RBAC,\n          for example `--authorization-mode=Node,RBAC`.\n        scored: true\n\n      - id: 1.2.9\n        text: \"Ensure that the admission control plugin EventRateLimit is set (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"EventRateLimit\"\n        remediation: |\n          Follow the Kubernetes documentation and set the desired limits in a configuration file.\n          Then, edit the API server pod specification file $apiserverconf\n          and set the below parameters.\n          --enable-admission-plugins=...,EventRateLimit,...\n          --admission-control-config-file=<path/to/configuration/file>\n        scored: false\n\n      - id: 1.2.10\n        text: \"Ensure that the admission control plugin AlwaysAdmit is not set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: nothave\n                value: AlwaysAdmit\n            - flag: \"--enable-admission-plugins\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and either remove the --enable-admission-plugins parameter, or set it to a\n          value that does not include AlwaysAdmit.\n        scored: true\n\n      - id: 1.2.11\n        text: \"Ensure that the admission control plugin AlwaysPullImages is set (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"AlwaysPullImages\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --enable-admission-plugins parameter to include\n          AlwaysPullImages.\n          --enable-admission-plugins=...,AlwaysPullImages,...\n        scored: false\n\n      - id: 1.2.12\n        text: \"Ensure that the admission control plugin SecurityContextDeny is set if PodSecurityPolicy is not used (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"SecurityContextDeny\"\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"PodSecurityPolicy\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --enable-admission-plugins parameter to include\n          SecurityContextDeny, unless PodSecurityPolicy is already in place.\n          --enable-admission-plugins=...,SecurityContextDeny,...\n        scored: false\n\n      - id: 1.2.13\n        text: \"Ensure that the admission control plugin ServiceAccount is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--disable-admission-plugins\"\n              compare:\n                op: nothave\n                value: \"ServiceAccount\"\n            - flag: \"--disable-admission-plugins\"\n              set: false\n        remediation: |\n          Follow the documentation and create ServiceAccount objects as per your environment.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and ensure that the --disable-admission-plugins parameter is set to a\n          value that does not include ServiceAccount.\n        scored: true\n\n      - id: 1.2.14\n        text: \"Ensure that the admission control plugin NamespaceLifecycle is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--disable-admission-plugins\"\n              compare:\n                op: nothave\n                value: \"NamespaceLifecycle\"\n            - flag: \"--disable-admission-plugins\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --disable-admission-plugins parameter to\n          ensure it does not include NamespaceLifecycle.\n        scored: true\n\n      - id: 1.2.15\n        text: \"Ensure that the admission control plugin NodeRestriction is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"NodeRestriction\"\n        remediation: |\n          Follow the Kubernetes documentation and configure NodeRestriction plug-in on kubelets.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --enable-admission-plugins parameter to a\n          value that includes NodeRestriction.\n          --enable-admission-plugins=...,NodeRestriction,...\n        scored: true\n\n      - id: 1.2.16\n        text: \"Ensure that the --secure-port argument is not set to 0 (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--secure-port\"\n              compare:\n                op: gt\n                value: 0\n            - flag: \"--secure-port\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and either remove the --secure-port parameter or\n          set it to a different (non-zero) desired port.\n        scored: true\n\n      - id: 1.2.17\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the below parameter.\n          --profiling=false\n        scored: true\n\n      - id: 1.2.18\n        text: \"Ensure that the --audit-log-path argument is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-path\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --audit-log-path parameter to a suitable path and\n          file where you would like audit logs to be written, for example,\n          --audit-log-path=/var/log/apiserver/audit.log\n        scored: true\n\n      - id: 1.2.19\n        text: \"Ensure that the --audit-log-maxage argument is set to 30 or as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxage\"\n              compare:\n                op: gte\n                value: 30\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --audit-log-maxage parameter to 30\n          or as an appropriate number of days, for example,\n          --audit-log-maxage=30\n        scored: true\n\n      - id: 1.2.20\n        text: \"Ensure that the --audit-log-maxbackup argument is set to 10 or as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxbackup\"\n              compare:\n                op: gte\n                value: 10\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --audit-log-maxbackup parameter to 10 or to an appropriate\n          value. For example,\n          --audit-log-maxbackup=10\n        scored: true\n\n      - id: 1.2.21\n        text: \"Ensure that the --audit-log-maxsize argument is set to 100 or as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxsize\"\n              compare:\n                op: gte\n                value: 100\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --audit-log-maxsize parameter to an appropriate size in MB.\n          For example, to set it as 100 MB, --audit-log-maxsize=100\n        scored: true\n\n      - id: 1.2.22\n        text: \"Ensure that the --request-timeout argument is set as appropriate (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        type: manual\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          and set the below parameter as appropriate and if needed.\n          For example, --request-timeout=300s\n        scored: false\n\n      - id: 1.2.23\n        text: \"Ensure that the --service-account-lookup argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--service-account-lookup\"\n              set: false\n            - flag: \"--service-account-lookup\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the below parameter.\n          --service-account-lookup=true\n          Alternatively, you can delete the --service-account-lookup parameter from this file so\n          that the default takes effect.\n        scored: true\n\n      - id: 1.2.24\n        text: \"Ensure that the --service-account-key-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--service-account-key-file\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --service-account-key-file parameter\n          to the public key file for service accounts. For example,\n          --service-account-key-file=<filename>\n        scored: true\n\n      - id: 1.2.25\n        text: \"Ensure that the --etcd-certfile and --etcd-keyfile arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--etcd-certfile\"\n            - flag: \"--etcd-keyfile\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection between the apiserver and etcd.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the etcd certificate and key file parameters.\n          --etcd-certfile=<path/to/client-certificate-file>\n          --etcd-keyfile=<path/to/client-key-file>\n        scored: true\n\n      - id: 1.2.26\n        text: \"Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--tls-cert-file\"\n            - flag: \"--tls-private-key-file\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection on the apiserver.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the TLS certificate and private key file parameters.\n          --tls-cert-file=<path/to/tls-certificate-file>\n          --tls-private-key-file=<path/to/tls-key-file>\n        scored: true\n\n      - id: 1.2.27\n        text: \"Ensure that the --client-ca-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--client-ca-file\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection on the apiserver.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the client certificate authority file.\n          --client-ca-file=<path/to/client-ca-file>\n        scored: true\n\n      - id: 1.2.28\n        text: \"Ensure that the --etcd-cafile argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--etcd-cafile\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection between the apiserver and etcd.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the etcd certificate authority file parameter.\n          --etcd-cafile=<path/to/ca-file>\n        scored: true\n\n      - id: 1.2.29\n        text: \"Ensure that the --encryption-provider-config argument is set as appropriate (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--encryption-provider-config\"\n        remediation: |\n          Follow the Kubernetes documentation and configure a EncryptionConfig file.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --encryption-provider-config parameter to the path of that file.\n          For example, --encryption-provider-config=</path/to/EncryptionConfig/File>\n        scored: false\n\n      - id: 1.2.30\n        text: \"Ensure that encryption providers are appropriately configured (Manual)\"\n        audit: |\n          ENCRYPTION_PROVIDER_CONFIG=$(ps -ef | grep $apiserverbin | grep -- --encryption-provider-config | sed 's%.*encryption-provider-config[= ]\\([^ ]*\\).*%\\1%')\n          if test -e $ENCRYPTION_PROVIDER_CONFIG; then grep -A1 'providers:' $ENCRYPTION_PROVIDER_CONFIG | tail -n1 | grep -o \"[A-Za-z]*\" | sed 's/^/provider=/'; fi\n        tests:\n          test_items:\n            - flag: \"provider\"\n              compare:\n                op: valid_elements\n                value: \"aescbc,kms,secretbox\"\n        remediation: |\n          Follow the Kubernetes documentation and configure a EncryptionConfig file.\n          In this file, choose aescbc, kms or secretbox as the encryption provider.\n        scored: false\n\n      - id: 1.2.31\n        text: \"Ensure that the API Server only makes use of Strong Cryptographic Ciphers (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--tls-cipher-suites\"\n              compare:\n                op: valid_elements\n                value: \"TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,TLS_CHACHA20_POLY1305_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,TLS_RSA_WITH_3DES_EDE_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_256_GCM_SHA384\"\n        remediation: |\n          Edit the API server pod specification file /etc/kubernetes/manifests/kube-apiserver.yaml\n          on the control plane node and set the below parameter.\n          --tls-cipher-suites=TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,TLS_CHACHA20_POLY1305_SHA256,\n          TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,\n          TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,\n          TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,\n          TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,\n          TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,\n          TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,TLS_RSA_WITH_3DES_EDE_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA,\n          TLS_RSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_256_GCM_SHA384\n        scored: false\n\n  - id: 1.3\n    text: \"Controller Manager\"\n    checks:\n      - id: 1.3.1\n        text: \"Ensure that the --terminated-pod-gc-threshold argument is set as appropriate (Manual)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--terminated-pod-gc-threshold\"\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the --terminated-pod-gc-threshold to an appropriate threshold,\n          for example, --terminated-pod-gc-threshold=10\n        scored: false\n\n      - id: 1.3.2\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the below parameter.\n          --profiling=false\n        scored: true\n\n      - id: 1.3.3\n        text: \"Ensure that the --use-service-account-credentials argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--use-service-account-credentials\"\n              compare:\n                op: noteq\n                value: false\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node to set the below parameter.\n          --use-service-account-credentials=true\n        scored: true\n\n      - id: 1.3.4\n        text: \"Ensure that the --service-account-private-key-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--service-account-private-key-file\"\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the --service-account-private-key-file parameter\n          to the private key file for service accounts.\n          --service-account-private-key-file=<filename>\n        scored: true\n\n      - id: 1.3.5\n        text: \"Ensure that the --root-ca-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--root-ca-file\"\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the --root-ca-file parameter to the certificate bundle file`.\n          --root-ca-file=<path/to/file>\n        scored: true\n\n      - id: 1.3.6\n        text: \"Ensure that the RotateKubeletServerCertificate argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--feature-gates\"\n              compare:\n                op: nothave\n                value: \"RotateKubeletServerCertificate=false\"\n              set: true\n            - flag: \"--feature-gates\"\n              set: false\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the --feature-gates parameter to include RotateKubeletServerCertificate=true.\n          --feature-gates=RotateKubeletServerCertificate=true\n        scored: true\n\n      - id: 1.3.7\n        text: \"Ensure that the --bind-address argument is set to 127.0.0.1 (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--bind-address\"\n              compare:\n                op: eq\n                value: \"127.0.0.1\"\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and ensure the correct value for the --bind-address parameter\n        scored: true\n\n  - id: 1.4\n    text: \"Scheduler\"\n    checks:\n      - id: 1.4.1\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: \"/bin/ps -ef | grep $schedulerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the Scheduler pod specification file $schedulerconf file\n          on the control plane node and set the below parameter.\n          --profiling=false\n        scored: true\n\n      - id: 1.4.2\n        text: \"Ensure that the --bind-address argument is set to 127.0.0.1 (Automated)\"\n        audit: \"/bin/ps -ef | grep $schedulerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--bind-address\"\n              compare:\n                op: eq\n                value: \"127.0.0.1\"\n        remediation: |\n          Edit the Scheduler pod specification file $schedulerconf\n          on the control plane node and ensure the correct value for the --bind-address parameter\n        scored: true\n"
  },
  {
    "path": "cfg/cis-1.24/node.yaml",
    "content": "---\ncontrols:\nversion: \"cis-1.24\"\nid: 4\ntext: \"Worker Node Security Configuration\"\ntype: \"node\"\ngroups:\n  - id: 4.1\n    text: \"Worker Node Configuration Files\"\n    checks:\n      - id: 4.1.1\n        text: \"Ensure that the kubelet service file permissions are set to 600 or more restrictive (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletsvc; then stat -c permissions=%a $kubeletsvc; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example, chmod 600 $kubeletsvc\n        scored: true\n\n      - id: 4.1.2\n        text: \"Ensure that the kubelet service file ownership is set to root:root (Automated)\"\n        audit: '/bin/sh -c \"if test -e $kubeletsvc; then stat -c %U:%G $kubeletsvc; else echo \\\"File not found\\\"; fi\"'\n        tests:\n          bin_op: or\n          test_items:\n            - flag: root:root\n            - flag: \"File not found\"\n        remediation: |\n            Run the below command (based on the file location on your system) on the each worker node.\n            For example,\n            chown root:root $kubeletsvc\n        scored: true\n\n      - id: 4.1.3\n        text: \"If proxy kubeconfig file exists ensure permissions are set to 600 or more restrictive (Manual)\"\n        audit: '/bin/sh -c ''if test -e $proxykubeconfig; then stat -c permissions=%a $proxykubeconfig; fi'' '\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"permissions\"\n              set: true\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chmod 600 $proxykubeconfig\n        scored: false\n\n      - id: 4.1.4\n        text: \"If proxy kubeconfig file exists ensure ownership is set to root:root (Manual)\"\n        audit: '/bin/sh -c ''if test -e $proxykubeconfig; then stat -c %U:%G $proxykubeconfig; fi'' '\n        tests:\n          bin_op: or\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example, chown root:root $proxykubeconfig\n        scored: false\n\n      - id: 4.1.5\n        text: \"Ensure that the --kubeconfig kubelet.conf file permissions are set to 600 or more restrictive (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletkubeconfig; then stat -c permissions=%a $kubeletkubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chmod 600 $kubeletkubeconfig\n        scored: true\n\n      - id: 4.1.6\n        text: \"Ensure that the --kubeconfig kubelet.conf file ownership is set to root:root (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletkubeconfig; then stat -c %U:%G $kubeletkubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chown root:root $kubeletkubeconfig\n        scored: true\n\n      - id: 4.1.7\n        text: \"Ensure that the certificate authorities file permissions are set to 600 or more restrictive (Manual)\"\n        audit: |\n          CAFILE=$(ps -ef | grep kubelet | grep -v apiserver | grep -- --client-ca-file= | awk -F '--client-ca-file=' '{print $2}' | awk '{print $1}' | uniq)\n          if test -z $CAFILE; then CAFILE=$kubeletcafile; fi\n          if test -e $CAFILE; then stat -c permissions=%a $CAFILE; fi\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the following command to modify the file permissions of the\n          --client-ca-file chmod 600 <filename>\n        scored: false\n\n      - id: 4.1.8\n        text: \"Ensure that the client certificate authorities file ownership is set to root:root (Manual)\"\n        audit: |\n          CAFILE=$(ps -ef | grep kubelet | grep -v apiserver | grep -- --client-ca-file= | awk -F '--client-ca-file=' '{print $2}' | awk '{print $1}' | uniq)\n          if test -z $CAFILE; then CAFILE=$kubeletcafile; fi\n          if test -e $CAFILE; then stat -c %U:%G $CAFILE; fi\n        tests:\n          test_items:\n            - flag: root:root\n              compare:\n                op: eq\n                value: root:root\n        remediation: |\n          Run the following command to modify the ownership of the --client-ca-file.\n          chown root:root <filename>\n        scored: false\n\n      - id: 4.1.9\n        text: \"If the kubelet config.yaml configuration file is being used validate permissions set to 600 or more restrictive (Manual)\"\n        audit: '/bin/sh -c ''if test -e $kubeletconf; then stat -c permissions=%a $kubeletconf; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the following command (using the config file location identified in the Audit step)\n          chmod 600 $kubeletconf\n        scored: false\n\n      - id: 4.1.10\n        text: \"If the kubelet config.yaml configuration file is being used validate file ownership is set to root:root (Manual)\"\n        audit: '/bin/sh -c ''if test -e $kubeletconf; then stat -c %U:%G $kubeletconf; fi'' '\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the following command (using the config file location identified in the Audit step)\n          chown root:root $kubeletconf\n        scored: false\n\n  - id: 4.2\n    text: \"Kubelet\"\n    checks:\n      - id: 4.2.1\n        text: \"Ensure that the --anonymous-auth argument is set to false (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: \"--anonymous-auth\"\n              path: '{.authentication.anonymous.enabled}'\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          If using a Kubelet config file, edit the file to set `authentication: anonymous: enabled` to\n          `false`.\n          If using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          `--anonymous-auth=false`\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.2\n        text: \"Ensure that the --authorization-mode argument is not set to AlwaysAllow (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --authorization-mode\n              path: '{.authorization.mode}'\n              compare:\n                op: nothave\n                value: AlwaysAllow\n        remediation: |\n          If using a Kubelet config file, edit the file to set `authorization.mode` to Webhook. If\n          using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_AUTHZ_ARGS variable.\n          --authorization-mode=Webhook\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.3\n        text: \"Ensure that the --client-ca-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --client-ca-file\n              path: '{.authentication.x509.clientCAFile}'\n        remediation: |\n          If using a Kubelet config file, edit the file to set `authentication.x509.clientCAFile` to\n          the location of the client CA file.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_AUTHZ_ARGS variable.\n          --client-ca-file=<path/to/client-ca-file>\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.4\n        text: \"Verify that the --read-only-port argument is set to 0 (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--read-only-port\"\n              path: '{.readOnlyPort}'\n              compare:\n                op: eq\n                value: 0\n            - flag: \"--read-only-port\"\n              path: '{.readOnlyPort}'\n              set: false\n        remediation: |\n          If using a Kubelet config file, edit the file to set `readOnlyPort` to 0.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --read-only-port=0\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.5\n        text: \"Ensure that the --streaming-connection-idle-timeout argument is not set to 0 (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --streaming-connection-idle-timeout\n              path: '{.streamingConnectionIdleTimeout}'\n              compare:\n                op: noteq\n                value: 0\n            - flag: --streaming-connection-idle-timeout\n              path: '{.streamingConnectionIdleTimeout}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to set `streamingConnectionIdleTimeout` to a\n          value other than 0.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --streaming-connection-idle-timeout=5m\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.6\n        text: \"Ensure that the --protect-kernel-defaults argument is set to true (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --protect-kernel-defaults\n              path: '{.protectKernelDefaults}'\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          If using a Kubelet config file, edit the file to set `protectKernelDefaults` to `true`.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --protect-kernel-defaults=true\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.7\n        text: \"Ensure that the --make-iptables-util-chains argument is set to true (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --make-iptables-util-chains\n              path: '{.makeIPTablesUtilChains}'\n              compare:\n                op: eq\n                value: true\n            - flag: --make-iptables-util-chains\n              path: '{.makeIPTablesUtilChains}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to set `makeIPTablesUtilChains` to `true`.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          remove the --make-iptables-util-chains argument from the\n          KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.8\n        text: \"Ensure that the --hostname-override argument is not set (Manual)\"\n        # This is one of those properties that can only be set as a command line argument.\n        # To check if the property is set as expected, we need to parse the kubelet command\n        # instead reading the Kubelet Configuration file.\n        audit: \"/bin/ps -fC $kubeletbin \"\n        tests:\n          test_items:\n            - flag: --hostname-override\n              set: false\n        remediation: |\n          Edit the kubelet service file $kubeletsvc\n          on each worker node and remove the --hostname-override argument from the\n          KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.9\n        text: \"Ensure that the eventRecordQPS argument is set to a level which ensures appropriate event capture (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --event-qps\n              path: '{.eventRecordQPS}'\n              compare:\n                op: gte\n                value: 0\n            - flag: --event-qps\n              path: '{.eventRecordQPS}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to set `eventRecordQPS` to an appropriate level.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.10\n        text: \"Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --tls-cert-file\n              path: '{.tlsCertFile}'\n            - flag: --tls-private-key-file\n              path: '{.tlsPrivateKeyFile}'\n        remediation: |\n          If using a Kubelet config file, edit the file to set `tlsCertFile` to the location\n          of the certificate file to use to identify this Kubelet, and `tlsPrivateKeyFile`\n          to the location of the corresponding private key file.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameters in KUBELET_CERTIFICATE_ARGS variable.\n          --tls-cert-file=<path/to/tls-certificate-file>\n          --tls-private-key-file=<path/to/tls-key-file>\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.11\n        text: \"Ensure that the --rotate-certificates argument is not set to false (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --rotate-certificates\n              path: '{.rotateCertificates}'\n              compare:\n                op: eq\n                value: true\n            - flag: --rotate-certificates\n              path: '{.rotateCertificates}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to add the line `rotateCertificates` to `true` or\n          remove it altogether to use the default value.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          remove --rotate-certificates=false argument from the KUBELET_CERTIFICATE_ARGS\n          variable.\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.12\n        text: \"Verify that the RotateKubeletServerCertificate argument is set to true (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: RotateKubeletServerCertificate\n              path: '{.featureGates.RotateKubeletServerCertificate}'\n              compare:\n                op: nothave\n                value: false\n            - flag: RotateKubeletServerCertificate\n              path: '{.featureGates.RotateKubeletServerCertificate}'\n              set: false\n        remediation: |\n          Edit the kubelet service file $kubeletsvc\n          on each worker node and set the below parameter in KUBELET_CERTIFICATE_ARGS variable.\n          --feature-gates=RotateKubeletServerCertificate=true\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.13\n        text: \"Ensure that the Kubelet only makes use of Strong Cryptographic Ciphers (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --tls-cipher-suites\n              path: '{range .tlsCipherSuites[:]}{}{'',''}{end}'\n              compare:\n                op: valid_elements\n                value: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\n        remediation: |\n          If using a Kubelet config file, edit the file to set `tlsCipherSuites` to\n          TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\n          or to a subset of these values.\n          If using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the --tls-cipher-suites parameter as follows, or to a subset of these values.\n          --tls-cipher-suites=TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n"
  },
  {
    "path": "cfg/cis-1.24/policies.yaml",
    "content": "---\ncontrols:\nversion: \"cis-1.24\"\nid: 5\ntext: \"Kubernetes Policies\"\ntype: \"policies\"\ngroups:\n  - id: 5.1\n    text: \"RBAC and Service Accounts\"\n    checks:\n      - id: 5.1.1\n        text: \"Ensure that the cluster-admin role is only used where required (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Identify all clusterrolebindings to the cluster-admin role. Check if they are used and\n          if they need this role or if they could use a role with fewer privileges.\n          Where possible, first bind users to a lower privileged role and then remove the\n          clusterrolebinding to the cluster-admin role :\n          kubectl delete clusterrolebinding [name]\n        scored: false\n\n      - id: 5.1.2\n        text: \"Minimize access to secrets (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove get, list and watch access to Secret objects in the cluster.\n        scored: false\n\n      - id: 5.1.3\n        text: \"Minimize wildcard use in Roles and ClusterRoles (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible replace any use of wildcards in clusterroles and roles with specific\n          objects or actions.\n        scored: false\n\n      - id: 5.1.4\n        text: \"Minimize access to create pods (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove create access to pod objects in the cluster.\n        scored: false\n\n      - id: 5.1.5\n        text: \"Ensure that default service accounts are not actively used. (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Create explicit service accounts wherever a Kubernetes workload requires specific access\n          to the Kubernetes API server.\n          Modify the configuration of each default service account to include this value\n          automountServiceAccountToken: false\n        scored: false\n\n      - id: 5.1.6\n        text: \"Ensure that Service Account Tokens are only mounted where necessary (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Modify the definition of pods and service accounts which do not need to mount service\n          account tokens to disable it.\n        scored: false\n\n      - id: 5.1.7\n        text: \"Avoid use of system:masters group (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Remove the system:masters group from all users in the cluster.\n        scored: false\n\n      - id: 5.1.8\n        text: \"Limit use of the Bind, Impersonate and Escalate permissions in the Kubernetes cluster (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove the impersonate, bind and escalate rights from subjects.\n        scored: false\n\n  - id: 5.2\n    text: \"Pod Security Standards\"\n    checks:\n      - id: 5.2.1\n        text: \"Ensure that the cluster has at least one active policy control mechanism in place (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that either Pod Security Admission or an external policy control system is in place\n          for every namespace which contains user workloads.\n        scored: false\n\n      - id: 5.2.2\n        text: \"Minimize the admission of privileged containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of privileged containers.\n        scored: false\n\n      - id: 5.2.3\n        text: \"Minimize the admission of containers wishing to share the host process ID namespace (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of `hostPID` containers.\n        scored: false\n\n      - id: 5.2.4\n        text: \"Minimize the admission of containers wishing to share the host IPC namespace (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of `hostIPC` containers.\n        scored: false\n\n      - id: 5.2.5\n        text: \"Minimize the admission of containers wishing to share the host network namespace (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of `hostNetwork` containers.\n        scored: false\n\n      - id: 5.2.6\n        text: \"Minimize the admission of containers with allowPrivilegeEscalation (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers with `.spec.allowPrivilegeEscalation` set to `true`.\n        scored: false\n\n      - id: 5.2.7\n        text: \"Minimize the admission of root containers (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Create a policy for each namespace in the cluster, ensuring that either `MustRunAsNonRoot`\n          or `MustRunAs` with the range of UIDs not including 0, is set.\n        scored: false\n\n      - id: 5.2.8\n        text: \"Minimize the admission of containers with the NET_RAW capability (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers with the `NET_RAW` capability.\n        scored: false\n\n      - id: 5.2.9\n        text: \"Minimize the admission of containers with added capabilities (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that `allowedCapabilities` is not present in policies for the cluster unless\n          it is set to an empty array.\n        scored: false\n\n      - id: 5.2.10\n        text: \"Minimize the admission of containers with capabilities assigned (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Review the use of capabilites in applications running on your cluster. Where a namespace\n          contains applications which do not require any Linux capabities to operate consider adding\n          a PSP which forbids the admission of containers which do not drop all capabilities.\n        scored: false\n\n      - id: 5.2.11\n        text: \"Minimize the admission of Windows HostProcess containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers that have `.securityContext.windowsOptions.hostProcess` set to `true`.\n        scored: false\n\n      - id: 5.2.12\n        text: \"Minimize the admission of HostPath volumes (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers with `hostPath` volumes.\n        scored: false\n\n      - id: 5.2.13\n        text: \"Minimize the admission of containers which use HostPorts (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers which use `hostPort` sections.\n        scored: false\n\n  - id: 5.3\n    text: \"Network Policies and CNI\"\n    checks:\n      - id: 5.3.1\n        text: \"Ensure that the CNI in use supports NetworkPolicies (Manual)\"\n        type: \"manual\"\n        remediation: |\n          If the CNI plugin in use does not support network policies, consideration should be given to\n          making use of a different plugin, or finding an alternate mechanism for restricting traffic\n          in the Kubernetes cluster.\n        scored: false\n\n      - id: 5.3.2\n        text: \"Ensure that all Namespaces have NetworkPolicies defined (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the documentation and create NetworkPolicy objects as you need them.\n        scored: false\n\n  - id: 5.4\n    text: \"Secrets Management\"\n    checks:\n      - id: 5.4.1\n        text: \"Prefer using Secrets as files over Secrets as environment variables (Manual)\"\n        type: \"manual\"\n        remediation: |\n          If possible, rewrite application code to read Secrets from mounted secret files, rather than\n          from environment variables.\n        scored: false\n\n      - id: 5.4.2\n        text: \"Consider external secret storage (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Refer to the Secrets management options offered by your cloud provider or a third-party\n          secrets management solution.\n        scored: false\n\n  - id: 5.5\n    text: \"Extensible Admission Control\"\n    checks:\n      - id: 5.5.1\n        text: \"Configure Image Provenance using ImagePolicyWebhook admission controller (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and setup image provenance.\n        scored: false\n\n  - id: 5.7\n    text: \"General Policies\"\n    checks:\n      - id: 5.7.1\n        text: \"Create administrative boundaries between resources using namespaces (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the documentation and create namespaces for objects in your deployment as you need\n          them.\n        scored: false\n\n      - id: 5.7.2\n        text: \"Ensure that the seccomp profile is set to docker/default in your Pod definitions (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Use `securityContext` to enable the docker/default seccomp profile in your pod definitions.\n          An example is as below:\n            securityContext:\n              seccompProfile:\n                type: RuntimeDefault\n        scored: false\n\n      - id: 5.7.3\n        text: \"Apply SecurityContext to your Pods and Containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and apply SecurityContexts to your Pods. For a\n          suggested list of SecurityContexts, you may refer to the CIS Security Benchmark for Docker\n          Containers.\n        scored: false\n\n      - id: 5.7.4\n        text: \"The default namespace should not be used (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that namespaces are created to allow for appropriate segregation of Kubernetes\n          resources and that all new resources are created in a specific namespace.\n        scored: false\n"
  },
  {
    "path": "cfg/cis-1.24-microk8s/config.yaml",
    "content": "---\n## Version-specific settings that override the values in cfg/config.yaml\n"
  },
  {
    "path": "cfg/cis-1.24-microk8s/controlplane.yaml",
    "content": "---\ncontrols:\nversion: \"cis-1.24\"\nid: 3\ntext: \"Control Plane Configuration\"\ntype: \"controlplane\"\ngroups:\n  - id: 3.1\n    text: \"Authentication and Authorization\"\n    checks:\n      - id: 3.1.1\n        text: \"Client certificate authentication should not be used for users (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Alternative mechanisms provided by Kubernetes such as the use of OIDC should be\n          implemented in place of client certificates.\n        scored: false\n\n  - id: 3.2\n    text: \"Logging\"\n    checks:\n      - id: 3.2.1\n        text: \"Ensure that a minimal audit policy is created (Manual)\"\n        audit: \"cat $apiserverconf | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-policy-file\"\n              set: true\n        remediation: |\n          Create an audit policy file for your cluster.\n        scored: false\n\n      - id: 3.2.2\n        text: \"Ensure that the audit policy covers key security concerns (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Review the audit policy provided for the cluster and ensure that it covers\n          at least the following areas,\n          - Access to Secrets managed by the cluster. Care should be taken to only\n            log Metadata for requests to Secrets, ConfigMaps, and TokenReviews, in\n            order to avoid risk of logging sensitive data.\n          - Modification of Pod and Deployment objects.\n          - Use of `pods/exec`, `pods/portforward`, `pods/proxy` and `services/proxy`.\n          For most requests, minimally logging at the Metadata level is recommended\n          (the most basic level of logging).\n        scored: false\n"
  },
  {
    "path": "cfg/cis-1.24-microk8s/etcd.yaml",
    "content": "---\ncontrols:\nversion: \"cis-1.24\"\nid: 2\ntext: \"Etcd Node Configuration\"\ntype: \"etcd\"\ngroups:\n  - id: 2\n    text: \"Etcd Node Configuration\"\n    checks:\n      - id: 2.1\n        text: \"Ensure that the --cert-file and --key-file arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--cert-file\"\n              env: \"ETCD_CERT_FILE\"\n            - flag: \"--key-file\"\n              env: \"ETCD_KEY_FILE\"\n        remediation: |\n          Not applicable. MicroK8s used dqlite and the communication to this service is done through a\n          local socket (/var/snap/microk8s/current/var/kubernetes/backend/kine.sock:12379) accessible\n          to users with root permissions.\n        scored: false\n\n      - id: 2.2\n        text: \"Ensure that the --client-cert-auth argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--client-cert-auth\"\n              env: \"ETCD_CLIENT_CERT_AUTH\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Not applicable. MicroK8s used dqlite and the communication to this service is done through a\n          local socket (/var/snap/microk8s/current/var/kubernetes/backend/kine.sock:12379) accessible\n          to users with root permissions.\n        scored: false\n\n      - id: 2.3\n        text: \"Ensure that the --auto-tls argument is not set to true (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--auto-tls\"\n              env: \"ETCD_AUTO_TLS\"\n              set: false\n            - flag: \"--auto-tls\"\n              env: \"ETCD_AUTO_TLS\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Not applicable. MicroK8s used dqlite and the communication to this service is done through a\n          local socket (/var/snap/microk8s/current/var/kubernetes/backend/kine.sock:12379) accessible\n          to users with root permissions.\n        scored: false\n\n      - id: 2.4\n        text: \"Ensure that the --peer-cert-file and --peer-key-file arguments are set as appropriate (Automated)\"\n        audit: \"if test -e /var/snap/microk8s/current/var/kubernetes/backend/cluster.crt && test -e /var/snap/microk8s/current/var/kubernetes/backend/cluster.key; then echo 'certs-found'; fi\"\n        tests:\n          test_items:\n            - flag: \"certs-found\"\n        remediation: |\n          The certificate pair for dqlite and tls peer communication is\n          /var/snap/microk8s/current/var/kubernetes/backend/cluster.crt and\n          /var/snap/microk8s/current/var/kubernetes/backend/cluster.key.\n        scored: true\n\n      - id: 2.5\n        text: \"Ensure that the --peer-client-cert-auth argument is set to true (Automated)\"\n        audit: \"/bin/cat $etcdconf | /bin/grep enable-tls || true\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--enable-tls\"\n              compare:\n                op: eq\n                value: true\n            - flag: \"--enable-tls\"\n              set: false\n        remediation: |\n          MicroK8s used dqlite and tls peer communication uses is TLS if the --enable-tls is set in\n          /var/snap/microk8s/current/args/k8s-dqlite, set to true by default.\n        scored: true\n\n      - id: 2.6\n        text: \"Ensure that the --peer-auto-tls argument is not set to true (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--peer-auto-tls\"\n              env: \"ETCD_PEER_AUTO_TLS\"\n              set: false\n            - flag: \"--peer-auto-tls\"\n              env: \"ETCD_PEER_AUTO_TLS\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Not applicable. MicroK8s used dqlite and tls peer communication uses the certificates\n          created upon the snap creation.\n        scored: false\n\n      - id: 2.7\n        text: \"Ensure that a unique Certificate Authority is used for etcd (Manual)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--trusted-ca-file\"\n              env: \"ETCD_TRUSTED_CA_FILE\"\n        remediation: |\n          Not applicable. MicroK8s used dqlite and tls peer communication uses the certificates\n          created upon the snap creation.\n        scored: false\n"
  },
  {
    "path": "cfg/cis-1.24-microk8s/master.yaml",
    "content": "---\ncontrols:\nversion: \"cis-1.24\"\nid: 1\ntext: \"Control Plane Security Configuration\"\ntype: \"master\"\ngroups:\n  - id: 1.1\n    text: \"Control Plane Node Configuration Files\"\n    checks:\n      - id: 1.1.1\n        text: \"Ensure that the API server pod specification file permissions are set to 644 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $apiserverconf; then stat -c permissions=%a $apiserverconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the\n          control plane node.\n          For example, chmod 644 $apiserverconf\n        scored: true\n\n      - id: 1.1.2\n        text: \"Ensure that the API server pod specification file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $apiserverconf; then stat -c %U:%G $apiserverconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chown root:root $apiserverconf\n        scored: true\n\n      - id: 1.1.3\n        text: \"Ensure that the controller manager pod specification file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerconf; then stat -c permissions=%a $controllermanagerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chmod 600 $controllermanagerconf\n        scored: true\n\n      - id: 1.1.4\n        text: \"Ensure that the controller manager pod specification file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerconf; then stat -c %U:%G $controllermanagerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chown root:root $controllermanagerconf\n        scored: true\n\n      - id: 1.1.5\n        text: \"Ensure that the scheduler pod specification file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerconf; then stat -c permissions=%a $schedulerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chmod 600 $schedulerconf\n        scored: true\n\n      - id: 1.1.6\n        text: \"Ensure that the scheduler pod specification file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerconf; then stat -c %U:%G $schedulerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chown root:root $schedulerconf\n        scored: true\n\n      - id: 1.1.7\n        text: \"Ensure that the etcd pod specification file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $etcdconf; then stat -c permissions=%a $etcdconf; fi'\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod 600 $etcdconf\n        scored: true\n\n      - id: 1.1.8\n        text: \"Ensure that the etcd pod specification file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $etcdconf; then stat -c %U:%G $etcdconf; fi'\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root $etcdconf\n        scored: true\n\n      - id: 1.1.9\n        text: \"Ensure that the Container Network Interface file permissions are set to 600 or more restrictive (Manual)\"\n        audit: |\n          find /var/snap/microk8s/current/args/cni-network/10-calico.conflist -type f 2> /dev/null | xargs --no-run-if-empty stat -c permissions=%a\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chmod 600 <path/to/cni/files>\n        scored: false\n\n      - id: 1.1.10\n        text: \"Ensure that the Container Network Interface file ownership is set to root:root (Manual)\"\n        audit: |\n          ps -ef | grep $kubeletbin | grep -- --cni-conf-dir | sed 's%.*cni-conf-dir[= ]\\([^ ]*\\).*%\\1%' | xargs -I{} find {} -mindepth 1 | xargs --no-run-if-empty stat -c %U:%G\n          find /var/snap/microk8s/current/args/cni-network/10-calico.conflist -type f 2> /dev/null | xargs --no-run-if-empty stat -c %U:%G\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root <path/to/cni/files>\n        scored: false\n\n      # Etcd is not running on MicroK8s master nodes\n      - id: 1.1.11\n        text: \"Ensure that the etcd data directory permissions are set to 700 or more restrictive (Automated)\"\n        audit: |\n          DATA_DIR='/var/snap/microk8s/current/var/kubernetes/backend/'\n          if ! test -d \"$DATA_DIR\"; then DATA_DIR=$etcddatadir; fi\n          stat -c permissions=%a \"$DATA_DIR\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"700\"\n        remediation: |\n          On the etcd server node, get the etcd data directory, passed as an argument --data-dir,\n          from the command 'ps -ef | grep etcd'.\n          Run the below command (based on the etcd data directory found above). For example,\n          chmod 700 /var/snap/microk8s/current/var/kubernetes/backend/\n        scored: true\n\n      # Etcd is not running on MicroK8s master nodes\n      - id: 1.1.12\n        text: \"Ensure that the etcd data directory ownership is set to etcd:etcd (Automated)\"\n        audit: |\n          DATA_DIR='/var/snap/microk8s/current/var/kubernetes/backend/'\n          if ! test -d \"$DATA_DIR\"; then DATA_DIR=$etcddatadir; fi\n          stat -c %U:%G \"$DATA_DIR\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          On the etcd server node, get the etcd data directory, passed as an argument --data-dir,\n          from the command 'ps -ef | grep etcd'.\n          Run the below command (based on the etcd data directory found above).\n          For example, chown root:root /var/snap/microk8s/current/var/kubernetes/backend/\n        scored: true\n\n      - id: 1.1.13\n        text: \"Ensure that the admin.conf file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e /var/snap/microk8s/current/credentials/client.config; then stat -c permissions=%a /var/snap/microk8s/current/credentials/client.config; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chmod 600 /var/snap/microk8s/current/credentials/client.config\n        scored: true\n\n      - id: 1.1.14\n        text: \"Ensure that the admin.conf file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e /var/snap/microk8s/current/credentials/client.config; then stat -c %U:%G /var/snap/microk8s/current/credentials/client.config; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chown root:root /var/snap/microk8s/current/credentials/client.config\n        scored: true\n\n      - id: 1.1.15\n        text: \"Ensure that the scheduler.conf file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerkubeconfig; then stat -c permissions=%a $schedulerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod 600 $schedulerkubeconfig\n        scored: true\n\n      - id: 1.1.16\n        text: \"Ensure that the scheduler.conf file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerkubeconfig; then stat -c %U:%G $schedulerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root $schedulerkubeconfig\n        scored: true\n\n      - id: 1.1.17\n        text: \"Ensure that the controller-manager.conf file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerkubeconfig; then stat -c permissions=%a $controllermanagerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod 600 $controllermanagerkubeconfig\n        scored: true\n\n      - id: 1.1.18\n        text: \"Ensure that the controller-manager.conf file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerkubeconfig; then stat -c %U:%G $controllermanagerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root $controllermanagerkubeconfig\n        scored: true\n\n      - id: 1.1.19\n        text: \"Ensure that the Kubernetes PKI directory and file ownership is set to root:root (Automated)\"\n        audit: \"find /var/snap/microk8s/current/certs/ | xargs stat -c %U:%G\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown -R root:root /var/snap/microk8s/current/certs/\n        scored: true\n\n      - id: 1.1.20\n        text: \"Ensure that the Kubernetes PKI certificate file permissions are set to 600 or more restrictive (Manual)\"\n        audit: \"find /var/snap/microk8s/current/certs/ -name '*.crt' | xargs stat -c permissions=%a\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod -R 600 /var/snap/microk8s/current/certs/*.crt\n        scored: false\n\n      - id: 1.1.21\n        text: \"Ensure that the Kubernetes PKI key file permissions are set to 600 (Manual)\"\n        audit: \"find /var/snap/microk8s/current/certs/ -name '*.key' | xargs stat -c permissions=%a\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod -R 600 /var/snap/microk8s/current/certs/*.key\n        scored: false\n\n  - id: 1.2\n    text: \"API Server\"\n    checks:\n      - id: 1.2.1\n        text: \"Ensure that the --anonymous-auth argument is set to false (Manual)\"\n        audit: \"cat $apiserverconf | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--anonymous-auth\"\n              compare:\n                op: eq\n                value: false\n            - flag: \"--anonymous-auth\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the below parameter.\n          --anonymous-auth=false\n        scored: false\n\n      - id: 1.2.2\n        text: \"Ensure that the --token-auth-file parameter is not set (Automated)\"\n        audit: \"cat $apiserverconf | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--token-auth-file\"\n              set: false\n        remediation: |\n          Follow the documentation and configure alternate mechanisms for authentication. Then,\n          edit the API server pod specification file $apiserverconf\n          on the control plane node and remove the --token-auth-file=<filename> parameter.\n        scored: true\n\n      - id: 1.2.3\n        text: \"Ensure that the --DenyServiceExternalIPs is not set (Automated)\"\n        audit: \"cat $apiserverconf | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: nothave\n                value: \"DenyServiceExternalIPs\"\n            - flag: \"--enable-admission-plugins\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and remove the `DenyServiceExternalIPs`\n          from enabled admission plugins.\n        scored: true\n\n      - id: 1.2.4\n        text: \"Ensure that the --kubelet-client-certificate and --kubelet-client-key arguments are set as appropriate (Automated)\"\n        audit: \"cat $apiserverconf | grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--kubelet-client-certificate\"\n            - flag: \"--kubelet-client-key\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection between the\n          apiserver and kubelets. Then, edit API server pod specification file\n          $apiserverconf on the control plane node and set the\n          kubelet client certificate and key parameters as below.\n          --kubelet-client-certificate=<path/to/client-certificate-file>\n          --kubelet-client-key=<path/to/client-key-file>\n        scored: true\n\n      - id: 1.2.5\n        text: \"Ensure that the --kubelet-certificate-authority argument is set as appropriate (Automated)\"\n        audit: \"cat $apiserverconf | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--kubelet-certificate-authority\"\n        remediation: |\n          Follow the Kubernetes documentation and setup the TLS connection between\n          the apiserver and kubelets. Then, edit the API server pod specification file\n          $apiserverconf on the control plane node and set the\n          --kubelet-certificate-authority parameter to the path to the cert file for the certificate authority.\n          --kubelet-certificate-authority=<ca-string>\n        scored: true\n\n      - id: 1.2.6\n        text: \"Ensure that the --authorization-mode argument is not set to AlwaysAllow (Automated)\"\n        audit: \"cat $apiserverconf | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: nothave\n                value: \"AlwaysAllow\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --authorization-mode parameter to values other than AlwaysAllow.\n          One such example could be as below.\n          --authorization-mode=RBAC\n        scored: true\n\n      - id: 1.2.7\n        text: \"Ensure that the --authorization-mode argument includes Node (Automated)\"\n        audit: \"cat $apiserverconf | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: has\n                value: \"Node\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --authorization-mode parameter to a value that includes Node.\n          --authorization-mode=Node,RBAC\n        scored: true\n\n      - id: 1.2.8\n        text: \"Ensure that the --authorization-mode argument includes RBAC (Automated)\"\n        audit: \"cat $apiserverconf | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: has\n                value: \"RBAC\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --authorization-mode parameter to a value that includes RBAC,\n          for example `--authorization-mode=Node,RBAC`.\n        scored: true\n\n      - id: 1.2.9\n        text: \"Ensure that the admission control plugin EventRateLimit is set (Manual)\"\n        audit: \"cat $apiserverconf | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"EventRateLimit\"\n        remediation: |\n          Follow the Kubernetes documentation and set the desired limits in a configuration file.\n          Then, edit the API server pod specification file $apiserverconf\n          and set the below parameters.\n          --enable-admission-plugins=...,EventRateLimit,...\n          --admission-control-config-file=<path/to/configuration/file>\n        scored: false\n\n      - id: 1.2.10\n        text: \"Ensure that the admission control plugin AlwaysAdmit is not set (Automated)\"\n        audit: \"cat $apiserverconf | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: nothave\n                value: AlwaysAdmit\n            - flag: \"--enable-admission-plugins\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and either remove the --enable-admission-plugins parameter, or set it to a\n          value that does not include AlwaysAdmit.\n        scored: true\n\n      - id: 1.2.11\n        text: \"Ensure that the admission control plugin AlwaysPullImages is set (Manual)\"\n        audit: \"cat $apiserverconf | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"AlwaysPullImages\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --enable-admission-plugins parameter to include\n          AlwaysPullImages.\n          --enable-admission-plugins=...,AlwaysPullImages,...\n        scored: false\n\n      - id: 1.2.12\n        text: \"Ensure that the admission control plugin SecurityContextDeny is set if PodSecurityPolicy is not used (Manual)\"\n        audit: \"cat $apiserverconf | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"SecurityContextDeny\"\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"PodSecurityPolicy\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --enable-admission-plugins parameter to include\n          SecurityContextDeny, unless PodSecurityPolicy is already in place.\n          --enable-admission-plugins=...,SecurityContextDeny,...\n        scored: false\n\n      - id: 1.2.13\n        text: \"Ensure that the admission control plugin ServiceAccount is set (Automated)\"\n        audit: \"cat $apiserverconf | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--disable-admission-plugins\"\n              compare:\n                op: nothave\n                value: \"ServiceAccount\"\n            - flag: \"--disable-admission-plugins\"\n              set: false\n        remediation: |\n          Follow the documentation and create ServiceAccount objects as per your environment.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and ensure that the --disable-admission-plugins parameter is set to a\n          value that does not include ServiceAccount.\n        scored: true\n\n      - id: 1.2.14\n        text: \"Ensure that the admission control plugin NamespaceLifecycle is set (Automated)\"\n        audit: \"cat $apiserverconf | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--disable-admission-plugins\"\n              compare:\n                op: nothave\n                value: \"NamespaceLifecycle\"\n            - flag: \"--disable-admission-plugins\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --disable-admission-plugins parameter to\n          ensure it does not include NamespaceLifecycle.\n        scored: true\n\n      - id: 1.2.15\n        text: \"Ensure that the admission control plugin NodeRestriction is set (Automated)\"\n        audit: \"cat $apiserverconf | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"NodeRestriction\"\n        remediation: |\n          Follow the Kubernetes documentation and configure NodeRestriction plug-in on kubelets.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --enable-admission-plugins parameter to a\n          value that includes NodeRestriction.\n          --enable-admission-plugins=...,NodeRestriction,...\n        scored: true\n\n      - id: 1.2.16\n        text: \"Ensure that the --secure-port argument is not set to 0 (Automated)\"\n        audit: \"cat $apiserverconf | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--secure-port\"\n              compare:\n                op: gt\n                value: 0\n            - flag: \"--secure-port\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and either remove the --secure-port parameter or\n          set it to a different (non-zero) desired port.\n        scored: true\n\n      - id: 1.2.17\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: \"cat $apiserverconf | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the below parameter.\n          --profiling=false\n        scored: true\n\n      - id: 1.2.18\n        text: \"Ensure that the --audit-log-path argument is set (Automated)\"\n        audit: \"cat $apiserverconf | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-path\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --audit-log-path parameter to a suitable path and\n          file where you would like audit logs to be written, for example,\n          --audit-log-path=/var/log/apiserver/audit.log\n        scored: true\n\n      - id: 1.2.19\n        text: \"Ensure that the --audit-log-maxage argument is set to 30 or as appropriate (Automated)\"\n        audit: \"cat $apiserverconf | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxage\"\n              compare:\n                op: gte\n                value: 30\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --audit-log-maxage parameter to 30\n          or as an appropriate number of days, for example,\n          --audit-log-maxage=30\n        scored: true\n\n      - id: 1.2.20\n        text: \"Ensure that the --audit-log-maxbackup argument is set to 10 or as appropriate (Automated)\"\n        audit: \"cat $apiserverconf | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxbackup\"\n              compare:\n                op: gte\n                value: 10\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --audit-log-maxbackup parameter to 10 or to an appropriate\n          value. For example,\n          --audit-log-maxbackup=10\n        scored: true\n\n      - id: 1.2.21\n        text: \"Ensure that the --audit-log-maxsize argument is set to 100 or as appropriate (Automated)\"\n        audit: \"cat $apiserverconf | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxsize\"\n              compare:\n                op: gte\n                value: 100\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --audit-log-maxsize parameter to an appropriate size in MB.\n          For example, to set it as 100 MB, --audit-log-maxsize=100\n        scored: true\n\n      - id: 1.2.22\n        text: \"Ensure that the --request-timeout argument is set as appropriate (Manual)\"\n        audit: \"cat $apiserverconf | grep -v grep\"\n        type: manual\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          and set the below parameter as appropriate and if needed.\n          For example, --request-timeout=300s\n        scored: false\n\n      - id: 1.2.23\n        text: \"Ensure that the --service-account-lookup argument is set to true (Automated)\"\n        audit: \"cat $apiserverconf | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--service-account-lookup\"\n              set: false\n            - flag: \"--service-account-lookup\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the below parameter.\n          --service-account-lookup=true\n          Alternatively, you can delete the --service-account-lookup parameter from this file so\n          that the default takes effect.\n        scored: true\n\n      - id: 1.2.24\n        text: \"Ensure that the --service-account-key-file argument is set as appropriate (Automated)\"\n        audit: \"cat $apiserverconf | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--service-account-key-file\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --service-account-key-file parameter\n          to the public key file for service accounts. For example,\n          --service-account-key-file=<filename>\n        scored: true\n\n      # MicroK8s does not use etcd. The API server talk to a local dqlite instance\n      - id: 1.2.25\n        text: \"Ensure that the --etcd-certfile and --etcd-keyfile arguments are set as appropriate (Automated)\"\n        audit: \"cat $apiserverconf | grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--etcd-certfile\"\n            - flag: \"--etcd-keyfile\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection between the apiserver and etcd.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the etcd certificate and key file parameters.\n          --etcd-certfile=<path/to/client-certificate-file>\n          --etcd-keyfile=<path/to/client-key-file>\n        scored: false\n\n      - id: 1.2.26\n        text: \"Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Automated)\"\n        audit: \"cat $apiserverconf | grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--tls-cert-file\"\n            - flag: \"--tls-private-key-file\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection on the apiserver.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the TLS certificate and private key file parameters.\n          --tls-cert-file=<path/to/tls-certificate-file>\n          --tls-private-key-file=<path/to/tls-key-file>\n        scored: true\n\n      - id: 1.2.27\n        text: \"Ensure that the --client-ca-file argument is set as appropriate (Automated)\"\n        audit: \"cat $apiserverconf | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--client-ca-file\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection on the apiserver.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the client certificate authority file.\n          --client-ca-file=<path/to/client-ca-file>\n        scored: true\n\n      - id: 1.2.28\n        text: \"Ensure that the --etcd-cafile argument is set as appropriate (Automated)\"\n        audit: \"cat $apiserverconf | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--etcd-cafile\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection between the apiserver and etcd.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the etcd certificate authority file parameter.\n          --etcd-cafile=<path/to/ca-file>\n        scored: false\n\n      - id: 1.2.29\n        text: \"Ensure that the --encryption-provider-config argument is set as appropriate (Manual)\"\n        audit: \"cat $apiserverconf | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--encryption-provider-config\"\n        remediation: |\n          Follow the Kubernetes documentation and configure a EncryptionConfig file.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --encryption-provider-config parameter to the path of that file.\n          For example, --encryption-provider-config=</path/to/EncryptionConfig/File>\n        scored: false\n\n      - id: 1.2.30\n        text: \"Ensure that encryption providers are appropriately configured (Manual)\"\n        audit: |\n          ENCRYPTION_PROVIDER_CONFIG=$(cat $apiserverconf | grep -- --encryption-provider-config | sed 's%.*encryption-provider-config[= ]\\([^ ]*\\).*%\\1%')\n          if test -e $ENCRYPTION_PROVIDER_CONFIG; then grep -A1 'providers:' $ENCRYPTION_PROVIDER_CONFIG | tail -n1 | grep -o \"[A-Za-z]*\" | sed 's/^/provider=/'; fi\n        tests:\n          test_items:\n            - flag: \"provider\"\n              compare:\n                op: valid_elements\n                value: \"aescbc,kms,secretbox\"\n        remediation: |\n          Follow the Kubernetes documentation and configure a EncryptionConfig file.\n          In this file, choose aescbc, kms or secretbox as the encryption provider.\n        scored: false\n\n      - id: 1.2.31\n        text: \"Ensure that the API Server only makes use of Strong Cryptographic Ciphers (Manual)\"\n        audit: \"cat $apiserverconf | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--tls-cipher-suites\"\n              compare:\n                op: valid_elements\n                value: \"TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,TLS_CHACHA20_POLY1305_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,TLS_RSA_WITH_3DES_EDE_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_256_GCM_SHA384\"\n        remediation: |\n          Edit the API server pod specification file /etc/kubernetes/manifests/kube-apiserver.yaml\n          on the control plane node and set the below parameter.\n          --tls-cipher-suites=TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,TLS_CHACHA20_POLY1305_SHA256,\n          TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,\n          TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,\n          TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,\n          TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,\n          TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,\n          TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,TLS_RSA_WITH_3DES_EDE_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA,\n          TLS_RSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_256_GCM_SHA384\n        scored: false\n\n  - id: 1.3\n    text: \"Controller Manager\"\n    checks:\n      - id: 1.3.1\n        text: \"Ensure that the --terminated-pod-gc-threshold argument is set as appropriate (Manual)\"\n        audit: \"cat $controllermanagerconf | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--terminated-pod-gc-threshold\"\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the --terminated-pod-gc-threshold to an appropriate threshold,\n          for example, --terminated-pod-gc-threshold=10\n        scored: false\n\n      - id: 1.3.2\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: \"cat $controllermanagerconf | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the below parameter.\n          --profiling=false\n        scored: true\n\n      - id: 1.3.3\n        text: \"Ensure that the --use-service-account-credentials argument is set to true (Automated)\"\n        audit: \"cat $controllermanagerconf | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--use-service-account-credentials\"\n              compare:\n                op: noteq\n                value: false\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node to set the below parameter.\n          --use-service-account-credentials=true\n        scored: true\n\n      - id: 1.3.4\n        text: \"Ensure that the --service-account-private-key-file argument is set as appropriate (Automated)\"\n        audit: \"cat $controllermanagerconf | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--service-account-private-key-file\"\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the --service-account-private-key-file parameter\n          to the private key file for service accounts.\n          --service-account-private-key-file=<filename>\n        scored: true\n\n      - id: 1.3.5\n        text: \"Ensure that the --root-ca-file argument is set as appropriate (Automated)\"\n        audit: \"cat $controllermanagerconf | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--root-ca-file\"\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the --root-ca-file parameter to the certificate bundle file`.\n          --root-ca-file=<path/to/file>\n        scored: true\n\n      - id: 1.3.6\n        text: \"Ensure that the RotateKubeletServerCertificate argument is set to true (Automated)\"\n        audit: \"cat $controllermanagerconf | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--feature-gates\"\n              compare:\n                op: nothave\n                value: \"RotateKubeletServerCertificate=false\"\n              set: true\n            - flag: \"--feature-gates\"\n              set: false\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the --feature-gates parameter to include RotateKubeletServerCertificate=true.\n          --feature-gates=RotateKubeletServerCertificate=true\n        scored: true\n\n      - id: 1.3.7\n        text: \"Ensure that the --bind-address argument is set to 127.0.0.1 (Automated)\"\n        audit: \"cat $controllermanagerconf | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--bind-address\"\n              compare:\n                op: eq\n                value: \"127.0.0.1\"\n            - flag: \"--bind-address\"\n              set: false\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and ensure the correct value for the --bind-address parameter\n        scored: true\n\n  - id: 1.4\n    text: \"Scheduler\"\n    checks:\n      - id: 1.4.1\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: \"cat $schedulerconf | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the Scheduler pod specification file $schedulerconf file\n          on the control plane node and set the below parameter.\n          --profiling=false\n        scored: true\n\n      - id: 1.4.2\n        text: \"Ensure that the --bind-address argument is set to 127.0.0.1 (Automated)\"\n        audit: \"cat $schedulerconf | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--bind-address\"\n              compare:\n                op: eq\n                value: \"127.0.0.1\"\n            - flag: \"--bind-address\"\n              set: false\n        remediation: |\n          Edit the Scheduler pod specification file $schedulerconf\n          on the control plane node and ensure the correct value for the --bind-address parameter\n        scored: true\n"
  },
  {
    "path": "cfg/cis-1.24-microk8s/node.yaml",
    "content": "---\ncontrols:\nversion: \"cis-1.24\"\nid: 4\ntext: \"Worker Node Security Configuration\"\ntype: \"node\"\ngroups:\n  - id: 4.1\n    text: \"Worker Node Configuration Files\"\n    checks:\n      - id: 4.1.1\n        text: \"Ensure that the kubelet service file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $kubeletsvc; then stat -c permissions=%a $kubeletsvc; fi' \"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example, chmod 600 $kubeletsvc\n        scored: true\n\n      - id: 4.1.2\n        text: \"Ensure that the kubelet service file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $kubeletsvc; then stat -c %U:%G $kubeletsvc; fi' \"\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chown root:root $kubeletsvc\n        scored: true\n\n      - id: 4.1.3\n        text: \"If proxy kubeconfig file exists ensure permissions are set to 600 or more restrictive (Manual)\"\n        audit: \"/bin/sh -c 'if test -e $proxykubeconfig; then stat -c permissions=%a $proxykubeconfig; fi' \"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"permissions\"\n              set: true\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chmod 600 $proxykubeconfig\n        scored: false\n\n      - id: 4.1.4\n        text: \"If proxy kubeconfig file exists ensure ownership is set to root:root (Manual)\"\n        audit: \"/bin/sh -c 'if test -e $proxykubeconfig; then stat -c %U:%G $proxykubeconfig; fi' \"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example, chown root:root $proxykubeconfig\n        scored: false\n\n      - id: 4.1.5\n        text: \"Ensure that the --kubeconfig kubelet.conf file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $kubeletkubeconfig; then stat -c permissions=%a $kubeletkubeconfig; fi' \"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chmod 600 $kubeletkubeconfig\n        scored: true\n\n      - id: 4.1.6\n        text: \"Ensure that the --kubeconfig kubelet.conf file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $kubeletkubeconfig; then stat -c %U:%G $kubeletkubeconfig; fi' \"\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chown root:root $kubeletkubeconfig\n        scored: true\n\n      - id: 4.1.7\n        text: \"Ensure that the certificate authorities file permissions are set to 600 or more restrictive (Manual)\"\n        audit: |\n          CAFILE=$(ps -ef | grep kubelet | grep -v apiserver | grep -- --client-ca-file= | awk -F '--client-ca-file=' '{print $2}' | awk '{print $1}')\n          if test -z $CAFILE; then CAFILE=$kubeletcafile; fi\n          if test -e $CAFILE; then stat -c permissions=%a $CAFILE; fi\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the following command to modify the file permissions of the\n          --client-ca-file chmod 600 <filename>\n        scored: false\n\n      - id: 4.1.8\n        text: \"Ensure that the client certificate authorities file ownership is set to root:root (Manual)\"\n        audit: |\n          CAFILE=$(ps -ef | grep kubelet | grep -v apiserver | grep -- --client-ca-file= | awk -F '--client-ca-file=' '{print $2}' | awk '{print $1}')\n          if test -z $CAFILE; then CAFILE=$kubeletcafile; fi\n          if test -e $CAFILE; then stat -c %U:%G $CAFILE; fi\n        tests:\n          test_items:\n            - flag: root:root\n              compare:\n                op: eq\n                value: root:root\n        remediation: |\n          Run the following command to modify the ownership of the --client-ca-file.\n          chown root:root <filename>\n        scored: false\n\n      - id: 4.1.9\n        text: \"If the kubelet config.yaml configuration file is being used validate permissions set to 600 or more restrictive (Manual)\"\n        audit: \"/bin/sh -c 'if test -e $kubeletconf; then stat -c permissions=%a $kubeletconf; fi' \"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the following command (using the config file location identified in the Audit step)\n          chmod 600 $kubeletconf\n        scored: false\n\n      - id: 4.1.10\n        text: \"If the kubelet config.yaml configuration file is being used validate file ownership is set to root:root (Manual)\"\n        audit: \"/bin/sh -c 'if test -e $kubeletconf; then stat -c %U:%G $kubeletconf; fi' \"\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the following command (using the config file location identified in the Audit step)\n          chown root:root $kubeletconf\n        scored: false\n\n  - id: 4.2\n    text: \"Kubelet\"\n    checks:\n      - id: 4.2.1\n        text: \"Ensure that the --anonymous-auth argument is set to false (Automated)\"\n        audit: \"cat $kubeletconf\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: \"--anonymous-auth\"\n              path: \"{.authentication.anonymous.enabled}\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          If using a Kubelet config file, edit the file to set `authentication: anonymous: enabled` to\n          `false`.\n          If using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          `--anonymous-auth=false`\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.2\n        text: \"Ensure that the --authorization-mode argument is not set to AlwaysAllow (Automated)\"\n        audit: \"cat $kubeletconf\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --authorization-mode\n              path: \"{.authorization.mode}\"\n              compare:\n                op: nothave\n                value: AlwaysAllow\n        remediation: |\n          If using a Kubelet config file, edit the file to set `authorization.mode` to Webhook. If\n          using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_AUTHZ_ARGS variable.\n          --authorization-mode=Webhook\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.3\n        text: \"Ensure that the --client-ca-file argument is set as appropriate (Automated)\"\n        audit: \"cat $kubeletconf\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --client-ca-file\n              path: \"{.authentication.x509.clientCAFile}\"\n        remediation: |\n          If using a Kubelet config file, edit the file to set `authentication.x509.clientCAFile` to\n          the location of the client CA file.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_AUTHZ_ARGS variable.\n          --client-ca-file=<path/to/client-ca-file>\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.4\n        text: \"Verify that the --read-only-port argument is set to 0 (Manual)\"\n        audit: \"cat $kubeletconf\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--read-only-port\"\n              path: \"{.readOnlyPort}\"\n              compare:\n                op: eq\n                value: 0\n            - flag: \"--read-only-port\"\n              path: \"{.readOnlyPort}\"\n              set: false\n        remediation: |\n          If using a Kubelet config file, edit the file to set `readOnlyPort` to 0.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --read-only-port=0\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.5\n        text: \"Ensure that the --streaming-connection-idle-timeout argument is not set to 0 (Manual)\"\n        audit: \"cat $kubeletconf\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --streaming-connection-idle-timeout\n              path: \"{.streamingConnectionIdleTimeout}\"\n              compare:\n                op: noteq\n                value: 0\n            - flag: --streaming-connection-idle-timeout\n              path: \"{.streamingConnectionIdleTimeout}\"\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to set `streamingConnectionIdleTimeout` to a\n          value other than 0.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --streaming-connection-idle-timeout=5m\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.6\n        text: \"Ensure that the --protect-kernel-defaults argument is set to true (Automated)\"\n        audit: \"cat $kubeletconf\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --protect-kernel-defaults\n              path: \"{.protectKernelDefaults}\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          If using a Kubelet config file, edit the file to set `protectKernelDefaults` to `true`.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --protect-kernel-defaults=true\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.7\n        text: \"Ensure that the --make-iptables-util-chains argument is set to true (Automated)\"\n        audit: \"cat $kubeletconf\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --make-iptables-util-chains\n              path: \"{.makeIPTablesUtilChains}\"\n              compare:\n                op: eq\n                value: true\n            - flag: --make-iptables-util-chains\n              path: \"{.makeIPTablesUtilChains}\"\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to set `makeIPTablesUtilChains` to `true`.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          remove the --make-iptables-util-chains argument from the\n          KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.8\n        text: \"Ensure that the --hostname-override argument is not set (Manual)\"\n        # This is one of those properties that can only be set as a command line argument.\n        # To check if the property is set as expected, we need to parse the kubelet command\n        # instead reading the Kubelet Configuration file.\n        audit: \"cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --hostname-override\n              set: false\n        remediation: |\n          Edit the kubelet service file $kubeletsvc\n          on each worker node and remove the --hostname-override argument from the\n          KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.9\n        text: \"Ensure that the eventRecordQPS argument is set to a level which ensures appropriate event capture (Manual)\"\n        audit: \"cat $kubeletconf\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --event-qps\n              path: \"{.eventRecordQPS}\"\n              compare:\n                op: eq\n                value: 0\n        remediation: |\n          If using a Kubelet config file, edit the file to set `eventRecordQPS` to an appropriate level.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.10\n        text: \"Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Manual)\"\n        audit: \"cat $kubeletconf\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --tls-cert-file\n              path: \"{.tlsCertFile}\"\n            - flag: --tls-private-key-file\n              path: \"{.tlsPrivateKeyFile}\"\n        remediation: |\n          If using a Kubelet config file, edit the file to set `tlsCertFile` to the location\n          of the certificate file to use to identify this Kubelet, and `tlsPrivateKeyFile`\n          to the location of the corresponding private key file.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameters in KUBELET_CERTIFICATE_ARGS variable.\n          --tls-cert-file=<path/to/tls-certificate-file>\n          --tls-private-key-file=<path/to/tls-key-file>\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.11\n        text: \"Ensure that the --rotate-certificates argument is not set to false (Automated)\"\n        audit: \"cat $kubeletconf\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --rotate-certificates\n              path: \"{.rotateCertificates}\"\n              compare:\n                op: eq\n                value: true\n            - flag: --rotate-certificates\n              path: \"{.rotateCertificates}\"\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to add the line `rotateCertificates` to `true` or\n          remove it altogether to use the default value.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          remove --rotate-certificates=false argument from the KUBELET_CERTIFICATE_ARGS\n          variable.\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.12\n        text: \"Verify that the RotateKubeletServerCertificate argument is set to true (Manual)\"\n        audit: \"cat $kubeletconf\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: RotateKubeletServerCertificate\n              path: \"{.featureGates.RotateKubeletServerCertificate}\"\n              compare:\n                op: nothave\n                value: false\n            - flag: RotateKubeletServerCertificate\n              path: \"{.featureGates.RotateKubeletServerCertificate}\"\n              set: false\n        remediation: |\n          Edit the kubelet service file $kubeletsvc\n          on each worker node and set the below parameter in KUBELET_CERTIFICATE_ARGS variable.\n          --feature-gates=RotateKubeletServerCertificate=true\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.13\n        text: \"Ensure that the Kubelet only makes use of Strong Cryptographic Ciphers (Manual)\"\n        audit: \"cat $kubeletconf\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --tls-cipher-suites\n              path: \"{range .tlsCipherSuites[:]}{}{','}{end}\"\n              compare:\n                op: valid_elements\n                value: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\n        remediation: |\n          If using a Kubelet config file, edit the file to set `tlsCipherSuites` to\n          TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\n          or to a subset of these values.\n          If using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the --tls-cipher-suites parameter as follows, or to a subset of these values.\n          --tls-cipher-suites=TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n"
  },
  {
    "path": "cfg/cis-1.24-microk8s/policies.yaml",
    "content": "---\ncontrols:\nversion: \"cis-1.24\"\nid: 5\ntext: \"Kubernetes Policies\"\ntype: \"policies\"\ngroups:\n  - id: 5.1\n    text: \"RBAC and Service Accounts\"\n    checks:\n      - id: 5.1.1\n        text: \"Ensure that the cluster-admin role is only used where required (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Identify all clusterrolebindings to the cluster-admin role. Check if they are used and\n          if they need this role or if they could use a role with fewer privileges.\n          Where possible, first bind users to a lower privileged role and then remove the\n          clusterrolebinding to the cluster-admin role :\n          kubectl delete clusterrolebinding [name]\n        scored: false\n\n      - id: 5.1.2\n        text: \"Minimize access to secrets (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove get, list and watch access to Secret objects in the cluster.\n        scored: false\n\n      - id: 5.1.3\n        text: \"Minimize wildcard use in Roles and ClusterRoles (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible replace any use of wildcards in clusterroles and roles with specific\n          objects or actions.\n        scored: false\n\n      - id: 5.1.4\n        text: \"Minimize access to create pods (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove create access to pod objects in the cluster.\n        scored: false\n\n      - id: 5.1.5\n        text: \"Ensure that default service accounts are not actively used. (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Create explicit service accounts wherever a Kubernetes workload requires specific access\n          to the Kubernetes API server.\n          Modify the configuration of each default service account to include this value\n          automountServiceAccountToken: false\n        scored: false\n\n      - id: 5.1.6\n        text: \"Ensure that Service Account Tokens are only mounted where necessary (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Modify the definition of pods and service accounts which do not need to mount service\n          account tokens to disable it.\n        scored: false\n\n      - id: 5.1.7\n        text: \"Avoid use of system:masters group (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Remove the system:masters group from all users in the cluster.\n        scored: false\n\n      - id: 5.1.8\n        text: \"Limit use of the Bind, Impersonate and Escalate permissions in the Kubernetes cluster (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove the impersonate, bind and escalate rights from subjects.\n        scored: false\n\n  - id: 5.2\n    text: \"Pod Security Standards\"\n    checks:\n      - id: 5.2.1\n        text: \"Ensure that the cluster has at least one active policy control mechanism in place (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that either Pod Security Admission or an external policy control system is in place\n          for every namespace which contains user workloads.\n        scored: false\n\n      - id: 5.2.2\n        text: \"Minimize the admission of privileged containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of privileged containers.\n        scored: false\n\n      - id: 5.2.3\n        text: \"Minimize the admission of containers wishing to share the host process ID namespace (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of `hostPID` containers.\n        scored: false\n\n      - id: 5.2.4\n        text: \"Minimize the admission of containers wishing to share the host IPC namespace (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of `hostIPC` containers.\n        scored: false\n\n      - id: 5.2.5\n        text: \"Minimize the admission of containers wishing to share the host network namespace (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of `hostNetwork` containers.\n        scored: false\n\n      - id: 5.2.6\n        text: \"Minimize the admission of containers with allowPrivilegeEscalation (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers with `.spec.allowPrivilegeEscalation` set to `true`.\n        scored: false\n\n      - id: 5.2.7\n        text: \"Minimize the admission of root containers (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Create a policy for each namespace in the cluster, ensuring that either `MustRunAsNonRoot`\n          or `MustRunAs` with the range of UIDs not including 0, is set.\n        scored: false\n\n      - id: 5.2.8\n        text: \"Minimize the admission of containers with the NET_RAW capability (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers with the `NET_RAW` capability.\n        scored: false\n\n      - id: 5.2.9\n        text: \"Minimize the admission of containers with added capabilities (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that `allowedCapabilities` is not present in policies for the cluster unless\n          it is set to an empty array.\n        scored: false\n\n      - id: 5.2.10\n        text: \"Minimize the admission of containers with capabilities assigned (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Review the use of capabilities in applications running on your cluster. Where a namespace\n          contains applications which do not require any Linux capabities to operate consider adding\n          a PSP which forbids the admission of containers which do not drop all capabilities.\n        scored: false\n\n      - id: 5.2.11\n        text: \"Minimize the admission of Windows HostProcess containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers that have `.securityContext.windowsOptions.hostProcess` set to `true`.\n        scored: false\n\n      - id: 5.2.12\n        text: \"Minimize the admission of HostPath volumes (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers with `hostPath` volumes.\n        scored: false\n\n      - id: 5.2.13\n        text: \"Minimize the admission of containers which use HostPorts (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers which use `hostPort` sections.\n        scored: false\n\n  - id: 5.3\n    text: \"Network Policies and CNI\"\n    checks:\n      - id: 5.3.1\n        text: \"Ensure that the CNI in use supports NetworkPolicies (Manual)\"\n        type: \"manual\"\n        remediation: |\n          If the CNI plugin in use does not support network policies, consideration should be given to\n          making use of a different plugin, or finding an alternate mechanism for restricting traffic\n          in the Kubernetes cluster.\n        scored: false\n\n      - id: 5.3.2\n        text: \"Ensure that all Namespaces have NetworkPolicies defined (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the documentation and create NetworkPolicy objects as you need them.\n        scored: false\n\n  - id: 5.4\n    text: \"Secrets Management\"\n    checks:\n      - id: 5.4.1\n        text: \"Prefer using Secrets as files over Secrets as environment variables (Manual)\"\n        type: \"manual\"\n        remediation: |\n          If possible, rewrite application code to read Secrets from mounted secret files, rather than\n          from environment variables.\n        scored: false\n\n      - id: 5.4.2\n        text: \"Consider external secret storage (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Refer to the Secrets management options offered by your cloud provider or a third-party\n          secrets management solution.\n        scored: false\n\n  - id: 5.5\n    text: \"Extensible Admission Control\"\n    checks:\n      - id: 5.5.1\n        text: \"Configure Image Provenance using ImagePolicyWebhook admission controller (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and setup image provenance.\n        scored: false\n\n  - id: 5.7\n    text: \"General Policies\"\n    checks:\n      - id: 5.7.1\n        text: \"Create administrative boundaries between resources using namespaces (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the documentation and create namespaces for objects in your deployment as you need\n          them.\n        scored: false\n\n      - id: 5.7.2\n        text: \"Ensure that the seccomp profile is set to docker/default in your Pod definitions (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Use `securityContext` to enable the docker/default seccomp profile in your pod definitions.\n          An example is as below:\n            securityContext:\n              seccompProfile:\n                type: RuntimeDefault\n        scored: false\n\n      - id: 5.7.3\n        text: \"Apply SecurityContext to your Pods and Containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and apply SecurityContexts to your Pods. For a\n          suggested list of SecurityContexts, you may refer to the CIS Security Benchmark for Docker\n          Containers.\n        scored: false\n\n      - id: 5.7.4\n        text: \"The default namespace should not be used (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that namespaces are created to allow for appropriate segregation of Kubernetes\n          resources and that all new resources are created in a specific namespace.\n        scored: false\n"
  },
  {
    "path": "cfg/cis-1.5/config.yaml",
    "content": "---\n## Version-specific settings that override the values in cfg/config.yaml\n"
  },
  {
    "path": "cfg/cis-1.5/controlplane.yaml",
    "content": "---\ncontrols:\nversion: \"cis-1.5\"\nid: 3\ntext: \"Control Plane Configuration\"\ntype: \"controlplane\"\ngroups:\n  - id: 3.1\n    text: \"Authentication and Authorization\"\n    checks:\n      - id: 3.1.1\n        text: \"Client certificate authentication should not be used for users (Not Scored)\"\n        type: \"manual\"\n        remediation: |\n          Alternative mechanisms provided by Kubernetes such as the use of OIDC should be\n          implemented in place of client certificates.\n        scored: false\n\n  - id: 3.2\n    text: \"Logging\"\n    checks:\n      - id: 3.2.1\n        text: \"Ensure that a minimal audit policy is created (Scored)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-policy-file\"\n              set: true\n        remediation: |\n          Create an audit policy file for your cluster.\n        scored: true\n\n      - id: 3.2.2\n        text: \"Ensure that the audit policy covers key security concerns (Not Scored)\"\n        type: \"manual\"\n        remediation: |\n          Consider modification of the audit policy in use on the cluster to include these items, at a\n          minimum.\n        scored: false\n"
  },
  {
    "path": "cfg/cis-1.5/etcd.yaml",
    "content": "---\ncontrols:\nversion: \"cis-1.5\"\nid: 2\ntext: \"Etcd Node Configuration\"\ntype: \"etcd\"\ngroups:\n  - id: 2\n    text: \"Etcd Node Configuration Files\"\n    checks:\n      - id: 2.1\n        text: \"Ensure that the --cert-file and --key-file arguments are set as appropriate (Scored)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--cert-file\"\n              set: true\n            - flag: \"--key-file\"\n              set: true\n        remediation: |\n          Follow the etcd service documentation and configure TLS encryption.\n          Then, edit the etcd pod specification file /etc/kubernetes/manifests/etcd.yaml\n          on the master node and set the below parameters.\n          --cert-file=</path/to/ca-file>\n          --key-file=</path/to/key-file>\n        scored: true\n\n      - id: 2.2\n        text: \"Ensure that the --client-cert-auth argument is set to true (Scored)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--client-cert-auth\"\n              compare:\n                op: eq\n                value: true\n              set: true\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and set the below parameter.\n          --client-cert-auth=\"true\"\n        scored: true\n\n      - id: 2.3\n        text: \"Ensure that the --auto-tls argument is not set to true (Scored)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--auto-tls\"\n              set: false\n            - flag: \"--auto-tls\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and either remove the --auto-tls parameter or set it to false.\n            --auto-tls=false\n        scored: true\n\n      - id: 2.4\n        text: \"Ensure that the --peer-cert-file and --peer-key-file arguments are\n        set as appropriate (Scored)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--peer-cert-file\"\n              set: true\n            - flag: \"--peer-key-file\"\n              set: true\n        remediation: |\n          Follow the etcd service documentation and configure peer TLS encryption as appropriate\n          for your etcd cluster. Then, edit the etcd pod specification file $etcdconf on the\n          master node and set the below parameters.\n          --peer-client-file=</path/to/peer-cert-file>\n          --peer-key-file=</path/to/peer-key-file>\n        scored: true\n\n      - id: 2.5\n        text: \"Ensure that the --peer-client-cert-auth argument is set to true (Scored)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--peer-client-cert-auth\"\n              compare:\n                op: eq\n                value: true\n              set: true\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and set the below parameter.\n          --peer-client-cert-auth=true\n        scored: true\n\n      - id: 2.6\n        text: \"Ensure that the --peer-auto-tls argument is not set to true (Scored)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--peer-auto-tls\"\n              set: false\n            - flag: \"--peer-auto-tls\"\n              compare:\n                op: eq\n                value: false\n              set: true\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and either remove the --peer-auto-tls parameter or set it to false.\n          --peer-auto-tls=false\n        scored: true\n\n      - id: 2.7\n        text: \"Ensure that a unique Certificate Authority is used for etcd (Not Scored)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--trusted-ca-file\"\n              set: true\n        remediation: |\n          [Manual test]\n          Follow the etcd documentation and create a dedicated certificate authority setup for the\n          etcd service.\n          Then, edit the etcd pod specification file $etcdconf on the\n          master node and set the below parameter.\n          --trusted-ca-file=</path/to/ca-file>\n        scored: false\n"
  },
  {
    "path": "cfg/cis-1.5/master.yaml",
    "content": "---\ncontrols:\nversion: \"cis-1.5\"\nid: 1\ntext: \"Master Node Security Configuration\"\ntype: \"master\"\ngroups:\n  - id: 1.1\n    text: \"Master Node Configuration Files\"\n    checks:\n      - id: 1.1.1\n        text: \"Ensure that the API server pod specification file permissions are set to 644 or more restrictive (Scored)\"\n        audit: \"/bin/sh -c 'if test -e $apiserverconf; then stat -c permissions=%a $apiserverconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the\n          master node.\n          For example, chmod 644 $apiserverconf\n        scored: true\n\n      - id: 1.1.2\n        text: \"Ensure that the API server pod specification file ownership is set to root:root (Scored)\"\n        audit: \"/bin/sh -c 'if test -e $apiserverconf; then stat -c %U:%G $apiserverconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n              compare:\n                op: eq\n                value: \"root:root\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chown root:root $apiserverconf\n        scored: true\n\n      - id: 1.1.3\n        text: \"Ensure that the controller manager pod specification file permissions are set to 644 or more restrictive (Scored)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerconf; then stat -c permissions=%a $controllermanagerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chmod 644 $controllermanagerconf\n        scored: true\n\n      - id: 1.1.4\n        text: \"Ensure that the controller manager pod specification file ownership is set to root:root (Scored)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerconf; then stat -c %U:%G $controllermanagerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n              compare:\n                op: eq\n                value: \"root:root\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chown root:root $controllermanagerconf\n        scored: true\n\n      - id: 1.1.5\n        text: \"Ensure that the scheduler pod specification file permissions are set to 644 or more restrictive (Scored)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerconf; then stat -c permissions=%a $schedulerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chmod 644 $schedulerconf\n        scored: true\n\n      - id: 1.1.6\n        text: \"Ensure that the scheduler pod specification file ownership is set to root:root (Scored)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerconf; then stat -c %U:%G $schedulerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n              compare:\n                op: eq\n                value: \"root:root\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chown root:root $schedulerconf\n        scored: true\n\n      - id: 1.1.7\n        text: \"Ensure that the etcd pod specification file permissions are set to 644 or more restrictive (Scored)\"\n        audit: \"/bin/sh -c 'if test -e $etcdconf; then stat -c permissions=%a $etcdconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chmod 644 $etcdconf\n        scored: true\n\n      - id: 1.1.8\n        text: \"Ensure that the etcd pod specification file ownership is set to root:root (Scored)\"\n        audit: \"/bin/sh -c 'if test -e $etcdconf; then stat -c %U:%G $etcdconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n              compare:\n                op: eq\n                value: \"root:root\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chown root:root $etcdconf\n        scored: true\n\n      - id: 1.1.9\n        text: \"Ensure that the Container Network Interface file permissions are set to 644 or more restrictive (Not Scored)\"\n        audit: \"stat -c permissions=%a <path/to/cni/files>\"\n        type: \"manual\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chmod 644 <path/to/cni/files>\n        scored: false\n\n      - id: 1.1.10\n        text: \"Ensure that the Container Network Interface file ownership is set to root:root (Not Scored)\"\n        audit: \"stat -c %U:%G <path/to/cni/files>\"\n        type: \"manual\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chown root:root <path/to/cni/files>\n        scored: false\n\n      - id: 1.1.11\n        text: \"Ensure that the etcd data directory permissions are set to 700 or more restrictive (Scored)\"\n        audit: |\n          DATA_DIR=''\n          for d in $(ps -ef | grep $etcdbin | grep -- --data-dir | sed 's%.*data-dir[= ]\\([^ ]*\\).*%\\1%'); do\n            if test -d \"$d\"; then DATA_DIR=\"$d\"; fi\n          done\n          if ! test -d \"$DATA_DIR\"; then DATA_DIR=$etcddatadir; fi\n          stat -c permissions=%a \"$DATA_DIR\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"700\"\n              set: true\n        remediation: |\n          On the etcd server node, get the etcd data directory, passed as an argument --data-dir,\n          from the below command:\n          ps -ef | grep etcd\n          Run the below command (based on the etcd data directory found above). For example,\n          chmod 700 /var/lib/etcd\n        scored: true\n\n      - id: 1.1.12\n        text: \"Ensure that the etcd data directory ownership is set to etcd:etcd (Scored)\"\n        audit: |\n          DATA_DIR=''\n          for d in $(ps -ef | grep $etcdbin | grep -- --data-dir | sed 's%.*data-dir[= ]\\([^ ]*\\).*%\\1%'); do\n            if test -d \"$d\"; then DATA_DIR=\"$d\"; fi\n          done\n          if ! test -d \"$DATA_DIR\"; then DATA_DIR=$etcddatadir; fi\n          stat -c %U:%G $DATA_DIR\n        tests:\n          test_items:\n            - flag: \"etcd:etcd\"\n              set: true\n        remediation: |\n          On the etcd server node, get the etcd data directory, passed as an argument --data-dir,\n          from the below command:\n          ps -ef | grep etcd\n          Run the below command (based on the etcd data directory found above).\n          For example, chown etcd:etcd /var/lib/etcd\n        scored: true\n\n      - id: 1.1.13\n        text: \"Ensure that the admin.conf file permissions are set to 644 or more restrictive (Scored)\"\n        audit: \"/bin/sh -c 'if test -e /etc/kubernetes/admin.conf; then stat -c permissions=%a /etc/kubernetes/admin.conf; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chmod 644 /etc/kubernetes/admin.conf\n        scored: true\n\n      - id: 1.1.14\n        text: \"Ensure that the admin.conf file ownership is set to root:root (Scored)\"\n        audit: \"/bin/sh -c 'if test -e /etc/kubernetes/admin.conf; then stat -c %U:%G /etc/kubernetes/admin.conf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n              compare:\n                op: eq\n                value: \"root:root\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chown root:root /etc/kubernetes/admin.conf\n        scored: true\n\n      - id: 1.1.15\n        text: \"Ensure that the scheduler.conf file permissions are set to 644 or more restrictive (Scored)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerkubeconfig; then stat -c permissions=%a $schedulerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chmod 644 $schedulerkubeconfig\n        scored: true\n\n      - id: 1.1.16\n        text: \"Ensure that the scheduler.conf file ownership is set to root:root (Scored)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerkubeconfig; then stat -c %U:%G $schedulerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n              compare:\n                op: eq\n                value: \"root:root\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chown root:root $schedulerkubeconfig\n        scored: true\n\n      - id: 1.1.17\n        text: \"Ensure that the controller-manager.conf file permissions are set to 644 or more restrictive (Scored)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerkubeconfig; then stat -c permissions=%a $controllermanagerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chmod 644 $controllermanagerkubeconfig\n        scored: true\n\n      - id: 1.1.18\n        text: \"Ensure that the controller-manager.conf file ownership is set to root:root (Scored)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerkubeconfig; then stat -c %U:%G $controllermanagerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n              compare:\n                op: eq\n                value: \"root:root\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chown root:root $controllermanagerkubeconfig\n        scored: true\n\n      - id: 1.1.19\n        text: \"Ensure that the Kubernetes PKI directory and file ownership is set to root:root (Scored)\"\n        audit: \"find /etc/kubernetes/pki/ | xargs stat -c %U:%G\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n              compare:\n                op: eq\n                value: \"root:root\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chown -R root:root /etc/kubernetes/pki/\n        scored: true\n\n      - id: 1.1.20\n        text: \"Ensure that the Kubernetes PKI certificate file permissions are set to 644 or more restrictive (Not Scored)\"\n        audit: \"find /etc/kubernetes/pki/ -name '*.crt' | xargs stat -c permissions=%a\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chmod -R 644 /etc/kubernetes/pki/*.crt\n        scored: false\n\n      - id: 1.1.21\n        text: \"Ensure that the Kubernetes PKI key file permissions are set to 600 (Not Scored)\"\n        audit: \"find /etc/kubernetes/pki/ -name '*.key' | xargs stat -c permissions=%a\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chmod -R 600 /etc/kubernetes/pki/*.key\n        scored: false\n\n  - id: 1.2\n    text: \"API Server\"\n    checks:\n      - id: 1.2.1\n        text: \"Ensure that the --anonymous-auth argument is set to false (Not Scored)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--anonymous-auth\"\n              compare:\n                op: eq\n                value: false\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and set the below parameter.\n          --anonymous-auth=false\n        scored: false\n\n      - id: 1.2.2\n        text: \"Ensure that the --basic-auth-file argument is not set (Scored)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--basic-auth-file\"\n              set: false\n        remediation: |\n          Follow the documentation and configure alternate mechanisms for authentication. Then,\n          edit the API server pod specification file $apiserverconf\n          on the master node and remove the --basic-auth-file=<filename> parameter.\n        scored: true\n\n      - id: 1.2.3\n        text: \"Ensure that the --token-auth-file parameter is not set (Scored)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--token-auth-file\"\n              set: false\n        remediation: |\n          Follow the documentation and configure alternate mechanisms for authentication. Then,\n          edit the API server pod specification file $apiserverconf\n          on the master node and remove the --token-auth-file=<filename> parameter.\n        scored: true\n\n      - id: 1.2.4\n        text: \"Ensure that the --kubelet-https argument is set to true (Scored)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--kubelet-https\"\n              compare:\n                op: eq\n                value: true\n              set: true\n            - flag: \"--kubelet-https\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and remove the --kubelet-https parameter.\n        scored: true\n\n      - id: 1.2.5\n        text: \"Ensure that the --kubelet-client-certificate and --kubelet-client-key arguments are set as appropriate (Scored)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--kubelet-client-certificate\"\n              set: true\n            - flag: \"--kubelet-client-key\"\n              set: true\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection between the\n          apiserver and kubelets. Then, edit API server pod specification file\n          $apiserverconf on the master node and set the\n          kubelet client certificate and key parameters as below.\n          --kubelet-client-certificate=<path/to/client-certificate-file>\n          --kubelet-client-key=<path/to/client-key-file>\n        scored: true\n\n      - id: 1.2.6\n        text: \"Ensure that the --kubelet-certificate-authority argument is set as appropriate (Scored)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--kubelet-certificate-authority\"\n              set: true\n        remediation: |\n          Follow the Kubernetes documentation and setup the TLS connection between\n          the apiserver and kubelets. Then, edit the API server pod specification file\n          $apiserverconf on the master node and set the\n          --kubelet-certificate-authority parameter to the path to the cert file for the certificate authority.\n          --kubelet-certificate-authority=<ca-string>\n        scored: true\n\n      - id: 1.2.7\n        text: \"Ensure that the --authorization-mode argument is not set to AlwaysAllow (Scored)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: nothave\n                value: \"AlwaysAllow\"\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and set the --authorization-mode parameter to values other than AlwaysAllow.\n          One such example could be as below.\n          --authorization-mode=RBAC\n        scored: true\n\n      - id: 1.2.8\n        text: \"Ensure that the --authorization-mode argument includes Node (Scored)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: has\n                value: \"Node\"\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and set the --authorization-mode parameter to a value that includes Node.\n          --authorization-mode=Node,RBAC\n        scored: true\n\n      - id: 1.2.9\n        text: \"Ensure that the --authorization-mode argument includes RBAC (Scored)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: has\n                value: \"RBAC\"\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and set the --authorization-mode parameter to a value that includes RBAC,\n          for example:\n          --authorization-mode=Node,RBAC\n        scored: true\n\n      - id: 1.2.10\n        text: \"Ensure that the admission control plugin EventRateLimit is set (Not Scored)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"EventRateLimit\"\n              set: true\n        remediation: |\n          Follow the Kubernetes documentation and set the desired limits in a configuration file.\n          Then, edit the API server pod specification file $apiserverconf\n          and set the below parameters.\n          --enable-admission-plugins=...,EventRateLimit,...\n          --admission-control-config-file=<path/to/configuration/file>\n        scored: false\n\n      - id: 1.2.11\n        text: \"Ensure that the admission control plugin AlwaysAdmit is not set (Scored)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: nothave\n                value: AlwaysAdmit\n              set: true\n            - flag: \"--enable-admission-plugins\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and either remove the --enable-admission-plugins parameter, or set it to a\n          value that does not include AlwaysAdmit.\n        scored: true\n\n      - id: 1.2.12\n        text: \"Ensure that the admission control plugin AlwaysPullImages is set (Not Scored)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"AlwaysPullImages\"\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and set the --enable-admission-plugins parameter to include\n          AlwaysPullImages.\n          --enable-admission-plugins=...,AlwaysPullImages,...\n        scored: false\n\n      - id: 1.2.13\n        text: \"Ensure that the admission control plugin SecurityContextDeny is set if PodSecurityPolicy is not used (Not Scored)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"SecurityContextDeny\"\n              set: true\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"PodSecurityPolicy\"\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and set the --enable-admission-plugins parameter to include\n          SecurityContextDeny, unless PodSecurityPolicy is already in place.\n          --enable-admission-plugins=...,SecurityContextDeny,...\n        scored: false\n\n      - id: 1.2.14\n        text: \"Ensure that the admission control plugin ServiceAccount is set (Scored)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--disable-admission-plugins\"\n              compare:\n                op: nothave\n                value: \"ServiceAccount\"\n              set: true\n            - flag: \"--disable-admission-plugins\"\n              set: false\n        remediation: |\n          Follow the documentation and create ServiceAccount objects as per your environment.\n          Then, edit the API server pod specification file $apiserverconf\n          on the master node and ensure that the --disable-admission-plugins parameter is set to a\n          value that does not include ServiceAccount.\n        scored: true\n\n      - id: 1.2.15\n        text: \"Ensure that the admission control plugin NamespaceLifecycle is set (Scored)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--disable-admission-plugins\"\n              compare:\n                op: nothave\n                value: \"NamespaceLifecycle\"\n              set: true\n            - flag: \"--disable-admission-plugins\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and set the --disable-admission-plugins parameter to\n          ensure it does not include NamespaceLifecycle.\n        scored: true\n\n      - id: 1.2.16\n        text: \"Ensure that the admission control plugin PodSecurityPolicy is set (Scored)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"PodSecurityPolicy\"\n              set: true\n        remediation: |\n          Follow the documentation and create Pod Security Policy objects as per your environment.\n          Then, edit the API server pod specification file $apiserverconf\n          on the master node and set the --enable-admission-plugins parameter to a\n          value that includes PodSecurityPolicy:\n          --enable-admission-plugins=...,PodSecurityPolicy,...\n          Then restart the API Server.\n        scored: true\n\n      - id: 1.2.17\n        text: \"Ensure that the admission control plugin NodeRestriction is set (Scored)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"NodeRestriction\"\n              set: true\n        remediation: |\n          Follow the Kubernetes documentation and configure NodeRestriction plug-in on kubelets.\n          Then, edit the API server pod specification file $apiserverconf\n          on the master node and set the --enable-admission-plugins parameter to a\n          value that includes NodeRestriction.\n          --enable-admission-plugins=...,NodeRestriction,...\n        scored: true\n\n      - id: 1.2.18\n        text: \"Ensure that the --insecure-bind-address argument is not set (Scored)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--insecure-bind-address\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and remove the --insecure-bind-address parameter.\n        scored: true\n\n      - id: 1.2.19\n        text: \"Ensure that the --insecure-port argument is set to 0 (Scored)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--insecure-port\"\n              compare:\n                op: eq\n                value: 0\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and set the below parameter.\n          --insecure-port=0\n        scored: true\n\n      - id: 1.2.20\n        text: \"Ensure that the --secure-port argument is not set to 0 (Scored)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--secure-port\"\n              compare:\n                op: gt\n                value: 0\n              set: true\n            - flag: \"--secure-port\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and either remove the --secure-port parameter or\n          set it to a different (non-zero) desired port.\n        scored: true\n\n      - id: 1.2.21\n        text: \"Ensure that the --profiling argument is set to false (Scored)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and set the below parameter.\n          --profiling=false\n        scored: true\n\n      - id: 1.2.22\n        text: \"Ensure that the --audit-log-path argument is set (Scored)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-path\"\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and set the --audit-log-path parameter to a suitable path and\n          file where you would like audit logs to be written, for example:\n          --audit-log-path=/var/log/apiserver/audit.log\n        scored: true\n\n      - id: 1.2.23\n        text: \"Ensure that the --audit-log-maxage argument is set to 30 or as appropriate (Scored)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxage\"\n              compare:\n                op: gte\n                value: 30\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and set the --audit-log-maxage parameter to 30 or as an appropriate number of days:\n          --audit-log-maxage=30\n        scored: true\n\n      - id: 1.2.24\n        text: \"Ensure that the --audit-log-maxbackup argument is set to 10 or as appropriate (Scored)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxbackup\"\n              compare:\n                op: gte\n                value: 10\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and set the --audit-log-maxbackup parameter to 10 or to an appropriate\n          value.\n          --audit-log-maxbackup=10\n        scored: true\n\n      - id: 1.2.25\n        text: \"Ensure that the --audit-log-maxsize argument is set to 100 or as appropriate (Scored)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxsize\"\n              compare:\n                op: gte\n                value: 100\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and set the --audit-log-maxsize parameter to an appropriate size in MB.\n          For example, to set it as 100 MB:\n          --audit-log-maxsize=100\n        scored: true\n\n      - id: 1.2.26\n        text: \"Ensure that the --request-timeout argument is set as appropriate (Scored)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        type: manual\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          and set the below parameter as appropriate and if needed.\n          For example,\n          --request-timeout=300s\n        scored: true\n\n      - id: 1.2.27\n        text: \"Ensure that the --service-account-lookup argument is set to true (Scored)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--service-account-lookup\"\n              set: false\n            - flag: \"--service-account-lookup\"\n              compare:\n                op: eq\n                value: true\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and set the below parameter.\n          --service-account-lookup=true\n          Alternatively, you can delete the --service-account-lookup parameter from this file so\n          that the default takes effect.\n        scored: true\n\n      - id: 1.2.28\n        text: \"Ensure that the --service-account-key-file argument is set as appropriate (Scored)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--service-account-key-file\"\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and set the --service-account-key-file parameter\n          to the public key file for service accounts:\n          --service-account-key-file=<filename>\n        scored: true\n\n      - id: 1.2.29\n        text: \"Ensure that the --etcd-certfile and --etcd-keyfile arguments are set as appropriate (Scored)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--etcd-certfile\"\n              set: true\n            - flag: \"--etcd-keyfile\"\n              set: true\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection between the apiserver and etcd.\n          Then, edit the API server pod specification file $apiserverconf\n          on the master node and set the etcd certificate and key file parameters.\n          --etcd-certfile=<path/to/client-certificate-file>\n          --etcd-keyfile=<path/to/client-key-file>\n        scored: true\n\n      - id: 1.2.30\n        text: \"Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Scored)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--tls-cert-file\"\n              set: true\n            - flag: \"--tls-private-key-file\"\n              set: true\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection on the apiserver.\n          Then, edit the API server pod specification file $apiserverconf\n          on the master node and set the TLS certificate and private key file parameters.\n          --tls-cert-file=<path/to/tls-certificate-file>\n          --tls-private-key-file=<path/to/tls-key-file>\n        scored: true\n\n      - id: 1.2.31\n        text: \"Ensure that the --client-ca-file argument is set as appropriate (Scored)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--client-ca-file\"\n              set: true\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection on the apiserver.\n          Then, edit the API server pod specification file $apiserverconf\n          on the master node and set the client certificate authority file.\n          --client-ca-file=<path/to/client-ca-file>\n        scored: true\n\n      - id: 1.2.32\n        text: \"Ensure that the --etcd-cafile argument is set as appropriate (Scored)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--etcd-cafile\"\n              set: true\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection between the apiserver and etcd.\n          Then, edit the API server pod specification file $apiserverconf\n          on the master node and set the etcd certificate authority file parameter.\n          --etcd-cafile=<path/to/ca-file>\n        scored: true\n\n      - id: 1.2.33\n        text: \"Ensure that the --encryption-provider-config argument is set as appropriate (Not Scored)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--encryption-provider-config\"\n              set: true\n        remediation: |\n          Follow the Kubernetes documentation and configure a EncryptionConfig file.\n          Then, edit the API server pod specification file $apiserverconf\n          on the master node and set the --encryption-provider-config parameter to the path of that file: --encryption-provider-config=</path/to/EncryptionConfig/File>\n        scored: false\n\n      - id: 1.2.34\n        text: \"Ensure that encryption providers are appropriately configured (Not Scored)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and configure a EncryptionConfig file.\n          In this file, choose aescbc, kms or secretbox as the encryption provider.\n        scored: false\n\n      - id: 1.2.35\n        text: \"Ensure that the API Server only makes use of Strong Cryptographic Ciphers (Not Scored)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--tls-cipher-suites\"\n              compare:\n                op: valid_elements\n                value: \"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\"\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and set the below parameter.\n          --tls-cipher-suites=TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\n        scored: false\n\n  - id: 1.3\n    text: \"Controller Manager\"\n    checks:\n      - id: 1.3.1\n        text: \"Ensure that the --terminated-pod-gc-threshold argument is set as appropriate (Not Scored)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--terminated-pod-gc-threshold\"\n              set: true\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the master node and set the --terminated-pod-gc-threshold to an appropriate threshold,\n          for example:\n          --terminated-pod-gc-threshold=10\n        scored: false\n\n      - id: 1.3.2\n        text: \"Ensure that the --profiling argument is set to false (Scored)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n              set: true\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the master node and set the below parameter.\n          --profiling=false\n        scored: true\n\n      - id: 1.3.3\n        text: \"Ensure that the --use-service-account-credentials argument is set to true (Scored)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--use-service-account-credentials\"\n              compare:\n                op: noteq\n                value: false\n              set: true\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the master node to set the below parameter.\n          --use-service-account-credentials=true\n        scored: true\n\n      - id: 1.3.4\n        text: \"Ensure that the --service-account-private-key-file argument is set as appropriate (Scored)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--service-account-private-key-file\"\n              set: true\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the master node and set the --service-account-private-key-file parameter\n          to the private key file for service accounts.\n          --service-account-private-key-file=<filename>\n        scored: true\n\n      - id: 1.3.5\n        text: \"Ensure that the --root-ca-file argument is set as appropriate (Scored)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--root-ca-file\"\n              set: true\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the master node and set the --root-ca-file parameter to the certificate bundle file`.\n          --root-ca-file=<path/to/file>\n        scored: true\n\n      - id: 1.3.6\n        text: \"Ensure that the RotateKubeletServerCertificate argument is set to true (Scored)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--feature-gates\"\n              compare:\n                op: nothave\n                value: \"RotateKubeletServerCertificate=false\"\n              set: true\n            - flag: \"--feature-gates\"\n              set: false\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the master node and set the --feature-gates parameter to include RotateKubeletServerCertificate=true.\n          --feature-gates=RotateKubeletServerCertificate=true\n        scored: true\n\n      - id: 1.3.7\n        text: \"Ensure that the --bind-address argument is set to 127.0.0.1 (Scored)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--bind-address\"\n              compare:\n                op: eq\n                value: \"127.0.0.1\"\n              set: true\n            - flag: \"--bind-address\"\n              set: false\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the master node and ensure the correct value for the --bind-address parameter\n        scored: true\n\n  - id: 1.4\n    text: \"Scheduler\"\n    checks:\n      - id: 1.4.1\n        text: \"Ensure that the --profiling argument is set to false (Scored)\"\n        audit: \"/bin/ps -ef | grep $schedulerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n              set: true\n        remediation: |\n          Edit the Scheduler pod specification file $schedulerconf file\n          on the master node and set the below parameter.\n          --profiling=false\n        scored: true\n\n      - id: 1.4.2\n        text: \"Ensure that the --bind-address argument is set to 127.0.0.1 (Scored)\"\n        audit: \"/bin/ps -ef | grep $schedulerbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--bind-address\"\n              compare:\n                op: eq\n                value: \"127.0.0.1\"\n              set: true\n            - flag: \"--bind-address\"\n              set: false\n        remediation: |\n          Edit the Scheduler pod specification file $schedulerconf\n          on the master node and ensure the correct value for the --bind-address parameter\n        scored: true\n"
  },
  {
    "path": "cfg/cis-1.5/node.yaml",
    "content": "---\ncontrols:\nversion: \"cis-1.5\"\nid: 4\ntext: \"Worker Node Security Configuration\"\ntype: \"node\"\ngroups:\n  - id: 4.1\n    text: \"Worker Node Configuration Files\"\n    checks:\n      - id: 4.1.1\n        text: \"Ensure that the kubelet service file permissions are set to 644 or more restrictive (Scored)\"\n        audit: '/bin/sh -c ''if test -e $kubeletsvc; then stat -c permissions=%a $kubeletsvc; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              set: true\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chmod 644 $kubeletsvc\n        scored: true\n\n      - id: 4.1.2\n        text: \"Ensure that the kubelet service file ownership is set to root:root (Automated)\"\n        audit: '/bin/sh -c \"if test -e $kubeletsvc; then stat -c %U:%G $kubeletsvc; else echo \\\"File not found\\\"; fi\"'\n        tests:\n          bin_op: or\n          test_items:\n            - flag: root:root\n            - flag: \"File not found\"\n        remediation: |\n            Run the below command (based on the file location on your system) on the each worker node.\n            For example,\n            chown root:root $kubeletsvc\n        scored: true\n\n      - id: 4.1.3\n        text: \"Ensure that the proxy kubeconfig file permissions are set to 644 or more restrictive (Scored)\"\n        audit: '/bin/sh -c ''if test -e $proxykubeconfig; then stat -c permissions=%a $proxykubeconfig; fi'' '\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"permissions\"\n              set: true\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chmod 644 $proxykubeconfig\n        scored: true\n\n      - id: 4.1.4\n        text: \"Ensure that the proxy kubeconfig file ownership is set to root:root (Scored)\"\n        audit: '/bin/sh -c ''if test -e $proxykubeconfig; then stat -c %U:%G $proxykubeconfig; fi'' '\n        tests:\n          bin_op: or\n          test_items:\n            - flag: root:root\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example, chown root:root $proxykubeconfig\n        scored: true\n\n      - id: 4.1.5\n        text: \"Ensure that the kubelet.conf file permissions are set to 644 or more restrictive (Scored)\"\n        audit: '/bin/sh -c ''if test -e $kubeletkubeconfig; then stat -c permissions=%a $kubeletkubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              set: true\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chmod 644 $kubeletkubeconfig\n        scored: true\n\n      - id: 4.1.6\n        text: \"Ensure that the kubelet.conf file ownership is set to root:root (Scored)\"\n        audit: '/bin/sh -c ''if test -e $kubeletkubeconfig; then stat -c %U:%G $kubeletkubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: root:root\n              set: true\n              compare:\n                op: eq\n                value: root:root\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chown root:root $kubeletkubeconfig\n        scored: true\n\n      - id: 4.1.7\n        text: \"Ensure that the certificate authorities file permissions are set to 644 or more restrictive (Scored)\"\n        audit: |\n          CAFILE=$(ps -ef | grep kubelet | grep -v apiserver | grep -- --client-ca-file= | awk -F '--client-ca-file=' '{print $2}' | awk '{print $1}' | uniq)\n          if test -z $CAFILE; then CAFILE=$kubeletcafile; fi\n          if test -e $CAFILE; then stat -c permissions=%a $CAFILE; fi\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              set: true\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the following command to modify the file permissions of the\n          --client-ca-file chmod 644 <filename>\n        scored: true\n\n      - id: 4.1.8\n        text: \"Ensure that the client certificate authorities file ownership is set to root:root (Scored)\"\n        audit: |\n          CAFILE=$(ps -ef | grep kubelet | grep -v apiserver | grep -- --client-ca-file= | awk -F '--client-ca-file=' '{print $2}' | awk '{print $1}' | uniq)\n          if test -z $CAFILE; then CAFILE=$kubeletcafile; fi\n          if test -e $CAFILE; then stat -c %U:%G $CAFILE; fi\n        tests:\n          test_items:\n            - flag: root:root\n              set: true\n              compare:\n                op: eq\n                value: root:root\n        remediation: |\n          Run the following command to modify the ownership of the --client-ca-file.\n          chown root:root <filename>\n        scored: true\n\n      - id: 4.1.9\n        text: \"Ensure that the kubelet configuration file has permissions set to 644 or more restrictive (Scored)\"\n        audit: '/bin/sh -c ''if test -e $kubeletconf; then stat -c permissions=%a $kubeletconf; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              set: true\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the following command (using the config file location identified in the Audit step)\n          chmod 644 $kubeletconf\n        scored: true\n\n      - id: 4.1.10\n        text: \"Ensure that the kubelet configuration file ownership is set to root:root (Scored)\"\n        audit: '/bin/sh -c ''if test -e $kubeletconf; then stat -c %U:%G $kubeletconf; fi'' '\n        tests:\n          test_items:\n            - flag: root:root\n              set: true\n        remediation: |\n          Run the following command (using the config file location identified in the Audit step)\n          chown root:root $kubeletconf\n        scored: true\n\n  - id: 4.2\n    text: \"Kubelet\"\n    checks:\n      - id: 4.2.1\n        text: \"Ensure that the anonymous-auth argument is set to false (Scored)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: \"--anonymous-auth\"\n              path: '{.authentication.anonymous.enabled}'\n              set: true\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          If using a Kubelet config file, edit the file to set authentication: anonymous: enabled to\n          false.\n          If using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --anonymous-auth=false\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.2\n        text: \"Ensure that the --authorization-mode argument is not set to AlwaysAllow (Scored)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --authorization-mode\n              path: '{.authorization.mode}'\n              set: true\n              compare:\n                op: nothave\n                value: AlwaysAllow\n        remediation: |\n          If using a Kubelet config file, edit the file to set authorization: mode to Webhook. If\n          using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_AUTHZ_ARGS variable.\n          --authorization-mode=Webhook\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.3\n        text: \"Ensure that the --client-ca-file argument is set as appropriate (Scored)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --client-ca-file\n              path: '{.authentication.x509.clientCAFile}'\n              set: true\n        remediation: |\n          If using a Kubelet config file, edit the file to set authentication: x509: clientCAFile to\n          the location of the client CA file.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_AUTHZ_ARGS variable.\n          --client-ca-file=<path/to/client-ca-file>\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.4\n        text: \"Ensure that the --read-only-port argument is set to 0 (Scored)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--read-only-port\"\n              path: '{.readOnlyPort}'\n              set: true\n              compare:\n                op: eq\n                value: 0\n            - flag: \"--read-only-port\"\n              path: '{.readOnlyPort}'\n              set: false\n        remediation: |\n          If using a Kubelet config file, edit the file to set readOnlyPort to 0.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --read-only-port=0\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.5\n        text: \"Ensure that the --streaming-connection-idle-timeout argument is not set to 0 (Scored)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --streaming-connection-idle-timeout\n              path: '{.streamingConnectionIdleTimeout}'\n              set: true\n              compare:\n                op: noteq\n                value: 0\n            - flag: --streaming-connection-idle-timeout\n              path: '{.streamingConnectionIdleTimeout}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to set streamingConnectionIdleTimeout to a\n          value other than 0.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --streaming-connection-idle-timeout=5m\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.6\n        text: \"Ensure that the --protect-kernel-defaults argument is set to true (Scored)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --protect-kernel-defaults\n              path: '{.protectKernelDefaults}'\n              set: true\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          If using a Kubelet config file, edit the file to set protectKernelDefaults: true.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --protect-kernel-defaults=true\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.7\n        text: \"Ensure that the --make-iptables-util-chains argument is set to true (Scored)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --make-iptables-util-chains\n              path: '{.makeIPTablesUtilChains}'\n              set: true\n              compare:\n                op: eq\n                value: true\n            - flag: --make-iptables-util-chains\n              path: '{.makeIPTablesUtilChains}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to set makeIPTablesUtilChains: true.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          remove the --make-iptables-util-chains argument from the\n          KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.8\n        text: \"Ensure that the --hostname-override argument is not set (Not Scored)\"\n        # This is one of those properties that can only be set as a command line argument.\n        # To check if the property is set as expected, we need to parse the kubelet command\n        # instead reading the Kubelet Configuration file.\n        audit: \"/bin/ps -fC $kubeletbin \"\n        tests:\n          test_items:\n            - flag: --hostname-override\n              set: false\n        remediation: |\n          Edit the kubelet service file $kubeletsvc\n          on each worker node and remove the --hostname-override argument from the\n          KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.9\n        text: \"Ensure that the --event-qps argument is set to 0 or a level which ensures appropriate event capture (Not Scored)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --event-qps\n              path: '{.eventRecordQPS}'\n              set: true\n              compare:\n                op: eq\n                value: 0\n        remediation: |\n          If using a Kubelet config file, edit the file to set eventRecordQPS: to an appropriate level.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.10\n        text: \"Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Scored)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --tls-cert-file\n              path: '{.tlsCertFile}'\n              set: true\n            - flag: --tls-private-key-file\n              path: '{.tlsPrivateKeyFile}'\n              set: true\n        remediation: |\n          If using a Kubelet config file, edit the file to set tlsCertFile to the location\n          of the certificate file to use to identify this Kubelet, and tlsPrivateKeyFile\n          to the location of the corresponding private key file.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameters in KUBELET_CERTIFICATE_ARGS variable.\n          --tls-cert-file=<path/to/tls-certificate-file>\n          --tls-private-key-file=<path/to/tls-key-file>\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.11\n        text: \"Ensure that the --rotate-certificates argument is not set to false (Scored)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --rotate-certificates\n              path: '{.rotateCertificates}'\n              set: true\n              compare:\n                op: eq\n                value: true\n            - flag: --rotate-certificates\n              path: '{.rotateCertificates}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to add the line rotateCertificates: true or\n          remove it altogether to use the default value.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          remove --rotate-certificates=false argument from the KUBELET_CERTIFICATE_ARGS\n          variable.\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.12\n        text: \"Ensure that the RotateKubeletServerCertificate argument is set to true (Scored)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: RotateKubeletServerCertificate\n              path: '{.featureGates.RotateKubeletServerCertificate}'\n              set: true\n              compare:\n                op: nothave\n                value: false\n            - flag: RotateKubeletServerCertificate\n              path: '{.featureGates.RotateKubeletServerCertificate}'\n              set: false\n        remediation: |\n          Edit the kubelet service file $kubeletsvc\n          on each worker node and set the below parameter in KUBELET_CERTIFICATE_ARGS variable.\n          --feature-gates=RotateKubeletServerCertificate=true\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.13\n        text: \"Ensure that the Kubelet only makes use of Strong Cryptographic Ciphers (Not Scored)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --tls-cipher-suites\n              path: '{range .tlsCipherSuites[:]}{}{'',''}{end}'\n              set: true\n              compare:\n                op: valid_elements\n                value: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\n        remediation: |\n          If using a Kubelet config file, edit the file to set tlsCipherSuites: to\n          TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\n          or to a subset of these values.\n          If using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the --tls-cipher-suites parameter as follows, or to a subset of these values.\n          --tls-cipher-suites=TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n"
  },
  {
    "path": "cfg/cis-1.5/policies.yaml",
    "content": "---\ncontrols:\nversion: \"cis-1.5\"\nid: 5\ntext: \"Kubernetes Policies\"\ntype: \"policies\"\ngroups:\n  - id: 5.1\n    text: \"RBAC and Service Accounts\"\n    checks:\n      - id: 5.1.1\n        text: \"Ensure that the cluster-admin role is only used where required (Not Scored)\"\n        type: \"manual\"\n        remediation: |\n          Identify all clusterrolebindings to the cluster-admin role. Check if they are used and\n          if they need this role or if they could use a role with fewer privileges.\n          Where possible, first bind users to a lower privileged role and then remove the\n          clusterrolebinding to the cluster-admin role :\n          kubectl delete clusterrolebinding [name]\n        scored: false\n\n      - id: 5.1.2\n        text: \"Minimize access to secrets (Not Scored)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove get, list and watch access to secret objects in the cluster.\n        scored: false\n\n      - id: 5.1.3\n        text: \"Minimize wildcard use in Roles and ClusterRoles (Not Scored)\"\n        type: \"manual\"\n        remediation: |\n          Where possible replace any use of wildcards in clusterroles and roles with specific\n          objects or actions.\n        scored: false\n\n      - id: 5.1.4\n        text: \"Minimize access to create pods (Not Scored)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove create access to pod objects in the cluster.\n        scored: false\n\n      - id: 5.1.5\n        text: \"Ensure that default service accounts are not actively used. (Scored)\"\n        type: \"manual\"\n        remediation: |\n          Create explicit service accounts wherever a Kubernetes workload requires specific access\n          to the Kubernetes API server.\n          Modify the configuration of each default service account to include this value\n          automountServiceAccountToken: false\n        scored: true\n\n      - id: 5.1.6\n        text: \"Ensure that Service Account Tokens are only mounted where necessary (Not Scored)\"\n        type: \"manual\"\n        remediation: |\n          Modify the definition of pods and service accounts which do not need to mount service\n          account tokens to disable it.\n        scored: false\n\n  - id: 5.2\n    text: \"Pod Security Policies\"\n    checks:\n      - id: 5.2.1\n        text: \"Minimize the admission of privileged containers (Not Scored)\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that\n          the .spec.privileged field is omitted or set to false.\n        scored: false\n\n      - id: 5.2.2\n        text: \"Minimize the admission of containers wishing to share the host process ID namespace (Scored)\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that the\n          .spec.hostPID field is omitted or set to false.\n        scored: true\n\n      - id: 5.2.3\n        text: \"Minimize the admission of containers wishing to share the host IPC namespace (Scored)\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that the\n          .spec.hostIPC field is omitted or set to false.\n        scored: true\n\n      - id: 5.2.4\n        text: \"Minimize the admission of containers wishing to share the host network namespace (Scored)\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that the\n          .spec.hostNetwork field is omitted or set to false.\n        scored: true\n\n      - id: 5.2.5\n        text: \"Minimize the admission of containers with allowPrivilegeEscalation (Scored)\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that the\n          .spec.allowPrivilegeEscalation field is omitted or set to false.\n        scored: true\n\n      - id: 5.2.6\n        text: \"Minimize the admission of root containers (Not Scored)\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that the\n          .spec.runAsUser.rule is set to either MustRunAsNonRoot or MustRunAs with the range of\n          UIDs not including 0.\n        scored: false\n\n      - id: 5.2.7\n        text: \"Minimize the admission of containers with the NET_RAW capability (Not Scored)\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that the\n          .spec.requiredDropCapabilities is set to include either NET_RAW or ALL.\n        scored: false\n\n      - id: 5.2.8\n        text: \"Minimize the admission of containers with added capabilities (Not Scored)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that allowedCapabilities is not present in PSPs for the cluster unless\n          it is set to an empty array.\n        scored: false\n\n      - id: 5.2.9\n        text: \"Minimize the admission of containers with capabilities assigned (Not Scored)\"\n        type: \"manual\"\n        remediation: |\n          Review the use of capabilites in applications running on your cluster. Where a namespace\n          contains applications which do not require any Linux capabities to operate consider adding\n          a PSP which forbids the admission of containers which do not drop all capabilities.\n        scored: false\n\n  - id: 5.3\n    text: \"Network Policies and CNI\"\n    checks:\n      - id: 5.3.1\n        text: \"Ensure that the CNI in use supports Network Policies (Not Scored)\"\n        type: \"manual\"\n        remediation: |\n          If the CNI plugin in use does not support network policies, consideration should be given to\n          making use of a different plugin, or finding an alternate mechanism for restricting traffic\n          in the Kubernetes cluster.\n        scored: false\n\n      - id: 5.3.2\n        text: \"Ensure that all Namespaces have Network Policies defined (Scored)\"\n        type: \"manual\"\n        remediation: |\n          Follow the documentation and create NetworkPolicy objects as you need them.\n        scored: true\n\n  - id: 5.4\n    text: \"Secrets Management\"\n    checks:\n      - id: 5.4.1\n        text: \"Prefer using secrets as files over secrets as environment variables (Not Scored)\"\n        type: \"manual\"\n        remediation: |\n          if possible, rewrite application code to read secrets from mounted secret files, rather than\n          from environment variables.\n        scored: false\n\n      - id: 5.4.2\n        text: \"Consider external secret storage (Not Scored)\"\n        type: \"manual\"\n        remediation: |\n          Refer to the secrets management options offered by your cloud provider or a third-party\n          secrets management solution.\n        scored: false\n\n  - id: 5.5\n    text: \"Extensible Admission Control\"\n    checks:\n      - id: 5.5.1\n        text: \"Configure Image Provenance using ImagePolicyWebhook admission controller (Not Scored)\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and setup image provenance.\n        scored: false\n\n  - id: 5.7\n    text: \"General Policies\"\n    checks:\n      - id: 5.7.1\n        text: \"Create administrative boundaries between resources using namespaces (Not Scored)\"\n        type: \"manual\"\n        remediation: |\n          Follow the documentation and create namespaces for objects in your deployment as you need\n          them.\n        scored: false\n\n      - id: 5.7.2\n        text: \"Ensure that the seccomp profile is set to docker/default in your pod definitions (Not Scored)\"\n        type: \"manual\"\n        remediation: |\n          Seccomp is an alpha feature currently. By default, all alpha features are disabled. So, you\n          would need to enable alpha features in the apiserver by passing \"--feature-\n          gates=AllAlpha=true\" argument.\n          Edit the /etc/kubernetes/apiserver file on the master node and set the KUBE_API_ARGS\n          parameter to \"--feature-gates=AllAlpha=true\"\n          KUBE_API_ARGS=\"--feature-gates=AllAlpha=true\"\n          Based on your system, restart the kube-apiserver service. For example:\n          systemctl restart kube-apiserver.service\n          Use annotations to enable the docker/default seccomp profile in your pod definitions. An\n          example is as below:\n          apiVersion: v1\n          kind: Pod\n          metadata:\n            name: trustworthy-pod\n            annotations:\n              seccomp.security.alpha.kubernetes.io/pod: docker/default\n          spec:\n            containers:\n              - name: trustworthy-container\n                image: sotrustworthy:latest\n        scored: false\n\n      - id: 5.7.3\n        text: \"Apply Security Context to Your Pods and Containers (Not Scored)\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and apply security contexts to your pods. For a\n          suggested list of security contexts, you may refer to the CIS Security Benchmark for Docker\n          Containers.\n        scored: false\n\n      - id: 5.7.4\n        text: \"The default namespace should not be used (Scored)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that namespaces are created to allow for appropriate segregation of Kubernetes\n          resources and that all new resources are created in a specific namespace.\n        scored: true\n"
  },
  {
    "path": "cfg/cis-1.6/config.yaml",
    "content": "---\n## Version-specific settings that override the values in cfg/config.yaml\n"
  },
  {
    "path": "cfg/cis-1.6/controlplane.yaml",
    "content": "---\ncontrols:\nversion: \"cis-1.6\"\nid: 3\ntext: \"Control Plane Configuration\"\ntype: \"controlplane\"\ngroups:\n  - id: 3.1\n    text: \"Authentication and Authorization\"\n    checks:\n      - id: 3.1.1\n        text: \"Client certificate authentication should not be used for users (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Alternative mechanisms provided by Kubernetes such as the use of OIDC should be\n          implemented in place of client certificates.\n        scored: false\n\n  - id: 3.2\n    text: \"Logging\"\n    checks:\n      - id: 3.2.1\n        text: \"Ensure that a minimal audit policy is created (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-policy-file\"\n              set: true\n        remediation: |\n          Create an audit policy file for your cluster.\n        scored: false\n\n      - id: 3.2.2\n        text: \"Ensure that the audit policy covers key security concerns (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Consider modification of the audit policy in use on the cluster to include these items, at a\n          minimum.\n        scored: false\n"
  },
  {
    "path": "cfg/cis-1.6/etcd.yaml",
    "content": "---\ncontrols:\nversion: \"cis-1.6\"\nid: 2\ntext: \"Etcd Node Configuration\"\ntype: \"etcd\"\ngroups:\n  - id: 2\n    text: \"Etcd Node Configuration Files\"\n    checks:\n      - id: 2.1\n        text: \"Ensure that the --cert-file and --key-file arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--cert-file\"\n              env: \"ETCD_CERT_FILE\"\n            - flag: \"--key-file\"\n              env: \"ETCD_KEY_FILE\"\n        remediation: |\n          Follow the etcd service documentation and configure TLS encryption.\n          Then, edit the etcd pod specification file /etc/kubernetes/manifests/etcd.yaml\n          on the master node and set the below parameters.\n          --cert-file=</path/to/ca-file>\n          --key-file=</path/to/key-file>\n        scored: true\n\n      - id: 2.2\n        text: \"Ensure that the --client-cert-auth argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--client-cert-auth\"\n              env: \"ETCD_CLIENT_CERT_AUTH\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and set the below parameter.\n          --client-cert-auth=\"true\"\n        scored: true\n\n      - id: 2.3\n        text: \"Ensure that the --auto-tls argument is not set to true (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--auto-tls\"\n              env: \"ETCD_AUTO_TLS\"\n              set: false\n            - flag: \"--auto-tls\"\n              env: \"ETCD_AUTO_TLS\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and either remove the --auto-tls parameter or set it to false.\n            --auto-tls=false\n        scored: true\n\n      - id: 2.4\n        text: \"Ensure that the --peer-cert-file and --peer-key-file arguments are\n        set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--peer-cert-file\"\n              env: \"ETCD_PEER_CERT_FILE\"\n            - flag: \"--peer-key-file\"\n              env: \"ETCD_PEER_KEY_FILE\"\n        remediation: |\n          Follow the etcd service documentation and configure peer TLS encryption as appropriate\n          for your etcd cluster.\n          Then, edit the etcd pod specification file $etcdconf on the\n          master node and set the below parameters.\n          --peer-client-file=</path/to/peer-cert-file>\n          --peer-key-file=</path/to/peer-key-file>\n        scored: true\n\n      - id: 2.5\n        text: \"Ensure that the --peer-client-cert-auth argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--peer-client-cert-auth\"\n              env: \"ETCD_PEER_CLIENT_CERT_AUTH\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and set the below parameter.\n          --peer-client-cert-auth=true\n        scored: true\n\n      - id: 2.6\n        text: \"Ensure that the --peer-auto-tls argument is not set to true (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--peer-auto-tls\"\n              env: \"ETCD_PEER_AUTO_TLS\"\n              set: false\n            - flag: \"--peer-auto-tls\"\n              env: \"ETCD_PEER_AUTO_TLS\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and either remove the --peer-auto-tls parameter or set it to false.\n          --peer-auto-tls=false\n        scored: true\n\n      - id: 2.7\n        text: \"Ensure that a unique Certificate Authority is used for etcd (Manual)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--trusted-ca-file\"\n              env: \"ETCD_TRUSTED_CA_FILE\"\n        remediation: |\n          [Manual test]\n          Follow the etcd documentation and create a dedicated certificate authority setup for the\n          etcd service.\n          Then, edit the etcd pod specification file $etcdconf on the\n          master node and set the below parameter.\n          --trusted-ca-file=</path/to/ca-file>\n        scored: false\n"
  },
  {
    "path": "cfg/cis-1.6/master.yaml",
    "content": "---\ncontrols:\nversion: \"cis-1.6\"\nid: 1\ntext: \"Master Node Security Configuration\"\ntype: \"master\"\ngroups:\n  - id: 1.1\n    text: \"Master Node Configuration Files\"\n    checks:\n      - id: 1.1.1\n        text: \"Ensure that the API server pod specification file permissions are set to 644 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $apiserverconf; then stat -c permissions=%a $apiserverconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the\n          master node.\n          For example, chmod 644 $apiserverconf\n        scored: true\n\n      - id: 1.1.2\n        text: \"Ensure that the API server pod specification file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $apiserverconf; then stat -c %U:%G $apiserverconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chown root:root $apiserverconf\n        scored: true\n\n      - id: 1.1.3\n        text: \"Ensure that the controller manager pod specification file permissions are set to 644 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerconf; then stat -c permissions=%a $controllermanagerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chmod 644 $controllermanagerconf\n        scored: true\n\n      - id: 1.1.4\n        text: \"Ensure that the controller manager pod specification file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerconf; then stat -c %U:%G $controllermanagerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chown root:root $controllermanagerconf\n        scored: true\n\n      - id: 1.1.5\n        text: \"Ensure that the scheduler pod specification file permissions are set to 644 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerconf; then stat -c permissions=%a $schedulerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chmod 644 $schedulerconf\n        scored: true\n\n      - id: 1.1.6\n        text: \"Ensure that the scheduler pod specification file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerconf; then stat -c %U:%G $schedulerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chown root:root $schedulerconf\n        scored: true\n\n      - id: 1.1.7\n        text: \"Ensure that the etcd pod specification file permissions are set to 644 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $etcdconf; then find $etcdconf -name '*etcd*' | xargs stat -c permissions=%a; fi'\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chmod 644 $etcdconf\n        scored: true\n\n      - id: 1.1.8\n        text: \"Ensure that the etcd pod specification file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $etcdconf; then find $etcdconf -name '*etcd*' | xargs stat -c %U:%G; fi'\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chown root:root $etcdconf\n        scored: true\n\n      - id: 1.1.9\n        text: \"Ensure that the Container Network Interface file permissions are set to 644 or more restrictive (Manual)\"\n        audit: |\n          ps -ef | grep $kubeletbin | grep -- --cni-conf-dir | sed 's%.*cni-conf-dir[= ]\\([^ ]*\\).*%\\1%' | xargs -I{} find {} -mindepth 1 | xargs --no-run-if-empty stat -c permissions=%a\n          find /var/lib/cni/networks -type f 2> /dev/null | xargs --no-run-if-empty stat -c permissions=%a\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chmod 644 <path/to/cni/files>\n        scored: false\n\n      - id: 1.1.10\n        text: \"Ensure that the Container Network Interface file ownership is set to root:root (Manual)\"\n        audit: |\n          ps -ef | grep $kubeletbin | grep -- --cni-conf-dir | sed 's%.*cni-conf-dir[= ]\\([^ ]*\\).*%\\1%' | xargs -I{} find {} -mindepth 1 | xargs --no-run-if-empty stat -c %U:%G\n          find /var/lib/cni/networks -type f 2> /dev/null | xargs --no-run-if-empty stat -c %U:%G\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chown root:root <path/to/cni/files>\n        scored: false\n\n      - id: 1.1.11\n        text: \"Ensure that the etcd data directory permissions are set to 700 or more restrictive (Automated)\"\n        audit: |\n          DATA_DIR=''\n          for d in $(ps -ef | grep $etcdbin | grep -- --data-dir | sed 's%.*data-dir[= ]\\([^ ]*\\).*%\\1%'); do\n            if test -d \"$d\"; then DATA_DIR=\"$d\"; fi\n          done\n          if ! test -d \"$DATA_DIR\"; then DATA_DIR=$etcddatadir; fi\n          stat -c permissions=%a \"$DATA_DIR\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"700\"\n        remediation: |\n          On the etcd server node, get the etcd data directory, passed as an argument --data-dir,\n          from the below command:\n          ps -ef | grep etcd\n          Run the below command (based on the etcd data directory found above). For example,\n          chmod 700 /var/lib/etcd\n        scored: true\n\n      - id: 1.1.12\n        text: \"Ensure that the etcd data directory ownership is set to etcd:etcd (Automated)\"\n        audit: |\n          DATA_DIR=''\n          for d in $(ps -ef | grep $etcdbin | grep -- --data-dir | sed 's%.*data-dir[= ]\\([^ ]*\\).*%\\1%'); do\n            if test -d \"$d\"; then DATA_DIR=\"$d\"; fi\n          done\n          if ! test -d \"$DATA_DIR\"; then DATA_DIR=$etcddatadir; fi\n          stat -c %U:%G $DATA_DIR\n        tests:\n          test_items:\n            - flag: \"etcd:etcd\"\n        remediation: |\n          On the etcd server node, get the etcd data directory, passed as an argument --data-dir,\n          from the below command:\n          ps -ef | grep etcd\n          Run the below command (based on the etcd data directory found above).\n          For example, chown etcd:etcd /var/lib/etcd\n        scored: true\n\n      - id: 1.1.13\n        text: \"Ensure that the admin.conf file permissions are set to 644 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e /etc/kubernetes/admin.conf; then stat -c permissions=%a /etc/kubernetes/admin.conf; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chmod 644 /etc/kubernetes/admin.conf\n        scored: true\n\n      - id: 1.1.14\n        text: \"Ensure that the admin.conf file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e /etc/kubernetes/admin.conf; then stat -c %U:%G /etc/kubernetes/admin.conf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chown root:root /etc/kubernetes/admin.conf\n        scored: true\n\n      - id: 1.1.15\n        text: \"Ensure that the scheduler.conf file permissions are set to 644 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerkubeconfig; then stat -c permissions=%a $schedulerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chmod 644 $schedulerkubeconfig\n        scored: true\n\n      - id: 1.1.16\n        text: \"Ensure that the scheduler.conf file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerkubeconfig; then stat -c %U:%G $schedulerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chown root:root $schedulerkubeconfig\n        scored: true\n\n      - id: 1.1.17\n        text: \"Ensure that the controller-manager.conf file permissions are set to 644 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerkubeconfig; then stat -c permissions=%a $controllermanagerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chmod 644 $controllermanagerkubeconfig\n        scored: true\n\n      - id: 1.1.18\n        text: \"Ensure that the controller-manager.conf file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerkubeconfig; then stat -c %U:%G $controllermanagerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chown root:root $controllermanagerkubeconfig\n        scored: true\n\n      - id: 1.1.19\n        text: \"Ensure that the Kubernetes PKI directory and file ownership is set to root:root (Automated)\"\n        audit: \"find /etc/kubernetes/pki/ | xargs stat -c %U:%G\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chown -R root:root /etc/kubernetes/pki/\n        scored: true\n\n      - id: 1.1.20\n        text: \"Ensure that the Kubernetes PKI certificate file permissions are set to 644 or more restrictive (Manual)\"\n        audit: \"find /etc/kubernetes/pki/ -name '*.crt' | xargs stat -c permissions=%a\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chmod -R 644 /etc/kubernetes/pki/*.crt\n        scored: false\n\n      - id: 1.1.21\n        text: \"Ensure that the Kubernetes PKI key file permissions are set to 600 (Manual)\"\n        audit: \"find /etc/kubernetes/pki/ -name '*.key' | xargs stat -c permissions=%a\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chmod -R 600 /etc/kubernetes/pki/*.key\n        scored: false\n\n  - id: 1.2\n    text: \"API Server\"\n    checks:\n      - id: 1.2.1\n        text: \"Ensure that the --anonymous-auth argument is set to false (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--anonymous-auth\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and set the below parameter.\n          --anonymous-auth=false\n        scored: false\n\n      - id: 1.2.2\n        text: \"Ensure that the --basic-auth-file argument is not set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--basic-auth-file\"\n              set: false\n        remediation: |\n          Follow the documentation and configure alternate mechanisms for authentication. Then,\n          edit the API server pod specification file $apiserverconf\n          on the master node and remove the --basic-auth-file=<filename> parameter.\n        scored: true\n\n      - id: 1.2.3\n        text: \"Ensure that the --token-auth-file parameter is not set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--token-auth-file\"\n              set: false\n        remediation: |\n          Follow the documentation and configure alternate mechanisms for authentication. Then,\n          edit the API server pod specification file $apiserverconf\n          on the master node and remove the --token-auth-file=<filename> parameter.\n        scored: true\n\n      - id: 1.2.4\n        text: \"Ensure that the --kubelet-https argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--kubelet-https\"\n              compare:\n                op: eq\n                value: true\n            - flag: \"--kubelet-https\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and remove the --kubelet-https parameter.\n        scored: true\n\n      - id: 1.2.5\n        text: \"Ensure that the --kubelet-client-certificate and --kubelet-client-key arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--kubelet-client-certificate\"\n            - flag: \"--kubelet-client-key\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection between the\n          apiserver and kubelets. Then, edit API server pod specification file\n          $apiserverconf on the master node and set the\n          kubelet client certificate and key parameters as below.\n          --kubelet-client-certificate=<path/to/client-certificate-file>\n          --kubelet-client-key=<path/to/client-key-file>\n        scored: true\n\n      - id: 1.2.6\n        text: \"Ensure that the --kubelet-certificate-authority argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--kubelet-certificate-authority\"\n        remediation: |\n          Follow the Kubernetes documentation and setup the TLS connection between\n          the apiserver and kubelets. Then, edit the API server pod specification file\n          $apiserverconf on the master node and set the\n          --kubelet-certificate-authority parameter to the path to the cert file for the certificate authority.\n          --kubelet-certificate-authority=<ca-string>\n        scored: true\n\n      - id: 1.2.7\n        text: \"Ensure that the --authorization-mode argument is not set to AlwaysAllow (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: nothave\n                value: \"AlwaysAllow\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and set the --authorization-mode parameter to values other than AlwaysAllow.\n          One such example could be as below.\n          --authorization-mode=RBAC\n        scored: true\n\n      - id: 1.2.8\n        text: \"Ensure that the --authorization-mode argument includes Node (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: has\n                value: \"Node\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and set the --authorization-mode parameter to a value that includes Node.\n          --authorization-mode=Node,RBAC\n        scored: true\n\n      - id: 1.2.9\n        text: \"Ensure that the --authorization-mode argument includes RBAC (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: has\n                value: \"RBAC\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and set the --authorization-mode parameter to a value that includes RBAC,\n          for example:\n          --authorization-mode=Node,RBAC\n        scored: true\n\n      - id: 1.2.10\n        text: \"Ensure that the admission control plugin EventRateLimit is set (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"EventRateLimit\"\n        remediation: |\n          Follow the Kubernetes documentation and set the desired limits in a configuration file.\n          Then, edit the API server pod specification file $apiserverconf\n          and set the below parameters.\n          --enable-admission-plugins=...,EventRateLimit,...\n          --admission-control-config-file=<path/to/configuration/file>\n        scored: false\n\n      - id: 1.2.11\n        text: \"Ensure that the admission control plugin AlwaysAdmit is not set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: nothave\n                value: AlwaysAdmit\n            - flag: \"--enable-admission-plugins\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and either remove the --enable-admission-plugins parameter, or set it to a\n          value that does not include AlwaysAdmit.\n        scored: true\n\n      - id: 1.2.12\n        text: \"Ensure that the admission control plugin AlwaysPullImages is set (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"AlwaysPullImages\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and set the --enable-admission-plugins parameter to include\n          AlwaysPullImages.\n          --enable-admission-plugins=...,AlwaysPullImages,...\n        scored: false\n\n      - id: 1.2.13\n        text: \"Ensure that the admission control plugin SecurityContextDeny is set if PodSecurityPolicy is not used (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"SecurityContextDeny\"\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"PodSecurityPolicy\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and set the --enable-admission-plugins parameter to include\n          SecurityContextDeny, unless PodSecurityPolicy is already in place.\n          --enable-admission-plugins=...,SecurityContextDeny,...\n        scored: false\n\n      - id: 1.2.14\n        text: \"Ensure that the admission control plugin ServiceAccount is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--disable-admission-plugins\"\n              compare:\n                op: nothave\n                value: \"ServiceAccount\"\n            - flag: \"--disable-admission-plugins\"\n              set: false\n        remediation: |\n          Follow the documentation and create ServiceAccount objects as per your environment.\n          Then, edit the API server pod specification file $apiserverconf\n          on the master node and ensure that the --disable-admission-plugins parameter is set to a\n          value that does not include ServiceAccount.\n        scored: true\n\n      - id: 1.2.15\n        text: \"Ensure that the admission control plugin NamespaceLifecycle is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--disable-admission-plugins\"\n              compare:\n                op: nothave\n                value: \"NamespaceLifecycle\"\n            - flag: \"--disable-admission-plugins\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and set the --disable-admission-plugins parameter to\n          ensure it does not include NamespaceLifecycle.\n        scored: true\n\n      - id: 1.2.16\n        text: \"Ensure that the admission control plugin PodSecurityPolicy is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"PodSecurityPolicy\"\n        remediation: |\n          Follow the documentation and create Pod Security Policy objects as per your environment.\n          Then, edit the API server pod specification file $apiserverconf\n          on the master node and set the --enable-admission-plugins parameter to a\n          value that includes PodSecurityPolicy:\n          --enable-admission-plugins=...,PodSecurityPolicy,...\n          Then restart the API Server.\n        scored: true\n\n      - id: 1.2.17\n        text: \"Ensure that the admission control plugin NodeRestriction is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"NodeRestriction\"\n        remediation: |\n          Follow the Kubernetes documentation and configure NodeRestriction plug-in on kubelets.\n          Then, edit the API server pod specification file $apiserverconf\n          on the master node and set the --enable-admission-plugins parameter to a\n          value that includes NodeRestriction.\n          --enable-admission-plugins=...,NodeRestriction,...\n        scored: true\n\n      - id: 1.2.18\n        text: \"Ensure that the --insecure-bind-address argument is not set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--insecure-bind-address\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and remove the --insecure-bind-address parameter.\n        scored: true\n\n      - id: 1.2.19\n        text: \"Ensure that the --insecure-port argument is set to 0 (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--insecure-port\"\n              compare:\n                op: eq\n                value: 0\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and set the below parameter.\n          --insecure-port=0\n        scored: true\n\n      - id: 1.2.20\n        text: \"Ensure that the --secure-port argument is not set to 0 (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--secure-port\"\n              compare:\n                op: gt\n                value: 0\n            - flag: \"--secure-port\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and either remove the --secure-port parameter or\n          set it to a different (non-zero) desired port.\n        scored: true\n\n      - id: 1.2.21\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and set the below parameter.\n          --profiling=false\n        scored: true\n\n      - id: 1.2.22\n        text: \"Ensure that the --audit-log-path argument is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-path\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and set the --audit-log-path parameter to a suitable path and\n          file where you would like audit logs to be written, for example:\n          --audit-log-path=/var/log/apiserver/audit.log\n        scored: true\n\n      - id: 1.2.23\n        text: \"Ensure that the --audit-log-maxage argument is set to 30 or as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxage\"\n              compare:\n                op: gte\n                value: 30\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and set the --audit-log-maxage parameter to 30 or as an appropriate number of days:\n          --audit-log-maxage=30\n        scored: true\n\n      - id: 1.2.24\n        text: \"Ensure that the --audit-log-maxbackup argument is set to 10 or as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxbackup\"\n              compare:\n                op: gte\n                value: 10\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and set the --audit-log-maxbackup parameter to 10 or to an appropriate\n          value.\n          --audit-log-maxbackup=10\n        scored: true\n\n      - id: 1.2.25\n        text: \"Ensure that the --audit-log-maxsize argument is set to 100 or as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxsize\"\n              compare:\n                op: gte\n                value: 100\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and set the --audit-log-maxsize parameter to an appropriate size in MB.\n          For example, to set it as 100 MB:\n          --audit-log-maxsize=100\n        scored: true\n\n      - id: 1.2.26\n        text: \"Ensure that the --request-timeout argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        type: manual\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          and set the below parameter as appropriate and if needed.\n          For example,\n          --request-timeout=300s\n        scored: true\n\n      - id: 1.2.27\n        text: \"Ensure that the --service-account-lookup argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--service-account-lookup\"\n              set: false\n            - flag: \"--service-account-lookup\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and set the below parameter.\n          --service-account-lookup=true\n          Alternatively, you can delete the --service-account-lookup parameter from this file so\n          that the default takes effect.\n        scored: true\n\n      - id: 1.2.28\n        text: \"Ensure that the --service-account-key-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--service-account-key-file\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the master node and set the --service-account-key-file parameter\n          to the public key file for service accounts:\n          --service-account-key-file=<filename>\n        scored: true\n\n      - id: 1.2.29\n        text: \"Ensure that the --etcd-certfile and --etcd-keyfile arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--etcd-certfile\"\n            - flag: \"--etcd-keyfile\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection between the apiserver and etcd.\n          Then, edit the API server pod specification file $apiserverconf\n          on the master node and set the etcd certificate and key file parameters.\n          --etcd-certfile=<path/to/client-certificate-file>\n          --etcd-keyfile=<path/to/client-key-file>\n        scored: true\n\n      - id: 1.2.30\n        text: \"Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--tls-cert-file\"\n            - flag: \"--tls-private-key-file\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection on the apiserver.\n          Then, edit the API server pod specification file $apiserverconf\n          on the master node and set the TLS certificate and private key file parameters.\n          --tls-cert-file=<path/to/tls-certificate-file>\n          --tls-private-key-file=<path/to/tls-key-file>\n        scored: true\n\n      - id: 1.2.31\n        text: \"Ensure that the --client-ca-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--client-ca-file\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection on the apiserver.\n          Then, edit the API server pod specification file $apiserverconf\n          on the master node and set the client certificate authority file.\n          --client-ca-file=<path/to/client-ca-file>\n        scored: true\n\n      - id: 1.2.32\n        text: \"Ensure that the --etcd-cafile argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--etcd-cafile\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection between the apiserver and etcd.\n          Then, edit the API server pod specification file $apiserverconf\n          on the master node and set the etcd certificate authority file parameter.\n          --etcd-cafile=<path/to/ca-file>\n        scored: true\n\n      - id: 1.2.33\n        text: \"Ensure that the --encryption-provider-config argument is set as appropriate (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--encryption-provider-config\"\n        remediation: |\n          Follow the Kubernetes documentation and configure a EncryptionConfig file.\n          Then, edit the API server pod specification file $apiserverconf\n          on the master node and set the --encryption-provider-config parameter to the path of that file: --encryption-provider-config=</path/to/EncryptionConfig/File>\n        scored: false\n\n      - id: 1.2.34\n        text: \"Ensure that encryption providers are appropriately configured (Manual)\"\n        audit: |\n          ENCRYPTION_PROVIDER_CONFIG=$(ps -ef | grep $apiserverbin | grep -- --encryption-provider-config | sed 's%.*encryption-provider-config[= ]\\([^ ]*\\).*%\\1%')\n          if test -e $ENCRYPTION_PROVIDER_CONFIG; then grep -A1 'providers:' $ENCRYPTION_PROVIDER_CONFIG | tail -n1 | grep -o \"[A-Za-z]*\" | sed 's/^/provider=/'; fi\n        tests:\n          test_items:\n            - flag: \"provider\"\n              compare:\n                op: valid_elements\n                value: \"aescbc,kms,secretbox\"\n        remediation: |\n          Follow the Kubernetes documentation and configure a EncryptionConfig file.\n          In this file, choose aescbc, kms or secretbox as the encryption provider.\n        scored: false\n\n      - id: 1.2.35\n        text: \"Ensure that the API Server only makes use of Strong Cryptographic Ciphers (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--tls-cipher-suites\"\n              compare:\n                op: valid_elements\n                value: \"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\"\n        remediation: |\n          Edit the API server pod specification file /etc/kubernetes/manifests/kube-apiserver.yaml\n          on the master node and set the below parameter.\n          --tls-cipher-suites=TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM\n          _SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM\n          _SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM\n          _SHA384\n        scored: false\n\n  - id: 1.3\n    text: \"Controller Manager\"\n    checks:\n      - id: 1.3.1\n        text: \"Ensure that the --terminated-pod-gc-threshold argument is set as appropriate (Manual)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--terminated-pod-gc-threshold\"\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the master node and set the --terminated-pod-gc-threshold to an appropriate threshold,\n          for example:\n          --terminated-pod-gc-threshold=10\n        scored: false\n\n      - id: 1.3.2\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the master node and set the below parameter.\n          --profiling=false\n        scored: true\n\n      - id: 1.3.3\n        text: \"Ensure that the --use-service-account-credentials argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--use-service-account-credentials\"\n              compare:\n                op: noteq\n                value: false\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the master node to set the below parameter.\n          --use-service-account-credentials=true\n        scored: true\n\n      - id: 1.3.4\n        text: \"Ensure that the --service-account-private-key-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--service-account-private-key-file\"\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the master node and set the --service-account-private-key-file parameter\n          to the private key file for service accounts.\n          --service-account-private-key-file=<filename>\n        scored: true\n\n      - id: 1.3.5\n        text: \"Ensure that the --root-ca-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--root-ca-file\"\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the master node and set the --root-ca-file parameter to the certificate bundle file`.\n          --root-ca-file=<path/to/file>\n        scored: true\n\n      - id: 1.3.6\n        text: \"Ensure that the RotateKubeletServerCertificate argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--feature-gates\"\n              compare:\n                op: nothave\n                value: \"RotateKubeletServerCertificate=false\"\n              set: true\n            - flag: \"--feature-gates\"\n              set: false\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the master node and set the --feature-gates parameter to include RotateKubeletServerCertificate=true.\n          --feature-gates=RotateKubeletServerCertificate=true\n        scored: true\n\n      - id: 1.3.7\n        text: \"Ensure that the --bind-address argument is set to 127.0.0.1 (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--bind-address\"\n              compare:\n                op: eq\n                value: \"127.0.0.1\"\n            - flag: \"--bind-address\"\n              set: false\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the master node and ensure the correct value for the --bind-address parameter\n        scored: true\n\n  - id: 1.4\n    text: \"Scheduler\"\n    checks:\n      - id: 1.4.1\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: \"/bin/ps -ef | grep $schedulerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the Scheduler pod specification file $schedulerconf file\n          on the master node and set the below parameter.\n          --profiling=false\n        scored: true\n\n      - id: 1.4.2\n        text: \"Ensure that the --bind-address argument is set to 127.0.0.1 (Automated)\"\n        audit: \"/bin/ps -ef | grep $schedulerbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--bind-address\"\n              compare:\n                op: eq\n                value: \"127.0.0.1\"\n            - flag: \"--bind-address\"\n              set: false\n        remediation: |\n          Edit the Scheduler pod specification file $schedulerconf\n          on the master node and ensure the correct value for the --bind-address parameter\n        scored: true\n"
  },
  {
    "path": "cfg/cis-1.6/node.yaml",
    "content": "---\ncontrols:\nversion: \"cis-1.6\"\nid: 4\ntext: \"Worker Node Security Configuration\"\ntype: \"node\"\ngroups:\n  - id: 4.1\n    text: \"Worker Node Configuration Files\"\n    checks:\n      - id: 4.1.1\n        text: \"Ensure that the kubelet service file permissions are set to 644 or more restrictive (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletsvc; then stat -c permissions=%a $kubeletsvc; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chmod 644 $kubeletsvc\n        scored: true\n\n      - id: 4.1.2\n        text: \"Ensure that the kubelet service file ownership is set to root:root (Automated)\"\n        audit: '/bin/sh -c \"if test -e $kubeletsvc; then stat -c %U:%G $kubeletsvc; else echo \\\"File not found\\\"; fi\"'\n        tests:\n          bin_op: or\n          test_items:\n            - flag: root:root\n            - flag: \"File not found\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chown root:root $kubeletsvc\n        scored: true\n\n      - id: 4.1.3\n        text: \"If proxy kubeconfig file exists ensure permissions are set to 644 or more restrictive (Manual)\"\n        audit: '/bin/sh -c ''if test -e $proxykubeconfig; then stat -c permissions=%a $proxykubeconfig; fi'' '\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"permissions\"\n              set: true\n              compare:\n                op: bitmask\n                value: \"644\"\n            - flag: \"$proxykubeconfig\"\n              set: false\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chmod 644 $proxykubeconfig\n        scored: false\n\n      - id: 4.1.4\n        text: \"Ensure that the proxy kubeconfig file ownership is set to root:root (Manual)\"\n        audit: '/bin/sh -c ''if test -e $proxykubeconfig; then stat -c %U:%G $proxykubeconfig; fi'' '\n        tests:\n          bin_op: or\n          test_items:\n            - flag: root:root\n            - flag: \"$proxykubeconfig\"\n              set: false\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example, chown root:root $proxykubeconfig\n        scored: false\n\n      - id: 4.1.5\n        text: \"Ensure that the --kubeconfig kubelet.conf file permissions are set to 644 or more restrictive (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletkubeconfig; then stat -c permissions=%a $kubeletkubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chmod 644 $kubeletkubeconfig\n        scored: true\n\n      - id: 4.1.6\n        text: \"Ensure that the --kubeconfig kubelet.conf file ownership is set to root:root (Manual)\"\n        audit: '/bin/sh -c ''if test -e $kubeletkubeconfig; then stat -c %U:%G $kubeletkubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chown root:root $kubeletkubeconfig\n        scored: false\n\n      - id: 4.1.7\n        text: \"Ensure that the certificate authorities file permissions are set to 644 or more restrictive (Manual)\"\n        audit: |\n          CAFILE=$(ps -ef | grep kubelet | grep -v apiserver | grep -- --client-ca-file= | awk -F '--client-ca-file=' '{print $2}' | awk '{print $1}' | uniq)\n          if test -z $CAFILE; then CAFILE=$kubeletcafile; fi\n          if test -e $CAFILE; then stat -c permissions=%a $CAFILE; fi\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the following command to modify the file permissions of the\n          --client-ca-file chmod 644 <filename>\n        scored: false\n\n      - id: 4.1.8\n        text: \"Ensure that the client certificate authorities file ownership is set to root:root (Manual)\"\n        audit: |\n          CAFILE=$(ps -ef | grep kubelet | grep -v apiserver | grep -- --client-ca-file= | awk -F '--client-ca-file=' '{print $2}' | awk '{print $1}' | uniq)\n          if test -z $CAFILE; then CAFILE=$kubeletcafile; fi\n          if test -e $CAFILE; then stat -c %U:%G $CAFILE; fi\n        tests:\n          test_items:\n            - flag: root:root\n              compare:\n                op: eq\n                value: root:root\n        remediation: |\n          Run the following command to modify the ownership of the --client-ca-file.\n          chown root:root <filename>\n        scored: false\n\n      - id: 4.1.9\n        text: \"Ensure that the kubelet --config configuration file has permissions set to 644 or more restrictive (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletconf; then stat -c permissions=%a $kubeletconf; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the following command (using the config file location identified in the Audit step)\n          chmod 644 $kubeletconf\n        scored: true\n\n      - id: 4.1.10\n        text: \"Ensure that the kubelet --config configuration file ownership is set to root:root (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletconf; then stat -c %U:%G $kubeletconf; fi'' '\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the following command (using the config file location identified in the Audit step)\n          chown root:root $kubeletconf\n        scored: true\n\n  - id: 4.2\n    text: \"Kubelet\"\n    checks:\n      - id: 4.2.1\n        text: \"Ensure that the anonymous-auth argument is set to false (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: \"--anonymous-auth\"\n              path: '{.authentication.anonymous.enabled}'\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          If using a Kubelet config file, edit the file to set authentication: anonymous: enabled to\n          false.\n          If using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --anonymous-auth=false\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.2\n        text: \"Ensure that the --authorization-mode argument is not set to AlwaysAllow (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --authorization-mode\n              path: '{.authorization.mode}'\n              compare:\n                op: nothave\n                value: AlwaysAllow\n        remediation: |\n          If using a Kubelet config file, edit the file to set authorization: mode to Webhook. If\n          using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_AUTHZ_ARGS variable.\n          --authorization-mode=Webhook\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.3\n        text: \"Ensure that the --client-ca-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --client-ca-file\n              path: '{.authentication.x509.clientCAFile}'\n        remediation: |\n          If using a Kubelet config file, edit the file to set authentication: x509: clientCAFile to\n          the location of the client CA file.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_AUTHZ_ARGS variable.\n          --client-ca-file=<path/to/client-ca-file>\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.4\n        text: \"Ensure that the --read-only-port argument is set to 0 (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--read-only-port\"\n              path: '{.readOnlyPort}'\n              compare:\n                op: eq\n                value: 0\n            - flag: \"--read-only-port\"\n              path: '{.readOnlyPort}'\n              set: false\n        remediation: |\n          If using a Kubelet config file, edit the file to set readOnlyPort to 0.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --read-only-port=0\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.5\n        text: \"Ensure that the --streaming-connection-idle-timeout argument is not set to 0 (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --streaming-connection-idle-timeout\n              path: '{.streamingConnectionIdleTimeout}'\n              compare:\n                op: noteq\n                value: 0\n            - flag: --streaming-connection-idle-timeout\n              path: '{.streamingConnectionIdleTimeout}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to set streamingConnectionIdleTimeout to a\n          value other than 0.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --streaming-connection-idle-timeout=5m\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.6\n        text: \"Ensure that the --protect-kernel-defaults argument is set to true (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --protect-kernel-defaults\n              path: '{.protectKernelDefaults}'\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          If using a Kubelet config file, edit the file to set protectKernelDefaults: true.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --protect-kernel-defaults=true\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.7\n        text: \"Ensure that the --make-iptables-util-chains argument is set to true (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --make-iptables-util-chains\n              path: '{.makeIPTablesUtilChains}'\n              compare:\n                op: eq\n                value: true\n            - flag: --make-iptables-util-chains\n              path: '{.makeIPTablesUtilChains}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to set makeIPTablesUtilChains: true.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          remove the --make-iptables-util-chains argument from the\n          KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.8\n        text: \"Ensure that the --hostname-override argument is not set (Manual)\"\n        # This is one of those properties that can only be set as a command line argument.\n        # To check if the property is set as expected, we need to parse the kubelet command\n        # instead reading the Kubelet Configuration file.\n        audit: \"/bin/ps -fC $kubeletbin \"\n        tests:\n          test_items:\n            - flag: --hostname-override\n              set: false\n        remediation: |\n          Edit the kubelet service file $kubeletsvc\n          on each worker node and remove the --hostname-override argument from the\n          KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.9\n        text: \"Ensure that the --event-qps argument is set to 0 or a level which ensures appropriate event capture (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --event-qps\n              path: '{.eventRecordQPS}'\n              compare:\n                op: eq\n                value: 0\n        remediation: |\n          If using a Kubelet config file, edit the file to set eventRecordQPS: to an appropriate level.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.10\n        text: \"Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --tls-cert-file\n              path: '{.tlsCertFile}'\n            - flag: --tls-private-key-file\n              path: '{.tlsPrivateKeyFile}'\n        remediation: |\n          If using a Kubelet config file, edit the file to set tlsCertFile to the location\n          of the certificate file to use to identify this Kubelet, and tlsPrivateKeyFile\n          to the location of the corresponding private key file.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameters in KUBELET_CERTIFICATE_ARGS variable.\n          --tls-cert-file=<path/to/tls-certificate-file>\n          --tls-private-key-file=<path/to/tls-key-file>\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.11\n        text: \"Ensure that the --rotate-certificates argument is not set to false (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --rotate-certificates\n              path: '{.rotateCertificates}'\n              compare:\n                op: eq\n                value: true\n            - flag: --rotate-certificates\n              path: '{.rotateCertificates}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to add the line rotateCertificates: true or\n          remove it altogether to use the default value.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          remove --rotate-certificates=false argument from the KUBELET_CERTIFICATE_ARGS\n          variable.\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.12\n        text: \"Verify that the RotateKubeletServerCertificate argument is set to true (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: RotateKubeletServerCertificate\n              path: '{.featureGates.RotateKubeletServerCertificate}'\n              compare:\n                op: nothave\n                value: false\n            - flag: RotateKubeletServerCertificate\n              path: '{.featureGates.RotateKubeletServerCertificate}'\n              set: false\n        remediation: |\n          Edit the kubelet service file $kubeletsvc\n          on each worker node and set the below parameter in KUBELET_CERTIFICATE_ARGS variable.\n          --feature-gates=RotateKubeletServerCertificate=true\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.13\n        text: \"Ensure that the Kubelet only makes use of Strong Cryptographic Ciphers (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --tls-cipher-suites\n              path: '{range .tlsCipherSuites[:]}{}{'',''}{end}'\n              compare:\n                op: valid_elements\n                value: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\n        remediation: |\n          If using a Kubelet config file, edit the file to set tlsCipherSuites: to\n          TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\n          or to a subset of these values.\n          If using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the --tls-cipher-suites parameter as follows, or to a subset of these values.\n          --tls-cipher-suites=TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n"
  },
  {
    "path": "cfg/cis-1.6/policies.yaml",
    "content": "---\ncontrols:\nversion: \"cis-1.6\"\nid: 5\ntext: \"Kubernetes Policies\"\ntype: \"policies\"\ngroups:\n  - id: 5.1\n    text: \"RBAC and Service Accounts\"\n    checks:\n      - id: 5.1.1\n        text: \"Ensure that the cluster-admin role is only used where required (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Identify all clusterrolebindings to the cluster-admin role. Check if they are used and\n          if they need this role or if they could use a role with fewer privileges.\n          Where possible, first bind users to a lower privileged role and then remove the\n          clusterrolebinding to the cluster-admin role :\n          kubectl delete clusterrolebinding [name]\n        scored: false\n\n      - id: 5.1.2\n        text: \"Minimize access to secrets (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove get, list and watch access to secret objects in the cluster.\n        scored: false\n\n      - id: 5.1.3\n        text: \"Minimize wildcard use in Roles and ClusterRoles (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible replace any use of wildcards in clusterroles and roles with specific\n          objects or actions.\n        scored: false\n\n      - id: 5.1.4\n        text: \"Minimize access to create pods (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove create access to pod objects in the cluster.\n        scored: false\n\n      - id: 5.1.5\n        text: \"Ensure that default service accounts are not actively used. (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Create explicit service accounts wherever a Kubernetes workload requires specific access\n          to the Kubernetes API server.\n          Modify the configuration of each default service account to include this value\n          automountServiceAccountToken: false\n        scored: false\n\n      - id: 5.1.6\n        text: \"Ensure that Service Account Tokens are only mounted where necessary (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Modify the definition of pods and service accounts which do not need to mount service\n          account tokens to disable it.\n        scored: false\n\n  - id: 5.2\n    text: \"Pod Security Policies\"\n    checks:\n      - id: 5.2.1\n        text: \"Minimize the admission of privileged containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that\n          the .spec.privileged field is omitted or set to false.\n        scored: false\n\n      - id: 5.2.2\n        text: \"Minimize the admission of containers wishing to share the host process ID namespace (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that the\n          .spec.hostPID field is omitted or set to false.\n        scored: false\n\n      - id: 5.2.3\n        text: \"Minimize the admission of containers wishing to share the host IPC namespace (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that the\n          .spec.hostIPC field is omitted or set to false.\n        scored: false\n\n      - id: 5.2.4\n        text: \"Minimize the admission of containers wishing to share the host network namespace (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that the\n          .spec.hostNetwork field is omitted or set to false.\n        scored: false\n\n      - id: 5.2.5\n        text: \"Minimize the admission of containers with allowPrivilegeEscalation (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that the\n          .spec.allowPrivilegeEscalation field is omitted or set to false.\n        scored: false\n\n      - id: 5.2.6\n        text: \"Minimize the admission of root containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that the\n          .spec.runAsUser.rule is set to either MustRunAsNonRoot or MustRunAs with the range of\n          UIDs not including 0.\n        scored: false\n\n      - id: 5.2.7\n        text: \"Minimize the admission of containers with the NET_RAW capability (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that the\n          .spec.requiredDropCapabilities is set to include either NET_RAW or ALL.\n        scored: false\n\n      - id: 5.2.8\n        text: \"Minimize the admission of containers with added capabilities (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that allowedCapabilities is not present in PSPs for the cluster unless\n          it is set to an empty array.\n        scored: false\n\n      - id: 5.2.9\n        text: \"Minimize the admission of containers with capabilities assigned (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Review the use of capabilites in applications running on your cluster. Where a namespace\n          contains applications which do not require any Linux capabities to operate consider adding\n          a PSP which forbids the admission of containers which do not drop all capabilities.\n        scored: false\n\n  - id: 5.3\n    text: \"Network Policies and CNI\"\n    checks:\n      - id: 5.3.1\n        text: \"Ensure that the CNI in use supports Network Policies (Manual)\"\n        type: \"manual\"\n        remediation: |\n          If the CNI plugin in use does not support network policies, consideration should be given to\n          making use of a different plugin, or finding an alternate mechanism for restricting traffic\n          in the Kubernetes cluster.\n        scored: false\n\n      - id: 5.3.2\n        text: \"Ensure that all Namespaces have Network Policies defined (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the documentation and create NetworkPolicy objects as you need them.\n        scored: false\n\n  - id: 5.4\n    text: \"Secrets Management\"\n    checks:\n      - id: 5.4.1\n        text: \"Prefer using secrets as files over secrets as environment variables (Manual)\"\n        type: \"manual\"\n        remediation: |\n          if possible, rewrite application code to read secrets from mounted secret files, rather than\n          from environment variables.\n        scored: false\n\n      - id: 5.4.2\n        text: \"Consider external secret storage (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Refer to the secrets management options offered by your cloud provider or a third-party\n          secrets management solution.\n        scored: false\n\n  - id: 5.5\n    text: \"Extensible Admission Control\"\n    checks:\n      - id: 5.5.1\n        text: \"Configure Image Provenance using ImagePolicyWebhook admission controller (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and setup image provenance.\n        scored: false\n\n  - id: 5.7\n    text: \"General Policies\"\n    checks:\n      - id: 5.7.1\n        text: \"Create administrative boundaries between resources using namespaces (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the documentation and create namespaces for objects in your deployment as you need\n          them.\n        scored: false\n\n      - id: 5.7.2\n        text: \"Ensure that the seccomp profile is set to docker/default in your pod definitions (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Seccomp is an alpha feature currently. By default, all alpha features are disabled. So, you\n          would need to enable alpha features in the apiserver by passing \"--feature-\n          gates=AllAlpha=true\" argument.\n          Edit the /etc/kubernetes/apiserver file on the master node and set the KUBE_API_ARGS\n          parameter to \"--feature-gates=AllAlpha=true\"\n          KUBE_API_ARGS=\"--feature-gates=AllAlpha=true\"\n          Based on your system, restart the kube-apiserver service. For example:\n          systemctl restart kube-apiserver.service\n          Use annotations to enable the docker/default seccomp profile in your pod definitions. An\n          example is as below:\n          apiVersion: v1\n          kind: Pod\n          metadata:\n            name: trustworthy-pod\n            annotations:\n              seccomp.security.alpha.kubernetes.io/pod: docker/default\n          spec:\n            containers:\n              - name: trustworthy-container\n                image: sotrustworthy:latest\n        scored: false\n\n      - id: 5.7.3\n        text: \"Apply Security Context to Your Pods and Containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and apply security contexts to your pods. For a\n          suggested list of security contexts, you may refer to the CIS Security Benchmark for Docker\n          Containers.\n        scored: false\n\n      - id: 5.7.4\n        text: \"The default namespace should not be used (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that namespaces are created to allow for appropriate segregation of Kubernetes\n          resources and that all new resources are created in a specific namespace.\n        scored: false\n"
  },
  {
    "path": "cfg/cis-1.6-k3s/config.yaml",
    "content": "---\n## Version-specific settings that override the values in cfg/config.yaml\n\nmaster:\n  components:\n    - scheduler\n    - controllermanager\n    - node\n\n  scheduler:\n    kubeconfig:\n      - /var/lib/rancher/k3s/server/cred/scheduler.kubeconfig\n    defaultkubeconfig: /var/lib/rancher/k3s/server/cred/scheduler.kubeconfig\n\n  controllermanager:\n    kubeconfig:\n      - /var/lib/rancher/k3s/server/cred/cloud-controller.kubeconfig\n    defaultkubeconfig: /var/lib/rancher/k3s/server/cred/cloud-controller.kubeconfig\n\netcd:\n  components:\n    - etcd\n  etcd:\n    confs:\n      - /var/lib/rancher/k3s/server/db/etcd/config\n    defaultconf: /var/lib/rancher/k3s/server/db/etcd/config\n\nnode:\n  components:\n    - proxy\n    - kubelet\n  proxy:\n    kubeconfig:\n      - \"/var/lib/rancher/k3s/agent/kubeproxy.kubeconfig\"\n    defaultkubeconfig: \"/var/lib/rancher/k3s/agent/kubeproxy.kubeconfig\"\n  kubelet:\n    kubeconfig:\n      - \"/var/lib/rancher/k3s/agent/kubelet.kubeconfig\"\n    defaultkubeconfig: \"/var/lib/rancher/k3s/agent/kubelet.kubeconfig\"\n    cafile:\n      - \"/var/lib/rancher/k3s/server/tls/server-ca.crt\"\n    defaultcafile: \"/var/lib/rancher/k3s/server/tls/server-ca.crt\"\n"
  },
  {
    "path": "cfg/cis-1.6-k3s/controlplane.yaml",
    "content": "---\ncontrols:\nversion: \"cis-1.6-k3s\"\nid: 3\ntext: \"Control Plane Configuration\"\ntype: \"controlplane\"\ngroups:\n  - id: 3.1\n    text: \"Authentication and Authorization\"\n    checks:\n      - id: 3.1.1\n        text: \"Client certificate authentication should not be used for users (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Alternative mechanisms provided by Kubernetes such as the use of OIDC should be\n          implemented in place of client certificates.\n        scored: false\n\n  - id: 3.2\n    text: \"Logging\"\n    checks:\n      - id: 3.2.1\n        text: \"Ensure that a minimal audit policy is created (Automated)\"\n        audit: journalctl -u k3s | grep \"Running kube-apiserver\" | tail -n1 | grep \"audit-policy-file\"\n        tests:\n          test_items:\n            - flag: \"--audit-policy-file\"\n              set: true\n        remediation: |\n          Create an audit policy file for your cluster and pass it to k3s.\n          e.g. --kube-apiserver-arg='audit-log-path=/var/lib/rancher/k3s/server/logs/audit-log'\n        scored: true\n\n      - id: 3.2.2\n        text: \"Ensure that the audit policy covers key security concerns (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Consider modification of the audit policy in use on the cluster to include these items, at a\n          minimum.\n        scored: false\n"
  },
  {
    "path": "cfg/cis-1.6-k3s/etcd.yaml",
    "content": "---\ncontrols:\nversion: \"cis-1.6-k3s\"\nid: 2\ntext: \"Etcd Node Configuration\"\ntype: \"etcd\"\ngroups:\n  - id: 2\n    text: \"Etcd Node Configuration Files\"\n    checks:\n      - id: 2.1\n        text: \"Ensure that the --cert-file and --key-file arguments are set as appropriate if use etcd as database (Automated)\"\n        audit: grep -A 4 'client-transport-security' $etcdconf | grep -E 'cert-file|key-file'\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"cert-file\"\n            - flag: \"key-file\"\n        remediation: |\n          By default, K3s uses a config file for etcd that can be found at $etcdconf.\n          The config file contains client-transport-security: which has fields that have the peer cert and peer key files. No manual remediation needed.\n        scored: true\n\n      - id: 2.2\n        text: \"Ensure that the --client-cert-auth argument is set to true (Automated)\"\n        audit: grep 'client-cert-auth' $etcdconf\n        tests:\n          test_items:\n            - flag: \"client-cert-auth\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          By default, K3s uses a config file for etcd that can be found at $etcdconf.\n          client-cert-auth is set to true. No manual remediation needed.\n        scored: true\n\n      - id: 2.3\n        text: \"Ensure that the --auto-tls argument is not set to true (Automated)\"\n        audit: grep 'auto-tls' $etcdconf | cat\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"auto-tls\"\n              set: false\n            - flag: \"auto-tls\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          By default, K3s starts Etcd without this flag. It is set to false by default.\n        scored: true\n\n      - id: 2.4\n        text: \"Ensure that the --peer-cert-file and --peer-key-file arguments are\n        set as appropriate (Automated)\"\n        audit: grep -A 4 'peer-transport-security' $etcdconf | grep -E 'cert-file|key-file'\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"cert-file\"\n            - flag: \"key-file\"\n        remediation: |\n          By default, K3s starts Etcd with a config file found here, $etcdconf.\n          The config file contains peer-transport-security: which has fields that have the peer cert and peer key files.\n        scored: true\n\n      - id: 2.5\n        text: \"Ensure that the --peer-client-cert-auth argument is set to true (Automated)\"\n        audit: grep -A 4 'peer-transport-security' $etcdconf | grep 'client-cert-auth'\n        tests:\n          test_items:\n            - flag: \"client-cert-auth\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          By default, K3s uses a config file for etcd that can be found at $etcdconf.\n          The config file contains peer-transport-security: which has client-cert-auth set to true. No manual remediation needed.\n        scored: true\n\n      - id: 2.6\n        text: \"Ensure that the --peer-auto-tls argument is not set to true (Automated)\"\n        audit: grep 'peer-auto-tls' $etcdconf | cat\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"peer-auto-tls\"\n              set: false\n            - flag: \"peer-auto-tls\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          By default, K3s uses a config file for etcd that can be found at $etcdconf.\n          Within the file, it does not contain the peer-auto-tls field. No manual remediation needed.\n        scored: true\n\n      - id: 2.7\n        text: \"Ensure that a unique Certificate Authority is used for etcd (Manual)\"\n        audit: |\n          if [ -f \"$etcdconf\" ];then\n            etcd_ca=$(grep 'trusted-ca-file' $etcdconf | awk -F \":|: *\" '{print $NF}');\n            apiserver_ca=$(journalctl -u k3s | grep \"Running kube-apiserver\" | tail -n1 | grep \"trusted-ca-file\" | awk -F \"=\" '{print $NF}')\n            if [ \"$etcd_ca\" == \"$apiserver_ca\" ]; then\n              echo 'etcd_and_apiserver_have_same_ca';\n            else\n              echo 'etcd_and_apiserver_ca_not_same1' ;\n            fi\n          else\n            echo 'etcd_and_apiserver_ca_not_same'; return ;\n          fi\n        tests:\n          test_items:\n            - flag: \"etcd_and_apiserver_ca_not_same\"\n        remediation: |\n          By default, K3s uses a config file for etcd that can be found at $etcdconf\n          and the trusted-ca-file parameters in it are set to unique values specific to etcd. No manual remediation needed.\n        scored: false\n"
  },
  {
    "path": "cfg/cis-1.6-k3s/master.yaml",
    "content": "---\ncontrols:\nversion: \"cis-1.6-k3s\"\nid: 1\ntext: \"Master Node Security Configuration\"\ntype: \"master\"\ngroups:\n  - id: 1.1\n    text: \"Master Node Configuration Files\"\n    checks:\n      - id: 1.1.1\n        text: \"Ensure that the API server pod specification file permissions are set to 644 or more restrictive (Not Applicable)\"\n        scored: false\n\n      - id: 1.1.2\n        text: \"Ensure that the API server pod specification file ownership is set to root:root (Not Applicable)\"\n        scored: false\n\n      - id: 1.1.3\n        text: \"Ensure that the controller manager pod specification file permissions are set to 644 or more restrictive (Not Applicable)\"\n        scored: false\n\n      - id: 1.1.4\n        text: \"Ensure that the controller manager pod specification file ownership is set to root:root (Not Applicable)\"\n        scored: false\n\n      - id: 1.1.5\n        text: \"Ensure that the scheduler pod specification file permissions are set to 644 or more restrictive (Not Applicable)\"\n        scored: false\n\n      - id: 1.1.6\n        text: \"Ensure that the scheduler pod specification file ownership is set to root:root (Not Applicable)\"\n        scored: false\n\n      - id: 1.1.7\n        text: \"Ensure that the etcd pod specification file permissions are set to 644 or more restrictive (Not Applicable)\"\n        scored: false\n\n      - id: 1.1.8\n        text: \"Ensure that the etcd pod specification file ownership is set to root:root (Not Applicable)\"\n        scored: false\n\n      - id: 1.1.9\n        text: \"Ensure that the Container Network Interface file permissions are set to 644 or more restrictive (Not Applicable)\"\n        scored: false\n\n      - id: 1.1.10\n        text: \"Ensure that the Container Network Interface file ownership is set to root:root (Not Applicable)\"\n        scored: false\n\n      - id: 1.1.11\n        text: \"Ensure that the etcd data directory permissions are set to 700 or more restrictive if etcd is used (Automated)\"\n        audit: stat -c permissions=%a /var/lib/rancher/k3s/server/db/etcd\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"700\"\n        remediation: |\n          On the etcd server node, get the etcd data directory, passed as an argument --data-dir,\n          from the below command:\n          journalctl -u k3s | grep 'Managed etcd' | grep -v grep\n          Run the below command (based on the etcd data directory found above). For example,\n          chmod 700 /var/lib/rancher/k3s/server/db/etcd\n        scored: true\n\n      - id: 1.1.12\n        text: \"Ensure that the etcd data directory ownership is set to etcd:etcd if etcd is used (Not Applicable)\"\n        scored: false\n\n      - id: 1.1.13\n        text: \"Ensure that the admin.kubeconfig file permissions are set to 644 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e /var/lib/rancher/k3s/server/cred/admin.kubeconfig; then stat -c permissions=%a /var/lib/rancher/k3s/server/cred/admin.kubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the k3s node.\n          For example,\n          chmod 644 /var/lib/rancher/k3s/server/cred/admin.kubeconfig\n        scored: true\n\n      - id: 1.1.14\n        text: \"Ensure that the admin.kubeconfig file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e /var/lib/rancher/k3s/server/cred/admin.kubeconfig; then stat -c %U:%G /var/lib/rancher/k3s/server/cred/admin.kubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the k3s node.\n          For example,\n          chown root:root /var/lib/rancher/k3s/server/cred/admin.kubeconfig\n        scored: true\n\n      - id: 1.1.15\n        text: \"Ensure that the scheduler.kubeconfig file permissions are set to 644 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerkubeconfig; then stat -c permissions=%a $schedulerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the k3s node.\n          For example,\n          chmod 644 $schedulerkubeconfig\n        scored: true\n\n      - id: 1.1.16\n        text: \"Ensure that the scheduler.kubeconfig file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerkubeconfig; then stat -c %U:%G $schedulerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the k3s node.\n          For example,\n          chown root:root $schedulerkubeconfig\n        scored: true\n\n      - id: 1.1.17\n        text: \"Ensure that the cloud-controller.kubeconfig file permissions are set to 644 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerkubeconfig; then stat -c permissions=%a $controllermanagerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chmod 644 $controllermanagerkubeconfig\n        scored: true\n\n      - id: 1.1.18\n        text: \"Ensure that the $controllermanagerkubeconfig file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerkubeconfig; then stat -c %U:%G $controllermanagerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chown root:root $controllermanagerkubeconfig\n        scored: true\n\n      - id: 1.1.19\n        text: \"Ensure that the Kubernetes PKI directory and file ownership is set to root:root (Automated)\"\n        audit: \"stat -c %U:%G /var/lib/rancher/k3s/server/tls\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the k3s node.\n          For example,\n          chown -R root:root /var/lib/rancher/k3s/server/tls\n        scored: true\n\n      - id: 1.1.20\n        text: \"Ensure that the Kubernetes PKI certificate file permissions are set to 644 or more restrictive (Automated)\"\n        audit: \"find /var/lib/rancher/k3s/server/tls/ -name '*.crt' | xargs stat -c permissions=%a\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chmod -R 644 /var/lib/rancher/k3s/server/tls/*.crt\n        scored: true\n\n      - id: 1.1.21\n        text: \"Ensure that the Kubernetes PKI key file permissions are set to 600 (Automated)\"\n        audit: \"find /var/lib/rancher/k3s/server/tls/ -name '*.key' | xargs stat -c permissions=%a\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chmod -R 600 /etc/kubernetes/pki/*.key\n        scored: true\n\n  - id: 1.2\n    text: \"API Server\"\n    checks:\n      - id: 1.2.1\n        text: \"Ensure that the --anonymous-auth argument is set to false (Automated)\"\n        audit: journalctl -u k3s | grep \"Running kube-apiserver\" | tail -n1 | grep \"anonymous-auth\"\n        tests:\n          test_items:\n            - flag: \"--anonymous-auth\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          By default, K3s kube-apiserver is configured to run with --anonymous-auth=false flag and value.\n        scored: false\n\n      - id: 1.2.2\n        text: \"Ensure that the --basic-auth-file argument is not set (Automated)\"\n        audit: journalctl -u k3s | grep \"Running kube-apiserver\" | tail -n1 | grep \"basic-auth-file\" | cat\n        tests:\n          test_items:\n            - flag: \"--basic-auth-file\"\n              set: false\n        remediation: |\n          By default, K3s does not run with basic authentication enabled. No manual remediation is needed.\n        scored: true\n\n      - id: 1.2.3\n        text: \"Ensure that the --token-auth-file parameter is not set (Automated)\"\n        audit: journalctl -u k3s | grep \"Running kube-apiserver\" | tail -n1 | grep \"token-auth-file\" | cat\n        tests:\n          test_items:\n            - flag: \"--token-auth-file\"\n              set: false\n        remediation: |\n          By default, K3s does not run with basic authentication enabled. No manual remediation is needed.\n        scored: true\n\n      - id: 1.2.4\n        text: \"Ensure that the --kubelet-https argument is set to true (Automated)\"\n        audit: journalctl -u k3s | grep \"Running kube-apiserver\" | tail -n1 | grep \"kubelet-https\" | cat\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--kubelet-https\"\n              compare:\n                op: eq\n                value: true\n            - flag: \"--kubelet-https\"\n              set: false\n        remediation: |\n          By default, K3s kube-apiserver doesn't run with the --kubelet-https parameter as it runs with TLS. No manual remediation is needed.\n        scored: true\n\n      - id: 1.2.5\n        text: \"Ensure that the --kubelet-client-certificate and --kubelet-client-key arguments are set as appropriate (Automated)\"\n        audit: journalctl -u k3s | grep \"Running kube-apiserver\" | tail -n1 | grep -E 'kubelet-client-certificate|kubelet-client-key'\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--kubelet-client-certificate\"\n            - flag: \"--kubelet-client-key\"\n        remediation: |\n          By default, K3s kube-apiserver is ran with these arguments for secure communication with kubelet. No manual remediation is needed.\n        scored: true\n\n      - id: 1.2.6\n        text: \"Ensure that the --kubelet-certificate-authority argument is set as appropriate (Automated)\"\n        audit: journalctl -u k3s | grep \"Running kube-apiserver\" | tail -n1 | grep \"kubelet-certificate-authority\"\n        tests:\n          test_items:\n            - flag: \"--kubelet-certificate-authority\"\n        remediation: |\n          By default, K3s kube-apiserver is ran with this argument for secure communication with kubelet. No manual remediation is needed.\n        scored: true\n\n      - id: 1.2.7\n        text: \"Ensure that the --authorization-mode argument is not set to AlwaysAllow (Automated)\"\n        audit: journalctl -u k3s | grep \"Running kube-apiserver\" | tail -n1 | grep \"authorization-mode\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: nothave\n                value: \"AlwaysAllow\"\n        remediation: |\n          By default, K3s sets Node,RBAC as the parameter to the --authorization-mode argument. No manual remediation is needed.\n        scored: true\n\n      - id: 1.2.8\n        text: \"Ensure that the --authorization-mode argument includes Node (Automated)\"\n        audit: journalctl -u k3s | grep \"Running kube-apiserver\" | tail -n1 | grep \"authorization-mode\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: has\n                value: \"Node\"\n        remediation: |\n          By default, K3s sets Node,RBAC as the parameter to the --authorization-mode argument. No manual remediation is needed.\n        scored: true\n\n      - id: 1.2.9\n        text: \"Ensure that the --authorization-mode argument includes RBAC (Automated)\"\n        audit: journalctl -u k3s | grep \"Running kube-apiserver\" | tail -n1 | grep \"authorization-mode\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: has\n                value: \"RBAC\"\n        remediation: |\n          By default, K3s sets Node,RBAC as the parameter to the --authorization-mode argument. No manual remediation is needed.\n        scored: true\n\n      - id: 1.2.10\n        text: \"Ensure that the admission control plugin EventRateLimit is set (Manual)\"\n        audit: journalctl -u k3s | grep \"Running kube-apiserver\" | tail -n1 | grep \"enable-admission-plugins\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"EventRateLimit\"\n        remediation: |\n          By default, K3s only sets NodeRestriction,PodSecurityPolicy as the parameter to the --enable-admission-plugins argument.\n          To configure this, follow the Kubernetes documentation and set the desired limits in a configuration file.\n          Then refer to K3s's documentation to see how to supply additional api server configuration via the kube-apiserver-arg parameter.\n        scored: false\n\n      - id: 1.2.11\n        text: \"Ensure that the admission control plugin AlwaysAdmit is not set (Automated)\"\n        audit: journalctl -u k3s | grep \"Running kube-apiserver\" | tail -n1 | grep \"enable-admission-plugins\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: nothave\n                value: AlwaysAdmit\n            - flag: \"--enable-admission-plugins\"\n              set: false\n        remediation: |\n          By default, K3s only sets NodeRestriction,PodSecurityPolicy as the parameter to the --enable-admission-plugins argument.\n          No manual remediation needed.\n        scored: true\n\n      - id: 1.2.12\n        text: \"Ensure that the admission control plugin AlwaysPullImages is set (Manual)\"\n        audit: journalctl -u k3s | grep \"Running kube-apiserver\" | tail -n1 | grep \"enable-admission-plugins\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"AlwaysPullImages\"\n        remediation: |\n          By default, K3s only sets NodeRestriction,PodSecurityPolicy as the parameter to the --enable-admission-plugins argument.\n          To configure this, follow the Kubernetes documentation and set the desired limits in a configuration file.\n          Then refer to K3s's documentation to see how to supply additional api server configuration via the kube-apiserver-arg parameter.\n        scored: false\n\n      - id: 1.2.13\n        text: \"Ensure that the admission control plugin SecurityContextDeny is set if PodSecurityPolicy is not used (Manual)\"\n        audit: journalctl -u k3s | grep \"Running kube-apiserver\" | tail -n1 | grep \"enable-admission-plugins\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"SecurityContextDeny\"\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"PodSecurityPolicy\"\n        remediation: |\n          K3s would need to have the SecurityContextDeny admission plugin enabled by passing it as an argument to K3s.\n          --kube-apiserver-arg='enable-admission-plugins=SecurityContextDeny\n        scored: false\n\n      - id: 1.2.14\n        text: \"Ensure that the admission control plugin ServiceAccount is set (Automated)\"\n        audit: journalctl -u k3s | grep \"Running kube-apiserver\" | tail -n1 | grep \"ServiceAccount\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--disable-admission-plugins\"\n              compare:\n                op: nothave\n                value: \"ServiceAccount\"\n            - flag: \"--disable-admission-plugins\"\n              set: false\n        remediation: |\n          By default, K3s does not use this argument.\n          If there's a desire to use this argument, follow the documentation and create ServiceAccount objects as per your environment.\n          Then refer to K3s's documentation to see how to supply additional api server configuration via the kube-apiserver-arg parameter.\n        scored: true\n\n      - id: 1.2.15\n        text: \"Ensure that the admission control plugin NamespaceLifecycle is set (Automated)\"\n        audit: journalctl -u k3s | grep \"Running kube-apiserver\" | tail -n1 | grep \"disable-admission-plugins\" | cat\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--disable-admission-plugins\"\n              compare:\n                op: nothave\n                value: \"NamespaceLifecycle\"\n            - flag: \"--disable-admission-plugins\"\n              set: false\n        remediation: |\n          By default, K3s does not use this argument. No manual remediation needed.\n        scored: true\n\n      - id: 1.2.16\n        text: \"Ensure that the admission control plugin PodSecurityPolicy is set (Automated)\"\n        audit: journalctl -u k3s | grep \"Running kube-apiserver\" | tail -n1 | grep \"enable-admission-plugins\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"PodSecurityPolicy\"\n        remediation: |\n          K3s would need to have the PodSecurityPolicy admission plugin enabled by passing it as an argument to K3s.\n          --kube-apiserver-arg='enable-admission-plugins=PodSecurityPolicy.\n        scored: true\n\n      - id: 1.2.17\n        text: \"Ensure that the admission control plugin NodeRestriction is set (Automated)\"\n        audit: journalctl -u k3s | grep \"Running kube-apiserver\" | tail -n1 | grep \"enable-admission-plugins\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"NodeRestriction\"\n        remediation: |\n          K3s would need to have the NodeRestriction admission plugin enabled by passing it as an argument to K3s.\n          --kube-apiserver-arg='enable-admission-plugins=NodeRestriction.\n        scored: true\n\n      - id: 1.2.18\n        text: \"Ensure that the --insecure-bind-address argument is not set (Automated)\"\n        audit: journalctl -u k3s | grep \"Running kube-apiserver\" | tail -n1 | grep \"enable-admission-plugins\"\n        tests:\n          test_items:\n            - flag: \"--insecure-bind-address\"\n              set: false\n        remediation: |\n          By default, K3s explicitly excludes the use of the --insecure-bind-address parameter. No manual remediation is needed.\n        scored: true\n\n      - id: 1.2.19\n        text: \"Ensure that the --insecure-port argument is set to 0 (Automated)\"\n        audit: journalctl -u k3s | grep \"Running kube-apiserver\" | tail -n1 | grep \"insecure-port\"\n        tests:\n          test_items:\n            - flag: \"--insecure-port\"\n              compare:\n                op: eq\n                value: 0\n        remediation: |\n          By default, K3s starts the kube-apiserver process with this argument's parameter set to 0. No manual remediation is needed.\n        scored: true\n\n      - id: 1.2.20\n        text: \"Ensure that the --secure-port argument is not set to 0 (Automated)\"\n        audit: journalctl -u k3s | grep \"Running kube-apiserver\" | tail -n1 | grep \"secure-port\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--secure-port\"\n              compare:\n                op: gt\n                value: 0\n            - flag: \"--secure-port\"\n              set: false\n        remediation: |\n          By default, K3s sets the parameter of 6444 for the --secure-port argument. No manual remediation is needed.\n        scored: true\n\n      - id: 1.2.21\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: journalctl -u k3s | grep \"Running kube-apiserver\" | tail -n1 | grep \"profiling\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          By default, K3s sets the --profiling flag parameter to false. No manual remediation needed.\n        scored: true\n\n      - id: 1.2.22\n        text: \"Ensure that the --audit-log-path argument is set (Automated)\"\n        audit: journalctl -u k3s | grep \"Running kube-apiserver\" | tail -n1 | grep \"audit-log-path\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-path\"\n        remediation: |\n          K3s server needs to be run with the following argument, --kube-apiserver-arg='audit-log-path=/path/to/log/file'\n        scored: true\n\n      - id: 1.2.23\n        text: \"Ensure that the --audit-log-maxage argument is set to 30 or as appropriate (Automated)\"\n        audit: journalctl -u k3s | grep \"Running kube-apiserver\" | tail -n1 | grep \"audit-log-maxage\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxage\"\n              compare:\n                op: gte\n                value: 30\n        remediation: |\n          K3s server needs to be run with the following argument, --kube-apiserver-arg='audit-log-maxage=30'\n        scored: true\n\n      - id: 1.2.24\n        text: \"Ensure that the --audit-log-maxbackup argument is set to 10 or as appropriate (Automated)\"\n        audit: journalctl -u k3s | grep \"Running kube-apiserver\" | tail -n1 | grep \"audit-log-maxbackup\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxbackup\"\n              compare:\n                op: gte\n                value: 10\n        remediation: |\n          K3s server needs to be run with the following argument, --kube-apiserver-arg='audit-log-maxbackup=10'\n        scored: true\n\n      - id: 1.2.25\n        text: \"Ensure that the --audit-log-maxsize argument is set to 100 or as appropriate (Automated)\"\n        audit: journalctl -u k3s | grep \"Running kube-apiserver\" | tail -n1 | grep \"audit-log-maxsize\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxsize\"\n              compare:\n                op: gte\n                value: 100\n        remediation: |\n          K3s server needs to be run with the following argument, --kube-apiserver-arg='audit-log-maxsize=100'\n        scored: true\n\n      - id: 1.2.26\n        text: \"Ensure that the --request-timeout argument is set as appropriate (Automated)\"\n        audit: journalctl -u k3s | grep \"Running kube-apiserver\" | tail -n1 | grep \"request-timeout\" | cat\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--request-timeout\"\n              set: false\n            - flag: \"--request-timeout\"\n              compare:\n                op: lte\n                value: 60\n        remediation: |\n          By default, K3s does not set the --request-timeout argument. No manual remediation needed.\n        scored: true\n\n      - id: 1.2.27\n        text: \"Ensure that the --service-account-lookup argument is set to true (Automated)\"\n        audit: journalctl -u k3s | grep \"Running kube-apiserver\" | tail -n1 | grep \"service-account-lookup\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--service-account-lookup\"\n              set: false\n            - flag: \"--service-account-lookup\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          K3s server needs to be run with the following argument, --kube-apiserver-arg='service-account-lookup=true'\n        scored: true\n\n      - id: 1.2.28\n        text: \"Ensure that the --service-account-key-file argument is set as appropriate (Automated)\"\n        audit: journalctl -u k3s | grep \"Running kube-apiserver\" | tail -n1 | grep \"service-account-key-file\"\n        tests:\n          test_items:\n            - flag: \"--service-account-key-file\"\n        remediation: |\n          By default, K3s sets the --service-account-key-file explicitly. No manual remediation needed.\n        scored: true\n\n      - id: 1.2.29\n        text: \"Ensure that the --etcd-certfile and --etcd-keyfile arguments are set as appropriate (Automated)\"\n        audit: journalctl -u k3s | grep \"Running kube-apiserver\" | tail -n1 | grep -E 'etcd-certfile|etcd-keyfile'\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--etcd-certfile\"\n            - flag: \"--etcd-keyfile\"\n        remediation: |\n          By default, K3s sets the --etcd-certfile and --etcd-keyfile arguments explicitly. No manual remediation needed.\n        scored: true\n\n      - id: 1.2.30\n        text: \"Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Automated)\"\n        audit: journalctl -u k3s | grep \"Running kube-apiserver\" | tail -n1 | grep -E 'tls-cert-file|tls-private-key-file'\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--tls-cert-file\"\n            - flag: \"--tls-private-key-file\"\n        remediation: |\n          By default, K3s sets the --tls-cert-file and --tls-private-key-file arguments explicitly. No manual remediation needed.\n        scored: true\n\n      - id: 1.2.31\n        text: \"Ensure that the --client-ca-file argument is set as appropriate (Automated)\"\n        audit: journalctl -u k3s | grep \"Running kube-apiserver\" | tail -n1 | grep \"client-ca-file\"\n        tests:\n          test_items:\n            - flag: \"--client-ca-file\"\n        remediation: |\n          By default, K3s sets the --client-ca-file argument explicitly. No manual remediation needed.\n        scored: true\n\n      - id: 1.2.32\n        text: \"Ensure that the --etcd-cafile argument is set as appropriate (Automated)\"\n        audit: journalctl -u k3s | grep \"Running kube-apiserver\" | tail -n1 | grep -E 'etcd-cafile'\n        tests:\n          test_items:\n            - flag: \"--etcd-cafile\"\n        remediation: |\n          By default, K3s sets the --etcd-cafile argument explicitly. No manual remediation needed.\n        scored: true\n\n      - id: 1.2.33\n        text: \"Ensure that the --encryption-provider-config argument is set as appropriate (Manual)\"\n        audit: journalctl -u k3s | grep \"Running kube-apiserver\" | tail -n1 | grep -E \"encryption-provider-config\"\n        tests:\n          test_items:\n            - flag: \"--encryption-provider-config\"\n        remediation: |\n          K3s server needs to be ran with the follow, --kube-apiserver-arg='encryption-provider-config=/path/to/encryption_config'.\n          This can be done by running k3s with the --secrets-encryptiuon argument which will configure the encryption provider.\n        scored: false\n\n      - id: 1.2.34\n        text: \"Ensure that encryption providers are appropriately configured (Manual)\"\n        type: manual\n        remediation: |\n          K3s server needs to be run with the following, --secrets-encryption=true, and verify that one of the allowed encryption providers is present.\n          Run the below command on the master node.\n          grep aescbc /path/to/encryption-config.json\n          Verify that aescbc/kms/secretbox is set as the encryption provider for all the desired resources.\n        scored: true\n\n      - id: 1.2.35\n        text: \"Ensure that the API Server only makes use of Strong Cryptographic Ciphers (Manual)\"\n        audit: journalctl -u k3s | grep \"Running kube-apiserver\" | tail -n1 | grep \"tls-cipher-suites\"\n        tests:\n          test_items:\n            - flag: \"--tls-cipher-suites\"\n              compare:\n                op: valid_elements\n                value: \"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\"\n        remediation: |\n          By default, K3s explicitly doesn't set this flag. No manual remediation needed.\n        scored: false\n\n  - id: 1.3\n    text: \"Controller Manager\"\n    checks:\n      - id: 1.3.1\n        text: \"Ensure that the --terminated-pod-gc-threshold argument is set as appropriate (Manual)\"\n        audit: |\n          journalctl -u k3s | grep \"Running kube-controller-manager\" | tail -n1 | grep \"terminated-pod-gc-threshold\"\n        tests:\n          test_items:\n            - flag: \"--terminated-pod-gc-threshold\"\n        remediation: |\n          K3s server needs to be run with the following, --kube-controller-manager-arg='terminated-pod-gc-threshold=10.\n        scored: false\n\n      - id: 1.3.2\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: journalctl -u k3s | grep \"Running kube-controller-manager\" | tail -n1 | grep \"profiling\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          By default, K3s sets the --profiling flag parameter to false. No manual remediation needed.\n        scored: true\n\n      - id: 1.3.3\n        text: \"Ensure that the --use-service-account-credentials argument is set to true (Automated)\"\n        audit: journalctl -u k3s | grep \"Running kube-controller-manager\" | tail -n1 | grep \"use-service-account-credentials\"\n        tests:\n          test_items:\n            - flag: \"--use-service-account-credentials\"\n              compare:\n                op: noteq\n                value: false\n        remediation: |\n          K3s server needs to be run with the following, --kube-controller-manager-arg='use-service-account-credentials=true'\n        scored: true\n\n      - id: 1.3.4\n        text: \"Ensure that the --service-account-private-key-file argument is set as appropriate (Automated)\"\n        audit: journalctl -u k3s | grep \"Running kube-controller-manager\" | tail -n1 | grep \"service-account-private-key-file\"\n        tests:\n          test_items:\n            - flag: \"--service-account-private-key-file\"\n        remediation: |\n          By default, K3s sets the --service-account-private-key-file argument with the service account key file. No manual remediation needed.\n        scored: true\n\n      - id: 1.3.5\n        text: \"Ensure that the --root-ca-file argument is set as appropriate (Automated)\"\n        audit: journalctl -u k3s | grep \"Running kube-controller-manager\" | tail -n1 | grep \"root-ca-file\"\n        tests:\n          test_items:\n            - flag: \"--root-ca-file\"\n        remediation: |\n          By default, K3s sets the --root-ca-file argument with the root ca file. No manual remediation needed.\n        scored: true\n\n      - id: 1.3.6\n        text: \"Ensure that the RotateKubeletServerCertificate argument is set to true (Automated)\"\n        audit: journalctl -u k3s | grep \"Running kube-controller-manager\" | tail -n1 | grep \"RotateKubeletServerCertificate\" | cat\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--feature-gates\"\n              compare:\n                op: nothave\n                value: \"RotateKubeletServerCertificate=false\"\n              set: true\n            - flag: \"--feature-gates\"\n              set: false\n        remediation: |\n          By default, K3s implements its own logic for certificate generation and rotation.\n        scored: true\n\n      - id: 1.3.7\n        text: \"Ensure that the --bind-address argument is set to 127.0.0.1 (Automated)\"\n        audit: journalctl -u k3s | grep \"Running kube-controller-manager\" | tail -n1 | grep \"bind-address\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--bind-address\"\n              compare:\n                op: eq\n                value: \"127.0.0.1\"\n            - flag: \"--bind-address\"\n              set: false\n        remediation: |\n          By default, K3s sets the --bind-address argument to 127.0.0.1. No manual remediation needed.\n        scored: true\n\n  - id: 1.4\n    text: \"Scheduler\"\n    checks:\n      - id: 1.4.1\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: journalctl -u k3s | grep \"Running kube-scheduler\" | tail -n1 | grep \"profiling\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          By default, K3s sets the --profiling flag parameter to false. No manual remediation needed.\n        scored: true\n\n      - id: 1.4.2\n        text: \"Ensure that the --bind-address argument is set to 127.0.0.1 (Automated)\"\n        audit: journalctl -u k3s | grep \"Running kube-controller-manager\" | tail -n1 | grep \"bind-address\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--bind-address\"\n              compare:\n                op: eq\n                value: \"127.0.0.1\"\n            - flag: \"--bind-address\"\n              set: false\n        remediation: |\n          By default, K3s sets the --bind-address argument to 127.0.0.1. No manual remediation needed.\n        scored: true\n"
  },
  {
    "path": "cfg/cis-1.6-k3s/node.yaml",
    "content": "---\ncontrols:\nversion: \"cis-1.6-k3s\"\nid: 4\ntext: \"Worker Node Security Configuration\"\ntype: \"node\"\ngroups:\n  - id: 4.1\n    text: \"Worker Node Configuration Files\"\n    checks:\n      - id: 4.1.1\n        text: \"Ensure that the kubelet service file permissions are set to 644 or more restrictive (Not Applicable)\"\n        scored: false\n\n      - id: 4.1.2\n        text: \"Ensure that the kubelet service file ownership is set to root:root (Not Applicable)\"\n        scored: false\n\n      - id: 4.1.3\n        text: \"If proxy kubeproxy.kubeconfig file exists ensure permissions are set to 644 or more restrictive (Automated)\"\n        audit: stat -c %a $proxykubeconfig\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"permissions\"\n              set: true\n              compare:\n                op: bitmask\n                value: \"644\"\n            - flag: \"$proxykubeconfig\"\n              set: false\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chmod 644 $proxykubeconfig\n        scored: true\n\n      - id: 4.1.4\n        text: \"Ensure that the proxy kubeconfig file ownership is set to root:root (Automated)\"\n        audit: '/bin/sh -c ''if test -e $proxykubeconfig; then stat -c %U:%G $proxykubeconfig; fi'' '\n        tests:\n          bin_op: or\n          test_items:\n            - flag: root:root\n            - flag: \"$proxykubeconfig\"\n              set: false\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example, chown root:root $proxykubeconfig\n        scored: true\n\n      - id: 4.1.5\n        text: \"Ensure that the --kubeconfig kubelet.conf file permissions are set to 644 or more restrictive (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletkubeconfig; then stat -c permissions=%a $kubeletkubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          By default, K3s creates $kubeletkubeconfig with 644 permissions. No manual remediation needed.\n        scored: true\n\n      - id: 4.1.6\n        text: \"Ensure that the --kubeconfig kubelet.conf file ownership is set to root:root (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletkubeconfig; then stat -c %U:%G $kubeletkubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          By default, K3s creates $kubeletkubeconfig with root:root ownership. No manual remediation needed.\n        scored: true\n\n      - id: 4.1.7\n        text: \"Ensure that the certificate authorities file permissions are set to 644 or more restrictive (Automated)\"\n        audit: stat -c permissions=%a $kubeletcafile\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          By default, K3s creates $kubeletcafile with 644 permissions.\n        scored: true\n\n      - id: 4.1.8\n        text: \"Ensure that the client certificate authorities file ownership is set to root:root (Automated)\"\n        audit: stat -c %U:%G $kubeletcafile\n        tests:\n          test_items:\n            - flag: root:root\n              compare:\n                op: eq\n                value: root:root\n        remediation: |\n          By default, K3s creates $kubeletcafile with root:root ownership.\n        scored: true\n\n      - id: 4.1.9\n        text: \"Ensure that the kubelet --config configuration file has permissions set to 644 or more restrictive (Not Applicable)\"\n        scored: false\n\n      - id: 4.1.10\n        text: \"Ensure that the kubelet --config configuration file ownership is set to root:root (Not Applicable)\"\n        scored: false\n\n  - id: 4.2\n    text: \"Kubelet\"\n    checks:\n      - id: 4.2.1\n        text: \"Ensure that the anonymous-auth argument is set to false (Automated)\"\n        audit: journalctl -u k3s | grep \"Running kube-apiserver\" | tail -n1 | grep \"anonymous-auth\"\n        tests:\n          test_items:\n            - flag: \"--anonymous-auth\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          By default, K3s starts kubelet with --anonymous-auth set to false. No manual remediation needed.\n        scored: true\n\n      - id: 4.2.2\n        text: \"Ensure that the --authorization-mode argument is not set to AlwaysAllow (Automated)\"\n        audit: journalctl -u k3s | grep \"Running kube-apiserver\" | tail -n1 | grep \"authorization-mode\"\n        tests:\n          test_items:\n            - flag: --authorization-mode\n              compare:\n                op: nothave\n                value: AlwaysAllow\n        remediation: |\n          K3s starts kubelet with Webhook as the value for the --authorization-mode argument. No manual remediation needed.\n        scored: true\n\n      - id: 4.2.3\n        text: \"Ensure that the --client-ca-file argument is set as appropriate (Automated)\"\n        audit: journalctl -u k3s | grep \"Running kube-apiserver\" | tail -n1 | grep \"client-ca-file\"\n        tests:\n          test_items:\n            - flag: --client-ca-file\n        remediation: |\n          By default, K3s starts the kubelet process with the --client-ca-file. No manual remediation needed.\n        scored: true\n\n      - id: 4.2.4\n        text: \"Ensure that the --read-only-port argument is set to 0 (Automated)\"\n        audit: journalctl -u k3s | grep \"Running kubelet\" | tail -n1 | grep \"read-only-port\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--read-only-port\"\n              compare:\n                op: eq\n                value: 0\n            - flag: \"--read-only-port\"\n              set: false\n        remediation: |\n          By default, K3s starts the kubelet process with the --read-only-port argument set to 0.\n        scored: false\n\n      - id: 4.2.5\n        text: \"Ensure that the --streaming-connection-idle-timeout argument is not set to 0 (Automated)\"\n        audit: journalctl -u k3s | grep \"Running kubelet\" | tail -n1 | grep \"streaming-connection-idle-timeout\"\n        tests:\n          test_items:\n            - flag: --streaming-connection-idle-timeout\n              compare:\n                op: noteq\n                value: 0\n            - flag: --streaming-connection-idle-timeout\n              set: false\n          bin_op: or\n        remediation: |\n          By default, K3s does not set --streaming-connection-idle-timeout when starting kubelet.\n        scored: true\n\n      - id: 4.2.6\n        text: \"Ensure that the --protect-kernel-defaults argument is set to true (Automated)\"\n        audit: journalctl -u k3s | grep \"Running kubelet\" | tail -n1 | grep \"protect-kernel-defaults\"\n        tests:\n          test_items:\n            - flag: --protect-kernel-defaults\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          K3s server needs to be started with the following, --protect-kernel-defaults=true.\n        scored: true\n\n      - id: 4.2.7\n        text: \"Ensure that the --make-iptables-util-chains argument is set to true (Automated)\"\n        audit: journalctl -u k3s | grep \"Running kubelet\" | tail -n1 | grep \"make-iptables-util-chains\"\n        tests:\n          test_items:\n            - flag: --make-iptables-util-chains\n              compare:\n                op: eq\n                value: true\n            - flag: --make-iptables-util-chains\n              set: false\n          bin_op: or\n        remediation: |\n          K3s server needs to be run with the following, --kube-apiserver-arg='make-iptables-util-chains=true'.\n        scored: true\n\n      - id: 4.2.8\n        text: \"Ensure that the --hostname-override argument is not set (Not Applicable)\"\n        scored: false\n\n      - id: 4.2.9\n        text: \"Ensure that the --event-qps argument is set to 0 or a level which ensures appropriate event capture (Manual)\"\n        audit: /bin/ps -fC containerd\n        tests:\n          test_items:\n            - flag: --event-qps\n              compare:\n                op: eq\n                value: 0\n        remediation: |\n          If using a Kubelet config file, edit the file to set eventRecordQPS: to an appropriate level.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.10\n        text: \"Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Manual)\"\n        audit: journalctl -u k3s | grep \"Running kubelet\" | tail -n1 | grep -E 'tls-cert-file|tls-private-key-file'\n        tests:\n          test_items:\n            - flag: --tls-cert-file\n            - flag: --tls-private-key-file\n        remediation: |\n          By default, K3s sets the --tls-cert-file and --tls-private-key-file arguments when executing the kubelet process.\n        scored: false\n\n      - id: 4.2.11\n        text: \"Ensure that the --rotate-certificates argument is not set to false (Not Applicable)\"\n        scored: false\n\n      - id: 4.2.12\n        text: \"Verify that the RotateKubeletServerCertificate argument is set to true (Not Applicable)\"\n        scored: false\n\n      - id: 4.2.13\n        text: \"Ensure that the Kubelet only makes use of Strong Cryptographic Ciphers (Not Applicable)\"\n        scored: false\n"
  },
  {
    "path": "cfg/cis-1.6-k3s/policies.yaml",
    "content": "---\ncontrols:\nversion: \"cis-1.6-k3s\"\nid: 5\ntext: \"Kubernetes Policies\"\ntype: \"policies\"\ngroups:\n  - id: 5.1\n    text: \"RBAC and Service Accounts\"\n    checks:\n      - id: 5.1.1\n        text: \"Ensure that the cluster-admin role is only used where required (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Identify all clusterrolebindings to the cluster-admin role. Check if they are used and\n          if they need this role or if they could use a role with fewer privileges.\n          Where possible, first bind users to a lower privileged role and then remove the\n          clusterrolebinding to the cluster-admin role :\n          kubectl delete clusterrolebinding [name]\n        scored: false\n\n      - id: 5.1.2\n        text: \"Minimize access to secrets (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove get, list and watch access to secret objects in the cluster.\n        scored: false\n\n      - id: 5.1.3\n        text: \"Minimize wildcard use in Roles and ClusterRoles (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible replace any use of wildcards in clusterroles and roles with specific\n          objects or actions.\n          kubectl get roles --all-namespaces -o yaml\n          kubectl get clusterroles -o yaml\n        scored: false\n\n      - id: 5.1.4\n        text: \"Minimize access to create pods (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove create access to pod objects in the cluster.\n        scored: false\n\n      - id: 5.1.5\n        text: \"Ensure that default service accounts are not actively used. (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Create explicit service accounts wherever a Kubernetes workload requires specific access\n          to the Kubernetes API server.\n          Modify the configuration of each default service account to include this value\n          automountServiceAccountToken: false\n        scored: false\n\n      - id: 5.1.6\n        text: \"Ensure that Service Account Tokens are only mounted where necessary (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Modify the definition of pods and service accounts which do not need to mount service\n          account tokens to disable it.\n        scored: false\n\n  - id: 5.2\n    text: \"Pod Security Policies\"\n    checks:\n      - id: 5.2.1\n        text: \"Minimize the admission of privileged containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          kubectl describe psp <psp_name> | grep MustRunAsNonRoot\n          An operator should apply a PodSecurityPolicy that sets the Rule value to MustRunAsNonRoot. An example of this can be found in the Hardening Guide\n          https://docs.rancher.cn/docs/k3s/security/hardening-guide/_index\n        scored: false\n\n      - id: 5.2.2\n        text: \"Minimize the admission of containers wishing to share the host process ID namespace (Manual)\"\n        type: \"manual\"\n        remediation: |\n          kubectl get psp -o json | jq .items[] | jq -r 'select((.spec.hostPID == null) or (.spec.hostPID == false))' | jq .metadata.name | wc -l | xargs -I {} echo '--count={}'\n          An operator should apply a PodSecurityPolicy that sets the hostPID value to false explicitly for the PSP it creates. An example of this can be found in the Hardening Guide.\n          https://docs.rancher.cn/docs/k3s/security/hardening-guide/_index\n        scored: false\n\n      - id: 5.2.3\n        text: \"Minimize the admission of containers wishing to share the host IPC namespace (Manual)\"\n        type: \"manual\"\n        remediation: |\n          kubectl get psp -o json | jq .items[] | jq -r 'select((.spec.hostIPC == null) or (.spec.hostIPC == false))' | jq .metadata.name | wc -l | xargs -I {} echo '--count={}'\n          An operator should apply a PodSecurityPolicy that sets the HostIPC value to false explicitly for the PSP it creates. An example of this can be found in the Hardening Guide.\n          https://docs.rancher.cn/docs/k3s/security/hardening-guide/_index\n        scored: false\n\n      - id: 5.2.4\n        text: \"Minimize the admission of containers wishing to share the host network namespace (Manual)\"\n        type: \"manual\"\n        remediation: |\n          kubectl get psp -o json | jq .items[] | jq -r 'select((.spec.hostNetwork == null) or (.spec.hostNetwork == false))' | jq .metadata.name | wc -l | xargs -I {} echo '--count={}'\n          An operator should apply a PodSecurityPolicy that sets the HostNetwork value to false explicitly for the PSP it creates. An example of this can be found in the Hardening Guide.\n          https://docs.rancher.cn/docs/k3s/security/hardening-guide/_index\n        scored: false\n\n      - id: 5.2.5\n        text: \"Minimize the admission of containers with allowPrivilegeEscalation (Manual)\"\n        type: \"manual\"\n        remediation: |\n          kubectl get psp -o json | jq .items[] | jq -r 'select((.spec.allowPrivilegeEscalation == null) or (.spec.allowPrivilegeEscalation == false))' | jq .metadata.name | wc -l | xargs -I {} echo '--count={}'\n          An operator should apply a PodSecurityPolicy that sets the allowPrivilegeEscalation value to false explicitly for the PSP it creates. An example of this can be found in the Hardening Guide.\n          https://docs.rancher.cn/docs/k3s/security/hardening-guide/_index\n        scored: false\n\n      - id: 5.2.6\n        text: \"Minimize the admission of root containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          kubectl get psp -o json | jq .items[] | jq -r 'select((.spec.allowPrivilegeEscalation == null) or (.spec.allowPrivilegeEscalation == false))' | jq .metadata.name | wc -l | xargs -I {} echo '--count={}'\n          An operator should apply a PodSecurityPolicy that sets the runAsUser.Rule value to MustRunAsNonRoot. An example of this can be found in the Hardening Guide.\n          https://docs.rancher.cn/docs/k3s/security/hardening-guide/_index\n        scored: false\n\n      - id: 5.2.7\n        text: \"Minimize the admission of containers with the NET_RAW capability (Manual)\"\n        type: \"manual\"\n        remediation: |\n          kubectl get psp <psp_name> -o json | jq .spec.requiredDropCapabilities[]\n          An operator should apply a PodSecurityPolicy that sets .spec.requiredDropCapabilities[] to a value of All. An example of this can be found in the Hardening Guide.\n          https://docs.rancher.cn/docs/k3s/security/hardening-guide/_index\n        scored: false\n\n      - id: 5.2.8\n        text: \"Minimize the admission of containers with added capabilities (Manual)\"\n        type: \"manual\"\n        remediation: |\n          kubectl get psp\n          An operator should apply a PodSecurityPolicy that sets allowedCapabilities to anything other than an empty array. An example of this can be found in the Hardening Guide.\n          https://docs.rancher.cn/docs/k3s/security/hardening-guide/_index\n        scored: false\n\n      - id: 5.2.9\n        text: \"Minimize the admission of containers with capabilities assigned (Manual)\"\n        type: \"manual\"\n        remediation: |\n          kubectl get psp\n          An operator should apply a PodSecurityPolicy that sets requiredDropCapabilities to ALL. An example of this can be found in the Hardening Guide.\n          https://docs.rancher.cn/docs/k3s/security/hardening-guide/_index\n        scored: false\n\n  - id: 5.3\n    text: \"Network Policies and CNI\"\n    checks:\n      - id: 5.3.1\n        text: \"Ensure that the CNI in use supports Network Policies (Manual)\"\n        type: \"manual\"\n        remediation: |\n          By default, K3s use Canal (Calico and Flannel) and fully supports network policies.\n        scored: false\n\n      - id: 5.3.2\n        text: \"Ensure that all Namespaces have Network Policies defined (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Run the below command on the master node.\n          for i in kube-system kube-public default; do\n            kubectl get networkpolicies -n $i;\n          done\n          Verify that there are network policies applied to each of the namespaces.\n          An operator should apply NetworkPolcyies that prevent unneeded traffic from traversing networks unnecessarily. An example of applying a NetworkPolcy can be found in the Hardening Guide.\n          https://docs.rancher.cn/docs/k3s/security/hardening-guide/_index\n        scored: false\n\n  - id: 5.4\n    text: \"Secrets Management\"\n    checks:\n      - id: 5.4.1\n        text: \"Prefer using secrets as files over secrets as environment variables (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Run the following command to find references to objects which use environment variables defined from secrets.\n          kubectl get all -o jsonpath='{range .items[?(@..secretKeyRef)]} {.kind} {.metadata.name} {\"\\n\"}{end}' -A\n\n          if possible, rewrite application code to read secrets from mounted secret files, rather than\n          from environment variables.\n        scored: false\n\n      - id: 5.4.2\n        text: \"Consider external secret storage (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Refer to the secrets management options offered by your cloud provider or a third-party\n          secrets management solution.\n        scored: false\n\n  - id: 5.5\n    text: \"Extensible Admission Control\"\n    checks:\n      - id: 5.5.1\n        text: \"Configure Image Provenance using ImagePolicyWebhook admission controller (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and setup image provenance.\n        scored: false\n\n  - id: 5.7\n    text: \"General Policies\"\n    checks:\n      - id: 5.7.1\n        text: \"Create administrative boundaries between resources using namespaces (Manual)\"\n        audit: kubectl get namespaces\n        type: \"manual\"\n        remediation: |\n          Ensure that these namespaces are the ones you need and are adequately administered as per your requirements.\n          Follow the documentation and create namespaces for objects in your deployment as you need\n          them.\n        scored: false\n\n      - id: 5.7.2\n        text: \"Ensure that the seccomp profile is set to docker/default in your pod definitions (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Seccomp is an alpha feature currently. By default, all alpha features are disabled. So, you\n          would need to enable alpha features in the apiserver by passing \"--feature-\n          gates=AllAlpha=true\" argument.\n          Edit the /etc/kubernetes/apiserver file on the master node and set the KUBE_API_ARGS\n          parameter to \"--feature-gates=AllAlpha=true\"\n          KUBE_API_ARGS=\"--feature-gates=AllAlpha=true\"\n          Based on your system, restart the kube-apiserver service. For example:\n          systemctl restart kube-apiserver.service\n          Use annotations to enable the docker/default seccomp profile in your pod definitions. An\n          example is as below:\n          apiVersion: v1\n          kind: Pod\n          metadata:\n            name: trustworthy-pod\n            annotations:\n              seccomp.security.alpha.kubernetes.io/pod: docker/default\n          spec:\n            containers:\n              - name: trustworthy-container\n                image: sotrustworthy:latest\n        scored: false\n\n      - id: 5.7.3\n        text: \"Apply Security Context to Your Pods and Containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and apply security contexts to your pods. For a\n          suggested list of security contexts, you may refer to the CIS Security Benchmark for Docker\n          Containers.\n        scored: false\n\n      - id: 5.7.4\n        text: \"The default namespace should not be used (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Run the below command on the master node.\n          kubectl get all -n default\n          The only entries there should be system-managed resources such as the kubernetes service.\n          Ensure that namespaces are created to allow for appropriate segregation of Kubernetes\n          resources and that all new resources are created in a specific namespace.\n        scored: false\n"
  },
  {
    "path": "cfg/cis-1.7/config.yaml",
    "content": "---\n## Version-specific settings that override the values in cfg/config.yaml\n"
  },
  {
    "path": "cfg/cis-1.7/controlplane.yaml",
    "content": "---\ncontrols:\nversion: \"cis-1.7\"\nid: 3\ntext: \"Control Plane Configuration\"\ntype: \"controlplane\"\ngroups:\n  - id: 3.1\n    text: \"Authentication and Authorization\"\n    checks:\n      - id: 3.1.1\n        text: \"Client certificate authentication should not be used for users (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Alternative mechanisms provided by Kubernetes such as the use of OIDC should be\n          implemented in place of client certificates.\n        scored: false\n      - id: 3.1.2\n        text: \"Service account token authentication should not be used for users (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Alternative mechanisms provided by Kubernetes such as the use of OIDC should be implemented\n          in place of service account tokens.\n        scored: false\n      - id: 3.1.3\n        text: \"Bootstrap token authentication should not be used for users (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Alternative mechanisms provided by Kubernetes such as the use of OIDC should be implemented\n          in place of bootstrap tokens.\n        scored: false\n\n  - id: 3.2\n    text: \"Logging\"\n    checks:\n      - id: 3.2.1\n        text: \"Ensure that a minimal audit policy is created (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-policy-file\"\n              set: true\n        remediation: |\n          Create an audit policy file for your cluster.\n        scored: false\n\n      - id: 3.2.2\n        text: \"Ensure that the audit policy covers key security concerns (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Review the audit policy provided for the cluster and ensure that it covers\n          at least the following areas,\n          - Access to Secrets managed by the cluster. Care should be taken to only\n            log Metadata for requests to Secrets, ConfigMaps, and TokenReviews, in\n            order to avoid risk of logging sensitive data.\n          - Modification of Pod and Deployment objects.\n          - Use of `pods/exec`, `pods/portforward`, `pods/proxy` and `services/proxy`.\n          For most requests, minimally logging at the Metadata level is recommended\n          (the most basic level of logging).\n        scored: false\n"
  },
  {
    "path": "cfg/cis-1.7/etcd.yaml",
    "content": "---\ncontrols:\nversion: \"cis-1.7\"\nid: 2\ntext: \"Etcd Node Configuration\"\ntype: \"etcd\"\ngroups:\n  - id: 2\n    text: \"Etcd Node Configuration\"\n    checks:\n      - id: 2.1\n        text: \"Ensure that the --cert-file and --key-file arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--cert-file\"\n              env: \"ETCD_CERT_FILE\"\n            - flag: \"--key-file\"\n              env: \"ETCD_KEY_FILE\"\n        remediation: |\n          Follow the etcd service documentation and configure TLS encryption.\n          Then, edit the etcd pod specification file /etc/kubernetes/manifests/etcd.yaml\n          on the master node and set the below parameters.\n          --cert-file=</path/to/ca-file>\n          --key-file=</path/to/key-file>\n        scored: true\n\n      - id: 2.2\n        text: \"Ensure that the --client-cert-auth argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--client-cert-auth\"\n              env: \"ETCD_CLIENT_CERT_AUTH\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and set the below parameter.\n          --client-cert-auth=\"true\"\n        scored: true\n\n      - id: 2.3\n        text: \"Ensure that the --auto-tls argument is not set to true (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--auto-tls\"\n              env: \"ETCD_AUTO_TLS\"\n              set: false\n            - flag: \"--auto-tls\"\n              env: \"ETCD_AUTO_TLS\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and either remove the --auto-tls parameter or set it to false.\n            --auto-tls=false\n        scored: true\n\n      - id: 2.4\n        text: \"Ensure that the --peer-cert-file and --peer-key-file arguments are\n        set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--peer-cert-file\"\n              env: \"ETCD_PEER_CERT_FILE\"\n            - flag: \"--peer-key-file\"\n              env: \"ETCD_PEER_KEY_FILE\"\n        remediation: |\n          Follow the etcd service documentation and configure peer TLS encryption as appropriate\n          for your etcd cluster.\n          Then, edit the etcd pod specification file $etcdconf on the\n          master node and set the below parameters.\n          --peer-client-file=</path/to/peer-cert-file>\n          --peer-key-file=</path/to/peer-key-file>\n        scored: true\n\n      - id: 2.5\n        text: \"Ensure that the --peer-client-cert-auth argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--peer-client-cert-auth\"\n              env: \"ETCD_PEER_CLIENT_CERT_AUTH\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and set the below parameter.\n          --peer-client-cert-auth=true\n        scored: true\n\n      - id: 2.6\n        text: \"Ensure that the --peer-auto-tls argument is not set to true (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--peer-auto-tls\"\n              env: \"ETCD_PEER_AUTO_TLS\"\n              set: false\n            - flag: \"--peer-auto-tls\"\n              env: \"ETCD_PEER_AUTO_TLS\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and either remove the --peer-auto-tls parameter or set it to false.\n          --peer-auto-tls=false\n        scored: true\n\n      - id: 2.7\n        text: \"Ensure that a unique Certificate Authority is used for etcd (Manual)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--trusted-ca-file\"\n              env: \"ETCD_TRUSTED_CA_FILE\"\n        remediation: |\n          [Manual test]\n          Follow the etcd documentation and create a dedicated certificate authority setup for the\n          etcd service.\n          Then, edit the etcd pod specification file $etcdconf on the\n          master node and set the below parameter.\n          --trusted-ca-file=</path/to/ca-file>\n        scored: false\n"
  },
  {
    "path": "cfg/cis-1.7/master.yaml",
    "content": "---\ncontrols:\nversion: \"cis-1.7\"\nid: 1\ntext: \"Control Plane Security Configuration\"\ntype: \"master\"\ngroups:\n  - id: 1.1\n    text: \"Control Plane Node Configuration Files\"\n    checks:\n      - id: 1.1.1\n        text: \"Ensure that the API server pod specification file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $apiserverconf; then stat -c permissions=%a $apiserverconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the\n          control plane node.\n          For example, chmod 600 $apiserverconf\n        scored: true\n\n      - id: 1.1.2\n        text: \"Ensure that the API server pod specification file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $apiserverconf; then stat -c %U:%G $apiserverconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chown root:root $apiserverconf\n        scored: true\n\n      - id: 1.1.3\n        text: \"Ensure that the controller manager pod specification file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerconf; then stat -c permissions=%a $controllermanagerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chmod 600 $controllermanagerconf\n        scored: true\n\n      - id: 1.1.4\n        text: \"Ensure that the controller manager pod specification file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerconf; then stat -c %U:%G $controllermanagerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chown root:root $controllermanagerconf\n        scored: true\n\n      - id: 1.1.5\n        text: \"Ensure that the scheduler pod specification file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerconf; then stat -c permissions=%a $schedulerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chmod 600 $schedulerconf\n        scored: true\n\n      - id: 1.1.6\n        text: \"Ensure that the scheduler pod specification file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerconf; then stat -c %U:%G $schedulerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chown root:root $schedulerconf\n        scored: true\n\n      - id: 1.1.7\n        text: \"Ensure that the etcd pod specification file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $etcdconf; then find $etcdconf -name '*etcd*' | xargs stat -c permissions=%a; fi'\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod 600 $etcdconf\n        scored: true\n\n      - id: 1.1.8\n        text: \"Ensure that the etcd pod specification file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $etcdconf; then find $etcdconf -name '*etcd*' | xargs stat -c %U:%G; fi'\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root $etcdconf\n        scored: true\n\n      - id: 1.1.9\n        text: \"Ensure that the Container Network Interface file permissions are set to 600 or more restrictive (Manual)\"\n        audit: |\n          ps -ef | grep $kubeletbin | grep -- --cni-conf-dir | sed 's%.*cni-conf-dir[= ]\\([^ ]*\\).*%\\1%' | xargs -I{} find {} -mindepth 1 | xargs --no-run-if-empty stat -c permissions=%a\n          find /var/lib/cni/networks -type f 2> /dev/null | xargs --no-run-if-empty stat -c permissions=%a\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chmod 600 <path/to/cni/files>\n        scored: false\n\n      - id: 1.1.10\n        text: \"Ensure that the Container Network Interface file ownership is set to root:root (Manual)\"\n        audit: |\n          ps -ef | grep $kubeletbin | grep -- --cni-conf-dir | sed 's%.*cni-conf-dir[= ]\\([^ ]*\\).*%\\1%' | xargs -I{} find {} -mindepth 1 | xargs --no-run-if-empty stat -c %U:%G\n          find /var/lib/cni/networks -type f 2> /dev/null | xargs --no-run-if-empty stat -c %U:%G\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root <path/to/cni/files>\n        scored: false\n\n      - id: 1.1.11\n        text: \"Ensure that the etcd data directory permissions are set to 700 or more restrictive (Automated)\"\n        audit: |\n          DATA_DIR=''\n          for d in $(ps -ef | grep $etcdbin | grep -- --data-dir | sed 's%.*data-dir[= ]\\([^ ]*\\).*%\\1%'); do\n            if test -d \"$d\"; then DATA_DIR=\"$d\"; fi\n          done\n          if ! test -d \"$DATA_DIR\"; then DATA_DIR=$etcddatadir; fi\n          stat -c permissions=%a \"$DATA_DIR\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"700\"\n        remediation: |\n          On the etcd server node, get the etcd data directory, passed as an argument --data-dir,\n          from the command 'ps -ef | grep etcd'.\n          Run the below command (based on the etcd data directory found above). For example,\n          chmod 700 /var/lib/etcd\n        scored: true\n\n      - id: 1.1.12\n        text: \"Ensure that the etcd data directory ownership is set to etcd:etcd (Automated)\"\n        audit: |\n          DATA_DIR=''\n          for d in $(ps -ef | grep $etcdbin | grep -- --data-dir | sed 's%.*data-dir[= ]\\([^ ]*\\).*%\\1%'); do\n            if test -d \"$d\"; then DATA_DIR=\"$d\"; fi\n          done\n          if ! test -d \"$DATA_DIR\"; then DATA_DIR=$etcddatadir; fi\n          stat -c %U:%G \"$DATA_DIR\"\n        tests:\n          test_items:\n            - flag: \"etcd:etcd\"\n        remediation: |\n          On the etcd server node, get the etcd data directory, passed as an argument --data-dir,\n          from the command 'ps -ef | grep etcd'.\n          Run the below command (based on the etcd data directory found above).\n          For example, chown etcd:etcd /var/lib/etcd\n        scored: true\n\n      - id: 1.1.13\n        text: \"Ensure that the admin.conf file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e /etc/kubernetes/admin.conf; then stat -c permissions=%a /etc/kubernetes/admin.conf; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chmod 600 /etc/kubernetes/admin.conf\n        scored: true\n\n      - id: 1.1.14\n        text: \"Ensure that the admin.conf file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e /etc/kubernetes/admin.conf; then stat -c %U:%G /etc/kubernetes/admin.conf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chown root:root /etc/kubernetes/admin.conf\n        scored: true\n\n      - id: 1.1.15\n        text: \"Ensure that the scheduler.conf file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerkubeconfig; then stat -c permissions=%a $schedulerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod 600 $schedulerkubeconfig\n        scored: true\n\n      - id: 1.1.16\n        text: \"Ensure that the scheduler.conf file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerkubeconfig; then stat -c %U:%G $schedulerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root $schedulerkubeconfig\n        scored: true\n\n      - id: 1.1.17\n        text: \"Ensure that the controller-manager.conf file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerkubeconfig; then stat -c permissions=%a $controllermanagerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod 600 $controllermanagerkubeconfig\n        scored: true\n\n      - id: 1.1.18\n        text: \"Ensure that the controller-manager.conf file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerkubeconfig; then stat -c %U:%G $controllermanagerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root $controllermanagerkubeconfig\n        scored: true\n\n      - id: 1.1.19\n        text: \"Ensure that the Kubernetes PKI directory and file ownership is set to root:root (Automated)\"\n        audit: \"find /etc/kubernetes/pki/ | xargs stat -c %U:%G\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown -R root:root /etc/kubernetes/pki/\n        scored: true\n\n      - id: 1.1.20\n        text: \"Ensure that the Kubernetes PKI certificate file permissions are set to 600 or more restrictive (Manual)\"\n        audit: \"find /etc/kubernetes/pki/ -name '*.crt' | xargs stat -c permissions=%a\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod -R 600 /etc/kubernetes/pki/*.crt\n        scored: false\n\n      - id: 1.1.21\n        text: \"Ensure that the Kubernetes PKI key file permissions are set to 600 (Manual)\"\n        audit: \"find /etc/kubernetes/pki/ -name '*.key' | xargs stat -c permissions=%a\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod -R 600 /etc/kubernetes/pki/*.key\n        scored: false\n\n  - id: 1.2\n    text: \"API Server\"\n    checks:\n      - id: 1.2.1\n        text: \"Ensure that the --anonymous-auth argument is set to false (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--anonymous-auth\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the below parameter.\n          --anonymous-auth=false\n        scored: false\n\n      - id: 1.2.2\n        text: \"Ensure that the --token-auth-file parameter is not set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--token-auth-file\"\n              set: false\n        remediation: |\n          Follow the documentation and configure alternate mechanisms for authentication. Then,\n          edit the API server pod specification file $apiserverconf\n          on the control plane node and remove the --token-auth-file=<filename> parameter.\n        scored: true\n\n      - id: 1.2.3\n        text: \"Ensure that the --DenyServiceExternalIPs is set (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"DenyServiceExternalIPs\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and add the `DenyServiceExternalIPs` plugin\n          to the enabled admission plugins, as such --enable-admission-plugin=DenyServiceExternalIPs.\n        scored: false\n\n      - id: 1.2.4\n        text: \"Ensure that the --kubelet-client-certificate and --kubelet-client-key arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--kubelet-client-certificate\"\n            - flag: \"--kubelet-client-key\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection between the\n          apiserver and kubelets. Then, edit API server pod specification file\n          $apiserverconf on the control plane node and set the\n          kubelet client certificate and key parameters as below.\n          --kubelet-client-certificate=<path/to/client-certificate-file>\n          --kubelet-client-key=<path/to/client-key-file>\n        scored: true\n\n      - id: 1.2.5\n        text: \"Ensure that the --kubelet-certificate-authority argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--kubelet-certificate-authority\"\n        remediation: |\n          Follow the Kubernetes documentation and setup the TLS connection between\n          the apiserver and kubelets. Then, edit the API server pod specification file\n          $apiserverconf on the control plane node and set the\n          --kubelet-certificate-authority parameter to the path to the cert file for the certificate authority.\n          --kubelet-certificate-authority=<ca-string>\n        scored: true\n\n      - id: 1.2.6\n        text: \"Ensure that the --authorization-mode argument is not set to AlwaysAllow (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: nothave\n                value: \"AlwaysAllow\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --authorization-mode parameter to values other than AlwaysAllow.\n          One such example could be as below.\n          --authorization-mode=RBAC\n        scored: true\n\n      - id: 1.2.7\n        text: \"Ensure that the --authorization-mode argument includes Node (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: has\n                value: \"Node\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --authorization-mode parameter to a value that includes Node.\n          --authorization-mode=Node,RBAC\n        scored: true\n\n      - id: 1.2.8\n        text: \"Ensure that the --authorization-mode argument includes RBAC (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: has\n                value: \"RBAC\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --authorization-mode parameter to a value that includes RBAC,\n          for example `--authorization-mode=Node,RBAC`.\n        scored: true\n\n      - id: 1.2.9\n        text: \"Ensure that the admission control plugin EventRateLimit is set (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"EventRateLimit\"\n        remediation: |\n          Follow the Kubernetes documentation and set the desired limits in a configuration file.\n          Then, edit the API server pod specification file $apiserverconf\n          and set the below parameters.\n          --enable-admission-plugins=...,EventRateLimit,...\n          --admission-control-config-file=<path/to/configuration/file>\n        scored: false\n\n      - id: 1.2.10\n        text: \"Ensure that the admission control plugin AlwaysAdmit is not set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: nothave\n                value: AlwaysAdmit\n            - flag: \"--enable-admission-plugins\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and either remove the --enable-admission-plugins parameter, or set it to a\n          value that does not include AlwaysAdmit.\n        scored: true\n\n      - id: 1.2.11\n        text: \"Ensure that the admission control plugin AlwaysPullImages is set (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"AlwaysPullImages\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --enable-admission-plugins parameter to include\n          AlwaysPullImages.\n          --enable-admission-plugins=...,AlwaysPullImages,...\n        scored: false\n\n      - id: 1.2.12\n        text: \"Ensure that the admission control plugin SecurityContextDeny is set if PodSecurityPolicy is not used (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"SecurityContextDeny\"\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"PodSecurityPolicy\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --enable-admission-plugins parameter to include\n          SecurityContextDeny, unless PodSecurityPolicy is already in place.\n          --enable-admission-plugins=...,SecurityContextDeny,...\n        scored: false\n\n      - id: 1.2.13\n        text: \"Ensure that the admission control plugin ServiceAccount is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--disable-admission-plugins\"\n              compare:\n                op: nothave\n                value: \"ServiceAccount\"\n            - flag: \"--disable-admission-plugins\"\n              set: false\n        remediation: |\n          Follow the documentation and create ServiceAccount objects as per your environment.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and ensure that the --disable-admission-plugins parameter is set to a\n          value that does not include ServiceAccount.\n        scored: true\n\n      - id: 1.2.14\n        text: \"Ensure that the admission control plugin NamespaceLifecycle is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--disable-admission-plugins\"\n              compare:\n                op: nothave\n                value: \"NamespaceLifecycle\"\n            - flag: \"--disable-admission-plugins\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --disable-admission-plugins parameter to\n          ensure it does not include NamespaceLifecycle.\n        scored: true\n\n      - id: 1.2.15\n        text: \"Ensure that the admission control plugin NodeRestriction is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"NodeRestriction\"\n        remediation: |\n          Follow the Kubernetes documentation and configure NodeRestriction plug-in on kubelets.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --enable-admission-plugins parameter to a\n          value that includes NodeRestriction.\n          --enable-admission-plugins=...,NodeRestriction,...\n        scored: true\n\n      - id: 1.2.16\n        text: \"Ensure that the --secure-port argument is not set to 0 - NoteThis recommendation is obsolete and will be deleted per the consensus process (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--secure-port\"\n              compare:\n                op: gt\n                value: 0\n            - flag: \"--secure-port\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and either remove the --secure-port parameter or\n          set it to a different (non-zero) desired port.\n        scored: false\n\n      - id: 1.2.17\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the below parameter.\n          --profiling=false\n        scored: true\n\n      - id: 1.2.18\n        text: \"Ensure that the --audit-log-path argument is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-path\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --audit-log-path parameter to a suitable path and\n          file where you would like audit logs to be written, for example,\n          --audit-log-path=/var/log/apiserver/audit.log\n        scored: true\n\n      - id: 1.2.19\n        text: \"Ensure that the --audit-log-maxage argument is set to 30 or as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxage\"\n              compare:\n                op: gte\n                value: 30\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --audit-log-maxage parameter to 30\n          or as an appropriate number of days, for example,\n          --audit-log-maxage=30\n        scored: true\n\n      - id: 1.2.20\n        text: \"Ensure that the --audit-log-maxbackup argument is set to 10 or as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxbackup\"\n              compare:\n                op: gte\n                value: 10\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --audit-log-maxbackup parameter to 10 or to an appropriate\n          value. For example,\n          --audit-log-maxbackup=10\n        scored: true\n\n      - id: 1.2.21\n        text: \"Ensure that the --audit-log-maxsize argument is set to 100 or as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxsize\"\n              compare:\n                op: gte\n                value: 100\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --audit-log-maxsize parameter to an appropriate size in MB.\n          For example, to set it as 100 MB, --audit-log-maxsize=100\n        scored: true\n\n      - id: 1.2.22\n        text: \"Ensure that the --request-timeout argument is set as appropriate (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        type: manual\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          and set the below parameter as appropriate and if needed.\n          For example, --request-timeout=300s\n        scored: false\n\n      - id: 1.2.23\n        text: \"Ensure that the --service-account-lookup argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--service-account-lookup\"\n              set: false\n            - flag: \"--service-account-lookup\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the below parameter.\n          --service-account-lookup=true\n          Alternatively, you can delete the --service-account-lookup parameter from this file so\n          that the default takes effect.\n        scored: true\n\n      - id: 1.2.24\n        text: \"Ensure that the --service-account-key-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--service-account-key-file\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --service-account-key-file parameter\n          to the public key file for service accounts. For example,\n          --service-account-key-file=<filename>\n        scored: true\n\n      - id: 1.2.25\n        text: \"Ensure that the --etcd-certfile and --etcd-keyfile arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--etcd-certfile\"\n            - flag: \"--etcd-keyfile\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection between the apiserver and etcd.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the etcd certificate and key file parameters.\n          --etcd-certfile=<path/to/client-certificate-file>\n          --etcd-keyfile=<path/to/client-key-file>\n        scored: true\n\n      - id: 1.2.26\n        text: \"Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--tls-cert-file\"\n            - flag: \"--tls-private-key-file\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection on the apiserver.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the TLS certificate and private key file parameters.\n          --tls-cert-file=<path/to/tls-certificate-file>\n          --tls-private-key-file=<path/to/tls-key-file>\n        scored: true\n\n      - id: 1.2.27\n        text: \"Ensure that the --client-ca-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--client-ca-file\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection on the apiserver.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the client certificate authority file.\n          --client-ca-file=<path/to/client-ca-file>\n        scored: true\n\n      - id: 1.2.28\n        text: \"Ensure that the --etcd-cafile argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--etcd-cafile\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection between the apiserver and etcd.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the etcd certificate authority file parameter.\n          --etcd-cafile=<path/to/ca-file>\n        scored: true\n\n      - id: 1.2.29\n        text: \"Ensure that the --encryption-provider-config argument is set as appropriate (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--encryption-provider-config\"\n        remediation: |\n          Follow the Kubernetes documentation and configure a EncryptionConfig file.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --encryption-provider-config parameter to the path of that file.\n          For example, --encryption-provider-config=</path/to/EncryptionConfig/File>\n        scored: false\n\n      - id: 1.2.30\n        text: \"Ensure that encryption providers are appropriately configured (Manual)\"\n        audit: |\n          ENCRYPTION_PROVIDER_CONFIG=$(ps -ef | grep $apiserverbin | grep -- --encryption-provider-config | sed 's%.*encryption-provider-config[= ]\\([^ ]*\\).*%\\1%')\n          if test -e $ENCRYPTION_PROVIDER_CONFIG; then grep -A1 'providers:' $ENCRYPTION_PROVIDER_CONFIG | tail -n1 | grep -o \"[A-Za-z]*\" | sed 's/^/provider=/'; fi\n        tests:\n          test_items:\n            - flag: \"provider\"\n              compare:\n                op: valid_elements\n                value: \"aescbc,kms,secretbox\"\n        remediation: |\n          Follow the Kubernetes documentation and configure a EncryptionConfig file.\n          In this file, choose aescbc, kms or secretbox as the encryption provider.\n        scored: false\n\n      - id: 1.2.31\n        text: \"Ensure that the API Server only makes use of Strong Cryptographic Ciphers (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--tls-cipher-suites\"\n              compare:\n                op: valid_elements\n                value: \"TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,TLS_CHACHA20_POLY1305_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,TLS_RSA_WITH_3DES_EDE_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_256_GCM_SHA384\"\n        remediation: |\n          Edit the API server pod specification file /etc/kubernetes/manifests/kube-apiserver.yaml\n          on the control plane node and set the below parameter.\n          --tls-cipher-suites=TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,TLS_CHACHA20_POLY1305_SHA256,\n          TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,\n          TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,\n          TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,\n          TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,\n          TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,\n          TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,TLS_RSA_WITH_3DES_EDE_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA,\n          TLS_RSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_256_GCM_SHA384\n        scored: false\n\n  - id: 1.3\n    text: \"Controller Manager\"\n    checks:\n      - id: 1.3.1\n        text: \"Ensure that the --terminated-pod-gc-threshold argument is set as appropriate (Manual)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--terminated-pod-gc-threshold\"\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the --terminated-pod-gc-threshold to an appropriate threshold,\n          for example, --terminated-pod-gc-threshold=10\n        scored: false\n\n      - id: 1.3.2\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the below parameter.\n          --profiling=false\n        scored: true\n\n      - id: 1.3.3\n        text: \"Ensure that the --use-service-account-credentials argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--use-service-account-credentials\"\n              compare:\n                op: noteq\n                value: false\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node to set the below parameter.\n          --use-service-account-credentials=true\n        scored: true\n\n      - id: 1.3.4\n        text: \"Ensure that the --service-account-private-key-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--service-account-private-key-file\"\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the --service-account-private-key-file parameter\n          to the private key file for service accounts.\n          --service-account-private-key-file=<filename>\n        scored: true\n\n      - id: 1.3.5\n        text: \"Ensure that the --root-ca-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--root-ca-file\"\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the --root-ca-file parameter to the certificate bundle file`.\n          --root-ca-file=<path/to/file>\n        scored: true\n\n      - id: 1.3.6\n        text: \"Ensure that the RotateKubeletServerCertificate argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--feature-gates\"\n              compare:\n                op: nothave\n                value: \"RotateKubeletServerCertificate=false\"\n              set: true\n            - flag: \"--feature-gates\"\n              set: false\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the --feature-gates parameter to include RotateKubeletServerCertificate=true.\n          --feature-gates=RotateKubeletServerCertificate=true\n        scored: true\n\n      - id: 1.3.7\n        text: \"Ensure that the --bind-address argument is set to 127.0.0.1 (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--bind-address\"\n              compare:\n                op: eq\n                value: \"127.0.0.1\"\n            - flag: \"--bind-address\"\n              set: false\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and ensure the correct value for the --bind-address parameter\n        scored: true\n\n  - id: 1.4\n    text: \"Scheduler\"\n    checks:\n      - id: 1.4.1\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: \"/bin/ps -ef | grep $schedulerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the Scheduler pod specification file $schedulerconf file\n          on the control plane node and set the below parameter.\n          --profiling=false\n        scored: true\n\n      - id: 1.4.2\n        text: \"Ensure that the --bind-address argument is set to 127.0.0.1 (Automated)\"\n        audit: \"/bin/ps -ef | grep $schedulerbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--bind-address\"\n              compare:\n                op: eq\n                value: \"127.0.0.1\"\n            - flag: \"--bind-address\"\n              set: false\n        remediation: |\n          Edit the Scheduler pod specification file $schedulerconf\n          on the control plane node and ensure the correct value for the --bind-address parameter\n        scored: true\n"
  },
  {
    "path": "cfg/cis-1.7/node.yaml",
    "content": "---\ncontrols:\nversion: \"cis-1.7\"\nid: 4\ntext: \"Worker Node Security Configuration\"\ntype: \"node\"\ngroups:\n  - id: 4.1\n    text: \"Worker Node Configuration Files\"\n    checks:\n      - id: 4.1.1\n        text: \"Ensure that the kubelet service file permissions are set to 600 or more restrictive (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletsvc; then stat -c permissions=%a $kubeletsvc; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example, chmod 600 $kubeletsvc\n        scored: true\n\n      - id: 4.1.2\n        text: \"Ensure that the kubelet service file ownership is set to root:root (Automated)\"\n        audit: '/bin/sh -c \"if test -e $kubeletsvc; then stat -c %U:%G $kubeletsvc; else echo \\\"File not found\\\"; fi\"'\n        tests:\n          bin_op: or\n          test_items:\n            - flag: root:root\n            - flag: \"File not found\"\n        remediation: |\n            Run the below command (based on the file location on your system) on the each worker node.\n            For example,\n            chown root:root $kubeletsvc\n        scored: true\n\n      - id: 4.1.3\n        text: \"If proxy kubeconfig file exists ensure permissions are set to 600 or more restrictive (Manual)\"\n        audit: '/bin/sh -c ''if test -e $proxykubeconfig; then stat -c permissions=%a $proxykubeconfig; fi'' '\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"permissions\"\n              set: true\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chmod 600 $proxykubeconfig\n        scored: false\n\n      - id: 4.1.4\n        text: \"If proxy kubeconfig file exists ensure ownership is set to root:root (Manual)\"\n        audit: '/bin/sh -c ''if test -e $proxykubeconfig; then stat -c %U:%G $proxykubeconfig; fi'' '\n        tests:\n          bin_op: or\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example, chown root:root $proxykubeconfig\n        scored: false\n\n      - id: 4.1.5\n        text: \"Ensure that the --kubeconfig kubelet.conf file permissions are set to 600 or more restrictive (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletkubeconfig; then stat -c permissions=%a $kubeletkubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chmod 600 $kubeletkubeconfig\n        scored: true\n\n      - id: 4.1.6\n        text: \"Ensure that the --kubeconfig kubelet.conf file ownership is set to root:root (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletkubeconfig; then stat -c %U:%G $kubeletkubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chown root:root $kubeletkubeconfig\n        scored: true\n\n      - id: 4.1.7\n        text: \"Ensure that the certificate authorities file permissions are set to 600 or more restrictive (Manual)\"\n        audit: |\n          CAFILE=$(ps -ef | grep kubelet | grep -v apiserver | grep -- --client-ca-file= | awk -F '--client-ca-file=' '{print $2}' | awk '{print $1}' | uniq)\n          if test -z $CAFILE; then CAFILE=$kubeletcafile; fi\n          if test -e $CAFILE; then stat -c permissions=%a $CAFILE; fi\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the following command to modify the file permissions of the\n          --client-ca-file chmod 600 <filename>\n        scored: false\n\n      - id: 4.1.8\n        text: \"Ensure that the client certificate authorities file ownership is set to root:root (Manual)\"\n        audit: |\n          CAFILE=$(ps -ef | grep kubelet | grep -v apiserver | grep -- --client-ca-file= | awk -F '--client-ca-file=' '{print $2}' | awk '{print $1}' | uniq)\n          if test -z $CAFILE; then CAFILE=$kubeletcafile; fi\n          if test -e $CAFILE; then stat -c %U:%G $CAFILE; fi\n        tests:\n          test_items:\n            - flag: root:root\n              compare:\n                op: eq\n                value: root:root\n        remediation: |\n          Run the following command to modify the ownership of the --client-ca-file.\n          chown root:root <filename>\n        scored: false\n\n      - id: 4.1.9\n        text: \"If the kubelet config.yaml configuration file is being used validate permissions set to 600 or more restrictive (Manual)\"\n        audit: '/bin/sh -c ''if test -e $kubeletconf; then stat -c permissions=%a $kubeletconf; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the following command (using the config file location identified in the Audit step)\n          chmod 600 $kubeletconf\n        scored: false\n\n      - id: 4.1.10\n        text: \"If the kubelet config.yaml configuration file is being used validate file ownership is set to root:root (Manual)\"\n        audit: '/bin/sh -c ''if test -e $kubeletconf; then stat -c %U:%G $kubeletconf; fi'' '\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the following command (using the config file location identified in the Audit step)\n          chown root:root $kubeletconf\n        scored: false\n\n  - id: 4.2\n    text: \"Kubelet\"\n    checks:\n      - id: 4.2.1\n        text: \"Ensure that the --anonymous-auth argument is set to false (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: \"--anonymous-auth\"\n              path: '{.authentication.anonymous.enabled}'\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          If using a Kubelet config file, edit the file to set `authentication: anonymous: enabled` to\n          `false`.\n          If using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          `--anonymous-auth=false`\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.2\n        text: \"Ensure that the --authorization-mode argument is not set to AlwaysAllow (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --authorization-mode\n              path: '{.authorization.mode}'\n              compare:\n                op: nothave\n                value: AlwaysAllow\n        remediation: |\n          If using a Kubelet config file, edit the file to set `authorization.mode` to Webhook. If\n          using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_AUTHZ_ARGS variable.\n          --authorization-mode=Webhook\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.3\n        text: \"Ensure that the --client-ca-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --client-ca-file\n              path: '{.authentication.x509.clientCAFile}'\n        remediation: |\n          If using a Kubelet config file, edit the file to set `authentication.x509.clientCAFile` to\n          the location of the client CA file.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_AUTHZ_ARGS variable.\n          --client-ca-file=<path/to/client-ca-file>\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.4\n        text: \"Verify that the --read-only-port argument is set to 0 (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--read-only-port\"\n              path: '{.readOnlyPort}'\n              compare:\n                op: eq\n                value: 0\n            - flag: \"--read-only-port\"\n              path: '{.readOnlyPort}'\n              set: false\n        remediation: |\n          If using a Kubelet config file, edit the file to set `readOnlyPort` to 0.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --read-only-port=0\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.5\n        text: \"Ensure that the --streaming-connection-idle-timeout argument is not set to 0 (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --streaming-connection-idle-timeout\n              path: '{.streamingConnectionIdleTimeout}'\n              compare:\n                op: noteq\n                value: 0\n            - flag: --streaming-connection-idle-timeout\n              path: '{.streamingConnectionIdleTimeout}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to set `streamingConnectionIdleTimeout` to a\n          value other than 0.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --streaming-connection-idle-timeout=5m\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.6\n        text: \"Ensure that the --make-iptables-util-chains argument is set to true (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --make-iptables-util-chains\n              path: '{.makeIPTablesUtilChains}'\n              compare:\n                op: eq\n                value: true\n            - flag: --make-iptables-util-chains\n              path: '{.makeIPTablesUtilChains}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to set `makeIPTablesUtilChains` to `true`.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          remove the --make-iptables-util-chains argument from the\n          KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.7\n        text: \"Ensure that the --hostname-override argument is not set (Manual)\"\n        # This is one of those properties that can only be set as a command line argument.\n        # To check if the property is set as expected, we need to parse the kubelet command\n        # instead reading the Kubelet Configuration file.\n        audit: \"/bin/ps -fC $kubeletbin \"\n        tests:\n          test_items:\n            - flag: --hostname-override\n              set: false\n        remediation: |\n          Edit the kubelet service file $kubeletsvc\n          on each worker node and remove the --hostname-override argument from the\n          KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.8\n        text: \"Ensure that the eventRecordQPS argument is set to a level which ensures appropriate event capture (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --event-qps\n              path: '{.eventRecordQPS}'\n              compare:\n                op: gte\n                value: 0\n            - flag: --event-qps\n              path: '{.eventRecordQPS}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to set `eventRecordQPS` to an appropriate level.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.9\n        text: \"Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --tls-cert-file\n              path: '{.tlsCertFile}'\n            - flag: --tls-private-key-file\n              path: '{.tlsPrivateKeyFile}'\n        remediation: |\n          If using a Kubelet config file, edit the file to set `tlsCertFile` to the location\n          of the certificate file to use to identify this Kubelet, and `tlsPrivateKeyFile`\n          to the location of the corresponding private key file.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameters in KUBELET_CERTIFICATE_ARGS variable.\n          --tls-cert-file=<path/to/tls-certificate-file>\n          --tls-private-key-file=<path/to/tls-key-file>\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.10\n        text: \"Ensure that the --rotate-certificates argument is not set to false (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --rotate-certificates\n              path: '{.rotateCertificates}'\n              compare:\n                op: eq\n                value: true\n            - flag: --rotate-certificates\n              path: '{.rotateCertificates}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to add the line `rotateCertificates` to `true` or\n          remove it altogether to use the default value.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          remove --rotate-certificates=false argument from the KUBELET_CERTIFICATE_ARGS\n          variable.\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.11\n        text: \"Verify that the RotateKubeletServerCertificate argument is set to true (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: RotateKubeletServerCertificate\n              path: '{.featureGates.RotateKubeletServerCertificate}'\n              compare:\n                op: nothave\n                value: false\n            - flag: RotateKubeletServerCertificate\n              path: '{.featureGates.RotateKubeletServerCertificate}'\n              set: false\n        remediation: |\n          Edit the kubelet service file $kubeletsvc\n          on each worker node and set the below parameter in KUBELET_CERTIFICATE_ARGS variable.\n          --feature-gates=RotateKubeletServerCertificate=true\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.12\n        text: \"Ensure that the Kubelet only makes use of Strong Cryptographic Ciphers (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --tls-cipher-suites\n              path: '{range .tlsCipherSuites[:]}{}{'',''}{end}'\n              compare:\n                op: valid_elements\n                value: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\n        remediation: |\n          If using a Kubelet config file, edit the file to set `tlsCipherSuites` to\n          TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\n          or to a subset of these values.\n          If using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the --tls-cipher-suites parameter as follows, or to a subset of these values.\n          --tls-cipher-suites=TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.13\n        text: \"Ensure that a limit is set on pod PIDs (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --pod-max-pids\n              path: '{.podPidsLimit}'\n        remediation: |\n          Decide on an appropriate level for this parameter and set it,\n          either via the --pod-max-pids command line parameter or the PodPidsLimit configuration file setting.\n        scored: false\n"
  },
  {
    "path": "cfg/cis-1.7/policies.yaml",
    "content": "---\ncontrols:\nversion: \"cis-1.7\"\nid: 5\ntext: \"Kubernetes Policies\"\ntype: \"policies\"\ngroups:\n  - id: 5.1\n    text: \"RBAC and Service Accounts\"\n    checks:\n      - id: 5.1.1\n        text: \"Ensure that the cluster-admin role is only used where required (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Identify all clusterrolebindings to the cluster-admin role. Check if they are used and\n          if they need this role or if they could use a role with fewer privileges.\n          Where possible, first bind users to a lower privileged role and then remove the\n          clusterrolebinding to the cluster-admin role :\n          kubectl delete clusterrolebinding [name]\n        scored: false\n\n      - id: 5.1.2\n        text: \"Minimize access to secrets (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove get, list and watch access to Secret objects in the cluster.\n        scored: false\n\n      - id: 5.1.3\n        text: \"Minimize wildcard use in Roles and ClusterRoles (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible replace any use of wildcards in clusterroles and roles with specific\n          objects or actions.\n        scored: false\n\n      - id: 5.1.4\n        text: \"Minimize access to create pods (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove create access to pod objects in the cluster.\n        scored: false\n\n      - id: 5.1.5\n        text: \"Ensure that default service accounts are not actively used. (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Create explicit service accounts wherever a Kubernetes workload requires specific access\n          to the Kubernetes API server.\n          Modify the configuration of each default service account to include this value\n          automountServiceAccountToken: false\n        scored: false\n\n      - id: 5.1.6\n        text: \"Ensure that Service Account Tokens are only mounted where necessary (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Modify the definition of pods and service accounts which do not need to mount service\n          account tokens to disable it.\n        scored: false\n\n      - id: 5.1.7\n        text: \"Avoid use of system:masters group (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Remove the system:masters group from all users in the cluster.\n        scored: false\n\n      - id: 5.1.8\n        text: \"Limit use of the Bind, Impersonate and Escalate permissions in the Kubernetes cluster (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove the impersonate, bind and escalate rights from subjects.\n        scored: false\n\n      - id: 5.1.9\n        text: \"Minimize access to create persistent volumes (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove create access to PersistentVolume objects in the cluster.\n        scored: false\n\n      - id: 5.1.10\n        text: \"Minimize access to the proxy sub-resource of nodes (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove access to the proxy sub-resource of node objects.\n        scored: false\n\n      - id: 5.1.11\n        text: \"Minimize access to the approval sub-resource of certificatesigningrequests objects (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove access to the approval sub-resource of certificatesigningrequest objects.\n        scored: false\n\n      - id: 5.1.12\n        text: \"Minimize access to webhook configuration objects (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove access to the validatingwebhookconfigurations or mutatingwebhookconfigurations objects\n        scored: false\n\n      - id: 5.1.13\n        text: \"Minimize access to the service account token creation (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove access to the token sub-resource of serviceaccount objects.\n        scored: false\n\n  - id: 5.2\n    text: \"Pod Security Standards\"\n    checks:\n      - id: 5.2.1\n        text: \"Ensure that the cluster has at least one active policy control mechanism in place (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that either Pod Security Admission or an external policy control system is in place\n          for every namespace which contains user workloads.\n        scored: false\n\n      - id: 5.2.2\n        text: \"Minimize the admission of privileged containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of privileged containers.\n        scored: false\n\n      - id: 5.2.3\n        text: \"Minimize the admission of containers wishing to share the host process ID namespace (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of `hostPID` containers.\n        scored: false\n\n      - id: 5.2.4\n        text: \"Minimize the admission of containers wishing to share the host IPC namespace (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of `hostIPC` containers.\n        scored: false\n\n      - id: 5.2.5\n        text: \"Minimize the admission of containers wishing to share the host network namespace (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of `hostNetwork` containers.\n        scored: false\n\n      - id: 5.2.6\n        text: \"Minimize the admission of containers with allowPrivilegeEscalation (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers with `.spec.allowPrivilegeEscalation` set to `true`.\n        scored: false\n\n      - id: 5.2.7\n        text: \"Minimize the admission of root containers (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Create a policy for each namespace in the cluster, ensuring that either `MustRunAsNonRoot`\n          or `MustRunAs` with the range of UIDs not including 0, is set.\n        scored: false\n\n      - id: 5.2.8\n        text: \"Minimize the admission of containers with the NET_RAW capability (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers with the `NET_RAW` capability.\n        scored: false\n\n      - id: 5.2.9\n        text: \"Minimize the admission of containers with added capabilities (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that `allowedCapabilities` is not present in policies for the cluster unless\n          it is set to an empty array.\n        scored: false\n\n      - id: 5.2.10\n        text: \"Minimize the admission of containers with capabilities assigned (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Review the use of capabilites in applications running on your cluster. Where a namespace\n          contains applications which do not require any Linux capabities to operate consider adding\n          a PSP which forbids the admission of containers which do not drop all capabilities.\n        scored: false\n\n      - id: 5.2.11\n        text: \"Minimize the admission of Windows HostProcess containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers that have `.securityContext.windowsOptions.hostProcess` set to `true`.\n        scored: false\n\n      - id: 5.2.12\n        text: \"Minimize the admission of HostPath volumes (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers with `hostPath` volumes.\n        scored: false\n\n      - id: 5.2.13\n        text: \"Minimize the admission of containers which use HostPorts (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers which use `hostPort` sections.\n        scored: false\n\n  - id: 5.3\n    text: \"Network Policies and CNI\"\n    checks:\n      - id: 5.3.1\n        text: \"Ensure that the CNI in use supports NetworkPolicies (Manual)\"\n        type: \"manual\"\n        remediation: |\n          If the CNI plugin in use does not support network policies, consideration should be given to\n          making use of a different plugin, or finding an alternate mechanism for restricting traffic\n          in the Kubernetes cluster.\n        scored: false\n\n      - id: 5.3.2\n        text: \"Ensure that all Namespaces have NetworkPolicies defined (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the documentation and create NetworkPolicy objects as you need them.\n        scored: false\n\n  - id: 5.4\n    text: \"Secrets Management\"\n    checks:\n      - id: 5.4.1\n        text: \"Prefer using Secrets as files over Secrets as environment variables (Manual)\"\n        type: \"manual\"\n        remediation: |\n          If possible, rewrite application code to read Secrets from mounted secret files, rather than\n          from environment variables.\n        scored: false\n\n      - id: 5.4.2\n        text: \"Consider external secret storage (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Refer to the Secrets management options offered by your cloud provider or a third-party\n          secrets management solution.\n        scored: false\n\n  - id: 5.5\n    text: \"Extensible Admission Control\"\n    checks:\n      - id: 5.5.1\n        text: \"Configure Image Provenance using ImagePolicyWebhook admission controller (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and setup image provenance.\n        scored: false\n\n  - id: 5.7\n    text: \"General Policies\"\n    checks:\n      - id: 5.7.1\n        text: \"Create administrative boundaries between resources using namespaces (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the documentation and create namespaces for objects in your deployment as you need\n          them.\n        scored: false\n\n      - id: 5.7.2\n        text: \"Ensure that the seccomp profile is set to docker/default in your Pod definitions (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Use `securityContext` to enable the docker/default seccomp profile in your pod definitions.\n          An example is as below:\n            securityContext:\n              seccompProfile:\n                type: RuntimeDefault\n        scored: false\n\n      - id: 5.7.3\n        text: \"Apply SecurityContext to your Pods and Containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and apply SecurityContexts to your Pods. For a\n          suggested list of SecurityContexts, you may refer to the CIS Security Benchmark for Docker\n          Containers.\n        scored: false\n\n      - id: 5.7.4\n        text: \"The default namespace should not be used (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that namespaces are created to allow for appropriate segregation of Kubernetes\n          resources and that all new resources are created in a specific namespace.\n        scored: false\n"
  },
  {
    "path": "cfg/cis-1.8/config.yaml",
    "content": "---\n## Version-specific settings that override the values in cfg/config.yaml\n"
  },
  {
    "path": "cfg/cis-1.8/controlplane.yaml",
    "content": "---\ncontrols:\nversion: \"cis-1.8\"\nid: 3\ntext: \"Control Plane Configuration\"\ntype: \"controlplane\"\ngroups:\n  - id: 3.1\n    text: \"Authentication and Authorization\"\n    checks:\n      - id: 3.1.1\n        text: \"Client certificate authentication should not be used for users (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Alternative mechanisms provided by Kubernetes such as the use of OIDC should be\n          implemented in place of client certificates.\n        scored: false\n      - id: 3.1.2\n        text: \"Service account token authentication should not be used for users (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Alternative mechanisms provided by Kubernetes such as the use of OIDC should be implemented\n          in place of service account tokens.\n        scored: false\n      - id: 3.1.3\n        text: \"Bootstrap token authentication should not be used for users (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Alternative mechanisms provided by Kubernetes such as the use of OIDC should be implemented\n          in place of bootstrap tokens.\n        scored: false\n\n  - id: 3.2\n    text: \"Logging\"\n    checks:\n      - id: 3.2.1\n        text: \"Ensure that a minimal audit policy is created (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-policy-file\"\n              set: true\n        remediation: |\n          Create an audit policy file for your cluster.\n        scored: false\n\n      - id: 3.2.2\n        text: \"Ensure that the audit policy covers key security concerns (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Review the audit policy provided for the cluster and ensure that it covers\n          at least the following areas,\n          - Access to Secrets managed by the cluster. Care should be taken to only\n            log Metadata for requests to Secrets, ConfigMaps, and TokenReviews, in\n            order to avoid risk of logging sensitive data.\n          - Modification of Pod and Deployment objects.\n          - Use of `pods/exec`, `pods/portforward`, `pods/proxy` and `services/proxy`.\n          For most requests, minimally logging at the Metadata level is recommended\n          (the most basic level of logging).\n        scored: false\n"
  },
  {
    "path": "cfg/cis-1.8/etcd.yaml",
    "content": "---\ncontrols:\nversion: \"cis-1.8\"\nid: 2\ntext: \"Etcd Node Configuration\"\ntype: \"etcd\"\ngroups:\n  - id: 2\n    text: \"Etcd Node Configuration\"\n    checks:\n      - id: 2.1\n        text: \"Ensure that the --cert-file and --key-file arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--cert-file\"\n              env: \"ETCD_CERT_FILE\"\n            - flag: \"--key-file\"\n              env: \"ETCD_KEY_FILE\"\n        remediation: |\n          Follow the etcd service documentation and configure TLS encryption.\n          Then, edit the etcd pod specification file /etc/kubernetes/manifests/etcd.yaml\n          on the master node and set the below parameters.\n          --cert-file=</path/to/ca-file>\n          --key-file=</path/to/key-file>\n        scored: true\n\n      - id: 2.2\n        text: \"Ensure that the --client-cert-auth argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--client-cert-auth\"\n              env: \"ETCD_CLIENT_CERT_AUTH\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and set the below parameter.\n          --client-cert-auth=\"true\"\n        scored: true\n\n      - id: 2.3\n        text: \"Ensure that the --auto-tls argument is not set to true (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--auto-tls\"\n              env: \"ETCD_AUTO_TLS\"\n              set: false\n            - flag: \"--auto-tls\"\n              env: \"ETCD_AUTO_TLS\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and either remove the --auto-tls parameter or set it to false.\n            --auto-tls=false\n        scored: true\n\n      - id: 2.4\n        text: \"Ensure that the --peer-cert-file and --peer-key-file arguments are\n        set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--peer-cert-file\"\n              env: \"ETCD_PEER_CERT_FILE\"\n            - flag: \"--peer-key-file\"\n              env: \"ETCD_PEER_KEY_FILE\"\n        remediation: |\n          Follow the etcd service documentation and configure peer TLS encryption as appropriate\n          for your etcd cluster.\n          Then, edit the etcd pod specification file $etcdconf on the\n          master node and set the below parameters.\n          --peer-client-file=</path/to/peer-cert-file>\n          --peer-key-file=</path/to/peer-key-file>\n        scored: true\n\n      - id: 2.5\n        text: \"Ensure that the --peer-client-cert-auth argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--peer-client-cert-auth\"\n              env: \"ETCD_PEER_CLIENT_CERT_AUTH\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and set the below parameter.\n          --peer-client-cert-auth=true\n        scored: true\n\n      - id: 2.6\n        text: \"Ensure that the --peer-auto-tls argument is not set to true (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--peer-auto-tls\"\n              env: \"ETCD_PEER_AUTO_TLS\"\n              set: false\n            - flag: \"--peer-auto-tls\"\n              env: \"ETCD_PEER_AUTO_TLS\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and either remove the --peer-auto-tls parameter or set it to false.\n          --peer-auto-tls=false\n        scored: true\n\n      - id: 2.7\n        text: \"Ensure that a unique Certificate Authority is used for etcd (Manual)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--trusted-ca-file\"\n              env: \"ETCD_TRUSTED_CA_FILE\"\n        remediation: |\n          [Manual test]\n          Follow the etcd documentation and create a dedicated certificate authority setup for the\n          etcd service.\n          Then, edit the etcd pod specification file $etcdconf on the\n          master node and set the below parameter.\n          --trusted-ca-file=</path/to/ca-file>\n        scored: false\n"
  },
  {
    "path": "cfg/cis-1.8/master.yaml",
    "content": "---\ncontrols:\nversion: \"cis-1.8\"\nid: 1\ntext: \"Control Plane Security Configuration\"\ntype: \"master\"\ngroups:\n  - id: 1.1\n    text: \"Control Plane Node Configuration Files\"\n    checks:\n      - id: 1.1.1\n        text: \"Ensure that the API server pod specification file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $apiserverconf; then stat -c permissions=%a $apiserverconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the\n          control plane node.\n          For example, chmod 600 $apiserverconf\n        scored: true\n\n      - id: 1.1.2\n        text: \"Ensure that the API server pod specification file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $apiserverconf; then stat -c %U:%G $apiserverconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chown root:root $apiserverconf\n        scored: true\n\n      - id: 1.1.3\n        text: \"Ensure that the controller manager pod specification file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerconf; then stat -c permissions=%a $controllermanagerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chmod 600 $controllermanagerconf\n        scored: true\n\n      - id: 1.1.4\n        text: \"Ensure that the controller manager pod specification file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerconf; then stat -c %U:%G $controllermanagerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chown root:root $controllermanagerconf\n        scored: true\n\n      - id: 1.1.5\n        text: \"Ensure that the scheduler pod specification file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerconf; then stat -c permissions=%a $schedulerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chmod 600 $schedulerconf\n        scored: true\n\n      - id: 1.1.6\n        text: \"Ensure that the scheduler pod specification file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerconf; then stat -c %U:%G $schedulerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chown root:root $schedulerconf\n        scored: true\n\n      - id: 1.1.7\n        text: \"Ensure that the etcd pod specification file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $etcdconf; then find $etcdconf -name '*etcd*' | xargs stat -c permissions=%a; fi'\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod 600 $etcdconf\n        scored: true\n\n      - id: 1.1.8\n        text: \"Ensure that the etcd pod specification file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $etcdconf; then find $etcdconf -name '*etcd*' | xargs stat -c %U:%G; fi'\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root $etcdconf\n        scored: true\n\n      - id: 1.1.9\n        text: \"Ensure that the Container Network Interface file permissions are set to 600 or more restrictive (Manual)\"\n        audit: |\n          ps -ef | grep $kubeletbin | grep -- --cni-conf-dir | sed 's%.*cni-conf-dir[= ]\\([^ ]*\\).*%\\1%' | xargs -I{} find {} -mindepth 1 | xargs --no-run-if-empty stat -c permissions=%a\n          find /var/lib/cni/networks -type f 2> /dev/null | xargs --no-run-if-empty stat -c permissions=%a\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chmod 600 <path/to/cni/files>\n        scored: false\n\n      - id: 1.1.10\n        text: \"Ensure that the Container Network Interface file ownership is set to root:root (Manual)\"\n        audit: |\n          ps -ef | grep $kubeletbin | grep -- --cni-conf-dir | sed 's%.*cni-conf-dir[= ]\\([^ ]*\\).*%\\1%' | xargs -I{} find {} -mindepth 1 | xargs --no-run-if-empty stat -c %U:%G\n          find /var/lib/cni/networks -type f 2> /dev/null | xargs --no-run-if-empty stat -c %U:%G\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root <path/to/cni/files>\n        scored: false\n\n      - id: 1.1.11\n        text: \"Ensure that the etcd data directory permissions are set to 700 or more restrictive (Automated)\"\n        audit: |\n          DATA_DIR=''\n          for d in $(ps -ef | grep $etcdbin | grep -- --data-dir | sed 's%.*data-dir[= ]\\([^ ]*\\).*%\\1%'); do\n            if test -d \"$d\"; then DATA_DIR=\"$d\"; fi\n          done\n          if ! test -d \"$DATA_DIR\"; then DATA_DIR=$etcddatadir; fi\n          stat -c permissions=%a \"$DATA_DIR\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"700\"\n        remediation: |\n          On the etcd server node, get the etcd data directory, passed as an argument --data-dir,\n          from the command 'ps -ef | grep etcd'.\n          Run the below command (based on the etcd data directory found above). For example,\n          chmod 700 /var/lib/etcd\n        scored: true\n\n      - id: 1.1.12\n        text: \"Ensure that the etcd data directory ownership is set to etcd:etcd (Automated)\"\n        audit: |\n          DATA_DIR=''\n          for d in $(ps -ef | grep $etcdbin | grep -- --data-dir | sed 's%.*data-dir[= ]\\([^ ]*\\).*%\\1%'); do\n            if test -d \"$d\"; then DATA_DIR=\"$d\"; fi\n          done\n          if ! test -d \"$DATA_DIR\"; then DATA_DIR=$etcddatadir; fi\n          stat -c %U:%G \"$DATA_DIR\"\n        tests:\n          test_items:\n            - flag: \"etcd:etcd\"\n        remediation: |\n          On the etcd server node, get the etcd data directory, passed as an argument --data-dir,\n          from the command 'ps -ef | grep etcd'.\n          Run the below command (based on the etcd data directory found above).\n          For example, chown etcd:etcd /var/lib/etcd\n        scored: true\n\n      - id: 1.1.13\n        text: \"Ensure that the admin.conf file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e /etc/kubernetes/admin.conf; then stat -c permissions=%a /etc/kubernetes/admin.conf; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chmod 600 /etc/kubernetes/admin.conf\n        scored: true\n\n      - id: 1.1.14\n        text: \"Ensure that the admin.conf file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e /etc/kubernetes/admin.conf; then stat -c %U:%G /etc/kubernetes/admin.conf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chown root:root /etc/kubernetes/admin.conf\n        scored: true\n\n      - id: 1.1.15\n        text: \"Ensure that the scheduler.conf file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerkubeconfig; then stat -c permissions=%a $schedulerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod 600 $schedulerkubeconfig\n        scored: true\n\n      - id: 1.1.16\n        text: \"Ensure that the scheduler.conf file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerkubeconfig; then stat -c %U:%G $schedulerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root $schedulerkubeconfig\n        scored: true\n\n      - id: 1.1.17\n        text: \"Ensure that the controller-manager.conf file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerkubeconfig; then stat -c permissions=%a $controllermanagerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod 600 $controllermanagerkubeconfig\n        scored: true\n\n      - id: 1.1.18\n        text: \"Ensure that the controller-manager.conf file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerkubeconfig; then stat -c %U:%G $controllermanagerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root $controllermanagerkubeconfig\n        scored: true\n\n      - id: 1.1.19\n        text: \"Ensure that the Kubernetes PKI directory and file ownership is set to root:root (Automated)\"\n        audit: \"find /etc/kubernetes/pki/ | xargs stat -c %U:%G\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown -R root:root /etc/kubernetes/pki/\n        scored: true\n\n      - id: 1.1.20\n        text: \"Ensure that the Kubernetes PKI certificate file permissions are set to 600 or more restrictive (Manual)\"\n        audit: \"find /etc/kubernetes/pki/ -name '*.crt' | xargs stat -c permissions=%a\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod -R 600 /etc/kubernetes/pki/*.crt\n        scored: false\n\n      - id: 1.1.21\n        text: \"Ensure that the Kubernetes PKI key file permissions are set to 600 (Manual)\"\n        audit: \"find /etc/kubernetes/pki/ -name '*.key' | xargs stat -c permissions=%a\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod -R 600 /etc/kubernetes/pki/*.key\n        scored: false\n\n  - id: 1.2\n    text: \"API Server\"\n    checks:\n      - id: 1.2.1\n        text: \"Ensure that the --anonymous-auth argument is set to false (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--anonymous-auth\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the below parameter.\n          --anonymous-auth=false\n        scored: false\n\n      - id: 1.2.2\n        text: \"Ensure that the --token-auth-file parameter is not set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--token-auth-file\"\n              set: false\n        remediation: |\n          Follow the documentation and configure alternate mechanisms for authentication. Then,\n          edit the API server pod specification file $apiserverconf\n          on the control plane node and remove the --token-auth-file=<filename> parameter.\n        scored: true\n\n      - id: 1.2.3\n        text: \"Ensure that the --DenyServiceExternalIPs is set (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"DenyServiceExternalIPs\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and add the `DenyServiceExternalIPs` plugin\n          to the enabled admission plugins, as such --enable-admission-plugin=DenyServiceExternalIPs.\n        scored: false\n\n      - id: 1.2.4\n        text: \"Ensure that the --kubelet-client-certificate and --kubelet-client-key arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--kubelet-client-certificate\"\n            - flag: \"--kubelet-client-key\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection between the\n          apiserver and kubelets. Then, edit API server pod specification file\n          $apiserverconf on the control plane node and set the\n          kubelet client certificate and key parameters as below.\n          --kubelet-client-certificate=<path/to/client-certificate-file>\n          --kubelet-client-key=<path/to/client-key-file>\n        scored: true\n\n      - id: 1.2.5\n        text: \"Ensure that the --kubelet-certificate-authority argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--kubelet-certificate-authority\"\n        remediation: |\n          Follow the Kubernetes documentation and setup the TLS connection between\n          the apiserver and kubelets. Then, edit the API server pod specification file\n          $apiserverconf on the control plane node and set the\n          --kubelet-certificate-authority parameter to the path to the cert file for the certificate authority.\n          --kubelet-certificate-authority=<ca-string>\n        scored: true\n\n      - id: 1.2.6\n        text: \"Ensure that the --authorization-mode argument is not set to AlwaysAllow (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: nothave\n                value: \"AlwaysAllow\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --authorization-mode parameter to values other than AlwaysAllow.\n          One such example could be as below.\n          --authorization-mode=RBAC\n        scored: true\n\n      - id: 1.2.7\n        text: \"Ensure that the --authorization-mode argument includes Node (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: has\n                value: \"Node\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --authorization-mode parameter to a value that includes Node.\n          --authorization-mode=Node,RBAC\n        scored: true\n\n      - id: 1.2.8\n        text: \"Ensure that the --authorization-mode argument includes RBAC (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: has\n                value: \"RBAC\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --authorization-mode parameter to a value that includes RBAC,\n          for example `--authorization-mode=Node,RBAC`.\n        scored: true\n\n      - id: 1.2.9\n        text: \"Ensure that the admission control plugin EventRateLimit is set (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"EventRateLimit\"\n        remediation: |\n          Follow the Kubernetes documentation and set the desired limits in a configuration file.\n          Then, edit the API server pod specification file $apiserverconf\n          and set the below parameters.\n          --enable-admission-plugins=...,EventRateLimit,...\n          --admission-control-config-file=<path/to/configuration/file>\n        scored: false\n\n      - id: 1.2.10\n        text: \"Ensure that the admission control plugin AlwaysAdmit is not set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: nothave\n                value: AlwaysAdmit\n            - flag: \"--enable-admission-plugins\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and either remove the --enable-admission-plugins parameter, or set it to a\n          value that does not include AlwaysAdmit.\n        scored: true\n\n      - id: 1.2.11\n        text: \"Ensure that the admission control plugin AlwaysPullImages is set (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"AlwaysPullImages\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --enable-admission-plugins parameter to include\n          AlwaysPullImages.\n          --enable-admission-plugins=...,AlwaysPullImages,...\n        scored: false\n\n      - id: 1.2.12\n        text: \"Ensure that the admission control plugin SecurityContextDeny is set if PodSecurityPolicy is not used (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"SecurityContextDeny\"\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"PodSecurityPolicy\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --enable-admission-plugins parameter to include\n          SecurityContextDeny, unless PodSecurityPolicy is already in place.\n          --enable-admission-plugins=...,SecurityContextDeny,...\n        scored: false\n\n      - id: 1.2.13\n        text: \"Ensure that the admission control plugin ServiceAccount is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--disable-admission-plugins\"\n              compare:\n                op: nothave\n                value: \"ServiceAccount\"\n            - flag: \"--disable-admission-plugins\"\n              set: false\n        remediation: |\n          Follow the documentation and create ServiceAccount objects as per your environment.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and ensure that the --disable-admission-plugins parameter is set to a\n          value that does not include ServiceAccount.\n        scored: true\n\n      - id: 1.2.14\n        text: \"Ensure that the admission control plugin NamespaceLifecycle is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--disable-admission-plugins\"\n              compare:\n                op: nothave\n                value: \"NamespaceLifecycle\"\n            - flag: \"--disable-admission-plugins\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --disable-admission-plugins parameter to\n          ensure it does not include NamespaceLifecycle.\n        scored: true\n\n      - id: 1.2.15\n        text: \"Ensure that the admission control plugin NodeRestriction is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"NodeRestriction\"\n        remediation: |\n          Follow the Kubernetes documentation and configure NodeRestriction plug-in on kubelets.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --enable-admission-plugins parameter to a\n          value that includes NodeRestriction.\n          --enable-admission-plugins=...,NodeRestriction,...\n        scored: true\n\n      - id: 1.2.16\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the below parameter.\n          --profiling=false\n        scored: true\n\n      - id: 1.2.17\n        text: \"Ensure that the --audit-log-path argument is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-path\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --audit-log-path parameter to a suitable path and\n          file where you would like audit logs to be written, for example,\n          --audit-log-path=/var/log/apiserver/audit.log\n        scored: true\n\n      - id: 1.2.18\n        text: \"Ensure that the --audit-log-maxage argument is set to 30 or as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxage\"\n              compare:\n                op: gte\n                value: 30\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --audit-log-maxage parameter to 30\n          or as an appropriate number of days, for example,\n          --audit-log-maxage=30\n        scored: true\n\n      - id: 1.2.19\n        text: \"Ensure that the --audit-log-maxbackup argument is set to 10 or as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxbackup\"\n              compare:\n                op: gte\n                value: 10\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --audit-log-maxbackup parameter to 10 or to an appropriate\n          value. For example,\n          --audit-log-maxbackup=10\n        scored: true\n\n      - id: 1.2.20\n        text: \"Ensure that the --audit-log-maxsize argument is set to 100 or as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxsize\"\n              compare:\n                op: gte\n                value: 100\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --audit-log-maxsize parameter to an appropriate size in MB.\n          For example, to set it as 100 MB, --audit-log-maxsize=100\n        scored: true\n\n      - id: 1.2.21\n        text: \"Ensure that the --request-timeout argument is set as appropriate (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        type: manual\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          and set the below parameter as appropriate and if needed.\n          For example, --request-timeout=300s\n        scored: false\n\n      - id: 1.2.22\n        text: \"Ensure that the --service-account-lookup argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--service-account-lookup\"\n              set: false\n            - flag: \"--service-account-lookup\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the below parameter.\n          --service-account-lookup=true\n          Alternatively, you can delete the --service-account-lookup parameter from this file so\n          that the default takes effect.\n        scored: true\n\n      - id: 1.2.23\n        text: \"Ensure that the --service-account-key-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--service-account-key-file\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --service-account-key-file parameter\n          to the public key file for service accounts. For example,\n          --service-account-key-file=<filename>\n        scored: true\n\n      - id: 1.2.24\n        text: \"Ensure that the --etcd-certfile and --etcd-keyfile arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--etcd-certfile\"\n            - flag: \"--etcd-keyfile\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection between the apiserver and etcd.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the etcd certificate and key file parameters.\n          --etcd-certfile=<path/to/client-certificate-file>\n          --etcd-keyfile=<path/to/client-key-file>\n        scored: true\n\n      - id: 1.2.25\n        text: \"Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--tls-cert-file\"\n            - flag: \"--tls-private-key-file\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection on the apiserver.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the TLS certificate and private key file parameters.\n          --tls-cert-file=<path/to/tls-certificate-file>\n          --tls-private-key-file=<path/to/tls-key-file>\n        scored: true\n\n      - id: 1.2.26\n        text: \"Ensure that the --client-ca-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--client-ca-file\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection on the apiserver.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the client certificate authority file.\n          --client-ca-file=<path/to/client-ca-file>\n        scored: true\n\n      - id: 1.2.27\n        text: \"Ensure that the --etcd-cafile argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--etcd-cafile\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection between the apiserver and etcd.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the etcd certificate authority file parameter.\n          --etcd-cafile=<path/to/ca-file>\n        scored: true\n\n      - id: 1.2.28\n        text: \"Ensure that the --encryption-provider-config argument is set as appropriate (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--encryption-provider-config\"\n        remediation: |\n          Follow the Kubernetes documentation and configure a EncryptionConfig file.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --encryption-provider-config parameter to the path of that file.\n          For example, --encryption-provider-config=</path/to/EncryptionConfig/File>\n        scored: false\n\n      - id: 1.2.29\n        text: \"Ensure that encryption providers are appropriately configured (Manual)\"\n        audit: |\n          ENCRYPTION_PROVIDER_CONFIG=$(ps -ef | grep $apiserverbin | grep -- --encryption-provider-config | sed 's%.*encryption-provider-config[= ]\\([^ ]*\\).*%\\1%')\n          if test -e $ENCRYPTION_PROVIDER_CONFIG; then grep -A1 'providers:' $ENCRYPTION_PROVIDER_CONFIG | tail -n1 | grep -o \"[A-Za-z]*\" | sed 's/^/provider=/'; fi\n        tests:\n          test_items:\n            - flag: \"provider\"\n              compare:\n                op: valid_elements\n                value: \"aescbc,kms,secretbox\"\n        remediation: |\n          Follow the Kubernetes documentation and configure a EncryptionConfig file.\n          In this file, choose aescbc, kms or secretbox as the encryption provider.\n        scored: false\n\n      - id: 1.2.30\n        text: \"Ensure that the API Server only makes use of Strong Cryptographic Ciphers (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--tls-cipher-suites\"\n              compare:\n                op: valid_elements\n                value: \"TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,TLS_CHACHA20_POLY1305_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,TLS_RSA_WITH_3DES_EDE_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_256_GCM_SHA384\"\n        remediation: |\n          Edit the API server pod specification file /etc/kubernetes/manifests/kube-apiserver.yaml\n          on the control plane node and set the below parameter.\n          --tls-cipher-suites=TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,TLS_CHACHA20_POLY1305_SHA256,\n          TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,\n          TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,\n          TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,\n          TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,\n          TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,\n          TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,TLS_RSA_WITH_3DES_EDE_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA,\n          TLS_RSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_256_GCM_SHA384\n        scored: false\n\n  - id: 1.3\n    text: \"Controller Manager\"\n    checks:\n      - id: 1.3.1\n        text: \"Ensure that the --terminated-pod-gc-threshold argument is set as appropriate (Manual)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--terminated-pod-gc-threshold\"\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the --terminated-pod-gc-threshold to an appropriate threshold,\n          for example, --terminated-pod-gc-threshold=10\n        scored: false\n\n      - id: 1.3.2\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the below parameter.\n          --profiling=false\n        scored: true\n\n      - id: 1.3.3\n        text: \"Ensure that the --use-service-account-credentials argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--use-service-account-credentials\"\n              compare:\n                op: noteq\n                value: false\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node to set the below parameter.\n          --use-service-account-credentials=true\n        scored: true\n\n      - id: 1.3.4\n        text: \"Ensure that the --service-account-private-key-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--service-account-private-key-file\"\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the --service-account-private-key-file parameter\n          to the private key file for service accounts.\n          --service-account-private-key-file=<filename>\n        scored: true\n\n      - id: 1.3.5\n        text: \"Ensure that the --root-ca-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--root-ca-file\"\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the --root-ca-file parameter to the certificate bundle file`.\n          --root-ca-file=<path/to/file>\n        scored: true\n\n      - id: 1.3.6\n        text: \"Ensure that the RotateKubeletServerCertificate argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--feature-gates\"\n              compare:\n                op: nothave\n                value: \"RotateKubeletServerCertificate=false\"\n              set: true\n            - flag: \"--feature-gates\"\n              set: false\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the --feature-gates parameter to include RotateKubeletServerCertificate=true.\n          --feature-gates=RotateKubeletServerCertificate=true\n        scored: true\n\n      - id: 1.3.7\n        text: \"Ensure that the --bind-address argument is set to 127.0.0.1 (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--bind-address\"\n              compare:\n                op: eq\n                value: \"127.0.0.1\"\n            - flag: \"--bind-address\"\n              set: false\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and ensure the correct value for the --bind-address parameter\n        scored: true\n\n  - id: 1.4\n    text: \"Scheduler\"\n    checks:\n      - id: 1.4.1\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: \"/bin/ps -ef | grep $schedulerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the Scheduler pod specification file $schedulerconf file\n          on the control plane node and set the below parameter.\n          --profiling=false\n        scored: true\n\n      - id: 1.4.2\n        text: \"Ensure that the --bind-address argument is set to 127.0.0.1 (Automated)\"\n        audit: \"/bin/ps -ef | grep $schedulerbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--bind-address\"\n              compare:\n                op: eq\n                value: \"127.0.0.1\"\n            - flag: \"--bind-address\"\n              set: false\n        remediation: |\n          Edit the Scheduler pod specification file $schedulerconf\n          on the control plane node and ensure the correct value for the --bind-address parameter\n        scored: true\n"
  },
  {
    "path": "cfg/cis-1.8/node.yaml",
    "content": "---\ncontrols:\nversion: \"cis-1.8\"\nid: 4\ntext: \"Worker Node Security Configuration\"\ntype: \"node\"\ngroups:\n  - id: 4.1\n    text: \"Worker Node Configuration Files\"\n    checks:\n      - id: 4.1.1\n        text: \"Ensure that the kubelet service file permissions are set to 600 or more restrictive (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletsvc; then stat -c permissions=%a $kubeletsvc; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example, chmod 600 $kubeletsvc\n        scored: true\n\n      - id: 4.1.2\n        text: \"Ensure that the kubelet service file ownership is set to root:root (Automated)\"\n        audit: '/bin/sh -c \"if test -e $kubeletsvc; then stat -c %U:%G $kubeletsvc; else echo \\\"File not found\\\"; fi\"'\n        tests:\n          bin_op: or\n          test_items:\n            - flag: root:root\n            - flag: \"File not found\"\n        remediation: |\n            Run the below command (based on the file location on your system) on the each worker node.\n            For example,\n            chown root:root $kubeletsvc\n        scored: true\n\n      - id: 4.1.3\n        text: \"If proxy kubeconfig file exists ensure permissions are set to 600 or more restrictive (Manual)\"\n        audit: '/bin/sh -c ''if test -e $proxykubeconfig; then stat -c permissions=%a $proxykubeconfig; fi'' '\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"permissions\"\n              set: true\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chmod 600 $proxykubeconfig\n        scored: false\n\n      - id: 4.1.4\n        text: \"If proxy kubeconfig file exists ensure ownership is set to root:root (Manual)\"\n        audit: '/bin/sh -c ''if test -e $proxykubeconfig; then stat -c %U:%G $proxykubeconfig; fi'' '\n        tests:\n          bin_op: or\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example, chown root:root $proxykubeconfig\n        scored: false\n\n      - id: 4.1.5\n        text: \"Ensure that the --kubeconfig kubelet.conf file permissions are set to 600 or more restrictive (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletkubeconfig; then stat -c permissions=%a $kubeletkubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chmod 600 $kubeletkubeconfig\n        scored: true\n\n      - id: 4.1.6\n        text: \"Ensure that the --kubeconfig kubelet.conf file ownership is set to root:root (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletkubeconfig; then stat -c %U:%G $kubeletkubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chown root:root $kubeletkubeconfig\n        scored: true\n\n      - id: 4.1.7\n        text: \"Ensure that the certificate authorities file permissions are set to 600 or more restrictive (Manual)\"\n        audit: |\n          CAFILE=$(ps -ef | grep kubelet | grep -v apiserver | grep -- --client-ca-file= | awk -F '--client-ca-file=' '{print $2}' | awk '{print $1}' | uniq)\n          if test -z $CAFILE; then CAFILE=$kubeletcafile; fi\n          if test -e $CAFILE; then stat -c permissions=%a $CAFILE; fi\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the following command to modify the file permissions of the\n          --client-ca-file chmod 600 <filename>\n        scored: false\n\n      - id: 4.1.8\n        text: \"Ensure that the client certificate authorities file ownership is set to root:root (Manual)\"\n        audit: |\n          CAFILE=$(ps -ef | grep kubelet | grep -v apiserver | grep -- --client-ca-file= | awk -F '--client-ca-file=' '{print $2}' | awk '{print $1}' | uniq)\n          if test -z $CAFILE; then CAFILE=$kubeletcafile; fi\n          if test -e $CAFILE; then stat -c %U:%G $CAFILE; fi\n        tests:\n          test_items:\n            - flag: root:root\n              compare:\n                op: eq\n                value: root:root\n        remediation: |\n          Run the following command to modify the ownership of the --client-ca-file.\n          chown root:root <filename>\n        scored: false\n\n      - id: 4.1.9\n        text: \"If the kubelet config.yaml configuration file is being used validate permissions set to 600 or more restrictive (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletconf; then stat -c permissions=%a $kubeletconf; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the following command (using the config file location identified in the Audit step)\n          chmod 600 $kubeletconf\n        scored: true\n\n      - id: 4.1.10\n        text: \"If the kubelet config.yaml configuration file is being used validate file ownership is set to root:root (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletconf; then stat -c %U:%G $kubeletconf; fi'' '\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the following command (using the config file location identified in the Audit step)\n          chown root:root $kubeletconf\n        scored: true\n\n  - id: 4.2\n    text: \"Kubelet\"\n    checks:\n      - id: 4.2.1\n        text: \"Ensure that the --anonymous-auth argument is set to false (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: \"--anonymous-auth\"\n              path: '{.authentication.anonymous.enabled}'\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          If using a Kubelet config file, edit the file to set `authentication: anonymous: enabled` to\n          `false`.\n          If using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          `--anonymous-auth=false`\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.2\n        text: \"Ensure that the --authorization-mode argument is not set to AlwaysAllow (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --authorization-mode\n              path: '{.authorization.mode}'\n              compare:\n                op: nothave\n                value: AlwaysAllow\n        remediation: |\n          If using a Kubelet config file, edit the file to set `authorization.mode` to Webhook. If\n          using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_AUTHZ_ARGS variable.\n          --authorization-mode=Webhook\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.3\n        text: \"Ensure that the --client-ca-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --client-ca-file\n              path: '{.authentication.x509.clientCAFile}'\n        remediation: |\n          If using a Kubelet config file, edit the file to set `authentication.x509.clientCAFile` to\n          the location of the client CA file.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_AUTHZ_ARGS variable.\n          --client-ca-file=<path/to/client-ca-file>\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.4\n        text: \"Verify that the --read-only-port argument is set to 0 (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--read-only-port\"\n              path: '{.readOnlyPort}'\n              compare:\n                op: eq\n                value: 0\n            - flag: \"--read-only-port\"\n              path: '{.readOnlyPort}'\n              set: false\n        remediation: |\n          If using a Kubelet config file, edit the file to set `readOnlyPort` to 0.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --read-only-port=0\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.5\n        text: \"Ensure that the --streaming-connection-idle-timeout argument is not set to 0 (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --streaming-connection-idle-timeout\n              path: '{.streamingConnectionIdleTimeout}'\n              compare:\n                op: noteq\n                value: 0\n            - flag: --streaming-connection-idle-timeout\n              path: '{.streamingConnectionIdleTimeout}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to set `streamingConnectionIdleTimeout` to a\n          value other than 0.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --streaming-connection-idle-timeout=5m\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.6\n        text: \"Ensure that the --make-iptables-util-chains argument is set to true (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --make-iptables-util-chains\n              path: '{.makeIPTablesUtilChains}'\n              compare:\n                op: eq\n                value: true\n            - flag: --make-iptables-util-chains\n              path: '{.makeIPTablesUtilChains}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to set `makeIPTablesUtilChains` to `true`.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          remove the --make-iptables-util-chains argument from the\n          KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.7\n        text: \"Ensure that the --hostname-override argument is not set (Manual)\"\n        # This is one of those properties that can only be set as a command line argument.\n        # To check if the property is set as expected, we need to parse the kubelet command\n        # instead reading the Kubelet Configuration file.\n        audit: \"/bin/ps -fC $kubeletbin \"\n        tests:\n          test_items:\n            - flag: --hostname-override\n              set: false\n        remediation: |\n          Edit the kubelet service file $kubeletsvc\n          on each worker node and remove the --hostname-override argument from the\n          KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.8\n        text: \"Ensure that the eventRecordQPS argument is set to a level which ensures appropriate event capture (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --event-qps\n              path: '{.eventRecordQPS}'\n              compare:\n                op: gte\n                value: 0\n            - flag: --event-qps\n              path: '{.eventRecordQPS}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to set `eventRecordQPS` to an appropriate level.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.9\n        text: \"Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --tls-cert-file\n              path: '{.tlsCertFile}'\n            - flag: --tls-private-key-file\n              path: '{.tlsPrivateKeyFile}'\n        remediation: |\n          If using a Kubelet config file, edit the file to set `tlsCertFile` to the location\n          of the certificate file to use to identify this Kubelet, and `tlsPrivateKeyFile`\n          to the location of the corresponding private key file.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameters in KUBELET_CERTIFICATE_ARGS variable.\n          --tls-cert-file=<path/to/tls-certificate-file>\n          --tls-private-key-file=<path/to/tls-key-file>\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.10\n        text: \"Ensure that the --rotate-certificates argument is not set to false (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --rotate-certificates\n              path: '{.rotateCertificates}'\n              compare:\n                op: eq\n                value: true\n            - flag: --rotate-certificates\n              path: '{.rotateCertificates}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to add the line `rotateCertificates` to `true` or\n          remove it altogether to use the default value.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          remove --rotate-certificates=false argument from the KUBELET_CERTIFICATE_ARGS\n          variable.\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.11\n        text: \"Verify that the RotateKubeletServerCertificate argument is set to true (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: RotateKubeletServerCertificate\n              path: '{.featureGates.RotateKubeletServerCertificate}'\n              compare:\n                op: nothave\n                value: false\n            - flag: RotateKubeletServerCertificate\n              path: '{.featureGates.RotateKubeletServerCertificate}'\n              set: false\n        remediation: |\n          Edit the kubelet service file $kubeletsvc\n          on each worker node and set the below parameter in KUBELET_CERTIFICATE_ARGS variable.\n          --feature-gates=RotateKubeletServerCertificate=true\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.12\n        text: \"Ensure that the Kubelet only makes use of Strong Cryptographic Ciphers (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --tls-cipher-suites\n              path: '{range .tlsCipherSuites[:]}{}{'',''}{end}'\n              compare:\n                op: valid_elements\n                value: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\n        remediation: |\n          If using a Kubelet config file, edit the file to set `tlsCipherSuites` to\n          TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\n          or to a subset of these values.\n          If using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the --tls-cipher-suites parameter as follows, or to a subset of these values.\n          --tls-cipher-suites=TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.13\n        text: \"Ensure that a limit is set on pod PIDs (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --pod-max-pids\n              path: '{.podPidsLimit}'\n        remediation: |\n          Decide on an appropriate level for this parameter and set it,\n          either via the --pod-max-pids command line parameter or the PodPidsLimit configuration file setting.\n        scored: false\n"
  },
  {
    "path": "cfg/cis-1.8/policies.yaml",
    "content": "---\ncontrols:\nversion: \"cis-1.8\"\nid: 5\ntext: \"Kubernetes Policies\"\ntype: \"policies\"\ngroups:\n  - id: 5.1\n    text: \"RBAC and Service Accounts\"\n    checks:\n      - id: 5.1.1\n        text: \"Ensure that the cluster-admin role is only used where required (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Identify all clusterrolebindings to the cluster-admin role. Check if they are used and\n          if they need this role or if they could use a role with fewer privileges.\n          Where possible, first bind users to a lower privileged role and then remove the\n          clusterrolebinding to the cluster-admin role :\n          kubectl delete clusterrolebinding [name]\n        scored: false\n\n      - id: 5.1.2\n        text: \"Minimize access to secrets (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove get, list and watch access to Secret objects in the cluster.\n        scored: false\n\n      - id: 5.1.3\n        text: \"Minimize wildcard use in Roles and ClusterRoles (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible replace any use of wildcards in clusterroles and roles with specific\n          objects or actions.\n        scored: false\n\n      - id: 5.1.4\n        text: \"Minimize access to create pods (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove create access to pod objects in the cluster.\n        scored: false\n\n      - id: 5.1.5\n        text: \"Ensure that default service accounts are not actively used. (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Create explicit service accounts wherever a Kubernetes workload requires specific access\n          to the Kubernetes API server.\n          Modify the configuration of each default service account to include this value\n          automountServiceAccountToken: false\n        scored: false\n\n      - id: 5.1.6\n        text: \"Ensure that Service Account Tokens are only mounted where necessary (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Modify the definition of pods and service accounts which do not need to mount service\n          account tokens to disable it.\n        scored: false\n\n      - id: 5.1.7\n        text: \"Avoid use of system:masters group (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Remove the system:masters group from all users in the cluster.\n        scored: false\n\n      - id: 5.1.8\n        text: \"Limit use of the Bind, Impersonate and Escalate permissions in the Kubernetes cluster (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove the impersonate, bind and escalate rights from subjects.\n        scored: false\n\n      - id: 5.1.9\n        text: \"Minimize access to create persistent volumes (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove create access to PersistentVolume objects in the cluster.\n        scored: false\n\n      - id: 5.1.10\n        text: \"Minimize access to the proxy sub-resource of nodes (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove access to the proxy sub-resource of node objects.\n        scored: false\n\n      - id: 5.1.11\n        text: \"Minimize access to the approval sub-resource of certificatesigningrequests objects (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove access to the approval sub-resource of certificatesigningrequest objects.\n        scored: false\n\n      - id: 5.1.12\n        text: \"Minimize access to webhook configuration objects (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove access to the validatingwebhookconfigurations or mutatingwebhookconfigurations objects\n        scored: false\n\n      - id: 5.1.13\n        text: \"Minimize access to the service account token creation (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove access to the token sub-resource of serviceaccount objects.\n        scored: false\n\n  - id: 5.2\n    text: \"Pod Security Standards\"\n    checks:\n      - id: 5.2.1\n        text: \"Ensure that the cluster has at least one active policy control mechanism in place (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that either Pod Security Admission or an external policy control system is in place\n          for every namespace which contains user workloads.\n        scored: false\n\n      - id: 5.2.2\n        text: \"Minimize the admission of privileged containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of privileged containers.\n        scored: false\n\n      - id: 5.2.3\n        text: \"Minimize the admission of containers wishing to share the host process ID namespace (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of `hostPID` containers.\n        scored: false\n\n      - id: 5.2.4\n        text: \"Minimize the admission of containers wishing to share the host IPC namespace (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of `hostIPC` containers.\n        scored: false\n\n      - id: 5.2.5\n        text: \"Minimize the admission of containers wishing to share the host network namespace (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of `hostNetwork` containers.\n        scored: false\n\n      - id: 5.2.6\n        text: \"Minimize the admission of containers with allowPrivilegeEscalation (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers with `.spec.allowPrivilegeEscalation` set to `true`.\n        scored: false\n\n      - id: 5.2.7\n        text: \"Minimize the admission of root containers (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Create a policy for each namespace in the cluster, ensuring that either `MustRunAsNonRoot`\n          or `MustRunAs` with the range of UIDs not including 0, is set.\n        scored: false\n\n      - id: 5.2.8\n        text: \"Minimize the admission of containers with the NET_RAW capability (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers with the `NET_RAW` capability.\n        scored: false\n\n      - id: 5.2.9\n        text: \"Minimize the admission of containers with added capabilities (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that `allowedCapabilities` is not present in policies for the cluster unless\n          it is set to an empty array.\n        scored: false\n\n      - id: 5.2.10\n        text: \"Minimize the admission of containers with capabilities assigned (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Review the use of capabilites in applications running on your cluster. Where a namespace\n          contains applications which do not require any Linux capabities to operate consider adding\n          a PSP which forbids the admission of containers which do not drop all capabilities.\n        scored: false\n\n      - id: 5.2.11\n        text: \"Minimize the admission of Windows HostProcess containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers that have `.securityContext.windowsOptions.hostProcess` set to `true`.\n        scored: false\n\n      - id: 5.2.12\n        text: \"Minimize the admission of HostPath volumes (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers with `hostPath` volumes.\n        scored: false\n\n      - id: 5.2.13\n        text: \"Minimize the admission of containers which use HostPorts (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers which use `hostPort` sections.\n        scored: false\n\n  - id: 5.3\n    text: \"Network Policies and CNI\"\n    checks:\n      - id: 5.3.1\n        text: \"Ensure that the CNI in use supports NetworkPolicies (Manual)\"\n        type: \"manual\"\n        remediation: |\n          If the CNI plugin in use does not support network policies, consideration should be given to\n          making use of a different plugin, or finding an alternate mechanism for restricting traffic\n          in the Kubernetes cluster.\n        scored: false\n\n      - id: 5.3.2\n        text: \"Ensure that all Namespaces have NetworkPolicies defined (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the documentation and create NetworkPolicy objects as you need them.\n        scored: false\n\n  - id: 5.4\n    text: \"Secrets Management\"\n    checks:\n      - id: 5.4.1\n        text: \"Prefer using Secrets as files over Secrets as environment variables (Manual)\"\n        type: \"manual\"\n        remediation: |\n          If possible, rewrite application code to read Secrets from mounted secret files, rather than\n          from environment variables.\n        scored: false\n\n      - id: 5.4.2\n        text: \"Consider external secret storage (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Refer to the Secrets management options offered by your cloud provider or a third-party\n          secrets management solution.\n        scored: false\n\n  - id: 5.5\n    text: \"Extensible Admission Control\"\n    checks:\n      - id: 5.5.1\n        text: \"Configure Image Provenance using ImagePolicyWebhook admission controller (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and setup image provenance.\n        scored: false\n\n  - id: 5.7\n    text: \"General Policies\"\n    checks:\n      - id: 5.7.1\n        text: \"Create administrative boundaries between resources using namespaces (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the documentation and create namespaces for objects in your deployment as you need\n          them.\n        scored: false\n\n      - id: 5.7.2\n        text: \"Ensure that the seccomp profile is set to docker/default in your Pod definitions (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Use `securityContext` to enable the docker/default seccomp profile in your pod definitions.\n          An example is as below:\n            securityContext:\n              seccompProfile:\n                type: RuntimeDefault\n        scored: false\n\n      - id: 5.7.3\n        text: \"Apply SecurityContext to your Pods and Containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and apply SecurityContexts to your Pods. For a\n          suggested list of SecurityContexts, you may refer to the CIS Security Benchmark for Docker\n          Containers.\n        scored: false\n\n      - id: 5.7.4\n        text: \"The default namespace should not be used (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that namespaces are created to allow for appropriate segregation of Kubernetes\n          resources and that all new resources are created in a specific namespace.\n        scored: false\n"
  },
  {
    "path": "cfg/cis-1.9/config.yaml",
    "content": "---\n## Version-specific settings that override the values in cfg/config.yaml\n"
  },
  {
    "path": "cfg/cis-1.9/controlplane.yaml",
    "content": "---\ncontrols:\nversion: \"cis-1.9\"\nid: 3\ntext: \"Control Plane Configuration\"\ntype: \"controlplane\"\ngroups:\n  - id: 3.1\n    text: \"Authentication and Authorization\"\n    checks:\n      - id: 3.1.1\n        text: \"Client certificate authentication should not be used for users (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Alternative mechanisms provided by Kubernetes such as the use of OIDC should be\n          implemented in place of client certificates.\n        scored: false\n\n      - id: 3.1.2\n        text: \"Service account token authentication should not be used for users (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Alternative mechanisms provided by Kubernetes such as the use of OIDC should be implemented\n          in place of service account tokens.\n        scored: false\n\n      - id: 3.1.3\n        text: \"Bootstrap token authentication should not be used for users (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Alternative mechanisms provided by Kubernetes such as the use of OIDC should be implemented\n          in place of bootstrap tokens.\n        scored: false\n\n  - id: 3.2\n    text: \"Logging\"\n    checks:\n      - id: 3.2.1\n        text: \"Ensure that a minimal audit policy is created (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-policy-file\"\n              set: true\n        remediation: |\n          Create an audit policy file for your cluster.\n        scored: false\n\n      - id: 3.2.2\n        text: \"Ensure that the audit policy covers key security concerns (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Review the audit policy provided for the cluster and ensure that it covers\n          at least the following areas,\n          - Access to Secrets managed by the cluster. Care should be taken to only\n            log Metadata for requests to Secrets, ConfigMaps, and TokenReviews, in\n            order to avoid risk of logging sensitive data.\n          - Modification of Pod and Deployment objects.\n          - Use of `pods/exec`, `pods/portforward`, `pods/proxy` and `services/proxy`.\n          For most requests, minimally logging at the Metadata level is recommended\n          (the most basic level of logging).\n        scored: false\n"
  },
  {
    "path": "cfg/cis-1.9/etcd.yaml",
    "content": "---\ncontrols:\nversion: \"cis-1.9\"\nid: 2\ntext: \"Etcd Node Configuration\"\ntype: \"etcd\"\ngroups:\n  - id: 2\n    text: \"Etcd Node Configuration\"\n    checks:\n      - id: 2.1\n        text: \"Ensure that the --cert-file and --key-file arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--cert-file\"\n              env: \"ETCD_CERT_FILE\"\n            - flag: \"--key-file\"\n              env: \"ETCD_KEY_FILE\"\n        remediation: |\n          Follow the etcd service documentation and configure TLS encryption.\n          Then, edit the etcd pod specification file /etc/kubernetes/manifests/etcd.yaml\n          on the master node and set the below parameters.\n          --cert-file=</path/to/ca-file>\n          --key-file=</path/to/key-file>\n        scored: true\n\n      - id: 2.2\n        text: \"Ensure that the --client-cert-auth argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--client-cert-auth\"\n              env: \"ETCD_CLIENT_CERT_AUTH\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and set the below parameter.\n          --client-cert-auth=\"true\"\n        scored: true\n\n      - id: 2.3\n        text: \"Ensure that the --auto-tls argument is not set to true (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--auto-tls\"\n              env: \"ETCD_AUTO_TLS\"\n              set: false\n            - flag: \"--auto-tls\"\n              env: \"ETCD_AUTO_TLS\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and either remove the --auto-tls parameter or set it to false.\n            --auto-tls=false\n        scored: true\n\n      - id: 2.4\n        text: \"Ensure that the --peer-cert-file and --peer-key-file arguments are\n        set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--peer-cert-file\"\n              env: \"ETCD_PEER_CERT_FILE\"\n            - flag: \"--peer-key-file\"\n              env: \"ETCD_PEER_KEY_FILE\"\n        remediation: |\n          Follow the etcd service documentation and configure peer TLS encryption as appropriate\n          for your etcd cluster.\n          Then, edit the etcd pod specification file $etcdconf on the\n          master node and set the below parameters.\n          --peer-client-file=</path/to/peer-cert-file>\n          --peer-key-file=</path/to/peer-key-file>\n        scored: true\n\n      - id: 2.5\n        text: \"Ensure that the --peer-client-cert-auth argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--peer-client-cert-auth\"\n              env: \"ETCD_PEER_CLIENT_CERT_AUTH\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and set the below parameter.\n          --peer-client-cert-auth=true\n        scored: true\n\n      - id: 2.6\n        text: \"Ensure that the --peer-auto-tls argument is not set to true (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--peer-auto-tls\"\n              env: \"ETCD_PEER_AUTO_TLS\"\n              set: false\n            - flag: \"--peer-auto-tls\"\n              env: \"ETCD_PEER_AUTO_TLS\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and either remove the --peer-auto-tls parameter or set it to false.\n          --peer-auto-tls=false\n        scored: true\n\n      - id: 2.7\n        text: \"Ensure that a unique Certificate Authority is used for etcd (Manual)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--trusted-ca-file\"\n              env: \"ETCD_TRUSTED_CA_FILE\"\n        remediation: |\n          [Manual test]\n          Follow the etcd documentation and create a dedicated certificate authority setup for the\n          etcd service.\n          Then, edit the etcd pod specification file $etcdconf on the\n          master node and set the below parameter.\n          --trusted-ca-file=</path/to/ca-file>\n        scored: false\n"
  },
  {
    "path": "cfg/cis-1.9/master.yaml",
    "content": "---\ncontrols:\nversion: \"cis-1.9\"\nid: 1\ntext: \"Control Plane Security Configuration\"\ntype: \"master\"\ngroups:\n  - id: 1.1\n    text: \"Control Plane Node Configuration Files\"\n    checks:\n      - id: 1.1.1\n        text: \"Ensure that the API server pod specification file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $apiserverconf; then stat -c permissions=%a $apiserverconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the\n          control plane node.\n          For example, chmod 600 $apiserverconf\n        scored: true\n\n      - id: 1.1.2\n        text: \"Ensure that the API server pod specification file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $apiserverconf; then stat -c %U:%G $apiserverconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chown root:root $apiserverconf\n        scored: true\n\n      - id: 1.1.3\n        text: \"Ensure that the controller manager pod specification file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerconf; then stat -c permissions=%a $controllermanagerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chmod 600 $controllermanagerconf\n        scored: true\n\n      - id: 1.1.4\n        text: \"Ensure that the controller manager pod specification file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerconf; then stat -c %U:%G $controllermanagerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chown root:root $controllermanagerconf\n        scored: true\n\n      - id: 1.1.5\n        text: \"Ensure that the scheduler pod specification file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerconf; then stat -c permissions=%a $schedulerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chmod 600 $schedulerconf\n        scored: true\n\n      - id: 1.1.6\n        text: \"Ensure that the scheduler pod specification file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerconf; then stat -c %U:%G $schedulerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chown root:root $schedulerconf\n        scored: true\n\n      - id: 1.1.7\n        text: \"Ensure that the etcd pod specification file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $etcdconf; then find $etcdconf -name '*etcd*' | xargs stat -c permissions=%a; fi'\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod 600 $etcdconf\n        scored: true\n\n      - id: 1.1.8\n        text: \"Ensure that the etcd pod specification file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $etcdconf; then find $etcdconf -name '*etcd*' | xargs stat -c %U:%G; fi'\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root $etcdconf\n        scored: true\n\n      - id: 1.1.9\n        text: \"Ensure that the Container Network Interface file permissions are set to 600 or more restrictive (Manual)\"\n        audit: |\n          ps -ef | grep $kubeletbin | grep -- --cni-conf-dir | sed 's%.*cni-conf-dir[= ]\\([^ ]*\\).*%\\1%' | xargs -I{} find {} -mindepth 1 | xargs --no-run-if-empty stat -c permissions=%a\n          find /var/lib/cni/networks -type f 2> /dev/null | xargs --no-run-if-empty stat -c permissions=%a\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chmod 600 <path/to/cni/files>\n        scored: false\n\n      - id: 1.1.10\n        text: \"Ensure that the Container Network Interface file ownership is set to root:root (Manual)\"\n        audit: |\n          ps -ef | grep $kubeletbin | grep -- --cni-conf-dir | sed 's%.*cni-conf-dir[= ]\\([^ ]*\\).*%\\1%' | xargs -I{} find {} -mindepth 1 | xargs --no-run-if-empty stat -c %U:%G\n          find /var/lib/cni/networks -type f 2> /dev/null | xargs --no-run-if-empty stat -c %U:%G\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root <path/to/cni/files>\n        scored: false\n\n      - id: 1.1.11\n        text: \"Ensure that the etcd data directory permissions are set to 700 or more restrictive (Automated)\"\n        audit: |\n          DATA_DIR=''\n          for d in $(ps -ef | grep $etcdbin | grep -- --data-dir | sed 's%.*data-dir[= ]\\([^ ]*\\).*%\\1%'); do\n            if test -d \"$d\"; then DATA_DIR=\"$d\"; fi\n          done\n          if ! test -d \"$DATA_DIR\"; then DATA_DIR=$etcddatadir; fi\n          stat -c permissions=%a \"$DATA_DIR\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"700\"\n        remediation: |\n          On the etcd server node, get the etcd data directory, passed as an argument --data-dir,\n          from the command 'ps -ef | grep etcd'.\n          Run the below command (based on the etcd data directory found above). For example,\n          chmod 700 /var/lib/etcd\n        scored: true\n\n      - id: 1.1.12\n        text: \"Ensure that the etcd data directory ownership is set to etcd:etcd (Automated)\"\n        audit: |\n          DATA_DIR=''\n          for d in $(ps -ef | grep $etcdbin | grep -- --data-dir | sed 's%.*data-dir[= ]\\([^ ]*\\).*%\\1%'); do\n            if test -d \"$d\"; then DATA_DIR=\"$d\"; fi\n          done\n          if ! test -d \"$DATA_DIR\"; then DATA_DIR=$etcddatadir; fi\n          stat -c %U:%G \"$DATA_DIR\"\n        tests:\n          test_items:\n            - flag: \"etcd:etcd\"\n        remediation: |\n          On the etcd server node, get the etcd data directory, passed as an argument --data-dir,\n          from the command 'ps -ef | grep etcd'.\n          Run the below command (based on the etcd data directory found above).\n          For example, chown etcd:etcd /var/lib/etcd\n        scored: true\n\n      - id: 1.1.13\n        text: \"Ensure that the default administrative credential file permissions are set to 600 (Automated)\"\n        audit: |\n         for adminconf in /etc/kubernetes/admin.conf /etc/kubernetes/super-admin.conf; do if test -e $adminconf; then stat -c \"permissions=%a %n\" $adminconf; fi; done\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chmod 600 /etc/kubernetes/admin.conf\n          On Kubernetes 1.29+ the super-admin.conf file should also be modified, if present.\n          For example, chmod 600 /etc/kubernetes/super-admin.conf\n        scored: true\n\n      - id: 1.1.14\n        text: \"Ensure that the default administrative credential file ownership is set to root:root (Automated)\"\n        audit: |\n         for adminconf in /etc/kubernetes/admin.conf /etc/kubernetes/super-admin.conf; do if test -e $adminconf; then stat -c \"ownership=%U:%G %n\" $adminconf; fi; done\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"ownership\"\n              compare:\n                op: eq\n                value: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chown root:root /etc/kubernetes/admin.conf\n          On Kubernetes 1.29+ the super-admin.conf file should also be modified, if present.\n          For example, chown root:root /etc/kubernetes/super-admin.conf\n        scored: true\n\n      - id: 1.1.15\n        text: \"Ensure that the scheduler.conf file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerkubeconfig; then stat -c permissions=%a $schedulerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod 600 $schedulerkubeconfig\n        scored: true\n\n      - id: 1.1.16\n        text: \"Ensure that the scheduler.conf file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerkubeconfig; then stat -c %U:%G $schedulerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root $schedulerkubeconfig\n        scored: true\n\n      - id: 1.1.17\n        text: \"Ensure that the controller-manager.conf file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerkubeconfig; then stat -c permissions=%a $controllermanagerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod 600 $controllermanagerkubeconfig\n        scored: true\n\n      - id: 1.1.18\n        text: \"Ensure that the controller-manager.conf file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerkubeconfig; then stat -c %U:%G $controllermanagerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root $controllermanagerkubeconfig\n        scored: true\n\n      - id: 1.1.19\n        text: \"Ensure that the Kubernetes PKI directory and file ownership is set to root:root (Automated)\"\n        audit: \"find /etc/kubernetes/pki/ | xargs stat -c %U:%G\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown -R root:root /etc/kubernetes/pki/\n        scored: true\n\n      - id: 1.1.20\n        text: \"Ensure that the Kubernetes PKI certificate file permissions are set to 600 or more restrictive (Manual)\"\n        audit: \"find /etc/kubernetes/pki/ -name '*.crt' | xargs stat -c permissions=%a\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod -R 600 /etc/kubernetes/pki/*.crt\n        scored: false\n\n      - id: 1.1.21\n        text: \"Ensure that the Kubernetes PKI key file permissions are set to 600 (Manual)\"\n        audit: \"find /etc/kubernetes/pki/ -name '*.key' | xargs stat -c permissions=%a\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod -R 600 /etc/kubernetes/pki/*.key\n        scored: false\n\n  - id: 1.2\n    text: \"API Server\"\n    checks:\n      - id: 1.2.1\n        text: \"Ensure that the --anonymous-auth argument is set to false (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--anonymous-auth\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the below parameter.\n          --anonymous-auth=false\n        scored: false\n\n      - id: 1.2.2\n        text: \"Ensure that the --token-auth-file parameter is not set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--token-auth-file\"\n              set: false\n        remediation: |\n          Follow the documentation and configure alternate mechanisms for authentication. Then,\n          edit the API server pod specification file $apiserverconf\n          on the control plane node and remove the --token-auth-file=<filename> parameter.\n        scored: true\n\n      - id: 1.2.3\n        text: \"Ensure that the --DenyServiceExternalIPs is set (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"DenyServiceExternalIPs\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and add the `DenyServiceExternalIPs` plugin\n          to the enabled admission plugins, as such --enable-admission-plugin=DenyServiceExternalIPs.\n        scored: false\n\n      - id: 1.2.4\n        text: \"Ensure that the --kubelet-client-certificate and --kubelet-client-key arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--kubelet-client-certificate\"\n            - flag: \"--kubelet-client-key\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection between the\n          apiserver and kubelets. Then, edit API server pod specification file\n          $apiserverconf on the control plane node and set the\n          kubelet client certificate and key parameters as below.\n          --kubelet-client-certificate=<path/to/client-certificate-file>\n          --kubelet-client-key=<path/to/client-key-file>\n        scored: true\n\n      - id: 1.2.5\n        text: \"Ensure that the --kubelet-certificate-authority argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--kubelet-certificate-authority\"\n        remediation: |\n          Follow the Kubernetes documentation and setup the TLS connection between\n          the apiserver and kubelets. Then, edit the API server pod specification file\n          $apiserverconf on the control plane node and set the\n          --kubelet-certificate-authority parameter to the path to the cert file for the certificate authority.\n          --kubelet-certificate-authority=<ca-string>\n        scored: true\n\n      - id: 1.2.6\n        text: \"Ensure that the --authorization-mode argument is not set to AlwaysAllow (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: nothave\n                value: \"AlwaysAllow\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --authorization-mode parameter to values other than AlwaysAllow.\n          One such example could be as below.\n          --authorization-mode=RBAC\n        scored: true\n\n      - id: 1.2.7\n        text: \"Ensure that the --authorization-mode argument includes Node (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: has\n                value: \"Node\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --authorization-mode parameter to a value that includes Node.\n          --authorization-mode=Node,RBAC\n        scored: true\n\n      - id: 1.2.8\n        text: \"Ensure that the --authorization-mode argument includes RBAC (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: has\n                value: \"RBAC\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --authorization-mode parameter to a value that includes RBAC,\n          for example `--authorization-mode=Node,RBAC`.\n        scored: true\n\n      - id: 1.2.9\n        text: \"Ensure that the admission control plugin EventRateLimit is set (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"EventRateLimit\"\n        remediation: |\n          Follow the Kubernetes documentation and set the desired limits in a configuration file.\n          Then, edit the API server pod specification file $apiserverconf\n          and set the below parameters.\n          --enable-admission-plugins=...,EventRateLimit,...\n          --admission-control-config-file=<path/to/configuration/file>\n        scored: false\n\n      - id: 1.2.10\n        text: \"Ensure that the admission control plugin AlwaysAdmit is not set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: nothave\n                value: AlwaysAdmit\n            - flag: \"--enable-admission-plugins\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and either remove the --enable-admission-plugins parameter, or set it to a\n          value that does not include AlwaysAdmit.\n        scored: true\n\n      - id: 1.2.11\n        text: \"Ensure that the admission control plugin AlwaysPullImages is set (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"AlwaysPullImages\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --enable-admission-plugins parameter to include\n          AlwaysPullImages.\n          --enable-admission-plugins=...,AlwaysPullImages,...\n        scored: false\n\n      - id: 1.2.12\n        text: \"Ensure that the admission control plugin ServiceAccount is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--disable-admission-plugins\"\n              compare:\n                op: nothave\n                value: \"ServiceAccount\"\n            - flag: \"--disable-admission-plugins\"\n              set: false\n        remediation: |\n          Follow the documentation and create ServiceAccount objects as per your environment.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and ensure that the --disable-admission-plugins parameter is set to a\n          value that does not include ServiceAccount.\n        scored: true\n\n      - id: 1.2.13\n        text: \"Ensure that the admission control plugin NamespaceLifecycle is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--disable-admission-plugins\"\n              compare:\n                op: nothave\n                value: \"NamespaceLifecycle\"\n            - flag: \"--disable-admission-plugins\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --disable-admission-plugins parameter to\n          ensure it does not include NamespaceLifecycle.\n        scored: true\n\n      - id: 1.2.14\n        text: \"Ensure that the admission control plugin NodeRestriction is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"NodeRestriction\"\n        remediation: |\n          Follow the Kubernetes documentation and configure NodeRestriction plug-in on kubelets.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --enable-admission-plugins parameter to a\n          value that includes NodeRestriction.\n          --enable-admission-plugins=...,NodeRestriction,...\n        scored: true\n\n      - id: 1.2.15\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the below parameter.\n          --profiling=false\n        scored: true\n\n      - id: 1.2.16\n        text: \"Ensure that the --audit-log-path argument is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-path\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --audit-log-path parameter to a suitable path and\n          file where you would like audit logs to be written, for example,\n          --audit-log-path=/var/log/apiserver/audit.log\n        scored: true\n\n      - id: 1.2.17\n        text: \"Ensure that the --audit-log-maxage argument is set to 30 or as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxage\"\n              compare:\n                op: gte\n                value: 30\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --audit-log-maxage parameter to 30\n          or as an appropriate number of days, for example,\n          --audit-log-maxage=30\n        scored: true\n\n      - id: 1.2.18\n        text: \"Ensure that the --audit-log-maxbackup argument is set to 10 or as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxbackup\"\n              compare:\n                op: gte\n                value: 10\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --audit-log-maxbackup parameter to 10 or to an appropriate\n          value. For example,\n          --audit-log-maxbackup=10\n        scored: true\n\n      - id: 1.2.19\n        text: \"Ensure that the --audit-log-maxsize argument is set to 100 or as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxsize\"\n              compare:\n                op: gte\n                value: 100\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --audit-log-maxsize parameter to an appropriate size in MB.\n          For example, to set it as 100 MB, --audit-log-maxsize=100\n        scored: true\n\n      - id: 1.2.20\n        text: \"Ensure that the --request-timeout argument is set as appropriate (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        type: manual\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          and set the below parameter as appropriate and if needed.\n          For example, --request-timeout=300s\n        scored: false\n\n      - id: 1.2.21\n        text: \"Ensure that the --service-account-lookup argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--service-account-lookup\"\n              set: false\n            - flag: \"--service-account-lookup\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the below parameter.\n          --service-account-lookup=true\n          Alternatively, you can delete the --service-account-lookup parameter from this file so\n          that the default takes effect.\n        scored: true\n\n      - id: 1.2.22\n        text: \"Ensure that the --service-account-key-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--service-account-key-file\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --service-account-key-file parameter\n          to the public key file for service accounts. For example,\n          --service-account-key-file=<filename>\n        scored: true\n\n      - id: 1.2.23\n        text: \"Ensure that the --etcd-certfile and --etcd-keyfile arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--etcd-certfile\"\n            - flag: \"--etcd-keyfile\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection between the apiserver and etcd.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the etcd certificate and key file parameters.\n          --etcd-certfile=<path/to/client-certificate-file>\n          --etcd-keyfile=<path/to/client-key-file>\n        scored: true\n\n      - id: 1.2.24\n        text: \"Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--tls-cert-file\"\n            - flag: \"--tls-private-key-file\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection on the apiserver.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the TLS certificate and private key file parameters.\n          --tls-cert-file=<path/to/tls-certificate-file>\n          --tls-private-key-file=<path/to/tls-key-file>\n        scored: true\n\n      - id: 1.2.25\n        text: \"Ensure that the --client-ca-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--client-ca-file\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection on the apiserver.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the client certificate authority file.\n          --client-ca-file=<path/to/client-ca-file>\n        scored: true\n\n      - id: 1.2.26\n        text: \"Ensure that the --etcd-cafile argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--etcd-cafile\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection between the apiserver and etcd.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the etcd certificate authority file parameter.\n          --etcd-cafile=<path/to/ca-file>\n        scored: true\n\n      - id: 1.2.27\n        text: \"Ensure that the --encryption-provider-config argument is set as appropriate (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--encryption-provider-config\"\n        remediation: |\n          Follow the Kubernetes documentation and configure a EncryptionConfig file.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --encryption-provider-config parameter to the path of that file.\n          For example, --encryption-provider-config=</path/to/EncryptionConfig/File>\n        scored: false\n\n      - id: 1.2.28\n        text: \"Ensure that encryption providers are appropriately configured (Manual)\"\n        audit: |\n          ENCRYPTION_PROVIDER_CONFIG=$(ps -ef | grep $apiserverbin | grep -- --encryption-provider-config | sed 's%.*encryption-provider-config[= ]\\([^ ]*\\).*%\\1%')\n          if test -e $ENCRYPTION_PROVIDER_CONFIG; then grep -A1 'providers:' $ENCRYPTION_PROVIDER_CONFIG | tail -n1 | grep -o \"[A-Za-z]*\" | sed 's/^/provider=/'; fi\n        tests:\n          test_items:\n            - flag: \"provider\"\n              compare:\n                op: valid_elements\n                value: \"aescbc,kms,secretbox\"\n        remediation: |\n          Follow the Kubernetes documentation and configure a EncryptionConfig file.\n          In this file, choose aescbc, kms or secretbox as the encryption provider.\n        scored: false\n\n      - id: 1.2.29\n        text: \"Ensure that the API Server only makes use of Strong Cryptographic Ciphers (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--tls-cipher-suites\"\n              compare:\n                op: valid_elements\n                value: \"TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,TLS_CHACHA20_POLY1305_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,TLS_RSA_WITH_3DES_EDE_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_256_GCM_SHA384\"\n        remediation: |\n          Edit the API server pod specification file /etc/kubernetes/manifests/kube-apiserver.yaml\n          on the control plane node and set the below parameter.\n          --tls-cipher-suites=TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,TLS_CHACHA20_POLY1305_SHA256,\n          TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,\n          TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,\n          TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,\n          TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,\n          TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,\n          TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,TLS_RSA_WITH_3DES_EDE_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA,\n          TLS_RSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_256_GCM_SHA384\n        scored: false\n\n  - id: 1.3\n    text: \"Controller Manager\"\n    checks:\n      - id: 1.3.1\n        text: \"Ensure that the --terminated-pod-gc-threshold argument is set as appropriate (Manual)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--terminated-pod-gc-threshold\"\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the --terminated-pod-gc-threshold to an appropriate threshold,\n          for example, --terminated-pod-gc-threshold=10\n        scored: false\n\n      - id: 1.3.2\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the below parameter.\n          --profiling=false\n        scored: true\n\n      - id: 1.3.3\n        text: \"Ensure that the --use-service-account-credentials argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--use-service-account-credentials\"\n              compare:\n                op: noteq\n                value: false\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node to set the below parameter.\n          --use-service-account-credentials=true\n        scored: true\n\n      - id: 1.3.4\n        text: \"Ensure that the --service-account-private-key-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--service-account-private-key-file\"\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the --service-account-private-key-file parameter\n          to the private key file for service accounts.\n          --service-account-private-key-file=<filename>\n        scored: true\n\n      - id: 1.3.5\n        text: \"Ensure that the --root-ca-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--root-ca-file\"\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the --root-ca-file parameter to the certificate bundle file`.\n          --root-ca-file=<path/to/file>\n        scored: true\n\n      - id: 1.3.6\n        text: \"Ensure that the RotateKubeletServerCertificate argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--feature-gates\"\n              compare:\n                op: nothave\n                value: \"RotateKubeletServerCertificate=false\"\n              set: true\n            - flag: \"--feature-gates\"\n              set: false\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the --feature-gates parameter to include RotateKubeletServerCertificate=true.\n          --feature-gates=RotateKubeletServerCertificate=true\n        scored: true\n\n      - id: 1.3.7\n        text: \"Ensure that the --bind-address argument is set to 127.0.0.1 (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--bind-address\"\n              compare:\n                op: eq\n                value: \"127.0.0.1\"\n            - flag: \"--bind-address\"\n              set: false\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and ensure the correct value for the --bind-address parameter\n        scored: true\n\n  - id: 1.4\n    text: \"Scheduler\"\n    checks:\n      - id: 1.4.1\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: \"/bin/ps -ef | grep $schedulerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the Scheduler pod specification file $schedulerconf file\n          on the control plane node and set the below parameter.\n          --profiling=false\n        scored: true\n\n      - id: 1.4.2\n        text: \"Ensure that the --bind-address argument is set to 127.0.0.1 (Automated)\"\n        audit: \"/bin/ps -ef | grep $schedulerbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--bind-address\"\n              compare:\n                op: eq\n                value: \"127.0.0.1\"\n            - flag: \"--bind-address\"\n              set: false\n        remediation: |\n          Edit the Scheduler pod specification file $schedulerconf\n          on the control plane node and ensure the correct value for the --bind-address parameter\n        scored: true\n"
  },
  {
    "path": "cfg/cis-1.9/node.yaml",
    "content": "---\ncontrols:\nversion: \"cis-1.9\"\nid: 4\ntext: \"Worker Node Security Configuration\"\ntype: \"node\"\ngroups:\n  - id: 4.1\n    text: \"Worker Node Configuration Files\"\n    checks:\n      - id: 4.1.1\n        text: \"Ensure that the kubelet service file permissions are set to 600 or more restrictive (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletsvc; then stat -c permissions=%a $kubeletsvc; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example, chmod 600 $kubeletsvc\n        scored: true\n\n      - id: 4.1.2\n        text: \"Ensure that the kubelet service file ownership is set to root:root (Automated)\"\n        audit: '/bin/sh -c \"if test -e $kubeletsvc; then stat -c %U:%G $kubeletsvc; else echo \\\"File not found\\\"; fi\"'\n        tests:\n          bin_op: or\n          test_items:\n            - flag: root:root\n            - flag: \"File not found\"\n        remediation: |\n            Run the below command (based on the file location on your system) on the each worker node.\n            For example,\n            chown root:root $kubeletsvc\n        scored: true\n\n      - id: 4.1.3\n        text: \"If proxy kubeconfig file exists ensure permissions are set to 600 or more restrictive (Manual)\"\n        audit: '/bin/sh -c ''if test -e $proxykubeconfig; then stat -c permissions=%a $proxykubeconfig; fi'' '\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"permissions\"\n              set: true\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chmod 600 $proxykubeconfig\n        scored: false\n\n      - id: 4.1.4\n        text: \"If proxy kubeconfig file exists ensure ownership is set to root:root (Manual)\"\n        audit: '/bin/sh -c ''if test -e $proxykubeconfig; then stat -c %U:%G $proxykubeconfig; fi'' '\n        tests:\n          bin_op: or\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example, chown root:root $proxykubeconfig\n        scored: false\n\n      - id: 4.1.5\n        text: \"Ensure that the --kubeconfig kubelet.conf file permissions are set to 600 or more restrictive (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletkubeconfig; then stat -c permissions=%a $kubeletkubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chmod 600 $kubeletkubeconfig\n        scored: true\n\n      - id: 4.1.6\n        text: \"Ensure that the --kubeconfig kubelet.conf file ownership is set to root:root (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletkubeconfig; then stat -c %U:%G $kubeletkubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chown root:root $kubeletkubeconfig\n        scored: true\n\n      - id: 4.1.7\n        text: \"Ensure that the certificate authorities file permissions are set to 600 or more restrictive (Manual)\"\n        audit: |\n          CAFILE=$(ps -ef | grep kubelet | grep -v apiserver | grep -- --client-ca-file= | awk -F '--client-ca-file=' '{print $2}' | awk '{print $1}' | uniq)\n          if test -z $CAFILE; then CAFILE=$kubeletcafile; fi\n          if test -e $CAFILE; then stat -c permissions=%a $CAFILE; fi\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the following command to modify the file permissions of the\n          --client-ca-file chmod 600 <filename>\n        scored: false\n\n      - id: 4.1.8\n        text: \"Ensure that the client certificate authorities file ownership is set to root:root (Manual)\"\n        audit: |\n          CAFILE=$(ps -ef | grep kubelet | grep -v apiserver | grep -- --client-ca-file= | awk -F '--client-ca-file=' '{print $2}' | awk '{print $1}' | uniq)\n          if test -z $CAFILE; then CAFILE=$kubeletcafile; fi\n          if test -e $CAFILE; then stat -c %U:%G $CAFILE; fi\n        tests:\n          test_items:\n            - flag: root:root\n              compare:\n                op: eq\n                value: root:root\n        remediation: |\n          Run the following command to modify the ownership of the --client-ca-file.\n          chown root:root <filename>\n        scored: false\n\n      - id: 4.1.9\n        text: \"If the kubelet config.yaml configuration file is being used validate permissions set to 600 or more restrictive (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletconf; then stat -c permissions=%a $kubeletconf; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the following command (using the config file location identified in the Audit step)\n          chmod 600 $kubeletconf\n        scored: true\n\n      - id: 4.1.10\n        text: \"If the kubelet config.yaml configuration file is being used validate file ownership is set to root:root (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletconf; then stat -c %U:%G $kubeletconf; fi'' '\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the following command (using the config file location identified in the Audit step)\n          chown root:root $kubeletconf\n        scored: true\n\n  - id: 4.2\n    text: \"Kubelet\"\n    checks:\n      - id: 4.2.1\n        text: \"Ensure that the --anonymous-auth argument is set to false (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: \"--anonymous-auth\"\n              path: '{.authentication.anonymous.enabled}'\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          If using a Kubelet config file, edit the file to set `authentication: anonymous: enabled` to\n          `false`.\n          If using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          `--anonymous-auth=false`\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.2\n        text: \"Ensure that the --authorization-mode argument is not set to AlwaysAllow (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --authorization-mode\n              path: '{.authorization.mode}'\n              compare:\n                op: nothave\n                value: AlwaysAllow\n        remediation: |\n          If using a Kubelet config file, edit the file to set `authorization.mode` to Webhook. If\n          using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_AUTHZ_ARGS variable.\n          --authorization-mode=Webhook\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.3\n        text: \"Ensure that the --client-ca-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --client-ca-file\n              path: '{.authentication.x509.clientCAFile}'\n        remediation: |\n          If using a Kubelet config file, edit the file to set `authentication.x509.clientCAFile` to\n          the location of the client CA file.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_AUTHZ_ARGS variable.\n          --client-ca-file=<path/to/client-ca-file>\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.4\n        text: \"Verify that the --read-only-port argument is set to 0 (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--read-only-port\"\n              path: '{.readOnlyPort}'\n              compare:\n                op: eq\n                value: 0\n            - flag: \"--read-only-port\"\n              path: '{.readOnlyPort}'\n              set: false\n        remediation: |\n          If using a Kubelet config file, edit the file to set `readOnlyPort` to 0.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --read-only-port=0\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.5\n        text: \"Ensure that the --streaming-connection-idle-timeout argument is not set to 0 (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --streaming-connection-idle-timeout\n              path: '{.streamingConnectionIdleTimeout}'\n              compare:\n                op: noteq\n                value: 0\n            - flag: --streaming-connection-idle-timeout\n              path: '{.streamingConnectionIdleTimeout}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to set `streamingConnectionIdleTimeout` to a\n          value other than 0.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --streaming-connection-idle-timeout=5m\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.6\n        text: \"Ensure that the --make-iptables-util-chains argument is set to true (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --make-iptables-util-chains\n              path: '{.makeIPTablesUtilChains}'\n              compare:\n                op: eq\n                value: true\n            - flag: --make-iptables-util-chains\n              path: '{.makeIPTablesUtilChains}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to set `makeIPTablesUtilChains` to `true`.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          remove the --make-iptables-util-chains argument from the\n          KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.7\n        text: \"Ensure that the --hostname-override argument is not set (Manual)\"\n        # This is one of those properties that can only be set as a command line argument.\n        # To check if the property is set as expected, we need to parse the kubelet command\n        # instead reading the Kubelet Configuration file.\n        audit: \"/bin/ps -fC $kubeletbin\"\n        tests:\n          test_items:\n            - flag: --hostname-override\n              set: false\n        remediation: |\n          Edit the kubelet service file $kubeletsvc\n          on each worker node and remove the --hostname-override argument from the\n          KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.8\n        text: \"Ensure that the eventRecordQPS argument is set to a level which ensures appropriate event capture (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --event-qps\n              path: '{.eventRecordQPS}'\n              compare:\n                op: gte\n                value: 0\n            - flag: --event-qps\n              path: '{.eventRecordQPS}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to set `eventRecordQPS` to an appropriate level.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.9\n        text: \"Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --tls-cert-file\n              path: '{.tlsCertFile}'\n            - flag: --tls-private-key-file\n              path: '{.tlsPrivateKeyFile}'\n        remediation: |\n          If using a Kubelet config file, edit the file to set `tlsCertFile` to the location\n          of the certificate file to use to identify this Kubelet, and `tlsPrivateKeyFile`\n          to the location of the corresponding private key file.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameters in KUBELET_CERTIFICATE_ARGS variable.\n          --tls-cert-file=<path/to/tls-certificate-file>\n          --tls-private-key-file=<path/to/tls-key-file>\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.10\n        text: \"Ensure that the --rotate-certificates argument is not set to false (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --rotate-certificates\n              path: '{.rotateCertificates}'\n              compare:\n                op: eq\n                value: true\n            - flag: --rotate-certificates\n              path: '{.rotateCertificates}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to add the line `rotateCertificates` to `true` or\n          remove it altogether to use the default value.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          remove --rotate-certificates=false argument from the KUBELET_CERTIFICATE_ARGS\n          variable.\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.11\n        text: \"Verify that the RotateKubeletServerCertificate argument is set to true (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: RotateKubeletServerCertificate\n              path: '{.featureGates.RotateKubeletServerCertificate}'\n              compare:\n                op: nothave\n                value: false\n            - flag: RotateKubeletServerCertificate\n              path: '{.featureGates.RotateKubeletServerCertificate}'\n              set: false\n        remediation: |\n          Edit the kubelet service file $kubeletsvc\n          on each worker node and set the below parameter in KUBELET_CERTIFICATE_ARGS variable.\n          --feature-gates=RotateKubeletServerCertificate=true\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.12\n        text: \"Ensure that the Kubelet only makes use of Strong Cryptographic Ciphers (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --tls-cipher-suites\n              path: '{range .tlsCipherSuites[:]}{}{'',''}{end}'\n              compare:\n                op: valid_elements\n                value: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\n        remediation: |\n          If using a Kubelet config file, edit the file to set `tlsCipherSuites` to\n          TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\n          or to a subset of these values.\n          If using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the --tls-cipher-suites parameter as follows, or to a subset of these values.\n          --tls-cipher-suites=TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.13\n        text: \"Ensure that a limit is set on pod PIDs (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --pod-max-pids\n              path: '{.podPidsLimit}'\n        remediation: |\n          Decide on an appropriate level for this parameter and set it,\n          either via the --pod-max-pids command line parameter or the PodPidsLimit configuration file setting.\n        scored: false\n\n  - id: 4.3\n    text: \"kube-proxy\"\n    checks:\n      - id: 4.3.1\n        text: \"Ensure that the kube-proxy metrics service is bound to localhost (Automated)\"\n        audit: \"/bin/ps -fC $proxybin\"\n        audit_config: \"/bin/sh -c 'if test -e $proxykubeconfig; then cat $proxykubeconfig; fi'\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--metrics-bind-address\"\n              path: '{.metricsBindAddress}'\n              compare:\n                op: has\n                value: \"127.0.0.1\"\n            - flag: \"--metrics-bind-address\"\n              path: '{.metricsBindAddress}'\n              set: false\n        remediation: |\n           Modify or remove any values which bind the metrics service to a non-localhost address.\n           The default value is 127.0.0.1:10249.\n        scored: true\n"
  },
  {
    "path": "cfg/cis-1.9/policies.yaml",
    "content": "---\ncontrols:\nversion: \"cis-1.9\"\nid: 5\ntext: \"Kubernetes Policies\"\ntype: \"policies\"\ngroups:\n  - id: 5.1\n    text: \"RBAC and Service Accounts\"\n    checks:\n      - id: 5.1.1\n        text: \"Ensure that the cluster-admin role is only used where required (Automated)\"\n        audit: |\n          kubectl get clusterrolebindings -o=custom-columns=NAME:.metadata.name,ROLE:.roleRef.name,SUBJECT:.subjects[*].name --no-headers | while read -r role_name role_binding subject\n          do\n            if [[ \"${role_name}\" != \"cluster-admin\" && \"${role_binding}\" == \"cluster-admin\" ]]; then\n              is_compliant=\"false\"\n            else\n              is_compliant=\"true\"\n            fi;\n            echo \"**role_name: ${role_name} role_binding: ${role_binding} subject: ${subject} is_compliant: ${is_compliant}\"\n          done\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"is_compliant\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Identify all clusterrolebindings to the cluster-admin role. Check if they are used and\n          if they need this role or if they could use a role with fewer privileges.\n          Where possible, first bind users to a lower privileged role and then remove the\n          clusterrolebinding to the cluster-admin role : kubectl delete clusterrolebinding [name]\n          Condition: is_compliant is false if rolename is not cluster-admin and rolebinding is cluster-admin.\n        scored: false\n\n      - id: 5.1.2\n        text: \"Minimize access to secrets (Automated)\"\n        audit: \"echo \\\"canGetListWatchSecretsAsSystemAuthenticated: $(kubectl auth can-i get,list,watch secrets --all-namespaces --as=system:authenticated)\\\"\"\n        tests:\n          test_items:\n            - flag: \"canGetListWatchSecretsAsSystemAuthenticated\"\n              compare:\n                op: eq\n                value: no\n        remediation: |\n          Where possible, remove get, list and watch access to Secret objects in the cluster.\n        scored: false\n\n      - id: 5.1.3\n        text: \"Minimize wildcard use in Roles and ClusterRoles (Automated)\"\n        audit: |\n          # Check Roles\n          kubectl get roles --all-namespaces -o custom-columns=ROLE_NAMESPACE:.metadata.namespace,ROLE_NAME:.metadata.name --no-headers | while read -r role_namespace role_name\n          do\n            role_rules=$(kubectl get role -n \"${role_namespace}\" \"${role_name}\" -o=json | jq -c '.rules')\n            if echo \"${role_rules}\" | grep -q \"\\[\\\"\\*\\\"\\]\"; then\n              role_is_compliant=\"false\"\n            else\n              role_is_compliant=\"true\"\n            fi;\n            echo \"**role_name: ${role_name} role_namespace: ${role_namespace} role_rules: ${role_rules} role_is_compliant: ${role_is_compliant}\"\n          done\n\n          # Check ClusterRoles\n          kubectl get clusterroles -o custom-columns=CLUSTERROLE_NAME:.metadata.name --no-headers | while read -r clusterrole_name\n          do\n            clusterrole_rules=$(kubectl get clusterrole \"${clusterrole_name}\" -o=json | jq -c '.rules')\n            if echo \"${clusterrole_rules}\" | grep -q \"\\[\\\"\\*\\\"\\]\"; then\n              clusterrole_is_compliant=\"false\"\n            else\n              clusterrole_is_compliant=\"true\"\n            fi;\n          echo \"**clusterrole_name: ${clusterrole_name} clusterrole_rules: ${clusterrole_rules} clusterrole_is_compliant: ${clusterrole_is_compliant}\"\n          done\n        use_multiple_values: true\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"role_is_compliant\"\n              compare:\n                op: eq\n                value: true\n              set: true\n            - flag: \"clusterrole_is_compliant\"\n              compare:\n                op: eq\n                value: true\n              set: true\n        remediation: |\n          Where possible replace any use of wildcards [\"*\"] in roles and clusterroles with specific\n          objects or actions.\n          Condition: role_is_compliant is false if [\"*\"] is found in rules.\n          Condition: clusterrole_is_compliant is false if [\"*\"] is found in rules.\n        scored: false\n\n      - id: 5.1.4\n        text: \"Minimize access to create pods (Automated)\"\n        audit: |\n          echo \"canCreatePodsAsSystemAuthenticated: $(kubectl auth can-i create pods --all-namespaces --as=system:authenticated)\"\n        tests:\n          test_items:\n            - flag: \"canCreatePodsAsSystemAuthenticated\"\n              compare:\n                op: eq\n                value: no\n        remediation: |\n          Where possible, remove create access to pod objects in the cluster.\n        scored: false\n      - id: 5.1.5\n        text: \"Ensure that default service accounts are not actively used (Automated)\"\n        audit: |\n          kubectl get serviceaccount --all-namespaces --field-selector metadata.name=default -o=json | jq -r '.items[] | \" namespace: \\(.metadata.namespace), kind: \\(.kind), name: \\(.metadata.name), automountServiceAccountToken: \\(.automountServiceAccountToken | if . == null then \"notset\" else . end )\"' | xargs -L 1\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"automountServiceAccountToken\"\n              compare:\n                op: eq\n                value: false\n              set: true\n        remediation: |\n          Create explicit service accounts wherever a Kubernetes workload requires specific access\n          to the Kubernetes API server.\n          Modify the configuration of each default service account to include this value\n          `automountServiceAccountToken: false`.\n        scored: false\n\n      - id: 5.1.6\n        text: \"Ensure that Service Account Tokens are only mounted where necessary (Automated)\"\n        audit: |\n          kubectl get pods --all-namespaces -o custom-columns=POD_NAMESPACE:.metadata.namespace,POD_NAME:.metadata.name,POD_SERVICE_ACCOUNT:.spec.serviceAccount,POD_IS_AUTOMOUNTSERVICEACCOUNTTOKEN:.spec.automountServiceAccountToken --no-headers | while read -r pod_namespace pod_name pod_service_account pod_is_automountserviceaccounttoken\n          do\n            # Retrieve automountServiceAccountToken's value for ServiceAccount and Pod, set to notset if null or <none>.\n            svacc_is_automountserviceaccounttoken=$(kubectl get serviceaccount -n \"${pod_namespace}\" \"${pod_service_account}\" -o json | jq -r '.automountServiceAccountToken' | sed -e 's/<none>/notset/g' -e 's/null/notset/g')\n            pod_is_automountserviceaccounttoken=$(echo \"${pod_is_automountserviceaccounttoken}\" | sed -e 's/<none>/notset/g' -e 's/null/notset/g')\n            if [ \"${svacc_is_automountserviceaccounttoken}\" = \"false\" ] && ( [ \"${pod_is_automountserviceaccounttoken}\" = \"false\" ] || [ \"${pod_is_automountserviceaccounttoken}\" = \"notset\" ] ); then\n              is_compliant=\"true\"\n            elif [ \"${svacc_is_automountserviceaccounttoken}\" = \"true\" ] && [ \"${pod_is_automountserviceaccounttoken}\" = \"false\" ]; then\n              is_compliant=\"true\"\n            else\n              is_compliant=\"false\"\n            fi\n            echo \"**namespace: ${pod_namespace} pod_name: ${pod_name} service_account: ${pod_service_account} pod_is_automountserviceaccounttoken: ${pod_is_automountserviceaccounttoken} svacc_is_automountServiceAccountToken: ${svacc_is_automountserviceaccounttoken} is_compliant: ${is_compliant}\"\n          done\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"is_compliant\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Modify the definition of ServiceAccounts and Pods which do not need to mount service\n          account tokens to disable it, with `automountServiceAccountToken: false`.\n          If both the ServiceAccount and the Pod's .spec specify a value for automountServiceAccountToken, the Pod spec takes precedence.\n          Condition: Pod is_compliant to true when\n            - ServiceAccount is automountServiceAccountToken: false and Pod is automountServiceAccountToken: false or notset\n            - ServiceAccount is automountServiceAccountToken: true notset and Pod is automountServiceAccountToken: false\n        scored: false\n\n      - id: 5.1.7\n        text: \"Avoid use of system:masters group (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Remove the system:masters group from all users in the cluster.\n        scored: false\n\n      - id: 5.1.8\n        text: \"Limit use of the Bind, Impersonate and Escalate permissions in the Kubernetes cluster (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove the impersonate, bind and escalate rights from subjects.\n        scored: false\n\n      - id: 5.1.9\n        text: \"Minimize access to create persistent volumes (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove create access to PersistentVolume objects in the cluster.\n        scored: false\n\n      - id: 5.1.10\n        text: \"Minimize access to the proxy sub-resource of nodes (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove access to the proxy sub-resource of node objects.\n        scored: false\n\n      - id: 5.1.11\n        text: \"Minimize access to the approval sub-resource of certificatesigningrequests objects (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove access to the approval sub-resource of certificatesigningrequest objects.\n        scored: false\n\n      - id: 5.1.12\n        text: \"Minimize access to webhook configuration objects (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove access to the validatingwebhookconfigurations or mutatingwebhookconfigurations objects\n        scored: false\n\n      - id: 5.1.13\n        text: \"Minimize access to the service account token creation (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove access to the token sub-resource of serviceaccount objects.\n        scored: false\n\n  - id: 5.2\n    text: \"Pod Security Standards\"\n    checks:\n      - id: 5.2.1\n        text: \"Ensure that the cluster has at least one active policy control mechanism in place (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that either Pod Security Admission or an external policy control system is in place\n          for every namespace which contains user workloads.\n        scored: false\n\n      - id: 5.2.2\n        text: \"Minimize the admission of privileged containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of privileged containers.\n        scored: false\n\n      - id: 5.2.3\n        text: \"Minimize the admission of containers wishing to share the host process ID namespace (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of `hostPID` containers.\n        scored: false\n\n      - id: 5.2.4\n        text: \"Minimize the admission of containers wishing to share the host IPC namespace (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of `hostIPC` containers.\n        scored: false\n\n      - id: 5.2.5\n        text: \"Minimize the admission of containers wishing to share the host network namespace (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of `hostNetwork` containers.\n        scored: false\n\n      - id: 5.2.6\n        text: \"Minimize the admission of containers with allowPrivilegeEscalation (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers with `.spec.allowPrivilegeEscalation` set to `true`.\n        scored: false\n\n      - id: 5.2.7\n        text: \"Minimize the admission of root containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Create a policy for each namespace in the cluster, ensuring that either `MustRunAsNonRoot`\n          or `MustRunAs` with the range of UIDs not including 0, is set.\n        scored: false\n\n      - id: 5.2.8\n        text: \"Minimize the admission of containers with the NET_RAW capability (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers with the `NET_RAW` capability.\n        scored: false\n\n      - id: 5.2.9\n        text: \"Minimize the admission of containers with added capabilities (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that `allowedCapabilities` is not present in policies for the cluster unless\n          it is set to an empty array.\n        scored: false\n\n      - id: 5.2.10\n        text: \"Minimize the admission of containers with capabilities assigned (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Review the use of capabilites in applications running on your cluster. Where a namespace\n          contains applications which do not require any Linux capabities to operate consider adding\n          a PSP which forbids the admission of containers which do not drop all capabilities.\n        scored: false\n\n      - id: 5.2.11\n        text: \"Minimize the admission of Windows HostProcess containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers that have `.securityContext.windowsOptions.hostProcess` set to `true`.\n        scored: false\n\n      - id: 5.2.12\n        text: \"Minimize the admission of HostPath volumes (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers with `hostPath` volumes.\n        scored: false\n\n      - id: 5.2.13\n        text: \"Minimize the admission of containers which use HostPorts (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers which use `hostPort` sections.\n        scored: false\n\n  - id: 5.3\n    text: \"Network Policies and CNI\"\n    checks:\n      - id: 5.3.1\n        text: \"Ensure that the CNI in use supports NetworkPolicies (Manual)\"\n        type: \"manual\"\n        remediation: |\n          If the CNI plugin in use does not support network policies, consideration should be given to\n          making use of a different plugin, or finding an alternate mechanism for restricting traffic\n          in the Kubernetes cluster.\n        scored: false\n\n      - id: 5.3.2\n        text: \"Ensure that all Namespaces have NetworkPolicies defined (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the documentation and create NetworkPolicy objects as you need them.\n        scored: false\n\n  - id: 5.4\n    text: \"Secrets Management\"\n    checks:\n      - id: 5.4.1\n        text: \"Prefer using Secrets as files over Secrets as environment variables (Manual)\"\n        type: \"manual\"\n        remediation: |\n          If possible, rewrite application code to read Secrets from mounted secret files, rather than\n          from environment variables.\n        scored: false\n\n      - id: 5.4.2\n        text: \"Consider external secret storage (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Refer to the Secrets management options offered by your cloud provider or a third-party\n          secrets management solution.\n        scored: false\n\n  - id: 5.5\n    text: \"Extensible Admission Control\"\n    checks:\n      - id: 5.5.1\n        text: \"Configure Image Provenance using ImagePolicyWebhook admission controller (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and setup image provenance.\n        scored: false\n\n  - id: 5.7\n    text: \"General Policies\"\n    checks:\n      - id: 5.7.1\n        text: \"Create administrative boundaries between resources using namespaces (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the documentation and create namespaces for objects in your deployment as you need\n          them.\n        scored: false\n\n      - id: 5.7.2\n        text: \"Ensure that the seccomp profile is set to docker/default in your Pod definitions (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Use `securityContext` to enable the docker/default seccomp profile in your pod definitions.\n          An example is as below:\n            securityContext:\n              seccompProfile:\n                type: RuntimeDefault\n        scored: false\n\n      - id: 5.7.3\n        text: \"Apply SecurityContext to your Pods and Containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and apply SecurityContexts to your Pods. For a\n          suggested list of SecurityContexts, you may refer to the CIS Security Benchmark for Docker\n          Containers.\n        scored: false\n\n      - id: 5.7.4\n        text: \"The default namespace should not be used (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that namespaces are created to allow for appropriate segregation of Kubernetes\n          resources and that all new resources are created in a specific namespace.\n        scored: false\n"
  },
  {
    "path": "cfg/config.yaml",
    "content": "---\n## Controls Files.\n# These are YAML files that hold all the details for running checks.\n#\n## Uncomment to use different control file paths.\n# masterControls: ./cfg/master.yaml\n# nodeControls: ./cfg/node.yaml\n\nmaster:\n  components:\n    - apiserver\n    - scheduler\n    - controllermanager\n    - etcd\n    - flanneld\n    # kubernetes is a component to cover the config file /etc/kubernetes/config that is referred to in the benchmark\n    - kubernetes\n    - kubelet\n\n  kubernetes:\n    defaultconf: /etc/kubernetes/config\n\n  apiserver:\n    bins:\n      - \"kube-apiserver\"\n      - \"hyperkube apiserver\"\n      - \"hyperkube kube-apiserver\"\n      - \"apiserver\"\n      - \"openshift start master api\"\n      - \"hypershift openshift-kube-apiserver\"\n    confs:\n      - /etc/kubernetes/manifests/kube-apiserver.yaml\n      - /etc/kubernetes/manifests/kube-apiserver.yml\n      - /etc/kubernetes/manifests/kube-apiserver.manifest\n      - /var/snap/kube-apiserver/current/args\n      - /var/snap/microk8s/current/args/kube-apiserver\n      - /etc/origin/master/master-config.yaml\n      - /etc/kubernetes/manifests/talos-kube-apiserver.yaml\n      - /var/lib/rancher/rke2/agent/pod-manifests/kube-apiserver.yaml\n    defaultconf: /etc/kubernetes/manifests/kube-apiserver.yaml\n\n  scheduler:\n    bins:\n      - \"kube-scheduler\"\n      - \"hyperkube scheduler\"\n      - \"hyperkube kube-scheduler\"\n      - \"scheduler\"\n      - \"openshift start master controllers\"\n    confs:\n      - /etc/kubernetes/manifests/kube-scheduler.yaml\n      - /etc/kubernetes/manifests/kube-scheduler.yml\n      - /etc/kubernetes/manifests/kube-scheduler.manifest\n      - /var/snap/kube-scheduler/current/args\n      - /var/snap/microk8s/current/args/kube-scheduler\n      - /etc/origin/master/scheduler.json\n      - /etc/kubernetes/manifests/talos-kube-scheduler.yaml\n      - /var/lib/rancher/rke2/agent/pod-manifests/kube-scheduler.yaml\n    defaultconf: /etc/kubernetes/manifests/kube-scheduler.yaml\n    kubeconfig:\n      - /etc/kubernetes/scheduler.conf\n      - /var/lib/kube-scheduler/kubeconfig\n      - /var/lib/kube-scheduler/config.yaml\n      - /var/lib/rancher/rke2/server/cred/scheduler.kubeconfig\n      - /system/secrets/kubernetes/kube-scheduler/kubeconfig\n    defaultkubeconfig: /etc/kubernetes/scheduler.conf\n\n  controllermanager:\n    bins:\n      - \"kube-controller-manager\"\n      - \"kube-controller\"\n      - \"hyperkube controller-manager\"\n      - \"hyperkube kube-controller-manager\"\n      - \"controller-manager\"\n      - \"openshift start master controllers\"\n      - \"hypershift openshift-controller-manager\"\n    confs:\n      - /etc/kubernetes/manifests/kube-controller-manager.yaml\n      - /etc/kubernetes/manifests/kube-controller-manager.yml\n      - /etc/kubernetes/manifests/kube-controller-manager.manifest\n      - /var/snap/kube-controller-manager/current/args\n      - /var/snap/microk8s/current/args/kube-controller-manager\n      - /etc/kubernetes/manifests/talos-kube-controller-manager.yaml\n      - /var/lib/rancher/rke2/agent/pod-manifests/kube-controller-manager.yaml\n    defaultconf: /etc/kubernetes/manifests/kube-controller-manager.yaml\n    kubeconfig:\n      - /etc/kubernetes/controller-manager.conf\n      - /var/lib/kube-controller-manager/kubeconfig\n      - /var/lib/rancher/rke2/server/cred/controller.kubeconfig\n      - /system/secrets/kubernetes/kube-controller-manager/kubeconfig\n    defaultkubeconfig: /etc/kubernetes/controller-manager.conf\n\n  etcd:\n    optional: true\n    bins:\n      - \"etcd\"\n      - \"openshift start etcd\"\n    datadirs:\n      - /var/lib/etcd/default.etcd\n      - /var/lib/etcd/data.etcd\n      - /var/lib/rancher/k3s/server/db/etcd\n    confs:\n      - /etc/kubernetes/manifests/etcd.yaml\n      - /etc/kubernetes/manifests/etcd.yml\n      - /etc/kubernetes/manifests/etcd.manifest\n      - /etc/etcd/etcd.conf\n      - /var/snap/etcd/common/etcd.conf.yml\n      - /var/snap/etcd/common/etcd.conf.yaml\n      - /var/snap/microk8s/current/args/etcd\n      - /usr/lib/systemd/system/etcd.service\n      - /var/lib/rancher/rke2/server/db/etcd/config\n      - /var/lib/rancher/k3s/server/db/etcd/config\n    defaultconf: /etc/kubernetes/manifests/etcd.yaml\n    defaultdatadir: /var/lib/etcd/default.etcd\n    client_cert_file: /var/lib/rancher/rke2/server/tls/etcd/server-client.crt\n    client_key_file: /var/lib/rancher/rke2/server/tls/etcd/server-client.key\n\n\n  flanneld:\n    optional: true\n    bins:\n      - flanneld\n    defaultconf: /etc/sysconfig/flanneld\n\n  kubelet:\n    optional: true\n    bins:\n      - \"hyperkube kubelet\"\n      - \"kubelet\"\n\nnode:\n  components:\n    - kubelet\n    - proxy\n    # kubernetes is a component to cover the config file /etc/kubernetes/config that is referred to in the benchmark\n    - kubernetes\n\n  kubernetes:\n    defaultconf: \"/etc/kubernetes/config\"\n\n  kubelet:\n    cafile:\n      - \"/var/lib/rancher/rke2/agent/client-ca.crt\"\n      - \"/var/lib/rancher/rke2/server/tls/server-ca.crt\"\n      - \"/etc/kubernetes/pki/ca.crt\"\n      - \"/etc/kubernetes/certs/ca.crt\"\n      - \"/etc/kubernetes/cert/ca.pem\"\n      - \"/var/snap/microk8s/current/certs/ca.crt\"\n      - \"/var/lib/rancher/rke2/agent/server.crt\"\n      - \"/var/lib/rancher/k3s/agent/client-ca.crt\"\n    svc:\n      # These paths must also be included\n      #  in the 'confs' property below\n      - \"/etc/systemd/system/kubelet.service.d/10-kubeadm.conf\"\n      - \"/etc/systemd/system/kubelet.service\"\n      - \"/lib/systemd/system/kubelet.service\"\n      - \"/etc/systemd/system/snap.kubelet.daemon.service\"\n      - \"/etc/systemd/system/snap.microk8s.daemon-kubelet.service\"\n      - \"/etc/systemd/system/atomic-openshift-node.service\"\n      - \"/etc/systemd/system/origin-node.service\"\n    bins:\n      - \"hyperkube kubelet\"\n      - \"kubelet\"\n    kubeconfig:\n      - \"/etc/kubernetes/kubelet.conf\"\n      - \"/etc/kubernetes/kubelet-kubeconfig.conf\"\n      - \"/var/lib/kubelet/kubeconfig\"\n      - \"/etc/kubernetes/kubelet-kubeconfig\"\n      - \"/etc/kubernetes/kubelet/kubeconfig\"\n      - \"/etc/kubernetes/ssl/kubecfg-kube-node.yaml\"\n      - \"/var/snap/microk8s/current/credentials/kubelet.config\"\n      - \"/etc/kubernetes/kubeconfig-kubelet\"\n      - \"/var/lib/rancher/rke2/agent/kubelet.kubeconfig\"\n      - \"/var/lib/rancher/k3s/agent/kubelet.kubeconfig\"\n    confs:\n      - \"/etc/kubernetes/kubelet-config.yaml\"\n      - \"/etc/kubernetes/kubelet/kubelet-config.json\"\n      - \"/var/lib/rancher/rke2/agent/etc/kubelet.conf.d\"\n      - \"/var/lib/kubelet/config.yaml\"\n      - \"/etc/kubernetes/azure.json\"\n      - \"/var/lib/kubelet/config.yml\"\n      - \"/etc/kubernetes/kubelet/kubelet-config.json\"\n      - \"/etc/kubernetes/kubelet/config.json\"\n      - \"/etc/kubernetes/kubelet/config\"\n      - \"/home/kubernetes/kubelet-config.yaml\"\n      - \"/home/kubernetes/kubelet-config.yml\"\n      - \"/etc/default/kubeletconfig.json\"\n      - \"/etc/default/kubelet\"\n      - \"/var/lib/kubelet/kubeconfig\"\n      - \"/var/snap/kubelet/current/args\"\n      - \"/var/snap/microk8s/current/args/kubelet\"\n      ## Due to the fact that the kubelet might be configured\n      ## without a kubelet-config file, we use a work-around\n      ## of pointing to the systemd service file (which can also\n      ## hold kubelet configuration).\n      ## Note: The following paths must match the one under 'svc'\n      - \"/etc/systemd/system/kubelet.service.d/10-kubeadm.conf\"\n      - \"/etc/systemd/system/kubelet.service\"\n      - \"/lib/systemd/system/kubelet.service\"\n      - \"/etc/systemd/system/snap.kubelet.daemon.service\"\n      - \"/etc/systemd/system/snap.microk8s.daemon-kubelet.service\"\n      - \"/etc/kubernetes/kubelet.yaml\"\n\n    defaultconf: \"/var/lib/kubelet/config.yaml\"\n    defaultsvc: \"/etc/systemd/system/kubelet.service.d/10-kubeadm.conf\"\n    defaultkubeconfig: \"/etc/kubernetes/kubelet.conf\"\n    defaultcafile: \"/etc/kubernetes/pki/ca.crt\"\n\n  proxy:\n    optional: true\n    bins:\n      - \"kube-proxy\"\n      - \"hyperkube proxy\"\n      - \"hyperkube kube-proxy\"\n      - \"proxy\"\n      - \"openshift start network\"\n    confs:\n      - /etc/kubernetes/proxy\n      - /etc/kubernetes/addons/kube-proxy-daemonset.yaml\n      - /etc/kubernetes/addons/kube-proxy-daemonset.yml\n      - /var/snap/kube-proxy/current/args\n      - /var/snap/microk8s/current/args/kube-proxy\n    kubeconfig:\n      - \"/etc/kubernetes/kubelet-kubeconfig\"\n      - \"/etc/kubernetes/kubelet-kubeconfig.conf\"\n      - \"/etc/kubernetes/kubelet/config\"\n      - \"/etc/kubernetes/ssl/kubecfg-kube-proxy.yaml\"\n      - \"/var/lib/kubelet/kubeconfig\"\n      - \"/var/snap/microk8s/current/credentials/proxy.config\"\n      - \"/var/lib/rancher/rke2/agent/kubeproxy.kubeconfig\"\n      - \"/var/lib/rancher/k3s/agent/kubeproxy.kubeconfig\"\n    svc:\n      - \"/lib/systemd/system/kube-proxy.service\"\n      - \"/etc/systemd/system/snap.microk8s.daemon-proxy.service\"\n    defaultconf: /etc/kubernetes/addons/kube-proxy-daemonset.yaml\n    defaultkubeconfig: \"/etc/kubernetes/proxy.conf\"\n\netcd:\n  components:\n    - etcd\n\n  etcd:\n    bins:\n      - \"etcd\"\n    datadirs:\n      - /var/lib/etcd/default.etcd\n      - /var/lib/etcd/data.etcd\n      - /var/lib/rancher/k3s/server/db/etcd\n    confs:\n      - /var/lib/rancher/rke2/server/db/etcd/config\n      - /var/lib/rancher/rke2/agent/pod-manifests/etcd.yaml\n      - /etc/kubernetes/manifests/etcd.yaml\n      - /etc/kubernetes/manifests/etcd.yml\n      - /etc/kubernetes/manifests/etcd.manifest\n      - /etc/etcd/etcd.conf\n      - /var/snap/etcd/common/etcd.conf.yml\n      - /var/snap/etcd/common/etcd.conf.yaml\n      - /var/snap/microk8s/current/args/etcd\n      - /usr/lib/systemd/system/etcd.service\n      - /var/lib/rancher/k3s/server/db/etcd/config\n    defaultconf: /etc/kubernetes/manifests/etcd.yaml\n    defaultdatadir: /var/lib/etcd/default.etcd\n\ncontrolplane:\n  components:\n    - apiserver\n\n  apiserver:\n    bins:\n      - \"kube-apiserver\"\n      - \"hyperkube apiserver\"\n      - \"hyperkube kube-apiserver\"\n      - \"apiserver\"\n\npolicies:\n  components: []\n\nmanagedservices:\n  components: []\n\nversion_mapping:\n  \"1.15\": \"cis-1.5\"\n  \"1.16\": \"cis-1.6\"\n  \"1.17\": \"cis-1.6\"\n  \"1.18\": \"cis-1.6\"\n  \"1.19\": \"cis-1.20\"\n  \"1.20\": \"cis-1.20\"\n  \"1.21\": \"cis-1.20\"\n  \"1.22\": \"cis-1.23\"\n  \"1.23\": \"cis-1.23\"\n  \"1.24\": \"cis-1.24\"\n  \"1.25\": \"cis-1.7\"\n  \"1.26\": \"cis-1.8\"\n  \"1.27\": \"cis-1.9\"\n  \"1.28\": \"cis-1.10\"\n  \"1.29\": \"cis-1.11\"\n  \"1.30\": \"cis-1.11\"\n  \"1.31\": \"cis-1.11\"\n  \"1.32\": \"cis-1.12\"\n  \"1.33\": \"cis-1.12\"\n  \"1.34\": \"cis-1.12\"\n  \"eks-1.0.1\": \"eks-1.0.1\"\n  \"eks-1.1.0\": \"eks-1.1.0\"\n  \"eks-1.2.0\": \"eks-1.2.0\"\n  \"eks-1.5.0\": \"eks-1.5.0\"\n  \"eks-1.7.0\": \"eks-1.7.0\"\n  \"eks-1.8.0\": \"eks-1.8.0\"\n  \"gke-1.0\": \"gke-1.0\"\n  \"gke-1.2.0\": \"gke-1.2.0\"\n  \"gke-1.6.0\": \"gke-1.6.0\"\n  \"gke-1.8.0\": \"gke-1.8.0\"\n  \"ocp-3.10\": \"rh-0.7\"\n  \"ocp-3.11\": \"rh-0.7\"\n  \"ocp-4.0\": \"rh-1.0\"\n  \"ocp-4.11\": \"rh-1.4\"\n  \"ocp-4.13\": \"rh-1.8\"\n  \"aks-1.0\": \"aks-1.0\"\n  \"aks-1.7\": \"aks-1.7\"\n  \"aks-1.8\": \"aks-1.8\"\n  \"ack-1.0\": \"ack-1.0\"\n  \"cis-1.6-k3s\": \"cis-1.6-k3s\"\n  \"cis-1.24-microk8s\": \"cis-1.24-microk8s\"\n  \"tkgi-1.2.53\": \"tkgi-1.2.53\"\n  \"k3s-cis-1.7\": \"k3s-cis-1.7\"\n  \"k3s-cis-1.23\": \"k3s-cis-1.23\"\n  \"k3s-cis-1.24\": \"k3s-cis-1.24\"\n  \"rke-cis-1.7\": \"rke-cis-1.7\"\n  \"rke-cis-1.23\": \"rke-cis-1.23\"\n  \"rke-cis-1.24\": \"rke-cis-1.24\"\n  \"rke2-cis-1.7\": \"rke2-cis-1.7\"\n  \"rke2-cis-1.8\": \"rke2-cis-1.8\"\n  \"rke2-cis-1.23\": \"rke2-cis-1.23\"\n  \"rke2-cis-1.24\": \"rke2-cis-1.24\"\n\ntarget_mapping:\n  \"cis-1.5\":\n    - \"master\"\n    - \"node\"\n    - \"controlplane\"\n    - \"etcd\"\n    - \"policies\"\n  \"cis-1.6\":\n    - \"master\"\n    - \"node\"\n    - \"controlplane\"\n    - \"etcd\"\n    - \"policies\"\n  \"cis-1.6-k3s\":\n    - \"master\"\n    - \"node\"\n    - \"controlplane\"\n    - \"etcd\"\n    - \"policies\"\n  \"cis-1.20\":\n    - \"master\"\n    - \"node\"\n    - \"controlplane\"\n    - \"etcd\"\n    - \"policies\"\n  \"cis-1.23\":\n    - \"master\"\n    - \"node\"\n    - \"controlplane\"\n    - \"etcd\"\n    - \"policies\"\n  \"cis-1.24\":\n    - \"master\"\n    - \"node\"\n    - \"controlplane\"\n    - \"etcd\"\n    - \"policies\"\n  \"cis-1.24-microk8s\":\n    - \"master\"\n    - \"etcd\"\n    - \"node\"\n    - \"controlplane\"\n    - \"policies\"\n  \"cis-1.7\":\n    - \"master\"\n    - \"node\"\n    - \"controlplane\"\n    - \"etcd\"\n    - \"policies\"\n  \"cis-1.8\":\n    - \"master\"\n    - \"node\"\n    - \"controlplane\"\n    - \"etcd\"\n    - \"policies\"\n  \"cis-1.9\":\n    - \"master\"\n    - \"node\"\n    - \"controlplane\"\n    - \"etcd\"\n    - \"policies\"\n  \"cis-1.10\":\n    - \"master\"\n    - \"node\"\n    - \"controlplane\"\n    - \"etcd\"\n    - \"policies\"\n  \"cis-1.11\":\n    - \"master\"\n    - \"node\"\n    - \"controlplane\"\n    - \"etcd\"\n    - \"policies\"\n  \"cis-1.12\":\n    - \"master\"\n    - \"node\"\n    - \"controlplane\"\n    - \"etcd\"\n    - \"policies\"\n  \"gke-1.0\":\n    - \"master\"\n    - \"node\"\n    - \"controlplane\"\n    - \"etcd\"\n    - \"policies\"\n    - \"managedservices\"\n  \"gke-1.2.0\":\n    - \"master\"\n    - \"node\"\n    - \"controlplane\"\n    - \"policies\"\n    - \"managedservices\"\n  \"gke-1.6.0\":\n    - \"master\"\n    - \"node\"\n    - \"controlplane\"\n    - \"policies\"\n    - \"managedservices\"\n  \"gke-1.8.0\":\n    - \"master\"\n    - \"node\"\n    - \"controlplane\"\n    - \"policies\"\n    - \"managedservices\"\n  \"eks-1.0.1\":\n    - \"master\"\n    - \"node\"\n    - \"controlplane\"\n    - \"policies\"\n    - \"managedservices\"\n  \"eks-1.1.0\":\n    - \"master\"\n    - \"node\"\n    - \"controlplane\"\n    - \"policies\"\n    - \"managedservices\"\n  \"eks-1.2.0\":\n    - \"master\"\n    - \"node\"\n    - \"controlplane\"\n    - \"policies\"\n    - \"managedservices\"\n  \"eks-1.5.0\":\n    - \"master\"\n    - \"node\"\n    - \"controlplane\"\n    - \"policies\"\n    - \"managedservices\"\n  \"eks-1.7.0\":\n    - \"master\"\n    - \"node\"\n    - \"controlplane\"\n    - \"policies\"\n    - \"managedservices\"\n  \"eks-1.8.0\":\n    - \"master\"\n    - \"node\"\n    - \"controlplane\"\n    - \"policies\"\n    - \"managedservices\"\n  \"rh-0.7\":\n    - \"master\"\n    - \"node\"\n  \"aks-1.0\":\n    - \"master\"\n    - \"node\"\n    - \"controlplane\"\n    - \"policies\"\n    - \"managedservices\"\n  \"aks-1.7\":\n    - \"master\"\n    - \"node\"\n    - \"controlplane\"\n    - \"policies\"\n    - \"managedservices\"\n  \"aks-1.8\":\n    - \"master\"\n    - \"node\"\n    - \"controlplane\"\n    - \"policies\"\n    - \"managedservices\"\n  \"ack-1.0\":\n    - \"master\"\n    - \"node\"\n    - \"controlplane\"\n    - \"etcd\"\n    - \"policies\"\n    - \"managedservices\"\n  \"rh-1.0\":\n    - \"master\"\n    - \"node\"\n    - \"controlplane\"\n    - \"policies\"\n    - \"etcd\"\n  \"rh-1.4\":\n    - \"master\"\n    - \"node\"\n    - \"controlplane\"\n    - \"policies\"\n    - \"etcd\"\n  \"rh-1.8\":\n    - \"master\"\n    - \"node\"\n    - \"controlplane\"\n    - \"policies\"\n    - \"etcd\"\n  \"eks-stig-kubernetes-v1r6\":\n    - \"node\"\n    - \"controlplane\"\n    - \"policies\"\n    - \"managedservices\"\n  \"tkgi-1.2.53\":\n    - \"master\"\n    - \"etcd\"\n    - \"controlplane\"\n    - \"node\"\n    - \"policies\"\n  \"k3s-cis-1.7\":\n    - \"master\"\n    - \"etcd\"\n    - \"controlplane\"\n    - \"node\"\n    - \"policies\"\n  \"k3s-cis-1.8\":\n    - \"master\"\n    - \"etcd\"\n    - \"controlplane\"\n    - \"node\"\n    - \"policies\"\n  \"k3s-cis-1.23\":\n    - \"master\"\n    - \"etcd\"\n    - \"controlplane\"\n    - \"node\"\n    - \"policies\"\n  \"k3s-cis-1.24\":\n    - \"master\"\n    - \"etcd\"\n    - \"controlplane\"\n    - \"node\"\n    - \"policies\"\n  \"rke-cis-1.7\":\n    - \"master\"\n    - \"etcd\"\n    - \"controlplane\"\n    - \"node\"\n    - \"policies\"\n  \"rke-cis-1.23\":\n    - \"master\"\n    - \"etcd\"\n    - \"controlplane\"\n    - \"node\"\n    - \"policies\"\n  \"rke-cis-1.24\":\n    - \"master\"\n    - \"etcd\"\n    - \"controlplane\"\n    - \"node\"\n    - \"policies\"\n  \"rke2-cis-1.7\":\n    - \"master\"\n    - \"etcd\"\n    - \"controlplane\"\n    - \"node\"\n    - \"policies\"\n  \"rke2-cis-1.8\":\n    - \"master\"\n    - \"etcd\"\n    - \"controlplane\"\n    - \"node\"\n    - \"policies\"\n  \"rke2-cis-1.23\":\n    - \"master\"\n    - \"etcd\"\n    - \"controlplane\"\n    - \"node\"\n    - \"policies\"\n  \"rke2-cis-1.24\":\n    - \"master\"\n    - \"etcd\"\n    - \"controlplane\"\n    - \"node\"\n    - \"policies\"\n"
  },
  {
    "path": "cfg/eks-1.0.1/config.yaml",
    "content": "---\n## Version-specific settings that override the values in cfg/config.yaml\n## These settings are required if you are using the --asff option to report findings to AWS Security Hub\n## AWS account number is required.\nAWS_ACCOUNT: \"<AWS_ACCT_NUMBER>\"\n## AWS region is required.\nAWS_REGION: \"<AWS_REGION>\"\n## EKS Cluster ARN is required.\nCLUSTER_ARN: \"<AWS_CLUSTER_ARN>\"\n"
  },
  {
    "path": "cfg/eks-1.0.1/controlplane.yaml",
    "content": "---\ncontrols:\nversion: \"eks-1.0.1\"\nid: 2\ntext: \"Control Plane Configuration\"\ntype: \"controlplane\"\ngroups:\n  - id: 2.1\n    text: \"Logging\"\n    checks:\n      - id: 2.1.1\n        text: \"Enable audit logs (Manual)\"\n        remediation: \"Enable control plane logging for API Server, Audit, Authenticator, Controller Manager, and Scheduler.\"\n        scored: false\n"
  },
  {
    "path": "cfg/eks-1.0.1/managedservices.yaml",
    "content": "---\ncontrols:\nversion: \"eks-1.0.1\"\nid: 5\ntext: \"Managed Services\"\ntype: \"managedservices\"\ngroups:\n  - id: 5.1\n    text: \"Image Registry and Image Scanning\"\n    checks:\n      - id: 5.1.1\n        text: \"Ensure Image Vulnerability Scanning using Amazon ECR image scanning or a third-party provider (Manual)\"\n        type: \"manual\"\n        remediation: \"No remediation\"\n        scored: false\n\n      - id: 5.1.2\n        text: \"Minimize user access to Amazon ECR (Manual)\"\n        type: \"manual\"\n        remediation: \"No remediation\"\n        scored: false\n\n      - id: 5.1.3\n        text: \"Minimize cluster access to read-only for Amazon ECR (Manual)\"\n        type: \"manual\"\n        remediation: \"No remediation\"\n        scored: false\n\n      - id: 5.1.4\n        text: \"Minimize Container Registries to only those approved (Manual)\"\n        type: \"manual\"\n        remediation: \"No remediation\"\n        scored: false\n\n  - id: 5.2\n    text: \"Identity and Access Management (IAM)\"\n    checks:\n      - id: 5.2.1\n        text: \"Prefer using dedicated Amazon EKS Service Accounts (Manual)\"\n        type: \"manual\"\n        remediation: \"No remediation\"\n        scored: false\n\n  - id: 5.3\n    text: \"AWS Key Management Service (KMS)\"\n    checks:\n      - id: 5.3.1\n        text: \"Ensure Kubernetes Secrets are encrypted using Customer Master Keys (CMKs) managed in AWS KMS (Manual)\"\n        type: \"manual\"\n        remediation: \"No remediation\"\n        scored: false\n\n  - id: 5.4\n    text: \"Cluster Networking\"\n    checks:\n      - id: 5.4.1\n        text: \"Restrict Access to the Control Plane Endpoint (Manual)\"\n        type: \"manual\"\n        remediation: \"No remediation\"\n        scored: false\n\n      - id: 5.4.2\n        text: \"Ensure clusters are created with Private Endpoint Enabled and Public Access Disabled (Manual)\"\n        type: \"manual\"\n        remediation: \"No remediation\"\n        scored: false\n\n      - id: 5.4.3\n        text: \"Ensure clusters are created with Private Nodes (Manual)\"\n        type: \"manual\"\n        remediation: \"No remediation\"\n        scored: false\n\n      - id: 5.4.4\n        text: \"Ensure Network Policy is Enabled and set as appropriate (Manual)\"\n        type: \"manual\"\n        remediation: \"No remediation\"\n        scored: false\n\n      - id: 5.4.5\n        text: \"Encrypt traffic to HTTPS load balancers with TLS certificates (Manual)\"\n        type: \"manual\"\n        remediation: \"No remediation\"\n        scored: false\n\n\n  - id: 5.5\n    text: \"Authentication and Authorization\"\n    checks:\n      - id: 5.5.1\n        text: \"Manage Kubernetes RBAC users with AWS IAM Authenticator for Kubernetes (Manual)\"\n        type: \"manual\"\n        remediation: \"No remediation\"\n        scored: false\n\n\n  - id: 5.6\n    text: \"Other Cluster Configurations\"\n    checks:\n      - id: 5.6.1\n        text: \"Consider Fargate for running untrusted workloads (Manual)\"\n        type: \"manual\"\n        remediation: \"No remediation\"\n        scored: false\n"
  },
  {
    "path": "cfg/eks-1.0.1/master.yaml",
    "content": "---\ncontrols:\nversion: \"eks-1.0.1\"\nid: 1\ntext: \"Control Plane Components\"\ntype: \"master\"\n"
  },
  {
    "path": "cfg/eks-1.0.1/node.yaml",
    "content": "---\ncontrols:\nversion: \"eks-1.0.1\"\nid: 3\ntext: \"Worker Node Security Configuration\"\ntype: \"node\"\ngroups:\n  - id: 3.1\n    text: \"Worker Node Configuration Files\"\n    checks:\n      - id: 3.1.1\n        text: \"Ensure that the kubeconfig file permissions are set to 644 or more restrictive (Manual)\"\n        audit: '/bin/sh -c ''if test -e $kubeletkubeconfig; then stat -c permissions=%a $kubeletkubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chmod 644 $kubeletkubeconfig\n        scored: false\n\n      - id: 3.1.2\n        text: \"Ensure that the kubelet kubeconfig file ownership is set to root:root (Manual)\"\n        audit: '/bin/sh -c ''if test -e $kubeletkubeconfig; then stat -c %U:%G $kubeletkubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chown root:root $kubeletkubeconfig\n        scored: false\n\n      - id: 3.1.3\n        text: \"Ensure that the kubelet configuration file has permissions set to 644 or more restrictive (Manual)\"\n        audit: '/bin/sh -c ''if test -e $kubeletconf; then stat -c permissions=%a $kubeletconf; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the following command (using the config file location identified in the Audit step)\n          chmod 644 $kubeletconf\n        scored: false\n\n      - id: 3.1.4\n        text: \"Ensure that the kubelet configuration file ownership is set to root:root (Manual)\"\n        audit: '/bin/sh -c ''if test -e $kubeletconf; then stat -c %U:%G $kubeletconf; fi'' '\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the following command (using the config file location identified in the Audit step)\n          chown root:root $kubeletconf\n        scored: false\n\n  - id: 3.2\n    text: \"Kubelet\"\n    checks:\n      - id: 3.2.1\n        text: \"Ensure that the --anonymous-auth argument is set to false (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: \"--anonymous-auth\"\n              path: '{.authentication.anonymous.enabled}'\n              set: true\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          If using a Kubelet config file, edit the file to set authentication: anonymous: enabled to\n          false.\n          If using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --anonymous-auth=false\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 3.2.2\n        text: \"Ensure that the --authorization-mode argument is not set to AlwaysAllow (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --authorization-mode\n              path: '{.authorization.mode}'\n              set: true\n              compare:\n                op: nothave\n                value: AlwaysAllow\n        remediation: |\n          If using a Kubelet config file, edit the file to set authorization: mode to Webhook. If\n          using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_AUTHZ_ARGS variable.\n          --authorization-mode=Webhook\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 3.2.3\n        text: \"Ensure that the --client-ca-file argument is set as appropriate (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --client-ca-file\n              path: '{.authentication.x509.clientCAFile}'\n              set: true\n        remediation: |\n          If using a Kubelet config file, edit the file to set authentication: x509: clientCAFile to\n          the location of the client CA file.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_AUTHZ_ARGS variable.\n          --client-ca-file=<path/to/client-ca-file>\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 3.2.4\n        text: \"Ensure that the --read-only-port argument is set to 0 (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: \"--read-only-port\"\n              path: '{.readOnlyPort}'\n              set: true\n              compare:\n                op: eq\n                value: 0\n        remediation: |\n          If using a Kubelet config file, edit the file to set readOnlyPort to 0.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --read-only-port=0\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 3.2.5\n        text: \"Ensure that the --streaming-connection-idle-timeout argument is not set to 0 (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --streaming-connection-idle-timeout\n              path: '{.streamingConnectionIdleTimeout}'\n              set: true\n              compare:\n                op: noteq\n                value: 0\n            - flag: --streaming-connection-idle-timeout\n              path: '{.streamingConnectionIdleTimeout}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to set streamingConnectionIdleTimeout to a\n          value other than 0.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --streaming-connection-idle-timeout=5m\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 3.2.6\n        text: \"Ensure that the --protect-kernel-defaults argument is set to true (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --protect-kernel-defaults\n              path: '{.protectKernelDefaults}'\n              set: true\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          If using a Kubelet config file, edit the file to set protectKernelDefaults: true.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --protect-kernel-defaults=true\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 3.2.7\n        text: \"Ensure that the --make-iptables-util-chains argument is set to true (Automated) \"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --make-iptables-util-chains\n              path: '{.makeIPTablesUtilChains}'\n              set: true\n              compare:\n                op: eq\n                value: true\n            - flag: --make-iptables-util-chains\n              path: '{.makeIPTablesUtilChains}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to set makeIPTablesUtilChains: true.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          remove the --make-iptables-util-chains argument from the\n          KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 3.2.8\n        text: \"Ensure that the --hostname-override argument is not set (Manual)\"\n        # This is one of those properties that can only be set as a command line argument.\n        # To check if the property is set as expected, we need to parse the kubelet command\n        # instead reading the Kubelet Configuration file.\n        audit: \"/bin/ps -fC $kubeletbin \"\n        tests:\n          test_items:\n            - flag: --hostname-override\n              set: false\n        remediation: |\n          Edit the kubelet service file $kubeletsvc\n          on each worker node and remove the --hostname-override argument from the\n          KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 3.2.9\n        text: \"Ensure that the --eventRecordQPS argument is set to 0 or a level which ensures appropriate event capture (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --event-qps\n              path: '{.eventRecordQPS}'\n              set: true\n              compare:\n                op: eq\n                value: 0\n        remediation: |\n          If using a Kubelet config file, edit the file to set eventRecordQPS: to an appropriate level.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 3.2.10\n        text: \"Ensure that the --rotate-certificates argument is not set to false (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --rotate-certificates\n              path: '{.rotateCertificates}'\n              set: true\n              compare:\n                op: eq\n                value: true\n            - flag: --rotate-certificates\n              path: '{.rotateCertificates}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to add the line rotateCertificates: true or\n          remove it altogether to use the default value.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          remove --rotate-certificates=false argument from the KUBELET_CERTIFICATE_ARGS\n          variable.\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 3.2.11\n        text: \"Ensure that the RotateKubeletServerCertificate argument is set to true (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: RotateKubeletServerCertificate\n              path: '{.featureGates.RotateKubeletServerCertificate}'\n              set: true\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Edit the kubelet service file $kubeletsvc\n          on each worker node and set the below parameter in KUBELET_CERTIFICATE_ARGS variable.\n          --feature-gates=RotateKubeletServerCertificate=true\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n"
  },
  {
    "path": "cfg/eks-1.0.1/policies.yaml",
    "content": "---\ncontrols:\nversion: \"eks-1.0.1\"\nid: 4\ntext: \"Policies\"\ntype: \"policies\"\ngroups:\n  - id: 4.1\n    text: \"RBAC and Service Accounts\"\n    checks:\n      - id: 4.1.1\n        text: \"Ensure that the cluster-admin role is only used where required (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Identify all clusterrolebindings to the cluster-admin role. Check if they are used and\n          if they need this role or if they could use a role with fewer privileges.\n          Where possible, first bind users to a lower privileged role and then remove the\n          clusterrolebinding to the cluster-admin role :\n          kubectl delete clusterrolebinding [name]\n        scored: false\n\n      - id: 4.1.2\n        text: \"Minimize access to secrets (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove get, list and watch access to secret objects in the cluster.\n        scored: false\n\n      - id: 4.1.3\n        text: \"Minimize wildcard use in Roles and ClusterRoles (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible replace any use of wildcards in clusterroles and roles with specific\n          objects or actions.\n        scored: false\n\n      - id: 4.1.4\n        text: \"Minimize access to create pods (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove create access to pod objects in the cluster.\n        scored: false\n\n      - id: 4.1.5\n        text: \"Ensure that default service accounts are not actively used. (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Create explicit service accounts wherever a Kubernetes workload requires specific access\n          to the Kubernetes API server.\n          Modify the configuration of each default service account to include this value\n          automountServiceAccountToken: false\n        scored: false\n\n      - id: 4.1.6\n        text: \"Ensure that Service Account Tokens are only mounted where necessary (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Modify the definition of pods and service accounts which do not need to mount service\n          account tokens to disable it.\n        scored: false\n\n  - id: 4.2\n    text: \"Pod Security Policies\"\n    checks:\n      - id: 4.2.1\n        text: \"Minimize the admission of privileged containers (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that\n          the .spec.privileged field is omitted or set to false.\n        scored: false\n\n      - id: 4.2.2\n        text: \"Minimize the admission of containers wishing to share the host process ID namespace (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that the\n          .spec.hostPID field is omitted or set to false.\n        scored: false\n\n      - id: 4.2.3\n        text: \"Minimize the admission of containers wishing to share the host IPC namespace (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that the\n          .spec.hostIPC field is omitted or set to false.\n        scored: false\n\n      - id: 4.2.4\n        text: \"Minimize the admission of containers wishing to share the host network namespace (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that the\n          .spec.hostNetwork field is omitted or set to false.\n        scored: false\n\n      - id: 4.2.5\n        text: \"Minimize the admission of containers with allowPrivilegeEscalation (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that the\n          .spec.allowPrivilegeEscalation field is omitted or set to false.\n        scored: false\n\n      - id: 4.2.6\n        text: \"Minimize the admission of root containers (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that the\n          .spec.runAsUser.rule is set to either MustRunAsNonRoot or MustRunAs with the range of\n          UIDs not including 0.\n        scored: false\n\n      - id: 4.2.7\n        text: \"Minimize the admission of containers with the NET_RAW capability (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that the\n          .spec.requiredDropCapabilities is set to include either NET_RAW or ALL.\n        scored: false\n\n      - id: 4.2.8\n        text: \"Minimize the admission of containers with added capabilities (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that allowedCapabilities is not present in PSPs for the cluster unless\n          it is set to an empty array.\n        scored: false\n\n      - id: 4.2.9\n        text: \"Minimize the admission of containers with capabilities assigned (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Review the use of capabilities in applications running on your cluster. Where a namespace\n          contains applications which do not require any Linux capabities to operate consider adding\n          a PSP which forbids the admission of containers which do not drop all capabilities.\n        scored: false\n\n  - id: 4.3\n    text: \"CNI Plugin\"\n    checks:\n      - id: 4.3.1\n        text: \"Ensure that the latest CNI version is used (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Review the documentation of AWS CNI plugin, and ensure latest CNI version is used.\n        scored: false\n\n      - id: 4.3.2\n        text: \"Ensure that all Namespaces have Network Policies defined (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Follow the documentation and create NetworkPolicy objects as you need them.\n        scored: false\n\n  - id: 4.4\n    text: \"Secrets Management\"\n    checks:\n      - id: 4.4.1\n        text: \"Prefer using secrets as files over secrets as environment variables (Manual)\"\n        type: \"manual\"\n        remediation: |\n          If possible, rewrite application code to read secrets from mounted secret files, rather than\n          from environment variables.\n        scored: false\n\n      - id: 4.4.2\n        text: \"Consider external secret storage (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Refer to the secrets management options offered by your cloud provider or a third-party\n          secrets management solution.\n        scored: false\n\n  - id: 4.5\n    text: \"Extensible Admission Control\"\n    checks:\n      - id: 4.5.1\n        text: \"Configure Image Provenance using ImagePolicyWebhook admission controller (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and setup image provenance.\n        scored: false\n\n  - id: 4.6\n    text: \"General Policies\"\n    checks:\n      - id: 4.6.1\n        text: \"Create administrative boundaries between resources using namespaces (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the documentation and create namespaces for objects in your deployment as you need\n          them.\n        scored: false\n\n      - id: 4.6.2\n        text: \"Apply Security Context to Your Pods and Containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and apply security contexts to your pods. For a\n          suggested list of security contexts, you may refer to the CIS Security Benchmark for Docker\n          Containers.\n        scored: false\n\n      - id: 4.6.3\n        text: \"The default namespace should not be used (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that namespaces are created to allow for appropriate segregation of Kubernetes\n          resources and that all new resources are created in a specific namespace.\n        scored: false\n"
  },
  {
    "path": "cfg/eks-1.1.0/config.yaml",
    "content": "---\n## Version-specific settings that override the values in cfg/config.yaml\n## These settings are required if you are using the --asff option to report findings to AWS Security Hub\n## AWS account number is required.\nAWS_ACCOUNT: \"<AWS_ACCT_NUMBER>\"\n## AWS region is required.\nAWS_REGION: \"<AWS_REGION>\"\n## EKS Cluster ARN is required.\nCLUSTER_ARN: \"<AWS_CLUSTER_ARN>\"\n"
  },
  {
    "path": "cfg/eks-1.1.0/controlplane.yaml",
    "content": "---\ncontrols:\nversion: \"eks-1.1.0\"\nid: 2\ntext: \"Control Plane Configuration\"\ntype: \"controlplane\"\ngroups:\n  - id: 2.1\n    text: \"Logging\"\n    checks:\n      - id: 2.1.1\n        text: \"Enable audit logs (Manual)\"\n        remediation: \"Enable control plane logging for API Server, Audit, Authenticator, Controller Manager, and Scheduler.\"\n        scored: false\n"
  },
  {
    "path": "cfg/eks-1.1.0/managedservices.yaml",
    "content": "---\ncontrols:\nversion: \"eks-1.1.0\"\nid: 5\ntext: \"Managed Services\"\ntype: \"managedservices\"\ngroups:\n  - id: 5.1\n    text: \"Image Registry and Image Scanning\"\n    checks:\n      - id: 5.1.1\n        text: \"Ensure Image Vulnerability Scanning using Amazon ECR image scanning or a third-party provider (Manual)\"\n        type: \"manual\"\n        remediation: |\n          To utilize AWS ECR for Image scanning please follow the steps below:\n\n          To create a repository configured for scan on push (AWS CLI):\n          aws ecr create-repository --repository-name $REPO_NAME --image-scanning-configuration scanOnPush=true --region $REGION_CODE\n\n          To edit the settings of an existing repository (AWS CLI):\n          aws ecr put-image-scanning-configuration --repository-name $REPO_NAME --image-scanning-configuration scanOnPush=true --region $REGION_CODE\n\n          Use the following steps to start a manual image scan using the AWS Management Console.\n              Open the Amazon ECR console at https://console.aws.amazon.com/ecr/repositories.\n              From the navigation bar, choose the Region to create your repository in.\n              In the navigation pane, choose Repositories.\n              On the Repositories page, choose the repository that contains the image to scan.\n              On the Images page, select the image to scan and then choose Scan.\n        scored: false\n\n      - id: 5.1.2\n        text: \"Minimize user access to Amazon ECR (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Before you use IAM to manage access to Amazon ECR, you should understand what IAM features\n          are available to use with Amazon ECR. To get a high-level view of how Amazon ECR and other\n          AWS services work with IAM, see AWS Services That Work with IAM in the IAM User Guide.\n        scored: false\n\n      - id: 5.1.3\n        text: \"Minimize cluster access to read-only for Amazon ECR (Manual)\"\n        type: \"manual\"\n        remediation: |\n          You can use your Amazon ECR images with Amazon EKS, but you need to satisfy the following prerequisites.\n\n          The Amazon EKS worker node IAM role (NodeInstanceRole) that you use with your worker nodes must possess\n          the following IAM policy permissions for Amazon ECR.\n\n          {\n              \"Version\": \"2012-10-17\",\n              \"Statement\": [\n                  {\n                      \"Effect\": \"Allow\",\n                      \"Action\": [\n                          \"ecr:BatchCheckLayerAvailability\",\n                          \"ecr:BatchGetImage\",\n                          \"ecr:GetDownloadUrlForLayer\",\n                          \"ecr:GetAuthorizationToken\"\n                      ],\n                      \"Resource\": \"*\"\n                  }\n              ]\n          }\n        scored: false\n\n      - id: 5.1.4\n        text: \"Minimize Container Registries to only those approved (Manual)\"\n        type: \"manual\"\n        remediation: \"No remediation\"\n        scored: false\n\n  - id: 5.2\n    text: \"Identity and Access Management (IAM)\"\n    checks:\n      - id: 5.2.1\n        text: \"Prefer using dedicated Amazon EKS Service Accounts (Manual)\"\n        type: \"manual\"\n        remediation: \"No remediation\"\n        scored: false\n\n  - id: 5.3\n    text: \"AWS Key Management Service (KMS)\"\n    checks:\n      - id: 5.3.1\n        text: \"Ensure Kubernetes Secrets are encrypted using Customer Master Keys (CMKs) managed in AWS KMS (Manual)\"\n        type: \"manual\"\n        remediation: |\n          This process can only be performed during Cluster Creation.\n\n          Enable 'Secrets Encryption' during Amazon EKS cluster creation as described\n          in the links within the 'References' section.\n        scored: false\n\n  - id: 5.4\n    text: \"Cluster Networking\"\n    checks:\n      - id: 5.4.1\n        text: \"Restrict Access to the Control Plane Endpoint (Manual)\"\n        type: \"manual\"\n        remediation: \"No remediation\"\n        scored: false\n\n      - id: 5.4.2\n        text: \"Ensure clusters are created with Private Endpoint Enabled and Public Access Disabled (Manual)\"\n        type: \"manual\"\n        remediation: \"No remediation\"\n        scored: false\n\n      - id: 5.4.3\n        text: \"Ensure clusters are created with Private Nodes (Manual)\"\n        type: \"manual\"\n        remediation: \"No remediation\"\n        scored: false\n\n      - id: 5.4.4\n        text: \"Ensure Network Policy is Enabled and set as appropriate (Manual)\"\n        type: \"manual\"\n        remediation: \"No remediation\"\n        scored: false\n\n      - id: 5.4.5\n        text: \"Encrypt traffic to HTTPS load balancers with TLS certificates (Manual)\"\n        type: \"manual\"\n        remediation: \"No remediation\"\n        scored: false\n\n\n  - id: 5.5\n    text: \"Authentication and Authorization\"\n    checks:\n      - id: 5.5.1\n        text: \"Manage Kubernetes RBAC users with AWS IAM Authenticator for Kubernetes (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Refer to the 'Managing users or IAM roles for your cluster' in Amazon EKS documentation.\n        scored: false\n\n\n  - id: 5.6\n    text: \"Other Cluster Configurations\"\n    checks:\n      - id: 5.6.1\n        text: \"Consider Fargate for running untrusted workloads (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Create a Fargate profile for your cluster Before you can schedule pods running on Fargate\n          in your cluster, you must define a Fargate profile that specifies which pods should use\n          Fargate when they are launched. For more information, see AWS Fargate profile.\n\n          Note: If you created your cluster with eksctl using the --fargate option, then a Fargate profile has\n          already been created for your cluster with selectors for all pods in the kube-system\n          and default namespaces. Use the following procedure to create Fargate profiles for\n          any other namespaces you would like to use with Fargate.\n        scored: false\n"
  },
  {
    "path": "cfg/eks-1.1.0/master.yaml",
    "content": "---\ncontrols:\nversion: \"eks-1.1.0\"\nid: 1\ntext: \"Control Plane Components\"\ntype: \"master\"\n"
  },
  {
    "path": "cfg/eks-1.1.0/node.yaml",
    "content": "---\ncontrols:\nversion: \"eks-1.1.0\"\nid: 3\ntext: \"Worker Node Security Configuration\"\ntype: \"node\"\ngroups:\n  - id: 3.1\n    text: \"Worker Node Configuration Files\"\n    checks:\n      - id: 3.1.1\n        text: \"Ensure that the kubeconfig file permissions are set to 644 or more restrictive (Manual)\"\n        audit: '/bin/sh -c ''if test -e $kubeletkubeconfig; then stat -c permissions=%a $kubeletkubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chmod 644 $kubeletkubeconfig\n        scored: false\n\n      - id: 3.1.2\n        text: \"Ensure that the kubelet kubeconfig file ownership is set to root:root (Manual)\"\n        audit: '/bin/sh -c ''if test -e $kubeletkubeconfig; then stat -c %U:%G $kubeletkubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chown root:root $kubeletkubeconfig\n        scored: false\n\n      - id: 3.1.3\n        text: \"Ensure that the kubelet configuration file has permissions set to 644 or more restrictive (Manual)\"\n        audit: '/bin/sh -c ''if test -e $kubeletconf; then stat -c permissions=%a $kubeletconf; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the following command (using the config file location identified in the Audit step)\n          chmod 644 $kubeletconf\n        scored: false\n\n      - id: 3.1.4\n        text: \"Ensure that the kubelet configuration file ownership is set to root:root (Manual)\"\n        audit: '/bin/sh -c ''if test -e $kubeletconf; then stat -c %U:%G $kubeletconf; fi'' '\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the following command (using the config file location identified in the Audit step)\n          chown root:root $kubeletconf\n        scored: false\n\n  - id: 3.2\n    text: \"Kubelet\"\n    checks:\n      - id: 3.2.1\n        text: \"Ensure that the --anonymous-auth argument is set to false (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: \"--anonymous-auth\"\n              path: '{.authentication.anonymous.enabled}'\n              set: true\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          If using a Kubelet config file, edit the file to set authentication: anonymous: enabled to\n          false.\n          If using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --anonymous-auth=false\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 3.2.2\n        text: \"Ensure that the --authorization-mode argument is not set to AlwaysAllow (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --authorization-mode\n              path: '{.authorization.mode}'\n              set: true\n              compare:\n                op: nothave\n                value: AlwaysAllow\n        remediation: |\n          If using a Kubelet config file, edit the file to set authorization: mode to Webhook. If\n          using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_AUTHZ_ARGS variable.\n          --authorization-mode=Webhook\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 3.2.3\n        text: \"Ensure that the --client-ca-file argument is set as appropriate (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --client-ca-file\n              path: '{.authentication.x509.clientCAFile}'\n              set: true\n        remediation: |\n          If using a Kubelet config file, edit the file to set authentication: x509: clientCAFile to\n          the location of the client CA file.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_AUTHZ_ARGS variable.\n          --client-ca-file=<path/to/client-ca-file>\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 3.2.4\n        text: \"Ensure that the --read-only-port argument is set to 0 (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: \"--read-only-port\"\n              path: '{.readOnlyPort}'\n              set: true\n              compare:\n                op: eq\n                value: 0\n        remediation: |\n          If using a Kubelet config file, edit the file to set readOnlyPort to 0.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --read-only-port=0\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 3.2.5\n        text: \"Ensure that the --streaming-connection-idle-timeout argument is not set to 0 (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --streaming-connection-idle-timeout\n              path: '{.streamingConnectionIdleTimeout}'\n              set: true\n              compare:\n                op: noteq\n                value: 0\n            - flag: --streaming-connection-idle-timeout\n              path: '{.streamingConnectionIdleTimeout}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to set streamingConnectionIdleTimeout to a\n          value other than 0.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --streaming-connection-idle-timeout=5m\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 3.2.6\n        text: \"Ensure that the --protect-kernel-defaults argument is set to true (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --protect-kernel-defaults\n              path: '{.protectKernelDefaults}'\n              set: true\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          If using a Kubelet config file, edit the file to set protectKernelDefaults: true.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --protect-kernel-defaults=true\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 3.2.7\n        text: \"Ensure that the --make-iptables-util-chains argument is set to true (Automated) \"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --make-iptables-util-chains\n              path: '{.makeIPTablesUtilChains}'\n              set: true\n              compare:\n                op: eq\n                value: true\n            - flag: --make-iptables-util-chains\n              path: '{.makeIPTablesUtilChains}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to set makeIPTablesUtilChains: true.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          remove the --make-iptables-util-chains argument from the\n          KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 3.2.8\n        text: \"Ensure that the --hostname-override argument is not set (Manual)\"\n        # This is one of those properties that can only be set as a command line argument.\n        # To check if the property is set as expected, we need to parse the kubelet command\n        # instead reading the Kubelet Configuration file.\n        audit: \"/bin/ps -fC $kubeletbin \"\n        tests:\n          test_items:\n            - flag: --hostname-override\n              set: false\n        remediation: |\n          Edit the kubelet service file $kubeletsvc\n          on each worker node and remove the --hostname-override argument from the\n          KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 3.2.9\n        text: \"Ensure that the --eventRecordQPS argument is set to 0 or a level which ensures appropriate event capture (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --event-qps\n              path: '{.eventRecordQPS}'\n              set: true\n              compare:\n                op: eq\n                value: 0\n        remediation: |\n          If using a Kubelet config file, edit the file to set eventRecordQPS: to an appropriate level.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 3.2.10\n        text: \"Ensure that the --rotate-certificates argument is not set to false (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --rotate-certificates\n              path: '{.rotateCertificates}'\n              set: true\n              compare:\n                op: eq\n                value: true\n            - flag: --rotate-certificates\n              path: '{.rotateCertificates}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to add the line rotateCertificates: true or\n          remove it altogether to use the default value.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          remove --rotate-certificates=false argument from the KUBELET_CERTIFICATE_ARGS\n          variable.\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 3.2.11\n        text: \"Ensure that the RotateKubeletServerCertificate argument is set to true (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: RotateKubeletServerCertificate\n              path: '{.featureGates.RotateKubeletServerCertificate}'\n              set: true\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Edit the kubelet service file $kubeletsvc\n          on each worker node and set the below parameter in KUBELET_CERTIFICATE_ARGS variable.\n          --feature-gates=RotateKubeletServerCertificate=true\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n  - id: 3.3\n    text: \"Container Optimized OS\"\n    checks:\n      - id: 3.3.1\n        text: \"Prefer using Container-Optimized OS when possible (Manual)\"\n        remediation: \"No remediation\"\n        scored: false\n"
  },
  {
    "path": "cfg/eks-1.1.0/policies.yaml",
    "content": "---\ncontrols:\nversion: \"eks-1.1.0\"\nid: 4\ntext: \"Policies\"\ntype: \"policies\"\ngroups:\n  - id: 4.1\n    text: \"RBAC and Service Accounts\"\n    checks:\n      - id: 4.1.1\n        text: \"Ensure that the cluster-admin role is only used where required (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Identify all clusterrolebindings to the cluster-admin role. Check if they are used and\n          if they need this role or if they could use a role with fewer privileges.\n          Where possible, first bind users to a lower privileged role and then remove the\n          clusterrolebinding to the cluster-admin role :\n          kubectl delete clusterrolebinding [name]\n        scored: false\n\n      - id: 4.1.2\n        text: \"Minimize access to secrets (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove get, list and watch access to secret objects in the cluster.\n        scored: false\n\n      - id: 4.1.3\n        text: \"Minimize wildcard use in Roles and ClusterRoles (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible replace any use of wildcards in clusterroles and roles with specific\n          objects or actions.\n        scored: false\n\n      - id: 4.1.4\n        text: \"Minimize access to create pods (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove create access to pod objects in the cluster.\n        scored: false\n\n      - id: 4.1.5\n        text: \"Ensure that default service accounts are not actively used. (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Create explicit service accounts wherever a Kubernetes workload requires specific access\n          to the Kubernetes API server.\n          Modify the configuration of each default service account to include this value\n          automountServiceAccountToken: false\n        scored: false\n\n      - id: 4.1.6\n        text: \"Ensure that Service Account Tokens are only mounted where necessary (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Modify the definition of pods and service accounts which do not need to mount service\n          account tokens to disable it.\n        scored: false\n\n  - id: 4.2\n    text: \"Pod Security Policies\"\n    checks:\n      - id: 4.2.1\n        text: \"Minimize the admission of privileged containers (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that\n          the .spec.privileged field is omitted or set to false.\n        scored: false\n\n      - id: 4.2.2\n        text: \"Minimize the admission of containers wishing to share the host process ID namespace (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that the\n          .spec.hostPID field is omitted or set to false.\n        scored: false\n\n      - id: 4.2.3\n        text: \"Minimize the admission of containers wishing to share the host IPC namespace (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that the\n          .spec.hostIPC field is omitted or set to false.\n        scored: false\n\n      - id: 4.2.4\n        text: \"Minimize the admission of containers wishing to share the host network namespace (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that the\n          .spec.hostNetwork field is omitted or set to false.\n        scored: false\n\n      - id: 4.2.5\n        text: \"Minimize the admission of containers with allowPrivilegeEscalation (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that the\n          .spec.allowPrivilegeEscalation field is omitted or set to false.\n        scored: false\n\n      - id: 4.2.6\n        text: \"Minimize the admission of root containers (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that the\n          .spec.runAsUser.rule is set to either MustRunAsNonRoot or MustRunAs with the range of\n          UIDs not including 0.\n        scored: false\n\n      - id: 4.2.7\n        text: \"Minimize the admission of containers with the NET_RAW capability (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that the\n          .spec.requiredDropCapabilities is set to include either NET_RAW or ALL.\n        scored: false\n\n      - id: 4.2.8\n        text: \"Minimize the admission of containers with added capabilities (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that allowedCapabilities is not present in PSPs for the cluster unless\n          it is set to an empty array.\n        scored: false\n\n      - id: 4.2.9\n        text: \"Minimize the admission of containers with capabilities assigned (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Review the use of capabilities in applications running on your cluster. Where a namespace\n          contains applications which do not require any Linux capabities to operate consider adding\n          a PSP which forbids the admission of containers which do not drop all capabilities.\n        scored: false\n\n  - id: 4.3\n    text: \"CNI Plugin\"\n    checks:\n      - id: 4.3.1\n        text: \"Ensure that the latest CNI version is used (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Review the documentation of AWS CNI plugin, and ensure latest CNI version is used.\n        scored: false\n\n      - id: 4.3.2\n        text: \"Ensure that all Namespaces have Network Policies defined (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the documentation and create NetworkPolicy objects as you need them.\n        scored: false\n\n  - id: 4.4\n    text: \"Secrets Management\"\n    checks:\n      - id: 4.4.1\n        text: \"Prefer using secrets as files over secrets as environment variables (Manual)\"\n        type: \"manual\"\n        remediation: |\n          If possible, rewrite application code to read secrets from mounted secret files, rather than\n          from environment variables.\n        scored: false\n\n      - id: 4.4.2\n        text: \"Consider external secret storage (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Refer to the secrets management options offered by your cloud provider or a third-party\n          secrets management solution.\n        scored: false\n\n  - id: 4.5\n    text: \"Extensible Admission Control\"\n    checks: []\n\n  - id: 4.6\n    text: \"General Policies\"\n    checks:\n      - id: 4.6.1\n        text: \"Create administrative boundaries between resources using namespaces (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the documentation and create namespaces for objects in your deployment as you need\n          them.\n        scored: false\n\n      - id: 4.6.2\n        text: \"Apply Security Context to Your Pods and Containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and apply security contexts to your pods. For a\n          suggested list of security contexts, you may refer to the CIS Security Benchmark for Docker\n          Containers.\n        scored: false\n\n      - id: 4.6.3\n        text: \"The default namespace should not be used (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that namespaces are created to allow for appropriate segregation of Kubernetes\n          resources and that all new resources are created in a specific namespace.\n        scored: false\n"
  },
  {
    "path": "cfg/eks-1.2.0/config.yaml",
    "content": "---\n## Version-specific settings that override the values in cfg/config.yaml\n## These settings are required if you are using the --asff option to report findings to AWS Security Hub\n## AWS account number is required.\nAWS_ACCOUNT: \"<AWS_ACCT_NUMBER>\"\n## AWS region is required.\nAWS_REGION: \"<AWS_REGION>\"\n## EKS Cluster ARN is required.\nCLUSTER_ARN: \"<AWS_CLUSTER_ARN>\"\n"
  },
  {
    "path": "cfg/eks-1.2.0/controlplane.yaml",
    "content": "---\ncontrols:\nversion: \"eks-1.2.0\"\nid: 2\ntext: \"Control Plane Configuration\"\ntype: \"controlplane\"\ngroups:\n  - id: 2.1\n    text: \"Logging\"\n    checks:\n      - id: 2.1.1\n        text: \"Enable audit logs (Manual)\"\n        remediation: \"Enable control plane logging for API Server, Audit, Authenticator, Controller Manager, and Scheduler.\"\n        scored: false\n"
  },
  {
    "path": "cfg/eks-1.2.0/managedservices.yaml",
    "content": "---\ncontrols:\nversion: \"eks-1.2.0\"\nid: 5\ntext: \"Managed Services\"\ntype: \"managedservices\"\ngroups:\n  - id: 5.1\n    text: \"Image Registry and Image Scanning\"\n    checks:\n      - id: 5.1.1\n        text: \"Ensure Image Vulnerability Scanning using Amazon ECR image scanning or a third-party provider (Manual)\"\n        type: \"manual\"\n        remediation: |\n          To utilize AWS ECR for Image scanning please follow the steps below:\n\n          To create a repository configured for scan on push (AWS CLI):\n          aws ecr create-repository --repository-name $REPO_NAME --image-scanning-configuration scanOnPush=true --region $REGION_CODE\n\n          To edit the settings of an existing repository (AWS CLI):\n          aws ecr put-image-scanning-configuration --repository-name $REPO_NAME --image-scanning-configuration scanOnPush=true --region $REGION_CODE\n\n          Use the following steps to start a manual image scan using the AWS Management Console.\n              Open the Amazon ECR console at https://console.aws.amazon.com/ecr/repositories.\n              From the navigation bar, choose the Region to create your repository in.\n              In the navigation pane, choose Repositories.\n              On the Repositories page, choose the repository that contains the image to scan.\n              On the Images page, select the image to scan and then choose Scan.\n        scored: false\n\n      - id: 5.1.2\n        text: \"Minimize user access to Amazon ECR (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Before you use IAM to manage access to Amazon ECR, you should understand what IAM features\n          are available to use with Amazon ECR. To get a high-level view of how Amazon ECR and other\n          AWS services work with IAM, see AWS Services That Work with IAM in the IAM User Guide.\n        scored: false\n\n      - id: 5.1.3\n        text: \"Minimize cluster access to read-only for Amazon ECR (Manual)\"\n        type: \"manual\"\n        remediation: |\n          You can use your Amazon ECR images with Amazon EKS, but you need to satisfy the following prerequisites.\n\n          The Amazon EKS worker node IAM role (NodeInstanceRole) that you use with your worker nodes must possess\n          the following IAM policy permissions for Amazon ECR.\n\n          {\n              \"Version\": \"2012-10-17\",\n              \"Statement\": [\n                  {\n                      \"Effect\": \"Allow\",\n                      \"Action\": [\n                          \"ecr:BatchCheckLayerAvailability\",\n                          \"ecr:BatchGetImage\",\n                          \"ecr:GetDownloadUrlForLayer\",\n                          \"ecr:GetAuthorizationToken\"\n                      ],\n                      \"Resource\": \"*\"\n                  }\n              ]\n          }\n        scored: false\n\n      - id: 5.1.4\n        text: \"Minimize Container Registries to only those approved (Manual)\"\n        type: \"manual\"\n        remediation: \"No remediation\"\n        scored: false\n\n  - id: 5.2\n    text: \"Identity and Access Management (IAM)\"\n    checks:\n      - id: 5.2.1\n        text: \"Prefer using dedicated Amazon EKS Service Accounts (Manual)\"\n        type: \"manual\"\n        remediation: \"No remediation\"\n        scored: false\n\n  - id: 5.3\n    text: \"AWS Key Management Service (KMS)\"\n    checks:\n      - id: 5.3.1\n        text: \"Ensure Kubernetes Secrets are encrypted using Customer Master Keys (CMKs) managed in AWS KMS (Manual)\"\n        type: \"manual\"\n        remediation: |\n          This process can only be performed during Cluster Creation.\n\n          Enable 'Secrets Encryption' during Amazon EKS cluster creation as described\n          in the links within the 'References' section.\n        scored: false\n\n  - id: 5.4\n    text: \"Cluster Networking\"\n    checks:\n      - id: 5.4.1\n        text: \"Restrict Access to the Control Plane Endpoint (Manual)\"\n        type: \"manual\"\n        remediation: \"No remediation\"\n        scored: false\n\n      - id: 5.4.2\n        text: \"Ensure clusters are created with Private Endpoint Enabled and Public Access Disabled (Manual)\"\n        type: \"manual\"\n        remediation: \"No remediation\"\n        scored: false\n\n      - id: 5.4.3\n        text: \"Ensure clusters are created with Private Nodes (Manual)\"\n        type: \"manual\"\n        remediation: \"No remediation\"\n        scored: false\n\n      - id: 5.4.4\n        text: \"Ensure Network Policy is Enabled and set as appropriate (Manual)\"\n        type: \"manual\"\n        remediation: \"No remediation\"\n        scored: false\n\n      - id: 5.4.5\n        text: \"Encrypt traffic to HTTPS load balancers with TLS certificates (Manual)\"\n        type: \"manual\"\n        remediation: \"No remediation\"\n        scored: false\n\n\n  - id: 5.5\n    text: \"Authentication and Authorization\"\n    checks:\n      - id: 5.5.1\n        text: \"Manage Kubernetes RBAC users with AWS IAM Authenticator for Kubernetes (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Refer to the 'Managing users or IAM roles for your cluster' in Amazon EKS documentation.\n        scored: false\n\n\n  - id: 5.6\n    text: \"Other Cluster Configurations\"\n    checks:\n      - id: 5.6.1\n        text: \"Consider Fargate for running untrusted workloads (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Create a Fargate profile for your cluster Before you can schedule pods running on Fargate\n          in your cluster, you must define a Fargate profile that specifies which pods should use\n          Fargate when they are launched. For more information, see AWS Fargate profile.\n\n          Note: If you created your cluster with eksctl using the --fargate option, then a Fargate profile has\n          already been created for your cluster with selectors for all pods in the kube-system\n          and default namespaces. Use the following procedure to create Fargate profiles for\n          any other namespaces you would like to use with Fargate.\n        scored: false\n"
  },
  {
    "path": "cfg/eks-1.2.0/master.yaml",
    "content": "---\ncontrols:\nversion: \"eks-1.2.0\"\nid: 1\ntext: \"Control Plane Components\"\ntype: \"master\"\n"
  },
  {
    "path": "cfg/eks-1.2.0/node.yaml",
    "content": "---\ncontrols:\nversion: \"eks-1.2.0\"\nid: 3\ntext: \"Worker Node Security Configuration\"\ntype: \"node\"\ngroups:\n  - id: 3.1\n    text: \"Worker Node Configuration Files\"\n    checks:\n      - id: 3.1.1\n        text: \"Ensure that the kubeconfig file permissions are set to 644 or more restrictive (Manual)\"\n        audit: '/bin/sh -c ''if test -e $kubeletkubeconfig; then stat -c permissions=%a $kubeletkubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chmod 644 $kubeletkubeconfig\n        scored: false\n\n      - id: 3.1.2\n        text: \"Ensure that the kubelet kubeconfig file ownership is set to root:root (Manual)\"\n        audit: '/bin/sh -c ''if test -e $kubeletkubeconfig; then stat -c %U:%G $kubeletkubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chown root:root $kubeletkubeconfig\n        scored: false\n\n      - id: 3.1.3\n        text: \"Ensure that the kubelet configuration file has permissions set to 644 or more restrictive (Manual)\"\n        audit: '/bin/sh -c ''if test -e $kubeletconf; then stat -c permissions=%a $kubeletconf; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the following command (using the config file location identified in the Audit step)\n          chmod 644 $kubeletconf\n        scored: false\n\n      - id: 3.1.4\n        text: \"Ensure that the kubelet configuration file ownership is set to root:root (Manual)\"\n        audit: '/bin/sh -c ''if test -e $kubeletconf; then stat -c %U:%G $kubeletconf; fi'' '\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the following command (using the config file location identified in the Audit step)\n          chown root:root $kubeletconf\n        scored: false\n\n  - id: 3.2\n    text: \"Kubelet\"\n    checks:\n      - id: 3.2.1\n        text: \"Ensure that the Anonymous Auth is Not Enabled (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: \"--anonymous-auth\"\n              path: '{.authentication.anonymous.enabled}'\n              set: true\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          If using a Kubelet config file, edit the file to set authentication: anonymous: enabled to\n          false.\n          If using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --anonymous-auth=false\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 3.2.2\n        text: \"Ensure that the --authorization-mode argument is not set to AlwaysAllow (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --authorization-mode\n              path: '{.authorization.mode}'\n              set: true\n              compare:\n                op: nothave\n                value: AlwaysAllow\n        remediation: |\n          If using a Kubelet config file, edit the file to set authorization: mode to Webhook. If\n          using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_AUTHZ_ARGS variable.\n          --authorization-mode=Webhook\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 3.2.3\n        text: \"Ensure that a Client CA File is Configured (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --client-ca-file\n              path: '{.authentication.x509.clientCAFile}'\n              set: true\n        remediation: |\n          If using a Kubelet config file, edit the file to set authentication: x509: clientCAFile to\n          the location of the client CA file.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_AUTHZ_ARGS variable.\n          --client-ca-file=<path/to/client-ca-file>\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 3.2.4\n        text: \"Ensure that the --read-only-port is disabled (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: \"--read-only-port\"\n              path: '{.readOnlyPort}'\n              set: true\n              compare:\n                op: eq\n                value: 0\n        remediation: |\n          If using a Kubelet config file, edit the file to set readOnlyPort to 0.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --read-only-port=0\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 3.2.5\n        text: \"Ensure that the --streaming-connection-idle-timeout argument is not set to 0 (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --streaming-connection-idle-timeout\n              path: '{.streamingConnectionIdleTimeout}'\n              set: true\n              compare:\n                op: noteq\n                value: 0\n            - flag: --streaming-connection-idle-timeout\n              path: '{.streamingConnectionIdleTimeout}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to set streamingConnectionIdleTimeout to a\n          value other than 0.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --streaming-connection-idle-timeout=5m\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 3.2.6\n        text: \"Ensure that the --protect-kernel-defaults argument is set to true (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --protect-kernel-defaults\n              path: '{.protectKernelDefaults}'\n              set: true\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          If using a Kubelet config file, edit the file to set protectKernelDefaults: true.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --protect-kernel-defaults=true\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 3.2.7\n        text: \"Ensure that the --make-iptables-util-chains argument is set to true (Automated) \"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --make-iptables-util-chains\n              path: '{.makeIPTablesUtilChains}'\n              set: true\n              compare:\n                op: eq\n                value: true\n            - flag: --make-iptables-util-chains\n              path: '{.makeIPTablesUtilChains}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to set makeIPTablesUtilChains: true.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          remove the --make-iptables-util-chains argument from the\n          KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 3.2.8\n        text: \"Ensure that the --hostname-override argument is not set (Manual)\"\n        # This is one of those properties that can only be set as a command line argument.\n        # To check if the property is set as expected, we need to parse the kubelet command\n        # instead reading the Kubelet Configuration file.\n        audit: \"/bin/ps -fC $kubeletbin \"\n        tests:\n          test_items:\n            - flag: --hostname-override\n              set: false\n        remediation: |\n          Edit the kubelet service file $kubeletsvc\n          on each worker node and remove the --hostname-override argument from the\n          KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 3.2.9\n        text: \"Ensure that the --eventRecordQPS argument is set to 0 or a level which ensures appropriate event capture (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --event-qps\n              path: '{.eventRecordQPS}'\n              set: true\n              compare:\n                op: gte\n                value: 0\n        remediation: |\n          If using a Kubelet config file, edit the file to set eventRecordQPS: to an appropriate level.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 3.2.10\n        text: \"Ensure that the --rotate-certificates argument is not present or is set to true (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --rotate-certificates\n              path: '{.rotateCertificates}'\n              set: true\n              compare:\n                op: eq\n                value: true\n            - flag: --rotate-certificates\n              path: '{.rotateCertificates}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to add the line rotateCertificates: true or\n          remove it altogether to use the default value.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          remove --rotate-certificates=false argument from the KUBELET_CERTIFICATE_ARGS\n          variable.\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 3.2.11\n        text: \"Ensure that the RotateKubeletServerCertificate argument is set to true (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: RotateKubeletServerCertificate\n              path: '{.featureGates.RotateKubeletServerCertificate}'\n              set: true\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Edit the kubelet service file $kubeletsvc\n          on each worker node and set the below parameter in KUBELET_CERTIFICATE_ARGS variable.\n          --feature-gates=RotateKubeletServerCertificate=true\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n  - id: 3.3\n    text: \"Container Optimized OS\"\n    checks:\n      - id: 3.3.1\n        text: \"Prefer using a container-optimized OS when possible (Manual)\"\n        remediation: \"No remediation\"\n        scored: false\n"
  },
  {
    "path": "cfg/eks-1.2.0/policies.yaml",
    "content": "---\ncontrols:\nversion: \"eks-1.2.0\"\nid: 4\ntext: \"Policies\"\ntype: \"policies\"\ngroups:\n  - id: 4.1\n    text: \"RBAC and Service Accounts\"\n    checks:\n      - id: 4.1.1\n        text: \"Ensure that the cluster-admin role is only used where required (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Identify all clusterrolebindings to the cluster-admin role. Check if they are used and\n          if they need this role or if they could use a role with fewer privileges.\n          Where possible, first bind users to a lower privileged role and then remove the\n          clusterrolebinding to the cluster-admin role :\n          kubectl delete clusterrolebinding [name]\n        scored: false\n\n      - id: 4.1.2\n        text: \"Minimize access to secrets (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove get, list and watch access to secret objects in the cluster.\n        scored: false\n\n      - id: 4.1.3\n        text: \"Minimize wildcard use in Roles and ClusterRoles (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible replace any use of wildcards in clusterroles and roles with specific\n          objects or actions.\n        scored: false\n\n      - id: 4.1.4\n        text: \"Minimize access to create pods (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove create access to pod objects in the cluster.\n        scored: false\n\n      - id: 4.1.5\n        text: \"Ensure that default service accounts are not actively used. (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Create explicit service accounts wherever a Kubernetes workload requires specific access\n          to the Kubernetes API server.\n          Modify the configuration of each default service account to include this value\n          automountServiceAccountToken: false\n        scored: false\n\n      - id: 4.1.6\n        text: \"Ensure that Service Account Tokens are only mounted where necessary (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Modify the definition of pods and service accounts which do not need to mount service\n          account tokens to disable it.\n        scored: false\n\n      - id: 4.1.7\n        text: \"Avoid use of system:masters group (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Remove the system:masters group from all users in the cluster.\n        scored: false\n\n      - id: 4.1.8\n        text: \"Limit use of the Bind, Impersonate and Escalate permissions in the Kubernetes cluster (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove the impersonate, bind and escalate rights from subjects.\n        scored: false\n\n  - id: 4.2\n    text: \"Pod Security Policies\"\n    checks:\n      - id: 4.2.1\n        text: \"Minimize the admission of privileged containers (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that\n          the .spec.privileged field is omitted or set to false.\n        scored: false\n\n      - id: 4.2.2\n        text: \"Minimize the admission of containers wishing to share the host process ID namespace (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that the\n          .spec.hostPID field is omitted or set to false.\n        scored: false\n\n      - id: 4.2.3\n        text: \"Minimize the admission of containers wishing to share the host IPC namespace (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that the\n          .spec.hostIPC field is omitted or set to false.\n        scored: false\n\n      - id: 4.2.4\n        text: \"Minimize the admission of containers wishing to share the host network namespace (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that the\n          .spec.hostNetwork field is omitted or set to false.\n        scored: false\n\n      - id: 4.2.5\n        text: \"Minimize the admission of containers with allowPrivilegeEscalation (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that the\n          .spec.allowPrivilegeEscalation field is omitted or set to false.\n        scored: false\n\n      - id: 4.2.6\n        text: \"Minimize the admission of root containers (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that the\n          .spec.runAsUser.rule is set to either MustRunAsNonRoot or MustRunAs with the range of\n          UIDs not including 0.\n        scored: false\n\n      - id: 4.2.7\n        text: \"Minimize the admission of containers with added capabilities (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that allowedCapabilities is not present in PSPs for the cluster unless\n          it is set to an empty array.\n        scored: false\n\n      - id: 4.2.8\n        text: \"Minimize the admission of containers with capabilities assigned (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Review the use of capabilities in applications running on your cluster. Where a namespace\n          contains applications which do not require any Linux capabities to operate consider adding\n          a PSP which forbids the admission of containers which do not drop all capabilities.\n        scored: false\n\n  - id: 4.3\n    text: \"CNI Plugin\"\n    checks:\n      - id: 4.3.1\n        text: \"Ensure CNI plugin supports network policies (Manual)\"\n        type: \"manual\"\n        remediation: |\n          As with RBAC policies, network policies should adhere to the policy of least privileged\n          access. Start by creating a deny all policy that restricts all inbound and outbound traffic\n          from a namespace or create a global policy using Calico.\n        scored: false\n\n      - id: 4.3.2\n        text: \"Ensure that all Namespaces have Network Policies defined (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the documentation and create NetworkPolicy objects as you need them.\n        scored: false\n\n  - id: 4.4\n    text: \"Secrets Management\"\n    checks:\n      - id: 4.4.1\n        text: \"Prefer using secrets as files over secrets as environment variables (Manual)\"\n        type: \"manual\"\n        remediation: |\n          If possible, rewrite application code to read secrets from mounted secret files, rather than\n          from environment variables.\n        scored: false\n\n      - id: 4.4.2\n        text: \"Consider external secret storage (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Refer to the secrets management options offered by your cloud provider or a third-party\n          secrets management solution.\n        scored: false\n\n  - id: 4.5\n    text: \"Extensible Admission Control\"\n    checks: []\n\n  - id: 4.6\n    text: \"General Policies\"\n    checks:\n      - id: 4.6.1\n        text: \"Create administrative boundaries between resources using namespaces (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the documentation and create namespaces for objects in your deployment as you need\n          them.\n        scored: false\n\n      - id: 4.6.2\n        text: \"Apply Security Context to Your Pods and Containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and apply security contexts to your pods. For a\n          suggested list of security contexts, you may refer to the CIS Security Benchmark for Docker\n          Containers.\n        scored: false\n\n      - id: 4.6.3\n        text: \"The default namespace should not be used (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that namespaces are created to allow for appropriate segregation of Kubernetes\n          resources and that all new resources are created in a specific namespace.\n        scored: false\n"
  },
  {
    "path": "cfg/eks-1.5.0/config.yaml",
    "content": "---\n## Version-specific settings that override the values in cfg/config.yaml\n## These settings are required if you are using the --asff option to report findings to AWS Security Hub\n## AWS account number is required.\nAWS_ACCOUNT: \"<AWS_ACCT_NUMBER>\"\n## AWS region is required.\nAWS_REGION: \"<AWS_REGION>\"\n## EKS Cluster ARN is required.\nCLUSTER_ARN: \"<AWS_CLUSTER_ARN>\"\n"
  },
  {
    "path": "cfg/eks-1.5.0/controlplane.yaml",
    "content": "---\ncontrols:\nversion: \"eks-1.5.0\"\nid: 2\ntext: \"Control Plane Configuration\"\ntype: \"controlplane\"\ngroups:\n  - id: 2.1\n    text: \"Logging\"\n    checks:\n      - id: 2.1.1\n        text: \"Enable audit Logs (Automated)\"\n        remediation: |\n          From Console:\n          1.  For each EKS Cluster in each region;\n          2.  Go to 'Amazon EKS' > 'Clusters' > '' > 'Configuration' > 'Logging'.\n          3.  Click 'Manage logging'.\n          4.  Ensure that all options are toggled to 'Enabled'.\n                API server: Enabled\n                Audit: Enabled\n                Authenticator: Enabled\n                Controller manager: Enabled\n                Scheduler: Enabled\n          5.  Click 'Save Changes'.\n\n          From CLI:\n          # For each EKS Cluster in each region;\n          aws eks update-cluster-config \\\n            --region '${REGION_CODE}' \\\n            --name '${CLUSTER_NAME}' \\\n            --logging '{\"clusterLogging\":[{\"types\":[\"api\",\"audit\",\"authenticator\",\"controllerManager\",\"scheduler\"],\"enabled\":true}]}'\n        scored: false\n"
  },
  {
    "path": "cfg/eks-1.5.0/managedservices.yaml",
    "content": "---\ncontrols:\nversion: \"eks-1.5.0\"\nid: 5\ntext: \"Managed Services\"\ntype: \"managedservices\"\ngroups:\n  - id: 5.1\n    text: \"Image Registry and Image Scanning\"\n    checks:\n      - id: 5.1.1\n        text: \"Ensure Image Vulnerability Scanning using Amazon ECR image scanning or a third party provider (Automated)\"\n        type: \"manual\"\n        remediation: |\n          To utilize AWS ECR for Image scanning please follow the steps below:\n\n          To create a repository configured for scan on push (AWS CLI):\n          aws ecr create-repository --repository-name $REPO_NAME --image-scanning-configuration scanOnPush=true --region $REGION_CODE\n\n          To edit the settings of an existing repository (AWS CLI):\n          aws ecr put-image-scanning-configuration --repository-name $REPO_NAME --image-scanning-configuration scanOnPush=true --region $REGION_CODE\n\n          Use the following steps to start a manual image scan using the AWS Management Console.\n\n          1.  Open the Amazon ECR console at https://console.aws.amazon.com/ecr/repositories.\n          2.  From the navigation bar, choose the Region to create your repository in.\n          3.  In the navigation pane, choose Repositories.\n          4.  On the Repositories page, choose the repository that contains the image to scan.\n          5.  On the Images page, select the image to scan and then choose Scan.\n        scored: false\n\n      - id: 5.1.2\n        text: \"Minimize user access to Amazon ECR (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Before you use IAM to manage access to Amazon ECR, you should understand what IAM features\n          are available to use with Amazon ECR. To get a high-level view of how Amazon ECR and other\n          AWS services work with IAM, see AWS Services That Work with IAM in the IAM User Guide.\n        scored: false\n\n      - id: 5.1.3\n        text: \"Minimize cluster access to read-only for Amazon ECR (Manual)\"\n        type: \"manual\"\n        remediation: |\n          You can use your Amazon ECR images with Amazon EKS, but you need to satisfy the following prerequisites.\n\n          The Amazon EKS worker node IAM role (NodeInstanceRole) that you use with your worker nodes must possess\n          the following IAM policy permissions for Amazon ECR.\n\n          {\n              \"Version\": \"2012-10-17\",\n              \"Statement\": [\n                  {\n                      \"Effect\": \"Allow\",\n                      \"Action\": [\n                          \"ecr:BatchCheckLayerAvailability\",\n                          \"ecr:BatchGetImage\",\n                          \"ecr:GetDownloadUrlForLayer\",\n                          \"ecr:GetAuthorizationToken\"\n                      ],\n                      \"Resource\": \"*\"\n                  }\n              ]\n          }\n        scored: false\n\n      - id: 5.1.4\n        text: \"Minimize Container Registries to only those approved (Manual)\"\n        type: \"manual\"\n        remediation: |\n          To minimize AWS ECR container registries to only those approved, you can follow these steps:\n\n          1.  Define your approval criteria: Determine the criteria that containers must meet to\n              be considered approved. This can include factors such as security, compliance,\n              compatibility, and other requirements.\n          2.  Identify all existing ECR registries: Identify all ECR registries that are currently\n              being used in your organization.\n          3.  Evaluate ECR registries against approval criteria: Evaluate each ECR registry\n              against your approval criteria to determine whether it should be approved or not.\n              This can be done by reviewing the registry settings and configuration, as well as\n              conducting security assessments and vulnerability scans.\n          4.  Establish policies and procedures: Establish policies and procedures that outline\n              how ECR registries will be approved, maintained, and monitored. This should\n              include guidelines for developers to follow when selecting a registry for their\n              container images.\n          5.  Implement access controls: Implement access controls to ensure that only\n              approved ECR registries are used to store and distribute container images. This\n              can be done by setting up IAM policies and roles that restrict access to\n              unapproved registries or create a whitelist of approved registries.\n          6.  Monitor and review: Continuously monitor and review the use of ECR registries\n              to ensure that they continue to meet your approval criteria. This can include\n        scored: false\n\n  - id: 5.2\n    text: \"Identity and Access Management (IAM)\"\n    checks:\n      - id: 5.2.1\n        text: \"Prefer using dedicated Amazon EKS Service Accounts (Automated)\"\n        type: \"manual\"\n        remediation: |\n          With IAM roles for service accounts on Amazon EKS clusters, you can associate an\n          IAM role with a Kubernetes service account. This service account can then provide\n          AWS permissions to the containers in any pod that uses that service account. With this\n          feature, you no longer need to provide extended permissions to the worker node IAM\n          role so that pods on that node can call AWS APIs.\n          Applications must sign their AWS API requests with AWS credentials. This feature\n          provides a strategy for managing credentials for your applications, similar to the way\n          that Amazon EC2 instance profiles provide credentials to Amazon EC2 instances.\n          Instead of creating and distributing your AWS credentials to the containers or using the\n          Amazon EC2 instance’s role, you can associate an IAM role with a Kubernetes service\n          account. The applications in the pod’s containers can then use an AWS SDK or the\n          AWS CLI to make API requests to authorized AWS services.\n\n          The IAM roles for service accounts feature provides the following benefits:\n\n          - Least privilege - By using the IAM roles for service accounts feature, you no\n            longer need to provide extended permissions to the worker node IAM role so that\n            pods on that node can call AWS APIs. You can scope IAM permissions to a\n            service account, and only pods that use that service account have access to\n            those permissions. This feature also eliminates the need for third-party solutions\n            such as kiam or kube2iam.\n          - Credential isolation - A container can only retrieve credentials for the IAM role\n            that is associated with the service account to which it belongs. A container never\n            has access to credentials that are intended for another container that belongs to\n            another pod.\n          - Audit-ability - Access and event logging is available through CloudTrail to help\n            ensure retrospective auditing.\n        scored: false\n\n  - id: 5.3\n    text: \"AWS EKS Key Management Service\"\n    checks:\n      - id: 5.3.1\n        text: \"Ensure Kubernetes Secrets are encrypted using Customer Master Keys (CMKs) managed in AWS KMS (Manual)\"\n        type: \"manual\"\n        remediation: |\n          This process can only be performed during Cluster Creation.\n\n          Enable 'Secrets Encryption' during Amazon EKS cluster creation as described\n          in the links within the 'References' section.\n        scored: false\n\n  - id: 5.4\n    text: \"Cluster Networking\"\n    checks:\n      - id: 5.4.1\n        text: \"Restrict Access to the Control Plane Endpoint (Automated)\"\n        type: \"manual\"\n        remediation: |\n          By enabling private endpoint access to the Kubernetes API server, all communication\n          between your nodes and the API server stays within your VPC. You can also limit the IP\n          addresses that can access your API server from the internet, or completely disable\n          internet access to the API server.\n          With this in mind, you can update your cluster accordingly using the AWS CLI to ensure\n          that Private Endpoint Access is enabled.\n          If you choose to also enable Public Endpoint Access then you should also configure a\n          list of allowable CIDR blocks, resulting in restricted access from the internet. If you\n          specify no CIDR blocks, then the public API server endpoint is able to receive and\n          process requests from all IP addresses by defaulting to ['0.0.0.0/0'].\n          For example, the following command would enable private access to the Kubernetes\n          API as well as limited public access over the internet from a single IP address (noting\n          the /32 CIDR suffix):\n          aws eks update-cluster-config --region $AWS_REGION --name $CLUSTER_NAME --resources-vpc-config endpointPrivateAccess=true,endpointPrivateAccess=true,publicAccessCidrs=\"203.0.113.5/32\"\n\n          Note: The CIDR blocks specified cannot include reserved addresses.\n          There is a maximum number of CIDR blocks that you can specify. For more information,\n          see the EKS Service Quotas link in the references section.\n          For more detailed information, see the EKS Cluster Endpoint documentation link in the\n          references section.\n        scored: false\n\n      - id: 5.4.2\n        text: \"Ensure clusters are created with Private Endpoint Enabled and Public Access Disabled (Automated)\"\n        type: \"manual\"\n        remediation: |\n          By enabling private endpoint access to the Kubernetes API server, all communication\n          between your nodes and the API server stays within your VPC.\n          With this in mind, you can update your cluster accordingly using the AWS CLI to ensure\n          that Private Endpoint Access is enabled.\n          For example, the following command would enable private access to the Kubernetes\n          API and ensure that no public access is permitted:\n          aws eks update-cluster-config --region $AWS_REGION --name $CLUSTER_NAME --resources-vpc-config endpointPrivateAccess=true,endpointPublicAccess=false\n\n          Note: For more detailed information, see the EKS Cluster Endpoint documentation link\n          in the references section.\n        scored: false\n\n      - id: 5.4.3\n        text: \"Ensure clusters are created with Private Nodes (Automated)\"\n        type: \"manual\"\n        remediation: |\n          aws eks update-cluster-config \\\n            --region region-code \\\n            --name my-cluster \\\n            --resources-vpc-config endpointPublicAccess=true,publicAccessCidrs=\"203.0.113.5/32\",endpointPrivateAccess=true\n        scored: false\n\n      - id: 5.4.4\n        text: \"Ensure Network Policy is Enabled and set as appropriate (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Utilize Calico or other network policy engine to segment and isolate your traffic.\n        scored: false\n\n      - id: 5.4.5\n        text: \"Encrypt traffic to HTTPS load balancers with TLS certificates (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Your load balancer vendor can provide details on configuring HTTPS with TLS.\n        scored: false\n\n\n  - id: 5.5\n    text: \"Authentication and Authorization\"\n    checks:\n      - id: 5.5.1\n        text: \"Manage Kubernetes RBAC users with AWS IAM Authenticator for Kubernetes or Upgrade to AWS CLI v1.16.156 or greater (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Refer to the 'Managing users or IAM roles for your cluster' in Amazon EKS documentation.\n\n          Note: If using AWS CLI version 1.16.156 or later there is no need to install the AWS\n          IAM Authenticator anymore.\n          The relevant AWS CLI commands, depending on the use case, are:\n          aws eks update-kubeconfig\n          aws eks get-token\n        scored: false\n"
  },
  {
    "path": "cfg/eks-1.5.0/master.yaml",
    "content": "---\ncontrols:\nversion: \"eks-1.5.0\"\nid: 1\ntext: \"Control Plane Components\"\ntype: \"master\"\n"
  },
  {
    "path": "cfg/eks-1.5.0/node.yaml",
    "content": "---\ncontrols:\nversion: \"eks-1.5.0\"\nid: 3\ntext: \"Worker Node Security Configuration\"\ntype: \"node\"\ngroups:\n  - id: 3.1\n    text: \"Worker Node Configuration Files\"\n    checks:\n      - id: 3.1.1\n        text: \"Ensure that the kubeconfig file permissions are set to 644 or more restrictive (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletkubeconfig; then stat -c permissions=%a $kubeletkubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chmod 644 $kubeletkubeconfig\n        scored: true\n\n      - id: 3.1.2\n        text: \"Ensure that the kubelet kubeconfig file ownership is set to root:root (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletkubeconfig; then stat -c %U:%G $kubeletkubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chown root:root $kubeletkubeconfig\n        scored: true\n\n      - id: 3.1.3\n        text: \"Ensure that the kubelet configuration file has permissions set to 644 or more restrictive (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletconf; then stat -c permissions=%a $kubeletconf; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the following command (using the config file location identified in the Audit step)\n          chmod 644 $kubeletconf\n        scored: true\n\n      - id: 3.1.4\n        text: \"Ensure that the kubelet configuration file ownership is set to root:root (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletconf; then stat -c %U:%G $kubeletconf; fi'' '\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the following command (using the config file location identified in the Audit step)\n          chown root:root $kubeletconf\n        scored: true\n\n  - id: 3.2\n    text: \"Kubelet\"\n    checks:\n      - id: 3.2.1\n        text: \"Ensure that the Anonymous Auth is Not Enabled (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: \"--anonymous-auth\"\n              path: '{.authentication.anonymous.enabled}'\n              set: true\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Remediation Method 1:\n          If configuring via the Kubelet config file, you first need to locate the file.\n          To do this, SSH to each node and execute the following command to find the kubelet\n          process:\n          ps -ef | grep kubelet\n          The output of the above command provides details of the active kubelet process, from\n          which we can see the location of the configuration file provided to the kubelet service\n          with the --config argument. The file can be viewed with a command such as more or\n          less, like so:\n          sudo less /path/to/kubelet-config.json\n          Disable Anonymous Authentication by setting the following parameter:\n          \"authentication\": { \"anonymous\": { \"enabled\": false } }\n\n          Remediation Method 2.\n          If using executable arguments, edit the kubelet service file on each worker node and\n          ensure the below parameters are part of the KUBELET_ARGS variable string.\n          For systems using systemd, such as the Amazon EKS Optimised Amazon Linux or\n          Bottlerocket AMIs, then this file can be found at\n          /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf. Otherwise,\n          you may need to look up documentation for your chosen operating system to determine\n          which service manager is configured:\n          --anonymous-auth=false\n\n          For Both Remediation Steps:\n          Based on your system, restart the kubelet service and check the service status.\n          The following example is for operating systems using systemd, such as the Amazon\n          EKS Optimised Amazon Linux or Bottlerocket AMIs, and invokes the systemctl\n          command. If systemctl is not available then you will need to look up documentation for\n          your chosen operating system to determine which service manager is configured:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n          systemctl status kubelet -l\n        scored: true\n\n      - id: 3.2.2\n        text: \"Ensure that the --authorization-mode argument is not set to AlwaysAllow (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --authorization-mode\n              path: '{.authorization.mode}'\n              set: true\n              compare:\n                op: nothave\n                value: AlwaysAllow\n        remediation: |\n          Remediation Method 1:\n          If configuring via the Kubelet config file, you first need to locate the file.\n          To do this, SSH to each node and execute the following command to find the kubelet\n          process:\n          ps -ef | grep kubelet\n          The output of the above command provides details of the active kubelet process, from\n          which we can see the location of the configuration file provided to the kubelet service\n          with the --config argument. The file can be viewed with a command such as more or\n          less, like so:\n          sudo less /path/to/kubelet-config.json\n          Enable Webhook Authentication by setting the following parameter:\n          \"authentication\": { \"webhook\": { \"enabled\": true } }\n          Next, set the Authorization Mode to Webhook by setting the following parameter:\n          \"authorization\": { \"mode\": \"Webhook }\n          Finer detail of the authentication and authorization fields can be found in the\n          Kubelet Configuration documentation.\n\n          Remediation Method 2:\n          If using executable arguments, edit the kubelet service file on each worker node and\n          ensure the below parameters are part of the KUBELET_ARGS variable string.\n          For systems using systemd, such as the Amazon EKS Optimised Amazon Linux or\n          Bottlerocket AMIs, then this file can be found at\n          /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf. Otherwise,\n          you may need to look up documentation for your chosen operating system to determine\n          which service manager is configured:\n          --authentication-token-webhook\n          --authorization-mode=Webhook\n\n          For Both Remediation Steps:\n          Based on your system, restart the kubelet service and check the service status.\n          The following example is for operating systems using systemd, such as the Amazon\n          EKS Optimised Amazon Linux or Bottlerocket AMIs, and invokes the systemctl\n          command. If systemctl is not available then you will need to look up documentation for\n          your chosen operating system to determine which service manager is configured:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n          systemctl status kubelet -l\n        scored: true\n\n      - id: 3.2.3\n        text: \"Ensure that a Client CA File is Configured (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --client-ca-file\n              path: '{.authentication.x509.clientCAFile}'\n              set: true\n        remediation: |\n          Remediation Method 1:\n          If configuring via the Kubelet config file, you first need to locate the file.\n          To do this, SSH to each node and execute the following command to find the kubelet\n          process:\n          ps -ef | grep kubelet\n          The output of the above command provides details of the active kubelet process, from\n          which we can see the location of the configuration file provided to the kubelet service\n          with the --config argument. The file can be viewed with a command such as more or\n          less, like so:\n          sudo less /path/to/kubelet-config.json\n          Configure the client certificate authority file by setting the following parameter\n          appropriately:\n          \"authentication\": { \"x509\": {\"clientCAFile\": <path/to/client-ca-file> } }\"\n\n          Remediation Method 2:\n          If using executable arguments, edit the kubelet service file on each worker node and\n          ensure the below parameters are part of the KUBELET_ARGS variable string.\n          For systems using systemd, such as the Amazon EKS Optimised Amazon Linux or\n          Bottlerocket AMIs, then this file can be found at\n          /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf. Otherwise,\n          you may need to look up documentation for your chosen operating system to determine\n          which service manager is configured:\n          --client-ca-file=<path/to/client-ca-file>\n\n          For Both Remediation Steps:\n          Based on your system, restart the kubelet service and check the service status.\n          The following example is for operating systems using systemd, such as the Amazon\n          EKS Optimised Amazon Linux or Bottlerocket AMIs, and invokes the systemctl\n          command. If systemctl is not available then you will need to look up documentation for\n          your chosen operating system to determine which service manager is configured:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n          systemctl status kubelet -l\n        scored: true\n\n      - id: 3.2.4\n        text: \"Ensure that the --read-only-port is disabled (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: \"--read-only-port\"\n              path: '{.readOnlyPort}'\n              set: true\n              compare:\n                op: eq\n                value: 0\n        remediation: |\n          If modifying the Kubelet config file, edit the kubelet-config.json file\n          /etc/kubernetes/kubelet/kubelet-config.json and set the below parameter to 0\n          \"readOnlyPort\": 0\n          If using executable arguments, edit the kubelet service file\n          /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf on each\n          worker node and add the below parameter at the end of the KUBELET_ARGS variable\n          string.\n          --read-only-port=0\n\n          Based on your system, restart the kubelet service and check status\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n          systemctl status kubelet -l\n        scored: true\n\n      - id: 3.2.5\n        text: \"Ensure that the --streaming-connection-idle-timeout argument is not set to 0 (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --streaming-connection-idle-timeout\n              path: '{.streamingConnectionIdleTimeout}'\n              set: true\n              compare:\n                op: noteq\n                value: 0\n            - flag: --streaming-connection-idle-timeout\n              path: '{.streamingConnectionIdleTimeout}'\n              set: false\n          bin_op: or\n        remediation: |\n          Remediation Method 1:\n          If modifying the Kubelet config file, edit the kubelet-config.json file\n          /etc/kubernetes/kubelet/kubelet-config.json and set the below parameter to a\n          non-zero value in the format of #h#m#s\n          \"streamingConnectionIdleTimeout\": \"4h0m0s\"\n          You should ensure that the kubelet service file\n          /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf does not\n          specify a --streaming-connection-idle-timeout argument because it would\n          override the Kubelet config file.\n\n          Remediation Method 2:\n          If using executable arguments, edit the kubelet service file\n          /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf on each\n          worker node and add the below parameter at the end of the KUBELET_ARGS variable\n          string.\n          --streaming-connection-idle-timeout=4h0m0s\n\n          Remediation Method 3:\n          If using the api configz endpoint consider searching for the status of\n          \"streamingConnectionIdleTimeout\": by extracting the live configuration from the\n          nodes running kubelet.\n          **See detailed step-by-step configmap procedures in Reconfigure a Node's Kubelet in a\n          Live Cluster, and then rerun the curl statement from audit process to check for kubelet\n          configuration changes\n          kubectl proxy --port=8001 &\n          export HOSTNAME_PORT=localhost:8001 (example host and port number)\n          export NODE_NAME=ip-192.168.31.226.ec2.internal (example node name from \"kubectl get nodes\")\n          curl -sSL \"http://${HOSTNAME_PORT}/api/v1/nodes/${NODE_NAME}/proxy/configz\"\n\n          For all three remediations:\n          Based on your system, restart the kubelet service and check status\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n          systemctl status kubelet -l\n        scored: true\n\n      - id: 3.2.6\n        text: \"Ensure that the --make-iptables-util-chains argument is set to true (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --make-iptables-util-chains\n              path: '{.makeIPTablesUtilChains}'\n              set: true\n              compare:\n                op: eq\n                value: true\n            - flag: --make-iptables-util-chains\n              path: '{.makeIPTablesUtilChains}'\n              set: false\n          bin_op: or\n        remediation: |\n          Remediation Method 1:\n          If modifying the Kubelet config file, edit the kubelet-config.json file\n          /etc/kubernetes/kubelet/kubelet-config.json and set the below parameter to\n          true\n          \"makeIPTablesUtilChains\": true\n          Ensure that /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf\n          does not set the --make-iptables-util-chains argument because that would\n          override your Kubelet config file.\n\n          Remediation Method 2:\n          If using executable arguments, edit the kubelet service file\n          /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf on each\n          worker node and add the below parameter at the end of the KUBELET_ARGS variable\n          string.\n          --make-iptables-util-chains:true\n\n          Remediation Method 3:\n          If using the api configz endpoint consider searching for the status of\n          \"makeIPTablesUtilChains.: true by extracting the live configuration from the nodes\n          running kubelet.\n          **See detailed step-by-step configmap procedures in Reconfigure a Node's Kubelet in a\n          Live Cluster, and then rerun the curl statement from audit process to check for kubelet\n          configuration changes\n          kubectl proxy --port=8001 &\n          export HOSTNAME_PORT=localhost:8001 (example host and port number)\n          export NODE_NAME=ip-192.168.31.226.ec2.internal (example node name from \"kubectl get nodes\")\n          curl -sSL \"http://${HOSTNAME_PORT}/api/v1/nodes/${NODE_NAME}/proxy/configz\"\n\n          For all three remediations:\n          Based on your system, restart the kubelet service and check status\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n          systemctl status kubelet -l\n        scored: true\n\n      - id: 3.2.7\n        text: \"Ensure that the --eventRecordQPS argument is set to 0 or a level which ensures appropriate event capture (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --event-qps\n              path: '{.eventRecordQPS}'\n              set: true\n              compare:\n                op: gte\n                value: 0\n        remediation: |\n          If using a Kubelet config file, edit the file to set eventRecordQPS: to an appropriate\n          level.\n          If using command line arguments, edit the kubelet service file\n          /etc/systemd/system/kubelet.service.d/10-kubeadm.conf on each worker node\n          and set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 3.2.8\n        text: \"Ensure that the --rotate-certificates argument is not present or is set to true (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --rotate-certificates\n              path: '{.rotateCertificates}'\n              set: true\n              compare:\n                op: eq\n                value: true\n            - flag: --rotate-certificates\n              path: '{.rotateCertificates}'\n              set: false\n          bin_op: or\n        remediation: |\n          Remediation Method 1:\n          If modifying the Kubelet config file, edit the kubelet-config.json file\n          /etc/kubernetes/kubelet/kubelet-config.json and set the below parameter to\n          true\n          \"RotateCertificate\":true\n          Additionally, ensure that the kubelet service file\n          /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf does not set the --RotateCertificate\n          executable argument to false because this would override the Kubelet\n          config file.\n\n          Remediation Method 2:\n          If using executable arguments, edit the kubelet service file\n          /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf on each\n          worker node and add the below parameter at the end of the KUBELET_ARGS variable\n          string.\n          --RotateCertificate=true\n        scored: true\n\n      - id: 3.2.9\n        text: \"Ensure that the RotateKubeletServerCertificate argument is set to true (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: RotateKubeletServerCertificate\n              path: '{.featureGates.RotateKubeletServerCertificate}'\n              set: true\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Remediation Method 1:\n          If modifying the Kubelet config file, edit the kubelet-config.json file\n          /etc/kubernetes/kubelet/kubelet-config.json and set the below parameter to\n          true\n\n          \"featureGates\": {\n            \"RotateKubeletServerCertificate\":true\n          },\n\n          Additionally, ensure that the kubelet service file\n          /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf does not set\n          the --rotate-kubelet-server-certificate executable argument to false because\n          this would override the Kubelet config file.\n\n          Remediation Method 2:\n          If using executable arguments, edit the kubelet service file\n          /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf on each\n          worker node and add the below parameter at the end of the KUBELET_ARGS variable\n          string.\n          --rotate-kubelet-server-certificate=true\n\n          Remediation Method 3:\n          If using the api configz endpoint consider searching for the status of\n          \"RotateKubeletServerCertificate\": by extracting the live configuration from the\n          nodes running kubelet.\n          **See detailed step-by-step configmap procedures in Reconfigure a Node's Kubelet in a\n          Live Cluster, and then rerun the curl statement from audit process to check for kubelet\n          configuration changes\n          kubectl proxy --port=8001 &\n          export HOSTNAME_PORT=localhost:8001 (example host and port number)\n          export NODE_NAME=ip-192.168.31.226.ec2.internal (example node name from \"kubectl get nodes\")\n          curl -sSL \"http://${HOSTNAME_PORT}/api/v1/nodes/${NODE_NAME}/proxy/configz\"\n\n          For all three remediation methods:\n          Restart the kubelet service and check status. The example below is for when using\n          systemctl to manage services:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n          systemctl status kubelet -l\n        scored: true\n"
  },
  {
    "path": "cfg/eks-1.5.0/policies.yaml",
    "content": "---\ncontrols:\nversion: \"eks-1.5.0\"\nid: 4\ntext: \"Policies\"\ntype: \"policies\"\ngroups:\n  - id: 4.1\n    text: \"RBAC and Service Accounts\"\n    checks:\n      - id: 4.1.1\n        text: \"Ensure that the cluster-admin role is only used where required (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Identify all clusterrolebindings to the cluster-admin role. Check if they are used and if\n          they need this role or if they could use a role with fewer privileges.\n          Where possible, first bind users to a lower privileged role and then remove the\n          clusterrolebinding to the cluster-admin role :\n          kubectl delete clusterrolebinding [name]\n        scored: false\n\n      - id: 4.1.2\n        text: \"Minimize access to secrets (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove get, list and watch access to secret objects in the cluster.\n        scored: false\n\n      - id: 4.1.3\n        text: \"Minimize wildcard use in Roles and ClusterRoles (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Where possible replace any use of wildcards in clusterroles and roles with specific\n          objects or actions.\n        scored: false\n\n      - id: 4.1.4\n        text: \"Minimize access to create pods (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove create access to pod objects in the cluster.\n        scored: false\n\n      - id: 4.1.5\n        text: \"Ensure that default service accounts are not actively used. ((Automated)\"\n        type: \"manual\"\n        remediation: |\n          Create explicit service accounts wherever a Kubernetes workload requires specific\n          access to the Kubernetes API server.\n          Modify the configuration of each default service account to include this value\n          automountServiceAccountToken: false\n\n          Automatic remediation for the default account:\n          kubectl patch serviceaccount default -p\n          $'automountServiceAccountToken: false'\n        scored: false\n\n      - id: 4.1.6\n        text: \"Ensure that Service Account Tokens are only mounted where necessary (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Modify the definition of pods and service accounts which do not need to mount service\n          account tokens to disable it.\n        scored: false\n\n      - id: 4.1.7\n        text: \"Avoid use of system:masters group (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Remove the system:masters group from all users in the cluster.\n        scored: false\n\n      - id: 4.1.8\n        text: \"Limit use of the Bind, Impersonate and Escalate permissions in the Kubernetes cluster (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove the impersonate, bind and escalate rights from subjects.\n        scored: false\n\n  - id: 4.2\n    text: \"Pod Security Standards\"\n    checks:\n      - id: 4.2.1\n        text: \"Minimize the admission of privileged containers (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of privileged containers.\n          To enable PSA for a namespace in your cluster, set the pod-security.kubernetes.io/enforce\n          label with the policy value you want to enforce.\n          kubectl label --overwrite ns NAMESPACE pod-security.kubernetes.io/enforce=restricted\n          The above command enforces the restricted policy for the NAMESPACE namespace.\n          You can also enable Pod Security Admission for all your namespaces. For example:\n          kubectl label --overwrite ns --all pod-security.kubernetes.io/warn=baseline\n        scored: false\n\n      - id: 4.2.2\n        text: \"Minimize the admission of containers wishing to share the host process ID namespace (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of hostPID containers.\n        scored: false\n\n      - id: 4.2.3\n        text: \"Minimize the admission of containers wishing to share the host IPC namespace (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of hostIPC containers.\n        scored: false\n\n      - id: 4.2.4\n        text: \"Minimize the admission of containers wishing to share the host network namespace (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of hostNetwork containers.\n        scored: false\n\n      - id: 4.2.5\n        text: \"Minimize the admission of containers with allowPrivilegeEscalation (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers with .spec.allowPrivilegeEscalation set to true.\n        scored: false\n\n  - id: 4.3\n    text: \"CNI Plugin\"\n    checks:\n      - id: 4.3.1\n        text: \"Ensure CNI plugin supports network policies (Manual)\"\n        type: \"manual\"\n        remediation: |\n          As with RBAC policies, network policies should adhere to the policy of least privileged\n          access. Start by creating a deny all policy that restricts all inbound and outbound traffic\n          from a namespace or create a global policy using Calico.\n        scored: false\n\n      - id: 4.3.2\n        text: \"Ensure that all Namespaces have Network Policies defined (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Follow the documentation and create NetworkPolicy objects as you need them.\n        scored: false\n\n  - id: 4.4\n    text: \"Secrets Management\"\n    checks:\n      - id: 4.4.1\n        text: \"Prefer using secrets as files over secrets as environment variables (Automated)\"\n        type: \"manual\"\n        remediation: |\n          If possible, rewrite application code to read secrets from mounted secret files, rather than\n          from environment variables.\n        scored: false\n\n      - id: 4.4.2\n        text: \"Consider external secret storage (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Refer to the secrets management options offered by your cloud provider or a third-party\n          secrets management solution.\n        scored: false\n\n  - id: 4.5\n    text: \"General Policies\"\n    checks:\n      - id: 4.5.1\n        text: \"Create administrative boundaries between resources using namespaces (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the documentation and create namespaces for objects in your deployment as you need\n          them.\n        scored: false\n\n      - id: 4.5.2\n        text: \"Apply Security Context to Your Pods and Containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          As a best practice we recommend that you scope the binding for privileged pods to\n          service accounts within a particular namespace, e.g. kube-system, and limiting access\n          to that namespace. For all other serviceaccounts/namespaces, we recommend\n          implementing a more restrictive policy such as this:\n\n          apiVersion: policy/v1beta1\n          kind: PodSecurityPolicy\n          metadata:\n            name: restricted\n            annotations:\n              seccomp.security.alpha.kubernetes.io/allowedProfileNames: 'docker/default,runtime/default'\n              apparmor.security.beta.kubernetes.io/allowedProfileNames: 'runtime/default'\n              seccomp.security.alpha.kubernetes.io/defaultProfileName: 'runtime/default'\n              apparmor.security.beta.kubernetes.io/defaultProfileName: 'runtime/default'\n          spec:\n            privileged: false\n            # Required to prevent escalations to root.\n            allowPrivilegeEscalation: false\n            # This is redundant with non-root + disallow privilege escalation,\n            # but we can provide it for defense in depth.\n            requiredDropCapabilities:\n            - ALL\n            # Allow core volume types.\n            volumes:\n            - 'configMap'\n            - 'emptyDir'\n            - 'projected'\n            - 'secret'\n            - 'downwardAPI'\n            # Assume that persistentVolumes set up by the cluster admin are safe to use.\n            - 'persistentVolumeClaim'\n            hostNetwork: false\n            hostIPC: false\n            hostPID: false\n            runAsUser:\n            # Require the container to run without root privileges.\n            rule: 'MustRunAsNonRoot'\n            seLinux:\n            # This policy assumes the nodes are using AppArmor rather than SELinux.\n            rule: 'RunAsAny'\n            supplementalGroups:\n            rule: 'MustRunAs'\n            ranges:\n              # Forbid adding the root group.\n              - min: 1\n                max: 65535\n            fsGroup:\n            rule: 'MustRunAs'\n            ranges:\n              # Forbid adding the root group.\n              - min: 1\n                max: 65535\n            readOnlyRootFilesystem: false\n\n          This policy prevents pods from running as privileged or escalating privileges. It also\n          restricts the types of volumes that can be mounted and the root supplemental groups\n          that can be added.\n          Another, albeit similar, approach is to start with policy that locks everything down and\n          incrementally add exceptions for applications that need looser restrictions such as\n          logging agents which need the ability to mount a host path.\n        scored: false\n\n      - id: 4.5.3\n        text: \"The default namespace should not be used (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that namespaces are created to allow for appropriate segregation of Kubernetes\n          resources and that all new resources are created in a specific namespace.\n        scored: false\n"
  },
  {
    "path": "cfg/eks-1.7.0/config.yaml",
    "content": "---\n## Version-specific settings that override the values in cfg/config.yaml\n## These settings are required if you are using the --asff option to report findings to AWS Security Hub\n## AWS account number is required.\nAWS_ACCOUNT: \"<AWS_ACCT_NUMBER>\"\n## AWS region is required.\nAWS_REGION: \"<AWS_REGION>\"\n## EKS Cluster ARN is required.\nCLUSTER_ARN: \"<AWS_CLUSTER_ARN>\"\n"
  },
  {
    "path": "cfg/eks-1.7.0/controlplane.yaml",
    "content": "---\ncontrols:\nversion: \"eks-1.7.0\"\nid: 2\ntext: \"Control Plane Configuration\"\ntype: \"controlplane\"\ngroups:\n  - id: 2.1\n    text: \"Logging\"\n    checks:\n      - id: 2.1.1\n        text: \"Enable audit Logs (Manual)\"\n        type: manual\n        remediation: |\n          From Console:\n          1.  For each EKS Cluster in each region;\n          2.  Go to 'Amazon EKS' > 'Clusters' > '' > 'Configuration' > 'Logging'.\n          3.  Click 'Manage logging'.\n          4.  Ensure that all options are toggled to 'Enabled'.\n                API server: Enabled\n                Audit: Enabled\n                Authenticator: Enabled\n                Controller manager: Enabled\n                Scheduler: Enabled\n          5.  Click 'Save Changes'.\n\n          From CLI:\n          # For each EKS Cluster in each region;\n          aws eks update-cluster-config \\\n            --region '${REGION_CODE}' \\\n            --name '${CLUSTER_NAME}' \\\n            --logging '{\"clusterLogging\":[{\"types\":[\"api\",\"audit\",\"authenticator\",\"controllerManager\",\"scheduler\"],\"enabled\":true}]}'\n        scored: false\n\n      - id: 2.1.2\n        text: \"Ensure audit logs are collected and managed (Manual)\"\n        type: manual\n        remediation: |\n          Create or update the audit-policy.yaml to specify the audit logging configuration:\n          apiVersion: audit.k8s.io/v1\n          kind: Policy\n          rules:\n            - level: Metadata\n              resources:\n                - group: \"\"\n                  resources: [\"pods\"]\n          Apply the audit policy configuration to the cluster:\n            kubectl apply -f <path-to-audit-policy>.yaml\n          Ensure audit logs are forwarded to a centralized logging system like CloudWatch, Elasticsearch, or another log management solution:\n            kubectl create configmap cluster-audit-policy --from-file=audit-policy.yaml -n kube-system\n            kubectl apply -f - <<EOF\n          apiVersion: v1\n          kind: Pod\n          metadata:\n            name: audit-logging\n            namespace: kube-system\n          spec:\n            containers:\n              - name: audit-log-forwarder\n                image: my-log-forwarder-image\n                volumeMounts:\n                  - mountPath: /etc/kubernetes/audit\n                    name: audit-config\n            volumes:\n              - name: audit-config\n                configMap:\n                  name: cluster-audit-policy\n            EOF\n        scored: false\n"
  },
  {
    "path": "cfg/eks-1.7.0/managedservices.yaml",
    "content": "---\ncontrols:\nversion: \"eks-1.7.0\"\nid: 5\ntext: \"Managed Services\"\ntype: \"managedservices\"\ngroups:\n  - id: 5.1\n    text: \"Image Registry and Image Scanning\"\n    checks:\n      - id: 5.1.1\n        text: \"Ensure Image Vulnerability Scanning using Amazon ECR image scanning or a third party provider (Manual)\"\n        type: \"manual\"\n        remediation: |\n          To utilize AWS ECR for Image scanning please follow the steps below:\n\n          To create a repository configured for scan on push (AWS CLI):\n          aws ecr create-repository --repository-name $REPO_NAME --image-scanning-configuration scanOnPush=true --region $REGION_CODE\n\n          To edit the settings of an existing repository (AWS CLI):\n          aws ecr put-image-scanning-configuration --repository-name $REPO_NAME --image-scanning-configuration scanOnPush=true --region $REGION_CODE\n\n          Use the following steps to start a manual image scan using the AWS Management Console.\n\n          1.  Open the Amazon ECR console at https://console.aws.amazon.com/ecr/repositories.\n          2.  From the navigation bar, choose the Region to create your repository in.\n          3.  In the navigation pane, choose Repositories.\n          4.  On the Repositories page, choose the repository that contains the image to scan.\n          5.  On the Images page, select the image to scan and then choose Scan.\n        scored: false\n\n      - id: 5.1.2\n        text: \"Minimize user access to Amazon ECR (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Before you use IAM to manage access to Amazon ECR, you should understand what IAM features\n          are available to use with Amazon ECR. To get a high-level view of how Amazon ECR and other\n          AWS services work with IAM, see AWS Services That Work with IAM in the IAM User Guide.\n        scored: false\n\n      - id: 5.1.3\n        text: \"Minimize cluster access to read-only for Amazon ECR (Manual)\"\n        type: \"manual\"\n        remediation: |\n          You can use your Amazon ECR images with Amazon EKS, but you need to satisfy the following prerequisites.\n\n          The Amazon EKS worker node IAM role (NodeInstanceRole) that you use with your worker nodes must possess\n          the following IAM policy permissions for Amazon ECR.\n\n          {\n              \"Version\": \"2012-10-17\",\n              \"Statement\": [\n                  {\n                      \"Effect\": \"Allow\",\n                      \"Action\": [\n                          \"ecr:BatchCheckLayerAvailability\",\n                          \"ecr:BatchGetImage\",\n                          \"ecr:GetDownloadUrlForLayer\",\n                          \"ecr:GetAuthorizationToken\"\n                      ],\n                      \"Resource\": \"*\"\n                  }\n              ]\n          }\n        scored: false\n\n      - id: 5.1.4\n        text: \"Minimize Container Registries to only those approved (Manual)\"\n        type: \"manual\"\n        remediation: |\n          To minimize AWS ECR container registries to only those approved, you can follow these steps:\n\n          1.  Define your approval criteria: Determine the criteria that containers must meet to\n              be considered approved. This can include factors such as security, compliance,\n              compatibility, and other requirements.\n          2.  Identify all existing ECR registries: Identify all ECR registries that are currently\n              being used in your organization.\n          3.  Evaluate ECR registries against approval criteria: Evaluate each ECR registry\n              against your approval criteria to determine whether it should be approved or not.\n              This can be done by reviewing the registry settings and configuration, as well as\n              conducting security assessments and vulnerability scans.\n          4.  Establish policies and procedures: Establish policies and procedures that outline\n              how ECR registries will be approved, maintained, and monitored. This should\n              include guidelines for developers to follow when selecting a registry for their\n              container images.\n          5.  Implement access controls: Implement access controls to ensure that only\n              approved ECR registries are used to store and distribute container images. This\n              can be done by setting up IAM policies and roles that restrict access to\n              unapproved registries or create a whitelist of approved registries.\n          6.  Monitor and review: Continuously monitor and review the use of ECR registries\n              to ensure that they continue to meet your approval criteria. This can include\n        scored: false\n\n  - id: 5.2\n    text: \"Identity and Access Management (IAM)\"\n    checks:\n      - id: 5.2.1\n        text: \"Prefer using dedicated Amazon EKS Service Accounts (Manual)\"\n        type: \"manual\"\n        remediation: |\n          With IAM roles for service accounts on Amazon EKS clusters, you can associate an\n          IAM role with a Kubernetes service account. This service account can then provide\n          AWS permissions to the containers in any pod that uses that service account. With this\n          feature, you no longer need to provide extended permissions to the worker node IAM\n          role so that pods on that node can call AWS APIs.\n          Applications must sign their AWS API requests with AWS credentials. This feature\n          provides a strategy for managing credentials for your applications, similar to the way\n          that Amazon EC2 instance profiles provide credentials to Amazon EC2 instances.\n          Instead of creating and distributing your AWS credentials to the containers or using the\n          Amazon EC2 instance’s role, you can associate an IAM role with a Kubernetes service\n          account. The applications in the pod’s containers can then use an AWS SDK or the\n          AWS CLI to make API requests to authorized AWS services.\n\n          The IAM roles for service accounts feature provides the following benefits:\n\n          - Least privilege - By using the IAM roles for service accounts feature, you no\n            longer need to provide extended permissions to the worker node IAM role so that\n            pods on that node can call AWS APIs. You can scope IAM permissions to a\n            service account, and only pods that use that service account have access to\n            those permissions. This feature also eliminates the need for third-party solutions\n            such as kiam or kube2iam.\n          - Credential isolation - A container can only retrieve credentials for the IAM role\n            that is associated with the service account to which it belongs. A container never\n            has access to credentials that are intended for another container that belongs to\n            another pod.\n          - Audit-ability - Access and event logging is available through CloudTrail to help\n            ensure retrospective auditing.\n        scored: false\n\n  - id: 5.3\n    text: \"AWS EKS Key Management Service\"\n    checks:\n      - id: 5.3.1\n        text: \"Ensure Kubernetes Secrets are encrypted using Customer Master Keys (CMKs) managed in AWS KMS (Manual)\"\n        type: \"manual\"\n        remediation: |\n          This process can only be performed during Cluster Creation.\n\n          Enable 'Secrets Encryption' during Amazon EKS cluster creation as described\n          in the links within the 'References' section.\n        scored: false\n\n  - id: 5.4\n    text: \"Cluster Networking\"\n    checks:\n      - id: 5.4.1\n        text: \"Restrict Access to the Control Plane Endpoint (Manual)\"\n        type: \"manual\"\n        remediation: |\n          By enabling private endpoint access to the Kubernetes API server, all communication\n          between your nodes and the API server stays within your VPC. You can also limit the IP\n          addresses that can access your API server from the internet, or completely disable\n          internet access to the API server.\n          With this in mind, you can update your cluster accordingly using the AWS CLI to ensure\n          that Private Endpoint Access is enabled.\n          If you choose to also enable Public Endpoint Access then you should also configure a\n          list of allowable CIDR blocks, resulting in restricted access from the internet. If you\n          specify no CIDR blocks, then the public API server endpoint is able to receive and\n          process requests from all IP addresses by defaulting to ['0.0.0.0/0'].\n          For example, the following command would enable private access to the Kubernetes\n          API as well as limited public access over the internet from a single IP address (noting\n          the /32 CIDR suffix):\n          aws eks update-cluster-config --region $AWS_REGION --name $CLUSTER_NAME --resources-vpc-config endpointPrivateAccess=true,endpointPrivateAccess=true,publicAccessCidrs=\"203.0.113.5/32\"\n\n          Note: The CIDR blocks specified cannot include reserved addresses.\n          There is a maximum number of CIDR blocks that you can specify. For more information,\n          see the EKS Service Quotas link in the references section.\n          For more detailed information, see the EKS Cluster Endpoint documentation link in the\n          references section.\n        scored: false\n\n      - id: 5.4.2\n        text: \"Ensure clusters are created with Private Endpoint Enabled and Public Access Disabled (Manual)\"\n        type: \"manual\"\n        remediation: |\n          By enabling private endpoint access to the Kubernetes API server, all communication\n          between your nodes and the API server stays within your VPC.\n          With this in mind, you can update your cluster accordingly using the AWS CLI to ensure\n          that Private Endpoint Access is enabled.\n          For example, the following command would enable private access to the Kubernetes\n          API and ensure that no public access is permitted:\n          aws eks update-cluster-config --region $AWS_REGION --name $CLUSTER_NAME --resources-vpc-config endpointPrivateAccess=true,endpointPublicAccess=false\n\n          Note: For more detailed information, see the EKS Cluster Endpoint documentation link\n          in the references section.\n        scored: false\n\n      - id: 5.4.3\n        text: \"Ensure clusters are created with Private Nodes (Manual)\"\n        type: \"manual\"\n        remediation: |\n          aws eks update-cluster-config \\\n            --region region-code \\\n            --name my-cluster \\\n            --resources-vpc-config endpointPublicAccess=true,publicAccessCidrs=\"203.0.113.5/32\",endpointPrivateAccess=true\n        scored: false\n\n      - id: 5.4.4\n        text: \"Ensure Network Policy is Enabled and set as appropriate (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Utilize Calico or other network policy engine to segment and isolate your traffic.\n        scored: false\n\n      - id: 5.4.5\n        text: \"Encrypt traffic to HTTPS load balancers with TLS certificates (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Your load balancer vendor can provide details on configuring HTTPS with TLS.\n        scored: false\n\n\n  - id: 5.5\n    text: \"Authentication and Authorization\"\n    checks:\n      - id: 5.5.1\n        text: \"Manage Kubernetes RBAC users with AWS IAM Authenticator for Kubernetes or Upgrade to AWS CLI v1.16.156 or greater (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Refer to the 'Managing users or IAM roles for your cluster' in Amazon EKS documentation.\n\n          Note: If using AWS CLI version 1.16.156 or later there is no need to install the AWS\n          IAM Authenticator anymore.\n          The relevant AWS CLI commands, depending on the use case, are:\n          aws eks update-kubeconfig\n          aws eks get-token\n        scored: false\n"
  },
  {
    "path": "cfg/eks-1.7.0/master.yaml",
    "content": "---\ncontrols:\nversion: \"eks-1.7.0\"\nid: 1\ntext: \"Control Plane Components\"\ntype: \"master\"\n"
  },
  {
    "path": "cfg/eks-1.7.0/node.yaml",
    "content": "---\ncontrols:\nversion: \"eks-1.7.0\"\nid: 3\ntext: \"Worker Nodes\"\ntype: \"node\"\ngroups:\n  - id: 3.1\n    text: \"Worker Node Configuration Files\"\n    checks:\n      - id: 3.1.1\n        text: \"Ensure that the kubeconfig file permissions are set to 644 or more restrictive (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletkubeconfig; then stat -c permissions=%a $kubeletkubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chmod 644 $kubeletkubeconfig\n        scored: true\n\n      - id: 3.1.2\n        text: \"Ensure that the kubelet kubeconfig file ownership is set to root:root (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletkubeconfig; then stat -c %U:%G $kubeletkubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chown root:root $kubeletkubeconfig\n        scored: true\n\n      - id: 3.1.3\n        text: \"Ensure that the kubelet configuration file has permissions set to 644 or more restrictive (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletconf; then stat -c permissions=%a $kubeletconf; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the following command (using the config file location identified in the Audit step)\n          chmod 644 $kubeletconf\n        scored: true\n\n      - id: 3.1.4\n        text: \"Ensure that the kubelet configuration file ownership is set to root:root (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletconf; then stat -c %U:%G $kubeletconf; fi'' '\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the following command (using the config file location identified in the Audit step)\n          chown root:root $kubeletconf\n        scored: true\n\n  - id: 3.2\n    text: \"Kubelet\"\n    checks:\n      - id: 3.2.1\n        text: \"Ensure that the Anonymous Auth is Not Enabled (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: \"--anonymous-auth\"\n              path: '{.authentication.anonymous.enabled}'\n              set: true\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Remediation Method 1:\n          If configuring via the Kubelet config file, you first need to locate the file.\n          To do this, SSH to each node and execute the following command to find the kubelet\n          process:\n          ps -ef | grep kubelet\n          The output of the above command provides details of the active kubelet process, from\n          which we can see the location of the configuration file provided to the kubelet service\n          with the --config argument. The file can be viewed with a command such as more or\n          less, like so:\n          sudo less /path/to/kubelet-config.json\n          Disable Anonymous Authentication by setting the following parameter:\n          \"authentication\": { \"anonymous\": { \"enabled\": false } }\n\n          Remediation Method 2.\n          If using executable arguments, edit the kubelet service file on each worker node and\n          ensure the below parameters are part of the KUBELET_ARGS variable string.\n          For systems using systemd, such as the Amazon EKS Optimised Amazon Linux or\n          Bottlerocket AMIs, then this file can be found at\n          /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf. Otherwise,\n          you may need to look up documentation for your chosen operating system to determine\n          which service manager is configured:\n          --anonymous-auth=false\n\n          For Both Remediation Steps:\n          Based on your system, restart the kubelet service and check the service status.\n          The following example is for operating systems using systemd, such as the Amazon\n          EKS Optimised Amazon Linux or Bottlerocket AMIs, and invokes the systemctl\n          command. If systemctl is not available then you will need to look up documentation for\n          your chosen operating system to determine which service manager is configured:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n          systemctl status kubelet -l\n        scored: true\n\n      - id: 3.2.2\n        text: \"Ensure that the --authorization-mode argument is not set to AlwaysAllow (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --authorization-mode\n              path: '{.authorization.mode}'\n              set: true\n              compare:\n                op: nothave\n                value: AlwaysAllow\n        remediation: |\n          Remediation Method 1:\n          If configuring via the Kubelet config file, you first need to locate the file.\n          To do this, SSH to each node and execute the following command to find the kubelet\n          process:\n          ps -ef | grep kubelet\n          The output of the above command provides details of the active kubelet process, from\n          which we can see the location of the configuration file provided to the kubelet service\n          with the --config argument. The file can be viewed with a command such as more or\n          less, like so:\n          sudo less /path/to/kubelet-config.json\n          Enable Webhook Authentication by setting the following parameter:\n          \"authentication\": { \"webhook\": { \"enabled\": true } }\n          Next, set the Authorization Mode to Webhook by setting the following parameter:\n          \"authorization\": { \"mode\": \"Webhook }\n          Finer detail of the authentication and authorization fields can be found in the\n          Kubelet Configuration documentation.\n\n          Remediation Method 2:\n          If using executable arguments, edit the kubelet service file on each worker node and\n          ensure the below parameters are part of the KUBELET_ARGS variable string.\n          For systems using systemd, such as the Amazon EKS Optimised Amazon Linux or\n          Bottlerocket AMIs, then this file can be found at\n          /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf. Otherwise,\n          you may need to look up documentation for your chosen operating system to determine\n          which service manager is configured:\n          --authentication-token-webhook\n          --authorization-mode=Webhook\n\n          For Both Remediation Steps:\n          Based on your system, restart the kubelet service and check the service status.\n          The following example is for operating systems using systemd, such as the Amazon\n          EKS Optimised Amazon Linux or Bottlerocket AMIs, and invokes the systemctl\n          command. If systemctl is not available then you will need to look up documentation for\n          your chosen operating system to determine which service manager is configured:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n          systemctl status kubelet -l\n        scored: true\n\n      - id: 3.2.3\n        text: \"Ensure that a Client CA File is Configured (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --client-ca-file\n              path: '{.authentication.x509.clientCAFile}'\n              set: true\n        remediation: |\n          Remediation Method 1:\n          If configuring via the Kubelet config file, you first need to locate the file.\n          To do this, SSH to each node and execute the following command to find the kubelet\n          process:\n          ps -ef | grep kubelet\n          The output of the above command provides details of the active kubelet process, from\n          which we can see the location of the configuration file provided to the kubelet service\n          with the --config argument. The file can be viewed with a command such as more or\n          less, like so:\n          sudo less /path/to/kubelet-config.json\n          Configure the client certificate authority file by setting the following parameter\n          appropriately:\n          \"authentication\": { \"x509\": {\"clientCAFile\": <path/to/client-ca-file> } }\"\n\n          Remediation Method 2:\n          If using executable arguments, edit the kubelet service file on each worker node and\n          ensure the below parameters are part of the KUBELET_ARGS variable string.\n          For systems using systemd, such as the Amazon EKS Optimised Amazon Linux or\n          Bottlerocket AMIs, then this file can be found at\n          /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf. Otherwise,\n          you may need to look up documentation for your chosen operating system to determine\n          which service manager is configured:\n          --client-ca-file=<path/to/client-ca-file>\n\n          For Both Remediation Steps:\n          Based on your system, restart the kubelet service and check the service status.\n          The following example is for operating systems using systemd, such as the Amazon\n          EKS Optimised Amazon Linux or Bottlerocket AMIs, and invokes the systemctl\n          command. If systemctl is not available then you will need to look up documentation for\n          your chosen operating system to determine which service manager is configured:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n          systemctl status kubelet -l\n        scored: true\n\n      - id: 3.2.4\n        text: \"Ensure that the --read-only-port is disabled (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: \"--read-only-port\"\n              path: '{.readOnlyPort}'\n              set: true\n              compare:\n                op: eq\n                value: 0\n        remediation: |\n          If modifying the Kubelet config file, edit the kubelet-config.json file\n          /etc/kubernetes/kubelet/kubelet-config.json and set the below parameter to 0\n          \"readOnlyPort\": 0\n          If using executable arguments, edit the kubelet service file\n          /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf on each\n          worker node and add the below parameter at the end of the KUBELET_ARGS variable\n          string.\n          --read-only-port=0\n\n          Based on your system, restart the kubelet service and check status\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n          systemctl status kubelet -l\n        scored: true\n\n      - id: 3.2.5\n        text: \"Ensure that the --streaming-connection-idle-timeout argument is not set to 0 (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --streaming-connection-idle-timeout\n              path: '{.streamingConnectionIdleTimeout}'\n              set: true\n              compare:\n                op: noteq\n                value: 0\n            - flag: --streaming-connection-idle-timeout\n              path: '{.streamingConnectionIdleTimeout}'\n              set: false\n          bin_op: or\n        remediation: |\n          Remediation Method 1:\n          If modifying the Kubelet config file, edit the kubelet-config.json file\n          /etc/kubernetes/kubelet/kubelet-config.json and set the below parameter to a\n          non-zero value in the format of #h#m#s\n          \"streamingConnectionIdleTimeout\": \"4h0m0s\"\n          You should ensure that the kubelet service file\n          /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf does not\n          specify a --streaming-connection-idle-timeout argument because it would\n          override the Kubelet config file.\n\n          Remediation Method 2:\n          If using executable arguments, edit the kubelet service file\n          /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf on each\n          worker node and add the below parameter at the end of the KUBELET_ARGS variable\n          string.\n          --streaming-connection-idle-timeout=4h0m0s\n\n          Remediation Method 3:\n          If using the api configz endpoint consider searching for the status of\n          \"streamingConnectionIdleTimeout\": by extracting the live configuration from the\n          nodes running kubelet.\n          **See detailed step-by-step configmap procedures in Reconfigure a Node's Kubelet in a\n          Live Cluster, and then rerun the curl statement from audit process to check for kubelet\n          configuration changes\n          kubectl proxy --port=8001 &\n          export HOSTNAME_PORT=localhost:8001 (example host and port number)\n          export NODE_NAME=ip-192.168.31.226.ec2.internal (example node name from \"kubectl get nodes\")\n          curl -sSL \"http://${HOSTNAME_PORT}/api/v1/nodes/${NODE_NAME}/proxy/configz\"\n\n          For all three remediations:\n          Based on your system, restart the kubelet service and check status\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n          systemctl status kubelet -l\n        scored: true\n\n      - id: 3.2.6\n        text: \"Ensure that the --make-iptables-util-chains argument is set to true (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --make-iptables-util-chains\n              path: '{.makeIPTablesUtilChains}'\n              set: true\n              compare:\n                op: eq\n                value: true\n            - flag: --make-iptables-util-chains\n              path: '{.makeIPTablesUtilChains}'\n              set: false\n          bin_op: or\n        remediation: |\n          Remediation Method 1:\n          If modifying the Kubelet config file, edit the kubelet-config.json file\n          /etc/kubernetes/kubelet/kubelet-config.json and set the below parameter to\n          true\n          \"makeIPTablesUtilChains\": true\n          Ensure that /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf\n          does not set the --make-iptables-util-chains argument because that would\n          override your Kubelet config file.\n\n          Remediation Method 2:\n          If using executable arguments, edit the kubelet service file\n          /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf on each\n          worker node and add the below parameter at the end of the KUBELET_ARGS variable\n          string.\n          --make-iptables-util-chains:true\n\n          Remediation Method 3:\n          If using the api configz endpoint consider searching for the status of\n          \"makeIPTablesUtilChains.: true by extracting the live configuration from the nodes\n          running kubelet.\n          **See detailed step-by-step configmap procedures in Reconfigure a Node's Kubelet in a\n          Live Cluster, and then rerun the curl statement from audit process to check for kubelet\n          configuration changes\n          kubectl proxy --port=8001 &\n          export HOSTNAME_PORT=localhost:8001 (example host and port number)\n          export NODE_NAME=ip-192.168.31.226.ec2.internal (example node name from \"kubectl get nodes\")\n          curl -sSL \"http://${HOSTNAME_PORT}/api/v1/nodes/${NODE_NAME}/proxy/configz\"\n\n          For all three remediations:\n          Based on your system, restart the kubelet service and check status\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n          systemctl status kubelet -l\n        scored: true\n\n      - id: 3.2.7\n        text: \"Ensure that the --eventRecordQPS argument is set to 0 or a level which ensures appropriate event capture (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --event-qps\n              path: '{.eventRecordQPS}'\n              set: true\n              compare:\n                op: gte\n                value: 0\n            - flag: --event-qps\n              path: '{.eventRecordQPS}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to set eventRecordQPS: to an appropriate\n          level.\n          If using command line arguments, edit the kubelet service file\n          /etc/systemd/system/kubelet.service.d/10-kubeadm.conf on each worker node\n          and set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 3.2.8\n        text: \"Ensure that the --rotate-certificates argument is not present or is set to true (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --rotate-certificates\n              path: '{.rotateCertificates}'\n              compare:\n                op: eq\n                value: true\n            - flag: --rotate-certificates\n              path: '{.rotateCertificates}'\n              set: false\n          bin_op: or\n        remediation: |\n          Remediation Method 1:\n          If modifying the Kubelet config file, edit the kubelet-config.json file\n          /etc/kubernetes/kubelet/kubelet-config.json and set the below parameter to\n          true\n          \"RotateCertificate\":true\n          Additionally, ensure that the kubelet service file\n          /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf does not set the --RotateCertificate\n          executable argument to false because this would override the Kubelet\n          config file.\n\n          Remediation Method 2:\n          If using executable arguments, edit the kubelet service file\n          /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf on each\n          worker node and add the below parameter at the end of the KUBELET_ARGS variable\n          string.\n          --RotateCertificate=true\n        scored: true\n\n      - id: 3.2.9\n        text: \"Ensure that the RotateKubeletServerCertificate argument is set to true (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: RotateKubeletServerCertificate\n              path: '{.featureGates.RotateKubeletServerCertificate}'\n              set: true\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Remediation Method 1:\n          If modifying the Kubelet config file, edit the kubelet-config.json file\n          /etc/kubernetes/kubelet/kubelet-config.json and set the below parameter to\n          true\n\n          \"featureGates\": {\n            \"RotateKubeletServerCertificate\":true\n          },\n\n          Additionally, ensure that the kubelet service file\n          /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf does not set\n          the --rotate-kubelet-server-certificate executable argument to false because\n          this would override the Kubelet config file.\n\n          Remediation Method 2:\n          If using executable arguments, edit the kubelet service file\n          /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf on each\n          worker node and add the below parameter at the end of the KUBELET_ARGS variable\n          string.\n          --rotate-kubelet-server-certificate=true\n\n          Remediation Method 3:\n          If using the api configz endpoint consider searching for the status of\n          \"RotateKubeletServerCertificate\": by extracting the live configuration from the\n          nodes running kubelet.\n          **See detailed step-by-step configmap procedures in Reconfigure a Node's Kubelet in a\n          Live Cluster, and then rerun the curl statement from audit process to check for kubelet\n          configuration changes\n          kubectl proxy --port=8001 &\n          export HOSTNAME_PORT=localhost:8001 (example host and port number)\n          export NODE_NAME=ip-192.168.31.226.ec2.internal (example node name from \"kubectl get nodes\")\n          curl -sSL \"http://${HOSTNAME_PORT}/api/v1/nodes/${NODE_NAME}/proxy/configz\"\n\n          For all three remediation methods:\n          Restart the kubelet service and check status. The example below is for when using\n          systemctl to manage services:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n          systemctl status kubelet -l\n        scored: true\n"
  },
  {
    "path": "cfg/eks-1.7.0/policies.yaml",
    "content": "---\ncontrols:\nversion: \"eks-1.7.0\"\nid: 4\ntext: \"Policies\"\ntype: \"policies\"\ngroups:\n  - id: 4.1\n    text: \"RBAC and Service Accounts\"\n    checks:\n      - id: 4.1.1\n        text: \"Ensure that the cluster-admin role is only used where required (Automated)\"\n        audit: |\n          kubectl get clusterrolebindings -o json | jq -r '\n            .items[]\n            | select(.roleRef.name == \"cluster-admin\")\n            | .subjects[]?\n            | select(.kind != \"Group\" or (.name != \"system:masters\" and .name != \"system:nodes\"))\n            | \"FOUND_CLUSTER_ADMIN_BINDING\"\n          ' || echo \"NO_CLUSTER_ADMIN_BINDINGS\"\n        tests:\n          test_items:\n            - flag: \"NO_CLUSTER_ADMIN_BINDINGS\"\n              set: true\n              compare:\n                op: eq\n                value: \"NO_CLUSTER_ADMIN_BINDINGS\"\n        remediation: |\n          Identify all clusterrolebindings to the cluster-admin role. Check if they are used and if\n          they need this role or if they could use a role with fewer privileges.\n          Where possible, first bind users to a lower privileged role and then remove the\n          clusterrolebinding to the cluster-admin role :\n          kubectl delete clusterrolebinding [name]\n        scored: true\n\n      - id: 4.1.2\n        text: \"Minimize access to secrets (Automated)\"\n        audit: |\n          count=$(kubectl get roles --all-namespaces -o json | jq '\n            .items[]\n            | select(.rules[]?\n              | (.resources[]? == \"secrets\")\n              and ((.verbs[]? == \"get\") or (.verbs[]? == \"list\") or (.verbs[]? == \"watch\"))\n            )' | wc -l)\n\n          if [ \"$count\" -gt 0 ]; then\n            echo \"SECRETS_ACCESS_FOUND\"\n          fi\n        tests:\n          test_items:\n            - flag: \"SECRETS_ACCESS_FOUND\"\n              set: false\n        remediation: |\n          Where possible, remove get, list and watch access to secret objects in the cluster.\n        scored: true\n\n      - id: 4.1.3\n        text: \"Minimize wildcard use in Roles and ClusterRoles (Automated)\"\n        audit: |\n          wildcards=$(kubectl get roles --all-namespaces -o json | jq '\n            .items[] | select(\n              .rules[]? | (.verbs[]? == \"*\" or .resources[]? == \"*\" or .apiGroups[]? == \"*\")\n            )' | wc -l)\n\n          wildcards_clusterroles=$(kubectl get clusterroles -o json | jq '\n            .items[] | select(\n              .rules[]? | (.verbs[]? == \"*\" or .resources[]? == \"*\" or .apiGroups[]? == \"*\")\n            )' | wc -l)\n\n          total=$((wildcards + wildcards_clusterroles))\n\n          if [ \"$total\" -gt 0 ]; then\n            echo \"wildcards_present\"\n          fi\n        tests:\n          test_items:\n            - flag: wildcards_present\n              set: false\n        remediation: |\n          Where possible replace any use of wildcards in clusterroles and roles with specific\n          objects or actions.\n        scored: true\n\n      - id: 4.1.4\n        text: \"Minimize access to create pods (Automated)\"\n        audit: |\n          access=$(kubectl get roles,clusterroles -A -o json | jq '\n            [.items[] |\n              select(\n                .rules[]? |\n                (.resources[]? == \"pods\" and .verbs[]? == \"create\")\n              )\n            ] | length')\n\n          if [ \"$access\" -gt 0 ]; then\n            echo \"pods_create_access\"\n          fi\n        tests:\n          test_items:\n            - flag: pods_create_access\n              set: false\n        remediation: |\n          Where possible, remove create access to pod objects in the cluster.\n        scored: true\n\n      - id: 4.1.5\n        text: \"Ensure that default service accounts are not actively used. (Automated)\"\n        audit: |\n          default_sa_count=$(kubectl get serviceaccounts --all-namespaces -o json | jq '\n            [.items[] | select(.metadata.name == \"default\" and (.automountServiceAccountToken != false))] | length')\n          if [ \"$default_sa_count\" -gt 0 ]; then\n            echo \"default_sa_not_auto_mounted\"\n          fi\n\n          pods_using_default_sa=$(kubectl get pods --all-namespaces -o json | jq '\n            [.items[] | select(.spec.serviceAccountName == \"default\")] | length')\n          if [ \"$pods_using_default_sa\" -gt 0 ]; then\n            echo \"default_sa_used_in_pods\"\n          fi\n        tests:\n          test_items:\n            - flag: default_sa_not_auto_mounted\n              set: false\n            - flag: default_sa_used_in_pods\n              set: false\n        remediation: |\n          Create explicit service accounts wherever a Kubernetes workload requires specific\n          access to the Kubernetes API server.\n          Modify the configuration of each default service account to include this value\n          automountServiceAccountToken: false\n\n          Automatic remediation for the default account:\n          kubectl patch serviceaccount default -p\n          $'automountServiceAccountToken: false'\n        scored: true\n\n      - id: 4.1.6\n        text: \"Ensure that Service Account Tokens are only mounted where necessary (Automated)\"\n        audit: |\n          pods_with_token_mount=$(kubectl get pods --all-namespaces -o json | jq '\n            [.items[] | select(.spec.automountServiceAccountToken != false)] | length')\n\n          if [ \"$pods_with_token_mount\" -gt 0 ]; then\n            echo \"automountServiceAccountToken\"\n          fi\n        tests:\n          test_items:\n            - flag: automountServiceAccountToken\n              set: false\n        remediation: |\n          Regularly review pod and service account objects in the cluster to ensure that the automountServiceAccountToken setting is false for pods and accounts that do not explicitly require API server access.\n        scored: true\n\n      - id: 4.1.7\n        text: \"Cluster Access Manager API to streamline and enhance the management of access controls within EKS clusters (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Log in to the AWS Management Console.\n            Navigate to Amazon EKS and select your EKS cluster.\n\n            Go to the Access tab and click on \"Manage Access\" in the \"Access Configuration section\".\n            Under Cluster Authentication Mode for Cluster Access settings.\n            Click EKS API to change cluster will source authenticated IAM principals only from EKS access entry APIs.\n            Click ConfigMap to change cluster will source authenticated IAM principals only from the aws-auth ConfigMap.\n          Note: EKS API and ConfigMap must be selected during Cluster creation and cannot be changed once the Cluster is provisioned.\n        scored: false\n\n      - id: 4.1.8\n        text: \"Limit use of the Bind, Impersonate and Escalate permissions in the Kubernetes cluster (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove the impersonate, bind and escalate rights from subjects.\n        scored: false\n\n  - id: 4.2\n    text: \"Pod Security Standards\"\n    checks:\n      - id: 4.2.1\n        text: \"Minimize the admission of privileged containers (Automated)\"\n        audit: |\n          kubectl get pods --all-namespaces -o json | \\\n            jq -r 'if any(.items[]?.spec.containers[]?; .securityContext?.privileged == true) then \"PRIVILEGED_FOUND\" else \"NO_PRIVILEGED\" end'\n        tests:\n          test_items:\n            - flag: \"NO_PRIVILEGED\"\n              set: true\n              compare:\n                op: eq\n                value: \"NO_PRIVILEGED\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the admission of privileged containers.\n            To enable PSA for a namespace in your cluster, set the pod-security.kubernetes.io/enforce label with the policy value you want to enforce.\n            kubectl label --overwrite ns NAMESPACE pod-security.kubernetes.io/enforce=restricted\n            The above command enforces the restricted policy for the NAMESPACE namespace.\n          You can also enable Pod Security Admission for all your namespaces. For example:\n            kubectl label --overwrite ns --all pod-security.kubernetes.io/warn=baseline\n        scored: true\n\n      - id: 4.2.2\n        text: \"Minimize the admission of containers wishing to share the host process ID namespace (Automated)\"\n        audit: |\n          kubectl get pods --all-namespaces -o json | \\\n            jq -r 'if any(.items[]?; .spec.hostPID == true) then \"HOSTPID_FOUND\" else \"NO_HOSTPID\" end'\n        tests:\n          test_items:\n            - flag: \"NO_HOSTPID\"\n              set: true\n              compare:\n                op: eq\n                value: \"NO_HOSTPID\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of hostPID containers.\n        scored: true\n\n      - id: 4.2.3\n        text: \"Minimize the admission of containers wishing to share the host IPC namespace (Automated)\"\n        audit: |\n          kubectl get pods --all-namespaces -o json | jq -r 'if any(.items[]?; .spec.hostIPC == true) then \"HOSTIPC_FOUND\" else \"NO_HOSTIPC\" end'\n        tests:\n          test_items:\n            - flag: \"NO_HOSTIPC\"\n              set: true\n              compare:\n                op: eq\n                value: \"NO_HOSTIPC\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of hostIPC containers.\n        scored: true\n\n      - id: 4.2.4\n        text: \"Minimize the admission of containers wishing to share the host network namespace (Automated)\"\n        audit: |\n          kubectl get pods --all-namespaces -o json | jq -r 'if any(.items[]?; .spec.hostNetwork == true) then \"HOSTNETWORK_FOUND\" else \"NO_HOSTNETWORK\" end'\n        tests:\n          test_items:\n            - flag: \"NO_HOSTNETWORK\"\n              set: true\n              compare:\n                op: eq\n                value: \"NO_HOSTNETWORK\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of hostNetwork containers.\n        scored: true\n\n      - id: 4.2.5\n        text: \"Minimize the admission of containers with allowPrivilegeEscalation (Automated)\"\n        audit: |\n          kubectl get pods --all-namespaces -o json | \\\n            jq -r 'if any(.items[]?.spec.containers[]?; .securityContext?.allowPrivilegeEscalation == true) then \"ALLOWPRIVILEGEESCALTION_FOUND\" else \"NO_ALLOWPRIVILEGEESCALTION\" end'\n        tests:\n          test_items:\n            - flag: \"NO_ALLOWPRIVILEGEESCALTION\"\n              set: true\n              compare:\n                op: eq\n                value: \"NO_ALLOWPRIVILEGEESCALTION\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers with .spec.allowPrivilegeEscalation set to true.\n        scored: true\n\n  - id: 4.3\n    text: \"CNI Plugin\"\n    checks:\n      - id: 4.3.1\n        text: \"Ensure CNI plugin supports network policies (Manual)\"\n        type: \"manual\"\n        remediation: |\n          As with RBAC policies, network policies should adhere to the policy of least privileged\n          access. Start by creating a deny all policy that restricts all inbound and outbound traffic\n          from a namespace or create a global policy using Calico.\n        scored: false\n\n      - id: 4.3.2\n        text: \"Ensure that all Namespaces have Network Policies defined (Automated)\"\n        audit: |\n          ns_without_np=$(kubectl get namespaces -o json | jq -r '.items[].metadata.name' | while read ns; do\n            count=$(kubectl get networkpolicy -n $ns --no-headers 2>/dev/null | wc -l)\n            if [ \"$count\" -eq 0 ]; then echo $ns; fi\n          done)\n          if [ -z \"$ns_without_np\" ]; then\n            echo \"ALL_NAMESPACES_HAVE_NETWORK_POLICIES\"\n          else\n            echo \"NAMESPACES_WITHOUT_NETWORK_POLICIES: $ns_without_np\"\n          fi\n        tests:\n          test_items:\n            - flag: \"ALL_NAMESPACES_HAVE_NETWORK_POLICIES\"\n              set: true\n              compare:\n                op: eq\n                value: \"ALL_NAMESPACES_HAVE_NETWORK_POLICIES\"\n        remediation: |\n          Create at least one NetworkPolicy in each namespace to control and restrict traffic between pods as needed.\n        scored: true\n\n  - id: 4.4\n    text: \"Secrets Management\"\n    checks:\n      - id: 4.4.1\n        text: \"Prefer using secrets as files over secrets as environment variables (Automated)\"\n        audit: |\n          result=$(kubectl get all --all-namespaces -o jsonpath='{range .items[?(@..secretKeyRef)]}{.metadata.namespace} {.kind} {.metadata.name}{\"\\n\"}{end}')\n          if [ -z \"$result\" ]; then\n            echo \"NO_SECRETS_AS_ENV_VARS\"\n          else\n            echo \"SECRETS_AS_ENV_VARS_FOUND: $result\"\n          fi\n        tests:\n          test_items:\n            - flag: \"NO_SECRETS_AS_ENV_VARS\"\n              set: true\n              compare:\n                op: eq\n                value: \"NO_SECRETS_AS_ENV_VARS\"\n        remediation: |\n          If possible, rewrite application code to read secrets from mounted secret files, rather than\n          from environment variables.\n        scored: true\n\n      - id: 4.4.2\n        text: \"Consider external secret storage (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Refer to the secrets management options offered by your cloud provider or a third-party\n          secrets management solution.\n        scored: false\n\n  - id: 4.5\n    text: \"General Policies\"\n    checks:\n      - id: 4.5.1\n        text: \"Create administrative boundaries between resources using namespaces (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the documentation and create namespaces for objects in your deployment as you need\n          them.\n        scored: false\n\n      - id: 4.5.2\n        text: \"The default namespace should not be used (Automated)\"\n        audit: |\n          output=$(kubectl get $(kubectl api-resources --verbs=list --namespaced=true -o name | paste -sd, -) --ignore-not-found -n default 2>/dev/null | grep -v \"^kubernetes \")\n          if [ -z \"$output\" ]; then\n            echo \"NO_USER_RESOURCES_IN_DEFAULT\"\n          else\n            echo \"USER_RESOURCES_IN_DEFAULT_FOUND: $output\"\n          fi\n        tests:\n          test_items:\n            - flag: \"NO_USER_RESOURCES_IN_DEFAULT\"\n              set: true\n        remediation: |\n          Create and use dedicated namespaces for resources instead of the default namespace. Move any user-defined objects out of the default namespace to improve resource segregation and RBAC control.\n        scored: true\n"
  },
  {
    "path": "cfg/eks-1.8.0/config.yaml",
    "content": "---\n## Version-specific settings that override the values in cfg/config.yaml\n## These settings are required if you are using the --asff option to report findings to AWS Security Hub\n## AWS account number is required.\nAWS_ACCOUNT: \"<AWS_ACCT_NUMBER>\"\n## AWS region is required.\nAWS_REGION: \"<AWS_REGION>\"\n## EKS Cluster ARN is required.\nCLUSTER_ARN: \"<AWS_CLUSTER_ARN>\"\n"
  },
  {
    "path": "cfg/eks-1.8.0/controlplane.yaml",
    "content": "---\ncontrols:\nversion: \"eks-1.8.0\"\nid: 2\ntext: \"Control Plane Configuration\"\ntype: \"controlplane\"\ngroups:\n  - id: 2.1\n    text: \"Logging\"\n    checks:\n      - id: 2.1.1\n        text: \"Enable audit Logs (Manual)\"\n        type: manual\n        remediation: |\n          From Console:\n          1.  For each EKS Cluster in each region;\n          2.  Go to 'Amazon EKS' > 'Clusters' > '' > 'Configuration' > 'Logging'.\n          3.  Click 'Manage logging'.\n          4.  Ensure that all options are toggled to 'Enabled'.\n                API server: Enabled\n                Audit: Enabled\n                Authenticator: Enabled\n                Controller manager: Enabled\n                Scheduler: Enabled\n          5.  Click 'Save Changes'.\n\n          From CLI:\n          # For each EKS Cluster in each region;\n          aws eks update-cluster-config \\\n            --region '${REGION_CODE}' \\\n            --name '${CLUSTER_NAME}' \\\n            --logging '{\"clusterLogging\":[{\"types\":[\"api\",\"audit\",\"authenticator\",\"controllerManager\",\"scheduler\"],\"enabled\":true}]}'\n        scored: false\n\n      - id: 2.1.2\n        text: \"Ensure audit logs are collected and managed (Manual)\"\n        type: manual\n        remediation: |\n          Create or update the audit-policy.yaml to specify the audit logging configuration:\n          apiVersion: audit.k8s.io/v1\n          kind: Policy\n          rules:\n            - level: Metadata\n              resources:\n                - group: \"\"\n                  resources: [\"pods\"]\n          Apply the audit policy configuration to the cluster:\n            kubectl apply -f <path-to-audit-policy>.yaml\n          Ensure audit logs are forwarded to a centralized logging system like CloudWatch, Elasticsearch, or another log management solution:\n            kubectl create configmap cluster-audit-policy --from-file=audit-policy.yaml -n kube-system\n            kubectl apply -f - <<EOF\n          apiVersion: v1\n          kind: Pod\n          metadata:\n            name: audit-logging\n            namespace: kube-system\n          spec:\n            containers:\n              - name: audit-log-forwarder\n                image: my-log-forwarder-image\n                volumeMounts:\n                  - mountPath: /etc/kubernetes/audit\n                    name: audit-config\n            volumes:\n              - name: audit-config\n                configMap:\n                  name: cluster-audit-policy\n            EOF\n        scored: false\n"
  },
  {
    "path": "cfg/eks-1.8.0/managedservices.yaml",
    "content": "---\ncontrols:\nversion: \"eks-1.8.0\"\nid: 5\ntext: \"Managed Services\"\ntype: \"managedservices\"\ngroups:\n  - id: 5.1\n    text: \"Image Registry and Image Scanning\"\n    checks:\n      - id: 5.1.1\n        text: \"Ensure Image Vulnerability Scanning using Amazon ECR image scanning or a third party provider (Manual)\"\n        type: \"manual\"\n        remediation: |\n          To utilize AWS ECR for Image scanning please follow the steps below:\n\n          To create a repository configured for scan on push (AWS CLI):\n          aws ecr create-repository --repository-name $REPO_NAME --image-scanning-configuration scanOnPush=true --region $REGION_CODE\n\n          To edit the settings of an existing repository (AWS CLI):\n          aws ecr put-image-scanning-configuration --repository-name $REPO_NAME --image-scanning-configuration scanOnPush=true --region $REGION_CODE\n\n          Use the following steps to start a manual image scan using the AWS Management Console.\n\n          1.  Open the Amazon ECR console at https://console.aws.amazon.com/ecr/repositories.\n          2.  From the navigation bar, choose the Region to create your repository in.\n          3.  In the navigation pane, choose Repositories.\n          4.  On the Repositories page, choose the repository that contains the image to scan.\n          5.  On the Images page, select the image to scan and then choose Scan.\n        scored: false\n\n      - id: 5.1.2\n        text: \"Minimize user access to Amazon ECR (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Before you use IAM to manage access to Amazon ECR, you should understand what IAM features\n          are available to use with Amazon ECR. To get a high-level view of how Amazon ECR and other\n          AWS services work with IAM, see AWS Services That Work with IAM in the IAM User Guide.\n        scored: false\n\n      - id: 5.1.3\n        text: \"Minimize cluster access to read-only for Amazon ECR (Manual)\"\n        type: \"manual\"\n        remediation: |\n          You can use your Amazon ECR images with Amazon EKS, but you need to satisfy the following prerequisites.\n\n          The Amazon EKS worker node IAM role (NodeInstanceRole) that you use with your worker nodes must possess\n          the following IAM policy permissions for Amazon ECR.\n\n          {\n              \"Version\": \"2012-10-17\",\n              \"Statement\": [\n                  {\n                      \"Effect\": \"Allow\",\n                      \"Action\": [\n                          \"ecr:BatchCheckLayerAvailability\",\n                          \"ecr:BatchGetImage\",\n                          \"ecr:GetDownloadUrlForLayer\",\n                          \"ecr:GetAuthorizationToken\"\n                      ],\n                      \"Resource\": \"*\"\n                  }\n              ]\n          }\n        scored: false\n\n      - id: 5.1.4\n        text: \"Minimize Container Registries to only those approved (Manual)\"\n        type: \"manual\"\n        remediation: |\n          To minimize AWS ECR container registries to only those approved, you can follow these steps:\n\n          1.  Define your approval criteria: Determine the criteria that containers must meet to\n              be considered approved. This can include factors such as security, compliance,\n              compatibility, and other requirements.\n          2.  Identify all existing ECR registries: Identify all ECR registries that are currently\n              being used in your organization.\n          3.  Evaluate ECR registries against approval criteria: Evaluate each ECR registry\n              against your approval criteria to determine whether it should be approved or not.\n              This can be done by reviewing the registry settings and configuration, as well as\n              conducting security assessments and vulnerability scans.\n          4.  Establish policies and procedures: Establish policies and procedures that outline\n              how ECR registries will be approved, maintained, and monitored. This should\n              include guidelines for developers to follow when selecting a registry for their\n              container images.\n          5.  Implement access controls: Implement access controls to ensure that only\n              approved ECR registries are used to store and distribute container images. This\n              can be done by setting up IAM policies and roles that restrict access to\n              unapproved registries or create a whitelist of approved registries.\n          6.  Monitor and review: Continuously monitor and review the use of ECR registries\n              to ensure that they continue to meet your approval criteria. This can include\n        scored: false\n\n  - id: 5.2\n    text: \"Identity and Access Management (IAM)\"\n    checks:\n      - id: 5.2.1\n        text: \"Prefer using dedicated Amazon EKS Service Accounts (Manual)\"\n        type: \"manual\"\n        remediation: |\n          With IAM roles for service accounts on Amazon EKS clusters, you can associate an\n          IAM role with a Kubernetes service account. This service account can then provide\n          AWS permissions to the containers in any pod that uses that service account. With this\n          feature, you no longer need to provide extended permissions to the worker node IAM\n          role so that pods on that node can call AWS APIs.\n          Applications must sign their AWS API requests with AWS credentials. This feature\n          provides a strategy for managing credentials for your applications, similar to the way\n          that Amazon EC2 instance profiles provide credentials to Amazon EC2 instances.\n          Instead of creating and distributing your AWS credentials to the containers or using the\n          Amazon EC2 instance’s role, you can associate an IAM role with a Kubernetes service\n          account. The applications in the pod’s containers can then use an AWS SDK or the\n          AWS CLI to make API requests to authorized AWS services.\n\n          The IAM roles for service accounts feature provides the following benefits:\n\n          - Least privilege - By using the IAM roles for service accounts feature, you no\n            longer need to provide extended permissions to the worker node IAM role so that\n            pods on that node can call AWS APIs. You can scope IAM permissions to a\n            service account, and only pods that use that service account have access to\n            those permissions. This feature also eliminates the need for third-party solutions\n            such as kiam or kube2iam.\n          - Credential isolation - A container can only retrieve credentials for the IAM role\n            that is associated with the service account to which it belongs. A container never\n            has access to credentials that are intended for another container that belongs to\n            another pod.\n          - Audit-ability - Access and event logging is available through CloudTrail to help\n            ensure retrospective auditing.\n        scored: false\n\n  - id: 5.3\n    text: \"AWS EKS Key Management Service\"\n    checks:\n      - id: 5.3.1\n        text: \"Ensure Kubernetes Secrets are encrypted using Customer Master Keys (CMKs) managed in AWS KMS (Manual)\"\n        type: \"manual\"\n        remediation: |\n          This process can only be performed during Cluster Creation.\n\n          Enable 'Secrets Encryption' during Amazon EKS cluster creation as described\n          in the links within the 'References' section.\n        scored: false\n\n  - id: 5.4\n    text: \"Cluster Networking\"\n    checks:\n      - id: 5.4.1\n        text: \"Restrict Access to the Control Plane Endpoint (Manual)\"\n        type: \"manual\"\n        remediation: |\n          By enabling private endpoint access to the Kubernetes API server, all communication\n          between your nodes and the API server stays within your VPC. You can also limit the IP\n          addresses that can access your API server from the internet, or completely disable\n          internet access to the API server.\n          With this in mind, you can update your cluster accordingly using the AWS CLI to ensure\n          that Private Endpoint Access is enabled.\n          If you choose to also enable Public Endpoint Access then you should also configure a\n          list of allowable CIDR blocks, resulting in restricted access from the internet. If you\n          specify no CIDR blocks, then the public API server endpoint is able to receive and\n          process requests from all IP addresses by defaulting to ['0.0.0.0/0'].\n          For example, the following command would enable private access to the Kubernetes\n          API as well as limited public access over the internet from a single IP address (noting\n          the /32 CIDR suffix):\n          aws eks update-cluster-config --region $AWS_REGION --name $CLUSTER_NAME --resources-vpc-config endpointPrivateAccess=true,publicAccessCidrs=\"203.0.113.5/32\"\n\n          Note: The CIDR blocks specified cannot include reserved addresses.\n          There is a maximum number of CIDR blocks that you can specify. For more information,\n          see the EKS Service Quotas link in the references section.\n          For more detailed information, see the EKS Cluster Endpoint documentation link in the\n          references section.\n        scored: false\n\n      - id: 5.4.2\n        text: \"Ensure clusters are created with Private Endpoint Enabled and Public Access Disabled (Manual)\"\n        type: \"manual\"\n        remediation: |\n          By enabling private endpoint access to the Kubernetes API server, all communication\n          between your nodes and the API server stays within your VPC.\n          With this in mind, you can update your cluster accordingly using the AWS CLI to ensure\n          that Private Endpoint Access is enabled.\n          For example, the following command would enable private access to the Kubernetes\n          API and ensure that no public access is permitted:\n          aws eks update-cluster-config --region $AWS_REGION --name $CLUSTER_NAME --resources-vpc-config endpointPrivateAccess=true,endpointPublicAccess=false\n\n          Note: For more detailed information, see the EKS Cluster Endpoint documentation link\n          in the references section.\n        scored: false\n\n      - id: 5.4.3\n        text: \"Ensure clusters are created with Private Nodes (Manual)\"\n        type: \"manual\"\n        remediation: |\n          aws eks update-cluster-config \\\n            --region region-code \\\n            --name my-cluster \\\n            --resources-vpc-config endpointPublicAccess=true,publicAccessCidrs=\"203.0.113.5/32\",endpointPrivateAccess=true\n        scored: false\n\n      - id: 5.4.4\n        text: \"Ensure Network Policy is Enabled and set as appropriate (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Utilize Calico or other network policy engine to segment and isolate your traffic.\n        scored: false\n\n      - id: 5.4.5\n        text: \"Encrypt traffic to HTTPS load balancers with TLS certificates (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Your load balancer vendor can provide details on configuring HTTPS with TLS.\n        scored: false\n\n\n  - id: 5.5\n    text: \"Authentication and Authorization\"\n    checks:\n      - id: 5.5.1\n        text: \"Manage Kubernetes RBAC users with AWS IAM Authenticator for Kubernetes or Upgrade to AWS CLI v1.16.156 or greater (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Refer to the 'Managing users or IAM roles for your cluster' in Amazon EKS documentation.\n\n          Note: If using AWS CLI version 1.16.156 or later there is no need to install the AWS\n          IAM Authenticator anymore.\n          The relevant AWS CLI commands, depending on the use case, are:\n          aws eks update-kubeconfig\n          aws eks get-token\n        scored: false\n"
  },
  {
    "path": "cfg/eks-1.8.0/master.yaml",
    "content": "---\ncontrols:\nversion: \"eks-1.8.0\"\nid: 1\ntext: \"Control Plane Components\"\ntype: \"master\"\n"
  },
  {
    "path": "cfg/eks-1.8.0/node.yaml",
    "content": "---\ncontrols:\nversion: \"eks-1.8.0\"\nid: 3\ntext: \"Worker Nodes\"\ntype: \"node\"\ngroups:\n  - id: 3.1\n    text: \"Worker Node Configuration Files\"\n    checks:\n      - id: 3.1.1\n        text: \"Ensure that the kubeconfig file permissions are set to 644 or more restrictive (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletkubeconfig; then stat -c permissions=%a $kubeletkubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chmod 644 $kubeletkubeconfig\n        scored: true\n\n      - id: 3.1.2\n        text: \"Ensure that the kubelet kubeconfig file ownership is set to root:root (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletkubeconfig; then stat -c %U:%G $kubeletkubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chown root:root $kubeletkubeconfig\n        scored: true\n\n      - id: 3.1.3\n        text: \"Ensure that the kubelet configuration file has permissions set to 644 or more restrictive (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletconf; then stat -c permissions=%a $kubeletconf; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the following command (using the config file location identified in the Audit step)\n          chmod 644 $kubeletconf\n        scored: true\n\n      - id: 3.1.4\n        text: \"Ensure that the kubelet configuration file ownership is set to root:root (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletconf; then stat -c %U:%G $kubeletconf; fi'' '\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the following command (using the config file location identified in the Audit step)\n          chown root:root $kubeletconf\n        scored: true\n\n  - id: 3.2\n    text: \"Kubelet\"\n    checks:\n      - id: 3.2.1\n        text: \"Ensure that the Anonymous Auth is Not Enabled (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: \"--anonymous-auth\"\n              path: '{.authentication.anonymous.enabled}'\n              set: true\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Remediation Method 1:\n          If configuring via the Kubelet config file, you first need to locate the file.\n          To do this, SSH to each node and execute the following command to find the kubelet\n          process:\n          ps -ef | grep kubelet\n          The output of the above command provides details of the active kubelet process, from\n          which we can see the location of the configuration file provided to the kubelet service\n          with the --config argument. The file can be viewed with a command such as more or\n          less, like so:\n          sudo less /path/to/kubelet-config.json\n          Disable Anonymous Authentication by setting the following parameter:\n          \"authentication\": { \"anonymous\": { \"enabled\": false } }\n\n          Remediation Method 2.\n          If using executable arguments, edit the kubelet service file on each worker node and\n          ensure the below parameters are part of the KUBELET_ARGS variable string.\n          For systems using systemd, such as the Amazon EKS Optimised Amazon Linux or\n          Bottlerocket AMIs, then this file can be found at\n          /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf. Otherwise,\n          you may need to look up documentation for your chosen operating system to determine\n          which service manager is configured:\n          --anonymous-auth=false\n\n          For Both Remediation Steps:\n          Based on your system, restart the kubelet service and check the service status.\n          The following example is for operating systems using systemd, such as the Amazon\n          EKS Optimised Amazon Linux or Bottlerocket AMIs, and invokes the systemctl\n          command. If systemctl is not available then you will need to look up documentation for\n          your chosen operating system to determine which service manager is configured:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n          systemctl status kubelet -l\n        scored: true\n\n      - id: 3.2.2\n        text: \"Ensure that the --authorization-mode argument is not set to AlwaysAllow (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --authorization-mode\n              path: '{.authorization.mode}'\n              set: true\n              compare:\n                op: nothave\n                value: AlwaysAllow\n        remediation: |\n          Remediation Method 1:\n          If configuring via the Kubelet config file, you first need to locate the file.\n          To do this, SSH to each node and execute the following command to find the kubelet\n          process:\n          ps -ef | grep kubelet\n          The output of the above command provides details of the active kubelet process, from\n          which we can see the location of the configuration file provided to the kubelet service\n          with the --config argument. The file can be viewed with a command such as more or\n          less, like so:\n          sudo less /path/to/kubelet-config.json\n          Enable Webhook Authentication by setting the following parameter:\n          \"authentication\": { \"webhook\": { \"enabled\": true } }\n          Next, set the Authorization Mode to Webhook by setting the following parameter:\n          \"authorization\": { \"mode\": \"Webhook }\n          Finer detail of the authentication and authorization fields can be found in the\n          Kubelet Configuration documentation.\n\n          Remediation Method 2:\n          If using executable arguments, edit the kubelet service file on each worker node and\n          ensure the below parameters are part of the KUBELET_ARGS variable string.\n          For systems using systemd, such as the Amazon EKS Optimised Amazon Linux or\n          Bottlerocket AMIs, then this file can be found at\n          /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf. Otherwise,\n          you may need to look up documentation for your chosen operating system to determine\n          which service manager is configured:\n          --authentication-token-webhook\n          --authorization-mode=Webhook\n\n          For Both Remediation Steps:\n          Based on your system, restart the kubelet service and check the service status.\n          The following example is for operating systems using systemd, such as the Amazon\n          EKS Optimised Amazon Linux or Bottlerocket AMIs, and invokes the systemctl\n          command. If systemctl is not available then you will need to look up documentation for\n          your chosen operating system to determine which service manager is configured:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n          systemctl status kubelet -l\n        scored: true\n\n      - id: 3.2.3\n        text: \"Ensure that a Client CA File is Configured (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --client-ca-file\n              path: '{.authentication.x509.clientCAFile}'\n              set: true\n        remediation: |\n          Remediation Method 1:\n          If configuring via the Kubelet config file, you first need to locate the file.\n          To do this, SSH to each node and execute the following command to find the kubelet\n          process:\n          ps -ef | grep kubelet\n          The output of the above command provides details of the active kubelet process, from\n          which we can see the location of the configuration file provided to the kubelet service\n          with the --config argument. The file can be viewed with a command such as more or\n          less, like so:\n          sudo less /path/to/kubelet-config.json\n          Configure the client certificate authority file by setting the following parameter\n          appropriately:\n          \"authentication\": { \"x509\": {\"clientCAFile\": <path/to/client-ca-file> } }\"\n\n          Remediation Method 2:\n          If using executable arguments, edit the kubelet service file on each worker node and\n          ensure the below parameters are part of the KUBELET_ARGS variable string.\n          For systems using systemd, such as the Amazon EKS Optimised Amazon Linux or\n          Bottlerocket AMIs, then this file can be found at\n          /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf. Otherwise,\n          you may need to look up documentation for your chosen operating system to determine\n          which service manager is configured:\n          --client-ca-file=<path/to/client-ca-file>\n\n          For Both Remediation Steps:\n          Based on your system, restart the kubelet service and check the service status.\n          The following example is for operating systems using systemd, such as the Amazon\n          EKS Optimised Amazon Linux or Bottlerocket AMIs, and invokes the systemctl\n          command. If systemctl is not available then you will need to look up documentation for\n          your chosen operating system to determine which service manager is configured:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n          systemctl status kubelet -l\n        scored: true\n\n      - id: 3.2.4\n        text: \"Ensure that the --read-only-port is disabled (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: \"--read-only-port\"\n              path: '{.readOnlyPort}'\n              set: true\n              compare:\n                op: eq\n                value: 0\n        remediation: |\n          If modifying the Kubelet config file, edit the kubelet-config.json file\n          /etc/kubernetes/kubelet/kubelet-config.json and set the below parameter to 0\n          \"readOnlyPort\": 0\n          If using executable arguments, edit the kubelet service file\n          /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf on each\n          worker node and add the below parameter at the end of the KUBELET_ARGS variable\n          string.\n          --read-only-port=0\n\n          Based on your system, restart the kubelet service and check status\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n          systemctl status kubelet -l\n        scored: true\n\n      - id: 3.2.5\n        text: \"Ensure that the --streaming-connection-idle-timeout argument is not set to 0 (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --streaming-connection-idle-timeout\n              path: '{.streamingConnectionIdleTimeout}'\n              set: true\n              compare:\n                op: noteq\n                value: 0\n            - flag: --streaming-connection-idle-timeout\n              path: '{.streamingConnectionIdleTimeout}'\n              set: false\n          bin_op: or\n        remediation: |\n          Remediation Method 1:\n          If modifying the Kubelet config file, edit the kubelet-config.json file\n          /etc/kubernetes/kubelet/kubelet-config.json and set the below parameter to a\n          non-zero value in the format of #h#m#s\n          \"streamingConnectionIdleTimeout\": \"4h0m0s\"\n          You should ensure that the kubelet service file\n          /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf does not\n          specify a --streaming-connection-idle-timeout argument because it would\n          override the Kubelet config file.\n\n          Remediation Method 2:\n          If using executable arguments, edit the kubelet service file\n          /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf on each\n          worker node and add the below parameter at the end of the KUBELET_ARGS variable\n          string.\n          --streaming-connection-idle-timeout=4h0m0s\n\n          Remediation Method 3:\n          If using the api configz endpoint consider searching for the status of\n          \"streamingConnectionIdleTimeout\": by extracting the live configuration from the\n          nodes running kubelet.\n          **See detailed step-by-step configmap procedures in Reconfigure a Node's Kubelet in a\n          Live Cluster, and then rerun the curl statement from audit process to check for kubelet\n          configuration changes\n          kubectl proxy --port=8001 &\n          export HOSTNAME_PORT=localhost:8001 (example host and port number)\n          export NODE_NAME=ip-192.168.31.226.ec2.internal (example node name from \"kubectl get nodes\")\n          curl -sSL \"http://${HOSTNAME_PORT}/api/v1/nodes/${NODE_NAME}/proxy/configz\"\n\n          For all three remediations:\n          Based on your system, restart the kubelet service and check status\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n          systemctl status kubelet -l\n        scored: true\n\n      - id: 3.2.6\n        text: \"Ensure that the --make-iptables-util-chains argument is set to true (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --make-iptables-util-chains\n              path: '{.makeIPTablesUtilChains}'\n              set: true\n              compare:\n                op: eq\n                value: true\n            - flag: --make-iptables-util-chains\n              path: '{.makeIPTablesUtilChains}'\n              set: false\n          bin_op: or\n        remediation: |\n          Remediation Method 1:\n          If modifying the Kubelet config file, edit the kubelet-config.json file\n          /etc/kubernetes/kubelet/kubelet-config.json and set the below parameter to\n          true\n          \"makeIPTablesUtilChains\": true\n          Ensure that /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf\n          does not set the --make-iptables-util-chains argument because that would\n          override your Kubelet config file.\n\n          Remediation Method 2:\n          If using executable arguments, edit the kubelet service file\n          /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf on each\n          worker node and add the below parameter at the end of the KUBELET_ARGS variable\n          string.\n          --make-iptables-util-chains:true\n\n          Remediation Method 3:\n          If using the api configz endpoint consider searching for the status of\n          \"makeIPTablesUtilChains.: true by extracting the live configuration from the nodes\n          running kubelet.\n          **See detailed step-by-step configmap procedures in Reconfigure a Node's Kubelet in a\n          Live Cluster, and then rerun the curl statement from audit process to check for kubelet\n          configuration changes\n          kubectl proxy --port=8001 &\n          export HOSTNAME_PORT=localhost:8001 (example host and port number)\n          export NODE_NAME=ip-192.168.31.226.ec2.internal (example node name from \"kubectl get nodes\")\n          curl -sSL \"http://${HOSTNAME_PORT}/api/v1/nodes/${NODE_NAME}/proxy/configz\"\n\n          For all three remediations:\n          Based on your system, restart the kubelet service and check status\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n          systemctl status kubelet -l\n        scored: true\n\n      - id: 3.2.7\n        text: \"Ensure that the --eventRecordQPS argument is set to 0 or a level which ensures appropriate event capture (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --event-qps\n              path: '{.eventRecordQPS}'\n              set: true\n              compare:\n                op: gte\n                value: 0\n            - flag: --event-qps\n              path: '{.eventRecordQPS}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to set eventRecordQPS: to an appropriate\n          level.\n          If using command line arguments, edit the kubelet service file\n          /etc/systemd/system/kubelet.service.d/10-kubeadm.conf on each worker node\n          and set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 3.2.8\n        text: \"Ensure that the --rotate-certificates argument is not present or is set to true (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --rotate-certificates\n              path: '{.rotateCertificates}'\n              compare:\n                op: eq\n                value: true\n            - flag: --rotate-certificates\n              path: '{.rotateCertificates}'\n              set: false\n          bin_op: or\n        remediation: |\n          Remediation Method 1:\n          If modifying the Kubelet config file, edit the kubelet-config.json file\n          /etc/kubernetes/kubelet/kubelet-config.json and set the below parameter to\n          true\n          \"RotateCertificate\":true\n          Additionally, ensure that the kubelet service file\n          /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf does not set the --RotateCertificate\n          executable argument to false because this would override the Kubelet\n          config file.\n\n          Remediation Method 2:\n          If using executable arguments, edit the kubelet service file\n          /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf on each\n          worker node and add the below parameter at the end of the KUBELET_ARGS variable\n          string.\n          --rotate-certificates=true\n        scored: true\n\n      - id: 3.2.9\n        text: \"Ensure that the RotateKubeletServerCertificate argument is set to true (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: RotateKubeletServerCertificate\n              path: '{.featureGates.RotateKubeletServerCertificate}'\n              set: true\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Remediation Method 1:\n          If modifying the Kubelet config file, edit the kubelet-config.json file\n          /etc/kubernetes/kubelet/kubelet-config.json and set the below parameter to\n          true\n\n          \"featureGates\": {\n            \"RotateKubeletServerCertificate\":true\n          },\n\n          Additionally, ensure that the kubelet service file\n          /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf does not set\n          the --rotate-kubelet-server-certificate executable argument to false because\n          this would override the Kubelet config file.\n\n          Remediation Method 2:\n          If using executable arguments, edit the kubelet service file\n          /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf on each\n          worker node and add the below parameter at the end of the KUBELET_ARGS variable\n          string.\n          --rotate-kubelet-server-certificate=true\n\n          Remediation Method 3:\n          If using the api configz endpoint consider searching for the status of\n          \"RotateKubeletServerCertificate\": by extracting the live configuration from the\n          nodes running kubelet.\n          **See detailed step-by-step configmap procedures in Reconfigure a Node's Kubelet in a\n          Live Cluster, and then rerun the curl statement from audit process to check for kubelet\n          configuration changes\n          kubectl proxy --port=8001 &\n          export HOSTNAME_PORT=localhost:8001 (example host and port number)\n          export NODE_NAME=ip-192.168.31.226.ec2.internal (example node name from \"kubectl get nodes\")\n          curl -sSL \"http://${HOSTNAME_PORT}/api/v1/nodes/${NODE_NAME}/proxy/configz\"\n\n          For all three remediation methods:\n          Restart the kubelet service and check status. The example below is for when using\n          systemctl to manage services:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n          systemctl status kubelet -l\n        scored: true\n"
  },
  {
    "path": "cfg/eks-1.8.0/policies.yaml",
    "content": "---\ncontrols:\nversion: \"eks-1.8.0\"\nid: 4\ntext: \"Policies\"\ntype: \"policies\"\ngroups:\n  - id: 4.1\n    text: \"RBAC and Service Accounts\"\n    checks:\n      - id: 4.1.1\n        text: \"Ensure that the cluster-admin role is only used where required (Automated)\"\n        audit: |\n          kubectl get clusterrolebindings -o json | jq -r '\n            .items[]\n            | select(.roleRef.name == \"cluster-admin\")\n            | .subjects[]?\n            | select(.kind != \"Group\" or (.name != \"system:masters\" and .name != \"system:nodes\"))\n            | \"FOUND_CLUSTER_ADMIN_BINDING\"\n          ' || echo \"NO_CLUSTER_ADMIN_BINDINGS\"\n        tests:\n          test_items:\n            - flag: \"NO_CLUSTER_ADMIN_BINDINGS\"\n              set: true\n              compare:\n                op: eq\n                value: \"NO_CLUSTER_ADMIN_BINDINGS\"\n        remediation: |\n          Identify all clusterrolebindings to the cluster-admin role. Check if they are used and if\n          they need this role or if they could use a role with fewer privileges.\n          Where possible, first bind users to a lower privileged role and then remove the\n          clusterrolebinding to the cluster-admin role :\n          kubectl delete clusterrolebinding [name]\n        scored: true\n\n      - id: 4.1.2\n        text: \"Minimize access to secrets (Automated)\"\n        audit: |\n          count=$(kubectl get roles --all-namespaces -o json | jq '\n            .items[]\n            | select(.rules[]?\n              | (.resources[]? == \"secrets\")\n              and ((.verbs[]? == \"get\") or (.verbs[]? == \"list\") or (.verbs[]? == \"watch\"))\n            )' | wc -l)\n\n          if [ \"$count\" -gt 0 ]; then\n            echo \"SECRETS_ACCESS_FOUND\"\n          fi\n        tests:\n          test_items:\n            - flag: \"SECRETS_ACCESS_FOUND\"\n              set: false\n        remediation: |\n          Where possible, remove get, list and watch access to secret objects in the cluster.\n        scored: true\n\n      - id: 4.1.3\n        text: \"Minimize wildcard use in Roles and ClusterRoles (Automated)\"\n        audit: |\n          wildcards=$(kubectl get roles --all-namespaces -o json | jq '\n            .items[] | select(\n              .rules[]? | (.verbs[]? == \"*\" or .resources[]? == \"*\" or .apiGroups[]? == \"*\")\n            )' | wc -l)\n\n          wildcards_clusterroles=$(kubectl get clusterroles -o json | jq '\n            .items[] | select(\n              .rules[]? | (.verbs[]? == \"*\" or .resources[]? == \"*\" or .apiGroups[]? == \"*\")\n            )' | wc -l)\n\n          total=$((wildcards + wildcards_clusterroles))\n\n          if [ \"$total\" -gt 0 ]; then\n            echo \"wildcards_present\"\n          fi\n        tests:\n          test_items:\n            - flag: wildcards_present\n              set: false\n        remediation: |\n          Where possible replace any use of wildcards in clusterroles and roles with specific\n          objects or actions.\n        scored: true\n\n      - id: 4.1.4\n        text: \"Minimize access to create pods (Automated)\"\n        audit: |\n          access=$(kubectl get roles,clusterroles -A -o json | jq '\n            [.items[] |\n              select(\n                .rules[]? |\n                (.resources[]? == \"pods\" and .verbs[]? == \"create\")\n              )\n            ] | length')\n\n          if [ \"$access\" -gt 0 ]; then\n            echo \"pods_create_access\"\n          fi\n        tests:\n          test_items:\n            - flag: pods_create_access\n              set: false\n        remediation: |\n          Where possible, remove create access to pod objects in the cluster.\n        scored: true\n\n      - id: 4.1.5\n        text: \"Ensure that default service accounts are not actively used. (Automated)\"\n        audit: |\n          default_sa_count=$(kubectl get serviceaccounts --all-namespaces -o json | jq '\n            [.items[] | select(.metadata.name == \"default\" and (.automountServiceAccountToken != false))] | length')\n          if [ \"$default_sa_count\" -gt 0 ]; then\n            echo \"default_sa_not_auto_mounted\"\n          fi\n          pods_using_default_sa=$(kubectl get pods --all-namespaces -o json | jq '\n            [.items[] | select(.spec.serviceAccountName == \"default\")] | length')\n          if [ \"$pods_using_default_sa\" -gt 0 ]; then\n            echo \"default_sa_used_in_pods\"\n          fi\n        tests:\n          test_items:\n            - flag: default_sa_not_auto_mounted\n              set: false\n            - flag: default_sa_used_in_pods\n              set: false\n        remediation: |\n          Create explicit service accounts wherever a Kubernetes workload requires specific\n          access to the Kubernetes API server.\n          Modify the configuration of each default service account to include this value\n          automountServiceAccountToken: false\n          Automatic remediation for the default account:\n          kubectl patch serviceaccount default -p\n          $'automountServiceAccountToken: false'\n        scored: true\n\n      - id: 4.1.6\n        text: \"Ensure that Service Account Tokens are only mounted where necessary (Automated)\"\n        audit: |\n          pods_with_token_mount=$(kubectl get pods --all-namespaces -o json | jq '\n            [.items[] | select(.spec.automountServiceAccountToken != false)] | length')\n\n          if [ \"$pods_with_token_mount\" -gt 0 ]; then\n            echo \"automountServiceAccountToken\"\n          fi\n        tests:\n          test_items:\n            - flag: automountServiceAccountToken\n              set: false\n        remediation: |\n          Regularly review pod and service account objects in the cluster to ensure that the automountServiceAccountToken setting is false for pods and accounts that do not explicitly require API server access.\n        scored: true\n\n      - id: 4.1.7\n        text: \"Cluster Access Manager API to streamline and enhance the management of access controls within EKS clusters (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Log in to the AWS Management Console.\n            Navigate to Amazon EKS and select your EKS cluster.\n\n            Go to the Access tab and click on \"Manage Access\" in the \"Access Configuration section\".\n            Under Cluster Authentication Mode for Cluster Access settings.\n            Click EKS API to change cluster will source authenticated IAM principals only from EKS access entry APIs.\n            Click ConfigMap to change cluster will source authenticated IAM principals only from the aws-auth ConfigMap.\n          Note: EKS API and ConfigMap must be selected during Cluster creation and cannot be changed once the Cluster is provisioned.\n        scored: false\n\n      - id: 4.1.8\n        text: \"Limit use of the Bind, Impersonate and Escalate permissions in the Kubernetes cluster (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove the impersonate, bind and escalate rights from subjects.\n        scored: false\n\n      - id: 4.1.9\n        text: \"Minimize access to create PersistentVolume objects (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Review the RBAC rules in the cluster and identify users, groups, or service accounts\n          with create permissions on PersistentVolume resources.\n          Where possible, remove or restrict create access to PersistentVolume objects to\n          trusted administrators only.\n        scored: false\n\n      - id: 4.1.10\n        text: \"Minimize access to the proxy sub-resource of Node objects (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Review RBAC roles and bindings in the cluster to identify users, groups,\n          or service accounts with access to the proxy sub-resource of Node objects.\n          Where possible, remove or restrict access to the node proxy sub-resource\n          to trusted administrators only.\n        scored: false\n\n      - id: 4.1.11\n        text: \"Minimize access to webhook configuration objects (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Review RBAC roles and bindings in the cluster to identify users, groups,\n          or service accounts with access to validatingwebhookconfigurations or\n          mutatingwebhookconfigurations objects. Where possible, remove or restrict\n          access to these webhook configuration objects to trusted administrators only.\n        scored: false\n\n      - id: 4.1.12\n        text: \"Minimize access to the service account token creation (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Review RBAC roles and bindings in the cluster to identify users, groups,\n          or service accounts with access to create the token sub-resource of\n          serviceaccount objects. Where possible, remove or restrict access to\n          token creation to trusted administrators only.\n        scored: false\n\n  - id: 4.2\n    text: \"Pod Security Standards\"\n    checks:\n      - id: 4.2.1\n        text: \"Minimize the admission of privileged containers (Automated)\"\n        audit: |\n          kubectl get pods --all-namespaces -o json | \\\n            jq -r 'if any(.items[]?.spec.containers[]?; .securityContext?.privileged == true) then \"PRIVILEGED_FOUND\" else \"NO_PRIVILEGED\" end'\n        tests:\n          test_items:\n            - flag: \"NO_PRIVILEGED\"\n              set: true\n              compare:\n                op: eq\n                value: \"NO_PRIVILEGED\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the admission of privileged containers.\n            To enable PSA for a namespace in your cluster, set the pod-security.kubernetes.io/enforce label with the policy value you want to enforce.\n            kubectl label --overwrite ns NAMESPACE pod-security.kubernetes.io/enforce=restricted\n            The above command enforces the restricted policy for the NAMESPACE namespace.\n          You can also enable Pod Security Admission for all your namespaces. For example:\n            kubectl label --overwrite ns --all pod-security.kubernetes.io/warn=baseline\n        scored: true\n\n      - id: 4.2.2\n        text: \"Minimize the admission of containers wishing to share the host process ID namespace (Automated)\"\n        audit: |\n          kubectl get pods --all-namespaces -o json | \\\n            jq -r 'if any(.items[]?; .spec.hostPID == true) then \"HOSTPID_FOUND\" else \"NO_HOSTPID\" end'\n        tests:\n          test_items:\n            - flag: \"NO_HOSTPID\"\n              set: true\n              compare:\n                op: eq\n                value: \"NO_HOSTPID\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of hostPID containers.\n        scored: true\n\n      - id: 4.2.3\n        text: \"Minimize the admission of containers wishing to share the host IPC namespace (Automated)\"\n        audit: |\n          kubectl get pods --all-namespaces -o json | jq -r 'if any(.items[]?; .spec.hostIPC == true) then \"HOSTIPC_FOUND\" else \"NO_HOSTIPC\" end'\n        tests:\n          test_items:\n            - flag: \"NO_HOSTIPC\"\n              set: true\n              compare:\n                op: eq\n                value: \"NO_HOSTIPC\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of hostIPC containers.\n        scored: true\n\n      - id: 4.2.4\n        text: \"Minimize the admission of containers wishing to share the host network namespace (Automated)\"\n        audit: |\n          kubectl get pods --all-namespaces -o json | jq -r 'if any(.items[]?; .spec.hostNetwork == true) then \"HOSTNETWORK_FOUND\" else \"NO_HOSTNETWORK\" end'\n        tests:\n          test_items:\n            - flag: \"NO_HOSTNETWORK\"\n              set: true\n              compare:\n                op: eq\n                value: \"NO_HOSTNETWORK\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of hostNetwork containers.\n        scored: true\n\n      - id: 4.2.5\n        text: \"Minimize the admission of containers with allowPrivilegeEscalation (Automated)\"\n        audit: |\n          kubectl get pods --all-namespaces -o json | \\\n            jq -r 'if any(.items[]?.spec.containers[]?; .securityContext?.allowPrivilegeEscalation == true) then \"ALLOWPRIVILEGEESCALTION_FOUND\" else \"NO_ALLOWPRIVILEGEESCALATION\" end'\n        tests:\n          test_items:\n            - flag: \"NO_ALLOWPRIVILEGEESCALATION\"\n              set: true\n              compare:\n                op: eq\n                value: \"NO_ALLOWPRIVILEGEESCALATION\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers with .spec.allowPrivilegeEscalation set to true.\n        scored: true\n\n  - id: 4.3\n    text: \"CNI Plugin\"\n    checks:\n      - id: 4.3.1\n        text: \"Ensure CNI plugin supports network policies (Manual)\"\n        type: \"manual\"\n        remediation: |\n          As with RBAC policies, network policies should adhere to the policy of least privileged\n          access. Start by creating a deny all policy that restricts all inbound and outbound traffic\n          from a namespace or create a global policy using Calico.\n        scored: false\n\n      - id: 4.3.2\n        text: \"Ensure that all Namespaces have Network Policies defined (Automated)\"\n        audit: |\n          ns_without_np=$(kubectl get namespaces -o json | jq -r '.items[].metadata.name' | while read ns; do\n            count=$(kubectl get networkpolicy -n $ns --no-headers 2>/dev/null | wc -l)\n            if [ \"$count\" -eq 0 ]; then echo $ns; fi\n          done)\n          if [ -z \"$ns_without_np\" ]; then\n            echo \"ALL_NAMESPACES_HAVE_NETWORK_POLICIES\"\n          else\n            echo \"NAMESPACES_WITHOUT_NETWORK_POLICIES: $ns_without_np\"\n          fi\n        tests:\n          test_items:\n            - flag: \"ALL_NAMESPACES_HAVE_NETWORK_POLICIES\"\n              set: true\n              compare:\n                op: eq\n                value: \"ALL_NAMESPACES_HAVE_NETWORK_POLICIES\"\n        remediation: |\n          Create at least one NetworkPolicy in each namespace to control and restrict traffic between pods as needed.\n        scored: true\n\n  - id: 4.4\n    text: \"Secrets Management\"\n    checks:\n      - id: 4.4.1\n        text: \"Prefer using secrets as files over secrets as environment variables (Automated)\"\n        audit: |\n          result=$(kubectl get all --all-namespaces -o jsonpath='{range .items[?(@..secretKeyRef)]}{.metadata.namespace} {.kind} {.metadata.name}{\"\\n\"}{end}')\n          if [ -z \"$result\" ]; then\n            echo \"NO_SECRETS_AS_ENV_VARS\"\n          else\n            echo \"SECRETS_AS_ENV_VARS_FOUND: $result\"\n          fi\n        tests:\n          test_items:\n            - flag: \"NO_SECRETS_AS_ENV_VARS\"\n              set: true\n              compare:\n                op: eq\n                value: \"NO_SECRETS_AS_ENV_VARS\"\n        remediation: |\n          If possible, rewrite application code to read secrets from mounted secret files, rather than\n          from environment variables.\n        scored: true\n\n      - id: 4.4.2\n        text: \"Consider external secret storage (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Refer to the secrets management options offered by your cloud provider or a third-party\n          secrets management solution.\n        scored: false\n\n  - id: 4.5\n    text: \"General Policies\"\n    checks:\n      - id: 4.5.1\n        text: \"Create administrative boundaries between resources using namespaces (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the documentation and create namespaces for objects in your deployment as you need\n          them.\n        scored: false\n\n      - id: 4.5.2\n        text: \"The default namespace should not be used (Automated)\"\n        audit: |\n          output=$(kubectl get $(kubectl api-resources --verbs=list --namespaced=true -o name | paste -sd, -) --ignore-not-found -n default 2>/dev/null | grep -v \"^kubernetes \")\n          if [ -z \"$output\" ]; then\n            echo \"NO_USER_RESOURCES_IN_DEFAULT\"\n          else\n            echo \"USER_RESOURCES_IN_DEFAULT_FOUND: $output\"\n          fi\n        tests:\n          test_items:\n            - flag: \"NO_USER_RESOURCES_IN_DEFAULT\"\n              set: true\n        remediation: |\n          Create and use dedicated namespaces for resources instead of the default namespace. Move any user-defined objects out of the default namespace to improve resource segregation and RBAC control.\n        scored: true\n"
  },
  {
    "path": "cfg/eks-stig-kubernetes-v1r6/config.yaml",
    "content": "---\n## Version-specific settings that override the values in cfg/config.yaml\n## These settings are required if you are using the --asff option to report findings to AWS Security Hub\n## AWS account number is required.\nAWS_ACCOUNT: \"<AWS_ACCT_NUMBER>\"\n## AWS region is required.\nAWS_REGION: \"<AWS_REGION>\"\n## EKS Cluster ARN is required.\nCLUSTER_ARN: \"<AWS_CLUSTER_ARN>\"\n"
  },
  {
    "path": "cfg/eks-stig-kubernetes-v1r6/controlplane.yaml",
    "content": "---\ncontrols:\nversion: \"eks-stig-kubernetes-v1r6\"\nid: 2\ntext: \"Control Plane Configuration\"\ntype: \"controlplane\"\ngroups:\n  - id: 2.1\n    text: \"DISA Category Code I\"\n    checks:\n      - id: V-242390\n        text: \"The Kubernetes API server must have anonymous authentication disabled (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: \"--anonymous-auth\"\n              path: '{.authentication.anonymous.enabled}'\n              set: true\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          If using a Kubelet config file, edit $kubeletconf to set authentication: anonymous: enabled to\n          false.\n          If using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --anonymous-auth=false\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n      - id: V-242400\n        text: \"The Kubernetes API server must have Alpha APIs disabled (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--feature-gates\"\n              compare:\n                op: nothave\n                value: \"AllAlpha=true\"\n              set: true\n            - flag: \"--feature-gates\"\n              set: false\n        remediation: |\n          Edit any manifest files or $kubeletconf that contain the feature-gates\n          setting with AllAlpha set to \"true\".\n          Set the flag to \"false\" or remove the \"AllAlpha\" setting\n          completely. Restart the kubelet service if the kubelet config file\n          if the kubelet config file is changed.\n        scored: true\n  - id: 2.2\n    text: \"DISA Category Code II\"\n    checks:\n      - id: V-242381\n        text: \"The Kubernetes Controller Manager must create unique service accounts for each work payload. (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Create explicit service accounts wherever a Kubernetes workload requires specific access\n          to the Kubernetes API server.\n          Modify the configuration of each default service account to include this value\n          automountServiceAccountToken: false\n        scored: false\n      - id: V-242402\n        text: \"The Kubernetes API Server must have an audit log path set (Manual)\"\n        type: \"manual\"\n        remediation: |\n            Enable control plane logging for API Server, Audit, Authenticator, Controller Manager, and Scheduler.\n            Ref: https://docs.aws.amazon.com/eks/latest/userguide/control-plane-logs.html\n        scored: false\n      - id: V-242403\n        text: \"Kubernetes API Server must generate audit records (Manual)\"\n        type: \"manual\"\n        remediation: |\n            Enable control plane logging for API Server, Audit, Authenticator, Controller Manager, and Scheduler.\n            Ref: https://docs.aws.amazon.com/eks/latest/userguide/control-plane-logs.html\n        scored: false\n      - id: V-242461\n        text: \"Kubernetes API Server audit logs must be enabled. (Manual)\"\n        type: \"manual\"\n        remediation: |\n            Enable control plane logging for API Server, Audit, Authenticator, Controller Manager, and Scheduler.\n            Ref: https://docs.aws.amazon.com/eks/latest/userguide/control-plane-logs.html\n        scored: false\n      - id: V-242462\n        text: \"The Kubernetes API Server must be set to audit log max size. (Manual)\"\n        type: \"manual\"\n        remediation: |\n            Enable control plane logging for API Server, Audit, Authenticator, Controller Manager, and Scheduler.\n            Ref: https://docs.aws.amazon.com/eks/latest/userguide/control-plane-logs.html\n        scored: false\n      - id: V-242463\n        text: \"The Kubernetes API Server must be set to audit log maximum backup. (Manual)\"\n        type: \"manual\"\n        remediation: |\n            Enable control plane logging for API Server, Audit, Authenticator, Controller Manager, and Scheduler.\n            Ref: https://docs.aws.amazon.com/eks/latest/userguide/control-plane-logs.html\n        scored: false\n      - id: V-242464\n        text: \"The Kubernetes API Server audit log retention must be set. (Manual)\"\n        type: \"manual\"\n        remediation: |\n            Enable control plane logging for API Server, Audit, Authenticator, Controller Manager, and Scheduler.\n            Ref: https://docs.aws.amazon.com/eks/latest/userguide/control-plane-logs.html\n        scored: false\n      - id: V-242465\n        text: \"The Kubernetes API Server audit log path must be set. (Manual)\"\n        type: \"manual\"\n        remediation: |\n            Enable control plane logging for API Server, Audit, Authenticator, Controller Manager, and Scheduler.\n            Ref: https://docs.aws.amazon.com/eks/latest/userguide/control-plane-logs.html\n        scored: false\n  - id: 2.2\n    text: \"DISA Category Code II\"\n    checks:\n      - id: V-242443\n        text: \" Kubernetes must contain the latest updates as authorized by IAVMs, CTOs, DTMs, and STIGs. (Manual)\"\n        type: \"manual\"\n        remediation: |\n         Upgrade Kubernetes to a supported version.\n         Ref: https://docs.aws.amazon.com/eks/latest/userguide/update-cluster.html\n"
  },
  {
    "path": "cfg/eks-stig-kubernetes-v1r6/managedservices.yaml",
    "content": "---\ncontrols:\nversion: \"eks-stig-kubernetes-v1r6\"\nid: 5\ntext: \"Managed Services\"\ntype: \"managedservices\"\ngroups:\n  - id: 5.1\n    text: \"DISA Category Code I\"\n    checks:\n      - id: V-242386\n        text: \"The Kubernetes API server must have the insecure port flag disabled | Component of EKS Control Plane\"\n        type: \"skip\"\n\n      - id: V-242388\n        text: \"The Kubernetes API server must have the insecure bind address not set | Component of EKS Control Plane\"\n        type: \"skip\"\n\n      - id: V-242436\n        text: \"The Kubernetes API server must have the ValidatingAdmissionWebhook enabled (manual)\"\n        type: \"manual\"\n        remediation: |\n         Amazon EKS version 1.18 and later automatically enable ValidatingAdmissionWebhook\n         Ref: https://docs.aws.amazon.com/eks/latest/userguide/platform-versions.html\n        scored: false\n\n      - id: V-245542\n        text: \"Kubernetes API Server must disable basic authentication to protect information in transit | Component of EKS Control Plane\"\n        type: \"skip\"\n\n  - id: 5.2\n    text: \"DISA Category Code II\"\n    checks:\n      - id: V-242376\n        text: \"The Kubernetes Controller Manager must use TLS 1.2, at a minimum | Component of EKS Control Plane\"\n        type: \"skip\"\n\n      - id: V-242377\n        text: \"The Kubernetes Scheduler must use TLS 1.2, at a minimum | Component of EKS Control Plane\"\n        type: \"skip\"\n\n      - id: V-242378\n        text: \"The Kubernetes API Server must use TLS 1.2, at a minimum | Component of EKS Control Plane\"\n        type: \"skip\"\n\n      - id: V-242379\n        text: \"The Kubernetes etcd must use TLS to protect the confidentiality of sensitive data during electronic dissemination | Component of EKS Control Plane\"\n        type: \"skip\"\n\n      - id: V-242380\n        text: \"The Kubernetes etcd must use TLS to protect the confidentiality of sensitive data during electronic dissemination | Component of EKS Control Plane\"\n        type: \"skip\"\n\n      - id: V-242382\n        text: \"The Kubernetes API Server must enable Node,RBAC as the authorization mode | Component of EKS Control Plane\"\n        type: \"skip\"\n\n      - id: V-242384\n        text: \"The Kubernetes Scheduler must have secure binding | Component of EKS Control Plane\"\n        type: \"skip\"\n\n      - id: V-242385\n        text: \"The Kubernetes Controller Manager must have secure binding | Component of EKS Control Plane\"\n        type: \"skip\"\n\n      - id: V-242389\n        text: \"The Kubernetes API server must have the secure port set | Component of EKS Control Plane\"\n        type: \"skip\"\n\n      - id: V-242401\n        text: \"The Kubernetes API Server must have an audit policy set | Component of EKS Control Plane\"\n        type: \"skip\"\n\n      - id: V-242402\n        text: \"The Kubernetes API Server must have an audit log path set | Component of EKS Control Plane\"\n        type: \"skip\"\n\n      - id: V-242403\n        text: \"Kubernetes API Server must generate audit records | Component of EKS Control Plane\"\n        type: \"skip\"\n\n      - id: V-242405\n        text: \"The Kubernetes manifests must be owned by root | Component of EKS Control Plane\"\n        type: \"skip\"\n\n      - id: V-242408\n        text: \"The Kubernetes manifests must have least privileges | Component of EKS Control Plane\"\n        type: \"skip\"\n\n      - id: V-242409\n        text: \"Kubernetes Controller Manager must disable profiling | Component of EKS Control Plane\"\n        type: \"skip\"\n\n      - id: V-242410\n        text: \"The Kubernetes API Server must enforce PPS that adhere to PPSM CAL | Component of EKS Control Plane\"\n        type: \"skip\"\n\n      - id: V-242411\n        text: \"The Kubernetes Scheduler must enforce PPS that adhere to PPSM CAL | Component of EKS Control Plane\"\n        type: \"skip\"\n\n      - id: V-242412\n        text: \"The Kubernetes Controllers must enforce PPS that adhere to PPSM CAL | Component of EKS Control Plane\"\n        type: \"skip\"\n\n      - id: V-242413\n        text: \"The Kubernetes etcd must enforce PPS that adhere to PPSM CAL | Component of EKS Control Plane\"\n        type: \"skip\"\n\n      - id: V-242418\n        text: \"The Kubernetes API server must use approved cipher suites | Component of EKS Control Plane\"\n        type: \"skip\"\n\n      - id: V-242419\n        text: \"Kubernetes API Server must have the SSL Certificate Authority set | Component of EKS Control Plane\"\n        type: \"skip\"\n\n      - id: V-242420\n        text: \"Kubernetes Kubelet must have the SSL Certificate Authority set | Component of EKS Control Plane\"\n        type: \"skip\"\n\n      - id: V-242421\n        text: \"Kubernetes Controller Manager must have the SSL Certificate Authority set | Component of EKS Control Plane\"\n        type: \"skip\"\n\n      - id: V-242422\n        text: \"Kubernetes API Server must have a certificate for communication | Component of EKS Control Plane\"\n        type: \"skip\"\n\n      - id: V-242423\n        text: \"Kubernetes etcd must enable client authentication to secure service | Component of EKS Control Plane\"\n        type: \"skip\"\n\n      - id: V-242424\n        text: \"Kubernetes etcd must enable client authentication to secure service | Component of EKS Control Plane\"\n        type: \"skip\"\n\n      - id: V-242425\n        text: \"Kubernetes Kubelet must enable tls-cert-file for client authentication to secure service | Component of EKS Control Plane\"\n        type: \"skip\"\n\n      - id: V-242426\n        text: \"Kubernetes etcd must enable client authentication to secure service | Component of EKS Control Plane\"\n        type: \"skip\"\n\n      - id: V-242427\n        text: \"Kubernetes etcd must have a key file for secure communication | Component of EKS Control Plane\"\n        type: \"skip\"\n\n      - id: V-242428\n        text: \"Kubernetes etcd must have a certificate for communication | Component of EKS Control Plane\"\n        type: \"skip\"\n\n      - id: V-242429\n        text: \"Kubernetes etcd must have the SSL Certificate Authority set | Component of EKS Control Plane\"\n        type: \"skip\"\n\n      - id: V-242430\n        text: \"Kubernetes etcd must have a certificate for communication | Component of EKS Control Plane\"\n        type: \"skip\"\n\n      - id: V-242431\n        text: \"Kubernetes etcd must have a key file for secure communication | Component of EKS Control Plane\"\n        type: \"skip\"\n\n      - id: V-242432\n        text: \"Kubernetes etcd must have peer-cert-file set for secure communication | Component of EKS Control Plane\"\n        type: \"skip\"\n\n      - id: V-242433\n        text: \"Kubernetes etcd must have a peer-key-file set for secure communication | Component of EKS Control Plane\"\n        type: \"skip\"\n\n      - id: V-242438\n        text: \"Kubernetes API Server must configure timeouts to limit attack surface | Component of EKS Control Plane\"\n        type: \"skip\"\n\n      - id: V-242444\n        text: \"The Kubernetes component manifests must be owned by root | Component of EKS Control Plane\"\n        type: \"skip\"\n\n      - id: V-242445\n        text: \"The Kubernetes component etcd must be owned by etcd | Component of EKS Control Plane\"\n        type: \"skip\"\n\n      - id: V-242446\n        text: \"The Kubernetes conf files must be owned by root | Component of EKS Control Plane\"\n        type: \"skip\"\n\n      - id: V-242447\n        text: \"The Kubernetes Kube Proxy must have file permissions set to 644 or more restrictive | Component of EKS Control Plane\"\n        type: \"skip\"\n\n      - id: V-242448\n        text: \"The Kubernetes Kube Proxy must be owned by root | Component of EKS Control Plane\"\n        type: \"skip\"\n\n      - id: V-242449\n        text: \"The Kubernetes Kubelet certificate authority file must have file permissions set to 644 or more restrictive | Component of EKS Control Plane\"\n        type: \"skip\"\n\n      - id: V-242450\n        text: \"The Kubernetes Kubelet certificate authority must be owned by root | Component of EKS Control Plane\"\n        type: \"skip\"\n\n      - id: V-242451\n        text: \"The Kubernetes component PKI must be owned by root | Component of EKS Control Plane\"\n        type: \"skip\"\n\n      - id: V-242452\n        text: \"The Kubernetes kubelet config must have file permissions set to 644 or more restrictive | Component of EKS Control Plane\"\n        type: \"skip\"\n\n      - id: V-242453\n        text: \"The Kubernetes kubelet config must be owned by root | Component of EKS Control Plane\"\n        type: \"skip\"\n\n      - id: V-242454\n        text: \"The Kubernetes kubeadm.conf must be owned by root | Component of EKS Control Plane\"\n        type: \"skip\"\n\n      - id: V-242455\n        text: \"The Kubernetes kubeadm.conf must have file permissions set to 644 or more restrictive | Component of EKS Control Plane\"\n        type: \"skip\"\n\n      - id: V-242456\n        text: \"The Kubernetes kubelet config must have file permissions set to 644 or more restrictive | Component of EKS Control Plane\"\n        type: \"skip\"\n\n      - id: V-242457\n        text: \"The Kubernetes kubelet config must be owned by root | Component of EKS Control Plane\"\n        type: \"skip\"\n\n      - id: V-242458\n        text: \"The Kubernetes API Server must have file permissions set to 644 or more restrictive | Component of EKS Control Plane\"\n        type: \"skip\"\n\n      - id: V-242459\n        text: \"The Kubernetes etcd must have file permissions set to 644 or more restrictive | Component of EKS Control Plane\"\n        type: \"skip\"\n\n      - id: V-242460\n        text: \"The Kubernetes admin.conf must have file permissions set to 644 or more restrictive | Component of EKS Control Plane\"\n        type: \"skip\"\n\n      - id: V-242466\n        text: \"The Kubernetes PKI CRT must have file permissions set to 644 or more restrictive | Component of EKS Control Plane\"\n        type: \"skip\"\n\n      - id: V-242467\n        text: \"The Kubernetes PKI keys must have file permissions set to 600 or more restrictive | Component of EKS Control Plane\"\n        type: \"skip\"\n\n      - id: V-242468\n        text: \"The Kubernetes API Server must prohibit communication using TLS version 1.0 and 1.1, and SSL 2.0 and 3.0 | Component of EKS Control Plane\"\n        type: \"skip\"\n\n      - id: V-245541\n        text: \"Kubernetes Kubelet must not disable timeouts | Component of EKS Control Plane\"\n        type: \"skip\"\n\n      - id: V-245543\n        text: \"Kubernetes API Server must disable token authentication to protect information in transit | Component of EKS Control Plane\"\n        type: \"skip\"\n\n      - id: V-245544\n        text: \"Kubernetes endpoints must use approved organizational certificate and key pair to protect information in transit | Component of EKS Control Plane\"\n        type: \"skip\"\n"
  },
  {
    "path": "cfg/eks-stig-kubernetes-v1r6/master.yaml",
    "content": "---\ncontrols:\nversion: \"eks-stig-kubernetes-v1r6\"\nid: 1\ntext: \"Control Plane Components\"\ntype: \"master\"\n"
  },
  {
    "path": "cfg/eks-stig-kubernetes-v1r6/node.yaml",
    "content": "---\ncontrols:\nversion: \"eks-stig-kubernetes-v1r6\"\nid: 3\ntext: \"Worker Node Security Configuration\"\ntype: \"node\"\ngroups:\n  - id: 3.1\n    text: \"DISA Category Code I\"\n    checks:\n      - id: V-242387   # CIS 3.2.4\n        text: \"The Kubernetes Kubelet must have the read-only port flag disabled (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: \"--read-only-port\"\n              path: '{.readOnlyPort}'\n              set: true\n              compare:\n                op: eq\n                value: 0\n        remediation: |\n          If using a Kubelet config file, edit $kubeletconf to set readOnlyPort to 0.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --read-only-port=0\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n      - id: V-242391  # CIS 3.2.1\n        text: \"The Kubernetes Kubelet must have anonymous authentication disabled (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: \"--anonymous-auth\"\n              path: '{.authentication.anonymous.enabled}'\n              set: true\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          If using a Kubelet config file, edit $kubeletconf to set authentication: anonymous: enabled to\n          false.\n          If using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --anonymous-auth=false\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n      - id: V-242392  # CIS 3.2.2\n        text: \"The Kubernetes kubelet must enable explicit authorization (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --authorization-mode\n              path: '{.authorization.mode}'\n              set: true\n              compare:\n                op: nothave\n                value: AlwaysAllow\n        remediation: |\n          If using a Kubelet config file, edit $kubeletconf to set authorization: mode to Webhook. If\n          using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_AUTHZ_ARGS variable.\n          --authorization-mode=Webhook\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n      - id: V-242397\n        text: \"The Kubernetes kubelet static PodPath must not enable static pods (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - path: '{.staticPodPath}'\n              set: false\n        remediation: |\n          Edit $kubeletconf on each node to to remove the staticPodPath\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n      - id: V-242415\n        text: \"Secrets in Kubernetes must not be stored as environment variables.(Manual)\"\n        type: \"manual\"\n        remediation: |\n         Run the following command:\n         kubectl get all -o jsonpath='{range .items[?(@..secretKeyRef)]} {.kind} {.metadata.name} {\"\\n\"}{end}' -A\n         If any of the values returned reference environment variables\n         rewrite application code to read secrets from mounted secret files, rather than\n         from environment variables.\n        scored: false\n      - id: V-242434  # CIS 3.2.6\n        text: \"Kubernetes Kubelet must enable kernel protection (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --protect-kernel-defaults\n              path: '{.protectKernelDefaults}'\n              set: true\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          If using a Kubelet config file, edit $kubeletconf to set protectKernelDefaults: true.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --protect-kernel-defaults=true\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n      - id: V-242435\n        text: \"Kubernetes must prevent non-privileged users from executing privileged functions (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --authorization-mode\n              path: '{.authorization.mode}'\n              set: true\n              compare:\n                op: nothave\n                value: AlwaysAllow\n        remediation: |\n          If using a Kubelet config file, edit $kubeletconf to set authorization: mode to Webhook. If\n          using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_AUTHZ_ARGS variable.\n          --authorization-mode=Webhook\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n      - id: V-242393\n        text: \"Kubernetes Worker Nodes must not have sshd service running. (Automated)\"\n        audit: '/bin/sh -c ''systemctl show -p ActiveState sshd'' '\n        tests:\n          test_items:\n            - flag: ActiveState\n              compare:\n                op: eq\n                value: inactive\n        remediation: |\n          To stop the sshd service, run the command: systemctl stop sshd\n        scored: true\n      - id: V-242394\n        text: \"Kubernetes Worker Nodes must not have the sshd service enabled. (Automated)\"\n        audit: \"/bin/sh -c 'systemctl is-enabled sshd.service'\"\n        tests:\n          test_items:\n            - flag: \"disabled\"\n        remediation: |\n          To disable the sshd service, run the command:\n            chkconfig sshd off\n        scored: true\n      - id: V-242395\n        text: \"Kubernetes dashboard must not be enabled. (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Run the command: kubectl get pods --all-namespaces -l k8s-app=kubernetes-dashboard\n          If any resources are returned, this is a finding.\n          Fix Text: Delete the Kubernetes dashboard deployment with the following command:\n            kubectl delete deployment kubernetes-dashboard --namespace=kube-system\n        scored: false\n      - id: V-242398\n        text: \"Kubernetes DynamicAuditing must not be enabled. (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--feature-gates\"\n              compare:\n                op: nothave\n                value: \"DynamicAuditing=true\"\n              set: true\n            - flag: \"--feature-gates\"\n              set: false\n        remediation: |\n          Edit any manifest files or kubelet config files that contain the feature-gates\n          setting with DynamicAuditing set to \"true\".\n          Set the flag to \"false\" or remove the \"DynamicAuditing\" setting\n          completely. Restart the kubelet service if the kubelet config file\n          if the kubelet config file is changed.\n        scored: true\n      - id: V-242399\n        text: \"Kubernetes DynamicKubeletConfig must not be enabled. (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--feature-gates\"\n              compare:\n                op: nothave\n                value: \"DynamicKubeletConfig=true\"\n              set: true\n            - flag: \"--feature-gates\"\n              set: false\n        remediation: |\n          Edit any manifest files or $kubeletconf that contain the feature-gates\n          setting with DynamicKubeletConfig set to \"true\".\n          Set the flag to \"false\" or remove the \"DynamicKubeletConfig\" setting\n          completely. Restart the kubelet service if the kubelet config file\n          if the kubelet config file is changed.\n        scored: true\n      - id: V-242404  # CIS 3.2.8\n        text: \"Kubernetes Kubelet must deny hostname override (Automated)\"\n        # This is one of those properties that can only be set as a command line argument.\n        # To check if the property is set as expected, we need to parse the kubelet command\n        # instead reading the Kubelet Configuration file.\n        audit: \"/bin/ps -fC $kubeletbin \"\n        tests:\n          test_items:\n            - flag: --hostname-override\n              set: false\n        remediation: |\n          Edit the kubelet service file $kubeletbin\n          on each worker node and remove the --hostname-override argument from the\n          KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n      - id: V-242406\n        text: \"The Kubernetes kubelet configuration file must be owned by root (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletkubeconfig; then stat -c %U:%G $kubeletkubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chown root:root $kubeletkubeconfig\n        scored: true\n      - id: V-242407\n        text: \"The Kubernetes kubelet configuration files must have file permissions set to 644 or more restrictive (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletconf; then stat -c permissions=%a $kubeletconf; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the following command (using the config file location identified in the Audit step)\n          chmod 644 $kubeletconf\n        scored: true\n      - id: V-242414\n        text: \"The Kubernetes cluster must use non-privileged host ports for user pods. (Manual)\"\n        type: \"manual\"\n        remediation: |\n          For any of the pods that are using ports below 1024,\n          reconfigure the pod to use a service to map a host non-privileged\n          port to the pod port or reconfigure the image to use non-privileged ports.\n        scored: false\n      - id: V-242442\n        text: \"Kubernetes must remove old components after updated versions have been installed. (Manual)\"\n        type: \"manual\"\n        remediation: |\n           To view all pods and the images used to create the pods, from the Master node, run the following command:\n            kubectl get pods --all-namespaces -o jsonpath=\"{..image}\" | \\\n            tr -s '[[:space:]]' '\\n' | \\\n            sort | \\\n            uniq -c\n            Review the images used for pods running within Kubernetes.\n            Remove any old pods that are using older images.\n        scored: false\n      - id: V-242396\n        text: \"Kubernetes Kubectl cp command must give expected access and results. (Manual)\"\n        type: \"manual\"\n        remediation: |\n          If any Worker nodes are not using kubectl version 1.12.9 or newer, this is a finding.\n          Upgrade the Master and Worker nodes to the latest version of kubectl.\n        scored: false\n"
  },
  {
    "path": "cfg/eks-stig-kubernetes-v1r6/policies.yaml",
    "content": "---\ncontrols:\nversion: \"eks-stig-kubernetes-v1r6\"\nid: 4\ntext: \"Policies\"\ntype: \"policies\"\ngroups:\n  - id: 4.1\n    text: \"Policies - DISA Category Code I\"\n    checks:\n      - id: V-242381\n        text: \"The Kubernetes Controller Manager must create unique service accounts for each work payload. (Manual)\"\n        type: \"manual\"\n        remediation: |\n         Create explicit service accounts wherever a Kubernetes workload requires specific access\n         to the Kubernetes API server.\n         Modify the configuration of each default service account to include this value\n         automountServiceAccountToken: false\n        scored: false\n\n      - id: V-242383\n        text: \"User-managed resources must be created in dedicated namespaces. (Manual)\"\n        type: \"manual\"\n        remediation: |\n         Move any user-managed resources from the default, kube-public and kube-node-lease namespaces, to user namespaces.\n        scored: false\n\n      - id: V-242417\n        text: \"Kubernetes must separate user functionality. (Manual)\"\n        type: \"manual\"\n        remediation: |\n         Move any user pods that are present in the Kubernetes system namespaces to user specific namespaces.\n        scored: false\n"
  },
  {
    "path": "cfg/gke-1.0/config.yaml",
    "content": "---\n## Version-specific settings that override the values in cfg/config.yaml\n"
  },
  {
    "path": "cfg/gke-1.0/controlplane.yaml",
    "content": "---\ncontrols:\nversion: \"gke-1.0\"\nid: 3\ntext: \"Control Plane Configuration\"\ntype: \"controlplane\"\ngroups:\n  - id: 3.1\n    text: \"Authentication and Authorization\"\n    checks:\n      - id: 3.1.1\n        text: \"Client certificate authentication should not be used for users (Not Scored)\"\n        type: \"manual\"\n        remediation: |\n          Alternative mechanisms provided by Kubernetes such as the use of OIDC should be\n          implemented in place of client certificates.\n          You can remediate the availability of client certificates in your GKE cluster. See\n          Recommendation 6.8.2.\n        scored: false\n\n  - id: 3.2\n    text: \"Logging\"\n    type: skip\n    checks:\n      - id: 3.2.1\n        text: \"Ensure that a minimal audit policy is created (Not Scored)\"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n      - id: 3.2.2\n        text: \"Ensure that the audit policy covers key security concerns (Not Scored) \"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n"
  },
  {
    "path": "cfg/gke-1.0/etcd.yaml",
    "content": "---\ncontrols:\nversion: \"gke-1.0\"\nid: 2\ntext: \"Etcd Node Configuration\"\ntype: \"etcd\"\ngroups:\n  - id: 2\n    text: \"Etcd Node Configuration Files\"\n    type: skip\n    checks:\n      - id: 2.1\n        text: \"Ensure that the --cert-file and --key-file arguments are set as appropriate (Not Scored)\"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n      - id: 2.2\n        text: \"Ensure that the --client-cert-auth argument is set to true (Not Scored)\"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n      - id: 2.3\n        text: \"Ensure that the --auto-tls argument is not set to true (Not Scored)\"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n      - id: 2.4\n        text: \"Ensure that the --peer-cert-file and --peer-key-file arguments are\n        set as appropriate (Not Scored)\"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n      - id: 2.5\n        text: \"Ensure that the --peer-client-cert-auth argument is set to true (Not Scored)\"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n      - id: 2.6\n        text: \"Ensure that the --peer-auto-tls argument is not set to true (Not Scored)\"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n      - id: 2.7\n        text: \"Ensure that a unique Certificate Authority is used for etcd (Not Scored)\"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n"
  },
  {
    "path": "cfg/gke-1.0/managedservices.yaml",
    "content": "---\ncontrols:\nversion: \"gke-1.0\"\nid: 6\ntext: \"Managed Services\"\ntype: \"managedservices\"\ngroups:\n  - id: 6.1\n    text: \"Image Registry and Image Scanning\"\n    checks:\n      - id: 6.1.1\n        text: \"Ensure Image Vulnerability Scanning using GCR Container Analysis\n        or a third-party provider (Scored)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n\n            gcloud services enable containerscanning.googleapis.com\n        scored: true\n\n      - id: 6.1.2\n        text: \"Minimize user access to GCR (Scored)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n            To change roles at the GCR bucket level:\n            Firstly, run the following if read permissions are required:\n\n              gsutil iam ch [TYPE]:[EMAIL-ADDRESS]:objectViewer\n              gs://artifacts.[PROJECT_ID].appspot.com\n\n            Then remove the excessively privileged role (Storage Admin / Storage Object Admin /\n            Storage Object Creator) using:\n\n              gsutil iam ch -d [TYPE]:[EMAIL-ADDRESS]:[ROLE]\n              gs://artifacts.[PROJECT_ID].appspot.com\n\n            where:\n              [TYPE] can be one of the following:\n                    o user, if the [EMAIL-ADDRESS] is a Google account\n                    o serviceAccount, if [EMAIL-ADDRESS] specifies a Service account\n              [EMAIL-ADDRESS] can be one of the following:\n                    o a Google account (for example, someone@example.com)\n                    o a Cloud IAM service account\n                    To modify roles defined at the project level and subsequently inherited within the GCR\n                    bucket, or the Service Account User role, extract the IAM policy file, modify it accordingly\n            and apply it using:\n\n              gcloud projects set-iam-policy [PROJECT_ID] [POLICY_FILE]\n        scored: true\n\n      - id: 6.1.3\n        text: \"Minimize cluster access to read-only for GCR (Scored)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n            For an account explicitly granted to the bucket. First, add read access to the Kubernetes\n            Service Account\n\n              gsutil iam ch [TYPE]:[EMAIL-ADDRESS]:objectViewer\n              gs://artifacts.[PROJECT_ID].appspot.com\n\n              where:\n              [TYPE] can be one of the following:\n                      o user, if the [EMAIL-ADDRESS] is a Google account\n                      o serviceAccount, if [EMAIL-ADDRESS] specifies a Service account\n              [EMAIL-ADDRESS] can be one of the following:\n                      o a Google account (for example, someone@example.com)\n                      o a Cloud IAM service account\n\n              Then remove the excessively privileged role (Storage Admin / Storage Object Admin /\n              Storage Object Creator) using:\n\n                gsutil iam ch -d [TYPE]:[EMAIL-ADDRESS]:[ROLE]\n                gs://artifacts.[PROJECT_ID].appspot.com\n\n              For an account that inherits access to the GCR Bucket through Project level permissions,\n              modify the Projects IAM policy file accordingly, then upload it using:\n\n                gcloud projects set-iam-policy [PROJECT_ID] [POLICY_FILE]\n        scored: true\n\n      - id: 6.1.4\n        text: \"Minimize Container Registries to only those approved (Not Scored)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n            First, update the cluster to enable Binary Authorization:\n\n              gcloud container cluster update [CLUSTER_NAME] \\\n                --enable-binauthz\n\n            Create a Binary Authorization Policy using the Binary Authorization Policy Reference\n            (https://cloud.google.com/binary-authorization/docs/policy-yaml-reference) for guidance.\n            Import the policy file into Binary Authorization:\n\n              gcloud container binauthz policy import [YAML_POLICY]\n        scored: false\n\n  - id: 6.2\n    text: \"Identity and Access Management (IAM)\"\n    checks:\n      - id: 6.2.1\n        text: \"Ensure GKE clusters are not running using the Compute Engine\n        default service account (Scored)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n            Firstly, create a minimally privileged service account:\n\n              gcloud iam service-accounts create [SA_NAME] \\\n                --display-name \"GKE Node Service Account\"\n              export NODE_SA_EMAIL=`gcloud iam service-accounts list \\\n                --format='value(email)' \\\n                --filter='displayName:GKE Node Service Account'`\n\n            Grant the following roles to the service account:\n\n              export PROJECT_ID=`gcloud config get-value project`\n              gcloud projects add-iam-policy-binding $PROJECT_ID \\\n                --member serviceAccount:$NODE_SA_EMAIL \\\n                --role roles/monitoring.metricWriter\n              gcloud projects add-iam-policy-binding $PROJECT_ID \\\n                --member serviceAccount:$NODE_SA_EMAIL \\\n                --role roles/monitoring.viewer\n              gcloud projects add-iam-policy-binding $PROJECT_ID \\\n                --member serviceAccount:$NODE_SA_EMAIL \\\n                --role roles/logging.logWriter\n\n            To create a new Node pool using the Service account, run the following command:\n\n              gcloud container node-pools create [NODE_POOL] \\\n                --service-account=[SA_NAME]@[PROJECT_ID].iam.gserviceaccount.com \\\n                --cluster=[CLUSTER_NAME] --zone [COMPUTE_ZONE]\n\n            You will need to migrate your workloads to the new Node pool, and delete Node pools that\n            use the default service account to complete the remediation.\n        scored: true\n\n      - id: 6.2.2\n        text: \"Prefer using dedicated GCP Service Accounts and Workload Identity (Not Scored)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n\n              gcloud beta container clusters update [CLUSTER_NAME] --zone [CLUSTER_ZONE] \\\n                --identity-namespace=[PROJECT_ID].svc.id.goog\n\n            Note that existing Node pools are unaffected. New Node pools default to --workload-\n            metadata-from-node=GKE_METADATA_SERVER .\n\n            Then, modify existing Node pools to enable GKE_METADATA_SERVER:\n\n              gcloud beta container node-pools update [NODEPOOL_NAME] \\\n                --cluster=[CLUSTER_NAME] --zone [CLUSTER_ZONE] \\\n                --workload-metadata-from-node=GKE_METADATA_SERVER\n\n            You may also need to modify workloads in order for them to use Workload Identity as\n            described within https://cloud.google.com/kubernetes-engine/docs/how-to/workload-\n            identity. Also consider the effects on the availability of your hosted workloads as Node\n            pools are updated, it may be more appropriate to create new Node Pools.\n        scored: false\n\n  - id: 6.3\n    text: \"Cloud Key Management Service (Cloud KMS)\"\n    checks:\n      - id: 6.3.1\n        text: \"Ensure Kubernetes Secrets are encrypted using keys managed in Cloud KMS (Scored)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n            To create a key\n\n            Create a key ring:\n\n              gcloud kms keyrings create [RING_NAME] \\\n                --location [LOCATION] \\\n                --project [KEY_PROJECT_ID]\n\n            Create a key:\n\n              gcloud kms keys create [KEY_NAME] \\\n                --location [LOCATION] \\\n                --keyring [RING_NAME] \\\n                --purpose encryption \\\n                --project [KEY_PROJECT_ID]\n\n            Grant the Kubernetes Engine Service Agent service account the Cloud KMS CryptoKey\n            Encrypter/Decrypter role:\n\n              gcloud kms keys add-iam-policy-binding [KEY_NAME] \\\n                --location [LOCATION] \\\n                --keyring [RING_NAME] \\\n                --member serviceAccount:[SERVICE_ACCOUNT_NAME] \\\n                --role roles/cloudkms.cryptoKeyEncrypterDecrypter \\\n                --project [KEY_PROJECT_ID]\n\n            To create a new cluster with Application-layer Secrets Encryption:\n\n              gcloud container clusters create [CLUSTER_NAME] \\\n                --cluster-version=latest \\\n                --zone [ZONE] \\\n                --database-encryption-key projects/[KEY_PROJECT_ID]/locations/[LOCATION]/keyRings/[RING_NAME]/cryptoKey s/[KEY_NAME] \\\n                --project [CLUSTER_PROJECT_ID]\n\n            To enable on an existing cluster:\n\n              gcloud container clusters update [CLUSTER_NAME] \\\n                --zone [ZONE] \\\n                --database-encryption-key projects/[KEY_PROJECT_ID]/locations/[LOCATION]/keyRings/[RING_NAME]/cryptoKey s/[KEY_NAME] \\\n                --project [CLUSTER_PROJECT_ID]\n        scored: true\n\n  - id: 6.4\n    text: \"Node Metadata\"\n    checks:\n      - id: 6.4.1\n        text: \"Ensure legacy Compute Engine instance metadata APIs are Disabled (Scored)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n            To update an existing cluster, create a new Node pool with the legacy GCE metadata\n            endpoint disabled:\n\n              gcloud container node-pools create [POOL_NAME] \\\n                --metadata disable-legacy-endpoints=true \\\n                --cluster [CLUSTER_NAME] \\\n                --zone [COMPUTE_ZONE]\n\n            You will need to migrate workloads from any existing non-conforming Node pools, to the\n            new Node pool, then delete non-conforming Node pools to complete the remediation.\n        scored: true\n\n      - id: 6.4.2\n        text: \"Ensure the GKE Metadata Server is Enabled (Not Scored)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n              gcloud beta container clusters update [CLUSTER_NAME] \\\n                --identity-namespace=[PROJECT_ID].svc.id.goog\n            Note that existing Node pools are unaffected. New Node pools default to --workload-\n            metadata-from-node=GKE_METADATA_SERVER .\n\n            To modify an existing Node pool to enable GKE Metadata Server:\n\n              gcloud beta container node-pools update [NODEPOOL_NAME] \\\n                --cluster=[CLUSTER_NAME] \\\n                --workload-metadata-from-node=GKE_METADATA_SERVER\n\n            You may also need to modify workloads in order for them to use Workload Identity as\n            described within https://cloud.google.com/kubernetes-engine/docs/how-to/workload-\n            identity.\n        scored: false\n\n  - id: 6.5\n    text: \"Node Configuration and Maintenance\"\n    checks:\n      - id: 6.5.1\n        text: \"Ensure Container-Optimized OS (COS) is used for GKE node images (Scored)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n            To set the node image to cos for an existing cluster's Node pool:\n\n              gcloud container clusters upgrade [CLUSTER_NAME]\\\n                --image-type cos \\\n                --zone [COMPUTE_ZONE] --node-pool [POOL_NAME]\n        scored: true\n\n      - id: 6.5.2\n        text: \"Ensure Node Auto-Repair is enabled for GKE nodes (Scored)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n            To enable node auto-repair for an existing cluster with Node pool, run the following\n            command:\n\n              gcloud container node-pools update [POOL_NAME] \\\n                --cluster [CLUSTER_NAME] --zone [COMPUTE_ZONE] \\\n                --enable-autorepair\n        scored: true\n\n      - id: 6.5.3\n        text: \"Ensure Node Auto-Upgrade is enabled for GKE nodes (Scored)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n            To enable node auto-upgrade for an existing cluster's Node pool, run the following\n            command:\n\n              gcloud container node-pools update [NODE_POOL] \\\n                --cluster [CLUSTER_NAME] --zone [COMPUTE_ZONE] \\\n                --enable-autoupgrade\n        scored: true\n\n      - id: 6.5.4\n        text: \"Automate GKE version management using Release Channels (Not Scored)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n            Create a new cluster by running the following command:\n\n              gcloud beta container clusters create [CLUSTER_NAME] \\\n                --zone [COMPUTE_ZONE] \\\n                --release-channel [RELEASE_CHANNEL]\n\n            where [RELEASE_CHANNEL] is stable or regular according to your needs.\n        scored: false\n\n      - id: 6.5.5\n        text: \"Ensure Shielded GKE Nodes are Enabled (Not Scored)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n            To create a Node pool within the cluster with Integrity Monitoring enabled, run the\n            following command:\n\n              gcloud beta container node-pools create [NODEPOOL_NAME] \\\n                --cluster [CLUSTER_NAME] --zone [COMPUTE_ZONE] \\\n                --shielded-integrity-monitoring\n\n            You will also need to migrate workloads from existing non-conforming Node pools to the\n            newly created Node pool, then delete the non-conforming pools.\n        scored: false\n\n      - id: 6.5.6\n        text: \"Ensure Shielded GKE Nodes are Enabled (Not Scored)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n            To migrate an existing cluster, you will need to specify the --enable-shielded-nodes flag\n            on a cluster update command:\n\n              gcloud beta container clusters update [CLUSTER_NAME] \\\n                --zone [CLUSTER_ZONE] \\\n                --enable-shielded-nodes\n        scored: false\n\n      - id: 6.5.7\n        text: \"Ensure Secure Boot for Shielded GKE Nodes is Enabled (Not Scored)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n            To create a Node pool within the cluster with Secure Boot enabled, run the following\n            command:\n\n              gcloud beta container node-pools create [NODEPOOL_NAME] \\\n                --cluster [CLUSTER_NAME] --zone [COMPUTE_ZONE] \\\n                --shielded-secure-boot\n\n            You will also need to migrate workloads from existing non-conforming Node pools to the\n            newly created Node pool, then delete the non-conforming pools.\n        scored: false\n\n  - id: 6.6\n    text: \"Cluster Networking\"\n    checks:\n      - id: 6.6.1\n        text: \"Enable VPC Flow Logs and Intranode Visibility (Not Scored)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n            To enable intranode visibility on an existing cluster, run the following command:\n\n              gcloud beta container clusters update [CLUSTER_NAME] \\\n                --enable-intra-node-visibility\n        scored: false\n\n      - id: 6.6.2\n        text: \"Ensure use of VPC-native clusters (Scored)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n            To enable Alias IP on a new cluster, run the following command:\n\n              gcloud container clusters create [CLUSTER_NAME] \\\n                --zone [COMPUTE_ZONE] \\\n                --enable-ip-alias\n        scored: true\n\n      - id: 6.6.3\n        text: \"Ensure Master Authorized Networks is Enabled (Scored)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n            To check Master Authorized Networks status for an existing cluster, run the following\n            command;\n\n              gcloud container clusters describe [CLUSTER_NAME] \\\n                --zone [COMPUTE_ZONE] \\\n                --format json | jq '.masterAuthorizedNetworksConfig'\n\n            The output should return\n\n              {\n                \"enabled\": true\n              }\n\n            if Master Authorized Networks is enabled.\n\n            If Master Authorized Networks is disabled, the\n            above command will return null ( { } ).\n        scored: true\n\n      - id: 6.6.4\n        text: \"Ensure clusters are created with Private Endpoint Enabled and Public Access Disabled (Scored)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n            Create a cluster with a Private Endpoint enabled and Public Access disabled by including\n            the --enable-private-endpoint flag within the cluster create command:\n\n              gcloud container clusters create [CLUSTER_NAME] \\\n                --enable-private-endpoint\n\n            Setting this flag also requires the setting of --enable-private-nodes , --enable-ip-alias\n            and --master-ipv4-cidr=[MASTER_CIDR_RANGE] .\n        scored: true\n\n      - id: 6.6.5\n        text: \"Ensure clusters are created with Private Nodes (Scored)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n            To create a cluster with Private Nodes enabled, include the --enable-private-nodes flag\n            within the cluster create command:\n\n              gcloud container clusters create [CLUSTER_NAME] \\\n                --enable-private-nodes\n\n            Setting this flag also requires the setting of --enable-ip-alias and --master-ipv4-\n            cidr=[MASTER_CIDR_RANGE] .\n        scored: true\n\n      - id: 6.6.6\n        text: \"Consider firewalling GKE worker nodes (Not Scored)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n            Use the following command to generate firewall rules, setting the variables as appropriate.\n            You may want to use the target [TAG] and [SERVICE_ACCOUNT] previously identified.\n\n              gcloud compute firewall-rules create FIREWALL_RULE_NAME \\\n                --network [NETWORK] \\\n                --priority [PRIORITY] \\\n                --direction [DIRECTION] \\\n                --action [ACTION] \\\n                --target-tags [TAG] \\\n                --target-service-accounts [SERVICE_ACCOUNT] \\\n                --source-ranges [SOURCE_CIDR-RANGE] \\\n                --source-tags [SOURCE_TAGS] \\\n                --source-service-accounts=[SOURCE_SERVICE_ACCOUNT] \\\n                --destination-ranges [DESTINATION_CIDR_RANGE] \\\n                --rules [RULES]\n        scored: false\n\n      - id: 6.6.7\n        text: \"Ensure Network Policy is Enabled and set as appropriate (Not Scored)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n            To enable Network Policy for an existing cluster, firstly enable the Network Policy add-on:\n\n              gcloud container clusters update [CLUSTER_NAME] \\\n                --zone [COMPUTE_ZONE] \\\n                --update-addons NetworkPolicy=ENABLED\n\n            Then, enable Network Policy:\n\n              gcloud container clusters update [CLUSTER_NAME] \\\n                --zone [COMPUTE_ZONE] \\\n                --enable-network-policy\n        scored: false\n\n      - id: 6.6.8\n        text: \"Ensure use of Google-managed SSL Certificates (Not Scored)\"\n        type: \"manual\"\n        remediation: |\n          If services of type:LoadBalancer are discovered, consider replacing the Service with an\n          Ingress.\n\n          To configure the Ingress and use Google-managed SSL certificates, follow the instructions\n          as listed at https://cloud.google.com/kubernetes-engine/docs/how-to/managed-certs.\n        scored: false\n\n  - id: 6.7\n    text: \"Logging\"\n    checks:\n      - id: 6.7.1\n        text: \"Ensure Stackdriver Kubernetes Logging and Monitoring is Enabled (Scored)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n\n            STACKDRIVER KUBERNETES ENGINE MONITORING SUPPORT (PREFERRED):\n            To enable Stackdriver Kubernetes Engine Monitoring for an existing cluster, run the\n            following command:\n\n              gcloud container clusters update [CLUSTER_NAME] \\\n                --zone [COMPUTE_ZONE] \\\n                --enable-stackdriver-kubernetes\n\n            LEGACY STACKDRIVER SUPPORT:\n            Both Logging and Monitoring support must be enabled.\n            To enable Legacy Stackdriver Logging for an existing cluster, run the following command:\n\n              gcloud container clusters update [CLUSTER_NAME] --zone [COMPUTE_ZONE] \\\n                --logging-service logging.googleapis.com\n\n            To enable Legacy Stackdriver Monitoring for an existing cluster, run the following\n            command:\n\n              gcloud container clusters update [CLUSTER_NAME] --zone [COMPUTE_ZONE] \\\n                --monitoring-service monitoring.googleapis.com\n        scored: true\n\n      - id: 6.7.2\n        text: \"Enable Linux auditd logging (Not Scored)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n            Download the example manifests:\n\n              curl https://raw.githubusercontent.com/GoogleCloudPlatform/k8s-node-tools/master/os-audit/cos-auditd-logging.yaml \\\n                > cos-auditd-logging.yaml\n\n            Edit the example manifests if needed. Then, deploy them:\n\n              kubectl apply -f cos-auditd-logging.yaml\n\n            Verify that the logging Pods have started. If you defined a different Namespace in your\n            manifests, replace cos-auditd with the name of the namespace you're using:\n\n              kubectl get pods --namespace=cos-auditd\n        scored: false\n\n  - id: 6.8\n    text: \"Authentication and Authorization\"\n    checks:\n      - id: 6.8.1\n        text: \"Ensure Basic Authentication using static passwords is Disabled (Scored)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n            To update an existing cluster and disable Basic Authentication by removing the static\n            password:\n\n              gcloud container clusters update [CLUSTER_NAME] \\\n                --no-enable-basic-auth\n        scored: true\n\n      - id: 6.8.2\n        text: \"Ensure authentication using Client Certificates is Disabled (Scored)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n            Create a new cluster without a Client Certificate:\n\n              gcloud container clusters create [CLUSTER_NAME] \\\n                --no-issue-client-certificate\n        scored: true\n\n      - id: 6.8.3\n        text: \"Manage Kubernetes RBAC users with Google Groups for GKE (Not Scored)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n            Follow the G Suite Groups instructions at https://cloud.google.com/kubernetes-\n            engine/docs/how-to/role-based-access-control#google-groups-for-gke.\n\n            Then, create a cluster with\n\n              gcloud beta container clusters create my-cluster \\\n                --security-group=\"gke-security-groups@[yourdomain.com]\"\n\n            Finally create Roles, ClusterRoles, RoleBindings, and ClusterRoleBindings that\n            reference your G Suite Groups.\n        scored: false\n\n      - id: 6.8.4\n        text: \"Ensure Legacy Authorization (ABAC) is Disabled (Scored)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n            To disable Legacy Authorization for an existing cluster, run the following command:\n\n              gcloud container clusters update [CLUSTER_NAME] \\\n                --zone [COMPUTE_ZONE] \\\n                --no-enable-legacy-authorization\n        scored: true\n\n  - id: 6.9\n    text: \"Storage\"\n    checks:\n      - id: 6.9.1\n        text: \"Enable Customer-Managed Encryption Keys (CMEK) for GKE Persistent Disks (PD) (Not Scored)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n            FOR NODE BOOT DISKS:\n            Create a new node pool using customer-managed encryption keys for the node boot disk, of\n            [DISK_TYPE] either pd-standard or pd-ssd :\n\n              gcloud beta container node-pools create [CLUSTER_NAME] \\\n                --disk-type [DISK_TYPE] \\\n                --boot-disk-kms-key \\\n                projects/[KEY_PROJECT_ID]/locations/[LOCATION]/keyRings/[RING_NAME]/cryptoKeys/[KEY_NAME]\n\n            Create a cluster using customer-managed encryption keys for the node boot disk, of\n            [DISK_TYPE] either pd-standard or pd-ssd :\n\n              gcloud beta container clusters create [CLUSTER_NAME] \\\n                --disk-type [DISK_TYPE] \\\n                --boot-disk-kms-key \\\n                projects/[KEY_PROJECT_ID]/locations/[LOCATION]/keyRings/[RING_NAME]/cryptoKeys/[KEY_NAME]\n\n            FOR ATTACHED DISKS:\n            Follow the instructions detailed at https://cloud.google.com/kubernetes-\n            engine/docs/how-to/using-cmek.\n        scored: false\n\n  - id: 6.10\n    text: \"Other Cluster Configurations\"\n    checks:\n      - id: 6.10.1\n        text: \"Ensure Kubernetes Web UI is Disabled (Scored)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n            To disable the Kubernetes Dashboard on an existing cluster, run the following command:\n\n              gcloud container clusters update [CLUSTER_NAME] \\\n                --zone [ZONE] \\\n                --update-addons=KubernetesDashboard=DISABLED\n        scored: true\n\n      - id: 6.10.2\n        text: \"Ensure that Alpha clusters are not used for production workloads (Scored)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n            Upon creating a new cluster\n\n              gcloud container clusters create [CLUSTER_NAME] \\\n                --zone [COMPUTE_ZONE]\n\n            Do not use the --enable-kubernetes-alpha argument.\n        scored: true\n\n      - id: 6.10.3\n        text: \"Ensure Pod Security Policy is Enabled and set as appropriate (Not Scored)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n            To enable Pod Security Policy for an existing cluster, run the following command:\n\n              gcloud beta container clusters update [CLUSTER_NAME] \\\n                --zone [COMPUTE_ZONE] \\\n                --enable-pod-security-policy\n        scored: false\n\n      - id: 6.10.4\n        text: \"Consider GKE Sandbox for running untrusted workloads (Not Scored)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n            To enable GKE Sandbox on an existing cluster, a new Node pool must be created.\n\n              gcloud container node-pools create [NODE_POOL_NAME] \\\n                --zone=[COMPUTE-ZONE] \\\n                --cluster=[CLUSTER_NAME] \\\n                --image-type=cos_containerd \\\n                --sandbox type=gvisor\n        scored: false\n\n      - id: 6.10.5\n        text: \"Ensure use of Binary Authorization (Scored)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n            Firstly, update the cluster to enable Binary Authorization:\n\n              gcloud container cluster update [CLUSTER_NAME] \\\n                --zone [COMPUTE-ZONE] \\\n                --enable-binauthz\n\n            Create a Binary Authorization Policy using the Binary Authorization Policy Reference\n            (https://cloud.google.com/binary-authorization/docs/policy-yaml-reference) for\n            guidance.\n\n            Import the policy file into Binary Authorization:\n\n              gcloud container binauthz policy import [YAML_POLICY]\n        scored: true\n\n      - id: 6.10.6\n        text: \"Enable Cloud Security Command Center (Cloud SCC) (Not Scored)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n            Follow the instructions at https://cloud.google.com/security-command-\n            center/docs/quickstart-scc-setup.\n        scored: false\n"
  },
  {
    "path": "cfg/gke-1.0/master.yaml",
    "content": "---\ncontrols:\nversion: \"gke-1.0\"\nid: 1\ntext: \"Control Plane Components\"\ntype: \"master\"\ngroups:\n  - id: 1.1\n    text: \"Master Node Configuration Files \"\n    type: skip\n    checks:\n      - id: 1.1.1\n        text: \"Ensure that the API server pod specification file permissions are set to 644 or more restrictive (Not Scored)\"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n      - id: 1.1.2\n        text: \"Ensure that the API server pod specification file ownership is set to root:root (Not Scored)\"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n      - id: 1.1.3\n        text: \"Ensure that the controller manager pod specification file permissions are set to 644 or more restrictive (Not Scored)\"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n      - id: 1.1.4\n        text: \"Ensure that the controller manager pod specification file ownership is set to root:root (Not Scored)\"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n      - id: 1.1.5\n        text: \"Ensure that the scheduler pod specification file permissions are set to 644 or more restrictive (Not Scored)\"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n      - id: 1.1.6\n        text: \"Ensure that the scheduler pod specification file ownership is set to root:root (Not Scored)\"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n      - id: 1.1.7\n        text: \"Ensure that the etcd pod specification file permissions are set to 644 or more restrictive (Not Scored)\"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n      - id: 1.1.8\n        text: \"Ensure that the etcd pod specification file ownership is set to root:root (Not Scored)\"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n      - id: 1.1.9\n        text: \"Ensure that the Container Network Interface file permissions are set to 644 or more restrictive (Not Scored)\"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n      - id: 1.1.10\n        text: \"Ensure that the Container Network Interface file ownership is set to root:root (Not Scored)\"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n      - id: 1.1.11\n        text: \"Ensure that the etcd data directory permissions are set to 700 or more restrictive (Not Scored)\"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n      - id: 1.1.12\n        text: \"Ensure that the etcd data directory ownership is set to etcd:etcd (Not Scored)\"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n      - id: 1.1.13\n        text: \"Ensure that the admin.conf file permissions are set to 644 or more restrictive (Not Scored)\"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n      - id: 1.1.14\n        text: \"Ensure that the admin.conf file ownership is set to root:root (Not Scored) \"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n      - id: 1.1.15\n        text: \"Ensure that the scheduler.conf file permissions are set to 644 or more restrictive (Not Scored)\"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: true\n\n      - id: 1.1.16\n        text: \"Ensure that the scheduler.conf file ownership is set to root:root (Not Scored)\"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n      - id: 1.1.17\n        text: \"Ensure that the controller-manager.conf file permissions are set to 644 or more restrictive (Not Scored)\"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n      - id: 1.1.18\n        text: \"Ensure that the controller-manager.conf file ownership is set to root:root (Not Scored)\"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n      - id: 1.1.19\n        text: \"Ensure that the Kubernetes PKI directory and file ownership is set to root:root (Not Scored)\"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n      - id: 1.1.20\n        text: \"Ensure that the Kubernetes PKI certificate file permissions are set to 644 or more restrictive (Not Scored)\"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n      - id: 1.1.21\n        text: \"Ensure that the Kubernetes PKI key file permissions are set to 600 (Not Scored)\"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n  - id: 1.2\n    text: \"API Server\"\n    type: skip\n    checks:\n      - id: 1.2.1\n        text: \"Ensure that the --anonymous-auth argument is set to false (Not Scored)\"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n      - id: 1.2.2\n        text: \"Ensure that the --basic-auth-file argument is not set (Not Scored)\"\n        remediation: |\n          Although the use of the --basic-auth-file argument cannot be audited on GKE, you can\n          remediate the use of basic authentication. See Recommendation 6.8.1.\n        scored: false\n\n      - id: 1.2.3\n        text: \"Ensure that the --token-auth-file parameter is not set (Not Scored)\"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n      - id: 1.2.4\n        text: \"Ensure that the --kubelet-https argument is set to true (Not Scored)\"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n      - id: 1.2.5\n        text: \"Ensure that the --kubelet-client-certificate and --kubelet-client-key arguments are set as appropriate (Not Scored)\"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n      - id: 1.2.6\n        text: \"Ensure that the --kubelet-certificate-authority argument is set as appropriate (Not Scored)\"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n      - id: 1.2.7\n        text: \"Ensure that the --authorization-mode argument is not set to AlwaysAllow (Not Scored)\"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n      - id: 1.2.8\n        text: \"Ensure that the --authorization-mode argument includes Node (Not Scored)\"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n      - id: 1.2.9\n        text: \"Ensure that the --authorization-mode argument includes RBAC (Not Scored)\"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n      - id: 1.2.10\n        text: \"Ensure that the admission control plugin EventRateLimit is set (Not Scored)\"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n      - id: 1.2.11\n        text: \"Ensure that the admission control plugin AlwaysAdmit is not set (Not Scored)\"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n      - id: 1.2.12\n        text: \"Ensure that the admission control plugin AlwaysPullImages is set (Not Scored)\"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n      - id: 1.2.13\n        text: \"Ensure that the admission control plugin SecurityContextDeny is set if PodSecurityPolicy is not used (Not Scored)\"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n      - id: 1.2.14\n        text: \"Ensure that the admission control plugin ServiceAccount is set (Not Scored)\"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n      - id: 1.2.15\n        text: \"Ensure that the admission control plugin NamespaceLifecycle is set (Not Scored)\"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n      - id: 1.2.16\n        text: \"Ensure that the admission control plugin PodSecurityPolicy is set (Not Scored)\"\n        remediation: |\n          To verify and remediate the use of Pod Security Policy on GKE, see Recommendation 6.10.3.\n        scored: false\n\n      - id: 1.2.17\n        text: \"Ensure that the admission control plugin NodeRestriction is set (Not Scored)\"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n      - id: 1.2.18\n        text: \"Ensure that the --insecure-bind-address argument is not set (Not Scored)\"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n      - id: 1.2.19\n        text: \"Ensure that the --insecure-port argument is set to 0 (Not Scored)\"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n      - id: 1.2.20\n        text: \"Ensure that the --secure-port argument is not set to 0 (Not Scored)\"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n      - id: 1.2.21\n        text: \"Ensure that the --profiling argument is set to false (Not Scored)\"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n      - id: 1.2.22\n        text: \"Ensure that the --audit-log-path argument is set (Not Scored)\"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n      - id: 1.2.23\n        text: \"Ensure that the --audit-log-maxage argument is set to 30 or as appropriate (Not Scored)\"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n      - id: 1.2.24\n        text: \"Ensure that the --audit-log-maxbackup argument is set to 10 or as appropriate (Not Scored)\"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n      - id: 1.2.25\n        text: \"Ensure that the --audit-log-maxsize argument is set to 100 or as appropriate (Not Scored)\"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n      - id: 1.2.26\n        text: \"Ensure that the --request-timeout argument is set as appropriate (Not Scored)\"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n      - id: 1.2.27\n        text: \"Ensure that the --service-account-lookup argument is set to true (Not Scored)\"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n      - id: 1.2.28\n        text: \"Ensure that the --service-account-key-file argument is set as appropriate (Not Scored)\"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n      - id: 1.2.29\n        text: \"Ensure that the --etcd-certfile and --etcd-keyfile arguments are set as appropriate (Not Scored)\"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n      - id: 1.2.30\n        text: \"Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Not Scored)\"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n      - id: 1.2.31\n        text: \"Ensure that the --client-ca-file argument is set as appropriate (Not Scored)\"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n      - id: 1.2.32\n        text: \"Ensure that the --etcd-cafile argument is set as appropriate (Not Scored)\"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n      - id: 1.2.33\n        text: \"Ensure that the --encryption-provider-config argument is set as appropriate (Not Scored)\"\n        remediation: |\n          To verify and remediate the use of secret encryption on GKE, see Recommendation 6.3.1.\n        scored: false\n\n      - id: 1.2.34\n        text: \"Ensure that encryption providers are appropriately configured (Not Scored)\"\n        remediation: |\n          To verify and remediate the use of secret encryption on GKE, see Recommendation 6.3.1.\n        scored: false\n\n      - id: 1.2.35\n        text: \"Ensure that the API Server only makes use of Strong Cryptographic Ciphers (Not Scored)\"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n  - id: 1.3\n    text: \"Controller Manager\"\n    type: skip\n    checks:\n      - id: 1.3.1\n        text: \"Ensure that the --terminated-pod-gc-threshold argument is set as appropriate (Not Scored)\"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n      - id: 1.3.2\n        text: \"Ensure that the --profiling argument is set to false (Not Scored)\"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n      - id: 1.3.3\n        text: \"Ensure that the --use-service-account-credentials argument is set to true (Not Scored)\"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n      - id: 1.3.4\n        text: \"Ensure that the --service-account-private-key-file argument is set as appropriate (Not Scored)\"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n      - id: 1.3.5\n        text: \"Ensure that the --root-ca-file argument is set as appropriate (Not Scored)\"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n      - id: 1.3.6\n        text: \"Ensure that the RotateKubeletServerCertificate argument is set to true (Not Scored)\"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n      - id: 1.3.7\n        text: \"Ensure that the --bind-address argument is set to 127.0.0.1 (Not Scored)\"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n  - id: 1.4\n    text: \"Scheduler\"\n    type: skip\n    checks:\n      - id: 1.4.1\n        text: \"Ensure that the --profiling argument is set to false (Not Scored)\"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n      - id: 1.4.2\n        text: \"Ensure that the --bind-address argument is set to 127.0.0.1 (Not Scored) \"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n"
  },
  {
    "path": "cfg/gke-1.0/node.yaml",
    "content": "---\ncontrols:\nversion: \"gke-1.0\"\nid: 4\ntext: \"Worker Node Security Configuration\"\ntype: \"node\"\ngroups:\n  - id: 4.1\n    text: \"Worker Node Configuration Files\"\n    checks:\n      - id: 4.1.1\n        text: \"Ensure that the kubelet service file permissions are set to 644 or more restrictive (Not Scored)\"\n        type: skip\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n      - id: 4.1.2\n        text: \"Ensure that the kubelet service file ownership is set to root:root (Not Scored)\"\n        type: skip\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n      - id: 4.1.3\n        text: \"Ensure that the proxy kubeconfig file permissions are set to 644 or more restrictive (Scored)\"\n        audit: '/bin/sh -c ''if test -e $proxykubeconfig; then stat -c permissions=%a $proxykubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on each worker node.\n          For example,\n          chmod 644 $proxykubeconfig\n        scored: true\n\n      - id: 4.1.4\n        text: \"Ensure that the proxy kubeconfig file ownership is set to root:root (Scored)\"\n        audit: '/bin/sh -c ''if test -e $proxykubeconfig; then stat -c %U:%G $proxykubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the below command (based on the file location on your system) on each worker node.\n          For example, chown root:root $proxykubeconfig\n        scored: true\n\n      - id: 4.1.5\n        text: \"Ensure that the kubelet.conf file permissions are set to 644 or more restrictive (Not Scored)\"\n        type: skip\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n      - id: 4.1.6\n        text: \"Ensure that the kubelet.conf file ownership is set to root:root (Not Scored)\"\n        type: skip\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n      - id: 4.1.7\n        text: \"Ensure that the certificate authorities file permissions are set to 644 or more restrictive (Not Scored)\"\n        type: skip\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n      - id: 4.1.8\n        text: \"Ensure that the client certificate authorities file ownership is set to root:root (Not Scored)\"\n        type: skip\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n      - id: 4.1.9\n        text: \"Ensure that the kubelet configuration file has permissions set to 644 or more restrictive (Scored)\"\n        audit: '/bin/sh -c ''if test -e $kubeletconf; then stat -c permissions=%a $kubeletconf; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              set: true\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the following command (using the config file location identified in the Audit step)\n          chmod 644 $kubeletconf\n        scored: true\n\n      - id: 4.1.10\n        text: \"Ensure that the kubelet configuration file ownership is set to root:root (Scored)\"\n        audit: '/bin/sh -c ''if test -e $kubeletconf; then stat -c %U:%G $kubeletconf; fi'' '\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the following command (using the config file location identified in the Audit step)\n          chown root:root $kubeletconf\n        scored: true\n\n  - id: 4.2\n    text: \"Kubelet\"\n    checks:\n      - id: 4.2.1\n        text: \"Ensure that the --anonymous-auth argument is set to false (Scored)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: \"--anonymous-auth\"\n              path: '{.authentication.anonymous.enabled}'\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          If using a Kubelet config file, edit the file to set authentication: anonymous: enabled to\n          false.\n          If using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --anonymous-auth=false\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.2\n        text: \"Ensure that the --authorization-mode argument is not set to AlwaysAllow (Scored)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --authorization-mode\n              path: '{.authorization.mode}'\n              compare:\n                op: nothave\n                value: AlwaysAllow\n        remediation: |\n          If using a Kubelet config file, edit the file to set authorization: mode to Webhook. If\n          using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_AUTHZ_ARGS variable.\n          --authorization-mode=Webhook\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.3\n        text: \"Ensure that the --client-ca-file argument is set as appropriate (Scored)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --client-ca-file\n              path: '{.authentication.x509.clientCAFile}'\n              set: true\n        remediation: |\n          If using a Kubelet config file, edit the file to set authentication: x509: clientCAFile to\n          the location of the client CA file.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_AUTHZ_ARGS variable.\n          --client-ca-file=<path/to/client-ca-file>\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.4\n        text: \"Ensure that the --read-only-port argument is set to 0 (Scored)\"\n        type: skip\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: true\n\n      - id: 4.2.5\n        text: \"Ensure that the --streaming-connection-idle-timeout argument is not set to 0 (Scored)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --streaming-connection-idle-timeout\n              path: '{.streamingConnectionIdleTimeout}'\n              compare:\n                op: noteq\n                value: 0\n            - flag: --streaming-connection-idle-timeout\n              path: '{.streamingConnectionIdleTimeout}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to set streamingConnectionIdleTimeout to a\n          value other than 0.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --streaming-connection-idle-timeout=5m\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.6\n        text: \"Ensure that the --protect-kernel-defaults argument is set to true (Scored)\"\n        type: skip\n        remediation: \"This control cannot be modified in GKE.\"\n\n      - id: 4.2.7\n        text: \"Ensure that the --make-iptables-util-chains argument is set to true (Scored) \"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --make-iptables-util-chains\n              path: '{.makeIPTablesUtilChains}'\n              compare:\n                op: eq\n                value: true\n            - flag: --make-iptables-util-chains\n              path: '{.makeIPTablesUtilChains}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to set makeIPTablesUtilChains: true.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          remove the --make-iptables-util-chains argument from the\n          KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.8\n        text: \"Ensure that the --hostname-override argument is not set (Scored)\"\n        audit: \"/bin/ps -fC $kubeletbin \"\n        tests:\n          test_items:\n            - flag: --hostname-override\n              set: false\n        remediation: |\n          Edit the kubelet service file $kubeletsvc\n          on each worker node and remove the --hostname-override argument from the\n          KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.9\n        text: \"Ensure that the --event-qps argument is set to 0 or a level which ensures appropriate event capture (Scored)\"\n        type: skip\n        remediation: \"This control cannot be modified in GKE.\"\n\n      - id: 4.2.10\n        text: \"Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Scored)\"\n        type: skip\n        remediation: \"This control cannot be modified in GKE.\"\n\n      - id: 4.2.11\n        text: \"Ensure that the --rotate-certificates argument is not set to false (Scored)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --rotate-certificates\n              path: '{.rotateCertificates}'\n              compare:\n                op: eq\n                value: true\n            - flag: --rotate-certificates\n              path: '{.rotateCertificates}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to add the line rotateCertificates: true or\n          remove it altogether to use the default value.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          remove --rotate-certificates=false argument from the KUBELET_CERTIFICATE_ARGS\n          variable.\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.12\n        text: \"Ensure that the RotateKubeletServerCertificate argument is set to true (Scored)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: RotateKubeletServerCertificate\n              path: '{.featureGates.RotateKubeletServerCertificate}'\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Edit the kubelet service file $kubeletsvc\n          on each worker node and set the below parameter in KUBELET_CERTIFICATE_ARGS variable.\n          --feature-gates=RotateKubeletServerCertificate=true\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.13\n        text: \"Ensure that the Kubelet only makes use of Strong Cryptographic Ciphers (Not Scored)\"\n        type: skip\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n"
  },
  {
    "path": "cfg/gke-1.0/policies.yaml",
    "content": "---\ncontrols:\nversion: \"gke-1.0\"\nid: 5\ntext: \"Kubernetes Policies\"\ntype: \"policies\"\ngroups:\n  - id: 5.1\n    text: \"RBAC and Service Accounts\"\n    checks:\n      - id: 5.1.1\n        text: \"Ensure that the cluster-admin role is only used where required (Not Scored)\"\n        type: \"manual\"\n        remediation: |\n          Identify all clusterrolebindings to the cluster-admin role. Check if they are used and\n          if they need this role or if they could use a role with fewer privileges.\n          Where possible, first bind users to a lower privileged role and then remove the\n          clusterrolebinding to the cluster-admin role :\n          kubectl delete clusterrolebinding [name]\n        scored: false\n\n      - id: 5.1.2\n        text: \"Minimize access to secrets (Not Scored)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove get, list and watch access to secret objects in the cluster.\n        scored: false\n\n      - id: 5.1.3\n        text: \"Minimize wildcard use in Roles and ClusterRoles (Not Scored)\"\n        type: \"manual\"\n        remediation: |\n          Where possible replace any use of wildcards in clusterroles and roles with specific\n          objects or actions.\n        scored: false\n\n      - id: 5.1.4\n        text: \"Minimize access to create pods (Not Scored)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove create access to pod objects in the cluster.\n        scored: false\n\n      - id: 5.1.5\n        text: \"Ensure that default service accounts are not actively used. (Scored)\"\n        type: \"manual\"\n        remediation: |\n          Create explicit service accounts wherever a Kubernetes workload requires specific access\n          to the Kubernetes API server.\n          Modify the configuration of each default service account to include this value\n          automountServiceAccountToken: false\n        scored: true\n\n      - id: 5.1.6\n        text: \"Ensure that Service Account Tokens are only mounted where necessary (Not Scored)\"\n        type: \"manual\"\n        remediation: |\n          Modify the definition of pods and service accounts which do not need to mount service\n          account tokens to disable it.\n        scored: false\n\n  - id: 5.2\n    text: \"Pod Security Policies\"\n    checks:\n      - id: 5.2.1\n        text: \"Minimize the admission of privileged containers (Not Scored)\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that\n          the .spec.privileged field is omitted or set to false.\n        scored: false\n\n      - id: 5.2.2\n        text: \"Minimize the admission of containers wishing to share the host process ID namespace (Scored)\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that the\n          .spec.hostPID field is omitted or set to false.\n        scored: true\n\n      - id: 5.2.3\n        text: \"Minimize the admission of containers wishing to share the host IPC namespace (Scored)\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that the\n          .spec.hostIPC field is omitted or set to false.\n        scored: true\n\n      - id: 5.2.4\n        text: \"Minimize the admission of containers wishing to share the host network namespace (Scored)\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that the\n          .spec.hostNetwork field is omitted or set to false.\n        scored: true\n\n      - id: 5.2.5\n        text: \"Minimize the admission of containers with allowPrivilegeEscalation (Scored)\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that the\n          .spec.allowPrivilegeEscalation field is omitted or set to false.\n        scored: true\n\n      - id: 5.2.6\n        text: \"Minimize the admission of root containers (Scored)\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that the\n          .spec.runAsUser.rule is set to either MustRunAsNonRoot or MustRunAs with the range of\n          UIDs not including 0.\n        scored: true\n\n      - id: 5.2.7\n        text: \"Minimize the admission of containers with the NET_RAW capability (Scored)\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that the\n          .spec.requiredDropCapabilities is set to include either NET_RAW or ALL.\n        scored: true\n\n      - id: 5.2.8\n        text: \"Minimize the admission of containers with added capabilities (Scored)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that allowedCapabilities is not present in PSPs for the cluster unless\n          it is set to an empty array.\n        scored: true\n\n      - id: 5.2.9\n        text: \"Minimize the admission of containers with capabilities assigned (Scored) \"\n        type: \"manual\"\n        remediation: |\n          Review the use of capabilites in applications running on your cluster. Where a namespace\n          contains applications which do not require any Linux capabities to operate consider adding\n          a PSP which forbids the admission of containers which do not drop all capabilities.\n        scored: true\n\n  - id: 5.3\n    text: \"Network Policies and CNI\"\n    checks:\n      - id: 5.3.1\n        text: \"Ensure that the CNI in use supports Network Policies (Not Scored)\"\n        type: \"manual\"\n        remediation: |\n          To use a CNI plugin with Network Policy, enable Network Policy in GKE, and the CNI plugin\n          will be updated. See Recommendation 6.6.7.\n        scored: false\n\n      - id: 5.3.2\n        text: \"Ensure that all Namespaces have Network Policies defined (Scored)\"\n        type: \"manual\"\n        remediation: |\n          Follow the documentation and create NetworkPolicy objects as you need them.\n        scored: true\n\n  - id: 5.4\n    text: \"Secrets Management\"\n    checks:\n      - id: 5.4.1\n        text: \"Prefer using secrets as files over secrets as environment variables (Not Scored)\"\n        type: \"manual\"\n        remediation: |\n          if possible, rewrite application code to read secrets from mounted secret files, rather than\n          from environment variables.\n        scored: false\n\n      - id: 5.4.2\n        text: \"Consider external secret storage (Not Scored)\"\n        type: \"manual\"\n        remediation: |\n          Refer to the secrets management options offered by your cloud provider or a third-party\n          secrets management solution.\n        scored: false\n\n  - id: 5.5\n    text: \"Extensible Admission Control\"\n    checks:\n      - id: 5.5.1\n        text: \"Configure Image Provenance using ImagePolicyWebhook admission controller (Not Scored)\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and setup image provenance.\n          See also Recommendation 6.10.5 for GKE specifically.\n        scored: false\n\n  - id: 5.6\n    text: \"General Policies\"\n    checks:\n      - id: 5.6.1\n        text: \"Create administrative boundaries between resources using namespaces (Not Scored)\"\n        type: \"manual\"\n        remediation: |\n          Follow the documentation and create namespaces for objects in your deployment as you need\n          them.\n        scored: false\n\n      - id: 5.6.2\n        text: \"Ensure that the seccomp profile is set to docker/default in your pod definitions (Not Scored)\"\n        type: \"manual\"\n        remediation: |\n          Seccomp is an alpha feature currently. By default, all alpha features are disabled. So, you\n          would need to enable alpha features in the apiserver by passing \"--feature-\n          gates=AllAlpha=true\" argument.\n          Edit the /etc/kubernetes/apiserver file on the master node and set the KUBE_API_ARGS\n          parameter to \"--feature-gates=AllAlpha=true\"\n          KUBE_API_ARGS=\"--feature-gates=AllAlpha=true\"\n          Based on your system, restart the kube-apiserver service. For example:\n          systemctl restart kube-apiserver.service\n          Use annotations to enable the docker/default seccomp profile in your pod definitions. An\n          example is as below:\n          apiVersion: v1\n          kind: Pod\n          metadata:\n            name: trustworthy-pod\n            annotations:\n              seccomp.security.alpha.kubernetes.io/pod: docker/default\n          spec:\n            containers:\n              - name: trustworthy-container\n                image: sotrustworthy:latest\n        scored: false\n\n      - id: 5.6.3\n        text: \"Apply Security Context to Your Pods and Containers (Not Scored)\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and apply security contexts to your pods. For a\n          suggested list of security contexts, you may refer to the CIS Security Benchmark for Docker\n          Containers.\n        scored: false\n\n      - id: 5.6.4\n        text: \"The default namespace should not be used (Scored)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that namespaces are created to allow for appropriate segregation of Kubernetes\n          resources and that all new resources are created in a specific namespace.\n        scored: true\n"
  },
  {
    "path": "cfg/gke-1.2.0/config.yaml",
    "content": "---\n## Version-specific settings that override the values in cfg/config.yaml\n"
  },
  {
    "path": "cfg/gke-1.2.0/controlplane.yaml",
    "content": "---\ncontrols:\nversion: \"gke-1.2.0\"\nid: 2\ntext: \"Control Plane Configuration\"\ntype: \"controlplane\"\ngroups:\n  - id: 2.1\n    text: \"Authentication and Authorization\"\n    checks:\n      - id: 2.1.1\n        text: \"Client certificate authentication should not be used for users (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Alternative mechanisms provided by Kubernetes such as the use of OIDC should be\n          implemented in place of client certificates.\n          You can remediate the availability of client certificates in your GKE cluster. See\n          Recommendation 6.8.2.\n        scored: false\n\n  - id: 2.2\n    text: \"Logging\"\n    type: skip\n    checks:\n      - id: 2.2.1\n        text: \"Ensure that a minimal audit policy is created (Manual)\"\n        type: \"manual\"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n\n      - id: 2.2.2\n        text: \"Ensure that the audit policy covers key security concerns (Manual)\"\n        type: \"manual\"\n        remediation: \"This control cannot be modified in GKE.\"\n        scored: false\n"
  },
  {
    "path": "cfg/gke-1.2.0/managedservices.yaml",
    "content": "---\ncontrols:\nversion: \"gke-1.2.0\"\nid: 5\ntext: \"Managed Services\"\ntype: \"managedservices\"\ngroups:\n  - id: 5.1\n    text: \"Image Registry and Image Scanning\"\n    checks:\n      - id: 5.1.1\n        text: \"Ensure Image Vulnerability Scanning using GCR Container Analysis\n        or a third-party provider (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n\n            gcloud services enable containerscanning.googleapis.com\n        scored: false\n\n      - id: 5.1.2\n        text: \"Minimize user access to GCR (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n            To change roles at the GCR bucket level:\n            Firstly, run the following if read permissions are required:\n\n              gsutil iam ch [TYPE]:[EMAIL-ADDRESS]:objectViewer\n              gs://artifacts.[PROJECT_ID].appspot.com\n\n            Then remove the excessively privileged role (Storage Admin / Storage Object Admin /\n            Storage Object Creator) using:\n\n              gsutil iam ch -d [TYPE]:[EMAIL-ADDRESS]:[ROLE]\n              gs://artifacts.[PROJECT_ID].appspot.com\n\n            where:\n              [TYPE] can be one of the following:\n                    o user, if the [EMAIL-ADDRESS] is a Google account\n                    o serviceAccount, if [EMAIL-ADDRESS] specifies a Service account\n              [EMAIL-ADDRESS] can be one of the following:\n                    o a Google account (for example, someone@example.com)\n                    o a Cloud IAM service account\n                    To modify roles defined at the project level and subsequently inherited within the GCR\n                    bucket, or the Service Account User role, extract the IAM policy file, modify it accordingly\n            and apply it using:\n\n              gcloud projects set-iam-policy [PROJECT_ID] [POLICY_FILE]\n        scored: false\n\n      - id: 5.1.3\n        text: \"Minimize cluster access to read-only for GCR (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n            For an account explicitly granted to the bucket. First, add read access to the Kubernetes\n            Service Account\n\n              gsutil iam ch [TYPE]:[EMAIL-ADDRESS]:objectViewer\n              gs://artifacts.[PROJECT_ID].appspot.com\n\n              where:\n              [TYPE] can be one of the following:\n                      o user, if the [EMAIL-ADDRESS] is a Google account\n                      o serviceAccount, if [EMAIL-ADDRESS] specifies a Service account\n              [EMAIL-ADDRESS] can be one of the following:\n                      o a Google account (for example, someone@example.com)\n                      o a Cloud IAM service account\n\n              Then remove the excessively privileged role (Storage Admin / Storage Object Admin /\n              Storage Object Creator) using:\n\n                gsutil iam ch -d [TYPE]:[EMAIL-ADDRESS]:[ROLE]\n                gs://artifacts.[PROJECT_ID].appspot.com\n\n              For an account that inherits access to the GCR Bucket through Project level permissions,\n              modify the Projects IAM policy file accordingly, then upload it using:\n\n                gcloud projects set-iam-policy [PROJECT_ID] [POLICY_FILE]\n        scored: false\n\n      - id: 5.1.4\n        text: \"Minimize Container Registries to only those approved (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n            First, update the cluster to enable Binary Authorization:\n\n              gcloud container cluster update [CLUSTER_NAME] \\\n                --enable-binauthz\n\n            Create a Binary Authorization Policy using the Binary Authorization Policy Reference\n            (https://cloud.google.com/binary-authorization/docs/policy-yaml-reference) for guidance.\n            Import the policy file into Binary Authorization:\n\n              gcloud container binauthz policy import [YAML_POLICY]\n        scored: false\n\n  - id: 5.2\n    text: \"Identity and Access Management (IAM)\"\n    checks:\n      - id: 5.2.1\n        text: \"Ensure GKE clusters are not running using the Compute Engine\n        default service account (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n            Firstly, create a minimally privileged service account:\n\n              gcloud iam service-accounts create [SA_NAME] \\\n                --display-name \"GKE Node Service Account\"\n              export NODE_SA_EMAIL=`gcloud iam service-accounts list \\\n                --format='value(email)' \\\n                --filter='displayName:GKE Node Service Account'`\n\n            Grant the following roles to the service account:\n\n              export PROJECT_ID=`gcloud config get-value project`\n              gcloud projects add-iam-policy-binding $PROJECT_ID \\\n                --member serviceAccount:$NODE_SA_EMAIL \\\n                --role roles/monitoring.metricWriter\n              gcloud projects add-iam-policy-binding $PROJECT_ID \\\n                --member serviceAccount:$NODE_SA_EMAIL \\\n                --role roles/monitoring.viewer\n              gcloud projects add-iam-policy-binding $PROJECT_ID \\\n                --member serviceAccount:$NODE_SA_EMAIL \\\n                --role roles/logging.logWriter\n\n            To create a new Node pool using the Service account, run the following command:\n\n              gcloud container node-pools create [NODE_POOL] \\\n                --service-account=[SA_NAME]@[PROJECT_ID].iam.gserviceaccount.com \\\n                --cluster=[CLUSTER_NAME] --zone [COMPUTE_ZONE]\n\n            You will need to migrate your workloads to the new Node pool, and delete Node pools that\n            use the default service account to complete the remediation.\n        scored: false\n\n      - id: 5.2.2\n        text: \"Prefer using dedicated GCP Service Accounts and Workload Identity (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n\n              gcloud beta container clusters update [CLUSTER_NAME] --zone [CLUSTER_ZONE] \\\n                --identity-namespace=[PROJECT_ID].svc.id.goog\n\n            Note that existing Node pools are unaffected. New Node pools default to --workload-\n            metadata-from-node=GKE_METADATA_SERVER .\n\n            Then, modify existing Node pools to enable GKE_METADATA_SERVER:\n\n              gcloud beta container node-pools update [NODEPOOL_NAME] \\\n                --cluster=[CLUSTER_NAME] --zone [CLUSTER_ZONE] \\\n                --workload-metadata-from-node=GKE_METADATA_SERVER\n\n            You may also need to modify workloads in order for them to use Workload Identity as\n            described within https://cloud.google.com/kubernetes-engine/docs/how-to/workload-\n            identity. Also consider the effects on the availability of your hosted workloads as Node\n            pools are updated, it may be more appropriate to create new Node Pools.\n        scored: false\n\n  - id: 5.3\n    text: \"Cloud Key Management Service (Cloud KMS)\"\n    checks:\n      - id: 5.3.1\n        text: \"Ensure Kubernetes Secrets are encrypted using keys managed in Cloud KMS (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n            To create a key\n\n            Create a key ring:\n\n              gcloud kms keyrings create [RING_NAME] \\\n                --location [LOCATION] \\\n                --project [KEY_PROJECT_ID]\n\n            Create a key:\n\n              gcloud kms keys create [KEY_NAME] \\\n                --location [LOCATION] \\\n                --keyring [RING_NAME] \\\n                --purpose encryption \\\n                --project [KEY_PROJECT_ID]\n\n            Grant the Kubernetes Engine Service Agent service account the Cloud KMS CryptoKey\n            Encrypter/Decrypter role:\n\n              gcloud kms keys add-iam-policy-binding [KEY_NAME] \\\n                --location [LOCATION] \\\n                --keyring [RING_NAME] \\\n                --member serviceAccount:[SERVICE_ACCOUNT_NAME] \\\n                --role roles/cloudkms.cryptoKeyEncrypterDecrypter \\\n                --project [KEY_PROJECT_ID]\n\n            To create a new cluster with Application-layer Secrets Encryption:\n\n              gcloud container clusters create [CLUSTER_NAME] \\\n                --cluster-version=latest \\\n                --zone [ZONE] \\\n                --database-encryption-key projects/[KEY_PROJECT_ID]/locations/[LOCATION]/keyRings/[RING_NAME]/cryptoKey s/[KEY_NAME] \\\n                --project [CLUSTER_PROJECT_ID]\n\n            To enable on an existing cluster:\n\n              gcloud container clusters update [CLUSTER_NAME] \\\n                --zone [ZONE] \\\n                --database-encryption-key projects/[KEY_PROJECT_ID]/locations/[LOCATION]/keyRings/[RING_NAME]/cryptoKey s/[KEY_NAME] \\\n                --project [CLUSTER_PROJECT_ID]\n        scored: false\n\n  - id: 5.4\n    text: \"Node Metadata\"\n    checks:\n      - id: 5.4.1\n        text: \"Ensure legacy Compute Engine instance metadata APIs are Disabled (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n            To update an existing cluster, create a new Node pool with the legacy GCE metadata\n            endpoint disabled:\n\n              gcloud container node-pools create [POOL_NAME] \\\n                --metadata disable-legacy-endpoints=true \\\n                --cluster [CLUSTER_NAME] \\\n                --zone [COMPUTE_ZONE]\n\n            You will need to migrate workloads from any existing non-conforming Node pools, to the\n            new Node pool, then delete non-conforming Node pools to complete the remediation.\n        scored: false\n\n      - id: 5.4.2\n        text: \"Ensure the GKE Metadata Server is Enabled (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n              gcloud beta container clusters update [CLUSTER_NAME] \\\n                --identity-namespace=[PROJECT_ID].svc.id.goog\n            Note that existing Node pools are unaffected. New Node pools default to --workload-\n            metadata-from-node=GKE_METADATA_SERVER .\n\n            To modify an existing Node pool to enable GKE Metadata Server:\n\n              gcloud beta container node-pools update [NODEPOOL_NAME] \\\n                --cluster=[CLUSTER_NAME] \\\n                --workload-metadata-from-node=GKE_METADATA_SERVER\n\n            You may also need to modify workloads in order for them to use Workload Identity as\n            described within https://cloud.google.com/kubernetes-engine/docs/how-to/workload-\n            identity.\n        scored: false\n\n  - id: 5.5\n    text: \"Node Configuration and Maintenance\"\n    checks:\n      - id: 5.5.1\n        text: \"Ensure Container-Optimized OS (COS) is used for GKE node images (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n            To set the node image to cos for an existing cluster's Node pool:\n\n              gcloud container clusters upgrade [CLUSTER_NAME]\\\n                --image-type cos \\\n                --zone [COMPUTE_ZONE] --node-pool [POOL_NAME]\n        scored: false\n\n      - id: 5.5.2\n        text: \"Ensure Node Auto-Repair is enabled for GKE nodes (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n            To enable node auto-repair for an existing cluster with Node pool, run the following\n            command:\n\n              gcloud container node-pools update [POOL_NAME] \\\n                --cluster [CLUSTER_NAME] --zone [COMPUTE_ZONE] \\\n                --enable-autorepair\n        scored: false\n\n      - id: 5.5.3\n        text: \"Ensure Node Auto-Upgrade is enabled for GKE nodes (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n            To enable node auto-upgrade for an existing cluster's Node pool, run the following\n            command:\n\n              gcloud container node-pools update [NODE_POOL] \\\n                --cluster [CLUSTER_NAME] --zone [COMPUTE_ZONE] \\\n                --enable-autoupgrade\n        scored: false\n\n      - id: 5.5.4\n        text: \"Automate GKE version management using Release Channels (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n            Create a new cluster by running the following command:\n\n              gcloud beta container clusters create [CLUSTER_NAME] \\\n                --zone [COMPUTE_ZONE] \\\n                --release-channel [RELEASE_CHANNEL]\n\n            where [RELEASE_CHANNEL] is stable or regular according to your needs.\n        scored: false\n\n      - id: 5.5.5\n        text: \"Ensure Shielded GKE Nodes are Enabled (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n            To create a Node pool within the cluster with Integrity Monitoring enabled, run the\n            following command:\n\n              gcloud beta container node-pools create [NODEPOOL_NAME] \\\n                --cluster [CLUSTER_NAME] --zone [COMPUTE_ZONE] \\\n                --shielded-integrity-monitoring\n\n            You will also need to migrate workloads from existing non-conforming Node pools to the\n            newly created Node pool, then delete the non-conforming pools.\n        scored: false\n\n      - id: 5.5.6\n        text: \"Ensure Integrity Monitoring for Shielded GKE Nodes is Enabled (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n            To create a Node pool within the cluster with Integrity Monitoring enabled, run the\n            following command:\n\n              gcloud beta container node-pools create [NODEPOOL_NAME] \\\n                --cluster [CLUSTER_NAME] --zone [COMPUTE_ZONE] \\\n                --shielded-integrity-monitoring\n\n          You will also need to migrate workloads from existing non-conforming Node pools to the newly created Node pool,\n          then delete the non-conforming pools.\n        scored: false\n\n      - id: 5.5.7\n        text: \"Ensure Secure Boot for Shielded GKE Nodes is Enabled (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n            To create a Node pool within the cluster with Secure Boot enabled, run the following\n            command:\n\n              gcloud beta container node-pools create [NODEPOOL_NAME] \\\n                --cluster [CLUSTER_NAME] --zone [COMPUTE_ZONE] \\\n                --shielded-secure-boot\n\n            You will also need to migrate workloads from existing non-conforming Node pools to the\n            newly created Node pool, then delete the non-conforming pools.\n        scored: false\n\n  - id: 5.6\n    text: \"Cluster Networking\"\n    checks:\n      - id: 5.6.1\n        text: \"Enable VPC Flow Logs and Intranode Visibility (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n            To enable intranode visibility on an existing cluster, run the following command:\n\n              gcloud beta container clusters update [CLUSTER_NAME] \\\n                --enable-intra-node-visibility\n        scored: false\n\n      - id: 5.6.2\n        text: \"Ensure use of VPC-native clusters (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n            To enable Alias IP on a new cluster, run the following command:\n\n              gcloud container clusters create [CLUSTER_NAME] \\\n                --zone [COMPUTE_ZONE] \\\n                --enable-ip-alias\n        scored: false\n\n      - id: 5.6.3\n        text: \"Ensure Master Authorized Networks is Enabled (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n            To check Master Authorized Networks status for an existing cluster, run the following\n            command;\n\n              gcloud container clusters describe [CLUSTER_NAME] \\\n                --zone [COMPUTE_ZONE] \\\n                --format json | jq '.masterAuthorizedNetworksConfig'\n\n            The output should return\n\n              {\n                \"enabled\": true\n              }\n\n            if Master Authorized Networks is enabled.\n\n            If Master Authorized Networks is disabled, the\n            above command will return null ( { } ).\n        scored: false\n\n      - id: 5.6.4\n        text: \"Ensure clusters are created with Private Endpoint Enabled and Public Access Disabled (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n            Create a cluster with a Private Endpoint enabled and Public Access disabled by including\n            the --enable-private-endpoint flag within the cluster create command:\n\n              gcloud container clusters create [CLUSTER_NAME] \\\n                --enable-private-endpoint\n\n            Setting this flag also requires the setting of --enable-private-nodes , --enable-ip-alias\n            and --master-ipv4-cidr=[MASTER_CIDR_RANGE] .\n        scored: false\n\n      - id: 5.6.5\n        text: \"Ensure clusters are created with Private Nodes (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n            To create a cluster with Private Nodes enabled, include the --enable-private-nodes flag\n            within the cluster create command:\n\n              gcloud container clusters create [CLUSTER_NAME] \\\n                --enable-private-nodes\n\n            Setting this flag also requires the setting of --enable-ip-alias and --master-ipv4-\n            cidr=[MASTER_CIDR_RANGE] .\n        scored: false\n\n      - id: 5.6.6\n        text: \"Consider firewalling GKE worker nodes (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n            Use the following command to generate firewall rules, setting the variables as appropriate.\n            You may want to use the target [TAG] and [SERVICE_ACCOUNT] previously identified.\n\n              gcloud compute firewall-rules create FIREWALL_RULE_NAME \\\n                --network [NETWORK] \\\n                --priority [PRIORITY] \\\n                --direction [DIRECTION] \\\n                --action [ACTION] \\\n                --target-tags [TAG] \\\n                --target-service-accounts [SERVICE_ACCOUNT] \\\n                --source-ranges [SOURCE_CIDR-RANGE] \\\n                --source-tags [SOURCE_TAGS] \\\n                --source-service-accounts=[SOURCE_SERVICE_ACCOUNT] \\\n                --destination-ranges [DESTINATION_CIDR_RANGE] \\\n                --rules [RULES]\n        scored: false\n\n      - id: 5.6.7\n        text: \"Ensure Network Policy is Enabled and set as appropriate (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n            To enable Network Policy for an existing cluster, firstly enable the Network Policy add-on:\n\n              gcloud container clusters update [CLUSTER_NAME] \\\n                --zone [COMPUTE_ZONE] \\\n                --update-addons NetworkPolicy=ENABLED\n\n            Then, enable Network Policy:\n\n              gcloud container clusters update [CLUSTER_NAME] \\\n                --zone [COMPUTE_ZONE] \\\n                --enable-network-policy\n        scored: false\n\n      - id: 5.6.8\n        text: \"Ensure use of Google-managed SSL Certificates (Manual)\"\n        type: \"manual\"\n        remediation: |\n          If services of type:LoadBalancer are discovered, consider replacing the Service with an\n          Ingress.\n\n          To configure the Ingress and use Google-managed SSL certificates, follow the instructions\n          as listed at https://cloud.google.com/kubernetes-engine/docs/how-to/managed-certs.\n        scored: false\n\n  - id: 5.7\n    text: \"Logging\"\n    checks:\n      - id: 5.7.1\n        text: \"Ensure Stackdriver Kubernetes Logging and Monitoring is Enabled (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n\n            STACKDRIVER KUBERNETES ENGINE MONITORING SUPPORT (PREFERRED):\n            To enable Stackdriver Kubernetes Engine Monitoring for an existing cluster, run the\n            following command:\n\n              gcloud container clusters update [CLUSTER_NAME] \\\n                --zone [COMPUTE_ZONE] \\\n                --enable-stackdriver-kubernetes\n\n            LEGACY STACKDRIVER SUPPORT:\n            Both Logging and Monitoring support must be enabled.\n            To enable Legacy Stackdriver Logging for an existing cluster, run the following command:\n\n              gcloud container clusters update [CLUSTER_NAME] --zone [COMPUTE_ZONE] \\\n                --logging-service logging.googleapis.com\n\n            To enable Legacy Stackdriver Monitoring for an existing cluster, run the following\n            command:\n\n              gcloud container clusters update [CLUSTER_NAME] --zone [COMPUTE_ZONE] \\\n                --monitoring-service monitoring.googleapis.com\n        scored: false\n\n      - id: 5.7.2\n        text: \"Enable Linux auditd logging (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n            Download the example manifests:\n\n              curl https://raw.githubusercontent.com/GoogleCloudPlatform/k8s-node-tools/master/os-audit/cos-auditd-logging.yaml \\\n                > cos-auditd-logging.yaml\n\n            Edit the example manifests if needed. Then, deploy them:\n\n              kubectl apply -f cos-auditd-logging.yaml\n\n            Verify that the logging Pods have started. If you defined a different Namespace in your\n            manifests, replace cos-auditd with the name of the namespace you're using:\n\n              kubectl get pods --namespace=cos-auditd\n        scored: false\n\n  - id: 5.8\n    text: \"Authentication and Authorization\"\n    checks:\n      - id: 5.8.1\n        text: \"Ensure Basic Authentication using static passwords is Disabled (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n            To update an existing cluster and disable Basic Authentication by removing the static\n            password:\n\n              gcloud container clusters update [CLUSTER_NAME] \\\n                --no-enable-basic-auth\n        scored: false\n\n      - id: 5.8.2\n        text: \"Ensure authentication using Client Certificates is Disabled (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n            Create a new cluster without a Client Certificate:\n\n              gcloud container clusters create [CLUSTER_NAME] \\\n                --no-issue-client-certificate\n        scored: false\n\n      - id: 5.8.3\n        text: \"Manage Kubernetes RBAC users with Google Groups for GKE (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n            Follow the G Suite Groups instructions at https://cloud.google.com/kubernetes-\n            engine/docs/how-to/role-based-access-control#google-groups-for-gke.\n\n            Then, create a cluster with\n\n              gcloud beta container clusters create my-cluster \\\n                --security-group=\"gke-security-groups@[yourdomain.com]\"\n\n            Finally create Roles, ClusterRoles, RoleBindings, and ClusterRoleBindings that\n            reference your G Suite Groups.\n        scored: false\n\n      - id: 5.8.4\n        text: \"Ensure Legacy Authorization (ABAC) is Disabled (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n            To disable Legacy Authorization for an existing cluster, run the following command:\n\n              gcloud container clusters update [CLUSTER_NAME] \\\n                --zone [COMPUTE_ZONE] \\\n                --no-enable-legacy-authorization\n        scored: false\n\n  - id: 5.9\n    text: \"Storage\"\n    checks:\n      - id: 5.9.1\n        text: \"Enable Customer-Managed Encryption Keys (CMEK) for GKE Persistent Disks (PD) (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n            FOR NODE BOOT DISKS:\n            Create a new node pool using customer-managed encryption keys for the node boot disk, of\n            [DISK_TYPE] either pd-standard or pd-ssd :\n\n              gcloud beta container node-pools create [CLUSTER_NAME] \\\n                --disk-type [DISK_TYPE] \\\n                --boot-disk-kms-key \\\n                projects/[KEY_PROJECT_ID]/locations/[LOCATION]/keyRings/[RING_NAME]/cryptoKeys/[KEY_NAME]\n\n            Create a cluster using customer-managed encryption keys for the node boot disk, of\n            [DISK_TYPE] either pd-standard or pd-ssd :\n\n              gcloud beta container clusters create [CLUSTER_NAME] \\\n                --disk-type [DISK_TYPE] \\\n                --boot-disk-kms-key \\\n                projects/[KEY_PROJECT_ID]/locations/[LOCATION]/keyRings/[RING_NAME]/cryptoKeys/[KEY_NAME]\n\n            FOR ATTACHED DISKS:\n            Follow the instructions detailed at https://cloud.google.com/kubernetes-\n            engine/docs/how-to/using-cmek.\n        scored: false\n\n  - id: 5.10\n    text: \"Other Cluster Configurations\"\n    checks:\n      - id: 5.10.1\n        text: \"Ensure Kubernetes Web UI is Disabled (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n            To disable the Kubernetes Dashboard on an existing cluster, run the following command:\n\n              gcloud container clusters update [CLUSTER_NAME] \\\n                --zone [ZONE] \\\n                --update-addons=KubernetesDashboard=DISABLED\n        scored: false\n\n      - id: 5.10.2\n        text: \"Ensure that Alpha clusters are not used for production workloads (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n            Upon creating a new cluster\n\n              gcloud container clusters create [CLUSTER_NAME] \\\n                --zone [COMPUTE_ZONE]\n\n            Do not use the --enable-kubernetes-alpha argument.\n        scored: false\n\n      - id: 5.10.3\n        text: \"Ensure Pod Security Policy is Enabled and set as appropriate (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n            To enable Pod Security Policy for an existing cluster, run the following command:\n\n              gcloud beta container clusters update [CLUSTER_NAME] \\\n                --zone [COMPUTE_ZONE] \\\n                --enable-pod-security-policy\n        scored: false\n\n      - id: 5.10.4\n        text: \"Consider GKE Sandbox for running untrusted workloads (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n            To enable GKE Sandbox on an existing cluster, a new Node pool must be created.\n\n              gcloud container node-pools create [NODE_POOL_NAME] \\\n                --zone=[COMPUTE-ZONE] \\\n                --cluster=[CLUSTER_NAME] \\\n                --image-type=cos_containerd \\\n                --sandbox type=gvisor\n        scored: false\n\n      - id: 5.10.5\n        text: \"Ensure use of Binary Authorization (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n            Firstly, update the cluster to enable Binary Authorization:\n\n              gcloud container cluster update [CLUSTER_NAME] \\\n                --zone [COMPUTE-ZONE] \\\n                --enable-binauthz\n\n            Create a Binary Authorization Policy using the Binary Authorization Policy Reference\n            (https://cloud.google.com/binary-authorization/docs/policy-yaml-reference) for\n            guidance.\n\n            Import the policy file into Binary Authorization:\n\n              gcloud container binauthz policy import [YAML_POLICY]\n        scored: false\n\n      - id: 5.10.6\n        text: \"Enable Cloud Security Command Center (Cloud SCC) (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n            Follow the instructions at https://cloud.google.com/security-command-\n            center/docs/quickstart-scc-setup.\n        scored: false\n"
  },
  {
    "path": "cfg/gke-1.2.0/master.yaml",
    "content": "---\ncontrols:\nversion: \"gke-1.2.0\"\nid: 1\ntext: \"Control Plane Components\"\ntype: \"master\"\n"
  },
  {
    "path": "cfg/gke-1.2.0/node.yaml",
    "content": "---\ncontrols:\nversion: \"gke-1.2.0\"\nid: 3\ntext: \"Worker Node Security Configuration\"\ntype: \"node\"\ngroups:\n  - id: 3.1\n    text: \"Worker Node Configuration Files\"\n    checks:\n      - id: 3.1.1\n        text: \"Ensure that the proxy kubeconfig file permissions are set to 644 or more restrictive (Manual)\"\n        audit: '/bin/sh -c ''if test -e $proxykubeconfig; then stat -c permissions=%a $proxykubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on each worker node.\n          For example,\n          chmod 644 $proxykubeconfig\n        scored: false\n\n      - id: 3.1.2\n        text: \"Ensure that the proxy kubeconfig file ownership is set to root:root (Manual)\"\n        audit: '/bin/sh -c ''if test -e $proxykubeconfig; then stat -c %U:%G $proxykubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the below command (based on the file location on your system) on each worker node.\n          For example, chown root:root $proxykubeconfig\n        scored: false\n\n      - id: 3.1.3\n        text: \"Ensure that the kubelet configuration file permissions are set to 644 or more restrictive (Manual)\"\n        audit: '/bin/sh -c ''if test -e $kubeletconf; then stat -c permissions=%a $kubeletconf; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the following command (using the config file location identied in the Audit step)\n          chmod 644 /var/lib/kubelet/config.yaml\n        scored: false\n\n      - id: 3.1.4\n        text: \"Ensure that the kubelet configuration file ownership is set to root:root (Manual)\"\n        audit: '/bin/sh -c ''if test -e $kubeletconf; then stat -c %U:%G $kubeletconf; fi'' '\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the following command (using the config file location identied in the Audit step)\n          chown root:root /etc/kubernetes/kubelet.conf\n        scored: false\n\n  - id: 3.2\n    text: \"Kubelet\"\n    checks:\n      - id: 3.2.1\n        text: \"Ensure that the --anonymous-auth argument is set to false (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: \"--anonymous-auth\"\n              path: '{.authentication.anonymous.enabled}'\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          If using a Kubelet config file, edit the file to set authentication: anonymous: enabled to\n          false.\n          If using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --anonymous-auth=false\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 3.2.2\n        text: \"Ensure that the --authorization-mode argument is not set to AlwaysAllow (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --authorization-mode\n              path: '{.authorization.mode}'\n              compare:\n                op: nothave\n                value: AlwaysAllow\n        remediation: |\n          If using a Kubelet config file, edit the file to set authorization: mode to Webhook. If\n          using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_AUTHZ_ARGS variable.\n          --authorization-mode=Webhook\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 3.2.3\n        text: \"Ensure that the --client-ca-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --client-ca-file\n              path: '{.authentication.x509.clientCAFile}'\n              set: true\n        remediation: |\n          If using a Kubelet config file, edit the file to set authentication: x509: clientCAFile to\n          the location of the client CA file.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_AUTHZ_ARGS variable.\n          --client-ca-file=<path/to/client-ca-file>\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 3.2.4\n        text: \"Ensure that the --read-only-port argument is set to 0 (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: \"--read-only-port\"\n              path: '{.readOnlyPort}'\n              set: true\n              compare:\n                op: eq\n                value: 0\n        remediation: |\n          If using a Kubelet config file, edit the file to set readOnlyPort to 0.\n          If using command line arguments, edit the kubelet service file /etc/systemd/system/kubelet.service.d/10-kubeadm.conf\n          on each worker node and set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --read-only-port=0\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 3.2.5\n        text: \"Ensure that the --streaming-connection-idle-timeout argument is not set to 0 (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --streaming-connection-idle-timeout\n              path: '{.streamingConnectionIdleTimeout}'\n              compare:\n                op: noteq\n                value: 0\n            - flag: --streaming-connection-idle-timeout\n              path: '{.streamingConnectionIdleTimeout}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to set streamingConnectionIdleTimeout to a\n          value other than 0.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --streaming-connection-idle-timeout=5m\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 3.2.6\n        text: \"Ensure that the --protect-kernel-defaults argument is set to true (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --protect-kernel-defaults\n              path: '{.protectKernelDefaults}'\n              set: true\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          If using a Kubelet config file, edit the file to set protectKernelDefaults: true.\n          If using command line arguments, edit the kubelet service file /etc/systemd/system/kubelet.service.d/10-kubeadm.conf\n          on each worker node and set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --protect-kernel-defaults=true\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 3.2.7\n        text: \"Ensure that the --make-iptables-util-chains argument is set to true (Automated) \"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --make-iptables-util-chains\n              path: '{.makeIPTablesUtilChains}'\n              compare:\n                op: eq\n                value: true\n            - flag: --make-iptables-util-chains\n              path: '{.makeIPTablesUtilChains}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to set makeIPTablesUtilChains: true.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          remove the --make-iptables-util-chains argument from the\n          KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 3.2.8\n        text: \"Ensure that the --hostname-override argument is not set (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin \"\n        tests:\n          test_items:\n            - flag: --hostname-override\n              set: false\n        remediation: |\n          Edit the kubelet service file $kubeletsvc\n          on each worker node and remove the --hostname-override argument from the\n          KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 3.2.9\n        text: \"Ensure that the --event-qps argument is set to 0 or a level which ensures appropriate event capture (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --event-qps\n              path: '{.eventRecordQPS}'\n              set: true\n              compare:\n                op: eq\n                value: 0\n        remediation: |\n          If using a Kubelet config file, edit the file to set eventRecordQPS: to an appropriate level.\n          If using command line arguments, edit the kubelet service file /etc/systemd/system/kubelet.service.d/10-kubeadm.conf\n          on each worker node and set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 3.2.10\n        text: \"Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --tls-cert-file\n              path: '{.tlsCertFile}'\n            - flag: --tls-private-key-file\n              path: '{.tlsPrivateKeyFile}'\n        remediation: |\n          If using a Kubelet config file, edit the file to set tlsCertFile to the location\n          of the certificate file to use to identify this Kubelet, and tlsPrivateKeyFile\n          to the location of the corresponding private key file.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameters in KUBELET_CERTIFICATE_ARGS variable.\n          --tls-cert-file=<path/to/tls-certificate-file>\n          --tls-private-key-file=<path/to/tls-key-file>\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 3.2.11\n        text: \"Ensure that the --rotate-certificates argument is not set to false (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --rotate-certificates\n              path: '{.rotateCertificates}'\n              compare:\n                op: eq\n                value: true\n            - flag: --rotate-certificates\n              path: '{.rotateCertificates}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to add the line rotateCertificates: true or\n          remove it altogether to use the default value.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          remove --rotate-certificates=false argument from the KUBELET_CERTIFICATE_ARGS\n          variable.\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 3.2.12\n        text: \"Ensure that the RotateKubeletServerCertificate argument is set to true (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: RotateKubeletServerCertificate\n              path: '{.featureGates.RotateKubeletServerCertificate}'\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Edit the kubelet service file $kubeletsvc\n          on each worker node and set the below parameter in KUBELET_CERTIFICATE_ARGS variable.\n          --feature-gates=RotateKubeletServerCertificate=true\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n"
  },
  {
    "path": "cfg/gke-1.2.0/policies.yaml",
    "content": "---\ncontrols:\nversion: \"gke-1.2.0\"\nid: 4\ntext: \"Kubernetes Policies\"\ntype: \"policies\"\ngroups:\n  - id: 4.1\n    text: \"RBAC and Service Accounts\"\n    checks:\n      - id: 4.1.1\n        text: \"Ensure that the cluster-admin role is only used where required (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Identify all clusterrolebindings to the cluster-admin role. Check if they are used and\n          if they need this role or if they could use a role with fewer privileges.\n          Where possible, first bind users to a lower privileged role and then remove the\n          clusterrolebinding to the cluster-admin role :\n          kubectl delete clusterrolebinding [name]\n        scored: false\n\n      - id: 4.1.2\n        text: \"Minimize access to secrets (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove get, list and watch access to secret objects in the cluster.\n        scored: false\n\n      - id: 4.1.3\n        text: \"Minimize wildcard use in Roles and ClusterRoles (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible replace any use of wildcards in clusterroles and roles with specific\n          objects or actions.\n        scored: false\n\n      - id: 4.1.4\n        text: \"Minimize access to create pods (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove create access to pod objects in the cluster.\n        scored: false\n\n      - id: 4.1.5\n        text: \"Ensure that default service accounts are not actively used. (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Create explicit service accounts wherever a Kubernetes workload requires specific access\n          to the Kubernetes API server.\n          Modify the configuration of each default service account to include this value\n          automountServiceAccountToken: false\n        scored: true\n\n      - id: 4.1.6\n        text: \"Ensure that Service Account Tokens are only mounted where necessary (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Modify the definition of pods and service accounts which do not need to mount service\n          account tokens to disable it.\n        scored: false\n\n  - id: 4.2\n    text: \"Pod Security Policies\"\n    checks:\n      - id: 4.2.1\n        text: \"Minimize the admission of privileged containers (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that\n          the .spec.privileged field is omitted or set to false.\n        scored: false\n\n      - id: 4.2.2\n        text: \"Minimize the admission of containers wishing to share the host process ID namespace (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that the\n          .spec.hostPID field is omitted or set to false.\n        scored: false\n\n      - id: 4.2.3\n        text: \"Minimize the admission of containers wishing to share the host IPC namespace (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that the\n          .spec.hostIPC field is omitted or set to false.\n        scored: false\n\n      - id: 4.2.4\n        text: \"Minimize the admission of containers wishing to share the host network namespace (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that the\n          .spec.hostNetwork field is omitted or set to false.\n        scored: false\n\n      - id: 4.2.5\n        text: \"Minimize the admission of containers with allowPrivilegeEscalation (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that the\n          .spec.allowPrivilegeEscalation field is omitted or set to false.\n        scored: false\n\n      - id: 4.2.6\n        text: \"Minimize the admission of root containers (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that the\n          .spec.runAsUser.rule is set to either MustRunAsNonRoot or MustRunAs with the range of\n          UIDs not including 0.\n        scored: false\n\n      - id: 4.2.7\n        text: \"Minimize the admission of containers with the NET_RAW capability (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that the\n          .spec.requiredDropCapabilities is set to include either NET_RAW or ALL.\n        scored: false\n\n      - id: 4.2.8\n        text: \"Minimize the admission of containers with added capabilities (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that allowedCapabilities is not present in PSPs for the cluster unless\n          it is set to an empty array.\n        scored: false\n\n      - id: 4.2.9\n        text: \"Minimize the admission of containers with capabilities assigned (Manual) \"\n        type: \"manual\"\n        remediation: |\n          Review the use of capabilites in applications running on your cluster. Where a namespace\n          contains applications which do not require any Linux capabities to operate consider adding\n          a PSP which forbids the admission of containers which do not drop all capabilities.\n        scored: false\n\n  - id: 4.3\n    text: \"Network Policies and CNI\"\n    checks:\n      - id: 4.3.1\n        text: \"Ensure that the CNI in use supports Network Policies (Manual)\"\n        type: \"manual\"\n        remediation: |\n          To use a CNI plugin with Network Policy, enable Network Policy in GKE, and the CNI plugin\n          will be updated. See Recommendation 6.6.7.\n        scored: false\n\n      - id: 4.3.2\n        text: \"Ensure that all Namespaces have Network Policies defined (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the documentation and create NetworkPolicy objects as you need them.\n        scored: false\n\n  - id: 4.4\n    text: \"Secrets Management\"\n    checks:\n      - id: 4.4.1\n        text: \"Prefer using secrets as files over secrets as environment variables (Manual)\"\n        type: \"manual\"\n        remediation: |\n          if possible, rewrite application code to read secrets from mounted secret files, rather than\n          from environment variables.\n        scored: false\n\n      - id: 4.4.2\n        text: \"Consider external secret storage (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Refer to the secrets management options offered by your cloud provider or a third-party\n          secrets management solution.\n        scored: false\n\n  - id: 4.5\n    text: \"Extensible Admission Control\"\n    checks:\n      - id: 4.5.1\n        text: \"Configure Image Provenance using ImagePolicyWebhook admission controller (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and setup image provenance.\n          See also Recommendation 6.10.5 for GKE specifically.\n        scored: false\n\n  - id: 4.6\n    text: \"General Policies\"\n    checks:\n      - id: 4.6.1\n        text: \"Create administrative boundaries between resources using namespaces (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the documentation and create namespaces for objects in your deployment as you need\n          them.\n        scored: false\n\n      - id: 4.6.2\n        text: \"Ensure that the seccomp profile is set to docker/default in your pod definitions (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Seccomp is an alpha feature currently. By default, all alpha features are disabled. So, you\n          would need to enable alpha features in the apiserver by passing \"--feature-\n          gates=AllAlpha=true\" argument.\n          Edit the /etc/kubernetes/apiserver file on the master node and set the KUBE_API_ARGS\n          parameter to \"--feature-gates=AllAlpha=true\"\n          KUBE_API_ARGS=\"--feature-gates=AllAlpha=true\"\n          Based on your system, restart the kube-apiserver service. For example:\n          systemctl restart kube-apiserver.service\n          Use annotations to enable the docker/default seccomp profile in your pod definitions. An\n          example is as below:\n          apiVersion: v1\n          kind: Pod\n          metadata:\n            name: trustworthy-pod\n            annotations:\n              seccomp.security.alpha.kubernetes.io/pod: docker/default\n          spec:\n            containers:\n              - name: trustworthy-container\n                image: sotrustworthy:latest\n        scored: false\n\n      - id: 4.6.3\n        text: \"Apply Security Context to Your Pods and Containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and apply security contexts to your pods. For a\n          suggested list of security contexts, you may refer to the CIS Security Benchmark for Docker\n          Containers.\n        scored: false\n\n      - id: 4.6.4\n        text: \"The default namespace should not be used (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that namespaces are created to allow for appropriate segregation of Kubernetes\n          resources and that all new resources are created in a specific namespace.\n        scored: false\n"
  },
  {
    "path": "cfg/gke-1.6.0/config.yaml",
    "content": "---\n## Version-specific settings that override the values in cfg/config.yaml\n\nnode:\n  proxy:\n    defaultkubeconfig: \"/var/lib/kubelet/kubeconfig\"\n\n  kubelet:\n    defaultconf: \"/etc/kubernetes/kubelet/kubelet-config.yaml\"\n"
  },
  {
    "path": "cfg/gke-1.6.0/controlplane.yaml",
    "content": "---\ncontrols:\nversion: \"gke-1.6.0\"\nid: 2\ntext: \"Control Plane Configuration\"\ntype: \"controlplane\"\ngroups:\n  - id: 2.1\n    text: \"Authentication and Authorization\"\n    checks:\n      - id: 2.1.1\n        text: \"Client certificate authentication should not be used for users (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Alternative mechanisms provided by Kubernetes such as the use of OIDC should be\n          implemented in place of client certificates.\n\n          You can remediate the availability of client certificates in your GKE cluster. See\n          Recommendation 5.8.1.\n        scored: false\n"
  },
  {
    "path": "cfg/gke-1.6.0/managedservices.yaml",
    "content": "---\ncontrols:\nversion: \"gke-1.6.0\"\nid: 5\ntext: \"Managed Services\"\ntype: \"managedservices\"\ngroups:\n  - id: 5.1\n    text: \"Image Registry and Image Scanning\"\n    checks:\n      - id: 5.1.1\n        text: \"Ensure Image Vulnerability Scanning is enabled (Automated)\"\n        type: \"manual\"\n        remediation: |\n          For Images Hosted in GCR:\n          Using Command Line:\n\n            gcloud services enable containeranalysis.googleapis.com\n\n          For Images Hosted in AR:\n          Using Command Line:\n\n            gcloud services enable containerscanning.googleapis.com\n        scored: false\n\n      - id: 5.1.2\n        text: \"Minimize user access to Container Image repositories (Manual)\"\n        type: \"manual\"\n        remediation: |\n          For Images Hosted in AR:\n          Using Command Line:\n\n            gcloud artifacts repositories set-iam-policy <repository-name> <path-to-policy-file> \\\n              --location <repository-location>\n\n          To learn how to configure policy files see: https://cloud.google.com/artifact-registry/docs/access-control#grant\n\n          For Images Hosted in GCR:\n          Using Command Line:\n          To change roles at the GCR bucket level:\n          Firstly, run the following if read permissions are required:\n\n            gsutil iam ch <type>:<email_address>:objectViewer gs://artifacts.<project_id>.appspot.com\n\n          Then remove the excessively privileged role (Storage Admin / Storage Object\n          Admin / Storage Object Creator) using:\n\n            gsutil iam ch -d <type>:<email_address>:<role> gs://artifacts.<project_id>.appspot.com\n\n          where:\n          <type> can be one of the following:\n            user, if the <email_address> is a Google account.\n            serviceAccount, if <email_address> specifies a Service account.\n            <email_address> can be one of the following:\n              a Google account (for example, someone@example.com).\n              a Cloud IAM service account.\n\n          To modify roles defined at the project level and subsequently inherited within the GCR\n          bucket, or the Service Account User role, extract the IAM policy file, modify it\n          accordingly and apply it using:\n\n            gcloud projects set-iam-policy <project_id> <policy_file>\n        scored: false\n\n      - id: 5.1.3\n        text: \"Minimize cluster access to read-only for Container Image repositories (Manual)\"\n        type: \"manual\"\n        remediation: |\n          For Images Hosted in AR:\n          Using Command Line:\n          Add artifactregistry.reader role\n\n            gcloud artifacts repositories add-iam-policy-binding <repository> \\\n            --location=<repository-location> \\\n            --member='serviceAccount:<email-address>' \\\n            --role='roles/artifactregistry.reader'\n\n          Remove any roles other than artifactregistry.reader\n\n            gcloud artifacts repositories remove-iam-policy-binding <repository> \\\n            --location <repository-location> \\\n            --member='serviceAccount:<email-address>' \\\n            --role='<role-name>'\n\n          For Images Hosted in GCR:\n          For an account explicitly granted to the bucket:\n          Firstly add read access to the Kubernetes Service Account:\n\n            gsutil iam ch <type>:<email_address>:objectViewer gs://artifacts.<project_id>.appspot.com\n\n            where:\n              <type> can be one of the following:\n                user, if the <email_address> is a Google account.\n                serviceAccount, if <email_address> specifies a Service account.\n                <email_address> can be one of the following:\n                  a Google account (for example, someone@example.com).\n                  a Cloud IAM service account.\n\n          Then remove the excessively privileged role (Storage Admin / Storage Object\n          Admin / Storage Object Creator) using:\n\n            gsutil iam ch -d <type>:<email_address>:<role> gs://artifacts.<project_id>.appspot.com\n\n          For an account that inherits access to the GCR Bucket through Project level\n          permissions, modify the Projects IAM policy file accordingly, then upload it using:\n\n            gcloud projects set-iam-policy <project_id> <policy_file>\n        scored: false\n\n      - id: 5.1.4\n        text: \"Ensure only trusted container images are used (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n          Update the cluster to enable Binary Authorization:\n\n            gcloud container cluster update <cluster_name> --enable-binauthz\n\n          Create a Binary Authorization Policy using the Binary Authorization Policy Reference:\n          https://cloud.google.com/binary-authorization/docs/policy-yaml-reference for guidance.\n\n          Import the policy file into Binary Authorization:\n\n            gcloud container binauthz policy import <yaml_policy>\n        scored: false\n\n  - id: 5.2\n    text: \"Identity and Access Management (IAM)\"\n    checks:\n      - id: 5.2.1\n        text: \"Ensure GKE clusters are not running using the Compute Engine default service account (Automated))\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n          To create a minimally privileged service account:\n\n            gcloud iam service-accounts create <node_sa_name> \\\n              --display-name \"GKE Node Service Account\"\n            export NODE_SA_EMAIL=gcloud iam service-accounts list \\\n              --format='value(email)' --filter='displayName:GKE Node Service Account'\n\n          Grant the following roles to the service account:\n\n            export PROJECT_ID=gcloud config get-value project\n            gcloud projects add-iam-policy-binding <project_id> --member \\\n              serviceAccount:<node_sa_email> --role roles/monitoring.metricWriter\n            gcloud projects add-iam-policy-binding <project_id> --member \\\n              serviceAccount:<node_sa_email> --role roles/monitoring.viewer\n            gcloud projects add-iam-policy-binding <project_id> --member \\\n              serviceAccount:<node_sa_email> --role roles/logging.logWriter\n\n          To create a new Node pool using the Service account, run the following command:\n\n            gcloud container node-pools create <node_pool> \\\n              --service-account=<sa_name>@<project_id>.iam.gserviceaccount.com \\\n              --cluster=<cluster_name> --zone <compute_zone>\n\n          Note: The workloads will need to be migrated to the new Node pool, and the old node\n          pools that use the default service account should be deleted to complete the\n          remediation.\n        scored: false\n\n      - id: 5.2.2\n        text: \"Prefer using dedicated GCP Service Accounts and Workload Identity (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n\n            gcloud container clusters update <cluster_name> --zone <cluster_zone> \\\n            --workload-pool <project_id>.svc.id.goog\n\n          Note that existing Node pools are unaffected. New Node pools default to --workload-\n          metadata-from-node=GKE_METADATA_SERVER.\n\n          Then, modify existing Node pools to enable GKE_METADATA_SERVER:\n\n            gcloud container node-pools update <node_pool_name> --cluster <cluster_name> \\\n              --zone <cluster_zone> --workload-metadata=GKE_METADATA\n\n          Workloads may need to be modified in order for them to use Workload Identity as\n          described within: https://cloud.google.com/kubernetes-engine/docs/how-to/workload-identity.\n          Also consider the effects on the availability of hosted workloads as Node pools\n          are updated. It may be more appropriate to create new Node Pools.\n        scored: false\n\n  - id: 5.3\n    text: \"Cloud Key Management Service (Cloud KMS)\"\n    checks:\n      - id: 5.3.1\n        text: \"Ensure Kubernetes Secrets are encrypted using keys managed in Cloud KMS (Automated)\"\n        type: \"manual\"\n        remediation: |\n          To create a key:\n          Create a key ring:\n\n            gcloud kms keyrings create <ring_name> --location <location> --project \\\n              <key_project_id>\n\n          Create a key:\n\n            gcloud kms keys create <key_name> --location <location> --keyring <ring_name> \\\n              --purpose encryption --project <key_project_id>\n\n          Grant the Kubernetes Engine Service Agent service account the Cloud KMS\n          CryptoKey Encrypter/Decrypter role:\n\n            gcloud kms keys add-iam-policy-binding <key_name> --location <location> \\\n            --keyring <ring_name> --member serviceAccount:<service_account_name> \\\n            --role roles/cloudkms.cryptoKeyEncrypterDecrypter --project <key_project_id>\n\n          To create a new cluster with Application-layer Secrets Encryption:\n\n            gcloud container clusters create <cluster_name> --cluster-version=latest \\\n            --zone <zone> \\\n            --database-encryption-key projects/<key_project_id>/locations/<location>/keyRings/<ring_name>/cryptoKeys/<key_name> \\\n            --project <cluster_project_id>\n\n          To enable on an existing cluster:\n\n            gcloud container clusters update <cluster_name> --zone <zone> \\\n            --database-encryption-key projects/<key_project_id>/locations/<location>/keyRings/<ring_name>/cryptoKeys/<key_name> \\\n            --project <cluster_project_id>\n        scored: false\n\n  - id: 5.4\n    text: \"Node Metadata\"\n    checks:\n      - id: 5.4.1\n        text: \"Ensure the GKE Metadata Server is Enabled (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n\n            gcloud container clusters update <cluster_name> --identity-namespace=<project_id>.svc.id.goog\n\n          Note that existing Node pools are unaffected. New Node pools default to --workload-\n          metadata-from-node=GKE_METADATA_SERVER.\n\n          To modify an existing Node pool to enable GKE Metadata Server:\n\n            gcloud container node-pools update <node_pool_name> --cluster=<cluster_name> \\\n              --workload-metadata-from-node=GKE_METADATA_SERVER\n\n          Workloads may need modification in order for them to use Workload Identity as\n          described within: https://cloud.google.com/kubernetes-engine/docs/how-to/workload-identity.\n        scored: false\n\n  - id: 5.5\n    text: \"Node Configuration and Maintenance\"\n    checks:\n      - id: 5.5.1\n        text: \"Ensure Container-Optimized OS (cos_containerd) is used for GKE node images (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n          To set the node image to cos for an existing cluster's Node pool:\n\n            gcloud container clusters upgrade <cluster_name> --image-type cos_containerd \\\n              --zone <compute_zone> --node-pool <node_pool_name>\n        scored: false\n\n      - id: 5.5.2\n        text: \"Ensure Node Auto-Repair is enabled for GKE nodes (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n          To enable node auto-repair for an existing cluster's Node pool:\n\n            gcloud container node-pools update <node_pool_name> --cluster <cluster_name> \\\n              --zone <compute_zone> --enable-autorepair\n        scored: false\n\n      - id: 5.5.3\n        text: \"Ensure Node Auto-Upgrade is enabled for GKE nodes (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n          To enable node auto-upgrade for an existing cluster's Node pool, run the following\n          command:\n\n            gcloud container node-pools update <node_pool_name> --cluster <cluster_name> \\\n              --zone <cluster_zone> --enable-autoupgrade\n        scored: false\n\n      - id: 5.5.4\n        text: \"When creating New Clusters - Automate GKE version management using Release Channels (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n          Create a new cluster by running the following command:\n\n            gcloud container clusters create <cluster_name> --zone <cluster_zone> \\\n              --release-channel <release_channel>\n\n          where <release_channel> is stable or regular, according to requirements.\n        scored: false\n\n      - id: 5.5.5\n        text: \"Ensure Shielded GKE Nodes are Enabled (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n          To migrate an existing cluster, the flag --enable-shielded-nodes needs to be\n          specified in the cluster update command:\n\n            gcloud container clusters update <cluster_name> --zone <cluster_zone> \\\n              --enable-shielded-nodes\n        scored: false\n\n      - id: 5.5.6\n        text: \"Ensure Integrity Monitoring for Shielded GKE Nodes is Enabled (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n          To create a Node pool within the cluster with Integrity Monitoring enabled, run the\n          following command:\n\n            gcloud container node-pools create <node_pool_name> --cluster <cluster_name> \\\n              --zone <compute_zone> --shielded-integrity-monitoring\n\n          Workloads from existing non-conforming Node pools will need to be migrated to the\n          newly created Node pool, then delete non-conforming Node pools to complete the\n          remediation\n        scored: false\n\n      - id: 5.5.7\n        text: \"Ensure Secure Boot for Shielded GKE Nodes is Enabled (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n          To create a Node pool within the cluster with Secure Boot enabled, run the following\n          command:\n\n            gcloud container node-pools create <node_pool_name> --cluster <cluster_name> \\\n              --zone <compute_zone> --shielded-secure-boot\n\n          Workloads will need to be migrated from existing non-conforming Node pools to the\n          newly created Node pool, then delete the non-conforming pools.\n        scored: false\n\n  - id: 5.6\n    text: \"Cluster Networking\"\n    checks:\n      - id: 5.6.1\n        text: \"Enable VPC Flow Logs and Intranode Visibility (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n          1. Find the subnetwork name associated with the cluster.\n\n            gcloud container clusters describe <cluster_name> \\\n              --region <cluster_region> - -format json | jq '.subnetwork'\n\n          2. Update the subnetwork to enable VPC Flow Logs.\n            gcloud compute networks subnets update <subnet_name> --enable-flow-logs\n        scored: false\n\n      - id: 5.6.2\n        text: \"Ensure use of VPC-native clusters (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n          To enable Alias IP on a new cluster, run the following command:\n\n            gcloud container clusters create <cluster_name> --zone <compute_zone> \\\n              --enable-ip-alias\n\n          If using Autopilot configuration mode:\n\n            gcloud container clusters create-auto <cluster_name> \\\n              --zone <compute_zone>\n        scored: false\n\n      - id: 5.6.3\n        text: \"Ensure Control Plane Authorized Networks is Enabled (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n          To enable Control Plane Authorized Networks for an existing cluster, run the following\n          command:\n\n            gcloud container clusters update <cluster_name> --zone <compute_zone> \\\n              --enable-master-authorized-networks\n\n          Along with this, you can list authorized networks using the --master-authorized-networks\n          flag which contains a list of up to 20 external networks that are allowed to\n          connect to your cluster's control plane through HTTPS. You provide these networks as\n          a comma-separated list of addresses in CIDR notation (such as 90.90.100.0/24).\n        scored: false\n\n      - id: 5.6.4\n        text: \"Ensure clusters are created with Private Endpoint Enabled and Public Access Disabled (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n          Create a cluster with a Private Endpoint enabled and Public Access disabled by including\n          the --enable-private-endpoint flag within the cluster create command:\n\n            gcloud container clusters create <cluster_name> --enable-private-endpoint\n\n          Setting this flag also requires the setting of --enable-private-nodes, --enable-ip-alias\n          and --master-ipv4-cidr=<master_cidr_range>.\n        scored: false\n\n      - id: 5.6.5\n        text: \"Ensure clusters are created with Private Nodes (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n          To create a cluster with Private Nodes enabled, include the --enable-private-nodes\n          flag within the cluster create command:\n\n            gcloud container clusters create <cluster_name> --enable-private-nodes\n\n          Setting this flag also requires the setting of --enable-ip-alias and\n          --master-ipv4-cidr=<master_cidr_range>.\n        scored: false\n\n      - id: 5.6.6\n        text: \"Consider firewalling GKE worker nodes (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n          Use the following command to generate firewall rules, setting the variables as\n          appropriate:\n\n            gcloud compute firewall-rules create <firewall_rule_name> \\\n            --network <network> --priority <priority> --direction <direction> \\\n            --action <action> --target-tags <tag> \\\n            --target-service-accounts <service_account> \\\n            --source-ranges <source_cidr_range> --source-tags <source_tags> \\\n            --source-service-accounts <source_service_account> \\\n            --destination-ranges <destination_cidr_range> --rules <rules>\n        scored: false\n\n      - id: 5.6.7\n        text: \"Ensure use of Google-managed SSL Certificates (Automated)\"\n        type: \"manual\"\n        remediation: |\n          If services of type:LoadBalancer are discovered, consider replacing the Service with\n          an Ingress.\n\n          To configure the Ingress and use Google-managed SSL certificates, follow the\n          instructions as listed at: https://cloud.google.com/kubernetes-engine/docs/how-\n          to/managed-certs.\n        scored: false\n\n  - id: 5.7\n    text: \"Logging\"\n    checks:\n      - id: 5.7.1\n        text: \"Ensure Logging and Cloud Monitoring is Enabled (Automated)\"\n        type: \"manual\"\n        remediation: |\n          To enable Logging for an existing cluster, run the following command:\n            gcloud container clusters update <cluster_name> --zone <compute_zone> \\\n            --logging=<components_to_be_logged>\n\n          See https://cloud.google.com/sdk/gcloud/reference/container/clusters/update#--logging\n          for a list of available components for logging.\n\n          To enable Cloud Monitoring for an existing cluster, run the following command:\n            gcloud container clusters update <cluster_name> --zone <compute_zone> \\\n            --monitoring=<components_to_be_logged>\n\n          See https://cloud.google.com/sdk/gcloud/reference/container/clusters/update#--\n          monitoring for a list of available components for Cloud Monitoring.\n        scored: false\n\n      - id: 5.7.2\n        text: \"Enable Linux auditd logging (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n          Download the example manifests:\n            curl https://raw.githubusercontent.com/GoogleCloudPlatform/k8s-node-tools/master/os-audit/cos-auditd-logging.yaml > cos-auditd-logging.yaml\n\n          Edit the example manifests if needed. Then, deploy them:\n            kubectl apply -f cos-auditd-logging.yaml\n\n          Verify that the logging Pods have started. If a different Namespace was defined in the\n          manifests, replace cos-auditd with the name of the namespace being used:\n            kubectl get pods --namespace=cos-auditd\n        scored: false\n\n  - id: 5.8\n    text: \"Authentication and Authorization\"\n    checks:\n      - id: 5.8.1\n        text: \"Ensure authentication using Client Certificates is Disabled (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n          Create a new cluster without a Client Certificate:\n            gcloud container clusters create [CLUSTER_NAME] \\\n              --no-issue-client-certificate\n        scored: false\n\n      - id: 5.8.2\n        text: \"Manage Kubernetes RBAC users with Google Groups for GKE (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n          Follow the G Suite Groups instructions at: https://cloud.google.com/kubernetes-\n          engine/docs/how-to/role-based-access-control#google-groups-for-gke.\n\n          Then, create a cluster with:\n            gcloud container clusters create <cluster_name> --security-group <security_group_name>\n\n          Finally create Roles, ClusterRoles, RoleBindings, and ClusterRoleBindings that\n          reference the G Suite Groups.\n        scored: false\n\n      - id: 5.8.3\n        text: \"Ensure Legacy Authorization (ABAC) is Disabled (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n          To disable Legacy Authorization for an existing cluster, run the following command:\n            gcloud container clusters update <cluster_name> --zone <compute_zone> \\\n              --no-enable-legacy-authorization\n        scored: false\n\n  - id: 5.9\n    text: \"Storage\"\n    checks:\n      - id: 5.9.1\n        text: \"Enable Customer-Managed Encryption Keys (CMEK) for GKE Persistent Disks (PD) (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n          Follow the instructions detailed at: https://cloud.google.com/kubernetes-engine/docs/how-to/using-cmek.\n        scored: false\n\n      - id: 5.9.2\n        text: \"Enable Customer-Managed Encryption Keys (CMEK) for Boot Disks (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n          Create a new node pool using customer-managed encryption keys for the node boot\n          disk, of <disk_type> either pd-standard or pd-ssd:\n            gcloud container node-pools create <cluster_name> --disk-type <disk_type> \\\n            --boot-disk-kms-key projects/<key_project_id>/locations/<location>/keyRings/<ring_name>/cryptoKeys/<key_name>\n\n          Create a cluster using customer-managed encryption keys for the node boot disk, of\n          <disk_type> either pd-standard or pd-ssd:\n            gcloud container clusters create <cluster_name> --disk-type <disk_type> \\\n            --boot-disk-kms-key projects/<key_project_id>/locations/<location>/keyRings/<ring_name>/cryptoKeys/<key_name>\n        scored: false\n\n  - id: 5.10\n    text: \"Other Cluster Configurations\"\n    checks:\n      - id: 5.10.1\n        text: \"Ensure Kubernetes Web UI is Disabled (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n          To disable the Kubernetes Dashboard on an existing cluster, run the following\n          command:\n            gcloud container clusters update <cluster_name> --zone <zone> \\\n              --update-addons=KubernetesDashboard=DISABLED\n        scored: false\n\n      - id: 5.10.2\n        text: \"Ensure that Alpha clusters are not used for production workloads (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n          Upon creating a new cluster\n            gcloud container clusters create [CLUSTER_NAME] \\\n              --zone [COMPUTE_ZONE]\n\n          Do not use the --enable-kubernetes-alpha argument.\n        scored: false\n\n      - id: 5.10.3\n        text: \"Consider GKE Sandbox for running untrusted workloads (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n          To enable GKE Sandbox on an existing cluster, a new Node pool must be created,\n          which can be done using:\n            gcloud container node-pools create <node_pool_name> --zone <compute-zone> \\\n              --cluster <cluster_name> --image-type=cos_containerd --sandbox=\"type=gvisor\"\n        scored: false\n\n      - id: 5.10.4\n        text: \"Ensure use of Binary Authorization (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n          Update the cluster to enable Binary Authorization:\n            gcloud container cluster update <cluster_name> --zone <compute_zone> \\\n            --binauthz-evaluation-mode=<evaluation_mode>\n\n          Example:\n            gcloud container clusters update $CLUSTER_NAME --zone $COMPUTE_ZONE \\\n            --binauthz-evaluation-mode=PROJECT_SINGLETON_POLICY_ENFORCE\n\n          See: https://cloud.google.com/sdk/gcloud/reference/container/clusters/update#--binauthz-evaluation-mode\n          for more details around the evaluation modes available.\n\n          Create a Binary Authorization Policy using the Binary Authorization Policy Reference:\n          https://cloud.google.com/binary-authorization/docs/policy-yaml-reference for guidance.\n\n          Import the policy file into Binary Authorization:\n            gcloud container binauthz policy import <yaml_policy>\n        scored: false\n\n      - id: 5.10.5\n        text: \"Enable Security Posture (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Enable security posture via the UI, gCloud or API.\n          https://cloud.google.com/kubernetes-engine/docs/how-to/protect-workload-configuration\n        scored: false\n"
  },
  {
    "path": "cfg/gke-1.6.0/master.yaml",
    "content": "---\ncontrols:\nversion: \"gke-1.6.0\"\nid: 1\ntext: \"Control Plane Components\"\ntype: \"master\"\n"
  },
  {
    "path": "cfg/gke-1.6.0/node.yaml",
    "content": "---\ncontrols:\nversion: \"gke-1.6.0\"\nid: 3\ntext: \"Worker Node Security Configuration\"\ntype: \"node\"\ngroups:\n  - id: 3.1\n    text: \"Worker Node Configuration Files\"\n    checks:\n      - id: 3.1.1\n        text: \"Ensure that the proxy kubeconfig file permissions are set to 644 or more restrictive (Manual)\"\n        audit: '/bin/sh -c ''if test -e $proxykubeconfig; then stat -c permissions=%a $proxykubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on each worker node.\n          For example,\n\n            chmod 644 $proxykubeconfig\n        scored: true\n\n      - id: 3.1.2\n        text: \"Ensure that the proxy kubeconfig file ownership is set to root:root (Manual)\"\n        audit: '/bin/sh -c ''if test -e $proxykubeconfig; then stat -c %U:%G $proxykubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the below command (based on the file location on your system) on each worker node.\n          For example:\n\n            chown root:root $proxykubeconfig\n        scored: true\n\n      - id: 3.1.3\n        text: \"Ensure that the kubelet configuration file has permissions set to 600 (Manual)\"\n        audit: '/bin/sh -c ''if test -e /home/kubernetes/kubelet-config.yaml; then stat -c permissions=%a /home/kubernetes/kubelet-config.yaml; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the following command (using the kubelet config file location)\n\n            chmod 644 /home/kubernetes/kubelet-config.yaml\n        scored: true\n\n      - id: 3.1.4\n        text: \"Ensure that the kubelet configuration file ownership is set to root:root (Manual)\"\n        audit: '/bin/sh -c ''if test -e /home/kubernetes/kubelet-config.yaml; then stat -c %U:%G /home/kubernetes/kubelet-config.yaml; fi'' '\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the following command (using the config file location identied in the Audit step)\n\n            chown root:root /home/kubernetes/kubelet-config.yaml\n        scored: true\n\n  - id: 3.2\n    text: \"Kubelet\"\n    checks:\n      - id: 3.2.1\n        text: \"Ensure that the Anonymous Auth is Not Enabled (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat /home/kubernetes/kubelet-config.yaml\"\n        tests:\n          test_items:\n            - flag: \"--anonymous-auth\"\n              path: '{.authentication.anonymous.enabled}'\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Remediation Method 1:\n          If configuring via the Kubelet config file, you first need to locate the file.\n          To do this, SSH to each node and execute the following command to find the kubelet\n          process:\n\n            ps -ef | grep kubelet\n\n          The output of the above command provides details of the active kubelet process, from\n          which we can see the location of the configuration file provided to the kubelet service\n          with the --config argument. The file can be viewed with a command such as more or\n          less, like so:\n\n            sudo less /home/kubernetes/kubelet-config.yaml\n\n          Disable Anonymous Authentication by setting the following parameter:\n\n            \"authentication\": { \"anonymous\": { \"enabled\": false } }\n\n          Remediation Method 2:\n          If using executable arguments, edit the kubelet service file on each worker node and\n          ensure the below parameters are part of the KUBELET_ARGS variable string.\n\n          For systems using systemd, such as the Amazon EKS Optimised Amazon Linux or\n          Bottlerocket AMIs, then this file can be found at\n          /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf. Otherwise,\n          you may need to look up documentation for your chosen operating system to determine\n          which service manager is configured:\n\n            --anonymous-auth=false\n\n          For Both Remediation Steps:\n          Based on your system, restart the kubelet service and check the service status.\n          The following example is for operating systems using systemd, such as the Amazon\n          EKS Optimised Amazon Linux or Bottlerocket AMIs, and invokes the systemctl\n          command. If systemctl is not available then you will need to look up documentation for\n          your chosen operating system to determine which service manager is configured:\n            systemctl daemon-reload\n            systemctl restart kubelet.service\n            systemctl status kubelet -l\n        scored: true\n\n      - id: 3.2.2\n        text: \"Ensure that the --authorization-mode argument is not set to AlwaysAllow (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat /home/kubernetes/kubelet-config.yaml\"\n        tests:\n          test_items:\n            - flag: --authorization-mode\n              path: '{.authorization.mode}'\n              compare:\n                op: nothave\n                value: AlwaysAllow\n        remediation: |\n          Remediation Method 1:\n          If configuring via the Kubelet config file, you first need to locate the file.\n          To do this, SSH to each node and execute the following command to find the kubelet\n          process:\n\n            ps -ef | grep kubelet\n\n          The output of the above command provides details of the active kubelet process, from\n          which we can see the location of the configuration file provided to the kubelet service\n          with the --config argument. The file can be viewed with a command such as more or\n          less, like so:\n\n            sudo less /path/to/kubelet-config.json\n\n          Enable Webhook Authentication by setting the following parameter:\n\n            \"authentication\": { \"webhook\": { \"enabled\": true } }\n\n          Next, set the Authorization Mode to Webhook by setting the following parameter:\n\n            \"authorization\": { \"mode\": \"Webhook }\n\n          Finer detail of the authentication and authorization fields can be found in the\n          Kubelet Configuration documentation (https://kubernetes.io/docs/reference/config-api/kubelet-config.v1beta1/).\n\n          Remediation Method 2:\n          If using executable arguments, edit the kubelet service file on each worker node and\n          ensure the below parameters are part of the KUBELET_ARGS variable string.\n          For systems using systemd, such as the Amazon EKS Optimised Amazon Linux or\n          Bottlerocket AMIs, then this file can be found at\n          /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf. Otherwise,\n          you may need to look up documentation for your chosen operating system to determine\n          which service manager is configured:\n\n              --authentication-token-webhook\n              --authorization-mode=Webhook\n\n          For Both Remediation Steps:\n          Based on your system, restart the kubelet service and check the service status.\n          The following example is for operating systems using systemd, such as the Amazon\n          EKS Optimised Amazon Linux or Bottlerocket AMIs, and invokes the systemctl\n          command. If systemctl is not available then you will need to look up documentation for\n          your chosen operating system to determine which service manager is configured:\n\n            systemctl daemon-reload\n            systemctl restart kubelet.service\n            systemctl status kubelet -l\n        scored: true\n\n      - id: 3.2.3\n        text: \"Ensure that a Client CA File is Configured (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat /home/kubernetes/kubelet-config.yaml\"\n        tests:\n          test_items:\n            - flag: --client-ca-file\n              path: '{.authentication.x509.clientCAFile}'\n              set: true\n        remediation: |\n          Remediation Method 1:\n          If configuring via the Kubelet config file, you first need to locate the file.\n          To do this, SSH to each node and execute the following command to find the kubelet\n          process:\n\n            ps -ef | grep kubelet\n\n          The output of the above command provides details of the active kubelet process, from\n          which we can see the location of the configuration file provided to the kubelet service\n          with the --config argument. The file can be viewed with a command such as more or\n          less, like so:\n\n            sudo less /path/to/kubelet-config.json\n\n          Configure the client certificate authority file by setting the following parameter\n          appropriately:\n\n            \"authentication\": { \"x509\": {\"clientCAFile\": <path/to/client-ca-file> } }\"\n\n          Remediation Method 2:\n          If using executable arguments, edit the kubelet service file on each worker node and\n          ensure the below parameters are part of the KUBELET_ARGS variable string.\n          For systems using systemd, such as the Amazon EKS Optimised Amazon Linux or\n          Bottlerocket AMIs, then this file can be found at\n          /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf. Otherwise,\n          you may need to look up documentation for your chosen operating system to determine\n          which service manager is configured:\n\n            --client-ca-file=<path/to/client-ca-file>\n\n          For Both Remediation Steps:\n          Based on your system, restart the kubelet service and check the service status.\n          The following example is for operating systems using systemd, such as the Amazon\n          EKS Optimised Amazon Linux or Bottlerocket AMIs, and invokes the systemctl\n          command. If systemctl is not available then you will need to look up documentation for\n          your chosen operating system to determine which service manager is configured:\n\n            systemctl daemon-reload\n            systemctl restart kubelet.service\n            systemctl status kubelet -l\n        scored: true\n\n      - id: 3.2.4\n        text: \"Ensure that the --read-only-port argument is disabled (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat /home/kubernetes/kubelet-config.yaml\"\n        tests:\n          test_items:\n            - flag: \"--read-only-port\"\n              path: '{.readOnlyPort}'\n              set: false\n            - flag: \"--read-only-port\"\n              path: '{.readOnlyPort}'\n              compare:\n                op: eq\n                value: 0\n          bin_op: or\n        remediation: |\n          If modifying the Kubelet config file, edit the kubelet-config.json file\n          /etc/kubernetes/kubelet/kubelet-config.json and set the below parameter to 0\n\n            \"readOnlyPort\": 0\n\n          If using executable arguments, edit the kubelet service file\n          /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf on each\n          worker node and add the below parameter at the end of the KUBELET_ARGS variable\n          string.\n\n            --read-only-port=0\n\n          For each remediation:\n          Based on your system, restart the kubelet service and check status\n\n            systemctl daemon-reload\n            systemctl restart kubelet.service\n            systemctl status kubelet -l\n        scored: true\n\n      - id: 3.2.5\n        text: \"Ensure that the --streaming-connection-idle-timeout argument is not set to 0 (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat /home/kubernetes/kubelet-config.yaml\"\n        tests:\n          test_items:\n            - flag: --streaming-connection-idle-timeout\n              path: '{.streamingConnectionIdleTimeout}'\n              compare:\n                op: noteq\n                value: 0\n            - flag: --streaming-connection-idle-timeout\n              path: '{.streamingConnectionIdleTimeout}'\n              set: false\n          bin_op: or\n        remediation: |\n          Remediation Method 1:\n          If modifying the Kubelet config file, edit the kubelet-config.json file\n          /etc/kubernetes/kubelet-config.yaml and set the below parameter to a non-zero\n          value in the format of #h#m#s\n\n            \"streamingConnectionIdleTimeout\": \"4h0m0s\"\n\n          You should ensure that the kubelet service file\n          /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf does not\n          specify a --streaming-connection-idle-timeout argument because it would\n          override the Kubelet config file.\n\n          Remediation Method 2:\n          If using executable arguments, edit the kubelet service file\n          /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf on each\n          worker node and add the below parameter at the end of the KUBELET_ARGS variable\n          string.\n\n            --streaming-connection-idle-timeout=4h0m0s\n\n          Remediation Method 3:\n          If using the api configz endpoint consider searching for the status of\n          \"streamingConnectionIdleTimeout\": by extracting the live configuration from the\n          nodes running kubelet.\n          **See detailed step-by-step configmap procedures in Reconfigure a Node's Kubelet in a\n          Live Cluster (https://kubernetes.io/docs/tasks/administer-cluster/reconfigure-kubelet/),\n          and then rerun the curl statement from audit process to check for kubelet\n          configuration changes\n\n            kubectl proxy --port=8001 &\n            export HOSTNAME_PORT=localhost:8001 (example host and port number)\n            export NODE_NAME=gke-cluster-1-pool1-5e572947-r2hg (example node name from\n            \"kubectl get nodes\")\n            curl -sSL \"http://${HOSTNAME_PORT}/api/v1/nodes/${NODE_NAME}/proxy/configz\"\n\n          For all three remediations:\n          Based on your system, restart the kubelet service and check status\n\n            systemctl daemon-reload\n            systemctl restart kubelet.service\n            systemctl status kubelet -l\n        scored: true\n\n      - id: 3.2.6\n        text: \"Ensure that the --make-iptables-util-chains argument is set to true (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat /home/kubernetes/kubelet-config.yaml\"\n        tests:\n          test_items:\n            - flag: --make-iptables-util-chains\n              path: '{.makeIPTablesUtilChains}'\n              compare:\n                op: eq\n                value: true\n            - flag: --make-iptables-utils-chains\n              path: '{.makeIPTablesUtilChains}'\n              set: false\n          bin_op: or\n        remediation: |\n          Remediation Method 1:\n          If modifying the Kubelet config file, edit the kubelet-config.json file\n          /etc/kubernetes/kubelet/kubelet-config.json and set the below parameter to\n          true\n\n            \"makeIPTablesUtilChains\": true\n\n          Ensure that /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf\n          does not set the --make-iptables-util-chains argument because that would\n          override your Kubelet config file.\n\n          Remediation Method 2:\n          If using executable arguments, edit the kubelet service file\n          /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf on each\n          worker node and add the below parameter at the end of the KUBELET_ARGS variable\n          string.\n\n            --make-iptables-util-chains:true\n\n          Remediation Method 3:\n          If using the api configz endpoint consider searching for the status of\n          \"makeIPTablesUtilChains.: true by extracting the live configuration from the nodes\n          running kubelet.\n\n          **See detailed step-by-step configmap procedures in Reconfigure a Node's Kubelet in a\n          Live Cluster (https://kubernetes.io/docs/tasks/administer-cluster/reconfigure-kubelet/),\n          and then rerun the curl statement from audit process to check for kubelet\n          configuration changes\n\n            kubectl proxy --port=8001 &\n            export HOSTNAME_PORT=localhost:8001 (example host and port number)\n            export NODE_NAME=gke-cluster-1-pool1-5e572947-r2hg (example node name from\n            \"kubectl get nodes\")\n            curl -sSL \"http://${HOSTNAME_PORT}/api/v1/nodes/${NODE_NAME}/proxy/configz\"\n\n          For all three remediations:\n          Based on your system, restart the kubelet service and check status\n\n            systemctl daemon-reload\n            systemctl restart kubelet.service\n            systemctl status kubelet -l\n        scored: true\n\n      - id: 3.2.7\n        text: \"Ensure that the --eventRecordQPS argument is set to 0 or a level which ensures appropriate event capture (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat /etc/systemd/system/kubelet.service.d/10-kubeadm.conf\"\n        tests:\n          test_items:\n            - flag: --event-qps\n              path: '{.eventRecordQPS}'\n              set: true\n              compare:\n                op: eq\n                value: 0\n        remediation: |\n          If using a Kubelet config file, edit the file to set eventRecordQPS: to an appropriate level.\n\n          If using command line arguments, edit the kubelet service file /etc/systemd/system/kubelet.service.d/10-kubeadm.conf\n          on each worker node and set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n\n          Based on your system, restart the kubelet service. For example:\n\n            systemctl daemon-reload\n            systemctl restart kubelet.service\n        scored: true\n\n      - id: 3.2.8\n        text: \"Ensure that the --rotate-certificates argument is not present or is set to true (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat /home/kubernetes/kubelet-config.yaml\"\n        tests:\n          test_items:\n            - flag: --rotate-certificates\n              path: '{.rotateCertificates}'\n              compare:\n                op: eq\n                value: true\n            - flag: --rotate-certificates\n              path: '{.rotateCertificates}'\n              set: false\n          bin_op: or\n        remediation: |\n          Remediation Method 1:\n          If modifying the Kubelet config file, edit the kubelet-config.yaml file\n          /etc/kubernetes/kubelet/kubelet-config.yaml and set the below parameter to\n          true\n\n            \"RotateCertificate\":true\n\n          Additionally, ensure that the kubelet service file\n          /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf does not set the --RotateCertificate\n          executable argument to false because this would override the Kubelet\n          config file.\n\n          Remediation Method 2:\n          If using executable arguments, edit the kubelet service file\n          /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf on each\n          worker node and add the below parameter at the end of the KUBELET_ARGS variable\n          string.\n\n            --RotateCertificate=true\n        scored: true\n\n      - id: 3.2.9\n        text: \"Ensure that the RotateKubeletServerCertificate argument is set to true (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat /home/kubernetes/kubelet-config.yaml\"\n        tests:\n          test_items:\n            - flag: RotateKubeletServerCertificate\n              path: '{.featureGates.RotateKubeletServerCertificate}'\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Remediation Method 1:\n          If modifying the Kubelet config file, edit the kubelet-config.json file\n          /etc/kubernetes/kubelet-config.yaml and set the below parameter to true\n\n            \"featureGates\": {\n            \"RotateKubeletServerCertificate\":true\n            },\n\n          Additionally, ensure that the kubelet service file\n          /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf does not set\n          the --rotate-kubelet-server-certificate executable argument to false because\n          this would override the Kubelet config file.\n\n          Remediation Method 2:\n          If using executable arguments, edit the kubelet service file\n          /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf on each\n          worker node and add the below parameter at the end of the KUBELET_ARGS variable\n          string.\n\n            --rotate-kubelet-server-certificate=true\n\n          Remediation Method 3:\n          If using the api configz endpoint consider searching for the status of\n          \"RotateKubeletServerCertificate\": by extracting the live configuration from the\n          nodes running kubelet.\n          **See detailed step-by-step configmap procedures in Reconfigure a Node's Kubelet in a\n          Live Cluster (https://kubernetes.io/docs/tasks/administer-cluster/reconfigure-kubelet/),\n          and then rerun the curl statement from audit process to check for kubelet\n          configuration changes\n\n            kubectl proxy --port=8001 &\n            export HOSTNAME_PORT=localhost:8001 (example host and port number)\n            export NODE_NAME=gke-cluster-1-pool1-5e572947-r2hg (example node name from\n            \"kubectl get nodes\")\n            curl -sSL \"http://${HOSTNAME_PORT}/api/v1/nodes/${NODE_NAME}/proxy/configz\"\n\n          For all three remediation methods:\n          Restart the kubelet service and check status. The example below is for when using\n          systemctl to manage services:\n\n            systemctl daemon-reload\n            systemctl restart kubelet.service\n            systemctl status kubelet -l\n        scored: true\n"
  },
  {
    "path": "cfg/gke-1.6.0/policies.yaml",
    "content": "---\ncontrols:\nversion: \"gke-1.6.0\"\nid: 4\ntext: \"Kubernetes Policies\"\ntype: \"policies\"\ngroups:\n  - id: 4.1\n    text: \"RBAC and Service Accounts\"\n    checks:\n      - id: 4.1.1\n        text: \"Ensure that the cluster-admin role is only used where required (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Identify all clusterrolebindings to the cluster-admin role. Check if they are used and\n          if they need this role or if they could use a role with fewer privileges.\n\n          Where possible, first bind users to a lower privileged role and then remove the\n          clusterrolebinding to the cluster-admin role :\n\n            kubectl delete clusterrolebinding [name]\n        scored: false\n\n      - id: 4.1.2\n        text: \"Minimize access to secrets (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove get, list and watch access to secret objects in the cluster.\n        scored: false\n\n      - id: 4.1.3\n        text: \"Minimize wildcard use in Roles and ClusterRoles (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Where possible replace any use of wildcards in clusterroles and roles with specific\n          objects or actions.\n        scored: false\n\n      - id: 4.1.4\n        text: \"Ensure that default service accounts are not actively used (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Create explicit service accounts wherever a Kubernetes workload requires specific\n          access to the Kubernetes API server.\n\n          Modify the configuration of each default service account to include this value\n\n            automountServiceAccountToken: false\n        scored: false\n\n      - id: 4.1.5\n        text: \"Ensure that Service Account Tokens are only mounted where necessary (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Modify the definition of pods and service accounts which do not need to mount service\n          account tokens to disable it.\n        scored: false\n\n      - id: 4.1.6\n        text: \"Avoid use of system:masters group (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Remove the system:masters group from all users in the cluster.\n        scored: false\n\n      - id: 4.1.7\n        text: \"Limit use of the Bind, Impersonate and Escalate permissions in the Kubernetes cluster (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove the impersonate, bind and escalate rights from subjects.\n        scored: false\n\n      - id: 4.1.8\n        text: \"Avoid bindings to system:anonymous (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Identify all clusterrolebindings and rolebindings to the user system:anonymous.\n          Check if they are used and review the permissions associated with the binding using the\n          commands in the Audit section above or refer to GKE documentation\n          (https://cloud.google.com/kubernetes-engine/docs/best-practices/rbac#detect-prevent-default).\n\n          Strongly consider replacing unsafe bindings with an authenticated, user-defined group.\n          Where possible, bind to non-default, user-defined groups with least-privilege roles.\n\n          If there are any unsafe bindings to the user system:anonymous, proceed to delete them\n          after consideration for cluster operations with only necessary, safer bindings.\n\n            kubectl delete clusterrolebinding [CLUSTER_ROLE_BINDING_NAME]\n            kubectl delete rolebinding [ROLE_BINDING_NAME] --namespace [ROLE_BINDING_NAMESPACE]\n        scored: false\n\n      - id: 4.1.9\n        text: \"Avoid non-default bindings to system:unauthenticated (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Identify all non-default clusterrolebindings and rolebindings to the group\n          system:unauthenticated. Check if they are used and review the permissions\n          associated with the binding using the commands in the Audit section above or refer to\n          GKE documentation (https://cloud.google.com/kubernetes-engine/docs/best-practices/rbac#detect-prevent-default).\n\n          Strongly consider replacing non-default, unsafe bindings with an authenticated, user-\n          defined group. Where possible, bind to non-default, user-defined groups with least-\n          privilege roles.\n\n          If there are any non-default, unsafe bindings to the group system:unauthenticated,\n          proceed to delete them after consideration for cluster operations with only necessary,\n          safer bindings.\n\n            kubectl delete clusterrolebinding [CLUSTER_ROLE_BINDING_NAME]\n            kubectl delete rolebinding [ROLE_BINDING_NAME] --namespace [ROLE_BINDING_NAMESPACE]\n        scored: false\n\n      - id: 4.1.10\n        text: \"Avoid non-default bindings to system:authenticated (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Identify all non-default clusterrolebindings and rolebindings to the group\n          system:authenticated. Check if they are used and review the permissions associated\n          with the binding using the commands in the Audit section above or refer to GKE\n          documentation.\n\n          Strongly consider replacing non-default, unsafe bindings with an authenticated, user-\n          defined group. Where possible, bind to non-default, user-defined groups with least-\n          privilege roles.\n\n          If there are any non-default, unsafe bindings to the group system:authenticated,\n          proceed to delete them after consideration for cluster operations with only necessary,\n          safer bindings.\n\n            kubectl delete clusterrolebinding [CLUSTER_ROLE_BINDING_NAME]\n            kubectl delete rolebinding [ROLE_BINDING_NAME] --namespace [ROLE_BINDING_NAMESPACE]\n        scored: false\n\n  - id: 4.2\n    text: \"Pod Security Standards\"\n    checks:\n      - id: 4.2.1\n        text: \"Ensure that the cluster enforces Pod Security Standard Baseline profile or stricter for all namespaces. (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that Pod Security Admission is in place for every namespace which contains\n          user workloads.\n          Run the following command to enforce the Baseline profile in a namespace:\n\n            kubectl label namespace pod-security.kubernetes.io/enforce=baseline\n        scored: false\n\n  - id: 4.3\n    text: \"Network Policies and CNI\"\n    checks:\n      - id: 4.3.1\n        text: \"Ensure that the CNI in use supports Network Policies (Manual)\"\n        type: \"manual\"\n        remediation: |\n          To use a CNI plugin with Network Policy, enable Network Policy in GKE, and the CNI plugin\n          will be updated. See Recommendation 5.6.7.\n        scored: false\n\n      - id: 4.3.2\n        text: \"Ensure that all Namespaces have Network Policies defined (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Follow the documentation and create NetworkPolicy objects as needed.\n          See: https://cloud.google.com/kubernetes-engine/docs/how-to/network-policy#creating_a_network_policy\n          for more information.\n        scored: false\n\n  - id: 4.4\n    text: \"Secrets Management\"\n    checks:\n      - id: 4.4.1\n        text: \"Prefer using secrets as files over secrets as environment variables (Automated)\"\n        type: \"manual\"\n        remediation: |\n          if possible, rewrite application code to read secrets from mounted secret files, rather than\n          from environment variables.\n        scored: false\n\n      - id: 4.4.2\n        text: \"Consider external secret storage (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Refer to the secrets management options offered by your cloud provider or a third-party\n          secrets management solution.\n        scored: false\n\n  - id: 4.5\n    text: \"Extensible Admission Control\"\n    checks:\n      - id: 4.5.1\n        text: \"Configure Image Provenance using ImagePolicyWebhook admission controller (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and setup image provenance.\n          Also see recommendation 5.10.4.\n        scored: false\n\n  - id: 4.6\n    text: \"General Policies\"\n    checks:\n      - id: 4.6.1\n        text: \"Create administrative boundaries between resources using namespaces (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the documentation and create namespaces for objects in your deployment as you need\n          them.\n        scored: false\n\n      - id: 4.6.2\n        text: \"Ensure that the seccomp profile is set to RuntimeDefault in your pod definitions (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Use security context to enable the RuntimeDefault seccomp profile in your pod\n          definitions. An example is as below:\n\n            {\n              \"namespace\": \"kube-system\",\n              \"name\": \"metrics-server-v0.7.0-dbcc8ddf6-gz7d4\",\n              \"seccompProfile\": \"RuntimeDefault\"\n            }\n        scored: false\n\n      - id: 4.6.3\n        text: \"Apply Security Context to Your Pods and Containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and apply security contexts to your pods. For a\n          suggested list of security contexts, you may refer to the CIS Google Container-\n          Optimized OS Benchmark.\n        scored: false\n\n      - id: 4.6.4\n        text: \"The default namespace should not be used (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that namespaces are created to allow for appropriate segregation of Kubernetes\n          resources and that all new resources are created in a specific namespace.\n        scored: false\n"
  },
  {
    "path": "cfg/gke-1.8.0/config.yaml",
    "content": "---\n## Version-specific settings that override the values in cfg/config.yaml\n\nnode:\n  proxy:\n    defaultkubeconfig: \"/var/lib/kubelet/kubeconfig\"\n\n  kubelet:\n    defaultconf: \"/etc/kubernetes/kubelet-config.yaml\"\n"
  },
  {
    "path": "cfg/gke-1.8.0/controlplane.yaml",
    "content": "---\ncontrols:\nversion: \"gke-1.8.0\"\nid: 2\ntext: \"Control Plane Configuration\"\ntype: \"controlplane\"\n"
  },
  {
    "path": "cfg/gke-1.8.0/managedservices.yaml",
    "content": "---\ncontrols:\nversion: \"gke-1.8.0\"\nid: 5\ntext: \"Managed Services\"\ntype: \"managedservices\"\ngroups:\n  - id: 5.1\n    text: \"Image Registry and Image Scanning\"\n    checks:\n      - id: 5.1.1\n        text: \"Ensure Image Vulnerability Scanning is enabled (Automated)\"\n        audit: \"gcloud services list --enabled\"\n        type: \"manual\"\n        remediation: |\n          For Images Hosted in GCR:\n          Using Google Cloud Console\n          Go to GCR by visiting: https://console.cloud.google.com/gcr\n          Select Settings and, under the Vulnerability Scanning heading, click the TURN ON button.\n          Using Command Line\n          gcloud services enable containeranalysis.googleapis.com\n          For Images Hosted in AR:\n          Using Google Cloud Console\n          Go to GCR by visiting: https://console.cloud.google.com/artifacts\n          Select Settings and, under the Vulnerability Scanning heading, click the ENABLE button.\n          Using Command Line\n          gcloud services enable containerscanning.googleapis.com\n        scored: false\n\n      - id: 5.1.2\n        text: \"Minimize user access to Container Image repositories (Manual)\"\n        audit: |\n          gcloud projects get-iam-policy <project_id> \\\n          --flatten=\"bindings[].members\" \\\n          --format='table(bindings.members,bindings.role)' \\\n          --filter=\"bindings.role:roles/storage.admin OR bindings.role:roles/storage.objectAdmin OR bindings.role:roles/storage.objectCreator OR bindings.role:roles/storage.legacyBucketOwner OR bindings.role:roles/storage.legacyBucketWriter OR bindings.role:roles/storage.legacyObjectOwner\"\n        type: \"manual\"\n        remediation: |\n          For Images Hosted in AR:\n          Using Command Line:\n\n            gcloud artifacts repositories set-iam-policy <repository-name> <path-to-policy-file> \\\n              --location <repository-location>\n\n          To learn how to configure policy files see: https://cloud.google.com/artifact-registry/docs/access-control#grant\n\n          For Images Hosted in GCR:\n          Using Command Line:\n          To change roles at the GCR bucket level:\n          Firstly, run the following if read permissions are required:\n\n            gsutil iam ch <type>:<email_address>:objectViewer gs://artifacts.<project_id>.appspot.com\n\n          Then remove the excessively privileged role (Storage Admin / Storage Object\n          Admin / Storage Object Creator) using:\n\n            gsutil iam ch -d <type>:<email_address>:<role> gs://artifacts.<project_id>.appspot.com\n\n          where:\n          <type> can be one of the following:\n            user, if the <email_address> is a Google account.\n            serviceAccount, if <email_address> specifies a Service account.\n            <email_address> can be one of the following:\n              a Google account (for example, someone@example.com).\n              a Cloud IAM service account.\n\n          To modify roles defined at the project level and subsequently inherited within the GCR\n          bucket, or the Service Account User role, extract the IAM policy file, modify it\n          accordingly and apply it using:\n\n            gcloud projects set-iam-policy <project_id> <policy_file>\n        scored: false\n\n      - id: 5.1.3\n        text: \"Minimize cluster access to read-only for Container Image repositories (Manual)\"\n        audit: |\n          gcloud projects get-iam-policy <project_id> \\\n          --flatten=\"bindings[].members\" \\\n          --format='table(bindings.members,bindings.role)' \\\n          --filter=\"bindings.role:roles/storage.admin OR bindings.role:roles/storage.objectAdmin OR bindings.role:roles/storage.objectCreator OR bindings.role:roles/storage.legacyBucketOwner OR bindings.role:roles/storage.legacyBucketWriter OR bindings.role:roles/storage.legacyObjectOwner\"\n        type: \"manual\"\n        remediation: |\n          For Images Hosted in AR:\n          Using Command Line:\n          Add artifactregistry.reader role\n\n            gcloud artifacts repositories add-iam-policy-binding <repository> \\\n            --location=<repository-location> \\\n            --member='serviceAccount:<email-address>' \\\n            --role='roles/artifactregistry.reader'\n\n          Remove any roles other than artifactregistry.reader\n\n            gcloud artifacts repositories remove-iam-policy-binding <repository> \\\n            --location <repository-location> \\\n            --member='serviceAccount:<email-address>' \\\n            --role='<role-name>'\n\n          For Images Hosted in GCR:\n          For an account explicitly granted to the bucket:\n          Firstly add read access to the Kubernetes Service Account:\n\n            gsutil iam ch <type>:<email_address>:objectViewer gs://artifacts.<project_id>.appspot.com\n\n            where:\n              <type> can be one of the following:\n                user, if the <email_address> is a Google account.\n                serviceAccount, if <email_address> specifies a Service account.\n                <email_address> can be one of the following:\n                  a Google account (for example, someone@example.com).\n                  a Cloud IAM service account.\n\n          Then remove the excessively privileged role (Storage Admin / Storage Object\n          Admin / Storage Object Creator) using:\n\n            gsutil iam ch -d <type>:<email_address>:<role> gs://artifacts.<project_id>.appspot.com\n\n          For an account that inherits access to the GCR Bucket through Project level\n          permissions, modify the Projects IAM policy file accordingly, then upload it using:\n\n            gcloud projects set-iam-policy <project_id> <policy_file>\n        scored: false\n\n      - id: 5.1.4\n        text: \"Ensure only trusted container images are used (Manual)\"\n        audit: |\n          gcloud container clusters describe $CLUSTER_NAME --zone $COMPUTE_ZONE --format json | jq .binaryAuthorization\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n          Update the cluster to enable Binary Authorization:\n\n            gcloud container cluster update <cluster_name> --enable-binauthz\n\n          Create a Binary Authorization Policy using the Binary Authorization Policy Reference:\n          https://cloud.google.com/binary-authorization/docs/policy-yaml-reference for guidance.\n\n          Import the policy file into Binary Authorization:\n\n            gcloud container binauthz policy import <yaml_policy>\n        scored: false\n\n  - id: 5.2\n    text: \"Identity and Access Management (IAM)\"\n    checks:\n      - id: 5.2.1\n        text: \"Ensure GKE clusters are not running using the Compute Engine default service account (Automated))\"\n        audit: |\n          gcloud container node-pools describe $NODE_POOL --cluster $CLUSTER_NAME --zone $COMPUTE_ZONE --format json | jq '.config.serviceAccount'\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n          To create a minimally privileged service account:\n\n            gcloud iam service-accounts create <node_sa_name> \\\n              --display-name \"GKE Node Service Account\"\n            export NODE_SA_EMAIL=gcloud iam service-accounts list \\\n              --format='value(email)' --filter='displayName:GKE Node Service Account'\n\n          Grant the following roles to the service account:\n\n            export PROJECT_ID=gcloud config get-value project\n            gcloud projects add-iam-policy-binding <project_id> --member \\\n              serviceAccount:<node_sa_email> --role roles/monitoring.metricWriter\n            gcloud projects add-iam-policy-binding <project_id> --member \\\n              serviceAccount:<node_sa_email> --role roles/monitoring.viewer\n            gcloud projects add-iam-policy-binding <project_id> --member \\\n              serviceAccount:<node_sa_email> --role roles/logging.logWriter\n\n          To create a new Node pool using the Service account, run the following command:\n\n            gcloud container node-pools create <node_pool> \\\n              --service-account=<sa_name>@<project_id>.iam.gserviceaccount.com \\\n              --cluster=<cluster_name> --zone <compute_zone>\n\n          Note: The workloads will need to be migrated to the new Node pool, and the old node\n          pools that use the default service account should be deleted to complete the\n          remediation.\n        scored: false\n\n      - id: 5.2.2\n        text: \"Prefer using dedicated GCP Service Accounts and Workload Identity (Manual)\"\n        audit: |\n          gcloud container clusters describe $CLUSTER_NAME --zone $COMPUTE_ZONE --format json | jq .workloadIdentityConfig\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n\n            gcloud container clusters update <cluster_name> --zone <cluster_zone> \\\n            --workload-pool <project_id>.svc.id.goog\n\n          Note that existing Node pools are unaffected. New Node pools default to --workload-\n          metadata-from-node=GKE_METADATA_SERVER.\n\n          Then, modify existing Node pools to enable GKE_METADATA_SERVER:\n\n            gcloud container node-pools update <node_pool_name> --cluster <cluster_name> \\\n              --zone <cluster_zone> --workload-metadata=GKE_METADATA\n\n          Workloads may need to be modified in order for them to use Workload Identity as\n          described within: https://cloud.google.com/kubernetes-engine/docs/how-to/workload-identity.\n          Also consider the effects on the availability of hosted workloads as Node pools\n          are updated. It may be more appropriate to create new Node Pools.\n        scored: false\n\n  - id: 5.3\n    text: \"Cloud Key Management Service (Cloud KMS)\"\n    checks:\n      - id: 5.3.1\n        text: \"Ensure Kubernetes Secrets are encrypted using keys managed in Cloud KMS (Automated)\"\n        audit: |\n          gcloud container clusters describe $CLUSTER_NAME --zone $COMPUTE_ZONE --format json | jq '.databaseEncryption'\n        type: \"manual\"\n        remediation: |\n          To create a key:\n          Create a key ring:\n\n            gcloud kms keyrings create <ring_name> --location <location> --project \\\n              <key_project_id>\n\n          Create a key:\n\n            gcloud kms keys create <key_name> --location <location> --keyring <ring_name> \\\n              --purpose encryption --project <key_project_id>\n\n          Grant the Kubernetes Engine Service Agent service account the Cloud KMS\n          CryptoKey Encrypter/Decrypter role:\n\n            gcloud kms keys add-iam-policy-binding <key_name> --location <location> \\\n            --keyring <ring_name> --member serviceAccount:<service_account_name> \\\n            --role roles/cloudkms.cryptoKeyEncrypterDecrypter --project <key_project_id>\n\n          To create a new cluster with Application-layer Secrets Encryption:\n\n            gcloud container clusters create <cluster_name> --cluster-version=latest \\\n            --zone <zone> \\\n            --database-encryption-key projects/<key_project_id>/locations/<location>/keyRings/<ring_name>/cryptoKeys/<key_name> \\\n            --project <cluster_project_id>\n\n          To enable on an existing cluster:\n\n            gcloud container clusters update <cluster_name> --zone <zone> \\\n            --database-encryption-key projects/<key_project_id>/locations/<location>/keyRings/<ring_name>/cryptoKeys/<key_name> \\\n            --project <cluster_project_id>\n        scored: false\n\n  - id: 5.4\n    text: \"Node Metadata\"\n    checks:\n      - id: 5.4.1\n        text: \"Ensure the GKE Metadata Server is Enabled (Automated)\"\n        audit: |\n          gcloud container clusters describe $CLUSTER_NAME --zone $COMPUTE_ZONE --format json | jq '.nodePools[].config.workloadMetadataConfig'\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n\n            gcloud container clusters update <cluster_name> --identity-namespace=<project_id>.svc.id.goog\n\n          Note that existing Node pools are unaffected. New Node pools default to --workload-\n          metadata-from-node=GKE_METADATA_SERVER.\n\n          To modify an existing Node pool to enable GKE Metadata Server:\n\n            gcloud container node-pools update <node_pool_name> --cluster=<cluster_name> \\\n              --workload-metadata-from-node=GKE_METADATA_SERVER\n\n          Workloads may need modification in order for them to use Workload Identity as\n          described within: https://cloud.google.com/kubernetes-engine/docs/how-to/workload-identity.\n        scored: false\n\n  - id: 5.5\n    text: \"Node Configuration and Maintenance\"\n    checks:\n      - id: 5.5.1\n        text: \"Ensure Container-Optimized OS (cos_containerd) is used for GKE node images (Automated)\"\n        audit: |\n          gcloud container node-pools describe $NODE_POOL --cluster $CLUSTER_NAME --zone $COMPUTE_ZONE --format json | jq '.config.imageType'\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n          To set the node image to cos for an existing cluster's Node pool:\n\n            gcloud container clusters upgrade <cluster_name> --image-type cos_containerd \\\n              --zone <compute_zone> --node-pool <node_pool_name>\n        scored: false\n\n      - id: 5.5.2\n        text: \"Ensure Node Auto-Repair is enabled for GKE nodes (Automated)\"\n        audit: |\n          gcloud container node-pools describe $POOL_NAME --cluster $CLUSTER_NAME --zone $COMPUTE_ZONE --format json | jq '.management'\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n          To enable node auto-repair for an existing cluster's Node pool:\n\n            gcloud container node-pools update <node_pool_name> --cluster <cluster_name> \\\n              --zone <compute_zone> --enable-autorepair\n        scored: false\n\n      - id: 5.5.3\n        text: \"Ensure Node Auto-Upgrade is enabled for GKE nodes (Automated)\"\n        audit: |\n          gcloud container node-pools describe $POOL_NAME --cluster $CLUSTER_NAME --zone $COMPUTE_ZONE --format json | jq '.management'\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n          To enable node auto-upgrade for an existing cluster's Node pool, run the following\n          command:\n\n            gcloud container node-pools update <node_pool_name> --cluster <cluster_name> \\\n              --zone <cluster_zone> --enable-autoupgrade\n        scored: false\n\n      - id: 5.5.4\n        text: \"When creating New Clusters - Automate GKE version management using Release Channels (Automated)\"\n        audit: |\n          gcloud container clusters describe $CLUSTER_NAME --zone $COMPUTE_ZONE --format json | jq .releaseChannel.channel\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n          Create a new cluster by running the following command:\n\n            gcloud container clusters create <cluster_name> --zone <cluster_zone> \\\n              --release-channel <release_channel>\n\n          where <release_channel> is stable or regular, according to requirements.\n        scored: false\n\n      - id: 5.5.5\n        text: \"Ensure Shielded GKE Nodes are Enabled (Automated)\"\n        audit: |\n          gcloud container clusters describe $CLUSTER_NAME --zone $COMPUTE_ZONE --format json | jq '.shieldedNodes'\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n          To migrate an existing cluster, the flag --enable-shielded-nodes needs to be\n          specified in the cluster update command:\n\n            gcloud container clusters update <cluster_name> --zone <cluster_zone> \\\n              --enable-shielded-nodes\n        scored: false\n\n      - id: 5.5.6\n        text: \"Ensure Integrity Monitoring for Shielded GKE Nodes is Enabled (Automated)\"\n        audit: |\n          gcloud container node-pools describe $POOL_NAME --cluster $CLUSTER_NAME --zone $COMPUTE_ZONE --format json | jq .config.shieldedInstanceConfig\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n          To create a Node pool within the cluster with Integrity Monitoring enabled, run the\n          following command:\n\n            gcloud container node-pools create <node_pool_name> --cluster <cluster_name> \\\n              --zone <compute_zone> --shielded-integrity-monitoring\n\n          Workloads from existing non-conforming Node pools will need to be migrated to the\n          newly created Node pool, then delete non-conforming Node pools to complete the\n          remediation\n        scored: false\n\n      - id: 5.5.7\n        text: \"Ensure Secure Boot for Shielded GKE Nodes is Enabled (Automated)\"\n        audit: |\n          gcloud container node-pools describe $POOL_NAME --cluster $CLUSTER_NAME --zone $COMPUTE_ZONE --format json | jq .config.shieldedInstanceConfig\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n          To create a Node pool within the cluster with Secure Boot enabled, run the following\n          command:\n\n            gcloud container node-pools create <node_pool_name> --cluster <cluster_name> \\\n              --zone <compute_zone> --shielded-secure-boot\n\n          Workloads will need to be migrated from existing non-conforming Node pools to the\n          newly created Node pool, then delete the non-conforming pools.\n        scored: false\n\n  - id: 5.6\n    text: \"Cluster Networking\"\n    checks:\n      - id: 5.6.1\n        text: \"Enable VPC Flow Logs and Intranode Visibility (Automated)\"\n        audit: |\n          gcloud container clusters describe $CLUSTER_NAME --zone $COMPUTE_ZONE --format json | jq '.networkConfig.enableIntraNodeVisibility'\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n          1. Find the subnetwork name associated with the cluster.\n\n            gcloud container clusters describe <cluster_name> \\\n              --region <cluster_region> - -format json | jq '.subnetwork'\n\n          2. Update the subnetwork to enable VPC Flow Logs.\n            gcloud compute networks subnets update <subnet_name> --enable-flow-logs\n        scored: false\n\n      - id: 5.6.2\n        text: \"Ensure use of VPC-native clusters (Automated)\"\n        audit: |\n          gcloud container clusters describe $CLUSTER_NAME --zone $COMPUTE_ZONE --format json | jq '.ipAllocationPolicy.useIpAliases'\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n          To enable Alias IP on a new cluster, run the following command:\n\n            gcloud container clusters create <cluster_name> --zone <compute_zone> \\\n              --enable-ip-alias\n        scored: false\n\n      - id: 5.6.3\n        text: \"Ensure Control Plane Authorized Networks is Enabled (Automated)\"\n        audit: |\n          gcloud container clusters describe $CLUSTER_NAME --zone $COMPUTE_ZONE --format json | jq '.masterAuthorizedNetworksConfig'\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n          To enable Control Plane Authorized Networks for an existing cluster, run the following\n          command:\n\n            gcloud container clusters update <cluster_name> --zone <compute_zone> \\\n              --enable-master-authorized-networks\n\n          Along with this, you can list authorized networks using the --master-authorized-networks\n          flag which contains a list of up to 20 external networks that are allowed to\n          connect to your cluster's control plane through HTTPS. You provide these networks as\n          a comma-separated list of addresses in CIDR notation (such as 90.90.100.0/24).\n        scored: false\n\n      - id: 5.6.4\n        text: \"Ensure clusters are created with Private Endpoint Enabled and Public Access Disabled (Automated)\"\n        audit: |\n          gcloud container clusters describe $CLUSTER_NAME --zone $COMPUTE_ZONE --format json | jq '.privateClusterConfig.enablePrivateEndpoint'\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n          Create a cluster with a Private Endpoint enabled and Public Access disabled by including\n          the --enable-private-endpoint flag within the cluster create command:\n\n            gcloud container clusters create <cluster_name> --enable-private-endpoint\n\n          Setting this flag also requires the setting of --enable-private-nodes, --enable-ip-alias\n          and --master-ipv4-cidr=<master_cidr_range>.\n        scored: false\n\n      - id: 5.6.5\n        text: \"Ensure clusters are created with Private Nodes (Automated)\"\n        audit: |\n          gcloud container clusters describe $CLUSTER_NAME --zone $COMPUTE_ZONE --format json | jq '.privateClusterConfig.enablePrivateNodes'\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n          To create a cluster with Private Nodes enabled, include the --enable-private-nodes\n          flag within the cluster create command:\n\n            gcloud container clusters create <cluster_name> --enable-private-nodes\n\n          Setting this flag also requires the setting of --enable-ip-alias and\n          --master-ipv4-cidr=<master_cidr_range>.\n        scored: false\n\n      - id: 5.6.6\n        text: \"Consider firewalling GKE worker nodes (Manual)\"\n        audit: |\n          gcloud compute instances describe $INSTANCE_NAME --zone $COMPUTE_ZONE --format json | jq '{tags: .tags.items[], serviceaccount:.serviceAccounts[].email, network: .networkInterfaces[].network}'\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n          Use the following command to generate firewall rules, setting the variables as\n          appropriate:\n\n            gcloud compute firewall-rules create <firewall_rule_name> \\\n            --network <network> --priority <priority> --direction <direction> \\\n            --action <action> --target-tags <tag> \\\n            --target-service-accounts <service_account> \\\n            --source-ranges <source_cidr_range> --source-tags <source_tags> \\\n            --source-service-accounts <source_service_account> \\\n            --destination-ranges <destination_cidr_range> --rules <rules>\n        scored: false\n\n      - id: 5.6.7\n        text: \"Ensure use of Google-managed SSL Certificates (Automated)\"\n        audit: |\n          svc_json=\"$(kubectl get svc -A -o json 2>/dev/null                || echo '{\"items\":[],\"__err\":\"SVC_FORBIDDEN\"}')\"\n          ing_json=\"$(kubectl get ingress -A -o json 2>/dev/null            || echo '{\"items\":[],\"__err\":\"INGRESS_FORBIDDEN\"}')\"\n          mc_json =\"$(kubectl get managedcertificates -A -o json 2>/dev/null || echo '{\"items\":[],\"__err\":\"MC_FORBIDDEN\"}')\"\n\n          printf '%s\\n%s\\n%s\\n' \"$svc_json\" \"$ing_json\" \"$mc_json\" \\\n          | jq -rs '\n            (.[0] // {}) as $svcsRaw |\n            (.[1] // {}) as $ingsRaw |\n            (.[2] // {}) as $mcsRaw |\n\n            # If any list failed, surface an error and DO NOT print the success string\n            if ($svcsRaw.__err or $ingsRaw.__err or $mcsRaw.__err) then\n              \"ERROR_KUBECTL_LIST:\" +\n              ([\n                ($svcsRaw.__err // empty),\n                ($ingsRaw.__err // empty),\n                ($mcsRaw.__err // empty)\n              ] | join(\",\"))\n            else\n              ($svcsRaw.items // []) as $svcs |\n              ($ingsRaw.items // []) as $ings |\n              ($mcsRaw.items // []) as $mcs |\n\n              def trim: gsub(\"^\\\\s+|\\\\s+$\";\"\");\n              def hasmc($ns;$name): any($mcs[]?; .metadata.namespace==$ns and .metadata.name==$name);\n\n              ([\n                # Public Services (not eligible for managed certs)\n                $svcs[]? | select(.spec.type==\"LoadBalancer\")\n                | \"FOUND_PUBLIC_LB_SERVICE:\\(.metadata.namespace // \"default\"):\\(.metadata.name)\"\n              ] + [\n                # Ingresses missing managed-certs annotation\n                $ings[]? as $i\n                | ($i.metadata.annotations.\"networking.gke.io/managed-certificates\" // \"\") as $ann\n                | select($ann==\"\")\n                | \"FOUND_INGRESS_WITHOUT_MANAGED_CERT:\\($i.metadata.namespace // \"default\"):\\($i.metadata.name)\"\n              ] + [\n                # Ingresses referencing non-existent ManagedCertificate(s)\n                $ings[]? as $i\n                | ($i.metadata.annotations.\"networking.gke.io/managed-certificates\" // \"\") as $ann\n                | select($ann!=\"\")\n                | ($i.metadata.namespace // \"default\") as $ns\n                | ($ann | split(\",\") | map(trim) | map(select(length>0)) | .[]) as $mc\n                | select(hasmc($ns;$mc) | not)\n                | \"FOUND_MISSING_MANAGED_CERT_RESOURCE:\\($ns):\\($i.metadata.name):cert=\\($mc)\"\n              ]) as $f\n              | if ($f|length)>0\n                  then $f[]\n                  else \"ALL_INGRESSES_USE_MANAGED_CERTS_AND_NO_PUBLIC_LB_SERVICES\"\n                end\n            end\n          '\n        tests:\n          test_items:\n            - flag: \"ALL_INGRESSES_USE_MANAGED_CERTS_AND_NO_PUBLIC_LB_SERVICES\"\n              set: true\n              compare:\n                op: eq\n                value: \"ALL_INGRESSES_USE_MANAGED_CERTS_AND_NO_PUBLIC_LB_SERVICES\"\n        remediation: |\n          If services of type:LoadBalancer are discovered, consider replacing the Service with\n          an Ingress.\n\n          To configure the Ingress and use Google-managed SSL certificates, follow the\n          instructions as listed at: https://cloud.google.com/kubernetes-engine/docs/how-\n          to/managed-certs.\n        scored: true\n\n  - id: 5.7\n    text: \"Logging\"\n    checks:\n      - id: 5.7.1\n        text: \"Ensure Logging and Cloud Monitoring is Enabled (Automated)\"\n        audit: |\n          gcloud container clusters describe $CLUSTER_NAME --zone $COMPUTE_ZONE --format json | jq '.loggingService'\n        type: \"manual\"\n        remediation: |\n          To enable Logging for an existing cluster, run the following command:\n            gcloud container clusters update <cluster_name> --zone <compute_zone> \\\n            --logging=<components_to_be_logged>\n\n          See https://cloud.google.com/sdk/gcloud/reference/container/clusters/update#--logging\n          for a list of available components for logging.\n\n          To enable Cloud Monitoring for an existing cluster, run the following command:\n            gcloud container clusters update <cluster_name> --zone <compute_zone> \\\n            --monitoring=<components_to_be_logged>\n\n          See https://cloud.google.com/sdk/gcloud/reference/container/clusters/update#--\n          monitoring for a list of available components for Cloud Monitoring.\n        scored: false\n\n      - id: 5.7.2\n        text: \"Enable Linux auditd logging (Manual)\"\n        audit: |\n          kubectl get daemonsets -A -o json | jq '.items[] | select (.spec.template.spec.containers[].image | contains (\"gcr.io/stackdriver-agents/stackdriver-logging-agent\"))'| jq '{name: .metadata.name, annotations: .metadata.annotations.\"kubernetes.io/description\", namespace: .metadata.namespace, status: .status}'\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n          Download the example manifests:\n            curl https://raw.githubusercontent.com/GoogleCloudPlatform/k8s-node-tools/master/os-audit/cos-auditd-logging.yaml > cos-auditd-logging.yaml\n\n          Edit the example manifests if needed. Then, deploy them:\n            kubectl apply -f cos-auditd-logging.yaml\n\n          Verify that the logging Pods have started. If a different Namespace was defined in the\n          manifests, replace cos-auditd with the name of the namespace being used:\n            kubectl get pods --namespace=cos-auditd\n        scored: false\n\n  - id: 5.8\n    text: \"Authentication and Authorization\"\n    checks:\n      - id: 5.8.1\n        text: \"Ensure authentication using Client Certificates is Disabled (Automated)\"\n        audit: |\n          gcloud container clusters describe $CLUSTER_NAME --zone $COMPUTE_ZONE --format json | jq '.masterAuth.clientKey'\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n          Create a new cluster without a Client Certificate:\n            gcloud container clusters create [CLUSTER_NAME] \\\n              --no-issue-client-certificate\n        scored: false\n\n      - id: 5.8.2\n        text: \"Manage Kubernetes RBAC users with Google Groups for GKE (Manual)\"\n        audit: |\n          gcloud container clusters create <cluster_name> --security-group <security_group_name>\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n          Follow the G Suite Groups instructions at: https://cloud.google.com/kubernetes-\n          engine/docs/how-to/role-based-access-control#google-groups-for-gke.\n\n          Then, create a cluster with:\n            gcloud container clusters create <cluster_name> --security-group <security_group_name>\n\n          Finally create Roles, ClusterRoles, RoleBindings, and ClusterRoleBindings that\n          reference the G Suite Groups.\n        scored: false\n\n      - id: 5.8.3\n        text: \"Ensure Legacy Authorization (ABAC) is Disabled (Automated)\"\n        audit: |\n          gcloud container clusters describe $CLUSTER_NAME --zone $COMPUTE_ZONE --format json | jq '.legacyAbac'\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n          To disable Legacy Authorization for an existing cluster, run the following command:\n            gcloud container clusters update <cluster_name> --zone <compute_zone> \\\n              --no-enable-legacy-authorization\n        scored: false\n\n  - id: 5.9\n    text: \"Storage\"\n    checks:\n      - id: 5.9.1\n        text: \"Enable Customer-Managed Encryption Keys (CMEK) for GKE Persistent Disks (PD) (Manual)\"\n        audit: |\n          gcloud compute disks describe $PV_NAME --zone $COMPUTE_ZONE --format json | jq '.diskEncryptionKey.kmsKeyName'\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n          Follow the instructions detailed at: https://cloud.google.com/kubernetes-engine/docs/how-to/using-cmek.\n        scored: false\n\n      - id: 5.9.2\n        text: \"Enable Customer-Managed Encryption Keys (CMEK) for Boot Disks (Automated)\"\n        audit: |\n          gcloud container node-pools describe $NODE_POOL --cluster $CLUSTER_NAME --zone $COMPUTE_ZONE\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n          Create a new node pool using customer-managed encryption keys for the node boot\n          disk, of <disk_type> either pd-standard or pd-ssd:\n            gcloud container node-pools create <cluster_name> --disk-type <disk_type> \\\n            --boot-disk-kms-key projects/<key_project_id>/locations/<location>/keyRings/<ring_name>/cryptoKeys/<key_name>\n\n          Create a cluster using customer-managed encryption keys for the node boot disk, of\n          <disk_type> either pd-standard or pd-ssd:\n            gcloud container clusters create <cluster_name> --disk-type <disk_type> \\\n            --boot-disk-kms-key projects/<key_project_id>/locations/<location>/keyRings/<ring_name>/cryptoKeys/<key_name>\n        scored: false\n\n  - id: 5.10\n    text: \"Other Cluster Configurations\"\n    checks:\n      - id: 5.10.1\n        text: \"Ensure Kubernetes Web UI is Disabled (Automated)\"\n        audit: |\n          gcloud container clusters describe $CLUSTER_NAME --zone $COMPUTE_ZONE  --format json | jq '.addonsConfig.kubernetesDashboard'\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n          To disable the Kubernetes Dashboard on an existing cluster, run the following\n          command:\n            gcloud container clusters update <cluster_name> --zone <zone> \\\n              --update-addons=KubernetesDashboard=DISABLED\n        scored: false\n\n      - id: 5.10.2\n        text: \"Ensure that Alpha clusters are not used for production workloads (Automated)\"\n        audit: |\n          gcloud container clusters describe $CLUSTER_NAME --zone $COMPUTE_ZONE --format json | jq '.enableKubernetesAlpha'\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n          Upon creating a new cluster\n            gcloud container clusters create [CLUSTER_NAME] \\\n              --zone [COMPUTE_ZONE]\n\n          Do not use the --enable-kubernetes-alpha argument.\n        scored: false\n\n      - id: 5.10.3\n        text: \"Consider GKE Sandbox for running untrusted workloads (Manual)\"\n        audit: |\n          gcloud container node-pools describe $NODE_POOL --cluster $CLUSTER_NAME --zone $COMPUTE_ZONE --format json | jq '.config.sandboxConfig'\n        type: \"manual\"\n        remediation: |\n          Using Command Line:\n          To enable GKE Sandbox on an existing cluster, a new Node pool must be created,\n          which can be done using:\n            gcloud container node-pools create <node_pool_name> --zone <compute-zone> \\\n              --cluster <cluster_name> --image-type=cos_containerd --sandbox=\"type=gvisor\"\n        scored: false\n\n      - id: 5.10.5\n        text: \"Enable Security Posture (Manual)\"\n        audit: \"gcloud container clusters --location describe\"\n        type: \"manual\"\n        remediation: |\n          Enable security posture via the UI, gCloud or API.\n          https://cloud.google.com/kubernetes-engine/docs/how-to/protect-workload-configuration\n        scored: false\n"
  },
  {
    "path": "cfg/gke-1.8.0/master.yaml",
    "content": "---\ncontrols:\nversion: \"gke-1.8.0\"\nid: 1\ntext: \"Control Plane Components\"\ntype: \"master\"\n"
  },
  {
    "path": "cfg/gke-1.8.0/node.yaml",
    "content": "---\ncontrols:\nversion: \"gke-1.8.0\"\nid: 3\ntext: \"Worker Nodes\"\ntype: \"node\"\ngroups:\n  - id: 3.1\n    text: \"Worker Node Configuration Files\"\n    checks:\n      - id: 3.1.1\n        text: \"Ensure that the kubeconfig file permissions are set to 644 or more restrictive (Automated)\"\n        audit: '/bin/sh -c ''if test -e $proxykubeconfig; then stat -c permissions=%a $proxykubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on each worker node.\n          For example,\n\n            chmod 644 $proxykubeconfig\n        scored: true\n\n      - id: 3.1.2\n        text: \"Ensure that the kubelet kubeconfig file ownership is set to root:root (Automated)\"\n        audit: '/bin/sh -c ''if test -e $proxykubeconfig; then stat -c %U:%G $proxykubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the below command (based on the file location on your system) on each worker node.\n          For example:\n\n            chown root:root $proxykubeconfig\n        scored: true\n\n      - id: 3.1.3\n        text: \"Ensure that the kubelet configuration file has permissions set to 644 (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletconf; then stat -c permissions=%a $kubeletconf; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the following command (using the kubelet config file location)\n\n            chmod 644 $kubeletconf\n        scored: true\n\n      - id: 3.1.4\n        text: \"Ensure that the kubelet configuration file ownership is set to root:root (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletconf; then stat -c %U:%G $kubeletconf; fi'' '\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the following command (using the config file location identied in the Audit step)\n\n            chown root:root $kubeletconf\n        scored: true\n"
  },
  {
    "path": "cfg/gke-1.8.0/policies.yaml",
    "content": "---\ncontrols:\nversion: \"gke-1.8.0\"\nid: 4\ntext: \"Kubernetes Policies\"\ntype: \"policies\"\ngroups:\n  - id: 4.1\n    text: \"RBAC and Service Accounts\"\n    checks:\n      - id: 4.1.1\n        text: \"Ensure that the cluster-admin role is only used where required (Automated)\"\n        audit: |\n          kubectl get clusterrolebindings -o json | jq -r '\n            [\n              .items[]\n              | select(.roleRef.name == \"cluster-admin\")\n              | .subjects[]?\n              | select(.kind != \"Group\" or .name != \"system:masters\")\n            ]\n            | if length == 0\n              then \"NO_CLUSTER_ADMIN_BINDINGS\"\n              else \"FOUND_CLUSTER_ADMIN_BINDING\"\n              end\n          '\n        tests:\n          test_items:\n            - flag: \"NO_CLUSTER_ADMIN_BINDINGS\"\n              set: true\n              compare:\n                op: eq\n                value: \"NO_CLUSTER_ADMIN_BINDINGS\"\n        remediation: |\n          Identify all ClusterRoleBindings to the \"cluster-admin\" role and review their subjects:\n\n            kubectl get clusterrolebindings -o=custom-columns=NAME:.metadata.name,ROLE:.roleRef.name,SUBJECTS:.subjects[*].name | grep cluster-admin\n\n          If non-system principals (users, groups, or service accounts) do not strictly require cluster-admin,\n          rebind them to a least-privileged (Cluster)Role and then remove the excessive binding:\n\n            kubectl delete clusterrolebinding <binding-name>\n\n          Notes:\n          - Do not modify bindings with the \"system:\" prefix that are required for core components.\n          - Prefer assigning narrowly scoped Roles/ClusterRoles that grant only the permissions needed.\n        scored: true\n\n      - id: 4.1.2\n        text: \"Minimize access to secrets (Automated)\"\n        audit: |\n          count=$(kubectl get roles --all-namespaces -o json | jq '\n            .items[]\n            | select(.rules[]?\n              | (.resources[]? == \"secrets\")\n              and ((.verbs[]? == \"get\") or (.verbs[]? == \"list\") or (.verbs[]? == \"watch\"))\n            )' | wc -l)\n\n          if [ \"$count\" -gt 0 ]; then\n            echo \"SECRETS_ACCESS_FOUND\"\n          fi\n        tests:\n          test_items:\n            - flag: \"SECRETS_ACCESS_FOUND\"\n              set: false\n        remediation: |\n          Where possible, remove get, list and watch access to Secret objects in the cluster.\n        scored: true\n\n      - id: 4.1.3\n        text: \"Minimize wildcard use in Roles and ClusterRoles (Automated)\"\n        audit: |\n          wildcards=$(kubectl get roles --all-namespaces -o json | jq '\n            .items[] | select(\n              .rules[]? | (.verbs[]? == \"*\" or .resources[]? == \"*\" or .apiGroups[]? == \"*\")\n            )' | wc -l)\n\n          wildcards_clusterroles=$(kubectl get clusterroles -o json | jq '\n            .items[] | select(\n              .rules[]? | (.verbs[]? == \"*\" or .resources[]? == \"*\" or .apiGroups[]? == \"*\")\n            )' | wc -l)\n\n          total=$((wildcards + wildcards_clusterroles))\n\n          if [ \"$total\" -gt 0 ]; then\n            echo \"wildcards_present\"\n          fi\n        tests:\n          test_items:\n            - flag: wildcards_present\n              set: false\n        remediation: |\n          Where possible replace any use of wildcards in clusterroles and roles with specific\n          objects or actions.\n        scored: true\n\n      - id: 4.1.4\n        text: \"Ensure that default service accounts are not actively used (Automated)\"\n        audit: |\n          echo \"🔹 Default Service Accounts with automountServiceAccountToken enabled:\"\n          default_sa_count=$(kubectl get serviceaccounts --all-namespaces -o json | jq '\n            [.items[] | select(.metadata.name == \"default\" and (.automountServiceAccountToken != false))] | length')\n          if [ \"$default_sa_count\" -gt 0 ]; then\n            echo \"default_sa_not_auto_mounted\"\n          fi\n\n          echo \"\\n🔹 Pods using default ServiceAccount:\"\n          pods_using_default_sa=$(kubectl get pods --all-namespaces -o json | jq '\n            [.items[] | select(.spec.serviceAccountName == \"default\")] | length')\n          if [ \"$pods_using_default_sa\" -gt 0 ]; then\n            echo \"default_sa_used_in_pods\"\n          fi\n        tests:\n          test_items:\n            - flag: default_sa_not_auto_mounted\n              set: false\n            - flag: default_sa_used_in_pods\n              set: false\n        remediation: |\n          Create explicit service accounts wherever a Kubernetes workload requires specific\n          access to the Kubernetes API server.\n\n          Modify the configuration of each default service account to include this value\n\n            automountServiceAccountToken: false\n        scored: true\n\n      - id: 4.1.5\n        text: \"Ensure that Service Account Tokens are only mounted where necessary (Automated)\"\n        audit: |\n          echo \"🔹 Pods with automountServiceAccountToken enabled:\"\n          pods_with_token_mount=$(kubectl get pods --all-namespaces -o json | jq '\n            [.items[] | select(.spec.automountServiceAccountToken != false)] | length')\n\n          if [ \"$pods_with_token_mount\" -gt 0 ]; then\n            echo \"automountServiceAccountToken\"\n          fi\n        tests:\n          test_items:\n            - flag: automountServiceAccountToken\n              set: false\n        remediation: |\n          Modify the definition of pods and service accounts which do not need to mount service\n          account tokens to disable it.\n        scored: true\n\n      - id: 4.1.6\n        text: \"Avoid use of system:masters group (Automated)\"\n        audit: |\n          found=0\n          for csr in $(kubectl get csr -o name 2>/dev/null | sed 's|^.*/||'); do\n            req=$(kubectl get csr \"$csr\" -o jsonpath='{.spec.request}' 2>/dev/null)\n            [ -z \"$req\" ] && continue\n            if echo \"$req\" | base64 -d 2>/dev/null | openssl req -noout -text 2>/dev/null | grep -q 'O = system:masters'; then\n              conds=$(kubectl get csr \"$csr\" -o json | jq -r '[.status.conditions[]?.type] | join(\",\")')\n              echo \"FOUND_SYSTEM_MASTERS_CSR:${csr}:${conds:-NONE}\"\n              found=1\n            fi\n          done\n          if [ \"$found\" -eq 0 ]; then\n            echo \"NO_SYSTEM_MASTERS_CREDENTIALS_FOUND\"\n          fi\n        tests:\n          test_items:\n            - flag: \"NO_SYSTEM_MASTERS_CREDENTIALS_FOUND\"\n              set: true\n              compare:\n                op: eq\n                value: \"NO_SYSTEM_MASTERS_CREDENTIALS_FOUND\"\n        remediation: |\n          Remove the system:masters group from all users in the cluster.\n        scored: true\n\n      - id: 4.1.7\n        text: \"Limit use of the Bind, Impersonate and Escalate permissions in the Kubernetes cluster (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove the impersonate, bind and escalate rights from subjects.\n        scored: false\n\n      - id: 4.1.8\n        text: \"Avoid bindings to system:anonymous (Automated)\"\n        audit: |\n          # Flags any ClusterRoleBinding/RoleBinding that targets the user \"system:anonymous\".\n          # Prints \"NO_ANONYMOUS_BINDINGS\" when none are found.\n          (\n            kubectl get clusterrolebindings -o json | jq -r '\n              .items[]\n              | select((.subjects | length) > 0)\n              | select(any(.subjects[]?;\n                  .kind==\"User\" and .name==\"system:anonymous\"\n                ))\n              | \"FOUND_ANONYMOUS:ClusterRoleBinding:\\(.metadata.name):ROLE=\\(.roleRef.kind)/\\(.roleRef.name)\"\n            ';\n            kubectl get rolebindings -A -o json | jq -r '\n              .items[]\n              | select((.subjects | length) > 0)\n              | select(any(.subjects[]?;\n                  .kind==\"User\" and .name==\"system:anonymous\"\n                ))\n              | \"FOUND_ANONYMOUS:RoleBinding:\\(.metadata.namespace):\\(.metadata.name):ROLE=\\(.roleRef.kind)/\\(.roleRef.name)\"\n            '\n          ) | (grep -q '^FOUND_ANONYMOUS:' && cat || echo 'NO_ANONYMOUS_BINDINGS')\n        tests:\n          test_items:\n            - flag: \"NO_ANONYMOUS_BINDINGS\"\n              set: true\n              compare:\n                op: eq\n                value: \"NO_ANONYMOUS_BINDINGS\"\n        remediation: |\n          Identify all clusterrolebindings and rolebindings to the user system:anonymous.\n          Check if they are used and review the permissions associated with the binding using the\n          commands in the Audit section above or refer to GKE documentation\n          (https://cloud.google.com/kubernetes-engine/docs/best-practices/rbac#detect-prevent-default).\n\n          Strongly consider replacing unsafe bindings with an authenticated, user-defined group.\n          Where possible, bind to non-default, user-defined groups with least-privilege roles.\n\n          If there are any unsafe bindings to the user system:anonymous, proceed to delete them\n          after consideration for cluster operations with only necessary, safer bindings.\n\n            kubectl delete clusterrolebinding [CLUSTER_ROLE_BINDING_NAME]\n            kubectl delete rolebinding [ROLE_BINDING_NAME] --namespace [ROLE_BINDING_NAMESPACE]\n        scored: true\n\n      - id: 4.1.9\n        text: \"Avoid non-default bindings to system:unauthenticated (Automated)\"\n        audit: |\n          # Flags any non-default binding to the group \"system:unauthenticated\".\n          # Prints \"NO_NON_DEFAULT_UNAUTH_BINDINGS\" when none are found.\n          (\n            kubectl get clusterrolebindings -o json | jq -r '\n              .items[]\n              | select(.metadata.name != \"system:public-info-viewer\")\n              | select((.subjects | length) > 0)\n              | select(any(.subjects[]?;\n                  .kind==\"Group\" and .name==\"system:unauthenticated\"\n                ))\n              | \"FOUND_UNAUTH:ClusterRoleBinding:\\(.metadata.name):ROLE=\\(.roleRef.kind)/\\(.roleRef.name)\"\n            ';\n            kubectl get rolebindings -A -o json | jq -r '\n              .items[]\n              | select((.subjects | length) > 0)\n              | select(any(.subjects[]?;\n                  .kind==\"Group\" and .name==\"system:unauthenticated\"\n                ))\n              | \"FOUND_UNAUTH:RoleBinding:\\(.metadata.namespace):\\(.metadata.name):ROLE=\\(.roleRef.kind)/\\(.roleRef.name)\"\n            '\n          ) | (grep -q \"^FOUND_UNAUTH:\" && cat || echo \"NO_NON_DEFAULT_UNAUTH_BINDINGS\")\n        tests:\n          test_items:\n            - flag: \"NO_NON_DEFAULT_UNAUTH_BINDINGS\"\n              set: true\n              compare:\n                op: eq\n                value: \"NO_NON_DEFAULT_UNAUTH_BINDINGS\"\n        remediation: |\n          Identify all non-default clusterrolebindings and rolebindings to the group\n          system:unauthenticated. Check if they are used and review the permissions\n          associated with the binding using the commands in the Audit section above or refer to\n          GKE documentation (https://cloud.google.com/kubernetes-engine/docs/best-practices/rbac#detect-prevent-default).\n\n          Strongly consider replacing non-default, unsafe bindings with an authenticated, user-\n          defined group. Where possible, bind to non-default, user-defined groups with least-\n          privilege roles.\n\n          If there are any non-default, unsafe bindings to the group system:unauthenticated,\n          proceed to delete them after consideration for cluster operations with only necessary,\n          safer bindings.\n\n            kubectl delete clusterrolebinding [CLUSTER_ROLE_BINDING_NAME]\n            kubectl delete rolebinding [ROLE_BINDING_NAME] --namespace [ROLE_BINDING_NAMESPACE]\n        scored: true\n\n      - id: 4.1.10\n        text: \"Avoid non-default bindings to system:authenticated (Automated)\"\n        audit: |\n          # Flags any non-default binding to the group \"system:authenticated\".\n          # Allowed defaults (CRB): system:basic-user, system:discovery\n          # Prints \"NO_NON_DEFAULT_AUTH_BINDINGS\" when none are found.\n          (\n            kubectl get clusterrolebindings -o json | jq -r '\n              .items[]\n              | select((.metadata.name != \"system:basic-user\") and (.metadata.name != \"system:discovery\"))\n              | select((.subjects | length) > 0)\n              | select(any(.subjects[]?;\n                  .kind==\"Group\" and .name==\"system:authenticated\"\n                ))\n              | \"FOUND_AUTH:ClusterRoleBinding:\\(.metadata.name):ROLE=\\(.roleRef.kind)/\\(.roleRef.name)\"\n            ';\n            kubectl get rolebindings -A -o json | jq -r '\n              .items[]\n              | select((.subjects | length) > 0)\n              | select(any(.subjects[]?;\n                  .kind==\"Group\" and .name==\"system:authenticated\"\n                ))\n              | \"FOUND_AUTH:RoleBinding:\\(.metadata.namespace):\\(.metadata.name):ROLE=\\(.roleRef.kind)/\\(.roleRef.name)\"\n            '\n          ) | (grep -q \"^FOUND_AUTH:\" && cat || echo \"NO_NON_DEFAULT_AUTH_BINDINGS\")\n        tests:\n          test_items:\n            - flag: \"NO_NON_DEFAULT_AUTH_BINDINGS\"\n              set: true\n              compare:\n                op: eq\n                value: \"NO_NON_DEFAULT_AUTH_BINDINGS\"\n        remediation: |\n          Identify all non-default clusterrolebindings and rolebindings to the group\n          system:authenticated. Check if they are used and review the permissions associated\n          with the binding using the commands in the Audit section above or refer to GKE\n          documentation.\n\n          Strongly consider replacing non-default, unsafe bindings with an authenticated, user-\n          defined group. Where possible, bind to non-default, user-defined groups with least-\n          privilege roles.\n\n          If there are any non-default, unsafe bindings to the group system:authenticated,\n          proceed to delete them after consideration for cluster operations with only necessary,\n          safer bindings.\n\n            kubectl delete clusterrolebinding [CLUSTER_ROLE_BINDING_NAME]\n            kubectl delete rolebinding [ROLE_BINDING_NAME] --namespace [ROLE_BINDING_NAMESPACE]\n        scored: true\n\n  - id: 4.2\n    text: \"Pod Security Standards\"\n    checks:\n      - id: 4.2.1\n        text: \"Ensure that the cluster enforces Pod Security Standard Baseline profile or stricter for all namespaces. (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that Pod Security Admission is in place for every namespace which contains\n          user workloads.\n          Run the following command to enforce the Baseline profile in a namespace:\n\n            kubectl label namespace pod-security.kubernetes.io/enforce=baseline\n        scored: false\n\n  - id: 4.3\n    text: \"Network Policies and CNI\"\n    checks:\n      - id: 4.3.1\n        text: \"Ensure that the CNI in use supports Network Policies (Manual)\"\n        type: \"manual\"\n        remediation: |\n          To use a CNI plugin with Network Policy, enable Network Policy in GKE, and the CNI plugin\n          will be updated. See Recommendation 5.6.7.\n        scored: false\n\n      - id: 4.3.2\n        text: \"Ensure that all Namespaces have Network Policies defined (Automated)\"\n        audit: |\n          (kubectl get ns -o json; kubectl get networkpolicy -A -o json) \\\n          | jq -rs '\n            (.[0].items | map(.metadata.name)\n             | map(select(.!=\"kube-system\" and .!=\"kube-public\" and .!=\"kube-node-lease\"))) as $ns\n            |\n            ( (.[1].items // [])\n              | sort_by(.metadata.namespace)\n              | group_by(.metadata.namespace)\n              | map({key: .[0].metadata.namespace, value: length})\n              | from_entries\n            ) as $np\n            |\n            [ $ns[] | select( ($np[.] // 0) == 0 ) ] as $missing\n            |\n            if ($missing|length)>0\n            then ($missing[] | \"FOUND_NAMESPACE_WITHOUT_NETWORKPOLICY:\"+.)\n            else \"ALL_NAMESPACES_HAVE_NETWORK_POLICIES\"\n            end\n          '\n        tests:\n          test_items:\n            - flag: \"ALL_NAMESPACES_HAVE_NETWORK_POLICIES\"\n              set: true\n              compare:\n                op: eq\n                value: \"ALL_NAMESPACES_HAVE_NETWORK_POLICIES\"\n        remediation: |\n          Follow the documentation and create NetworkPolicy objects as needed.\n          See: https://cloud.google.com/kubernetes-engine/docs/how-to/network-policy#creating_a_network_policy\n          for more information.\n        scored: true\n\n  - id: 4.4\n    text: \"Secrets Management\"\n    checks:\n      - id: 4.4.1\n        text: \"Prefer using secrets as files over secrets as environment variables (Automated)\"\n        audit: |\n          output=$(kubectl get all --all-namespaces -o jsonpath='{range .items[?(@..secretKeyRef)]} {.kind} {.metadata.name} {\"\\n\"}{end}')\n          if [ -z \"$output\" ]; then echo \"NO_ENV_SECRET_REFERENCES\"; else echo \"ENV_SECRET_REFERENCES_FOUND\"; fi\n        tests:\n          test_items:\n            - flag: \"NO_ENV_SECRET_REFERENCES\"\n              set: true\n              compare:\n                op: eq\n                value: \"NO_ENV_SECRET_REFERENCES\"\n        remediation: |\n          if possible, rewrite application code to read secrets from mounted secret files, rather than\n          from environment variables.\n        scored: true\n\n      - id: 4.4.2\n        text: \"Consider external secret storage (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Refer to the secrets management options offered by your cloud provider or a third-party\n          secrets management solution.\n        scored: false\n\n  - id: 4.5\n    text: \"Extensible Admission Control\"\n    checks:\n      - id: 4.5.1\n        text: \"Configure Image Provenance using ImagePolicyWebhook admission controller (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and setup image provenance.\n          Also see recommendation 5.10.4.\n        scored: false\n\n  - id: 4.6\n    text: \"General Policies\"\n    checks:\n      - id: 4.6.1\n        text: \"Create administrative boundaries between resources using namespaces (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the documentation and create namespaces for objects in your deployment as you need\n          them.\n        scored: false\n\n      - id: 4.6.2\n        text: \"Ensure that the seccomp profile is set to RuntimeDefault in your pod definitions (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Use security context to enable the RuntimeDefault seccomp profile in your pod\n          definitions. An example is as below:\n\n            {\n              \"namespace\": \"kube-system\",\n              \"name\": \"metrics-server-v0.7.0-dbcc8ddf6-gz7d4\",\n              \"seccompProfile\": \"RuntimeDefault\"\n            }\n        scored: false\n\n      - id: 4.6.3\n        text: \"Apply Security Context to Your Pods and Containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and apply security contexts to your pods. For a\n          suggested list of security contexts, you may refer to the CIS Google Container-\n          Optimized OS Benchmark.\n        scored: false\n\n      - id: 4.6.4\n        text: \"The default namespace should not be used (Automated)\"\n        audit: |\n          output=$(kubectl get all -n default --no-headers 2>/dev/null | grep -v '^service\\s\\+kubernetes\\s' || true)\n          if [ -z \"$output\" ]; then echo \"DEFAULT_NAMESPACE_UNUSED\"; else echo \"DEFAULT_NAMESPACE_IN_USE\"; fi\n        tests:\n          test_items:\n            - flag: \"DEFAULT_NAMESPACE_UNUSED\"\n              set: true\n              compare:\n                op: eq\n                value: \"DEFAULT_NAMESPACE_UNUSED\"\n        remediation: |\n          Ensure that namespaces are created to allow for appropriate segregation of Kubernetes\n          resources and that all new resources are created in a specific namespace.\n        scored: true\n"
  },
  {
    "path": "cfg/k3s-cis-1.23/config.yaml",
    "content": "---\n## Version-specific settings that override the values in cfg/config.yaml\n\nmaster:\n  components:\n    - apiserver\n    - scheduler\n    - controllermanager\n    - etcd\n    - policies\n\n  apiserver:\n    bins:\n      - containerd\n\n  scheduler:\n    bins:\n      - containerd\n\n  controllermanager:\n    bins:\n      - containerd\n\n  etcd:\n    bins:\n      - containerd\n    datadirs:\n      - /var/lib/rancher/k3s/server/db/etcd\n  node:\n    components:\n      - kubelet\n      - proxy\n\n    kubelet:\n      bins:\n        - containerd\n      defaultkubeconfig: /var/lib/rancher/k3s/agent/kubelet.kubeconfig\n      defaultcafile: /var/lib/rancher/k3s/agent/client-ca.crt\n\n    proxy:\n      bins:\n        - containerd\n      defaultkubeconfig: /var/lib/rancher/k3s/agent/kubeproxy.kubeconfig\n\n  policies:\n    components:\n      - policies\n"
  },
  {
    "path": "cfg/k3s-cis-1.23/controlplane.yaml",
    "content": "---\ncontrols:\nversion: \"k3s-cis-1.23\"\nid: 3\ntext: \"Control Plane Configuration\"\ntype: \"controlplane\"\ngroups:\n  - id: 3.1\n    text: \"Authentication and Authorization\"\n    checks:\n      - id: 3.1.1\n        text: \"Client certificate authentication should not be used for users (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Alternative mechanisms provided by Kubernetes such as the use of OIDC should be\n          implemented in place of client certificates.\n        scored: false\n\n  - id: 3.2\n    text: \"Logging\"\n    checks:\n      - id: 3.2.1\n        text: \"Ensure that a minimal audit policy is created (Manual)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'audit-policy-file'\"\n        type: \"manual\"\n        tests:\n          test_items:\n            - flag: \"--audit-policy-file\"\n              set: true\n        remediation: |\n          Create an audit policy file for your cluster.\n        scored: false\n\n      - id: 3.2.2\n        text: \"Ensure that the audit policy covers key security concerns (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Review the audit policy provided for the cluster and ensure that it covers\n          at least the following areas,\n          - Access to Secrets managed by the cluster. Care should be taken to only\n            log Metadata for requests to Secrets, ConfigMaps, and TokenReviews, in\n            order to avoid risk of logging sensitive data.\n          - Modification of Pod and Deployment objects.\n          - Use of `pods/exec`, `pods/portforward`, `pods/proxy` and `services/proxy`.\n          For most requests, minimally logging at the Metadata level is recommended\n          (the most basic level of logging).\n        scored: false\n"
  },
  {
    "path": "cfg/k3s-cis-1.23/etcd.yaml",
    "content": "---\ncontrols:\nversion: \"k3s-cis-1.23\"\nid: 2\ntext: \"Etcd Node Configuration\"\ntype: \"etcd\"\ngroups:\n  - id: 2\n    text: \"Etcd Node Configuration\"\n    checks:\n      - id: 2.1\n        text: \"Ensure that the --cert-file and --key-file arguments are set as appropriate (Automated)\"\n        audit: \"grep -A 4 'client-transport-security' $etcdconf | grep -E 'cert-file|key-file'\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"cert-file\"\n              set: true\n            - flag: \"key-file\"\n              set: true\n        remediation: |\n          Follow the etcd service documentation and configure TLS encryption.\n          Then, edit the etcd pod specification file /etc/kubernetes/manifests/etcd.yaml\n          on the master node and set the below parameters.\n          --cert-file=</path/to/ca-file>\n          --key-file=</path/to/key-file>\n        scored: true\n\n      - id: 2.2\n        text: \"Ensure that the --client-cert-auth argument is set to true (Automated)\"\n        audit: \"grep -A 4 'client-transport-security' $etcdconf | grep 'client-cert-auth'\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--client-cert-auth\"\n              set: true\n            - flag: \"client-cert-auth\"\n              compare:\n                op: eq\n                value: true\n              set: true\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and set the below parameter.\n          --client-cert-auth=\"true\"\n        scored: true\n\n      - id: 2.3\n        text: \"Ensure that the --auto-tls argument is not set to true (Automated)\"\n        audit: \"if grep -q '^auto-tls' $etcdconf;then grep '^auto-tls' $etcdconf;else echo 'notset';fi\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--auto-tls\"\n              set: false\n            - flag: \"--auto-tls\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and either remove the --auto-tls parameter or set it to false.\n            --auto-tls=false\n        scored: true\n\n      - id: 2.4\n        text: \"Ensure that the --peer-cert-file and --peer-key-file arguments are set as appropriate (Automated)\"\n        audit: \"grep -A 4 'peer-transport-security' $etcdconf | grep -E 'cert-file|key-file'\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"cert-file\"\n              set: true\n            - flag: \"key-file\"\n              set: true\n        remediation: |\n          Follow the etcd service documentation and configure peer TLS encryption as appropriate\n          for your etcd cluster.\n          Then, edit the etcd pod specification file $etcdconf on the\n          master node and set the below parameters.\n          --peer-client-file=</path/to/peer-cert-file>\n          --peer-key-file=</path/to/peer-key-file>\n        scored: true\n\n      - id: 2.5\n        text: \"Ensure that the --peer-client-cert-auth argument is set to true (Automated)\"\n        audit: \"grep -A 4 'peer-transport-security' $etcdconf | grep 'client-cert-auth'\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--client-cert-auth\"\n              set: true\n            - flag: \"client-cert-auth\"\n              compare:\n                op: eq\n                value: true\n              set: true\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and set the below parameter.\n          --peer-client-cert-auth=true\n        scored: true\n\n      - id: 2.6\n        text: \"Ensure that the --peer-auto-tls argument is not set to true (Automated)\"\n        audit: \"if grep -q '^peer-auto-tls' $etcdconf;then grep '^peer-auto-tls' $etcdconf;else echo 'notset';fi\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--peer-auto-tls\"\n              set: false\n            - flag: \"--peer-auto-tls\"\n              compare:\n                op: eq\n                value: false\n              set: true\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and either remove the --peer-auto-tls parameter or set it to false.\n          --peer-auto-tls=false\n        scored: true\n\n      - id: 2.7\n        text: \"Ensure that a unique Certificate Authority is used for etcd (Manual)\"\n        audit: \"if grep -q 'trusted-ca-file' $etcdconf;then grep 'trusted-ca-file' $etcdconf;else echo 'notset';fi\"\n        tests:\n          test_items:\n            - flag: \"trusted-ca-file\"\n              set: true\n        remediation: |\n          [Manual test]\n          Follow the etcd documentation and create a dedicated certificate authority setup for the\n          etcd service.\n          Then, edit the etcd pod specification file $etcdconf on the\n          master node and set the below parameter.\n          --trusted-ca-file=</path/to/ca-file>\n        scored: false\n"
  },
  {
    "path": "cfg/k3s-cis-1.23/master.yaml",
    "content": "---\ncontrols:\nversion: \"k3s-cis-1.23\"\nid: 1\ntext: \"Control Plane Security Configuration\"\ntype: \"master\"\ngroups:\n  - id: 1.1\n    text: \"Control Plane Node Configuration Files\"\n    checks:\n      - id: 1.1.1\n        text: \"Ensure that the API server pod specification file permissions are set to 644 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $apiserverconf; then stat -c permissions=%a $apiserverconf; fi'\"\n        type: \"skip\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the\n          control plane node.\n          For example, chmod 644 $apiserverconf\n        scored: true\n\n      - id: 1.1.2\n        text: \"Ensure that the API server pod specification file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $apiserverconf; then stat -c %U:%G $apiserverconf; fi'\"\n        type: \"skip\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chown root:root $apiserverconf\n        scored: true\n\n      - id: 1.1.3\n        text: \"Ensure that the controller manager pod specification file permissions are set to 644 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerconf; then stat -c permissions=%a $controllermanagerconf; fi'\"\n        type: \"skip\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chmod 644 $controllermanagerconf\n        scored: true\n\n      - id: 1.1.4\n        text: \"Ensure that the controller manager pod specification file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerconf; then stat -c %U:%G $controllermanagerconf; fi'\"\n        type: \"skip\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chown root:root $controllermanagerconf\n        scored: true\n\n      - id: 1.1.5\n        text: \"Ensure that the scheduler pod specification file permissions are set to 644 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerconf; then stat -c permissions=%a $schedulerconf; fi'\"\n        type: \"skip\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chmod 644 $schedulerconf\n        scored: true\n\n      - id: 1.1.6\n        text: \"Ensure that the scheduler pod specification file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerconf; then stat -c %U:%G $schedulerconf; fi'\"\n        type: \"skip\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chown root:root $schedulerconf\n        scored: true\n\n      - id: 1.1.7\n        text: \"Ensure that the etcd pod specification file permissions are set to 644 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $etcdconf; then stat -c permissions=%a $etcdconf; fi'\"\n        type: \"skip\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod 644 $etcdconf\n        scored: true\n\n      - id: 1.1.8\n        text: \"Ensure that the etcd pod specification file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $etcdconf; then stat -c %U:%G $etcdconf; fi'\"\n        type: \"skip\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root $etcdconf\n        scored: true\n\n      - id: 1.1.9\n        text: \"Ensure that the Container Network Interface file permissions are set to 644 or more restrictive (Manual)\"\n        type: \"skip\"\n        audit: |\n          ps -ef | grep $kubeletbin | grep -- --cni-conf-dir | sed 's%.*cni-conf-dir[= ]\\([^ ]*\\).*%\\1%' | xargs -I{} find {} -mindepth 1 | xargs --no-run-if-empty stat -c permissions=%a\n          find /var/lib/cni/networks -type f 2> /dev/null | xargs --no-run-if-empty stat -c permissions=%a\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chmod 644 <path/to/cni/files>\n        scored: false\n\n      - id: 1.1.10\n        text: \"Ensure that the Container Network Interface file ownership is set to root:root (Manual)\"\n        type: \"skip\"\n        audit: |\n          ps -ef | grep $kubeletbin | grep -- --cni-conf-dir | sed 's%.*cni-conf-dir[= ]\\([^ ]*\\).*%\\1%' | xargs -I{} find {} -mindepth 1 | xargs --no-run-if-empty stat -c %U:%G\n          find /var/lib/cni/networks -type f 2> /dev/null | xargs --no-run-if-empty stat -c %U:%G\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root <path/to/cni/files>\n        scored: false\n\n      - id: 1.1.11\n        text: \"Ensure that the etcd data directory permissions are set to 700 or more restrictive (Automated)\"\n        audit: \"stat -c %a $etcddatadir\"\n        tests:\n          test_items:\n            - flag: \"700\"\n              compare:\n                op: eq\n                value: \"700\"\n              set: true\n        remediation: |\n          On the etcd server node, get the etcd data directory, passed as an argument --data-dir,\n          from the command 'ps -ef | grep etcd'.\n          Run the below command (based on the etcd data directory found above). For example,\n          chmod 700 /var/lib/etcd\n        scored: true\n\n      - id: 1.1.12\n        text: \"Ensure that the etcd data directory ownership is set to etcd:etcd (Automated)\"\n        audit: ps -ef | grep $etcdbin | grep -- --data-dir | sed 's%.*data-dir[= ]\\([^ ]*\\).*%\\1%' | xargs stat -c %U:%G\n        type: \"skip\"\n        tests:\n          test_items:\n            - flag: \"etcd:etcd\"\n        remediation: |\n          On the etcd server node, get the etcd data directory, passed as an argument --data-dir,\n          from the command 'ps -ef | grep etcd'.\n          Run the below command (based on the etcd data directory found above).\n          For example, chown etcd:etcd /var/lib/etcd\n        scored: true\n\n      - id: 1.1.13\n        text: \"Ensure that the admin.conf file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e /var/lib/rancher/k3s/server/cred/admin.kubeconfig; then stat -c permissions=%a /var/lib/rancher/k3s/server/cred/admin.kubeconfig'\"\n        type: \"skip\"\n        tests:\n          test_items:\n            - flag: \"600\"\n              compare:\n                op: eq\n                value: \"600\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chmod 600 /var/lib/rancher/k3s/server/cred/admin.kubeconfig\n        scored: true\n\n      - id: 1.1.14\n        text: \"Ensure that the admin.conf file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e /var/lib/rancher/k3s/server/cred/admin.kubeconfig; then stat -c %U:%G /var/lib/rancher/k3s/server/cred/admin.kubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n              compare:\n                op: eq\n                value: \"root:root\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chown root:root /etc/kubernetes/admin.conf\n        scored: true\n\n      - id: 1.1.15\n        text: \"Ensure that the scheduler.conf file permissions are set to 644 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e /var/lib/rancher/k3s/server/cred/scheduler.kubeconfig; then stat -c permissions=%a /var/lib/rancher/k3s/server/cred/scheduler.kubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod 644 $schedulerkubeconfig\n        scored: true\n\n      - id: 1.1.16\n        text: \"Ensure that the scheduler.conf file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e /var/lib/rancher/k3s/server/cred/scheduler.kubeconfig; then stat -c %U:%G /var/lib/rancher/k3s/server/cred/scheduler.kubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root $schedulerkubeconfig\n        scored: true\n\n      - id: 1.1.17\n        text: \"Ensure that the controller-manager.conf file permissions are set to 644 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e /var/lib/rancher/k3s/server/cred/controller.kubeconfig; then stat -c permissions=%a /var/lib/rancher/k3s/server/cred/controller.kubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod 644 $controllermanagerkubeconfig\n        scored: true\n\n      - id: 1.1.18\n        text: \"Ensure that the controller-manager.conf file ownership is set to root:root (Automated)\"\n        audit: \"stat -c %U:%G /var/lib/rancher/k3s/server/tls\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n              compare:\n                op: eq\n                value: \"root:root\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root $controllermanagerkubeconfig\n        scored: true\n\n      - id: 1.1.19\n        text: \"Ensure that the Kubernetes PKI directory and file ownership is set to root:root (Automated)\"\n        audit: \"find /var/lib/rancher/k3s/server/tls | xargs stat -c %U:%G\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown -R root:root /etc/kubernetes/pki/\n        scored: true\n\n      - id: 1.1.20\n        text: \"Ensure that the Kubernetes PKI certificate file permissions are set to 644 or more restrictive (Manual)\"\n        audit: \"stat -c %n\\ %a /var/lib/rancher/k3s/server/tls/*.crt\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod -R 644 /etc/kubernetes/pki/*.crt\n        scored: false\n\n      - id: 1.1.21\n        text: \"Ensure that the Kubernetes PKI key file permissions are set to 600 (Manual)\"\n        audit: \"stat -c %n\\ %a /var/lib/rancher/k3s/server/tls/*.key\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod -R 600 /etc/kubernetes/pki/*.key\n        scored: false\n\n  - id: 1.2\n    text: \"API Server\"\n    checks:\n      - id: 1.2.1\n        text: \"Ensure that the --anonymous-auth argument is set to false (Manual)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'anonymous-auth'\"\n        type: manual\n        tests:\n          test_items:\n            - flag: \"--anonymous-auth\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the below parameter.\n          --anonymous-auth=false\n        scored: false\n\n      - id: 1.2.2\n        text: \"Ensure that the --token-auth-file parameter is not set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--token-auth-file\"\n              set: false\n        remediation: |\n          Follow the documentation and configure alternate mechanisms for authentication. Then,\n          edit the API server pod specification file $apiserverconf\n          on the control plane node and remove the --token-auth-file=<filename> parameter.\n        scored: true\n\n      - id: 1.2.3\n        text: \"Ensure that the --DenyServiceExternalIPs is not set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: nothave\n                value: \"DenyServiceExternalIPs\"\n              set: true\n            - flag: \"--enable-admission-plugins\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and remove the `DenyServiceExternalIPs`\n          from enabled admission plugins.\n        scored: true\n\n      - id: 1.2.4\n        text: \"Ensure that the --kubelet-https argument is set to true (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'kubelet-https'\"\n        type: \"skip\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--kubelet-https\"\n              compare:\n                op: eq\n                value: true\n            - flag: \"--kubelet-https\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and remove the --kubelet-https parameter.\n        scored: true\n\n      - id: 1.2.5\n        text: \"Ensure that the --kubelet-client-certificate and --kubelet-client-key arguments are set as appropriate (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'kubelet-certificate-authority'\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--kubelet-client-certificate\"\n            - flag: \"--kubelet-client-key\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection between the\n          apiserver and kubelets. Then, edit API server pod specification file\n          $apiserverconf on the control plane node and set the\n          kubelet client certificate and key parameters as below.\n          --kubelet-client-certificate=<path/to/client-certificate-file>\n          --kubelet-client-key=<path/to/client-key-file>\n        scored: true\n\n      - id: 1.2.6\n        text: \"Ensure that the --kubelet-certificate-authority argument is set as appropriate (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'kubelet-certificate-authority'\"\n        tests:\n          test_items:\n            - flag: \"--kubelet-certificate-authority\"\n        remediation: |\n          Follow the Kubernetes documentation and setup the TLS connection between\n          the apiserver and kubelets. Then, edit the API server pod specification file\n          $apiserverconf on the control plane node and set the\n          --kubelet-certificate-authority parameter to the path to the cert file for the certificate authority.\n          --kubelet-certificate-authority=<ca-string>\n        scored: true\n\n      - id: 1.2.7\n        text: \"Ensure that the --authorization-mode argument is not set to AlwaysAllow (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'authorization-mode'\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: nothave\n                value: \"AlwaysAllow\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --authorization-mode parameter to values other than AlwaysAllow.\n          One such example could be as below.\n          --authorization-mode=RBAC\n        scored: true\n\n      - id: 1.2.8\n        text: \"Ensure that the --authorization-mode argument includes Node (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'authorization-mode'\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: has\n                value: \"Node\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --authorization-mode parameter to a value that includes Node.\n          --authorization-mode=Node,RBAC\n        scored: true\n\n      - id: 1.2.9\n        text: \"Ensure that the --authorization-mode argument includes RBAC (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'authorization-mode'\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: has\n                value: \"RBAC\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --authorization-mode parameter to a value that includes RBAC,\n          for example `--authorization-mode=Node,RBAC`.\n        scored: true\n\n      - id: 1.2.10\n        text: \"Ensure that the admission control plugin EventRateLimit is set (Manual)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'enable-admission-plugins'\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"EventRateLimit\"\n        remediation: |\n          Follow the Kubernetes documentation and set the desired limits in a configuration file.\n          Then, edit the API server pod specification file $apiserverconf\n          and set the below parameters.\n          --enable-admission-plugins=...,EventRateLimit,...\n          --admission-control-config-file=<path/to/configuration/file>\n        scored: false\n\n      - id: 1.2.11\n        text: \"Ensure that the admission control plugin AlwaysAdmit is not set (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'enable-admission-plugins'\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: nothave\n                value: AlwaysAdmit\n            - flag: \"--enable-admission-plugins\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and either remove the --enable-admission-plugins parameter, or set it to a\n          value that does not include AlwaysAdmit.\n        scored: true\n\n      - id: 1.2.12\n        text: \"Ensure that the admission control plugin AlwaysPullImages is set (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"AlwaysPullImages\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --enable-admission-plugins parameter to include\n          AlwaysPullImages.\n          --enable-admission-plugins=...,AlwaysPullImages,...\n        scored: false\n\n      - id: 1.2.13\n        text: \"Ensure that the admission control plugin SecurityContextDeny is set if PodSecurityPolicy is not used (Manual)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'enable-admission-plugins'\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"SecurityContextDeny\"\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"PodSecurityPolicy\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --enable-admission-plugins parameter to include\n          SecurityContextDeny, unless PodSecurityPolicy is already in place.\n          --enable-admission-plugins=...,SecurityContextDeny,...\n        scored: false\n\n      - id: 1.2.14\n        text: \"Ensure that the admission control plugin ServiceAccount is set (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--disable-admission-plugins\"\n              compare:\n                op: nothave\n                value: \"ServiceAccount\"\n            - flag: \"--disable-admission-plugins\"\n              set: false\n        remediation: |\n          Follow the documentation and create ServiceAccount objects as per your environment.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and ensure that the --disable-admission-plugins parameter is set to a\n          value that does not include ServiceAccount.\n        scored: true\n\n      - id: 1.2.15\n        text: \"Ensure that the admission control plugin NamespaceLifecycle is set (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--disable-admission-plugins\"\n              compare:\n                op: nothave\n                value: \"NamespaceLifecycle\"\n            - flag: \"--disable-admission-plugins\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --disable-admission-plugins parameter to\n          ensure it does not include NamespaceLifecycle.\n        scored: true\n\n      - id: 1.2.16\n        text: \"Ensure that the admission control plugin NodeRestriction is set (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'enable-admission-plugins'\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"NodeRestriction\"\n        remediation: |\n          Follow the Kubernetes documentation and configure NodeRestriction plug-in on kubelets.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --enable-admission-plugins parameter to a\n          value that includes NodeRestriction.\n          --enable-admission-plugins=...,NodeRestriction,...\n        scored: true\n\n      - id: 1.2.17\n        text: \"Ensure that the --secure-port argument is not set to 0 (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'secure-port'\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--secure-port\"\n              compare:\n                op: gt\n                value: 0\n            - flag: \"--secure-port\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and either remove the --secure-port parameter or\n          set it to a different (non-zero) desired port.\n        scored: true\n\n      - id: 1.2.18\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'profiling'\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the below parameter.\n          --profiling=false\n        scored: true\n\n      - id: 1.2.19\n        text: \"Ensure that the --audit-log-path argument is set (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep -v grep\"\n        type: \"skip\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-path\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --audit-log-path parameter to a suitable path and\n          file where you would like audit logs to be written, for example,\n          --audit-log-path=/var/log/apiserver/audit.log\n        scored: true\n\n      - id: 1.2.20\n        text: \"Ensure that the --audit-log-maxage argument is set to 30 or as appropriate (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep -v grep\"\n        type: \"skip\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxage\"\n              compare:\n                op: gte\n                value: 30\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --audit-log-maxage parameter to 30\n          or as an appropriate number of days, for example,\n          --audit-log-maxage=30\n        scored: true\n\n      - id: 1.2.21\n        text: \"Ensure that the --audit-log-maxbackup argument is set to 10 or as appropriate (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep -v grep\"\n        type: \"skip\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxbackup\"\n              compare:\n                op: gte\n                value: 10\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --audit-log-maxbackup parameter to 10 or to an appropriate\n          value. For example,\n          --audit-log-maxbackup=10\n        scored: true\n\n      - id: 1.2.22\n        text: \"Ensure that the --audit-log-maxsize argument is set to 100 or as appropriate (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep -v grep\"\n        type: \"skip\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxsize\"\n              compare:\n                op: gte\n                value: 100\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --audit-log-maxsize parameter to an appropriate size in MB.\n          For example, to set it as 100 MB, --audit-log-maxsize=100\n        scored: true\n\n      - id: 1.2.23\n        text: \"Ensure that the --request-timeout argument is set as appropriate (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep -v grep\"\n        type: \"skip\"\n        tests:\n          test_items:\n            - flag: \"--request-timeout\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          and set the below parameter as appropriate and if needed.\n          For example, --request-timeout=300s\n        scored: true\n\n      - id: 1.2.24\n        text: \"Ensure that the --service-account-lookup argument is set to true (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--service-account-lookup\"\n              set: false\n            - flag: \"--service-account-lookup\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the below parameter.\n          --service-account-lookup=true\n          Alternatively, you can delete the --service-account-lookup parameter from this file so\n          that the default takes effect.\n        scored: true\n\n      - id: 1.2.25\n        text: \"Ensure that the --service-account-key-file argument is set as appropriate (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep -v grep\"\n        type: \"skip\"\n        tests:\n          test_items:\n            - flag: \"--service-account-key-file\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --service-account-key-file parameter\n          to the public key file for service accounts. For example,\n          --service-account-key-file=<filename>\n        scored: true\n\n      - id: 1.2.26\n        text: \"Ensure that the --etcd-certfile and --etcd-keyfile arguments are set as appropriate (Automated)\"\n        audit: \"journalctl -m -u k3s | grep -m1 'Running kube-apiserver'\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--etcd-certfile\"\n              set: true\n            - flag: \"--etcd-keyfile\"\n              set: true\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection between the apiserver and etcd.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the etcd certificate and key file parameters.\n          --etcd-certfile=<path/to/client-certificate-file>\n          --etcd-keyfile=<path/to/client-key-file>\n        scored: true\n\n      - id: 1.2.27\n        text: \"Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Automated)\"\n        audit: \"journalctl -m -u k3s | grep -A1 'Running kube-apiserver' | tail -n2\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--tls-cert-file\"\n              set: true\n            - flag: \"--tls-private-key-file\"\n              set: true\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection on the apiserver.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the TLS certificate and private key file parameters.\n          --tls-cert-file=<path/to/tls-certificate-file>\n          --tls-private-key-file=<path/to/tls-key-file>\n        scored: true\n\n      - id: 1.2.28\n        text: \"Ensure that the --client-ca-file argument is set as appropriate (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'client-ca-file'\"\n        tests:\n          test_items:\n            - flag: \"--client-ca-file\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection on the apiserver.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the client certificate authority file.\n          --client-ca-file=<path/to/client-ca-file>\n        scored: true\n\n      - id: 1.2.29\n        text: \"Ensure that the --etcd-cafile argument is set as appropriate (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'etcd-cafile'\"\n        tests:\n          test_items:\n            - flag: \"--etcd-cafile\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection between the apiserver and etcd.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the etcd certificate authority file parameter.\n          --etcd-cafile=<path/to/ca-file>\n        scored: true\n\n      - id: 1.2.30\n        text: \"Ensure that the --encryption-provider-config argument is set as appropriate (Manual)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'encryption-provider-config'\"\n        tests:\n          test_items:\n            - flag: \"--encryption-provider-config\"\n        remediation: |\n          Follow the Kubernetes documentation and configure a EncryptionConfig file.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --encryption-provider-config parameter to the path of that file.\n          For example, --encryption-provider-config=</path/to/EncryptionConfig/File>\n        scored: false\n\n      - id: 1.2.31\n        text: \"Ensure that encryption providers are appropriately configured (Manual)\"\n        audit: \"grep aescbc /path/to/encryption-config.json\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and configure a EncryptionConfig file.\n          In this file, choose aescbc, kms or secretbox as the encryption provider.\n        scored: false\n\n      - id: 1.2.32\n        text: \"Ensure that the API Server only makes use of Strong Cryptographic Ciphers (Manual)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'tls-cipher-suites'\"\n        tests:\n          test_items:\n            - flag: \"--tls-cipher-suites\"\n              compare:\n                op: valid_elements\n                value: \"TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,TLS_CHACHA20_POLY1305_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,TLS_RSA_WITH_3DES_EDE_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_256_GCM_SHA384\"\n        remediation: |\n          Edit the API server pod specification file /etc/kubernetes/manifests/kube-apiserver.yaml\n          on the control plane node and set the below parameter.\n          --tls-cipher-suites=TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,TLS_CHACHA20_POLY1305_SHA256,\n          TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,\n          TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,\n          TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,\n          TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,\n          TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,\n          TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,TLS_RSA_WITH_3DES_EDE_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA,\n          TLS_RSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_256_GCM_SHA384\n        scored: false\n\n  - id: 1.3\n    text: \"Controller Manager\"\n    checks:\n      - id: 1.3.1\n        text: \"Ensure that the --terminated-pod-gc-threshold argument is set as appropriate (Manual)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-controller-manager' | tail -n1 | grep 'terminated-pod-gc-threshold'\"\n        tests:\n          test_items:\n            - flag: \"--terminated-pod-gc-threshold\"\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the --terminated-pod-gc-threshold to an appropriate threshold,\n          for example, --terminated-pod-gc-threshold=10\n        scored: false\n\n      - id: 1.3.2\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-controller-manager' | tail -n1 | grep 'profiling'\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the below parameter.\n          --profiling=false\n        scored: true\n\n      - id: 1.3.3\n        text: \"Ensure that the --use-service-account-credentials argument is set to true (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-controller-manager' | tail -n1 | grep 'use-service-account-credentials'\"\n        tests:\n          test_items:\n            - flag: \"--use-service-account-credentials\"\n              compare:\n                op: noteq\n                value: false\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node to set the below parameter.\n          --use-service-account-credentials=true\n        scored: true\n\n      - id: 1.3.4\n        text: \"Ensure that the --service-account-private-key-file argument is set as appropriate (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-controller-manager' | tail -n1 | grep 'service-account-private-key-file'\"\n        tests:\n          test_items:\n            - flag: \"--service-account-private-key-file\"\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the --service-account-private-key-file parameter\n          to the private key file for service accounts.\n          --service-account-private-key-file=<filename>\n        scored: true\n\n      - id: 1.3.5\n        text: \"Ensure that the --root-ca-file argument is set as appropriate (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-controller-manager' | tail -n1 | grep 'root-ca-file'\"\n        tests:\n          test_items:\n            - flag: \"--root-ca-file\"\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the --root-ca-file parameter to the certificate bundle file`.\n          --root-ca-file=<path/to/file>\n        scored: true\n\n      - id: 1.3.6\n        text: \"Ensure that the RotateKubeletServerCertificate argument is set to true (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-controller-manager' | tail -n1 | grep 'RotateKubeletServerCertificate'\"\n        type: \"skip\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--feature-gates\"\n              compare:\n                op: nothave\n                value: \"RotateKubeletServerCertificate=false\"\n              set: true\n            - flag: \"--feature-gates\"\n              set: false\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the --feature-gates parameter to include RotateKubeletServerCertificate=true.\n          --feature-gates=RotateKubeletServerCertificate=true\n        scored: true\n\n      - id: 1.3.7\n        text: \"Ensure that the --bind-address argument is set to 127.0.0.1 (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--bind-address\"\n              compare:\n                op: eq\n                value: \"127.0.0.1\"\n              set: true\n            - flag: \"--bind-address\"\n              set: false\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and ensure the correct value for the --bind-address parameter\n        scored: true\n\n  - id: 1.4\n    text: \"Scheduler\"\n    checks:\n      - id: 1.4.1\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-scheduler' | tail -n1\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n              set: true\n        remediation: |\n          Edit the Scheduler pod specification file $schedulerconf file\n          on the control plane node and set the below parameter.\n          --profiling=false\n        scored: true\n\n      - id: 1.4.2\n        text: \"Ensure that the --bind-address argument is set to 127.0.0.1 (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-scheduler' | tail -n1 | grep 'bind-address'\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--bind-address\"\n              compare:\n                op: eq\n                value: \"127.0.0.1\"\n              set: true\n            - flag: \"--bind-address\"\n              set: false\n        remediation: |\n          Edit the Scheduler pod specification file $schedulerconf\n          on the control plane node and ensure the correct value for the --bind-address parameter\n        scored: true\n"
  },
  {
    "path": "cfg/k3s-cis-1.23/node.yaml",
    "content": "---\ncontrols:\nversion: \"k3s-cis-1.23\"\nid: 4\ntext: \"Worker Node Security Configuration\"\ntype: \"node\"\ngroups:\n  - id: 4.1\n    text: \"Worker Node Configuration Files\"\n    checks:\n      - id: 4.1.1\n        text: \"Ensure that the kubelet service file permissions are set to 644 or more restrictive (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletsvc; then stat -c permissions=%a $kubeletsvc; fi'' '\n        type: \"skip\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example, chmod 644 $kubeletsvc\n        scored: true\n\n      - id: 4.1.2\n        text: \"Ensure that the kubelet service file ownership is set to root:root (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletsvc; then stat -c %U:%G $kubeletsvc; fi'' '\n        type: \"skip\"\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chown root:root $kubeletsvc\n        scored: true\n\n      - id: 4.1.3\n        text: \"If proxy kubeconfig file exists ensure permissions are set to 644 or more restrictive (Manual)\"\n        audit: 'stat -c %a /var/lib/rancher/k3s/agent/kubeproxy.kubeconfig'\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"permissions\"\n              set: true\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chmod 644 $proxykubeconfig\n        scored: false\n\n      - id: 4.1.4\n        text: \"If proxy kubeconfig file exists ensure ownership is set to root:root (Manual)\"\n        audit: '/bin/sh -c ''if test -e /var/lib/rancher/k3s/agent/kubeproxy.kubeconfig; then stat -c %U:%G /var/lib/rancher/k3s/agent/kubeproxy.kubeconfig; fi'' '\n        tests:\n          bin_op: or\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example, chown root:root $proxykubeconfig\n        scored: false\n\n      - id: 4.1.5\n        text: \"Ensure that the --kubeconfig kubelet.conf file permissions are set to 644 or more restrictive (Automated)\"\n        audit: 'stat -c %a /var/lib/rancher/k3s/agent/kubelet.kubeconfig '\n        tests:\n          test_items:\n            - flag: \"644\"\n              compare:\n                op: eq\n                value: \"644\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chmod 644 $kubeletkubeconfig\n        scored: true\n\n      - id: 4.1.6\n        text: \"Ensure that the --kubeconfig kubelet.conf file ownership is set to root:root (Automated)\"\n        audit: 'stat -c %U:%G /var/lib/rancher/k3s/agent/kubelet.kubeconfig'\n        tests:\n          test_items:\n            - flag: \"root:root\"\n              compare:\n                op: eq\n                value: \"root:root\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chown root:root $kubeletkubeconfig\n        scored: true\n\n      - id: 4.1.7\n        text: \"Ensure that the certificate authorities file permissions are set to 644 or more restrictive (Manual)\"\n        audit: \"stat -c %a /var/lib/rancher/k3s/server/tls/server-ca.crt\"\n        tests:\n          test_items:\n            - flag: \"644\"\n              compare:\n                op: eq\n                value: \"644\"\n              set: true\n            - flag: \"640\"\n              compare:\n                op: eq\n                value: \"640\"\n              set: true\n            - flag: \"600\"\n              compare:\n                op: eq\n                value: \"600\"\n              set: true\n            - flag: \"444\"\n              compare:\n                op: eq\n                value: \"444\"\n              set: true\n            - flag: \"440\"\n              compare:\n                op: eq\n                value: \"440\"\n              set: true\n            - flag: \"400\"\n              compare:\n                op: eq\n                value: \"400\"\n              set: true\n            - flag: \"000\"\n              compare:\n                op: eq\n                value: \"000\"\n              set: true\n          bin_op: or\n        remediation: |\n          Run the following command to modify the file permissions of the\n          --client-ca-file chmod 644 <filename>\n        scored: true\n\n      - id: 4.1.8\n        text: \"Ensure that the client certificate authorities file ownership is set to root:root (Manual)\"\n        audit: \"stat -c %U:%G /var/lib/rancher/k3s/server/tls/client-ca.crt\"\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the following command to modify the ownership of the --client-ca-file.\n          chown root:root <filename>\n        scored: false\n\n      - id: 4.1.9\n        text: \"Ensure that the kubelet --config configuration file has permissions set to 644 or more restrictive (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletconf; then stat -c permissions=%a $kubeletconf; fi'' '\n        type: \"skip\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the following command (using the config file location identified in the Audit step)\n          chmod 644 $kubeletconf\n        scored: true\n\n      - id: 4.1.10\n        text: \"Ensure that the kubelet --config configuration file ownership is set to root:root (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletconf; then stat -c %U:%G $kubeletconf; fi'' '\n        type: \"skip\"\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the following command (using the config file location identified in the Audit step)\n          chown root:root $kubeletconf\n        scored: true\n\n  - id: 4.2\n    text: \"Kubelet\"\n    checks:\n      - id: 4.2.1\n        text: \"Ensure that the --anonymous-auth argument is set to false (Automated)\"\n        audit: '/bin/sh -c ''if test $(journalctl -m -u k3s -u k3s-agent | grep \"Running kubelet\" | wc -l) -gt 0; then journalctl -m -u k3s -u k3s-agent | grep \"Running kubelet\" | tail -n1 | grep \"anonymous-auth\" | grep -v grep; else echo \"--anonymous-auth=false\"; fi'' '\n        tests:\n          test_items:\n            - flag: \"--anonymous-auth\"\n              path: '{.authentication.anonymous.enabled}'\n              compare:\n                op: eq\n                value: false\n              set: true\n        remediation: |\n          If using a Kubelet config file, edit the file to set `authentication: anonymous: enabled` to\n          `false`.\n          If using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          `--anonymous-auth=false`\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.2\n        text: \"Ensure that the --authorization-mode argument is not set to AlwaysAllow (Automated)\"\n        audit: '/bin/sh -c ''if test $(journalctl -m -u k3s -u k3s-agent | grep \"Running kubelet\" | wc -l) -gt 0; then journalctl -m -u k3s -u k3s-agent | grep \"Running kubelet\" | tail -n1 | grep \"authorization-mode\" | grep -v grep; else echo \"--authorization-mode=Webhook\"; fi'' '\n        tests:\n          test_items:\n            - flag: --authorization-mode\n              path: '{.authorization.mode}'\n              compare:\n                op: nothave\n                value: AlwaysAllow\n              set: true\n        remediation: |\n          If using a Kubelet config file, edit the file to set `authorization.mode` to Webhook. If\n          using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_AUTHZ_ARGS variable.\n          --authorization-mode=Webhook\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.3\n        text: \"Ensure that the --client-ca-file argument is set as appropriate (Automated)\"\n        audit: '/bin/sh -c ''if test $(journalctl -m -u k3s -u k3s-agent | grep \"Running kubelet\" | wc -l) -gt 0; then journalctl -m -u k3s -u k3s-agent | grep \"Running kubelet\" | tail -n1 | grep \"client-ca-file\" | grep -v grep; else echo \"--client-ca-file=/var/lib/rancher/k3s/server/tls/request-header-ca.crt\"; fi'' '\n        tests:\n          test_items:\n            - flag: --client-ca-file\n              path: '{.authentication.x509.clientCAFile}'\n              set: true\n        remediation: |\n          If using a Kubelet config file, edit the file to set `authentication.x509.clientCAFile` to\n          the location of the client CA file.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_AUTHZ_ARGS variable.\n          --client-ca-file=<path/to/client-ca-file>\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.4\n        text: \"Ensure that the --read-only-port argument is set to 0 (Manual)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kubelet' | tail -n1 | grep 'read-only-port' \"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--read-only-port\"\n              path: '{.readOnlyPort}'\n              compare:\n                op: eq\n                value: 0\n            - flag: \"--read-only-port\"\n              path: '{.readOnlyPort}'\n              set: false\n        remediation: |\n          If using a Kubelet config file, edit the file to set `readOnlyPort` to 0.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --read-only-port=0\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.5\n        text: \"Ensure that the --streaming-connection-idle-timeout argument is not set to 0 (Manual)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kubelet' | tail -n1 | grep 'streaming-connection-idle-timeout'\"\n        tests:\n          test_items:\n            - flag: --streaming-connection-idle-timeout\n              path: '{.streamingConnectionIdleTimeout}'\n              compare:\n                op: noteq\n                value: 0\n            - flag: --streaming-connection-idle-timeout\n              path: '{.streamingConnectionIdleTimeout}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to set `streamingConnectionIdleTimeout` to a\n          value other than 0.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --streaming-connection-idle-timeout=5m\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.6\n        text: \"Ensure that the --protect-kernel-defaults argument is set to true (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kubelet' | tail -n1 | grep 'protect-kernel-defaults'\"\n        type: \"skip\"\n        tests:\n          test_items:\n            - flag: --protect-kernel-defaults\n              path: '{.protectKernelDefaults}'\n              compare:\n                op: eq\n                value: true\n              set: true\n        remediation: |\n          If using a Kubelet config file, edit the file to set `protectKernelDefaults` to `true`.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --protect-kernel-defaults=true\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.7\n        text: \"Ensure that the --make-iptables-util-chains argument is set to true (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kubelet' | tail -n1 | grep 'make-iptables-util-chains'\"\n        type: \"skip\"\n        tests:\n          test_items:\n            - flag: --make-iptables-util-chains\n              path: '{.makeIPTablesUtilChains}'\n              compare:\n                op: eq\n                value: true\n              set: true\n            - flag: --make-iptables-util-chains\n              path: '{.makeIPTablesUtilChains}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to set `makeIPTablesUtilChains` to `true`.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          remove the --make-iptables-util-chains argument from the\n          KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.8\n        text: \"Ensure that the --hostname-override argument is not set (Manual)\"\n        # This is one of those properties that can only be set as a command line argument.\n        # To check if the property is set as expected, we need to parse the kubelet command\n        # instead reading the Kubelet Configuration file.\n        audit: \"/bin/ps -fC $kubeletbin \"\n        type: \"skip\"\n        tests:\n          test_items:\n            - flag: --hostname-override\n              set: false\n        remediation: |\n          Edit the kubelet service file $kubeletsvc\n          on each worker node and remove the --hostname-override argument from the\n          KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.9\n        text: \"Ensure that the --event-qps argument is set to 0 or a level which ensures appropriate event capture (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        type: \"manual\"\n        tests:\n          test_items:\n            - flag: --event-qps\n              path: '{.eventRecordQPS}'\n              compare:\n                op: eq\n                value: 0\n        remediation: |\n          If using a Kubelet config file, edit the file to set `eventRecordQPS` to an appropriate level.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.10\n        text: \"Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Manual)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kubelet' | tail -n1\"\n        tests:\n          test_items:\n            - flag: --tls-cert-file\n              path: '/var/lib/rancher/k3s/agent/serving-kubelet.crt'\n            - flag: --tls-private-key-file\n              path: '/var/lib/rancher/k3s/agent/serving-kubelet.key'\n        remediation: |\n          If using a Kubelet config file, edit the file to set `tlsCertFile` to the location\n          of the certificate file to use to identify this Kubelet, and `tlsPrivateKeyFile`\n          to the location of the corresponding private key file.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameters in KUBELET_CERTIFICATE_ARGS variable.\n          --tls-cert-file=<path/to/tls-certificate-file>\n          --tls-private-key-file=<path/to/tls-key-file>\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.11\n        text: \"Ensure that the --rotate-certificates argument is not set to false (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        type: \"skip\"\n        tests:\n          test_items:\n            - flag: --rotate-certificates\n              path: '{.rotateCertificates}'\n              compare:\n                op: eq\n                value: true\n            - flag: --rotate-certificates\n              path: '{.rotateCertificates}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to add the line `rotateCertificates` to `true` or\n          remove it altogether to use the default value.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          remove --rotate-certificates=false argument from the KUBELET_CERTIFICATE_ARGS\n          variable.\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.12\n        text: \"Verify that the RotateKubeletServerCertificate argument is set to true (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        type: \"skip\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: RotateKubeletServerCertificate\n              path: '{.featureGates.RotateKubeletServerCertificate}'\n              compare:\n                op: nothave\n                value: false\n            - flag: RotateKubeletServerCertificate\n              path: '{.featureGates.RotateKubeletServerCertificate}'\n              set: false\n        remediation: |\n          Edit the kubelet service file $kubeletsvc\n          on each worker node and set the below parameter in KUBELET_CERTIFICATE_ARGS variable.\n          --feature-gates=RotateKubeletServerCertificate=true\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.13\n        text: \"Ensure that the Kubelet only makes use of Strong Cryptographic Ciphers (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        type: \"manual\"\n        tests:\n          test_items:\n            - flag: --tls-cipher-suites\n              path: '{range .tlsCipherSuites[:]}{}{'',''}{end}'\n              compare:\n                op: valid_elements\n                value: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\n        remediation: |\n          If using a Kubelet config file, edit the file to set `tlsCipherSuites` to\n          TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\n          or to a subset of these values.\n          If using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the --tls-cipher-suites parameter as follows, or to a subset of these values.\n          --tls-cipher-suites=TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n"
  },
  {
    "path": "cfg/k3s-cis-1.23/policies.yaml",
    "content": "---\ncontrols:\nversion: \"k3s-cis-1.23\"\nid: 5\ntext: \"Kubernetes Policies\"\ntype: \"policies\"\ngroups:\n  - id: 5.1\n    text: \"RBAC and Service Accounts\"\n    checks:\n      - id: 5.1.1\n        text: \"Ensure that the cluster-admin role is only used where required (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Identify all clusterrolebindings to the cluster-admin role. Check if they are used and\n          if they need this role or if they could use a role with fewer privileges.\n          Where possible, first bind users to a lower privileged role and then remove the\n          clusterrolebinding to the cluster-admin role :\n          kubectl delete clusterrolebinding [name]\n        scored: false\n\n      - id: 5.1.2\n        text: \"Minimize access to secrets (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove get, list and watch access to Secret objects in the cluster.\n        scored: false\n\n      - id: 5.1.3\n        text: \"Minimize wildcard use in Roles and ClusterRoles (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible replace any use of wildcards in clusterroles and roles with specific\n          objects or actions.\n        scored: false\n\n      - id: 5.1.4\n        text: \"Minimize access to create pods (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove create access to pod objects in the cluster.\n        scored: false\n\n      - id: 5.1.5\n        text: \"Ensure that default service accounts are not actively used. (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Create explicit service accounts wherever a Kubernetes workload requires specific access\n          to the Kubernetes API server.\n          Modify the configuration of each default service account to include this value\n          automountServiceAccountToken: false\n        scored: false\n\n      - id: 5.1.6\n        text: \"Ensure that Service Account Tokens are only mounted where necessary (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Modify the definition of pods and service accounts which do not need to mount service\n          account tokens to disable it.\n        scored: false\n\n      - id: 5.1.7\n        text: \"Avoid use of system:masters group (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Remove the system:masters group from all users in the cluster.\n        scored: false\n\n      - id: 5.1.8\n        text: \"Limit use of the Bind, Impersonate and Escalate permissions in the Kubernetes cluster (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove the impersonate, bind and escalate rights from subjects.\n        scored: false\n\n  - id: 5.2\n    text: \"Pod Security Standards\"\n    checks:\n      - id: 5.2.1\n        text: \"Ensure that the cluster has at least one active policy control mechanism in place (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that either Pod Security Admission or an external policy control system is in place\n          for every namespace which contains user workloads.\n        scored: false\n\n      - id: 5.2.2\n        text: \"Minimize the admission of privileged containers (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of privileged containers.\n        scored: false\n\n      - id: 5.2.3\n        text: \"Minimize the admission of containers wishing to share the host process ID namespace (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of `hostPID` containers.\n        scored: false\n\n      - id: 5.2.4\n        text: \"Minimize the admission of containers wishing to share the host IPC namespace (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of `hostIPC` containers.\n        scored: false\n\n      - id: 5.2.5\n        text: \"Minimize the admission of containers wishing to share the host network namespace (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of `hostNetwork` containers.\n        scored: false\n\n      - id: 5.2.6\n        text: \"Minimize the admission of containers with allowPrivilegeEscalation (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers with `.spec.allowPrivilegeEscalation` set to `true`.\n        scored: false\n\n      - id: 5.2.7\n        text: \"Minimize the admission of root containers (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Create a policy for each namespace in the cluster, ensuring that either `MustRunAsNonRoot`\n          or `MustRunAs` with the range of UIDs not including 0, is set.\n        scored: false\n\n      - id: 5.2.8\n        text: \"Minimize the admission of containers with the NET_RAW capability (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers with the `NET_RAW` capability.\n        scored: false\n\n      - id: 5.2.9\n        text: \"Minimize the admission of containers with added capabilities (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that `allowedCapabilities` is not present in policies for the cluster unless\n          it is set to an empty array.\n        scored: false\n\n      - id: 5.2.10\n        text: \"Minimize the admission of containers with capabilities assigned (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Review the use of capabilites in applications running on your cluster. Where a namespace\n          contains applications which do not require any Linux capabities to operate consider adding\n          a PSP which forbids the admission of containers which do not drop all capabilities.\n        scored: false\n\n      - id: 5.2.11\n        text: \"Minimize the admission of Windows HostProcess containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers that have `.securityContext.windowsOptions.hostProcess` set to `true`.\n        scored: false\n\n      - id: 5.2.12\n        text: \"Minimize the admission of HostPath volumes (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers with `hostPath` volumes.\n        scored: false\n\n      - id: 5.2.13\n        text: \"Minimize the admission of containers which use HostPorts (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers which use `hostPort` sections.\n        scored: false\n\n  - id: 5.3\n    text: \"Network Policies and CNI\"\n    checks:\n      - id: 5.3.1\n        text: \"Ensure that the CNI in use supports NetworkPolicies (Manual)\"\n        type: \"manual\"\n        remediation: |\n          If the CNI plugin in use does not support network policies, consideration should be given to\n          making use of a different plugin, or finding an alternate mechanism for restricting traffic\n          in the Kubernetes cluster.\n        scored: false\n\n      - id: 5.3.2\n        text: \"Ensure that all Namespaces have NetworkPolicies defined (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the documentation and create NetworkPolicy objects as you need them.\n        scored: false\n\n  - id: 5.4\n    text: \"Secrets Management\"\n    checks:\n      - id: 5.4.1\n        text: \"Prefer using Secrets as files over Secrets as environment variables (Manual)\"\n        type: \"manual\"\n        remediation: |\n          If possible, rewrite application code to read Secrets from mounted secret files, rather than\n          from environment variables.\n        scored: false\n\n      - id: 5.4.2\n        text: \"Consider external secret storage (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Refer to the Secrets management options offered by your cloud provider or a third-party\n          secrets management solution.\n        scored: false\n\n  - id: 5.5\n    text: \"Extensible Admission Control\"\n    checks:\n      - id: 5.5.1\n        text: \"Configure Image Provenance using ImagePolicyWebhook admission controller (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and setup image provenance.\n        scored: false\n\n  - id: 5.7\n    text: \"General Policies\"\n    checks:\n      - id: 5.7.1\n        text: \"Create administrative boundaries between resources using namespaces (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the documentation and create namespaces for objects in your deployment as you need\n          them.\n        scored: false\n\n      - id: 5.7.2\n        text: \"Ensure that the seccomp profile is set to docker/default in your Pod definitions (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Use `securityContext` to enable the docker/default seccomp profile in your pod definitions.\n          An example is as below:\n            securityContext:\n              seccompProfile:\n                type: RuntimeDefault\n        scored: false\n\n      - id: 5.7.3\n        text: \"Apply SecurityContext to your Pods and Containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and apply SecurityContexts to your Pods. For a\n          suggested list of SecurityContexts, you may refer to the CIS Security Benchmark for Docker\n          Containers.\n        scored: false\n\n      - id: 5.7.4\n        text: \"The default namespace should not be used (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that namespaces are created to allow for appropriate segregation of Kubernetes\n          resources and that all new resources are created in a specific namespace.\n        scored: false\n"
  },
  {
    "path": "cfg/k3s-cis-1.24/config.yaml",
    "content": "---\n## Version-specific settings that override the values in cfg/config.yaml\n\nmaster:\n  components:\n    - apiserver\n    - scheduler\n    - controllermanager\n    - etcd\n    - policies\n\n  apiserver:\n    bins:\n      - containerd\n\n  scheduler:\n    bins:\n      - containerd\n    kubeconfig:\n      - /var/lib/rancher/k3s/server/cred/scheduler.kubeconfig\n\n  controllermanager:\n    bins:\n      - containerd\n    kubeconfig:\n      - /var/lib/rancher/k3s/server/cred/controller.kubeconfig\n\n\n  etcd:\n    bins:\n      - containerd\n\netcd:\n  components:\n    - etcd\n\n  etcd:\n    confs: /var/lib/rancher/k3s/server/db/etcd/config\n\nnode:\n  components:\n    - kubelet\n    - proxy\n\n  kubelet:\n    bins:\n      - containerd\n    defaultkubeconfig: /var/lib/rancher/k3s/agent/kubelet.kubeconfig\n    defaultcafile: /var/lib/rancher/k3s/agent/client-ca.crt\n\n  proxy:\n    bins:\n      - containerd\n    defaultkubeconfig: /var/lib/rancher/k3s/agent/kubeproxy.kubeconfig\n\npolicies:\n  components:\n    - policies\n"
  },
  {
    "path": "cfg/k3s-cis-1.24/controlplane.yaml",
    "content": "---\ncontrols:\nversion: \"k3s-cis-1.24\"\nid: 3\ntext: \"Control Plane Configuration\"\ntype: \"controlplane\"\ngroups:\n  - id: 3.1\n    text: \"Authentication and Authorization\"\n    checks:\n      - id: 3.1.1\n        text: \"Client certificate authentication should not be used for users (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Alternative mechanisms provided by Kubernetes such as the use of OIDC should be\n          implemented in place of client certificates.\n        scored: false\n\n  - id: 3.2\n    text: \"Logging\"\n    checks:\n      - id: 3.2.1\n        text: \"Ensure that a minimal audit policy is created (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'audit-policy-file'\"\n        tests:\n          test_items:\n            - flag: \"--audit-policy-file\"\n              set: true\n        remediation: |\n          Create an audit policy file for your cluster.\n        scored: false\n\n      - id: 3.2.2\n        text: \"Ensure that the audit policy covers key security concerns (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Review the audit policy provided for the cluster and ensure that it covers\n          at least the following areas,\n          - Access to Secrets managed by the cluster. Care should be taken to only\n            log Metadata for requests to Secrets, ConfigMaps, and TokenReviews, in\n            order to avoid risk of logging sensitive data.\n          - Modification of Pod and Deployment objects.\n          - Use of `pods/exec`, `pods/portforward`, `pods/proxy` and `services/proxy`.\n          For most requests, minimally logging at the Metadata level is recommended\n          (the most basic level of logging).\n        scored: false\n"
  },
  {
    "path": "cfg/k3s-cis-1.24/etcd.yaml",
    "content": "---\ncontrols:\nversion: \"k3s-cis-1.24\"\nid: 2\ntext: \"Etcd Node Configuration\"\ntype: \"etcd\"\ngroups:\n  - id: 2\n    text: \"Etcd Node Configuration\"\n    checks:\n      - id: 2.1\n        text: \"Ensure that the --cert-file and --key-file arguments are set as appropriate (Automated)\"\n        audit_config: \"cat $etcdconf\"\n        tests:\n          bin_op: and\n          test_items:\n            - path: \"{.client-transport-security.cert-file}\"\n              compare:\n                op: eq\n                value: \"/var/lib/rancher/k3s/server/tls/etcd/server-client.crt\"\n            - path: \"{.client-transport-security.key-file}\"\n              compare:\n                op: eq\n                value: \"/var/lib/rancher/k3s/server/tls/etcd/server-client.key\"\n        remediation: |\n          If running on with sqlite or a external DB, etcd checks are Not Applicable.\n          When running with embedded-etcd, K3s generates cert and key files for etcd.\n          These are located in /var/lib/rancher/k3s/server/tls/etcd/.\n          If this check fails, ensure that the configuration file $etcdconf\n          has not been modified to use custom cert and key files.\n        scored: false\n\n      - id: 2.2\n        text: \"Ensure that the --client-cert-auth argument is set to true (Automated)\"\n        audit_config: \"cat $etcdconf\"\n        tests:\n          test_items:\n            - path: \"{.client-transport-security.client-cert-auth}\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          If running on with sqlite or a external DB, etcd checks are Not Applicable.\n          When running with embedded-etcd, K3s sets the --client-cert-auth parameter to true.\n          If this check fails, ensure that the configuration file $etcdconf\n          has not been modified to disable client certificate authentication.\n        scored: false\n\n      - id: 2.3\n        text: \"Ensure that the --auto-tls argument is not set to true (Automated)\"\n        audit_config: \"cat $etcdconf\"\n        tests:\n          bin_op: or\n          test_items:\n            - path: \"{.client-transport-security.auto-tls}\"\n              compare:\n                op: eq\n                value: false\n            - path: \"{.client-transport-security.auto-tls}\"\n              set: false\n        remediation: |\n          If running on with sqlite or a external DB, etcd checks are Not Applicable.\n          When running with embedded-etcd, K3s does not set the --auto-tls parameter.\n          If this check fails, edit the etcd pod specification file $etcdconf on the master\n          node and either remove the --auto-tls parameter or set it to false.\n          client-transport-security:\n            auto-tls: false\n        scored: false\n\n      - id: 2.4\n        text: \"Ensure that the --peer-cert-file and --peer-key-file arguments are set as appropriate (Automated)\"\n        audit_config: \"cat $etcdconf\"\n        tests:\n          bin_op: and\n          test_items:\n            - path: \"{.peer-transport-security.cert-file}\"\n              compare:\n                op: eq\n                value: \"/var/lib/rancher/k3s/server/tls/etcd/peer-server-client.crt\"\n            - path: \"{.peer-transport-security.key-file}\"\n              compare:\n                op: eq\n                value: \"/var/lib/rancher/k3s/server/tls/etcd/peer-server-client.key\"\n        remediation: |\n          If running on with sqlite or a external DB, etcd checks are Not Applicable.\n          When running with embedded-etcd, K3s generates peer cert and key files for etcd.\n          These are located in /var/lib/rancher/k3s/server/tls/etcd/.\n          If this check fails, ensure that the configuration file $etcdconf\n          has not been modified to use custom peer cert and key files.\n        scored: false\n\n      - id: 2.5\n        text: \"Ensure that the --peer-client-cert-auth argument is set to true (Automated)\"\n        audit_config: \"cat $etcdconf\"\n        tests:\n          test_items:\n            - path: \"{.peer-transport-security.client-cert-auth}\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          If running on with sqlite or a external DB, etcd checks are Not Applicable.\n          When running with embedded-etcd, K3s sets the --peer-cert-auth parameter to true.\n          If this check fails, ensure that the configuration file $etcdconf\n          has not been modified to disable peer client certificate authentication.\n        scored: false\n\n      - id: 2.6\n        text: \"Ensure that the --peer-auto-tls argument is not set to true (Automated)\"\n        audit_config: \"cat $etcdconf\"\n        tests:\n          bin_op: or\n          test_items:\n            - path: \"{.peer-transport-security.auto-tls}\"\n              compare:\n                op: eq\n                value: false\n            - path: \"{.peer-transport-security.auto-tls}\"\n              set: false\n        remediation: |\n          If running on with sqlite or a external DB, etcd checks are Not Applicable.\n          When running with embedded-etcd, K3s does not set the --peer-auto-tls parameter.\n          If this check fails, edit the etcd pod specification file $etcdconf on the master\n          node and either remove the --peer-auto-tls parameter or set it to false.\n          peer-transport-security:\n            auto-tls: false\n        scored: false\n\n      - id: 2.7\n        text: \"Ensure that a unique Certificate Authority is used for etcd (Automated)\"\n        audit_config: \"cat $etcdconf\"\n        tests:\n          test_items:\n            - path: \"{.peer-transport-security.trusted-ca-file}\"\n              compare:\n                op: eq\n                value: \"/var/lib/rancher/k3s/server/tls/etcd/peer-ca.crt\"\n        remediation: |\n          If running on with sqlite or a external DB, etcd checks are Not Applicable.\n          When running with embedded-etcd, K3s generates a unique certificate authority for etcd.\n          This is located at /var/lib/rancher/k3s/server/tls/etcd/peer-ca.crt.\n          If this check fails, ensure that the configuration file $etcdconf\n          has not been modified to use a shared certificate authority.\n        scored: false\n"
  },
  {
    "path": "cfg/k3s-cis-1.24/master.yaml",
    "content": "---\ncontrols:\nversion: \"k3s-cis-1.24\"\nid: 1\ntext: \"Control Plane Security Configuration\"\ntype: \"master\"\ngroups:\n  - id: 1.1\n    text: \"Control Plane Node Configuration Files\"\n    checks:\n      - id: 1.1.1\n        text: \"Ensure that the API server pod specification file permissions are set to 644 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $apiserverconf; then stat -c permissions=%a $apiserverconf; fi'\"\n        type: \"skip\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Not Applicable.\n          By default, K3s embeds the api server within the k3s process. There is no API server pod specification file.\n        scored: true\n\n      - id: 1.1.2\n        text: \"Ensure that the API server pod specification file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $apiserverconf; then stat -c %U:%G $apiserverconf; fi'\"\n        type: \"skip\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Not Applicable.\n          By default, K3s embeds the api server within the k3s process. There is no API server pod specification file.\n        scored: true\n\n      - id: 1.1.3\n        text: \"Ensure that the controller manager pod specification file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerconf; then stat -c permissions=%a $controllermanagerconf; fi'\"\n        type: \"skip\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Not Applicable.\n          By default, K3s embeds the controller manager within the k3s process. There is no controller manager pod specification file.\n        scored: true\n\n      - id: 1.1.4\n        text: \"Ensure that the controller manager pod specification file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerconf; then stat -c %U:%G $controllermanagerconf; fi'\"\n        type: \"skip\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Not Applicable.\n          By default, K3s embeds the controller manager within the k3s process. There is no controller manager pod specification file.\n        scored: true\n\n      - id: 1.1.5\n        text: \"Ensure that the scheduler pod specification file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerconf; then stat -c permissions=%a $schedulerconf; fi'\"\n        type: \"skip\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Not Applicable.\n          By default, K3s embeds the scheduler within the k3s process. There is no scheduler pod specification file.\n        scored: true\n\n      - id: 1.1.6\n        text: \"Ensure that the scheduler pod specification file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerconf; then stat -c %U:%G $schedulerconf; fi'\"\n        type: \"skip\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Not Applicable.\n          By default, K3s embeds the scheduler within the k3s process. There is no scheduler pod specification file.\n        scored: true\n\n      - id: 1.1.7\n        text: \"Ensure that the etcd pod specification file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $etcdconf; then stat -c permissions=%a $etcdconf; fi'\"\n        type: \"skip\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Not Applicable.\n          By default, K3s embeds etcd within the k3s process. There is no etcd pod specification file.\n        scored: true\n\n      - id: 1.1.8\n        text: \"Ensure that the etcd pod specification file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $etcdconf; then stat -c %U:%G $etcdconf; fi'\"\n        type: \"skip\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Not Applicable.\n          By default, K3s embeds etcd within the k3s process. There is no etcd pod specification file.\n        scored: true\n\n      - id: 1.1.9\n        text: \"Ensure that the Container Network Interface file permissions are set to 600 or more restrictive (Automated)\"\n        audit: find /var/lib/cni/networks -type f ! -name lock 2> /dev/null | xargs --no-run-if-empty stat -c permissions=%a\n        type: \"skip\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Not Applicable.\n          The default K3s CNI, flannel, does not create any files in /var/lib/cni/networks.\n        scored: false\n\n      - id: 1.1.10\n        text: \"Ensure that the Container Network Interface file ownership is set to root:root (Automated)\"\n        audit: find /var/lib/cni/networks -type f 2> /dev/null | xargs --no-run-if-empty stat -c %U:%G\\\n        type: \"skip\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Not Applicable.\n          The default K3s CNI, flannel, does not create any files in /var/lib/cni/networks.\n        scored: true\n\n      - id: 1.1.11\n        text: \"Ensure that the etcd data directory permissions are set to 700 or more restrictive (Automated)\"\n        audit: |\n          if [ \"$(journalctl -m -u k3s | grep -m1 'Managed etcd cluster' | wc -l)\" -gt 0 ]; then\n            stat -c permissions=%a /var/lib/rancher/k3s/server/db/etcd\n          else\n            echo \"permissions=700\"\n          fi\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"700\"\n        remediation: |\n          On the etcd server node, get the etcd data directory, passed as an argument --data-dir,\n          from the command 'ps -ef | grep etcd'.\n          Run the below command (based on the etcd data directory found above). For example,\n          chmod 700 /var/lib/etcd\n        scored: true\n\n      - id: 1.1.12\n        text: \"Ensure that the etcd data directory ownership is set to etcd:etcd (Automated)\"\n        audit: ps -ef | grep $etcdbin | grep -- --data-dir | sed 's%.*data-dir[= ]\\([^ ]*\\).*%\\1%' | xargs stat -c %U:%G\n        type: \"skip\"\n        tests:\n          test_items:\n            - flag: \"etcd:etcd\"\n        remediation: |\n          Not Applicable.\n          For K3s, etcd is embedded within the k3s process. There is no separate etcd process.\n          Therefore the etcd data directory ownership is managed by the k3s process and should be root:root.\n        scored: true\n\n      - id: 1.1.13\n        text: \"Ensure that the admin.conf file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e /var/lib/rancher/k3s/server/cred/admin.kubeconfig; then stat -c permissions=%a /var/lib/rancher/k3s/server/cred/admin.kubeconfig; fi'\"\n        type: \"skip\"\n        tests:\n          test_items:\n            - flag: \"600\"\n              compare:\n                op: eq\n                value: \"600\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chmod 600 /var/lib/rancher/k3s/server/cred/admin.kubeconfig\n        scored: true\n\n      - id: 1.1.14\n        text: \"Ensure that the admin.conf file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e /var/lib/rancher/k3s/server/cred/admin.kubeconfig; then stat -c %U:%G /var/lib/rancher/k3s/server/cred/admin.kubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n              compare:\n                op: eq\n                value: \"root:root\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chown root:root /var/lib/rancher/k3s/server/cred/admin.kubeconfig\n        scored: true\n\n      - id: 1.1.15\n        text: \"Ensure that the scheduler.conf file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerkubeconfig; then stat -c permissions=%a $schedulerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod 600 $schedulerkubeconfig\n        scored: true\n\n      - id: 1.1.16\n        text: \"Ensure that the scheduler.conf file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerkubeconfig; then stat -c %U:%G $schedulerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root $schedulerkubeconfig\n        scored: true\n\n      - id: 1.1.17\n        text: \"Ensure that the controller-manager.conf file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerkubeconfig; then stat -c permissions=%a $controllermanagerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod 600 $controllermanagerkubeconfig\n        scored: true\n\n      - id: 1.1.18\n        text: \"Ensure that the controller-manager.conf file ownership is set to root:root (Automated)\"\n        audit: \"stat -c %U:%G /var/lib/rancher/k3s/server/tls\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n              compare:\n                op: eq\n                value: \"root:root\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root $controllermanagerkubeconfig\n        scored: true\n\n      - id: 1.1.19\n        text: \"Ensure that the Kubernetes PKI directory and file ownership is set to root:root (Automated)\"\n        audit: \"find /var/lib/rancher/k3s/server/tls | xargs stat -c %U:%G\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown -R root:root /etc/kubernetes/pki/\n        scored: true\n\n      - id: 1.1.20\n        text: \"Ensure that the Kubernetes PKI certificate file permissions are set to 600 or more restrictive (Manual)\"\n        audit: \"/bin/sh -c 'stat -c permissions=%a /var/lib/rancher/k3s/server/tls/*.crt'\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chmod -R 600 /var/lib/rancher/k3s/server/tls/*.crt\n        scored: false\n\n      - id: 1.1.21\n        text: \"Ensure that the Kubernetes PKI key file permissions are set to 600 (Automated)\"\n        audit: \"/bin/sh -c 'stat -c permissions=%a /var/lib/rancher/k3s/server/tls/*.key'\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chmod -R 600 /var/lib/rancher/k3s/server/tls/*.key\n        scored: true\n\n  - id: 1.2\n    text: \"API Server\"\n    checks:\n      - id: 1.2.1\n        text: \"Ensure that the --anonymous-auth argument is set to false (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'anonymous-auth'\"\n        tests:\n          test_items:\n            - flag: \"--anonymous-auth\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          By default, K3s sets the --anonymous-auth argument to false. If it is set to true,\n          edit the K3s config file /etc/rancher/k3s/config.yaml and remove anything similar to below.\n          kube-apiserver-arg:\n            - \"anonymous-auth=true\"\n        scored: true\n\n      - id: 1.2.2\n        text: \"Ensure that the --token-auth-file parameter is not set (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1\"\n        tests:\n          test_items:\n            - flag: \"--token-auth-file\"\n              set: false\n        remediation: |\n          Follow the documentation and configure alternate mechanisms for authentication.\n          If this check fails, edit the K3s config file /etc/rancher/k3s/config.yaml and remove anything similar to below.\n          kube-apiserver-arg:\n            - \"token-auth-file=<path>\"\n        scored: true\n\n      - id: 1.2.3\n        text: \"Ensure that the --DenyServiceExternalIPs is not set (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: nothave\n                value: \"DenyServiceExternalIPs\"\n            - flag: \"--enable-admission-plugins\"\n              set: false\n        remediation: |\n          By default, K3s does not set DenyServiceExternalIPs.\n          If this check fails, edit the K3s config file /etc/rancher/k3s/config.yaml, remove any lines like below.\n          kube-apiserver-arg:\n            - \"enable-admission-plugins=DenyServiceExternalIPs\"\n        scored: true\n\n      - id: 1.2.4\n        text: \"Ensure that the --kubelet-https argument is set to true (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1\"\n        type: \"skip\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--kubelet-https\"\n              compare:\n                op: eq\n                value: true\n            - flag: \"--kubelet-https\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and remove the --kubelet-https parameter.\n        scored: true\n\n      - id: 1.2.5\n        text: \"Ensure that the --kubelet-client-certificate and --kubelet-client-key arguments are set as appropriate (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'kubelet-certificate-authority'\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--kubelet-client-certificate\"\n            - flag: \"--kubelet-client-key\"\n        remediation: |\n          By default, K3s automatically provides the kubelet client certificate and key.\n          They are generated and located at /var/lib/rancher/k3s/server/tls/client-kube-apiserver.crt and /var/lib/rancher/k3s/server/tls/client-kube-apiserver.key\n          If for some reason you need to provide your own certificate and key, you can set the\n          below parameters in the K3s config file /etc/rancher/k3s/config.yaml.\n          kube-apiserver-arg:\n            - \"kubelet-client-certificate=<path/to/client-cert-file>\"\n            - \"kubelet-client-key=<path/to/client-key-file>\"\n        scored: true\n\n      - id: 1.2.6\n        text: \"Ensure that the --kubelet-certificate-authority argument is set as appropriate (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'kubelet-certificate-authority'\"\n        tests:\n          test_items:\n            - flag: \"--kubelet-certificate-authority\"\n        remediation: |\n          Follow the Kubernetes documentation and setup the TLS connection between\n          the apiserver and kubelets. Then, edit the API server pod specification file\n          $apiserverconf on the control plane node and set the\n          --kubelet-certificate-authority parameter to the path to the cert file for the certificate authority.\n          --kubelet-certificate-authority=<ca-string>\n        scored: true\n\n      - id: 1.2.7\n        text: \"Ensure that the --authorization-mode argument is not set to AlwaysAllow (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'authorization-mode'\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: nothave\n                value: \"AlwaysAllow\"\n        remediation: |\n          By default, K3s does not set the --authorization-mode to AlwaysAllow.\n          If this check fails, edit K3s config file /etc/rancher/k3s/config.yaml, remove any lines like below.\n          kube-apiserver-arg:\n            - \"authorization-mode=AlwaysAllow\"\n        scored: true\n\n      - id: 1.2.8\n        text: \"Ensure that the --authorization-mode argument includes Node (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'authorization-mode'\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: has\n                value: \"Node\"\n        remediation: |\n          By default, K3s sets the --authorization-mode to Node and RBAC.\n          If this check fails, edit the K3s config file /etc/rancher/k3s/config.yaml,\n          ensure that you are not overriding authorization-mode.\n        scored: true\n\n      - id: 1.2.9\n        text: \"Ensure that the --authorization-mode argument includes RBAC (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'authorization-mode'\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: has\n                value: \"RBAC\"\n        remediation: |\n          By default, K3s sets the --authorization-mode to Node and RBAC.\n          If this check fails, edit the K3s config file /etc/rancher/k3s/config.yaml,\n          ensure that you are not overriding authorization-mode.\n        scored: true\n\n      - id: 1.2.10\n        text: \"Ensure that the admission control plugin EventRateLimit is set (Manual)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'enable-admission-plugins'\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"EventRateLimit\"\n        remediation: |\n          Follow the Kubernetes documentation and set the desired limits in a configuration file.\n          Then, edit the K3s config file /etc/rancher/k3s/config.yaml and set the below parameters.\n          kube-apiserver-arg:\n            - \"enable-admission-plugins=...,EventRateLimit,...\"\n            - \"admission-control-config-file=<path/to/configuration/file>\"\n        scored: false\n\n      - id: 1.2.11\n        text: \"Ensure that the admission control plugin AlwaysAdmit is not set (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'enable-admission-plugins'\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: nothave\n                value: AlwaysAdmit\n            - flag: \"--enable-admission-plugins\"\n              set: false\n        remediation: |\n          By default, K3s does not set the --enable-admission-plugins to AlwaysAdmit.\n          If this check fails, edit K3s config file /etc/rancher/k3s/config.yaml, remove any lines like below.\n          kube-apiserver-arg:\n            - \"enable-admission-plugins=AlwaysAdmit\"\n        scored: true\n\n      - id: 1.2.12\n        text: \"Ensure that the admission control plugin AlwaysPullImages is set (Manual)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'enable-admission-plugins'\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"AlwaysPullImages\"\n        remediation: |\n          Permissive, per CIS guidelines,\n          \"This setting could impact offline or isolated clusters, which have images pre-loaded and\n          do not have access to a registry to pull in-use images. This setting is not appropriate for\n          clusters which use this configuration.\"\n          Edit the K3s config file /etc/rancher/k3s/config.yaml and set the below parameter.\n          kube-apiserver-arg:\n            - \"enable-admission-plugins=...,AlwaysPullImages,...\"\n        scored: false\n\n      - id: 1.2.13\n        text: \"Ensure that the admission control plugin SecurityContextDeny is set if PodSecurityPolicy is not used (Manual)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'enable-admission-plugins'\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"SecurityContextDeny\"\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"PodSecurityPolicy\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --enable-admission-plugins parameter to include\n          SecurityContextDeny, unless PodSecurityPolicy is already in place.\n          --enable-admission-plugins=...,SecurityContextDeny,...\n        scored: false\n\n      - id: 1.2.14\n        text: \"Ensure that the admission control plugin ServiceAccount is set (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'ServiceAccount'\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--disable-admission-plugins\"\n              compare:\n                op: nothave\n                value: \"ServiceAccount\"\n            - flag: \"--disable-admission-plugins\"\n              set: false\n        remediation: |\n          By default, K3s does not set the --disable-admission-plugins to anything.\n          Follow the documentation and create ServiceAccount objects as per your environment.\n          If this check fails, edit the K3s config file /etc/rancher/k3s/config.yaml and remove any lines like below.\n          kube-apiserver-arg:\n            - \"disable-admission-plugins=ServiceAccount\"\n        scored: true\n\n      - id: 1.2.15\n        text: \"Ensure that the admission control plugin NamespaceLifecycle is set (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--disable-admission-plugins\"\n              compare:\n                op: nothave\n                value: \"NamespaceLifecycle\"\n            - flag: \"--disable-admission-plugins\"\n              set: false\n        remediation: |\n          By default, K3s does not set the --disable-admission-plugins to anything.\n          If this check fails, edit the K3s config file /etc/rancher/k3s/config.yaml and remove any lines like below.\n          kube-apiserver-arg:\n            - \"disable-admission-plugins=...,NamespaceLifecycle,...\"\n        scored: true\n\n      - id: 1.2.16\n        text: \"Ensure that the admission control plugin NodeRestriction is set (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'enable-admission-plugins'\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"NodeRestriction\"\n        remediation: |\n          By default, K3s sets the --enable-admission-plugins to NodeRestriction.\n          If using the K3s config file /etc/rancher/k3s/config.yaml, check that you are not overriding the admission plugins.\n          If you are, include NodeRestriction in the list.\n          kube-apiserver-arg:\n            - \"enable-admission-plugins=...,NodeRestriction,...\"\n        scored: true\n\n      - id: 1.2.17\n        text: \"Ensure that the --secure-port argument is not set to 0 (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'secure-port'\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--secure-port\"\n              compare:\n                op: gt\n                value: 0\n            - flag: \"--secure-port\"\n              set: false\n        remediation: |\n          By default, K3s sets the secure port to 6444.\n          If this check fails, edit the K3s config file /etc/rancher/k3s/config.yaml and remove any lines like below.\n          kube-apiserver-arg:\n            - \"secure-port=<PORT>\"\n        scored: true\n\n      - id: 1.2.18\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'profiling'\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          By default, K3s sets the --profiling argument to false.\n          If this check fails, edit the K3s config file /etc/rancher/k3s/config.yaml and remove any lines like below.\n          kube-apiserver-arg:\n            - \"profiling=true\"\n        scored: true\n\n      - id: 1.2.19\n        text: \"Ensure that the --audit-log-path argument is set (Manual)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'audit-log-path'\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-path\"\n        remediation: |\n          Edit the K3s config file /etc/rancher/k3s/config.yaml and set the audit-log-path parameter to a suitable path and\n          file where you would like audit logs to be written, for example,\n          kube-apiserver-arg:\n            - \"audit-log-path=/var/lib/rancher/k3s/server/logs/audit.log\"\n        scored: false\n\n      - id: 1.2.20\n        text: \"Ensure that the --audit-log-maxage argument is set to 30 or as appropriate (Manual)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'audit-log-maxage'\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxage\"\n              compare:\n                op: gte\n                value: 30\n        remediation: |\n          Edit the K3s config file /etc/rancher/k3s/config.yaml on the control plane node and\n          set the audit-log-maxage parameter to 30 or as an appropriate number of days, for example,\n          kube-apiserver-arg:\n            - \"audit-log-maxage=30\"\n        scored: false\n\n      - id: 1.2.21\n        text: \"Ensure that the --audit-log-maxbackup argument is set to 10 or as appropriate (Manual)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'audit-log-maxbackup'\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxbackup\"\n              compare:\n                op: gte\n                value: 10\n        remediation: |\n          Edit the K3s config file /etc/rancher/k3s/config.yaml on the control plane node and\n          set the audit-log-maxbackup parameter to 10 or to an appropriate value. For example,\n          kube-apiserver-arg:\n            - \"audit-log-maxbackup=10\"\n        scored: false\n\n      - id: 1.2.22\n        text: \"Ensure that the --audit-log-maxsize argument is set to 100 or as appropriate (Manual)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'audit-log-maxsize'\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxsize\"\n              compare:\n                op: gte\n                value: 100\n        remediation: |\n          Edit the K3s config file /etc/rancher/k3s/config.yaml on the control plane node and\n          set the audit-log-maxsize parameter to an appropriate size in MB. For example,\n          kube-apiserver-arg:\n            - \"audit-log-maxsize=100\"\n        scored: false\n\n      - id: 1.2.23\n        text: \"Ensure that the --request-timeout argument is set as appropriate (Manual)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'request-timeout'\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--request-timeout\"\n              set: false\n            - flag: \"--request-timeout\"\n        remediation: |\n          Permissive, per CIS guidelines,\n          \"it is recommended to set this limit as appropriate and change the default limit of 60 seconds only if needed\".\n          Edit the K3s config file /etc/rancher/k3s/config.yaml\n          and set the below parameter if needed. For example,\n          kube-apiserver-arg:\n            - \"request-timeout=300s\"\n        scored: false\n\n      - id: 1.2.24\n        text: \"Ensure that the --service-account-lookup argument is set to true (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--service-account-lookup\"\n              set: false\n            - flag: \"--service-account-lookup\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          By default, K3s does not set the --service-account-lookup argument.\n          Edit the K3s config file /etc/rancher/k3s/config.yaml and set the service-account-lookup. For example,\n          kube-apiserver-arg:\n            - \"service-account-lookup=true\"\n          Alternatively, you can delete the service-account-lookup parameter from this file so\n          that the default takes effect.\n        scored: true\n\n      - id: 1.2.25\n        text: \"Ensure that the --service-account-key-file argument is set as appropriate (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'service-account-key-file'\"\n        tests:\n          test_items:\n            - flag: \"--service-account-key-file\"\n        remediation: |\n          K3s automatically generates and sets the service account key file.\n          It is located at /var/lib/rancher/k3s/server/tls/service.key.\n          If this check fails, edit K3s config file /etc/rancher/k3s/config.yaml and remove any lines like below.\n          kube-apiserver-arg:\n            - \"service-account-key-file=<path>\"\n        scored: true\n\n      - id: 1.2.26\n        text: \"Ensure that the --etcd-certfile and --etcd-keyfile arguments are set as appropriate (Automated)\"\n        audit: |\n          if [ \"$(journalctl -m -u k3s | grep -m1 'Managed etcd cluster' | wc -l)\" -gt 0 ]; then\n            journalctl -m -u k3s | grep -m1 'Running kube-apiserver' | tail -n1\n          else\n            echo \"--etcd-certfile AND --etcd-keyfile\"\n          fi\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--etcd-certfile\"\n              set: true\n            - flag: \"--etcd-keyfile\"\n              set: true\n        remediation: |\n          K3s automatically generates and sets the etcd certificate and key files.\n          They are located at /var/lib/rancher/k3s/server/tls/etcd/client.crt and /var/lib/rancher/k3s/server/tls/etcd/client.key.\n          If this check fails, edit the K3s config file /etc/rancher/k3s/config.yaml and remove any lines like below.\n          kube-apiserver-arg:\n            - \"etcd-certfile=<path>\"\n            - \"etcd-keyfile=<path>\"\n        scored: true\n\n      - id: 1.2.27\n        text: \"Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Automated)\"\n        audit: \"journalctl -m -u k3s | grep -A1 'Running kube-apiserver' | tail -n2\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--tls-cert-file\"\n              set: true\n            - flag: \"--tls-private-key-file\"\n              set: true\n        remediation: |\n          By default, K3s automatically generates and provides the TLS certificate and private key for the apiserver.\n          They are generated and located at /var/lib/rancher/k3s/server/tls/serving-kube-apiserver.crt and /var/lib/rancher/k3s/server/tls/serving-kube-apiserver.key\n          If this check fails, edit the K3s config file /etc/rancher/k3s/config.yaml and remove any lines like below.\n          kube-apiserver-arg:\n            - \"tls-cert-file=<path>\"\n            - \"tls-private-key-file=<path>\"\n        scored: true\n\n      - id: 1.2.28\n        text: \"Ensure that the --client-ca-file argument is set as appropriate (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'client-ca-file'\"\n        tests:\n          test_items:\n            - flag: \"--client-ca-file\"\n        remediation: |\n          By default, K3s automatically provides the client certificate authority file.\n          It is generated and located at /var/lib/rancher/k3s/server/tls/client-ca.crt.\n          If this check fails, edit the K3s config file /etc/rancher/k3s/config.yaml and remove any lines like below.\n          kube-apiserver-arg:\n            - \"client-ca-file=<path>\"\n        scored: true\n\n      - id: 1.2.29\n        text: \"Ensure that the --etcd-cafile argument is set as appropriate (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'etcd-cafile'\"\n        tests:\n          test_items:\n            - flag: \"--etcd-cafile\"\n        remediation: |\n          By default, K3s automatically provides the etcd certificate authority file.\n          It is generated and located at /var/lib/rancher/k3s/server/tls/client-ca.crt.\n          If this check fails, edit the K3s config file /etc/rancher/k3s/config.yaml and remove any lines like below.\n          kube-apiserver-arg:\n            - \"etcd-cafile=<path>\"\n        scored: true\n\n      - id: 1.2.30\n        text: \"Ensure that the --encryption-provider-config argument is set as appropriate (Manual)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'encryption-provider-config'\"\n        tests:\n          test_items:\n            - flag: \"--encryption-provider-config\"\n        remediation: |\n          K3s can be configured to use encryption providers to encrypt secrets at rest.\n          Edit the K3s config file /etc/rancher/k3s/config.yaml on the control plane node and set the below parameter.\n          secrets-encryption: true\n          Secrets encryption can then be managed with the k3s secrets-encrypt command line tool.\n          If needed, you can find the generated encryption config at /var/lib/rancher/k3s/server/cred/encryption-config.json.\n        scored: false\n\n      - id: 1.2.31\n        text: \"Ensure that encryption providers are appropriately configured (Manual)\"\n        audit: |\n          ENCRYPTION_PROVIDER_CONFIG=$(journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep -- --encryption-provider-config | sed 's%.*encryption-provider-config[= ]\\([^ ]*\\).*%\\1%')\n          if test -e $ENCRYPTION_PROVIDER_CONFIG; then grep -o 'providers\\\"\\:\\[.*\\]' $ENCRYPTION_PROVIDER_CONFIG | grep -o \"[A-Za-z]*\" | head -2 | tail -1  | sed 's/^/provider=/'; fi\n        tests:\n          test_items:\n            - flag: \"provider\"\n              compare:\n                op: valid_elements\n                value: \"aescbc,kms,secretbox\"\n        remediation: |\n          K3s can be configured to use encryption providers to encrypt secrets at rest. K3s will utilize the aescbc provider.\n          Edit the K3s config file /etc/rancher/k3s/config.yaml on the control plane node and set the below parameter.\n          secrets-encryption: true\n          Secrets encryption can then be managed with the k3s secrets-encrypt command line tool.\n          If needed, you can find the generated encryption config at /var/lib/rancher/k3s/server/cred/encryption-config.json\n        scored: false\n\n      - id: 1.2.32\n        text: \"Ensure that the API Server only makes use of Strong Cryptographic Ciphers (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'tls-cipher-suites'\"\n        tests:\n          test_items:\n            - flag: \"--tls-cipher-suites\"\n              compare:\n                op: valid_elements\n                value: \"TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,TLS_CHACHA20_POLY1305_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,TLS_RSA_WITH_3DES_EDE_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_256_GCM_SHA384\"\n        remediation: |\n          By default, the K3s kube-apiserver complies with this test. Changes to these values may cause regression, therefore ensure that all apiserver clients support the new TLS configuration before applying it in production deployments.\n          If a custom TLS configuration is required, consider also creating a custom version of this rule that aligns with your requirements.\n          If this check fails, remove any custom configuration around `tls-cipher-suites` or update the /etc/rancher/k3s/config.yaml file to match the default by adding the following:\n          kube-apiserver-arg:\n            - \"tls-cipher-suites=TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305\"\n        scored: true\n\n  - id: 1.3\n    text: \"Controller Manager\"\n    checks:\n      - id: 1.3.1\n        text: \"Ensure that the --terminated-pod-gc-threshold argument is set as appropriate (Manual)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-controller-manager' | tail -n1 | grep 'terminated-pod-gc-threshold'\"\n        tests:\n          test_items:\n            - flag: \"--terminated-pod-gc-threshold\"\n        remediation: |\n          Edit the K3s config file /etc/rancher/k3s/config.yaml on the control plane node\n          and set the --terminated-pod-gc-threshold to an appropriate threshold,\n          kube-controller-manager-arg:\n            - \"terminated-pod-gc-threshold=10\"\n        scored: false\n\n      - id: 1.3.2\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-controller-manager' | tail -n1 | grep 'profiling'\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          By default, K3s sets the --profiling argument to false.\n          If this check fails, edit the K3s config file /etc/rancher/k3s/config.yaml and remove any lines like below.\n          kube-controller-manager-arg:\n            - \"profiling=true\"\n        scored: true\n\n      - id: 1.3.3\n        text: \"Ensure that the --use-service-account-credentials argument is set to true (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-controller-manager' | tail -n1 | grep 'use-service-account-credentials'\"\n        tests:\n          test_items:\n            - flag: \"--use-service-account-credentials\"\n              compare:\n                op: noteq\n                value: false\n        remediation: |\n          By default, K3s sets the --use-service-account-credentials argument to true.\n          If this check fails, edit the K3s config file /etc/rancher/k3s/config.yaml and remove any lines like below.\n          kube-controller-manager-arg:\n            - \"use-service-account-credentials=false\"\n        scored: true\n\n      - id: 1.3.4\n        text: \"Ensure that the --service-account-private-key-file argument is set as appropriate (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-controller-manager' | tail -n1 | grep 'service-account-private-key-file'\"\n        tests:\n          test_items:\n            - flag: \"--service-account-private-key-file\"\n        remediation: |\n          By default, K3s automatically provides the service account private key file.\n          It is generated and located at /var/lib/rancher/k3s/server/tls/service.current.key.\n          If this check fails, edit the K3s config file /etc/rancher/k3s/config.yaml and remove any lines like below.\n          kube-controller-manager-arg:\n            - \"service-account-private-key-file=<path>\"\n        scored: true\n\n      - id: 1.3.5\n        text: \"Ensure that the --root-ca-file argument is set as appropriate (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-controller-manager' | tail -n1 | grep 'root-ca-file'\"\n        tests:\n          test_items:\n            - flag: \"--root-ca-file\"\n        remediation: |\n          By default, K3s automatically provides the root CA file.\n          It is generated and located at /var/lib/rancher/k3s/server/tls/server-ca.crt.\n          If this check fails, edit the K3s config file /etc/rancher/k3s/config.yaml and remove any lines like below.\n          kube-controller-manager-arg:\n            - \"root-ca-file=<path>\"\n        scored: true\n\n      - id: 1.3.6\n        text: \"Ensure that the RotateKubeletServerCertificate argument is set to true (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-controller-manager' | tail -n1\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--feature-gates\"\n              compare:\n                op: nothave\n                value: \"RotateKubeletServerCertificate=false\"\n              set: true\n            - flag: \"--feature-gates\"\n              set: false\n        remediation: |\n          By default, K3s does not set the RotateKubeletServerCertificate feature gate.\n          If you have enabled this feature gate, you should remove it.\n          If this check fails, edit the K3s config file /etc/rancher/k3s/config.yaml, remove any lines like below.\n          kube-controller-manager-arg:\n            - \"feature-gate=RotateKubeletServerCertificate\"\n        scored: true\n\n      - id: 1.3.7\n        text: \"Ensure that the --bind-address argument is set to 127.0.0.1 (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-controller-manager' | tail -n1 | grep 'bind-address'\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--bind-address\"\n              compare:\n                op: eq\n                value: \"127.0.0.1\"\n              set: true\n            - flag: \"--bind-address\"\n              set: false\n        remediation: |\n          By default, K3s sets the --bind-address argument to 127.0.0.1\n          If this check fails, edit the K3s config file /etc/rancher/k3s/config.yaml and remove any lines like below.\n          kube-controller-manager-arg:\n            - \"bind-address=<IP>\"\n        scored: true\n\n  - id: 1.4\n    text: \"Scheduler\"\n    checks:\n      - id: 1.4.1\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-scheduler' | tail -n1\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n              set: true\n        remediation: |\n          By default, K3s sets the --profiling argument to false.\n          If this check fails, edit the K3s config file /etc/rancher/k3s/config.yaml and remove any lines like below.\n          kube-scheduler-arg:\n            - \"profiling=true\"\n        scored: true\n\n      - id: 1.4.2\n        text: \"Ensure that the --bind-address argument is set to 127.0.0.1 (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-scheduler' | tail -n1 | grep 'bind-address'\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--bind-address\"\n              compare:\n                op: eq\n                value: \"127.0.0.1\"\n              set: true\n            - flag: \"--bind-address\"\n              set: false\n        remediation: |\n          By default, K3s sets the --bind-address argument to 127.0.0.1\n          If this check fails, edit the K3s config file /etc/rancher/k3s/config.yaml and remove any lines like below.\n          kube-scheduler-arg:\n            - \"bind-address=<IP>\"\n        scored: true\n"
  },
  {
    "path": "cfg/k3s-cis-1.24/node.yaml",
    "content": "---\ncontrols:\nversion: \"k3s-cis-1.24\"\nid: 4\ntext: \"Worker Node Security Configuration\"\ntype: \"node\"\ngroups:\n  - id: 4.1\n    text: \"Worker Node Configuration Files\"\n    checks:\n      - id: 4.1.1\n        text: \"Ensure that the kubelet service file permissions are set to 600 or more restrictive (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletsvc; then stat -c permissions=%a $kubeletsvc; fi'' '\n        type: \"skip\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Not Applicable.\n          The kubelet is embedded in the k3s process. There is no kubelet service file, all configuration is passed in as arguments at runtime.\n        scored: true\n\n      - id: 4.1.2\n        text: \"Ensure that the kubelet service file ownership is set to root:root (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletsvc; then stat -c %U:%G $kubeletsvc; fi'' '\n        type: \"skip\"\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Not Applicable.\n          The kubelet is embedded in the k3s process. There is no kubelet service file, all configuration is passed in as arguments at runtime.\n        scored: true\n\n      - id: 4.1.3\n        text: \"If proxy kubeconfig file exists ensure permissions are set to 600 or more restrictive (Automated)\"\n        audit: '/bin/sh -c ''if test -e $proxykubeconfig; then stat -c permissions=%a $proxykubeconfig; fi'' '\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"permissions\"\n              set: true\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chmod 600 $proxykubeconfig\n        scored: true\n\n      - id: 4.1.4\n        text: \"If proxy kubeconfig file exists ensure ownership is set to root:root (Automated)\"\n        audit: 'stat -c %U:%G $proxykubeconfig'\n        tests:\n          bin_op: or\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example, chown root:root $proxykubeconfig\n        scored: true\n\n      - id: 4.1.5\n        text: \"Ensure that the --kubeconfig kubelet.conf file permissions are set to 600 or more restrictive (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletkubeconfig; then stat -c permissions=%a $kubeletkubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chmod 600 $kubeletkubeconfig\n        scored: true\n\n      - id: 4.1.6\n        text: \"Ensure that the --kubeconfig kubelet.conf file ownership is set to root:root (Automated)\"\n        audit: 'stat -c %U:%G $kubeletkubeconfig'\n        tests:\n          test_items:\n            - flag: \"root:root\"\n              compare:\n                op: eq\n                value: \"root:root\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chown root:root $kubeletkubeconfig\n        scored: true\n\n      - id: 4.1.7\n        text: \"Ensure that the certificate authorities file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"stat -c permissions=%a $kubeletcafile\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n              set: true\n        remediation: |\n          Run the following command to modify the file permissions of the\n          --client-ca-file chmod 600 $kubeletcafile\n        scored: true\n\n      - id: 4.1.8\n        text: \"Ensure that the client certificate authorities file ownership is set to root:root (Automated)\"\n        audit: \"stat -c %U:%G $kubeletcafile\"\n        tests:\n          test_items:\n            - flag: root:root\n              compare:\n                op: eq\n                value: root:root\n        remediation: |\n          Run the following command to modify the ownership of the --client-ca-file.\n          chown root:root $kubeletcafile\n        scored: true\n\n      - id: 4.1.9\n        text: \"If the kubelet config.yaml configuration file is being used validate permissions set to 600 or more restrictive (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletconf; then stat -c permissions=%a $kubeletconf; fi'' '\n        type: \"skip\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Not Applicable.\n          The kubelet is embedded in the k3s process. There is no kubelet config file, all configuration is passed in as arguments at runtime.\n        scored: true\n\n      - id: 4.1.10\n        text: \"If the kubelet config.yaml configuration file is being used validate file ownership is set to root:root (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletconf; then stat -c %U:%G $kubeletconf; fi'' '\n        type: \"skip\"\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Not Applicable.\n          The kubelet is embedded in the k3s process. There is no kubelet config file, all configuration is passed in as arguments at runtime.\n        scored: true\n\n  - id: 4.2\n    text: \"Kubelet\"\n    checks:\n      - id: 4.2.1\n        text: \"Ensure that the --anonymous-auth argument is set to false (Automated)\"\n        audit: '/bin/sh -c ''if test $(journalctl -m -u k3s -u k3s-agent | grep \"Running kubelet\" | wc -l) -gt 0; then journalctl -m -u k3s -u k3s-agent | grep \"Running kubelet\" | tail -n1 | grep \"anonymous-auth\" | grep -v grep; else echo \"--anonymous-auth=false\"; fi'' '\n        tests:\n          test_items:\n            - flag: \"--anonymous-auth\"\n              path: '{.authentication.anonymous.enabled}'\n              compare:\n                op: eq\n                value: false\n              set: true\n        remediation: |\n          By default, K3s sets the --anonymous-auth to false. If you have set this to a different value, you\n          should set it back to false. If using the K3s config file /etc/rancher/k3s/config.yaml, remove any lines similar to below.\n          kubelet-arg:\n            - \"anonymous-auth=true\"\n          If using the command line, edit the K3s service file and remove the below argument.\n          --kubelet-arg=\"anonymous-auth=true\"\n          Based on your system, restart the k3s service. For example,\n          systemctl daemon-reload\n          systemctl restart k3s.service\n        scored: true\n\n      - id: 4.2.2\n        text: \"Ensure that the --authorization-mode argument is not set to AlwaysAllow (Automated)\"\n        audit: '/bin/sh -c ''if test $(journalctl -m -u k3s -u k3s-agent | grep \"Running kubelet\" | wc -l) -gt 0; then journalctl -m -u k3s -u k3s-agent | grep \"Running kubelet\" | tail -n1 | grep \"authorization-mode\"; else echo \"--authorization-mode=Webhook\"; fi'' '\n        tests:\n          test_items:\n            - flag: --authorization-mode\n              path: '{.authorization.mode}'\n              compare:\n                op: nothave\n                value: AlwaysAllow\n              set: true\n        remediation: |\n          By default, K3s does not set the --authorization-mode to AlwaysAllow.\n          If using the K3s config file /etc/rancher/k3s/config.yaml, remove any lines similar to below.\n          kubelet-arg:\n            - \"authorization-mode=AlwaysAllow\"\n          If using the command line, edit the K3s service file and remove the below argument.\n          --kubelet-arg=\"authorization-mode=AlwaysAllow\"\n          Based on your system, restart the k3s service. For example,\n          systemctl daemon-reload\n          systemctl restart k3s.service\n        scored: true\n\n      - id: 4.2.3\n        text: \"Ensure that the --client-ca-file argument is set as appropriate (Automated)\"\n        audit: '/bin/sh -c ''if test $(journalctl -m -u k3s -u k3s-agent | grep \"Running kubelet\" | wc -l) -gt 0; then journalctl -m -u k3s -u k3s-agent | grep \"Running kubelet\" | tail -n1 | grep \"client-ca-file\"; else echo \"--client-ca-file=/var/lib/rancher/k3s/server/tls/request-header-ca.crt\"; fi'' '\n        tests:\n          test_items:\n            - flag: --client-ca-file\n              path: '{.authentication.x509.clientCAFile}'\n              set: true\n        remediation: |\n          By default, K3s automatically provides the client ca certificate for the Kubelet.\n          It is generated and located at /var/lib/rancher/k3s/agent/client-ca.crt\n        scored: true\n\n      - id: 4.2.4\n        text: \"Verify that the --read-only-port argument is set to 0 (Automated)\"\n        audit: \"journalctl -m -u k3s -u k3s-agent | grep 'Running kubelet' | tail -n1\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--read-only-port\"\n              path: '{.readOnlyPort}'\n              compare:\n                op: eq\n                value: 0\n            - flag: \"--read-only-port\"\n              path: '{.readOnlyPort}'\n              set: false\n        remediation: |\n          By default, K3s sets the --read-only-port to 0. If you have set this to a different value, you\n          should set it back to 0. If using the K3s config file /etc/rancher/k3s/config.yaml, remove any lines similar to below.\n          kubelet-arg:\n            - \"read-only-port=XXXX\"\n          If using the command line, edit the K3s service file and remove the below argument.\n          --kubelet-arg=\"read-only-port=XXXX\"\n          Based on your system, restart the k3s service. For example,\n          systemctl daemon-reload\n          systemctl restart k3s.service\n        scored: true\n\n      - id: 4.2.5\n        text: \"Ensure that the --streaming-connection-idle-timeout argument is not set to 0 (Manual)\"\n        audit: \"journalctl -m -u k3s -u k3s-agent | grep 'Running kubelet' | tail -n1\"\n        tests:\n          test_items:\n            - flag: --streaming-connection-idle-timeout\n              path: '{.streamingConnectionIdleTimeout}'\n              compare:\n                op: noteq\n                value: 0\n            - flag: --streaming-connection-idle-timeout\n              path: '{.streamingConnectionIdleTimeout}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using the K3s config file /etc/rancher/k3s/config.yaml, set the following parameter to an appropriate value.\n          kubelet-arg:\n            - \"streaming-connection-idle-timeout=5m\"\n          If using the command line, run K3s with --kubelet-arg=\"streaming-connection-idle-timeout=5m\".\n          Based on your system, restart the k3s service. For example,\n          systemctl restart k3s.service\n        scored: false\n\n      - id: 4.2.6\n        text: \"Ensure that the --protect-kernel-defaults argument is set to true (Automated)\"\n        audit: \"journalctl -m -u k3s -u k3s-agent | grep 'Running kubelet' | tail -n1\"\n        tests:\n          test_items:\n            - flag: --protect-kernel-defaults\n              path: '{.protectKernelDefaults}'\n              compare:\n                op: eq\n                value: true\n              set: true\n        remediation: |\n          If using the K3s config file /etc/rancher/k3s/config.yaml, set the following parameter.\n          protect-kernel-defaults: true\n          If using the command line, run K3s with --protect-kernel-defaults=true.\n          Based on your system, restart the k3s service. For example,\n          systemctl restart k3s.service\n        scored: true\n\n      - id: 4.2.7\n        text: \"Ensure that the --make-iptables-util-chains argument is set to true (Automated)\"\n        audit: \"journalctl -m -u k3s -u k3s-agent | grep 'Running kubelet' | tail -n1\"\n        tests:\n          test_items:\n            - flag: --make-iptables-util-chains\n              path: '{.makeIPTablesUtilChains}'\n              compare:\n                op: eq\n                value: true\n              set: true\n            - flag: --make-iptables-util-chains\n              path: '{.makeIPTablesUtilChains}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using the K3s config file /etc/rancher/k3s/config.yaml, set the following parameter.\n          kubelet-arg:\n            - \"make-iptables-util-chains=true\"\n          If using the command line, run K3s with --kubelet-arg=\"make-iptables-util-chains=true\".\n          Based on your system, restart the k3s service. For example,\n          systemctl restart k3s.service\n        scored: true\n\n      - id: 4.2.8\n        text: \"Ensure that the --hostname-override argument is not set (Automated)\"\n        type: \"skip\"\n        audit: \"journalctl -m -u k3s -u k3s-agent | grep 'Running kubelet' | tail -n1\"\n        tests:\n          test_items:\n            - flag: --hostname-override\n              set: false\n        remediation: |\n          Not Applicable.\n          By default, K3s does set the --hostname-override argument. Per CIS guidelines, this is to comply\n          with cloud providers that require this flag to ensure that hostname matches node names.\n        scored: true\n\n      - id: 4.2.9\n        text: \"Ensure that the eventRecordQPS argument is set to a level which ensures appropriate event capture (Manual)\"\n        audit: \"journalctl -m -u k3s -u k3s-agent | grep 'Running kubelet' | tail -n1\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --event-qps\n              path: '{.eventRecordQPS}'\n              compare:\n                op: eq\n                value: 0\n        remediation: |\n          By default, K3s sets the event-qps to 0. Should you wish to change this,\n          If using the K3s config file /etc/rancher/k3s/config.yaml, set the following parameter to an appropriate value.\n          kubelet-arg:\n            - \"event-qps=<value>\"\n          If using the command line, run K3s with --kubelet-arg=\"event-qps=<value>\".\n          Based on your system, restart the k3s service. For example,\n          systemctl restart k3s.service\n        scored: false\n\n      - id: 4.2.10\n        text: \"Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Automated)\"\n        audit: \"journalctl -m -u k3s -u k3s-agent | grep 'Running kubelet' | tail -n1\"\n        tests:\n          test_items:\n            - flag: --tls-cert-file\n              path: '/var/lib/rancher/k3s/agent/serving-kubelet.crt'\n            - flag: --tls-private-key-file\n              path: '/var/lib/rancher/k3s/agent/serving-kubelet.key'\n        remediation: |\n          By default, K3s automatically provides the TLS certificate and private key for the Kubelet.\n          They are generated and located at /var/lib/rancher/k3s/agent/serving-kubelet.crt and /var/lib/rancher/k3s/agent/serving-kubelet.key\n          If for some reason you need to provide your own certificate and key, you can set the\n          below parameters in the K3s config file /etc/rancher/k3s/config.yaml.\n          kubelet-arg:\n            - \"tls-cert-file=<path/to/tls-cert-file>\"\n            - \"tls-private-key-file=<path/to/tls-private-key-file>\"\n        scored: true\n\n      - id: 4.2.11\n        text: \"Ensure that the --rotate-certificates argument is not set to false (Automated)\"\n        audit: \"journalctl -m -u k3s -u k3s-agent | grep 'Running kubelet' | tail -n1\"\n        audit_config: \"/bin/sh -c 'if test -e $kubeletconf; then /bin/cat $kubeletconf; fi' \"\n        tests:\n          test_items:\n            - flag: --rotate-certificates\n              path: '{.rotateCertificates}'\n              compare:\n                op: eq\n                value: true\n            - flag: --rotate-certificates\n              path: '{.rotateCertificates}'\n              set: false\n          bin_op: or\n        remediation: |\n          By default, K3s does not set the --rotate-certificates argument. If you have set this flag with a value of `false`, you should either set it to `true` or completely remove the flag.\n          If using the K3s config file /etc/rancher/k3s/config.yaml, remove any rotate-certificates parameter.\n          If using the command line, remove the K3s flag --kubelet-arg=\"rotate-certificates\".\n          Based on your system, restart the k3s service. For example,\n          systemctl restart k3s.service\n        scored: true\n\n      - id: 4.2.12\n        text: \"Verify that the RotateKubeletServerCertificate argument is set to true (Automated)\"\n        audit: \"journalctl -m -u k3s -u k3s-agent | grep 'Running kubelet' | tail -n1\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: RotateKubeletServerCertificate\n              path: '{.featureGates.RotateKubeletServerCertificate}'\n              compare:\n                op: nothave\n                value: false\n            - flag: RotateKubeletServerCertificate\n              path: '{.featureGates.RotateKubeletServerCertificate}'\n              set: false\n        remediation: |\n          By default, K3s does not set the RotateKubeletServerCertificate feature gate.\n          If you have enabled this feature gate, you should remove it.\n          If using the K3s config file /etc/rancher/k3s/config.yaml, remove any feature-gate=RotateKubeletServerCertificate parameter.\n          If using the command line, remove the K3s flag --kubelet-arg=\"feature-gate=RotateKubeletServerCertificate\".\n          Based on your system, restart the k3s service. For example,\n          systemctl restart k3s.service\n        scored: true\n\n      - id: 4.2.13\n        text: \"Ensure that the Kubelet only makes use of Strong Cryptographic Ciphers (Manual)\"\n        audit: \"journalctl -m -u k3s -u k3s-agent | grep 'Running kubelet' | tail -n1\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --tls-cipher-suites\n              path: '{range .tlsCipherSuites[:]}{}{'',''}{end}'\n              compare:\n                op: valid_elements\n                value: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\n        remediation: |\n          If using a K3s config file /etc/rancher/k3s/config.yaml, edit the file to set `tlsCipherSuites` to\n          kubelet-arg:\n            - \"tls-cipher-suites=TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305\"\n          or to a subset of these values.\n          If using the command line, add the K3s flag --kubelet-arg=\"tls-cipher-suites=<same values as above>\"\n          Based on your system, restart the k3s service. For example,\n          systemctl restart k3s.service\n        scored: false\n"
  },
  {
    "path": "cfg/k3s-cis-1.24/policies.yaml",
    "content": "---\ncontrols:\nversion: \"k3s-cis-1.24\"\nid: 5\ntext: \"Kubernetes Policies\"\ntype: \"policies\"\ngroups:\n  - id: 5.1\n    text: \"RBAC and Service Accounts\"\n    checks:\n      - id: 5.1.1\n        text: \"Ensure that the cluster-admin role is only used where required (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Identify all clusterrolebindings to the cluster-admin role. Check if they are used and\n          if they need this role or if they could use a role with fewer privileges.\n          Where possible, first bind users to a lower privileged role and then remove the\n          clusterrolebinding to the cluster-admin role :\n          kubectl delete clusterrolebinding [name]\n        scored: false\n\n      - id: 5.1.2\n        text: \"Minimize access to secrets (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove get, list and watch access to Secret objects in the cluster.\n        scored: false\n\n      - id: 5.1.3\n        text: \"Minimize wildcard use in Roles and ClusterRoles (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible replace any use of wildcards in clusterroles and roles with specific\n          objects or actions.\n        scored: false\n\n      - id: 5.1.4\n        text: \"Minimize access to create pods (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove create access to pod objects in the cluster.\n        scored: false\n\n      - id: 5.1.5\n        text: \"Ensure that default service accounts are not actively used. (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Create explicit service accounts wherever a Kubernetes workload requires specific access\n          to the Kubernetes API server.\n          Modify the configuration of each default service account to include this value\n          automountServiceAccountToken: false\n        scored: false\n\n      - id: 5.1.6\n        text: \"Ensure that Service Account Tokens are only mounted where necessary (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Modify the definition of pods and service accounts which do not need to mount service\n          account tokens to disable it.\n        scored: false\n\n      - id: 5.1.7\n        text: \"Avoid use of system:masters group (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Remove the system:masters group from all users in the cluster.\n        scored: false\n\n      - id: 5.1.8\n        text: \"Limit use of the Bind, Impersonate and Escalate permissions in the Kubernetes cluster (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove the impersonate, bind and escalate rights from subjects.\n        scored: false\n\n  - id: 5.2\n    text: \"Pod Security Standards\"\n    checks:\n      - id: 5.2.1\n        text: \"Ensure that the cluster has at least one active policy control mechanism in place (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that either Pod Security Admission or an external policy control system is in place\n          for every namespace which contains user workloads.\n        scored: false\n\n      - id: 5.2.2\n        text: \"Minimize the admission of privileged containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of privileged containers.\n        scored: false\n\n      - id: 5.2.3\n        text: \"Minimize the admission of containers wishing to share the host process ID namespace (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of `hostPID` containers.\n        scored: false\n\n      - id: 5.2.4\n        text: \"Minimize the admission of containers wishing to share the host IPC namespace (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of `hostIPC` containers.\n        scored: false\n\n      - id: 5.2.5\n        text: \"Minimize the admission of containers wishing to share the host network namespace (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of `hostNetwork` containers.\n        scored: false\n\n      - id: 5.2.6\n        text: \"Minimize the admission of containers with allowPrivilegeEscalation (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers with `.spec.allowPrivilegeEscalation` set to `true`.\n        scored: false\n\n      - id: 5.2.7\n        text: \"Minimize the admission of root containers (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Create a policy for each namespace in the cluster, ensuring that either `MustRunAsNonRoot`\n          or `MustRunAs` with the range of UIDs not including 0, is set.\n        scored: false\n\n      - id: 5.2.8\n        text: \"Minimize the admission of containers with the NET_RAW capability (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers with the `NET_RAW` capability.\n        scored: false\n\n      - id: 5.2.9\n        text: \"Minimize the admission of containers with added capabilities (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that `allowedCapabilities` is not present in policies for the cluster unless\n          it is set to an empty array.\n        scored: false\n\n      - id: 5.2.10\n        text: \"Minimize the admission of containers with capabilities assigned (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Review the use of capabilities in applications running on your cluster. Where a namespace\n          contains applications which do not require any Linux capabities to operate consider adding\n          a PSP which forbids the admission of containers which do not drop all capabilities.\n        scored: false\n\n      - id: 5.2.11\n        text: \"Minimize the admission of Windows HostProcess containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers that have `.securityContext.windowsOptions.hostProcess` set to `true`.\n        scored: false\n\n      - id: 5.2.12\n        text: \"Minimize the admission of HostPath volumes (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers with `hostPath` volumes.\n        scored: false\n\n      - id: 5.2.13\n        text: \"Minimize the admission of containers which use HostPorts (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers which use `hostPort` sections.\n        scored: false\n\n  - id: 5.3\n    text: \"Network Policies and CNI\"\n    checks:\n      - id: 5.3.1\n        text: \"Ensure that the CNI in use supports NetworkPolicies (Manual)\"\n        type: \"manual\"\n        remediation: |\n          If the CNI plugin in use does not support network policies, consideration should be given to\n          making use of a different plugin, or finding an alternate mechanism for restricting traffic\n          in the Kubernetes cluster.\n        scored: false\n\n      - id: 5.3.2\n        text: \"Ensure that all Namespaces have NetworkPolicies defined (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the documentation and create NetworkPolicy objects as you need them.\n        scored: false\n\n  - id: 5.4\n    text: \"Secrets Management\"\n    checks:\n      - id: 5.4.1\n        text: \"Prefer using Secrets as files over Secrets as environment variables (Manual)\"\n        type: \"manual\"\n        remediation: |\n          If possible, rewrite application code to read Secrets from mounted secret files, rather than\n          from environment variables.\n        scored: false\n\n      - id: 5.4.2\n        text: \"Consider external secret storage (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Refer to the Secrets management options offered by your cloud provider or a third-party\n          secrets management solution.\n        scored: false\n\n  - id: 5.5\n    text: \"Extensible Admission Control\"\n    checks:\n      - id: 5.5.1\n        text: \"Configure Image Provenance using ImagePolicyWebhook admission controller (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and setup image provenance.\n        scored: false\n\n  - id: 5.7\n    text: \"General Policies\"\n    checks:\n      - id: 5.7.1\n        text: \"Create administrative boundaries between resources using namespaces (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the documentation and create namespaces for objects in your deployment as you need\n          them.\n        scored: false\n\n      - id: 5.7.2\n        text: \"Ensure that the seccomp profile is set to docker/default in your Pod definitions (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Use `securityContext` to enable the docker/default seccomp profile in your pod definitions.\n          An example is as below:\n            securityContext:\n              seccompProfile:\n                type: RuntimeDefault\n        scored: false\n\n      - id: 5.7.3\n        text: \"Apply SecurityContext to your Pods and Containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and apply SecurityContexts to your Pods. For a\n          suggested list of SecurityContexts, you may refer to the CIS Security Benchmark for Docker\n          Containers.\n        scored: false\n\n      - id: 5.7.4\n        text: \"The default namespace should not be used (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that namespaces are created to allow for appropriate segregation of Kubernetes\n          resources and that all new resources are created in a specific namespace.\n        scored: false\n"
  },
  {
    "path": "cfg/k3s-cis-1.7/config.yaml",
    "content": "---\n## Version-specific settings that override the values in cfg/config.yaml\n\nmaster:\n  components:\n    - apiserver\n    - kubelet\n    - scheduler\n    - controllermanager\n    - etcd\n    - policies\n\n  apiserver:\n    bins:\n      - containerd\n\n  kubelet:\n    bins:\n      - containerd\n    defaultkubeconfig: /var/lib/rancher/k3s/agent/kubelet.kubeconfig\n    defaultcafile: /var/lib/rancher/k3s/agent/client-ca.crt\n\n  scheduler:\n    bins:\n      - containerd\n    kubeconfig:\n      - /var/lib/rancher/k3s/server/cred/scheduler.kubeconfig\n\n  controllermanager:\n    bins:\n      - containerd\n    kubeconfig:\n      - /var/lib/rancher/k3s/server/cred/controller.kubeconfig\n\n  etcd:\n    bins:\n      - containerd\n\netcd:\n  components:\n    - etcd\n\n  etcd:\n    confs: /var/lib/rancher/k3s/server/db/etcd/config\n\nnode:\n  components:\n    - kubelet\n    - proxy\n\n  kubelet:\n    bins:\n      - containerd\n    defaultkubeconfig: /var/lib/rancher/k3s/agent/kubelet.kubeconfig\n    defaultcafile: /var/lib/rancher/k3s/agent/client-ca.crt\n\n  proxy:\n    bins:\n      - containerd\n    defaultkubeconfig: /var/lib/rancher/k3s/agent/kubeproxy.kubeconfig\n\npolicies:\n  components:\n    - policies\n"
  },
  {
    "path": "cfg/k3s-cis-1.7/controlplane.yaml",
    "content": "---\ncontrols:\nversion: \"k3s-cis-1.7\"\nid: 3\ntext: \"Control Plane Configuration\"\ntype: \"controlplane\"\ngroups:\n  - id: 3.1\n    text: \"Authentication and Authorization\"\n    checks:\n      - id: 3.1.1\n        text: \"Client certificate authentication should not be used for users (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Alternative mechanisms provided by Kubernetes such as the use of OIDC should be\n          implemented in place of client certificates.\n        scored: false\n      - id: 3.1.2\n        text: \"Service account token authentication should not be used for users (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Alternative mechanisms provided by Kubernetes such as the use of OIDC should be implemented\n          in place of service account tokens.\n        scored: false\n      - id: 3.1.3\n        text: \"Bootstrap token authentication should not be used for users (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Alternative mechanisms provided by Kubernetes such as the use of OIDC should be implemented\n          in place of bootstrap tokens.\n        scored: false\n\n  - id: 3.2\n    text: \"Logging\"\n    checks:\n      - id: 3.2.1\n        text: \"Ensure that a minimal audit policy is created (Manual)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'audit-policy-file'\"\n        tests:\n          test_items:\n            - flag: \"--audit-policy-file\"\n              set: true\n        remediation: |\n          Create an audit policy file for your cluster.\n        scored: false\n\n      - id: 3.2.2\n        text: \"Ensure that the audit policy covers key security concerns (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Review the audit policy provided for the cluster and ensure that it covers\n          at least the following areas,\n          - Access to Secrets managed by the cluster. Care should be taken to only\n            log Metadata for requests to Secrets, ConfigMaps, and TokenReviews, in\n            order to avoid risk of logging sensitive data.\n          - Modification of Pod and Deployment objects.\n          - Use of `pods/exec`, `pods/portforward`, `pods/proxy` and `services/proxy`.\n          For most requests, minimally logging at the Metadata level is recommended\n          (the most basic level of logging).\n        scored: false\n"
  },
  {
    "path": "cfg/k3s-cis-1.7/etcd.yaml",
    "content": "---\ncontrols:\nversion: \"k3s-cis-1.7\"\nid: 2\ntext: \"Etcd Node Configuration\"\ntype: \"etcd\"\ngroups:\n  - id: 2\n    text: \"Etcd Node Configuration\"\n    checks:\n      - id: 2.1\n        text: \"Ensure that the --cert-file and --key-file arguments are set as appropriate (Automated)\"\n        audit_config: \"cat $etcdconf\"\n        tests:\n          bin_op: and\n          test_items:\n            - path: \"{.client-transport-security.cert-file}\"\n              compare:\n                op: eq\n                value: \"/var/lib/rancher/k3s/server/tls/etcd/server-client.crt\"\n            - path: \"{.client-transport-security.key-file}\"\n              compare:\n                op: eq\n                value: \"/var/lib/rancher/k3s/server/tls/etcd/server-client.key\"\n        remediation: |\n          If running on with sqlite or a external DB, etcd checks are Not Applicable.\n          When running with embedded-etcd, K3s generates cert and key files for etcd.\n          These are located in /var/lib/rancher/k3s/server/tls/etcd/.\n          If this check fails, ensure that the configuration file $etcdconf\n          has not been modified to use custom cert and key files.\n        scored: false\n\n      - id: 2.2\n        text: \"Ensure that the --client-cert-auth argument is set to true (Automated)\"\n        audit_config: \"cat $etcdconf\"\n        tests:\n          test_items:\n            - path: \"{.client-transport-security.client-cert-auth}\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          If running on with sqlite or a external DB, etcd checks are Not Applicable.\n          When running with embedded-etcd, K3s sets the --client-cert-auth parameter to true.\n          If this check fails, ensure that the configuration file $etcdconf\n          has not been modified to disable client certificate authentication.\n        scored: false\n\n      - id: 2.3\n        text: \"Ensure that the --auto-tls argument is not set to true (Automated)\"\n        audit_config: \"cat $etcdconf\"\n        tests:\n          bin_op: or\n          test_items:\n            - path: \"{.client-transport-security.auto-tls}\"\n              compare:\n                op: eq\n                value: false\n            - path: \"{.client-transport-security.auto-tls}\"\n              set: false\n        remediation: |\n          If running on with sqlite or a external DB, etcd checks are Not Applicable.\n          When running with embedded-etcd, K3s does not set the --auto-tls parameter.\n          If this check fails, edit the etcd pod specification file $etcdconf on the master\n          node and either remove the --auto-tls parameter or set it to false.\n          client-transport-security:\n            auto-tls: false\n        scored: false\n\n      - id: 2.4\n        text: \"Ensure that the --peer-cert-file and --peer-key-file arguments are set as appropriate (Automated)\"\n        audit_config: \"cat $etcdconf\"\n        tests:\n          bin_op: and\n          test_items:\n            - path: \"{.peer-transport-security.cert-file}\"\n              compare:\n                op: eq\n                value: \"/var/lib/rancher/k3s/server/tls/etcd/peer-server-client.crt\"\n            - path: \"{.peer-transport-security.key-file}\"\n              compare:\n                op: eq\n                value: \"/var/lib/rancher/k3s/server/tls/etcd/peer-server-client.key\"\n        remediation: |\n          If running on with sqlite or a external DB, etcd checks are Not Applicable.\n          When running with embedded-etcd, K3s generates peer cert and key files for etcd.\n          These are located in /var/lib/rancher/k3s/server/tls/etcd/.\n          If this check fails, ensure that the configuration file $etcdconf\n          has not been modified to use custom peer cert and key files.\n        scored: false\n\n      - id: 2.5\n        text: \"Ensure that the --peer-client-cert-auth argument is set to true (Automated)\"\n        audit_config: \"cat $etcdconf\"\n        tests:\n          test_items:\n            - path: \"{.peer-transport-security.client-cert-auth}\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          If running on with sqlite or a external DB, etcd checks are Not Applicable.\n          When running with embedded-etcd, K3s sets the --peer-cert-auth parameter to true.\n          If this check fails, ensure that the configuration file $etcdconf\n          has not been modified to disable peer client certificate authentication.\n        scored: false\n\n      - id: 2.6\n        text: \"Ensure that the --peer-auto-tls argument is not set to true (Automated)\"\n        audit_config: \"cat $etcdconf\"\n        tests:\n          bin_op: or\n          test_items:\n            - path: \"{.peer-transport-security.auto-tls}\"\n              compare:\n                op: eq\n                value: false\n            - path: \"{.peer-transport-security.auto-tls}\"\n              set: false\n        remediation: |\n          If running on with sqlite or a external DB, etcd checks are Not Applicable.\n          When running with embedded-etcd, K3s does not set the --peer-auto-tls parameter.\n          If this check fails, edit the etcd pod specification file $etcdconf on the master\n          node and either remove the --peer-auto-tls parameter or set it to false.\n          peer-transport-security:\n            auto-tls: false\n        scored: false\n\n      - id: 2.7\n        text: \"Ensure that a unique Certificate Authority is used for etcd (Automated)\"\n        audit_config: \"cat $etcdconf\"\n        tests:\n          test_items:\n            - path: \"{.peer-transport-security.trusted-ca-file}\"\n              compare:\n                op: eq\n                value: \"/var/lib/rancher/k3s/server/tls/etcd/peer-ca.crt\"\n        remediation: |\n          If running on with sqlite or a external DB, etcd checks are Not Applicable.\n          When running with embedded-etcd, K3s generates a unique certificate authority for etcd.\n          This is located at /var/lib/rancher/k3s/server/tls/etcd/peer-ca.crt.\n          If this check fails, ensure that the configuration file $etcdconf\n          has not been modified to use a shared certificate authority.\n        scored: false\n"
  },
  {
    "path": "cfg/k3s-cis-1.7/master.yaml",
    "content": "---\ncontrols:\nversion: \"k3s-cis-1.7\"\nid: 1\ntext: \"Control Plane Security Configuration\"\ntype: \"master\"\ngroups:\n  - id: 1.1\n    text: \"Control Plane Node Configuration Files\"\n    checks:\n      - id: 1.1.1\n        text: \"Ensure that the API server pod specification file permissions are set to 600 or more restrictive (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/sh -c 'if test -e $apiserverconf; then stat -c permissions=%a $apiserverconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Not Applicable.\n          By default, K3s embeds the api server within the k3s process. There is no API server pod specification file.\n        scored: true\n\n      - id: 1.1.2\n        text: \"Ensure that the API server pod specification file ownership is set to root:root (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/sh -c 'if test -e $apiserverconf; then stat -c %U:%G $apiserverconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Not Applicable.\n          By default, K3s embeds the api server within the k3s process. There is no API server pod specification file.\n        scored: true\n\n      - id: 1.1.3\n        text: \"Ensure that the controller manager pod specification file permissions are set to 600 or more restrictive (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerconf; then stat -c permissions=%a $controllermanagerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Not Applicable.\n          By default, K3s embeds the controller manager within the k3s process. There is no controller manager pod specification file.\n        scored: true\n\n      - id: 1.1.4\n        text: \"Ensure that the controller manager pod specification file ownership is set to root:root (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerconf; then stat -c %U:%G $controllermanagerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Not Applicable.\n          By default, K3s embeds the controller manager within the k3s process. There is no controller manager pod specification file.\n        scored: true\n\n      - id: 1.1.5\n        text: \"Ensure that the scheduler pod specification file permissions are set to 600 or more restrictive (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/sh -c 'if test -e $schedulerconf; then stat -c permissions=%a $schedulerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Not Applicable.\n          By default, K3s embeds the scheduler within the k3s process. There is no scheduler pod specification file.\n        scored: true\n\n      - id: 1.1.6\n        text: \"Ensure that the scheduler pod specification file ownership is set to root:root (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/sh -c 'if test -e $schedulerconf; then stat -c %U:%G $schedulerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Not Applicable.\n          By default, K3s embeds the scheduler within the k3s process. There is no scheduler pod specification file.\n        scored: true\n\n      - id: 1.1.7\n        text: \"Ensure that the etcd pod specification file permissions are set to 600 or more restrictive (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/sh -c 'if test -e $etcdconf; then find $etcdconf -name '*etcd*' | xargs stat -c permissions=%a; fi'\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Not Applicable.\n          By default, K3s embeds etcd within the k3s process. There is no etcd pod specification file.\n        scored: true\n\n      - id: 1.1.8\n        text: \"Ensure that the etcd pod specification file ownership is set to root:root (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/sh -c 'if test -e $etcdconf; then find $etcdconf -name '*etcd*' | xargs stat -c %U:%G; fi'\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Not Applicable.\n          By default, K3s embeds etcd within the k3s process. There is no etcd pod specification file.\n        scored: true\n\n      - id: 1.1.9\n        text: \"Ensure that the Container Network Interface file permissions are set to 600 or more restrictive (Manual)\"\n        audit: find /var/lib/cni/networks -type f ! -name lock 2> /dev/null | xargs --no-run-if-empty stat -c permissions=%a\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          By default, K3s sets the CNI file permissions to 644.\n          Note that for many CNIs, a lock file is created with permissions 750. This is expected and can be ignored.\n          If you modify your CNI configuration, ensure that the permissions are set to 600.\n          For example, chmod 600 /var/lib/cni/networks/<filename>\n        scored: false\n\n      - id: 1.1.10\n        text: \"Ensure that the Container Network Interface file ownership is set to root:root (Automated)\"\n        audit: find /var/lib/cni/networks -type f 2> /dev/null | xargs --no-run-if-empty stat -c %U:%G\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root /var/lib/cni/networks/<filename>\n        scored: true\n\n      - id: 1.1.11\n        text: \"Ensure that the etcd data directory permissions are set to 700 or more restrictive (Automated)\"\n        audit: |\n          if [ \"$(journalctl -m -u k3s | grep -m1 'Managed etcd cluster' | wc -l)\" -gt 0 ]; then\n            stat -c permissions=%a /var/lib/rancher/k3s/server/db/etcd\n          else\n            echo \"permissions=700\"\n          fi\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"700\"\n        remediation: |\n          On the etcd server node, get the etcd data directory, passed as an argument --data-dir,\n          from the command 'ps -ef | grep etcd'.\n          Run the below command (based on the etcd data directory found above). For example,\n          chmod 700 $etcddatadir\n        scored: true\n\n      - id: 1.1.12\n        text: \"Ensure that the etcd data directory ownership is set to etcd:etcd (Automated)\"\n        audit: ps -ef | grep $etcdbin | grep -- --data-dir | sed 's%.*data-dir[= ]\\([^ ]*\\).*%\\1%' | xargs stat -c %U:%G\n        type: \"skip\"\n        tests:\n          test_items:\n            - flag: \"etcd:etcd\"\n        remediation: |\n          Not Applicable.\n          For K3s, etcd is embedded within the k3s process. There is no separate etcd process.\n          Therefore the etcd data directory ownership is managed by the k3s process and should be root:root.\n        scored: true\n\n      - id: 1.1.13\n        text: \"Ensure that the admin.conf file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e /var/lib/rancher/k3s/server/cred/admin.kubeconfig; then stat -c permissions=%a /var/lib/rancher/k3s/server/cred/admin.kubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chmod 600 /var/lib/rancher/k3s/server/cred/admin.kubeconfig\n        scored: true\n\n      - id: 1.1.14\n        text: \"Ensure that the admin.conf file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e /var/lib/rancher/k3s/server/cred/admin.kubeconfig; then stat -c %U:%G /var/lib/rancher/k3s/server/cred/admin.kubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n              compare:\n                op: eq\n                value: \"root:root\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chown root:root /var/lib/rancher/k3s/server/cred/admin.kubeconfig\n        scored: true\n\n      - id: 1.1.15\n        text: \"Ensure that the scheduler.conf file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerkubeconfig; then stat -c permissions=%a $schedulerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod 600 $schedulerkubeconfig\n        scored: true\n\n      - id: 1.1.16\n        text: \"Ensure that the scheduler.conf file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerkubeconfig; then stat -c %U:%G $schedulerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root $schedulerkubeconfig\n        scored: true\n\n      - id: 1.1.17\n        text: \"Ensure that the controller-manager.conf file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerkubeconfig; then stat -c permissions=%a $controllermanagerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod 600 $controllermanagerkubeconfig\n        scored: true\n\n      - id: 1.1.18\n        text: \"Ensure that the controller-manager.conf file ownership is set to root:root (Automated)\"\n        audit: \"stat -c %U:%G $controllermanagerkubeconfig\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n              compare:\n                op: eq\n                value: \"root:root\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root $controllermanagerkubeconfig\n        scored: true\n\n      - id: 1.1.19\n        text: \"Ensure that the Kubernetes PKI directory and file ownership is set to root:root (Automated)\"\n        audit: \"stat -c %U:%G /var/lib/rancher/k3s/server/tls\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown -R root:root /var/lib/rancher/k3s/server/tls\n        scored: true\n\n      - id: 1.1.20\n        text: \"Ensure that the Kubernetes PKI certificate file permissions are set to 600 or more restrictive (Manual)\"\n        audit: \"/bin/sh -c 'stat -c permissions=%a /var/lib/rancher/k3s/server/tls/*.crt'\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chmod -R 600 /var/lib/rancher/k3s/server/tls/*.crt\n        scored: false\n\n      - id: 1.1.21\n        text: \"Ensure that the Kubernetes PKI key file permissions are set to 600 (Automated)\"\n        audit: \"/bin/sh -c 'stat -c permissions=%a /var/lib/rancher/k3s/server/tls/*.key'\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chmod -R 600 /var/lib/rancher/k3s/server/tls/*.key\n        scored: true\n\n  - id: 1.2\n    text: \"API Server\"\n    checks:\n      - id: 1.2.1\n        text: \"Ensure that the --anonymous-auth argument is set to false (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'anonymous-auth'\"\n        tests:\n          test_items:\n            - flag: \"--anonymous-auth\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          By default, K3s sets the --anonymous-auth argument to false. If it is set to true,\n          edit the K3s config file /etc/rancher/k3s/config.yaml and remove anything similar to below.\n          kube-apiserver-arg:\n            - \"anonymous-auth=true\"\n        scored: true\n\n      - id: 1.2.2\n        text: \"Ensure that the --token-auth-file parameter is not set (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1\"\n        tests:\n          test_items:\n            - flag: \"--token-auth-file\"\n              set: false\n        remediation: |\n          Follow the documentation and configure alternate mechanisms for authentication.\n          If this check fails, edit the K3s config file /etc/rancher/k3s/config.yaml and remove anything similar to below.\n          kube-apiserver-arg:\n            - \"token-auth-file=<path>\"\n        scored: true\n\n      - id: 1.2.3\n        text: \"Ensure that the --DenyServiceExternalIPs is not set (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: nothave\n                value: \"DenyServiceExternalIPs\"\n              set: true\n            - flag: \"--enable-admission-plugins\"\n              set: false\n        remediation: |\n          By default, K3s does not set DenyServiceExternalIPs.\n          If this check fails, edit the K3s config file /etc/rancher/k3s/config.yaml, remove any lines like below.\n          kube-apiserver-arg:\n            - \"enable-admission-plugins=DenyServiceExternalIPs\"\n        scored: true\n\n      - id: 1.2.4\n        text: \"Ensure that the --kubelet-client-certificate and --kubelet-client-key arguments are set as appropriate (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'kubelet-certificate-authority'\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--kubelet-client-certificate\"\n            - flag: \"--kubelet-client-key\"\n        remediation: |\n          By default, K3s automatically provides the kubelet client certificate and key.\n          They are generated and located at /var/lib/rancher/k3s/server/tls/client-kube-apiserver.crt and /var/lib/rancher/k3s/server/tls/client-kube-apiserver.key\n          If for some reason you need to provide your own certificate and key, you can set the\n          below parameters in the K3s config file /etc/rancher/k3s/config.yaml.\n          kube-apiserver-arg:\n            - \"kubelet-client-certificate=<path/to/client-cert-file>\"\n            - \"kubelet-client-key=<path/to/client-key-file>\"\n        scored: true\n\n      - id: 1.2.5\n        text: \"Ensure that the --kubelet-certificate-authority argument is set as appropriate (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'kubelet-certificate-authority'\"\n        tests:\n          test_items:\n            - flag: \"--kubelet-certificate-authority\"\n        remediation: |\n          By default, K3s automatically provides the kubelet CA cert file, at /var/lib/rancher/k3s/server/tls/server-ca.crt.\n          If this check fails, edit the K3s config file /etc/rancher/k3s/config.yaml and remove any lines like below.\n          kube-apiserver-arg:\n            - \"kubelet-certificate-authority=<path/to/ca-cert-file>\"\n        scored: true\n\n      - id: 1.2.6\n        text: \"Ensure that the --authorization-mode argument is not set to AlwaysAllow (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'authorization-mode'\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: nothave\n                value: \"AlwaysAllow\"\n        remediation: |\n          By default, K3s does not set the --authorization-mode to AlwaysAllow.\n          If this check fails, edit K3s config file /etc/rancher/k3s/config.yaml, remove any lines like below.\n          kube-apiserver-arg:\n            - \"authorization-mode=AlwaysAllow\"\n        scored: true\n\n      - id: 1.2.7\n        text: \"Ensure that the --authorization-mode argument includes Node (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'authorization-mode'\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: has\n                value: \"Node\"\n        remediation: |\n          By default, K3s sets the --authorization-mode to Node and RBAC.\n          If this check fails, edit the K3s config file /etc/rancher/k3s/config.yaml,\n          ensure that you are not overriding authorization-mode.\n        scored: true\n\n      - id: 1.2.8\n        text: \"Ensure that the --authorization-mode argument includes RBAC (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'authorization-mode'\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: has\n                value: \"RBAC\"\n        remediation: |\n          By default, K3s sets the --authorization-mode to Node and RBAC.\n          If this check fails, edit the K3s config file /etc/rancher/k3s/config.yaml,\n          ensure that you are not overriding authorization-mode.\n        scored: true\n\n      - id: 1.2.9\n        text: \"Ensure that the admission control plugin EventRateLimit is set (Manual)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'enable-admission-plugins'\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"EventRateLimit\"\n        remediation: |\n          Follow the Kubernetes documentation and set the desired limits in a configuration file.\n          Then, edit the K3s config file /etc/rancher/k3s/config.yaml and set the below parameters.\n          kube-apiserver-arg:\n            - \"enable-admission-plugins=...,EventRateLimit,...\"\n            - \"admission-control-config-file=<path/to/configuration/file>\"\n        scored: false\n\n      - id: 1.2.10\n        text: \"Ensure that the admission control plugin AlwaysAdmit is not set (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'enable-admission-plugins'\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: nothave\n                value: AlwaysAdmit\n            - flag: \"--enable-admission-plugins\"\n              set: false\n        remediation: |\n          By default, K3s does not set the --enable-admission-plugins to AlwaysAdmit.\n          If this check fails, edit K3s config file /etc/rancher/k3s/config.yaml, remove any lines like below.\n          kube-apiserver-arg:\n            - \"enable-admission-plugins=AlwaysAdmit\"\n        scored: true\n\n      - id: 1.2.11\n        text: \"Ensure that the admission control plugin AlwaysPullImages is set (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"AlwaysPullImages\"\n        remediation: |\n          Permissive, per CIS guidelines,\n          \"This setting could impact offline or isolated clusters, which have images pre-loaded and\n          do not have access to a registry to pull in-use images. This setting is not appropriate for\n          clusters which use this configuration.\"\n          Edit the K3s config file /etc/rancher/k3s/config.yaml and set the below parameter.\n          kube-apiserver-arg:\n            - \"enable-admission-plugins=...,AlwaysPullImages,...\"\n        scored: false\n\n      - id: 1.2.12\n        text: \"Ensure that the admission control plugin SecurityContextDeny is set if PodSecurityPolicy is not used (Manual)\"\n        type: \"skip\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"SecurityContextDeny\"\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"PodSecurityPolicy\"\n        remediation: |\n          Not Applicable.\n          Enabling Pod Security Policy is no longer supported on K3s v1.25+ and will cause applications to unexpectedly fail.\n        scored: false\n\n      - id: 1.2.13\n        text: \"Ensure that the admission control plugin ServiceAccount is set (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--disable-admission-plugins\"\n              compare:\n                op: nothave\n                value: \"ServiceAccount\"\n            - flag: \"--disable-admission-plugins\"\n              set: false\n        remediation: |\n          By default, K3s does not set the --disable-admission-plugins to anything.\n          Follow the documentation and create ServiceAccount objects as per your environment.\n          If this check fails, edit the K3s config file /etc/rancher/k3s/config.yaml and remove any lines like below.\n          kube-apiserver-arg:\n            - \"disable-admission-plugins=ServiceAccount\"\n        scored: true\n\n      - id: 1.2.14\n        text: \"Ensure that the admission control plugin NamespaceLifecycle is set (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--disable-admission-plugins\"\n              compare:\n                op: nothave\n                value: \"NamespaceLifecycle\"\n            - flag: \"--disable-admission-plugins\"\n              set: false\n        remediation: |\n          By default, K3s does not set the --disable-admission-plugins to anything.\n          If this check fails, edit the K3s config file /etc/rancher/k3s/config.yaml and remove any lines like below.\n          kube-apiserver-arg:\n            - \"disable-admission-plugins=...,NamespaceLifecycle,...\"\n        scored: true\n\n      - id: 1.2.15\n        text: \"Ensure that the admission control plugin NodeRestriction is set (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'enable-admission-plugins'\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"NodeRestriction\"\n        remediation: |\n          By default, K3s sets the --enable-admission-plugins to NodeRestriction.\n          If using the K3s config file /etc/rancher/k3s/config.yaml, check that you are not overriding the admission plugins.\n          If you are, include NodeRestriction in the list.\n          kube-apiserver-arg:\n            - \"enable-admission-plugins=...,NodeRestriction,...\"\n        scored: true\n\n      - id: 1.2.16\n        text: \"Ensure that the --secure-port argument is not set to 0 - NoteThis recommendation is obsolete and will be deleted per the consensus process (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'secure-port'\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--secure-port\"\n              compare:\n                op: gt\n                value: 0\n            - flag: \"--secure-port\"\n              set: false\n        remediation: |\n          By default, K3s sets the secure port to 6444.\n          If this check fails, edit the K3s config file /etc/rancher/k3s/config.yaml and remove any lines like below.\n          kube-apiserver-arg:\n            - \"secure-port=<PORT>\"\n        scored: true\n\n      - id: 1.2.17\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'profiling'\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          By default, K3s sets the --profiling argument to false.\n          If this check fails, edit the K3s config file /etc/rancher/k3s/config.yaml and remove any lines like below.\n          kube-apiserver-arg:\n            - \"profiling=true\"\n        scored: true\n\n      - id: 1.2.18\n        text: \"Ensure that the --audit-log-path argument is set (Manual)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-path\"\n        remediation: |\n          Edit the K3s config file /etc/rancher/k3s/config.yaml and set the audit-log-path parameter to a suitable path and\n          file where you would like audit logs to be written, for example,\n          kube-apiserver-arg:\n            - \"audit-log-path=/var/lib/rancher/k3s/server/logs/audit.log\"\n        scored: false\n\n      - id: 1.2.19\n        text: \"Ensure that the --audit-log-maxage argument is set to 30 or as appropriate (Manual)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxage\"\n              compare:\n                op: gte\n                value: 30\n        remediation: |\n          Edit the K3s config file /etc/rancher/k3s/config.yaml on the control plane node and\n          set the audit-log-maxage parameter to 30 or as an appropriate number of days, for example,\n          kube-apiserver-arg:\n            - \"audit-log-maxage=30\"\n        scored: false\n\n      - id: 1.2.20\n        text: \"Ensure that the --audit-log-maxbackup argument is set to 10 or as appropriate (Manual)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxbackup\"\n              compare:\n                op: gte\n                value: 10\n        remediation: |\n          Edit the K3s config file /etc/rancher/k3s/config.yaml on the control plane node and\n          set the audit-log-maxbackup parameter to 10 or to an appropriate value. For example,\n          kube-apiserver-arg:\n            - \"audit-log-maxbackup=10\"\n        scored: false\n\n      - id: 1.2.21\n        text: \"Ensure that the --audit-log-maxsize argument is set to 100 or as appropriate (Manual)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxsize\"\n              compare:\n                op: gte\n                value: 100\n        remediation: |\n          Edit the K3s config file /etc/rancher/k3s/config.yaml on the control plane node and\n          set the audit-log-maxsize parameter to an appropriate size in MB. For example,\n          kube-apiserver-arg:\n            - \"audit-log-maxsize=100\"\n        scored: false\n\n      - id: 1.2.22\n        text: \"Ensure that the --request-timeout argument is set as appropriate (Manual)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1\"\n        tests:\n          test_items:\n            - flag: \"--request-timeout\"\n        remediation: |\n          Permissive, per CIS guidelines,\n          \"it is recommended to set this limit as appropriate and change the default limit of 60 seconds only if needed\".\n          Edit the K3s config file /etc/rancher/k3s/config.yaml\n          and set the below parameter if needed. For example,\n          kube-apiserver-arg:\n            - \"request-timeout=300s\"\n        scored: false\n\n      - id: 1.2.23\n        text: \"Ensure that the --service-account-lookup argument is set to true (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--service-account-lookup\"\n              set: false\n            - flag: \"--service-account-lookup\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          By default, K3s does not set the --service-account-lookup argument.\n          Edit the K3s config file /etc/rancher/k3s/config.yaml and set the service-account-lookup. For example,\n          kube-apiserver-arg:\n            - \"service-account-lookup=true\"\n          Alternatively, you can delete the service-account-lookup parameter from this file so\n          that the default takes effect.\n        scored: true\n\n      - id: 1.2.24\n        text: \"Ensure that the --service-account-key-file argument is set as appropriate (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1\"\n        tests:\n          test_items:\n            - flag: \"--service-account-key-file\"\n        remediation: |\n          K3s automatically generates and sets the service account key file.\n          It is located at /var/lib/rancher/k3s/server/tls/service.key.\n          If this check fails, edit K3s config file /etc/rancher/k3s/config.yaml and remove any lines like below.\n          kube-apiserver-arg:\n            - \"service-account-key-file=<path>\"\n        scored: true\n\n      - id: 1.2.25\n        text: \"Ensure that the --etcd-certfile and --etcd-keyfile arguments are set as appropriate (Automated)\"\n        audit: |\n          if [ \"$(journalctl -m -u k3s | grep -m1 'Managed etcd cluster' | wc -l)\" -gt 0 ]; then\n            journalctl -m -u k3s | grep -m1 'Running kube-apiserver' | tail -n1\n          else\n            echo \"--etcd-certfile AND --etcd-keyfile\"\n          fi\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--etcd-certfile\"\n              set: true\n            - flag: \"--etcd-keyfile\"\n              set: true\n        remediation: |\n          K3s automatically generates and sets the etcd certificate and key files.\n          They are located at /var/lib/rancher/k3s/server/tls/etcd/client.crt and /var/lib/rancher/k3s/server/tls/etcd/client.key.\n          If this check fails, edit the K3s config file /etc/rancher/k3s/config.yaml and remove any lines like below.\n          kube-apiserver-arg:\n            - \"etcd-certfile=<path>\"\n            - \"etcd-keyfile=<path>\"\n        scored: true\n\n      - id: 1.2.26\n        text: \"Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Automated)\"\n        audit: \"journalctl -m -u k3s | grep -A1 'Running kube-apiserver' | tail -n2\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--tls-cert-file\"\n              set: true\n            - flag: \"--tls-private-key-file\"\n              set: true\n        remediation: |\n          By default, K3s automatically generates and provides the TLS certificate and private key for the apiserver.\n          They are generated and located at /var/lib/rancher/k3s/server/tls/serving-kube-apiserver.crt and /var/lib/rancher/k3s/server/tls/serving-kube-apiserver.key\n          If this check fails, edit the K3s config file /etc/rancher/k3s/config.yaml and remove any lines like below.\n          kube-apiserver-arg:\n            - \"tls-cert-file=<path>\"\n            - \"tls-private-key-file=<path>\"\n        scored: true\n\n      - id: 1.2.27\n        text: \"Ensure that the --client-ca-file argument is set as appropriate (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'client-ca-file'\"\n        tests:\n          test_items:\n            - flag: \"--client-ca-file\"\n        remediation: |\n          By default, K3s automatically provides the client certificate authority file.\n          It is generated and located at /var/lib/rancher/k3s/server/tls/client-ca.crt.\n          If this check fails, edit the K3s config file /etc/rancher/k3s/config.yaml and remove any lines like below.\n          kube-apiserver-arg:\n            - \"client-ca-file=<path>\"\n        scored: true\n\n      - id: 1.2.28\n        text: \"Ensure that the --etcd-cafile argument is set as appropriate (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'etcd-cafile'\"\n        tests:\n          test_items:\n            - flag: \"--etcd-cafile\"\n        remediation: |\n          By default, K3s automatically provides the etcd certificate authority file.\n          It is generated and located at /var/lib/rancher/k3s/server/tls/client-ca.crt.\n          If this check fails, edit the K3s config file /etc/rancher/k3s/config.yaml and remove any lines like below.\n          kube-apiserver-arg:\n            - \"etcd-cafile=<path>\"\n        scored: true\n\n      - id: 1.2.29\n        text: \"Ensure that the --encryption-provider-config argument is set as appropriate (Manual)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'encryption-provider-config'\"\n        tests:\n          test_items:\n            - flag: \"--encryption-provider-config\"\n        remediation: |\n          K3s can be configured to use encryption providers to encrypt secrets at rest.\n          Edit the K3s config file /etc/rancher/k3s/config.yaml on the control plane node and set the below parameter.\n          secrets-encryption: true\n          Secrets encryption can then be managed with the k3s secrets-encrypt command line tool.\n          If needed, you can find the generated encryption config at /var/lib/rancher/k3s/server/cred/encryption-config.json.\n        scored: false\n\n      - id: 1.2.30\n        text: \"Ensure that encryption providers are appropriately configured (Manual)\"\n        audit: |\n          ENCRYPTION_PROVIDER_CONFIG=$(journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep -- --encryption-provider-config | sed 's%.*encryption-provider-config[= ]\\([^ ]*\\).*%\\1%')\n          if test -e $ENCRYPTION_PROVIDER_CONFIG; then grep -o 'providers\\\"\\:\\[.*\\]' $ENCRYPTION_PROVIDER_CONFIG | grep -o \"[A-Za-z]*\" | head -2 | tail -1  | sed 's/^/provider=/'; fi\n        tests:\n          test_items:\n            - flag: \"provider\"\n              compare:\n                op: valid_elements\n                value: \"aescbc,kms,secretbox\"\n        remediation: |\n          K3s can be configured to use encryption providers to encrypt secrets at rest. K3s will utilize the aescbc provider.\n          Edit the K3s config file /etc/rancher/k3s/config.yaml on the control plane node and set the below parameter.\n          secrets-encryption: true\n          Secrets encryption can then be managed with the k3s secrets-encrypt command line tool.\n          If needed, you can find the generated encryption config at /var/lib/rancher/k3s/server/cred/encryption-config.json\n        scored: false\n\n      - id: 1.2.31\n        text: \"Ensure that the API Server only makes use of Strong Cryptographic Ciphers (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'tls-cipher-suites'\"\n        tests:\n          test_items:\n            - flag: \"--tls-cipher-suites\"\n              compare:\n                op: valid_elements\n                value: \"TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,TLS_CHACHA20_POLY1305_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,TLS_RSA_WITH_3DES_EDE_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_256_GCM_SHA384\"\n        remediation: |\n          By default, the K3s kube-apiserver complies with this test. Changes to these values may cause regression, therefore ensure that all apiserver clients support the new TLS configuration before applying it in production deployments.\n          If a custom TLS configuration is required, consider also creating a custom version of this rule that aligns with your requirements.\n          If this check fails, remove any custom configuration around `tls-cipher-suites` or update the /etc/rancher/k3s/config.yaml file to match the default by adding the following:\n          kube-apiserver-arg:\n            - \"tls-cipher-suites=TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305\"\n        scored: true\n\n  - id: 1.3\n    text: \"Controller Manager\"\n    checks:\n      - id: 1.3.1\n        text: \"Ensure that the --terminated-pod-gc-threshold argument is set as appropriate (Manual)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-controller-manager' | tail -n1 | grep 'terminated-pod-gc-threshold'\"\n        tests:\n          test_items:\n            - flag: \"--terminated-pod-gc-threshold\"\n        remediation: |\n          Edit the K3s config file /etc/rancher/k3s/config.yaml on the control plane node\n          and set the --terminated-pod-gc-threshold to an appropriate threshold,\n          kube-controller-manager-arg:\n            - \"terminated-pod-gc-threshold=10\"\n        scored: false\n\n      - id: 1.3.2\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-controller-manager' | tail -n1 | grep 'profiling'\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          By default, K3s sets the --profiling argument to false.\n          If this check fails, edit the K3s config file /etc/rancher/k3s/config.yaml and remove any lines like below.\n          kube-controller-manager-arg:\n            - \"profiling=true\"\n        scored: true\n\n      - id: 1.3.3\n        text: \"Ensure that the --use-service-account-credentials argument is set to true (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-controller-manager' | tail -n1 | grep 'use-service-account-credentials'\"\n        tests:\n          test_items:\n            - flag: \"--use-service-account-credentials\"\n              compare:\n                op: noteq\n                value: false\n        remediation: |\n          By default, K3s sets the --use-service-account-credentials argument to true.\n          If this check fails, edit the K3s config file /etc/rancher/k3s/config.yaml and remove any lines like below.\n          kube-controller-manager-arg:\n            - \"use-service-account-credentials=false\"\n        scored: true\n\n      - id: 1.3.4\n        text: \"Ensure that the --service-account-private-key-file argument is set as appropriate (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-controller-manager' | tail -n1 | grep 'service-account-private-key-file'\"\n        tests:\n          test_items:\n            - flag: \"--service-account-private-key-file\"\n        remediation: |\n          By default, K3s automatically provides the service account private key file.\n          It is generated and located at /var/lib/rancher/k3s/server/tls/service.current.key.\n          If this check fails, edit the K3s config file /etc/rancher/k3s/config.yaml and remove any lines like below.\n          kube-controller-manager-arg:\n            - \"service-account-private-key-file=<path>\"\n        scored: true\n\n      - id: 1.3.5\n        text: \"Ensure that the --root-ca-file argument is set as appropriate (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-controller-manager' | tail -n1 | grep 'root-ca-file'\"\n        tests:\n          test_items:\n            - flag: \"--root-ca-file\"\n        remediation: |\n          By default, K3s automatically provides the root CA file.\n          It is generated and located at /var/lib/rancher/k3s/server/tls/server-ca.crt.\n          If this check fails, edit the K3s config file /etc/rancher/k3s/config.yaml and remove any lines like below.\n          kube-controller-manager-arg:\n            - \"root-ca-file=<path>\"\n        scored: true\n\n      - id: 1.3.6\n        text: \"Ensure that the RotateKubeletServerCertificate argument is set to true (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-controller-manager' | tail -n1\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--feature-gates\"\n              compare:\n                op: nothave\n                value: \"RotateKubeletServerCertificate=false\"\n              set: true\n            - flag: \"--feature-gates\"\n              set: false\n        remediation: |\n          By default, K3s does not set the RotateKubeletServerCertificate feature gate.\n          If you have enabled this feature gate, you should remove it.\n          If this check fails, edit the K3s config file /etc/rancher/k3s/config.yaml, remove any lines like below.\n          kube-controller-manager-arg:\n            - \"feature-gate=RotateKubeletServerCertificate\"\n        scored: true\n\n      - id: 1.3.7\n        text: \"Ensure that the --bind-address argument is set to 127.0.0.1 (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--bind-address\"\n              compare:\n                op: eq\n                value: \"127.0.0.1\"\n              set: true\n            - flag: \"--bind-address\"\n              set: false\n        remediation: |\n          By default, K3s sets the --bind-address argument to 127.0.0.1\n          If this check fails, edit the K3s config file /etc/rancher/k3s/config.yaml and remove any lines like below.\n          kube-controller-manager-arg:\n            - \"bind-address=<IP>\"\n        scored: true\n\n  - id: 1.4\n    text: \"Scheduler\"\n    checks:\n      - id: 1.4.1\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-scheduler' | tail -n1\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n              set: true\n        remediation: |\n          By default, K3s sets the --profiling argument to false.\n          If this check fails, edit the K3s config file /etc/rancher/k3s/config.yaml and remove any lines like below.\n          kube-scheduler-arg:\n            - \"profiling=true\"\n        scored: true\n\n      - id: 1.4.2\n        text: \"Ensure that the --bind-address argument is set to 127.0.0.1 (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-scheduler' | tail -n1 | grep 'bind-address'\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--bind-address\"\n              compare:\n                op: eq\n                value: \"127.0.0.1\"\n              set: true\n            - flag: \"--bind-address\"\n              set: false\n        remediation: |\n          By default, K3s sets the --bind-address argument to 127.0.0.1\n          If this check fails, edit the K3s config file /etc/rancher/k3s/config.yaml and remove any lines like below.\n          kube-scheduler-arg:\n            - \"bind-address=<IP>\"\n        scored: true\n"
  },
  {
    "path": "cfg/k3s-cis-1.7/node.yaml",
    "content": "---\ncontrols:\nversion: \"k3s-cis-1.7\"\nid: 4\ntext: \"Worker Node Security Configuration\"\ntype: \"node\"\ngroups:\n  - id: 4.1\n    text: \"Worker Node Configuration Files\"\n    checks:\n      - id: 4.1.1\n        text: \"Ensure that the kubelet service file permissions are set to 600 or more restrictive (Automated)\"\n        type: \"skip\"\n        audit: '/bin/sh -c ''if test -e $kubeletsvc; then stat -c permissions=%a $kubeletsvc; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Not Applicable.\n          The kubelet is embedded in the k3s process. There is no kubelet service file, all configuration is passed in as arguments at runtime.\n        scored: true\n\n      - id: 4.1.2\n        text: \"Ensure that the kubelet service file ownership is set to root:root (Automated)\"\n        type: \"skip\"\n        audit: '/bin/sh -c ''if test -e $kubeletsvc; then stat -c %U:%G $kubeletsvc; fi'' '\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Not Applicable.\n          The kubelet is embedded in the k3s process. There is no kubelet service file, all configuration is passed in as arguments at runtime.\n          Not Applicable.\n           All configuration is passed in as arguments at container run time.\n        scored: true\n\n      - id: 4.1.3\n        text: \"If proxy kubeconfig file exists ensure permissions are set to 600 or more restrictive (Automated)\"\n        audit: '/bin/sh -c ''if test -e $proxykubeconfig; then stat -c permissions=%a $proxykubeconfig; fi'' '\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chmod 600 $proxykubeconfig\n        scored: true\n\n      - id: 4.1.4\n        text: \"If proxy kubeconfig file exists ensure ownership is set to root:root (Automated)\"\n        audit: '/bin/sh -c ''if test -e $proxykubeconfig; then stat -c %U:%G $proxykubeconfig; fi'' '\n        tests:\n          bin_op: or\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example, chown root:root $proxykubeconfig\n        scored: true\n\n      - id: 4.1.5\n        text: \"Ensure that the --kubeconfig kubelet.conf file permissions are set to 600 or more restrictive (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletkubeconfig; then stat -c permissions=%a $kubeletkubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chmod 600 $kubeletkubeconfig\n        scored: true\n\n      - id: 4.1.6\n        text: \"Ensure that the --kubeconfig kubelet.conf file ownership is set to root:root (Automated)\"\n        audit: 'stat -c %U:%G $kubeletkubeconfig'\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chown root:root $kubeletkubeconfig\n        scored: true\n\n      - id: 4.1.7\n        text: \"Ensure that the certificate authorities file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"stat -c permissions=%a $kubeletcafile\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the following command to modify the file permissions of the\n          --client-ca-file chmod 600 $kubeletcafile\n        scored: true\n\n      - id: 4.1.8\n        text: \"Ensure that the client certificate authorities file ownership is set to root:root (Automated)\"\n        audit: \"stat -c %U:%G $kubeletcafile\"\n        tests:\n          test_items:\n            - flag: root:root\n              compare:\n                op: eq\n                value: root:root\n        remediation: |\n          Run the following command to modify the ownership of the --client-ca-file.\n          chown root:root $kubeletcafile\n        scored: true\n\n      - id: 4.1.9\n        text: \"Ensure that the kubelet --config configuration file has permissions set to 600 or more restrictive (Automated)\"\n        type: \"skip\"\n        audit: '/bin/sh -c ''if test -e $kubeletconf; then stat -c permissions=%a $kubeletconf; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Not Applicable.\n          The kubelet is embedded in the k3s process. There is no kubelet config file, all configuration is passed in as arguments at runtime.\n        scored: true\n\n      - id: 4.1.10\n        text: \"Ensure that the kubelet --config configuration file ownership is set to root:root (Automated)\"\n        type: \"skip\"\n        audit: '/bin/sh -c ''if test -e $kubeletconf; then stat -c %U:%G $kubeletconf; fi'' '\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Not Applicable.\n          The kubelet is embedded in the k3s process. There is no kubelet config file, all configuration is passed in as arguments at runtime.\n        scored: true\n\n  - id: 4.2\n    text: \"Kubelet\"\n    checks:\n      - id: 4.2.1\n        text: \"Ensure that the --anonymous-auth argument is set to false (Automated)\"\n        audit: '/bin/sh -c ''if test $(journalctl -m -u k3s | grep \"Running kubelet\" | wc -l) -gt 0; then journalctl -m -u k3s -u k3s-agent | grep \"Running kubelet\" | tail -n1 | grep \"anonymous-auth\" | grep -v grep; else echo \"--anonymous-auth=false\"; fi'' '\n        tests:\n          test_items:\n            - flag: \"--anonymous-auth\"\n              path: '{.authentication.anonymous.enabled}'\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          By default, K3s sets the --anonymous-auth to false. If you have set this to a different value, you\n          should set it back to false. If using the K3s config file /etc/rancher/k3s/config.yaml, remove any lines similar to below.\n          kubelet-arg:\n            - \"anonymous-auth=true\"\n          If using the command line, edit the K3s service file and remove the below argument.\n          --kubelet-arg=\"anonymous-auth=true\"\n          Based on your system, restart the k3s service. For example,\n          systemctl daemon-reload\n          systemctl restart k3s.service\n        scored: true\n\n      - id: 4.2.2\n        text: \"Ensure that the --authorization-mode argument is not set to AlwaysAllow (Automated)\"\n        audit: '/bin/sh -c ''if test $(journalctl -m -u k3s -u k3s-agent | grep \"Running kubelet\" | wc -l) -gt 0; then journalctl -m -u k3s -u k3s-agent | grep \"Running kubelet\" | tail -n1 | grep \"authorization-mode\"; else echo \"--authorization-mode=Webhook\"; fi'' '\n        audit_config: \"/bin/sh -c 'if test -e $kubeletconf; then /bin/cat $kubeletconf; fi' \"\n        tests:\n          test_items:\n            - flag: --authorization-mode\n              path: '{.authorization.mode}'\n              compare:\n                op: nothave\n                value: AlwaysAllow\n        remediation: |\n          By default, K3s does not set the --authorization-mode to AlwaysAllow.\n          If using the K3s config file /etc/rancher/k3s/config.yaml, remove any lines similar to below.\n          kubelet-arg:\n            - \"authorization-mode=AlwaysAllow\"\n          If using the command line, edit the K3s service file and remove the below argument.\n          --kubelet-arg=\"authorization-mode=AlwaysAllow\"\n          Based on your system, restart the k3s service. For example,\n          systemctl daemon-reload\n          systemctl restart k3s.service\n        scored: true\n\n      - id: 4.2.3\n        text: \"Ensure that the --client-ca-file argument is set as appropriate (Automated)\"\n        audit: '/bin/sh -c ''if test $(journalctl -m -u k3s -u k3s-agent | grep \"Running kubelet\" | wc -l) -gt 0; then journalctl -m -u k3s -u k3s-agent | grep \"Running kubelet\" | tail -n1 | grep \"client-ca-file\"; else echo \"--client-ca-file=/var/lib/rancher/k3s/server/tls/request-header-ca.crt\"; fi'' '\n        tests:\n          test_items:\n            - flag: --client-ca-file\n              path: '{.authentication.x509.clientCAFile}'\n        remediation: |\n          By default, K3s automatically provides the client ca certificate for the Kubelet.\n          It is generated and located at /var/lib/rancher/k3s/agent/client-ca.crt\n        scored: true\n\n      - id: 4.2.4\n        text: \"Verify that the --read-only-port argument is set to 0 (Automated)\"\n        audit: \"journalctl -m -u k3s -u k3s-agent | grep 'Running kubelet' | tail -n1\"\n        audit_config: \"/bin/sh -c 'if test -e $kubeletconf; then /bin/cat $kubeletconf; fi' \"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--read-only-port\"\n              path: '{.readOnlyPort}'\n              compare:\n                op: eq\n                value: 0\n            - flag: \"--read-only-port\"\n              path: '{.readOnlyPort}'\n              set: false\n        remediation: |\n          By default, K3s sets the --read-only-port to 0. If you have set this to a different value, you\n          should set it back to 0. If using the K3s config file /etc/rancher/k3s/config.yaml, remove any lines similar to below.\n          kubelet-arg:\n            - \"read-only-port=XXXX\"\n          If using the command line, edit the K3s service file and remove the below argument.\n          --kubelet-arg=\"read-only-port=XXXX\"\n          Based on your system, restart the k3s service. For example,\n          systemctl daemon-reload\n          systemctl restart k3s.service\n        scored: true\n\n      - id: 4.2.5\n        text: \"Ensure that the --streaming-connection-idle-timeout argument is not set to 0 (Manual)\"\n        audit: \"journalctl -m -u k3s -u k3s-agent | grep 'Running kubelet' | tail -n1\"\n        tests:\n          test_items:\n            - flag: --streaming-connection-idle-timeout\n              path: '{.streamingConnectionIdleTimeout}'\n              compare:\n                op: noteq\n                value: 0\n            - flag: --streaming-connection-idle-timeout\n              path: '{.streamingConnectionIdleTimeout}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using the K3s config file /etc/rancher/k3s/config.yaml, set the following parameter to an appropriate value.\n          kubelet-arg:\n            - \"streaming-connection-idle-timeout=5m\"\n          If using the command line, run K3s with --kubelet-arg=\"streaming-connection-idle-timeout=5m\".\n          Based on your system, restart the k3s service. For example,\n          systemctl restart k3s.service\n        scored: false\n\n      - id: 4.2.6\n        text: \"Ensure that the --make-iptables-util-chains argument is set to true (Automated)\"\n        audit: \"journalctl -m -u k3s -u k3s-agent | grep 'Running kubelet' | tail -n1\"\n        tests:\n          test_items:\n            - flag: --make-iptables-util-chains\n              path: '{.makeIPTablesUtilChains}'\n              compare:\n                op: eq\n                value: true\n            - flag: --make-iptables-util-chains\n              path: '{.makeIPTablesUtilChains}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using the K3s config file /etc/rancher/k3s/config.yaml, set the following parameter.\n          kubelet-arg:\n            - \"make-iptables-util-chains=true\"\n          If using the command line, run K3s with --kubelet-arg=\"make-iptables-util-chains=true\".\n          Based on your system, restart the k3s service. For example,\n          systemctl restart k3s.service\n        scored: true\n\n      - id: 4.2.7\n        text: \"Ensure that the --hostname-override argument is not set (Automated)\"\n        audit: \"journalctl -m -u k3s -u k3s-agent | grep 'Running kubelet' | tail -n1\"\n        type: \"skip\"\n        tests:\n          test_items:\n            - flag: --hostname-override\n              set: false\n        remediation: |\n          Not Applicable.\n          By default, K3s does set the --hostname-override argument. Per CIS guidelines, this is to comply\n          with cloud providers that require this flag to ensure that hostname matches node names.\n        scored: true\n\n      - id: 4.2.8\n        text: \"Ensure that the eventRecordQPS argument is set to a level which ensures appropriate event capture (Manual)\"\n        audit: \"journalctl -m -u k3s -u k3s-agent | grep 'Running kubelet' | tail -n1\"\n        audit_config: \"/bin/sh -c 'if test -e $kubeletconf; then /bin/cat $kubeletconf; fi' \"\n        tests:\n          test_items:\n            - flag: --event-qps\n              path: '{.eventRecordQPS}'\n              compare:\n                op: gte\n                value: 0\n            - flag: --event-qps\n              path: '{.eventRecordQPS}'\n              set: false\n          bin_op: or\n        remediation: |\n          By default, K3s sets the event-qps to 0. Should you wish to change this,\n          If using the K3s config file /etc/rancher/k3s/config.yaml, set the following parameter to an appropriate value.\n          kubelet-arg:\n            - \"event-qps=<value>\"\n          If using the command line, run K3s with --kubelet-arg=\"event-qps=<value>\".\n          Based on your system, restart the k3s service. For example,\n          systemctl restart k3s.service\n        scored: false\n\n      - id: 4.2.9\n        text: \"Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Automated)\"\n        audit: \"journalctl -m -u k3s -u k3s-agent | grep 'Running kubelet' | tail -n1\"\n        tests:\n          test_items:\n            - flag: --tls-cert-file\n              path: '/var/lib/rancher/k3s/agent/serving-kubelet.crt'\n            - flag: --tls-private-key-file\n              path: '/var/lib/rancher/k3s/agent/serving-kubelet.key'\n        remediation: |\n         By default, K3s automatically provides the TLS certificate and private key for the Kubelet.\n         They are generated and located at /var/lib/rancher/k3s/agent/serving-kubelet.crt and /var/lib/rancher/k3s/agent/serving-kubelet.key\n         If for some reason you need to provide your own certificate and key, you can set the\n         the below parameters in the K3s config file /etc/rancher/k3s/config.yaml.\n         kubelet-arg:\n         - \"tls-cert-file=<path/to/tls-cert-file>\"\n         - \"tls-private-key-file=<path/to/tls-private-key-file>\"\n        scored: true\n\n      - id: 4.2.10\n        text: \"Ensure that the --rotate-certificates argument is not set to false (Automated)\"\n        audit: \"journalctl -m -u k3s -u k3s-agent | grep 'Running kubelet' | tail -n1\"\n        audit_config: \"/bin/sh -c 'if test -e $kubeletconf; then /bin/cat $kubeletconf; fi' \"\n        tests:\n          test_items:\n            - flag: --rotate-certificates\n              path: '{.rotateCertificates}'\n              compare:\n                op: eq\n                value: true\n            - flag: --rotate-certificates\n              path: '{.rotateCertificates}'\n              set: false\n          bin_op: or\n        remediation: |\n          By default, K3s does not set the --rotate-certificates argument. If you have set this flag with a value of `false`, you should either set it to `true` or completely remove the flag.\n          If using the K3s config file /etc/rancher/k3s/config.yaml, remove any rotate-certificates parameter.\n          If using the command line, remove the K3s flag --kubelet-arg=\"rotate-certificates\".\n          Based on your system, restart the k3s service. For example,\n          systemctl restart k3s.service\n        scored: true\n\n      - id: 4.2.11\n        text: \"Verify that the RotateKubeletServerCertificate argument is set to true (Automated)\"\n        audit: \"journalctl -m -u k3s -u k3s-agent | grep 'Running kubelet' | tail -n1\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: RotateKubeletServerCertificate\n              path: '{.featureGates.RotateKubeletServerCertificate}'\n              compare:\n                op: nothave\n                value: false\n            - flag: RotateKubeletServerCertificate\n              path: '{.featureGates.RotateKubeletServerCertificate}'\n              set: false\n        remediation: |\n          By default, K3s does not set the RotateKubeletServerCertificate feature gate.\n          If you have enabled this feature gate, you should remove it.\n          If using the K3s config file /etc/rancher/k3s/config.yaml, remove any feature-gate=RotateKubeletServerCertificate parameter.\n          If using the command line, remove the K3s flag --kubelet-arg=\"feature-gate=RotateKubeletServerCertificate\".\n          Based on your system, restart the k3s service. For example,\n          systemctl restart k3s.service\n        scored: true\n\n      - id: 4.2.12\n        text: \"Ensure that the Kubelet only makes use of Strong Cryptographic Ciphers (Manual)\"\n        audit: \"journalctl -m -u k3s -u k3s-agent | grep 'Running kubelet' | tail -n1\"\n        audit_config: \"/bin/sh -c 'if test -e $kubeletconf; then /bin/cat $kubeletconf; fi' \"\n        tests:\n          test_items:\n            - flag: --tls-cipher-suites\n              path: '{range .tlsCipherSuites[:]}{}{'',''}{end}'\n              compare:\n                op: valid_elements\n                value: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\n        remediation: |\n          If using a K3s config file /etc/rancher/k3s/config.yaml, edit the file to set `tlsCipherSuites` to\n          kubelet-arg:\n            - \"tls-cipher-suites=TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305\"\n          or to a subset of these values.\n          If using the command line, add the K3s flag --kubelet-arg=\"tls-cipher-suites=<same values as above>\"\n          Based on your system, restart the k3s service. For example,\n          systemctl restart k3s.service\n        scored: false\n\n      - id: 4.2.13\n        text: \"Ensure that a limit is set on pod PIDs (Manual)\"\n        audit: \"journalctl -m -u k3s -u k3s-agent | grep 'Running kubelet' | tail -n1\"\n        audit_config: \"/bin/sh -c 'if test -e $kubeletconf; then /bin/cat $kubeletconf; fi' \"\n        tests:\n          test_items:\n            - flag: --pod-max-pids\n              path: '{.podPidsLimit}'\n        remediation: |\n          Decide on an appropriate level for this parameter and set it,\n          If using a K3s config file /etc/rancher/k3s/config.yaml, edit the file to set `podPidsLimit` to\n          kubelet-arg:\n            - \"pod-max-pids=<value>\"\n        scored: false\n"
  },
  {
    "path": "cfg/k3s-cis-1.7/policies.yaml",
    "content": "---\ncontrols:\nversion: \"k3s-cis-1.7\"\nid: 5\ntext: \"Kubernetes Policies\"\ntype: \"policies\"\ngroups:\n  - id: 5.1\n    text: \"RBAC and Service Accounts\"\n    checks:\n      - id: 5.1.1\n        text: \"Ensure that the cluster-admin role is only used where required (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Identify all clusterrolebindings to the cluster-admin role. Check if they are used and\n          if they need this role or if they could use a role with fewer privileges.\n          Where possible, first bind users to a lower privileged role and then remove the\n          clusterrolebinding to the cluster-admin role :\n          kubectl delete clusterrolebinding [name]\n        scored: false\n\n      - id: 5.1.2\n        text: \"Minimize access to secrets (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove get, list and watch access to Secret objects in the cluster.\n        scored: false\n\n      - id: 5.1.3\n        text: \"Minimize wildcard use in Roles and ClusterRoles (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible replace any use of wildcards in clusterroles and roles with specific\n          objects or actions.\n        scored: false\n\n      - id: 5.1.4\n        text: \"Minimize access to create pods (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove create access to pod objects in the cluster.\n        scored: false\n\n      - id: 5.1.5\n        text: \"Ensure that default service accounts are not actively used. (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Create explicit service accounts wherever a Kubernetes workload requires specific access\n          to the Kubernetes API server.\n          Modify the configuration of each default service account to include this value\n          automountServiceAccountToken: false\n        scored: false\n\n\n      - id: 5.1.6\n        text: \"Ensure that Service Account Tokens are only mounted where necessary (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Modify the definition of pods and service accounts which do not need to mount service\n          account tokens to disable it.\n        scored: false\n\n      - id: 5.1.7\n        text: \"Avoid use of system:masters group (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Remove the system:masters group from all users in the cluster.\n        scored: false\n\n      - id: 5.1.8\n        text: \"Limit use of the Bind, Impersonate and Escalate permissions in the Kubernetes cluster (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove the impersonate, bind and escalate rights from subjects.\n        scored: false\n\n      - id: 5.1.9\n        text: \"Minimize access to create persistent volumes (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove create access to PersistentVolume objects in the cluster.\n        scored: false\n\n      - id: 5.1.10\n        text: \"Minimize access to the proxy sub-resource of nodes (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove access to the proxy sub-resource of node objects.\n        scored: false\n\n      - id: 5.1.11\n        text: \"Minimize access to the approval sub-resource of certificatesigningrequests objects (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove access to the approval sub-resource of certificatesigningrequest objects.\n        scored: false\n\n      - id: 5.1.12\n        text: \"Minimize access to webhook configuration objects (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove access to the validatingwebhookconfigurations or mutatingwebhookconfigurations objects\n        scored: false\n\n      - id: 5.1.13\n        text: \"Minimize access to the service account token creation (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove access to the token sub-resource of serviceaccount objects.\n        scored: false\n\n  - id: 5.2\n    text: \"Pod Security Standards\"\n    checks:\n      - id: 5.2.1\n        text: \"Ensure that the cluster has at least one active policy control mechanism in place (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that either Pod Security Admission or an external policy control system is in place\n          for every namespace which contains user workloads.\n        scored: false\n\n      - id: 5.2.2\n        text: \"Minimize the admission of privileged containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of privileged containers.\n        scored: false\n\n      - id: 5.2.3\n        text: \"Minimize the admission of containers wishing to share the host process ID namespace (Automated)\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of `hostPID` containers.\n        scored: false\n\n      - id: 5.2.4\n        text: \"Minimize the admission of containers wishing to share the host IPC namespace (Automated)\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of `hostIPC` containers.\n        scored: false\n\n      - id: 5.2.5\n        text: \"Minimize the admission of containers wishing to share the host network namespace (Automated)\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of `hostNetwork` containers.\n        scored: false\n\n      - id: 5.2.6\n        text: \"Minimize the admission of containers with allowPrivilegeEscalation (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers with `.spec.allowPrivilegeEscalation` set to `true`.\n        scored: true\n\n      - id: 5.2.7\n        text: \"Minimize the admission of root containers (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Create a policy for each namespace in the cluster, ensuring that either `MustRunAsNonRoot`\n          or `MustRunAs` with the range of UIDs not including 0, is set.\n        scored: false\n\n      - id: 5.2.8\n        text: \"Minimize the admission of containers with the NET_RAW capability (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers with the `NET_RAW` capability.\n        scored: false\n\n      - id: 5.2.9\n        text: \"Minimize the admission of containers with added capabilities (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that `allowedCapabilities` is not present in policies for the cluster unless\n          it is set to an empty array.\n        scored: false\n\n      - id: 5.2.10\n        text: \"Minimize the admission of containers with capabilities assigned (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Review the use of capabilities in applications running on your cluster. Where a namespace\n          contains applications which do not require any Linux capabities to operate consider adding\n          a PSP which forbids the admission of containers which do not drop all capabilities.\n        scored: false\n\n      - id: 5.2.11\n        text: \"Minimize the admission of Windows HostProcess containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers that have `.securityContext.windowsOptions.hostProcess` set to `true`.\n        scored: false\n\n      - id: 5.2.12\n        text: \"Minimize the admission of HostPath volumes (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers with `hostPath` volumes.\n        scored: false\n\n      - id: 5.2.13\n        text: \"Minimize the admission of containers which use HostPorts (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers which use `hostPort` sections.\n        scored: false\n\n  - id: 5.3\n    text: \"Network Policies and CNI\"\n    checks:\n      - id: 5.3.1\n        text: \"Ensure that the CNI in use supports NetworkPolicies (Manual)\"\n        type: \"manual\"\n        remediation: |\n          If the CNI plugin in use does not support network policies, consideration should be given to\n          making use of a different plugin, or finding an alternate mechanism for restricting traffic\n          in the Kubernetes cluster.\n        scored: false\n\n      - id: 5.3.2\n        text: \"Ensure that all Namespaces have NetworkPolicies defined (Manual)\"\n        remediation: |\n          Follow the documentation and create NetworkPolicy objects as you need them.\n        scored: false\n\n  - id: 5.4\n    text: \"Secrets Management\"\n    checks:\n      - id: 5.4.1\n        text: \"Prefer using Secrets as files over Secrets as environment variables (Manual)\"\n        type: \"manual\"\n        remediation: |\n          If possible, rewrite application code to read Secrets from mounted secret files, rather than\n          from environment variables.\n        scored: false\n\n      - id: 5.4.2\n        text: \"Consider external secret storage (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Refer to the Secrets management options offered by your cloud provider or a third-party\n          secrets management solution.\n        scored: false\n\n  - id: 5.5\n    text: \"Extensible Admission Control\"\n    checks:\n      - id: 5.5.1\n        text: \"Configure Image Provenance using ImagePolicyWebhook admission controller (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and setup image provenance.\n        scored: false\n\n  - id: 5.7\n    text: \"General Policies\"\n    checks:\n      - id: 5.7.1\n        text: \"Create administrative boundaries between resources using namespaces (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the documentation and create namespaces for objects in your deployment as you need\n          them.\n        scored: false\n\n      - id: 5.7.2\n        text: \"Ensure that the seccomp profile is set to docker/default in your Pod definitions (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Use `securityContext` to enable the docker/default seccomp profile in your pod definitions.\n          An example is as below:\n            securityContext:\n              seccompProfile:\n                type: RuntimeDefault\n        scored: false\n\n      - id: 5.7.3\n        text: \"Apply SecurityContext to your Pods and Containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and apply SecurityContexts to your Pods. For a\n          suggested list of SecurityContexts, you may refer to the CIS Security Benchmark for Docker\n          Containers.\n        scored: false\n\n      - id: 5.7.4\n        text: \"The default namespace should not be used (Manual)\"\n        remediation: |\n          Ensure that namespaces are created to allow for appropriate segregation of Kubernetes\n          resources and that all new resources are created in a specific namespace.\n        scored: false\n"
  },
  {
    "path": "cfg/k3s-cis-1.8/config.yaml",
    "content": "---\n## Version-specific settings that override the values in cfg/config.yaml\n\nmaster:\n  components:\n    - apiserver\n    - kubelet\n    - scheduler\n    - controllermanager\n    - etcd\n    - policies\n  apiserver:\n    bins:\n      - containerd\n  kubelet:\n    bins:\n      - containerd\n    defaultkubeconfig: /var/lib/rancher/k3s/agent/kubelet.kubeconfig\n    defaultcafile: /var/lib/rancher/k3s/agent/client-ca.crt\n  scheduler:\n    bins:\n      - containerd\n    kubeconfig:\n      - /var/lib/rancher/k3s/server/cred/scheduler.kubeconfig\n  controllermanager:\n    bins:\n      - containerd\n    kubeconfig:\n      - /var/lib/rancher/k3s/server/cred/controller.kubeconfig\n  etcd:\n    bins:\n      - containerd\n\netcd:\n  confs: /var/lib/rancher/k3s/server/db/etcd/config\n\nnode:\n  components:\n    - kubelet\n    - proxy\n  kubelet:\n    bins:\n      - containerd\n    confs:\n      - /var/lib/rancher/k3s/agent/kubelet.kubeconfig\n    defaultkubeconfig: /var/lib/rancher/k3s/agent/kubelet.kubeconfig\n    defaultcafile: /var/lib/rancher/k3s/agent/client-ca.crt\n  proxy:\n    bins:\n      - containerd\n    defaultkubeconfig: /var/lib/rancher/k3s/agent/kubeproxy.kubeconfig\npolicies:\n  components:\n    - policies\n"
  },
  {
    "path": "cfg/k3s-cis-1.8/controlplane.yaml",
    "content": "---\ncontrols:\nversion: \"k3s-cis-1.8\"\nid: 3\ntext: \"Control Plane Configuration\"\ntype: \"controlplane\"\ngroups:\n  - id: 3.1\n    text: \"Authentication and Authorization\"\n    checks:\n      - id: 3.1.1\n        text: \"Client certificate authentication should not be used for users (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Alternative mechanisms provided by Kubernetes such as the use of OIDC should be\n          implemented in place of client certificates.\n        scored: false\n\n      - id: 3.1.2\n        text: \"Service account token authentication should not be used for users (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Alternative mechanisms provided by Kubernetes such as the use of OIDC should be implemented\n          in place of service account tokens.\n        scored: false\n\n      - id: 3.1.3\n        text: \"Bootstrap token authentication should not be used for users (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Alternative mechanisms provided by Kubernetes such as the use of OIDC should be implemented\n          in place of bootstrap tokens.\n        scored: false\n\n  - id: 3.2\n    text: \"Logging\"\n    checks:\n      - id: 3.2.1\n        text: \"Ensure that a minimal audit policy is created (Manual)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'audit-policy-file'\"\n        tests:\n          test_items:\n            - flag: \"--audit-policy-file\"\n              set: true\n        remediation: |\n          Create an audit policy file for your cluster.\n        scored: false\n\n      - id: 3.2.2\n        text: \"Ensure that the audit policy covers key security concerns (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Review the audit policy provided for the cluster and ensure that it covers\n          at least the following areas,\n          - Access to Secrets managed by the cluster. Care should be taken to only\n            log Metadata for requests to Secrets, ConfigMaps, and TokenReviews, in\n            order to avoid risk of logging sensitive data.\n          - Modification of Pod and Deployment objects.\n          - Use of `pods/exec`, `pods/portforward`, `pods/proxy` and `services/proxy`.\n          For most requests, minimally logging at the Metadata level is recommended\n          (the most basic level of logging).\n        scored: false\n"
  },
  {
    "path": "cfg/k3s-cis-1.8/etcd.yaml",
    "content": "---\ncontrols:\nversion: \"k3s-cis-1.8\"\nid: 2\ntext: \"Etcd Node Configuration\"\ntype: \"etcd\"\ngroups:\n  - id: 2\n    text: \"Etcd Node Configuration\"\n    checks:\n      - id: 2.1\n        text: \"Ensure that the --cert-file and --key-file arguments are set as appropriate (Automated)\"\n        audit_config: \"cat $etcdconf\"\n        tests:\n          bin_op: and\n          test_items:\n            - path: \"{.client-transport-security.cert-file}\"\n              compare:\n                op: eq\n                value: \"/var/lib/rancher/k3s/server/tls/etcd/server-client.crt\"\n            - path: \"{.client-transport-security.key-file}\"\n              compare:\n                op: eq\n                value: \"/var/lib/rancher/k3s/server/tls/etcd/server-client.key\"\n        remediation: |\n          If running on with sqlite or a external DB, etcd checks are Not Applicable.\n          When running with embedded-etcd, K3s generates cert and key files for etcd.\n          These are located in /var/lib/rancher/k3s/server/tls/etcd/.\n          If this check fails, ensure that the configuration file $etcdconf\n          has not been modified to use custom cert and key files.\n        scored: false\n\n      - id: 2.2\n        text: \"Ensure that the --client-cert-auth argument is set to true (Automated)\"\n        audit_config: \"cat $etcdconf\"\n        tests:\n          test_items:\n            - path: \"{.client-transport-security.client-cert-auth}\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          If running on with sqlite or a external DB, etcd checks are Not Applicable.\n          When running with embedded-etcd, K3s sets the --client-cert-auth parameter to true.\n          If this check fails, ensure that the configuration file $etcdconf\n          has not been modified to disable client certificate authentication.\n        scored: false\n\n      - id: 2.3\n        text: \"Ensure that the --auto-tls argument is not set to true (Automated)\"\n        audit_config: \"cat $etcdconf\"\n        tests:\n          bin_op: or\n          test_items:\n            - path: \"{.client-transport-security.auto-tls}\"\n              compare:\n                op: eq\n                value: false\n            - path: \"{.client-transport-security.auto-tls}\"\n              set: false\n        remediation: |\n          If running on with sqlite or a external DB, etcd checks are Not Applicable.\n          When running with embedded-etcd, K3s does not set the --auto-tls parameter.\n          If this check fails, edit the etcd pod specification file $etcdconf on the master\n          node and either remove the --auto-tls parameter or set it to false.\n          client-transport-security:\n            auto-tls: false\n        scored: false\n\n      - id: 2.4\n        text: \"Ensure that the --peer-cert-file and --peer-key-file arguments are set as appropriate (Automated)\"\n        audit_config: \"cat $etcdconf\"\n        tests:\n          bin_op: and\n          test_items:\n            - path: \"{.peer-transport-security.cert-file}\"\n              compare:\n                op: eq\n                value: \"/var/lib/rancher/k3s/server/tls/etcd/peer-server-client.crt\"\n            - path: \"{.peer-transport-security.key-file}\"\n              compare:\n                op: eq\n                value: \"/var/lib/rancher/k3s/server/tls/etcd/peer-server-client.key\"\n        remediation: |\n          If running on with sqlite or a external DB, etcd checks are Not Applicable.\n          When running with embedded-etcd, K3s generates peer cert and key files for etcd.\n          These are located in /var/lib/rancher/k3s/server/tls/etcd/.\n          If this check fails, ensure that the configuration file $etcdconf\n          has not been modified to use custom peer cert and key files.\n        scored: false\n\n      - id: 2.5\n        text: \"Ensure that the --peer-client-cert-auth argument is set to true (Automated)\"\n        audit_config: \"cat $etcdconf\"\n        tests:\n          test_items:\n            - path: \"{.peer-transport-security.client-cert-auth}\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          If running on with sqlite or a external DB, etcd checks are Not Applicable.\n          When running with embedded-etcd, K3s sets the --peer-cert-auth parameter to true.\n          If this check fails, ensure that the configuration file $etcdconf\n          has not been modified to disable peer client certificate authentication.\n        scored: false\n\n      - id: 2.6\n        text: \"Ensure that the --peer-auto-tls argument is not set to true (Automated)\"\n        audit_config: \"cat $etcdconf\"\n        tests:\n          bin_op: or\n          test_items:\n            - path: \"{.peer-transport-security.auto-tls}\"\n              compare:\n                op: eq\n                value: false\n            - path: \"{.peer-transport-security.auto-tls}\"\n              set: false\n        remediation: |\n          If running on with sqlite or a external DB, etcd checks are Not Applicable.\n          When running with embedded-etcd, K3s does not set the --peer-auto-tls parameter.\n          If this check fails, edit the etcd pod specification file $etcdconf on the master\n          node and either remove the --peer-auto-tls parameter or set it to false.\n          peer-transport-security:\n            auto-tls: false\n        scored: false\n\n      - id: 2.7\n        text: \"Ensure that a unique Certificate Authority is used for etcd (Automated)\"\n        audit_config: \"cat $etcdconf\"\n        tests:\n          test_items:\n            - path: \"{.peer-transport-security.trusted-ca-file}\"\n              compare:\n                op: eq\n                value: \"/var/lib/rancher/k3s/server/tls/etcd/peer-ca.crt\"\n        remediation: |\n          If running on with sqlite or a external DB, etcd checks are Not Applicable.\n          When running with embedded-etcd, K3s generates a unique certificate authority for etcd.\n          This is located at /var/lib/rancher/k3s/server/tls/etcd/peer-ca.crt.\n          If this check fails, ensure that the configuration file $etcdconf\n          has not been modified to use a shared certificate authority.\n        scored: false\n"
  },
  {
    "path": "cfg/k3s-cis-1.8/master.yaml",
    "content": "---\ncontrols:\nversion: \"k3s-cis-1.8\"\nid: 1\ntext: \"Control Plane Security Configuration\"\ntype: \"master\"\ngroups:\n  - id: 1.1\n    text: \"Control Plane Node Configuration Files\"\n    checks:\n      - id: 1.1.1\n        text: \"Ensure that the API server pod specification file permissions are set to 600 or more restrictive (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/sh -c 'if test -e $apiserverconf; then stat -c permissions=%a $apiserverconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Not Applicable.\n          By default, K3s embeds the api server within the k3s process. There is no API server pod specification file.\n        scored: true\n\n      - id: 1.1.2\n        text: \"Ensure that the API server pod specification file ownership is set to root:root (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/sh -c 'if test -e $apiserverconf; then stat -c %U:%G $apiserverconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Not Applicable.\n          By default, K3s embeds the api server within the k3s process. There is no API server pod specification file.\n        scored: true\n\n      - id: 1.1.3\n        text: \"Ensure that the controller manager pod specification file permissions are set to 600 or more restrictive (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerconf; then stat -c permissions=%a $controllermanagerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Not Applicable.\n          By default, K3s embeds the controller manager within the k3s process. There is no controller manager pod specification file.\n        scored: true\n\n      - id: 1.1.4\n        text: \"Ensure that the controller manager pod specification file ownership is set to root:root (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerconf; then stat -c %U:%G $controllermanagerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Not Applicable.\n          By default, K3s embeds the controller manager within the k3s process. There is no controller manager pod specification file.\n        scored: true\n\n      - id: 1.1.5\n        text: \"Ensure that the scheduler pod specification file permissions are set to 600 or more restrictive (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/sh -c 'if test -e $schedulerconf; then stat -c permissions=%a $schedulerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Not Applicable.\n          By default, K3s embeds the scheduler within the k3s process. There is no scheduler pod specification file.\n        scored: true\n\n      - id: 1.1.6\n        text: \"Ensure that the scheduler pod specification file ownership is set to root:root (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/sh -c 'if test -e $schedulerconf; then stat -c %U:%G $schedulerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Not Applicable.\n          By default, K3s embeds the scheduler within the k3s process. There is no scheduler pod specification file.\n        scored: true\n\n      - id: 1.1.7\n        text: \"Ensure that the etcd pod specification file permissions are set to 600 or more restrictive (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/sh -c 'if test -e $etcdconf; then find $etcdconf -name '*etcd*' | xargs stat -c permissions=%a; fi'\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Not Applicable.\n          By default, K3s embeds etcd within the k3s process. There is no etcd pod specification file.\n        scored: true\n\n      - id: 1.1.8\n        text: \"Ensure that the etcd pod specification file ownership is set to root:root (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/sh -c 'if test -e $etcdconf; then find $etcdconf -name '*etcd*' | xargs stat -c %U:%G; fi'\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Not Applicable.\n          By default, K3s embeds etcd within the k3s process. There is no etcd pod specification file.\n        scored: true\n\n      - id: 1.1.9\n        text: \"Ensure that the Container Network Interface file permissions are set to 600 or more restrictive (Automated)\"\n        audit: find /var/lib/cni/networks -type f ! -name lock 2> /dev/null | xargs --no-run-if-empty stat -c permissions=%a\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          By default, K3s sets the CNI file permissions to 600.\n          Note that for many CNIs, a lock file is created with permissions 750. This is expected and can be ignored.\n          If you modify your CNI configuration, ensure that the permissions are set to 600.\n          For example, chmod 600 /var/lib/cni/networks/<filename>\n        scored: true\n\n      - id: 1.1.10\n        text: \"Ensure that the Container Network Interface file ownership is set to root:root (Automated)\"\n        audit: find /var/lib/cni/networks -type f 2> /dev/null | xargs --no-run-if-empty stat -c %U:%G\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root /var/lib/cni/networks/<filename>\n        scored: true\n\n      - id: 1.1.11\n        text: \"Ensure that the etcd data directory permissions are set to 700 or more restrictive (Automated)\"\n        audit: |\n          if [ \"$(journalctl -m -u k3s | grep -m1 'Managed etcd cluster' | wc -l)\" -gt 0 ]; then\n            stat -c permissions=%a /var/lib/rancher/k3s/server/db/etcd\n          else\n            echo \"permissions=700\"\n          fi\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"700\"\n        remediation: |\n          On the etcd server node, get the etcd data directory, passed as an argument --data-dir,\n          from the command 'ps -ef | grep etcd'.\n          Run the below command (based on the etcd data directory found above). For example,\n          chmod 700 /var/lib/etcd\n        scored: true\n\n      - id: 1.1.12\n        text: \"Ensure that the etcd data directory ownership is set to etcd:etcd (Automated)\"\n        audit: ps -ef | grep $etcdbin | grep -- --data-dir | sed 's%.*data-dir[= ]\\([^ ]*\\).*%\\1%' | xargs stat -c %U:%G\n        type: \"skip\"\n        tests:\n          test_items:\n            - flag: \"etcd:etcd\"\n        remediation: |\n          Not Applicable.\n          For K3s, etcd is embedded within the k3s process. There is no separate etcd process.\n          Therefore the etcd data directory ownership is managed by the k3s process and should be root:root.\n        scored: true\n\n      - id: 1.1.13\n        text: \"Ensure that the admin.conf file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e /var/lib/rancher/k3s/server/cred/admin.kubeconfig; then stat -c permissions=%a /var/lib/rancher/k3s/server/cred/admin.kubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chmod 600 /var/lib/rancher/k3s/server/cred/admin.kubeconfig\n        scored: true\n\n      - id: 1.1.14\n        text: \"Ensure that the admin.conf file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e /var/lib/rancher/k3s/server/cred/admin.kubeconfig; then stat -c %U:%G /var/lib/rancher/k3s/server/cred/admin.kubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n              compare:\n                op: eq\n                value: \"root:root\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chown root:root /var/lib/rancher/k3s/server/cred/admin.kubeconfig\n        scored: true\n\n      - id: 1.1.15\n        text: \"Ensure that the scheduler.conf file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerkubeconfig; then stat -c permissions=%a $schedulerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod 600 $schedulerkubeconfig\n        scored: true\n\n      - id: 1.1.16\n        text: \"Ensure that the scheduler.conf file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerkubeconfig; then stat -c %U:%G $schedulerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root $schedulerkubeconfig\n        scored: true\n\n      - id: 1.1.17\n        text: \"Ensure that the controller-manager.conf file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerkubeconfig; then stat -c permissions=%a $controllermanagerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod 600 $controllermanagerkubeconfig\n        scored: true\n\n      - id: 1.1.18\n        text: \"Ensure that the controller-manager.conf file ownership is set to root:root (Automated)\"\n        audit: \"stat -c %U:%G $controllermanagerkubeconfig\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n              compare:\n                op: eq\n                value: \"root:root\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root $controllermanagerkubeconfig\n        scored: true\n\n      - id: 1.1.19\n        text: \"Ensure that the Kubernetes PKI directory and file ownership is set to root:root (Automated)\"\n        audit: \"stat -c %U:%G /var/lib/rancher/k3s/server/tls\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown -R root:root /var/lib/rancher/k3s/server/tls\n        scored: true\n\n      - id: 1.1.20\n        text: \"Ensure that the Kubernetes PKI certificate file permissions are set to 600 or more restrictive (Manual)\"\n        audit: \"/bin/sh -c 'stat -c permissions=%a /var/lib/rancher/k3s/server/tls/*.crt'\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chmod -R 600 /var/lib/rancher/k3s/server/tls/*.crt\n        scored: false\n\n      - id: 1.1.21\n        text: \"Ensure that the Kubernetes PKI key file permissions are set to 600 (Automated)\"\n        audit: \"/bin/sh -c 'stat -c permissions=%a /var/lib/rancher/k3s/server/tls/*.key'\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chmod -R 600 /var/lib/rancher/k3s/server/tls/*.key\n        scored: true\n\n  - id: 1.2\n    text: \"API Server\"\n    checks:\n      - id: 1.2.1\n        text: \"Ensure that the --anonymous-auth argument is set to false (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'anonymous-auth'\"\n        tests:\n          test_items:\n            - flag: \"--anonymous-auth\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          By default, K3s sets the --anonymous-auth argument to false.\n          If this check fails, edit the K3s config file /etc/rancher/k3s/config.yaml and remove anything similar to below.\n          kube-apiserver-arg:\n            - \"anonymous-auth=true\"\n        scored: true\n\n      - id: 1.2.2\n        text: \"Ensure that the --token-auth-file parameter is not set (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1\"\n        tests:\n          test_items:\n            - flag: \"--token-auth-file\"\n              set: false\n        remediation: |\n          Follow the documentation and configure alternate mechanisms for authentication.\n          If this check fails, edit the K3s config file /etc/rancher/k3s/config.yaml and remove anything similar to below.\n          kube-apiserver-arg:\n            - \"token-auth-file=<path>\"\n        scored: true\n\n      - id: 1.2.3\n        text: \"Ensure that the --DenyServiceExternalIPs is not set (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: nothave\n                value: \"DenyServiceExternalIPs\"\n              set: true\n            - flag: \"--enable-admission-plugins\"\n              set: false\n        remediation: |\n          By default, K3s does not set DenyServiceExternalIPs.\n          If this check fails, edit the K3s config file /etc/rancher/k3s/config.yaml, remove any lines like below.\n          kube-apiserver-arg:\n            - \"enable-admission-plugins=DenyServiceExternalIPs\"\n        scored: true\n\n      - id: 1.2.4\n        text: \"Ensure that the --kubelet-client-certificate and --kubelet-client-key arguments are set as appropriate (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--kubelet-client-certificate\"\n            - flag: \"--kubelet-client-key\"\n        remediation: |\n          By default, K3s automatically provides the kubelet client certificate and key.\n          They are generated and located at /var/lib/rancher/k3s/server/tls/client-kube-apiserver.crt and /var/lib/rancher/k3s/server/tls/client-kube-apiserver.key\n          If for some reason you need to provide your own certificate and key, you can set the\n          below parameters in the K3s config file /etc/rancher/k3s/config.yaml.\n          kube-apiserver-arg:\n            - \"kubelet-client-certificate=<path/to/client-cert-file>\"\n            - \"kubelet-client-key=<path/to/client-key-file>\"\n        scored: true\n\n      - id: 1.2.5\n        text: \"Ensure that the --kubelet-certificate-authority argument is set as appropriate (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'kubelet-certificate-authority'\"\n        tests:\n          test_items:\n            - flag: \"--kubelet-certificate-authority\"\n        remediation: |\n          By default, K3s automatically provides the kubelet CA cert file, at /var/lib/rancher/k3s/server/tls/server-ca.crt.\n          If for some reason you need to provide your own ca certificate, look at using the k3s certificate command line tool.\n          If this check fails, edit the K3s config file /etc/rancher/k3s/config.yaml and remove any lines like below.\n          kube-apiserver-arg:\n            - \"kubelet-certificate-authority=<path/to/ca-cert-file>\"\n        scored: true\n\n      - id: 1.2.6\n        text: \"Ensure that the --authorization-mode argument is not set to AlwaysAllow (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'authorization-mode'\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: nothave\n                value: \"AlwaysAllow\"\n        remediation: |\n          By default, K3s does not set the --authorization-mode to AlwaysAllow.\n          If this check fails, edit K3s config file /etc/rancher/k3s/config.yaml, remove any lines like below.\n          kube-apiserver-arg:\n            - \"authorization-mode=AlwaysAllow\"\n        scored: true\n\n      - id: 1.2.7\n        text: \"Ensure that the --authorization-mode argument includes Node (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'authorization-mode'\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: has\n                value: \"Node\"\n        remediation: |\n          By default, K3s sets the --authorization-mode to Node and RBAC.\n          If this check fails, edit the K3s config file /etc/rancher/k3s/config.yaml,\n          ensure that you are not overriding authorization-mode.\n        scored: true\n\n      - id: 1.2.8\n        text: \"Ensure that the --authorization-mode argument includes RBAC (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'authorization-mode'\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: has\n                value: \"RBAC\"\n        remediation: |\n          By default, K3s sets the --authorization-mode to Node and RBAC.\n          If this check fails, edit the K3s config file /etc/rancher/k3s/config.yaml,\n          ensure that you are not overriding authorization-mode.\n        scored: true\n\n      - id: 1.2.9\n        text: \"Ensure that the admission control plugin EventRateLimit is set (Manual)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'enable-admission-plugins'\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"EventRateLimit\"\n        remediation: |\n          Follow the Kubernetes documentation and set the desired limits in a configuration file.\n          Then, edit the K3s config file /etc/rancher/k3s/config.yaml and set the below parameters.\n          kube-apiserver-arg:\n            - \"enable-admission-plugins=...,EventRateLimit,...\"\n            - \"admission-control-config-file=<path/to/configuration/file>\"\n        scored: false\n\n      - id: 1.2.10\n        text: \"Ensure that the admission control plugin AlwaysAdmit is not set (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'enable-admission-plugins'\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: nothave\n                value: AlwaysAdmit\n            - flag: \"--enable-admission-plugins\"\n              set: false\n        remediation: |\n          By default, K3s does not set the --enable-admission-plugins to AlwaysAdmit.\n          If this check fails, edit K3s config file /etc/rancher/k3s/config.yaml, remove any lines like below.\n          kube-apiserver-arg:\n            - \"enable-admission-plugins=AlwaysAdmit\"\n        scored: true\n\n      - id: 1.2.11\n        text: \"Ensure that the admission control plugin AlwaysPullImages is set (Manual)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"AlwaysPullImages\"\n        remediation: |\n          Permissive, per CIS guidelines,\n          \"This setting could impact offline or isolated clusters, which have images pre-loaded and\n          do not have access to a registry to pull in-use images. This setting is not appropriate for\n          clusters which use this configuration.\"\n          Edit the K3s config file /etc/rancher/k3s/config.yaml and set the below parameter.\n          kube-apiserver-arg:\n            - \"enable-admission-plugins=...,AlwaysPullImages,...\"\n        scored: false\n\n      - id: 1.2.12\n        text: \"Ensure that the admission control plugin SecurityContextDeny is set if PodSecurityPolicy is not used (Manual)\"\n        type: \"skip\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"SecurityContextDeny\"\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"PodSecurityPolicy\"\n        remediation: |\n          Not Applicable.\n          Enabling Pod Security Policy is no longer supported on K3s v1.25+ and will cause applications to unexpectedly fail.\n        scored: false\n\n      - id: 1.2.13\n        text: \"Ensure that the admission control plugin ServiceAccount is set (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--disable-admission-plugins\"\n              compare:\n                op: nothave\n                value: \"ServiceAccount\"\n            - flag: \"--disable-admission-plugins\"\n              set: false\n        remediation: |\n          By default, K3s does not set the --disable-admission-plugins to anything.\n          Follow the documentation and create ServiceAccount objects as per your environment.\n          If this check fails, edit the K3s config file /etc/rancher/k3s/config.yaml and remove any lines like below.\n          kube-apiserver-arg:\n            - \"disable-admission-plugins=ServiceAccount\"\n        scored: true\n\n      - id: 1.2.14\n        text: \"Ensure that the admission control plugin NamespaceLifecycle is set (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--disable-admission-plugins\"\n              compare:\n                op: nothave\n                value: \"NamespaceLifecycle\"\n            - flag: \"--disable-admission-plugins\"\n              set: false\n        remediation: |\n          By default, K3s does not set the --disable-admission-plugins to anything.\n          If this check fails, edit the K3s config file /etc/rancher/k3s/config.yaml and remove any lines like below.\n          kube-apiserver-arg:\n            - \"disable-admission-plugins=...,NamespaceLifecycle,...\"\n        scored: true\n\n      - id: 1.2.15\n        text: \"Ensure that the admission control plugin NodeRestriction is set (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'enable-admission-plugins'\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"NodeRestriction\"\n        remediation: |\n          By default, K3s sets the --enable-admission-plugins to NodeRestriction.\n          If using the K3s config file /etc/rancher/k3s/config.yaml, check that you are not overriding the admission plugins.\n          If you are, include NodeRestriction in the list.\n          kube-apiserver-arg:\n            - \"enable-admission-plugins=...,NodeRestriction,...\"\n        scored: true\n\n      - id: 1.2.16\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'profiling'\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          By default, K3s sets the --profiling argument to false.\n          If this check fails, edit the K3s config file /etc/rancher/k3s/config.yaml and remove any lines like below.\n          kube-apiserver-arg:\n            - \"profiling=true\"\n        scored: true\n\n      - id: 1.2.17\n        text: \"Ensure that the --audit-log-path argument is set (Manual)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-path\"\n        remediation: |\n          Edit the K3s config file /etc/rancher/k3s/config.yaml and set the audit-log-path parameter to a suitable path and\n          file where you would like audit logs to be written, for example,\n          kube-apiserver-arg:\n            - \"audit-log-path=/var/lib/rancher/k3s/server/logs/audit.log\"\n        scored: false\n\n      - id: 1.2.18\n        text: \"Ensure that the --audit-log-maxage argument is set to 30 or as appropriate (Manual)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxage\"\n              compare:\n                op: gte\n                value: 30\n        remediation: |\n          Edit the K3s config file /etc/rancher/k3s/config.yaml on the control plane node and\n          set the audit-log-maxage parameter to 30 or as an appropriate number of days, for example,\n          kube-apiserver-arg:\n            - \"audit-log-maxage=30\"\n        scored: false\n\n      - id: 1.2.19\n        text: \"Ensure that the --audit-log-maxbackup argument is set to 10 or as appropriate (Manual)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxbackup\"\n              compare:\n                op: gte\n                value: 10\n        remediation: |\n          Edit the K3s config file /etc/rancher/k3s/config.yaml on the control plane node and\n          set the audit-log-maxbackup parameter to 10 or to an appropriate value. For example,\n          kube-apiserver-arg:\n            - \"audit-log-maxbackup=10\"\n        scored: false\n\n      - id: 1.2.20\n        text: \"Ensure that the --audit-log-maxsize argument is set to 100 or as appropriate (Manual)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxsize\"\n              compare:\n                op: gte\n                value: 100\n        remediation: |\n          Edit the K3s config file /etc/rancher/k3s/config.yaml on the control plane node and\n          set the audit-log-maxsize parameter to an appropriate size in MB. For example,\n          kube-apiserver-arg:\n            - \"audit-log-maxsize=100\"\n        scored: false\n\n      - id: 1.2.21\n        text: \"Ensure that the --request-timeout argument is set as appropriate (Manual)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1\"\n        tests:\n          test_items:\n            - flag: \"--request-timeout\"\n        remediation: |\n          Permissive, per CIS guidelines,\n          \"it is recommended to set this limit as appropriate and change the default limit of 60 seconds only if needed\".\n          Edit the K3s config file /etc/rancher/k3s/config.yaml\n          and set the below parameter if needed. For example,\n          kube-apiserver-arg:\n            - \"request-timeout=300s\"\n        scored: false\n\n      - id: 1.2.22\n        text: \"Ensure that the --service-account-lookup argument is set to true (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--service-account-lookup\"\n              set: false\n            - flag: \"--service-account-lookup\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          By default, K3s does not set the --service-account-lookup argument.\n          Edit the K3s config file /etc/rancher/k3s/config.yaml and set the service-account-lookup. For example,\n          kube-apiserver-arg:\n            - \"service-account-lookup=true\"\n          Alternatively, you can delete the service-account-lookup parameter from this file so\n          that the default takes effect.\n        scored: true\n\n      - id: 1.2.23\n        text: \"Ensure that the --service-account-key-file argument is set as appropriate (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1\"\n        tests:\n          test_items:\n            - flag: \"--service-account-key-file\"\n        remediation: |\n          K3s automatically generates and sets the service account key file.\n          It is located at /var/lib/rancher/k3s/server/tls/service.key.\n          If this check fails, edit K3s config file /etc/rancher/k3s/config.yaml and remove any lines like below.\n          kube-apiserver-arg:\n            - \"service-account-key-file=<path>\"\n        scored: true\n\n      - id: 1.2.24\n        text: \"Ensure that the --etcd-certfile and --etcd-keyfile arguments are set as appropriate (Automated)\"\n        audit: |\n          if [ \"$(journalctl -m -u k3s | grep -m1 'Managed etcd cluster' | wc -l)\" -gt 0 ]; then\n            journalctl -m -u k3s | grep -m1 'Running kube-apiserver' | tail -n1\n          else\n            echo \"--etcd-certfile AND --etcd-keyfile\"\n          fi\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--etcd-certfile\"\n              set: true\n            - flag: \"--etcd-keyfile\"\n              set: true\n        remediation: |\n          K3s automatically generates and sets the etcd certificate and key files.\n          They are located at /var/lib/rancher/k3s/server/tls/etcd/client.crt and /var/lib/rancher/k3s/server/tls/etcd/client.key.\n          If this check fails, edit the K3s config file /etc/rancher/k3s/config.yaml and remove any lines like below.\n          kube-apiserver-arg:\n            - \"etcd-certfile=<path>\"\n            - \"etcd-keyfile=<path>\"\n        scored: true\n\n      - id: 1.2.25\n        text: \"Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Automated)\"\n        audit: \"journalctl -m -u k3s | grep -A1 'Running kube-apiserver' | tail -n2\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--tls-cert-file\"\n              set: true\n            - flag: \"--tls-private-key-file\"\n              set: true\n        remediation: |\n          By default, K3s automatically generates and provides the TLS certificate and private key for the apiserver.\n          They are generated and located at /var/lib/rancher/k3s/server/tls/serving-kube-apiserver.crt and /var/lib/rancher/k3s/server/tls/serving-kube-apiserver.key\n          If this check fails, edit the K3s config file /etc/rancher/k3s/config.yaml and remove any lines like below.\n          kube-apiserver-arg:\n            - \"tls-cert-file=<path>\"\n            - \"tls-private-key-file=<path>\"\n        scored: true\n\n      - id: 1.2.26\n        text: \"Ensure that the --client-ca-file argument is set as appropriate (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'client-ca-file'\"\n        tests:\n          test_items:\n            - flag: \"--client-ca-file\"\n        remediation: |\n          By default, K3s automatically provides the client certificate authority file.\n          It is generated and located at /var/lib/rancher/k3s/server/tls/client-ca.crt.\n          If for some reason you need to provide your own ca certificate, look at using the k3s certificate command line tool.\n          If this check fails, edit the K3s config file /etc/rancher/k3s/config.yaml and remove any lines like below.\n          kube-apiserver-arg:\n            - \"client-ca-file=<path>\"\n        scored: true\n\n      - id: 1.2.27\n        text: \"Ensure that the --etcd-cafile argument is set as appropriate (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'etcd-cafile'\"\n        tests:\n          test_items:\n            - flag: \"--etcd-cafile\"\n        remediation: |\n          By default, K3s automatically provides the etcd certificate authority file.\n          It is generated and located at /var/lib/rancher/k3s/server/tls/client-ca.crt.\n          If for some reason you need to provide your own ca certificate, look at using the k3s certificate command line tool.\n          If this check fails, edit the K3s config file /etc/rancher/k3s/config.yaml and remove any lines like below.\n          kube-apiserver-arg:\n            - \"etcd-cafile=<path>\"\n        scored: true\n\n      - id: 1.2.28\n        text: \"Ensure that the --encryption-provider-config argument is set as appropriate (Manual)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'encryption-provider-config'\"\n        tests:\n          test_items:\n            - flag: \"--encryption-provider-config\"\n        remediation: |\n          K3s can be configured to use encryption providers to encrypt secrets at rest.\n          Edit the K3s config file /etc/rancher/k3s/config.yaml on the control plane node and set the below parameter.\n          secrets-encryption: true\n          Secrets encryption can then be managed with the k3s secrets-encrypt command line tool.\n          If needed, you can find the generated encryption config at /var/lib/rancher/k3s/server/cred/encryption-config.json.\n        scored: false\n\n      - id: 1.2.29\n        text: \"Ensure that encryption providers are appropriately configured (Manual)\"\n        audit: |\n          ENCRYPTION_PROVIDER_CONFIG=$(journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep -- --encryption-provider-config | sed 's%.*encryption-provider-config[= ]\\([^ ]*\\).*%\\1%')\n          if test -e $ENCRYPTION_PROVIDER_CONFIG; then grep -o 'providers\\\"\\:\\[.*\\]' $ENCRYPTION_PROVIDER_CONFIG | grep -o \"[A-Za-z]*\" | head -2 | tail -1  | sed 's/^/provider=/'; fi\n        tests:\n          test_items:\n            - flag: \"provider\"\n              compare:\n                op: valid_elements\n                value: \"aescbc,kms,secretbox\"\n        remediation: |\n          K3s can be configured to use encryption providers to encrypt secrets at rest. K3s will utilize the aescbc provider.\n          Edit the K3s config file /etc/rancher/k3s/config.yaml on the control plane node and set the below parameter.\n          secrets-encryption: true\n          Secrets encryption can then be managed with the k3s secrets-encrypt command line tool.\n          If needed, you can find the generated encryption config at /var/lib/rancher/k3s/server/cred/encryption-config.json\n        scored: false\n\n      - id: 1.2.30\n        text: \"Ensure that the API Server only makes use of Strong Cryptographic Ciphers (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-apiserver' | tail -n1 | grep 'tls-cipher-suites'\"\n        tests:\n          test_items:\n            - flag: \"--tls-cipher-suites\"\n              compare:\n                op: valid_elements\n                value: \"TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,TLS_CHACHA20_POLY1305_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,TLS_RSA_WITH_3DES_EDE_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_256_GCM_SHA384\"\n        remediation: |\n          By default, the K3s kube-apiserver complies with this test. Changes to these values may cause regression, therefore ensure that all apiserver clients support the new TLS configuration before applying it in production deployments.\n          If a custom TLS configuration is required, consider also creating a custom version of this rule that aligns with your requirements.\n          If this check fails, remove any custom configuration around `tls-cipher-suites` or update the /etc/rancher/k3s/config.yaml file to match the default by adding the following:\n          kube-apiserver-arg:\n            - \"tls-cipher-suites=TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305\"\n        scored: true\n\n  - id: 1.3\n    text: \"Controller Manager\"\n    checks:\n      - id: 1.3.1\n        text: \"Ensure that the --terminated-pod-gc-threshold argument is set as appropriate (Manual)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-controller-manager' | tail -n1 | grep 'terminated-pod-gc-threshold'\"\n        tests:\n          test_items:\n            - flag: \"--terminated-pod-gc-threshold\"\n        remediation: |\n          Edit the K3s config file /etc/rancher/k3s/config.yaml on the control plane node\n          and set the --terminated-pod-gc-threshold to an appropriate threshold,\n          kube-controller-manager-arg:\n            - \"terminated-pod-gc-threshold=10\"\n        scored: false\n\n      - id: 1.3.2\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-controller-manager' | tail -n1 | grep 'profiling'\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          By default, K3s sets the --profiling argument to false.\n          If this check fails, edit the K3s config file /etc/rancher/k3s/config.yaml and remove any lines like below.\n          kube-controller-manager-arg:\n            - \"profiling=true\"\n        scored: true\n\n      - id: 1.3.3\n        text: \"Ensure that the --use-service-account-credentials argument is set to true (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-controller-manager' | tail -n1 | grep 'use-service-account-credentials'\"\n        tests:\n          test_items:\n            - flag: \"--use-service-account-credentials\"\n              compare:\n                op: noteq\n                value: false\n        remediation: |\n          By default, K3s sets the --use-service-account-credentials argument to true.\n          If this check fails, edit the K3s config file /etc/rancher/k3s/config.yaml and remove any lines like below.\n          kube-controller-manager-arg:\n            - \"use-service-account-credentials=false\"\n        scored: true\n\n      - id: 1.3.4\n        text: \"Ensure that the --service-account-private-key-file argument is set as appropriate (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-controller-manager' | tail -n1 | grep 'service-account-private-key-file'\"\n        tests:\n          test_items:\n            - flag: \"--service-account-private-key-file\"\n        remediation: |\n          By default, K3s automatically provides the service account private key file.\n          It is generated and located at /var/lib/rancher/k3s/server/tls/service.current.key.\n          If this check fails, edit the K3s config file /etc/rancher/k3s/config.yaml and remove any lines like below.\n          kube-controller-manager-arg:\n            - \"service-account-private-key-file=<path>\"\n        scored: true\n\n      - id: 1.3.5\n        text: \"Ensure that the --root-ca-file argument is set as appropriate (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-controller-manager' | tail -n1 | grep 'root-ca-file'\"\n        tests:\n          test_items:\n            - flag: \"--root-ca-file\"\n        remediation: |\n          By default, K3s automatically provides the root CA file.\n          It is generated and located at /var/lib/rancher/k3s/server/tls/server-ca.crt.\n          If for some reason you need to provide your own ca certificate, look at using the k3s certificate command line tool.\n          If this check fails, edit the K3s config file /etc/rancher/k3s/config.yaml and remove any lines like below.\n          kube-controller-manager-arg:\n            - \"root-ca-file=<path>\"\n        scored: true\n\n      - id: 1.3.6\n        text: \"Ensure that the RotateKubeletServerCertificate argument is set to true (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-controller-manager' | tail -n1\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--feature-gates\"\n              compare:\n                op: nothave\n                value: \"RotateKubeletServerCertificate=false\"\n              set: true\n            - flag: \"--feature-gates\"\n              set: false\n        remediation: |\n          By default, K3s does not set the RotateKubeletServerCertificate feature gate.\n          If you have enabled this feature gate, you should remove it.\n          If this check fails, edit the K3s config file /etc/rancher/k3s/config.yaml, remove any lines like below.\n          kube-controller-manager-arg:\n            - \"feature-gate=RotateKubeletServerCertificate\"\n        scored: true\n\n      - id: 1.3.7\n        text: \"Ensure that the --bind-address argument is set to 127.0.0.1 (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-controller-manager' | tail -n1\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--bind-address\"\n              compare:\n                op: eq\n                value: \"127.0.0.1\"\n              set: true\n            - flag: \"--bind-address\"\n              set: false\n        remediation: |\n          By default, K3s sets the --bind-address argument to 127.0.0.1\n          If this check fails, edit the K3s config file /etc/rancher/k3s/config.yaml and remove any lines like below.\n          kube-controller-manager-arg:\n            - \"bind-address=<IP>\"\n        scored: true\n\n  - id: 1.4\n    text: \"Scheduler\"\n    checks:\n      - id: 1.4.1\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-scheduler' | tail -n1 | grep 'profiling'\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n              set: true\n        remediation: |\n          By default, K3s sets the --profiling argument to false.\n          If this check fails, edit the K3s config file /etc/rancher/k3s/config.yaml and remove any lines like below.\n          kube-scheduler-arg:\n            - \"profiling=true\"\n        scored: true\n\n      - id: 1.4.2\n        text: \"Ensure that the --bind-address argument is set to 127.0.0.1 (Automated)\"\n        audit: \"journalctl -m -u k3s | grep 'Running kube-scheduler' | tail -n1 | grep 'bind-address'\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--bind-address\"\n              compare:\n                op: eq\n                value: \"127.0.0.1\"\n              set: true\n            - flag: \"--bind-address\"\n              set: false\n        remediation: |\n          By default, K3s sets the --bind-address argument to 127.0.0.1\n          If this check fails, edit the K3s config file /etc/rancher/k3s/config.yaml and remove any lines like below.\n          kube-scheduler-arg:\n            - \"bind-address=<IP>\"\n        scored: true\n"
  },
  {
    "path": "cfg/k3s-cis-1.8/node.yaml",
    "content": "---\ncontrols:\nversion: \"k3s-cis-1.8\"\nid: 4\ntext: \"Worker Node Security Configuration\"\ntype: \"node\"\ngroups:\n  - id: 4.1\n    text: \"Worker Node Configuration Files\"\n    checks:\n      - id: 4.1.1\n        text: \"Ensure that the kubelet service file permissions are set to 600 or more restrictive (Automated)\"\n        type: \"skip\"\n        audit: '/bin/sh -c ''if test -e $kubeletsvc; then stat -c permissions=%a $kubeletsvc; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Not Applicable.\n          The kubelet is embedded in the k3s process. There is no kubelet service file, all configuration is passed in as arguments at runtime.\n        scored: true\n\n      - id: 4.1.2\n        text: \"Ensure that the kubelet service file ownership is set to root:root (Automated)\"\n        type: \"skip\"\n        audit: '/bin/sh -c ''if test -e $kubeletsvc; then stat -c %U:%G $kubeletsvc; fi'' '\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Not Applicable.\n          The kubelet is embedded in the k3s process. There is no kubelet service file, all configuration is passed in as arguments at runtime.\n          Not Applicable.\n           All configuration is passed in as arguments at container run time.\n        scored: true\n\n      - id: 4.1.3\n        text: \"If proxy kubeconfig file exists ensure permissions are set to 600 or more restrictive (Automated)\"\n        audit: '/bin/sh -c ''if test -e $proxykubeconfig; then stat -c permissions=%a $proxykubeconfig; fi'' '\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chmod 600 $proxykubeconfig\n        scored: true\n\n      - id: 4.1.4\n        text: \"If proxy kubeconfig file exists ensure ownership is set to root:root (Automated)\"\n        audit: '/bin/sh -c ''if test -e $proxykubeconfig; then stat -c %U:%G $proxykubeconfig; fi'' '\n        tests:\n          bin_op: or\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example, chown root:root $proxykubeconfig\n        scored: true\n\n      - id: 4.1.5\n        text: \"Ensure that the --kubeconfig kubelet.conf file permissions are set to 600 or more restrictive (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletkubeconfig; then stat -c permissions=%a $kubeletkubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chmod 600 $kubeletkubeconfig\n        scored: true\n\n      - id: 4.1.6\n        text: \"Ensure that the --kubeconfig kubelet.conf file ownership is set to root:root (Automated)\"\n        audit: 'stat -c %U:%G $kubeletkubeconfig'\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chown root:root $kubeletkubeconfig\n        scored: true\n\n      - id: 4.1.7\n        text: \"Ensure that the certificate authorities file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"stat -c permissions=%a $kubeletcafile\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the following command to modify the file permissions of the\n          --client-ca-file chmod 600 $kubeletcafile\n        scored: true\n\n      - id: 4.1.8\n        text: \"Ensure that the client certificate authorities file ownership is set to root:root (Automated)\"\n        audit: \"stat -c %U:%G $kubeletcafile\"\n        tests:\n          test_items:\n            - flag: root:root\n              compare:\n                op: eq\n                value: root:root\n        remediation: |\n          Run the following command to modify the ownership of the --client-ca-file.\n          chown root:root $kubeletcafile\n        scored: true\n\n      - id: 4.1.9\n        text: \"Ensure that the kubelet --config configuration file has permissions set to 600 or more restrictive (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletconf; then stat -c permissions=%a $kubeletconf; fi'' '\n        type: \"skip\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Not Applicable.\n          The kubelet is embedded in the k3s process. There is no kubelet config file, all configuration is passed in as arguments at runtime.\n        scored: true\n\n      - id: 4.1.10\n        text: \"Ensure that the kubelet --config configuration file ownership is set to root:root (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletconf; then stat -c %U:%G $kubeletconf; fi'' '\n        type: \"skip\"\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Not Applicable.\n          The kubelet is embedded in the k3s process. There is no kubelet config file, all configuration is passed in as arguments at runtime.\n        scored: true\n\n  - id: 4.2\n    text: \"Kubelet\"\n    checks:\n      - id: 4.2.1\n        text: \"Ensure that the --anonymous-auth argument is set to false (Automated)\"\n        audit: '/bin/sh -c ''if test $(journalctl -m -u k3s -u k3s-agent | grep \"Running kubelet\" | wc -l) -gt 0; then journalctl -m -u k3s -u k3s-agent | grep \"Running kubelet\" | tail -n1 | grep \"anonymous-auth\" | grep -v grep; else echo \"--anonymous-auth=false\"; fi'' '\n        tests:\n          test_items:\n            - flag: \"--anonymous-auth\"\n              path: '{.authentication.anonymous.enabled}'\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          By default, K3s sets the --anonymous-auth to false. If you have set this to a different value, you\n          should set it back to false. If using the K3s config file /etc/rancher/k3s/config.yaml, remove any lines similar to below.\n          kubelet-arg:\n            - \"anonymous-auth=true\"\n          If using the command line, edit the K3s service file and remove the below argument.\n          --kubelet-arg=\"anonymous-auth=true\"\n          Based on your system, restart the k3s service. For example,\n          systemctl daemon-reload\n          systemctl restart k3s.service\n        scored: true\n\n      - id: 4.2.2\n        text: \"Ensure that the --authorization-mode argument is not set to AlwaysAllow (Automated)\"\n        audit: '/bin/sh -c ''if test $(journalctl -m -u k3s -u k3s-agent | grep \"Running kubelet\" | wc -l) -gt 0; then journalctl -m -u k3s -u k3s-agent | grep \"Running kubelet\" | tail -n1 | grep \"authorization-mode\"; else echo \"--authorization-mode=Webhook\"; fi'' '\n        audit_config: \"/bin/sh -c 'if test -e $kubeletconf; then /bin/cat $kubeletconf; fi' \"\n        tests:\n          test_items:\n            - flag: --authorization-mode\n              path: '{.authorization.mode}'\n              compare:\n                op: nothave\n                value: AlwaysAllow\n        remediation: |\n          By default, K3s does not set the --authorization-mode to AlwaysAllow.\n          If using the K3s config file /etc/rancher/k3s/config.yaml, remove any lines similar to below.\n          kubelet-arg:\n            - \"authorization-mode=AlwaysAllow\"\n          If using the command line, edit the K3s service file and remove the below argument.\n          --kubelet-arg=\"authorization-mode=AlwaysAllow\"\n          Based on your system, restart the k3s service. For example,\n          systemctl daemon-reload\n          systemctl restart k3s.service\n        scored: true\n\n      - id: 4.2.3\n        text: \"Ensure that the --client-ca-file argument is set as appropriate (Automated)\"\n        audit: '/bin/sh -c ''if test $(journalctl -m -u k3s -u k3s-agent | grep \"Running kubelet\" | wc -l) -gt 0; then journalctl -m -u k3s -u k3s-agent | grep \"Running kubelet\" | tail -n1 | grep \"client-ca-file\"; else echo \"--client-ca-file=/var/lib/rancher/k3s/server/tls/request-header-ca.crt\"; fi'' '\n        tests:\n          test_items:\n            - flag: --client-ca-file\n              path: '{.authentication.x509.clientCAFile}'\n        remediation: |\n          By default, K3s automatically provides the client ca certificate for the Kubelet.\n          It is generated and located at /var/lib/rancher/k3s/agent/client-ca.crt\n        scored: true\n\n      - id: 4.2.4\n        text: \"Verify that the --read-only-port argument is set to 0 (Automated)\"\n        audit: \"journalctl -m -u k3s -u k3s-agent | grep 'Running kubelet' | tail -n1\"\n        audit_config: \"/bin/sh -c 'if test -e $kubeletconf; then /bin/cat $kubeletconf; fi' \"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--read-only-port\"\n              path: '{.readOnlyPort}'\n              compare:\n                op: eq\n                value: 0\n            - flag: \"--read-only-port\"\n              path: '{.readOnlyPort}'\n              set: false\n        remediation: |\n          By default, K3s sets the --read-only-port to 0. If you have set this to a different value, you\n          should set it back to 0. If using the K3s config file /etc/rancher/k3s/config.yaml, remove any lines similar to below.\n          kubelet-arg:\n            - \"read-only-port=XXXX\"\n          If using the command line, edit the K3s service file and remove the below argument.\n          --kubelet-arg=\"read-only-port=XXXX\"\n          Based on your system, restart the k3s service. For example,\n          systemctl daemon-reload\n          systemctl restart k3s.service\n        scored: true\n\n      - id: 4.2.5\n        text: \"Ensure that the --streaming-connection-idle-timeout argument is not set to 0 (Manual)\"\n        audit: \"journalctl -m -u k3s -u k3s-agent | grep 'Running kubelet' | tail -n1\"\n        tests:\n          test_items:\n            - flag: --streaming-connection-idle-timeout\n              path: '{.streamingConnectionIdleTimeout}'\n              compare:\n                op: noteq\n                value: 0\n            - flag: --streaming-connection-idle-timeout\n              path: '{.streamingConnectionIdleTimeout}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using the K3s config file /etc/rancher/k3s/config.yaml, set the following parameter to an appropriate value.\n          kubelet-arg:\n            - \"streaming-connection-idle-timeout=5m\"\n          If using the command line, run K3s with --kubelet-arg=\"streaming-connection-idle-timeout=5m\".\n          Based on your system, restart the k3s service. For example,\n          systemctl restart k3s.service\n        scored: false\n\n      - id: 4.2.6\n        text: \"Ensure that the --make-iptables-util-chains argument is set to true (Automated)\"\n        audit: \"journalctl -m -u k3s -u k3s-agent | grep 'Running kubelet' | tail -n1\"\n        tests:\n          test_items:\n            - flag: --make-iptables-util-chains\n              path: '{.makeIPTablesUtilChains}'\n              compare:\n                op: eq\n                value: true\n            - flag: --make-iptables-util-chains\n              path: '{.makeIPTablesUtilChains}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using the K3s config file /etc/rancher/k3s/config.yaml, set the following parameter.\n          kubelet-arg:\n            - \"make-iptables-util-chains=true\"\n          If using the command line, run K3s with --kubelet-arg=\"make-iptables-util-chains=true\".\n          Based on your system, restart the k3s service. For example,\n          systemctl restart k3s.service\n        scored: true\n\n      - id: 4.2.7\n        text: \"Ensure that the --hostname-override argument is not set (Automated)\"\n        audit: \"journalctl -m -u k3s -u k3s-agent | grep 'Running kubelet' | tail -n1\"\n        type: \"skip\"\n        tests:\n          test_items:\n            - flag: --hostname-override\n              set: false\n        remediation: |\n          Not Applicable.\n          By default, K3s does set the --hostname-override argument. Per CIS guidelines, this is to comply\n          with cloud providers that require this flag to ensure that hostname matches node names.\n        scored: true\n\n      - id: 4.2.8\n        text: \"Ensure that the eventRecordQPS argument is set to a level which ensures appropriate event capture (Manual)\"\n        audit: \"journalctl -m -u k3s -u k3s-agent | grep 'Running kubelet' | tail -n1\"\n        audit_config: \"/bin/sh -c 'if test -e $kubeletconf; then /bin/cat $kubeletconf; fi' \"\n        tests:\n          test_items:\n            - flag: --event-qps\n              path: '{.eventRecordQPS}'\n              compare:\n                op: gte\n                value: 0\n            - flag: --event-qps\n              path: '{.eventRecordQPS}'\n              set: false\n          bin_op: or\n        remediation: |\n          By default, K3s sets the event-qps to 0. Should you wish to change this,\n          If using the K3s config file /etc/rancher/k3s/config.yaml, set the following parameter to an appropriate value.\n          kubelet-arg:\n            - \"event-qps=<value>\"\n          If using the command line, run K3s with --kubelet-arg=\"event-qps=<value>\".\n          Based on your system, restart the k3s service. For example,\n          systemctl restart k3s.service\n        scored: false\n\n      - id: 4.2.9\n        text: \"Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Automated)\"\n        audit: \"journalctl -m -u k3s -u k3s-agent | grep 'Running kubelet' | tail -n1\"\n        tests:\n          test_items:\n            - flag: --tls-cert-file\n              path: '/var/lib/rancher/k3s/agent/serving-kubelet.crt'\n            - flag: --tls-private-key-file\n              path: '/var/lib/rancher/k3s/agent/serving-kubelet.key'\n        remediation: |\n          By default, K3s automatically provides the TLS certificate and private key for the Kubelet.\n          They are generated and located at /var/lib/rancher/k3s/agent/serving-kubelet.crt and /var/lib/rancher/k3s/agent/serving-kubelet.key\n          If for some reason you need to provide your own certificate and key, you can set the\n          below parameters in the K3s config file /etc/rancher/k3s/config.yaml.\n          kubelet-arg:\n            - \"tls-cert-file=<path/to/tls-cert-file>\"\n            - \"tls-private-key-file=<path/to/tls-private-key-file>\"\n        scored: true\n\n      - id: 4.2.10\n        text: \"Ensure that the --rotate-certificates argument is not set to false (Automated)\"\n        audit: \"journalctl -m -u k3s -u k3s-agent | grep 'Running kubelet' | tail -n1\"\n        audit_config: \"/bin/sh -c 'if test -e $kubeletconf; then /bin/cat $kubeletconf; fi' \"\n        tests:\n          test_items:\n            - flag: --rotate-certificates\n              path: '{.rotateCertificates}'\n              compare:\n                op: eq\n                value: true\n            - flag: --rotate-certificates\n              path: '{.rotateCertificates}'\n              set: false\n          bin_op: or\n        remediation: |\n          By default, K3s does not set the --rotate-certificates argument. If you have set this flag with a value of `false`, you should either set it to `true` or completely remove the flag.\n          If using the K3s config file /etc/rancher/k3s/config.yaml, remove any rotate-certificates parameter.\n          If using the command line, remove the K3s flag --kubelet-arg=\"rotate-certificates\".\n          Based on your system, restart the k3s service. For example,\n          systemctl restart k3s.service\n        scored: true\n\n      - id: 4.2.11\n        text: \"Verify that the RotateKubeletServerCertificate argument is set to true (Automated)\"\n        audit: \"journalctl -m -u k3s -u k3s-agent | grep 'Running kubelet' | tail -n1\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: RotateKubeletServerCertificate\n              path: '{.featureGates.RotateKubeletServerCertificate}'\n              compare:\n                op: nothave\n                value: false\n            - flag: RotateKubeletServerCertificate\n              path: '{.featureGates.RotateKubeletServerCertificate}'\n              set: false\n        remediation: |\n          By default, K3s does not set the RotateKubeletServerCertificate feature gate.\n          If you have enabled this feature gate, you should remove it.\n          If using the K3s config file /etc/rancher/k3s/config.yaml, remove any feature-gate=RotateKubeletServerCertificate parameter.\n          If using the command line, remove the K3s flag --kubelet-arg=\"feature-gate=RotateKubeletServerCertificate\".\n          Based on your system, restart the k3s service. For example,\n          systemctl restart k3s.service\n        scored: true\n\n      - id: 4.2.12\n        text: \"Ensure that the Kubelet only makes use of Strong Cryptographic Ciphers (Manual)\"\n        audit: \"journalctl -m -u k3s -u k3s-agent | grep 'Running kubelet' | tail -n1\"\n        audit_config: \"/bin/sh -c 'if test -e $kubeletconf; then /bin/cat $kubeletconf; fi' \"\n        tests:\n          test_items:\n            - flag: --tls-cipher-suites\n              path: '{range .tlsCipherSuites[:]}{}{'',''}{end}'\n              compare:\n                op: valid_elements\n                value: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\n        remediation: |\n          If using a K3s config file /etc/rancher/k3s/config.yaml, edit the file to set `tlsCipherSuites` to\n          kubelet-arg:\n            - \"tls-cipher-suites=TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305\"\n          or to a subset of these values.\n          If using the command line, add the K3s flag --kubelet-arg=\"tls-cipher-suites=<same values as above>\"\n          Based on your system, restart the k3s service. For example,\n          systemctl restart k3s.service\n        scored: false\n\n      - id: 4.2.13\n        text: \"Ensure that a limit is set on pod PIDs (Manual)\"\n        audit: \"journalctl -m -u k3s -u k3s-agent | grep 'Running kubelet' | tail -n1\"\n        audit_config: \"/bin/sh -c 'if test -e $kubeletconf; then /bin/cat $kubeletconf; fi' \"\n        tests:\n          test_items:\n            - flag: --pod-max-pids\n              path: '{.podPidsLimit}'\n        remediation: |\n          Decide on an appropriate level for this parameter and set it,\n          If using a K3s config file /etc/rancher/k3s/config.yaml, edit the file to set `podPidsLimit` to\n          kubelet-arg:\n            - \"pod-max-pids=<value>\"\n        scored: false\n"
  },
  {
    "path": "cfg/k3s-cis-1.8/policies.yaml",
    "content": "---\ncontrols:\nversion: \"k3s-cis-1.8\"\nid: 5\ntext: \"Kubernetes Policies\"\ntype: \"policies\"\ngroups:\n  - id: 5.1\n    text: \"RBAC and Service Accounts\"\n    checks:\n      - id: 5.1.1\n        text: \"Ensure that the cluster-admin role is only used where required (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Identify all clusterrolebindings to the cluster-admin role. Check if they are used and\n          if they need this role or if they could use a role with fewer privileges.\n          Where possible, first bind users to a lower privileged role and then remove the\n          clusterrolebinding to the cluster-admin role :\n          kubectl delete clusterrolebinding [name]\n        scored: false\n\n      - id: 5.1.2\n        text: \"Minimize access to secrets (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove get, list and watch access to Secret objects in the cluster.\n        scored: false\n\n      - id: 5.1.3\n        text: \"Minimize wildcard use in Roles and ClusterRoles (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible replace any use of wildcards in clusterroles and roles with specific\n          objects or actions.\n        scored: false\n\n      - id: 5.1.4\n        text: \"Minimize access to create pods (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove create access to pod objects in the cluster.\n        scored: false\n\n      - id: 5.1.5\n        text: \"Ensure that default service accounts are not actively used. (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Create explicit service accounts wherever a Kubernetes workload requires specific access\n          to the Kubernetes API server.\n          Modify the configuration of each default service account to include this value\n          automountServiceAccountToken: false\n        scored: false\n\n\n      - id: 5.1.6\n        text: \"Ensure that Service Account Tokens are only mounted where necessary (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Modify the definition of pods and service accounts which do not need to mount service\n          account tokens to disable it.\n        scored: false\n\n      - id: 5.1.7\n        text: \"Avoid use of system:masters group (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Remove the system:masters group from all users in the cluster.\n        scored: false\n\n      - id: 5.1.8\n        text: \"Limit use of the Bind, Impersonate and Escalate permissions in the Kubernetes cluster (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove the impersonate, bind and escalate rights from subjects.\n        scored: false\n\n      - id: 5.1.9\n        text: \"Minimize access to create persistent volumes (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove create access to PersistentVolume objects in the cluster.\n        scored: false\n\n      - id: 5.1.10\n        text: \"Minimize access to the proxy sub-resource of nodes (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove access to the proxy sub-resource of node objects.\n        scored: false\n\n      - id: 5.1.11\n        text: \"Minimize access to the approval sub-resource of certificatesigningrequests objects (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove access to the approval sub-resource of certificatesigningrequest objects.\n        scored: false\n\n      - id: 5.1.12\n        text: \"Minimize access to webhook configuration objects (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove access to the validatingwebhookconfigurations or mutatingwebhookconfigurations objects\n        scored: false\n\n      - id: 5.1.13\n        text: \"Minimize access to the service account token creation (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove access to the token sub-resource of serviceaccount objects.\n        scored: false\n\n  - id: 5.2\n    text: \"Pod Security Standards\"\n    checks:\n      - id: 5.2.1\n        text: \"Ensure that the cluster has at least one active policy control mechanism in place (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that either Pod Security Admission or an external policy control system is in place\n          for every namespace which contains user workloads.\n        scored: false\n\n      - id: 5.2.2\n        text: \"Minimize the admission of privileged containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of privileged containers.\n        scored: false\n\n      - id: 5.2.3\n        text: \"Minimize the admission of containers wishing to share the host process ID namespace (Automated)\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of `hostPID` containers.\n        scored: false\n\n      - id: 5.2.4\n        text: \"Minimize the admission of containers wishing to share the host IPC namespace (Automated)\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of `hostIPC` containers.\n        scored: false\n\n      - id: 5.2.5\n        text: \"Minimize the admission of containers wishing to share the host network namespace (Automated)\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of `hostNetwork` containers.\n        scored: false\n\n      - id: 5.2.6\n        text: \"Minimize the admission of containers with allowPrivilegeEscalation (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers with `.spec.allowPrivilegeEscalation` set to `true`.\n        scored: true\n\n      - id: 5.2.7\n        text: \"Minimize the admission of root containers (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Create a policy for each namespace in the cluster, ensuring that either `MustRunAsNonRoot`\n          or `MustRunAs` with the range of UIDs not including 0, is set.\n        scored: false\n\n      - id: 5.2.8\n        text: \"Minimize the admission of containers with the NET_RAW capability (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers with the `NET_RAW` capability.\n        scored: false\n\n      - id: 5.2.9\n        text: \"Minimize the admission of containers with added capabilities (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that `allowedCapabilities` is not present in policies for the cluster unless\n          it is set to an empty array.\n        scored: false\n\n      - id: 5.2.10\n        text: \"Minimize the admission of containers with capabilities assigned (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Review the use of capabilities in applications running on your cluster. Where a namespace\n          contains applications which do not require any Linux capabities to operate consider adding\n          a PSP which forbids the admission of containers which do not drop all capabilities.\n        scored: false\n\n      - id: 5.2.11\n        text: \"Minimize the admission of Windows HostProcess containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers that have `.securityContext.windowsOptions.hostProcess` set to `true`.\n        scored: false\n\n      - id: 5.2.12\n        text: \"Minimize the admission of HostPath volumes (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers with `hostPath` volumes.\n        scored: false\n\n      - id: 5.2.13\n        text: \"Minimize the admission of containers which use HostPorts (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers which use `hostPort` sections.\n        scored: false\n\n  - id: 5.3\n    text: \"Network Policies and CNI\"\n    checks:\n      - id: 5.3.1\n        text: \"Ensure that the CNI in use supports NetworkPolicies (Manual)\"\n        type: \"manual\"\n        remediation: |\n          If the CNI plugin in use does not support network policies, consideration should be given to\n          making use of a different plugin, or finding an alternate mechanism for restricting traffic\n          in the Kubernetes cluster.\n        scored: false\n\n      - id: 5.3.2\n        text: \"Ensure that all Namespaces have NetworkPolicies defined (Manual)\"\n        remediation: |\n          Follow the documentation and create NetworkPolicy objects as you need them.\n        scored: false\n\n  - id: 5.4\n    text: \"Secrets Management\"\n    checks:\n      - id: 5.4.1\n        text: \"Prefer using Secrets as files over Secrets as environment variables (Manual)\"\n        type: \"manual\"\n        remediation: |\n          If possible, rewrite application code to read Secrets from mounted secret files, rather than\n          from environment variables.\n        scored: false\n\n      - id: 5.4.2\n        text: \"Consider external secret storage (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Refer to the Secrets management options offered by your cloud provider or a third-party\n          secrets management solution.\n        scored: false\n\n  - id: 5.5\n    text: \"Extensible Admission Control\"\n    checks:\n      - id: 5.5.1\n        text: \"Configure Image Provenance using ImagePolicyWebhook admission controller (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and setup image provenance.\n        scored: false\n\n  - id: 5.7\n    text: \"General Policies\"\n    checks:\n      - id: 5.7.1\n        text: \"Create administrative boundaries between resources using namespaces (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the documentation and create namespaces for objects in your deployment as you need\n          them.\n        scored: false\n\n      - id: 5.7.2\n        text: \"Ensure that the seccomp profile is set to docker/default in your Pod definitions (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Use `securityContext` to enable the docker/default seccomp profile in your pod definitions.\n          An example is as below:\n            securityContext:\n              seccompProfile:\n                type: RuntimeDefault\n        scored: false\n\n      - id: 5.7.3\n        text: \"Apply SecurityContext to your Pods and Containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and apply SecurityContexts to your Pods. For a\n          suggested list of SecurityContexts, you may refer to the CIS Security Benchmark for Docker\n          Containers.\n        scored: false\n\n      - id: 5.7.4\n        text: \"The default namespace should not be used (Manual)\"\n        remediation: |\n          Ensure that namespaces are created to allow for appropriate segregation of Kubernetes\n          resources and that all new resources are created in a specific namespace.\n        scored: false\n"
  },
  {
    "path": "cfg/rh-0.7/config.yaml",
    "content": "---\n## Version-specific settings that override the values in cfg/config.yaml\n"
  },
  {
    "path": "cfg/rh-0.7/master.yaml",
    "content": "---\ncontrols:\nversion: \"rh-0.7\"\nid: 1\ntext: \"Securing the OpenShift Master\"\ntype: \"master\"\ngroups:\n\n  - id: 1\n    text: \"Protecting the API Server\"\n    checks:\n      - id: 1.1\n        text: \"Maintain default behavior for anonymous access\"\n        type: \"skip\"\n        scored: true\n\n      - id: 1.2\n        text: \"Verify that the basic-auth-file method is not enabled\"\n        audit_config: \"cat /etc/origin/master/master-config.yaml\"\n        tests:\n          test_items:\n            - path: \"{.kubernetesMasterConfig.apiServerArguments.basic-auth-file}\"\n              set: false\n        remediation: |\n          Edit the kubernetes master config file /etc/origin/master/master-config.yaml and\n          remove the basic-auth-file entry.\n\n          kubernetesMasterConfig:\n            apiServerArguments:\n               basic-auth-file:\n                 - /path/to/any/file\n        scored: true\n\n      - id: 1.3\n        text: \"Insecure Tokens\"\n        type: \"skip\"\n        scored: true\n\n      - id: 1.4\n        text: \"Secure communications between the API server and master nodes\"\n        audit_config: \"cat /etc/origin/master/master-config.yaml\"\n        tests:\n          bin_op: and\n          test_items:\n            - path: \"{.kubeletClientInfo.ca}\"\n              compare:\n                op: has\n                value: \"ca-bundle.crt\"\n            - path: \"{.kubeletClientInfo.certFile}\"\n              compare:\n                op: has\n                value: \"master.kubelet-client.crt\"\n            - path: \"{.kubeletClientInfo.keyFile}\"\n              compare:\n                op: has\n                value: \"master.kubelet-client.key\"\n              set: true\n            - path: \"{.kubeletClientInfo.port}\"\n              compare:\n                op: eq\n                value: \"10250\"\n        remediation: |\n          Edit the kubernetes master config file /etc/origin/master/master-config.yaml\n          and change it to match the below.\n\n          kubeletClientInfo:\n            ca: ca-bundle.crt\n            certFile: master.kubelet-client.crt\n            keyFile: master.kubelet-client.key\n            port: 10250\n        scored: true\n\n      - id: 1.5\n        text: \"Prevent insecure bindings\"\n        audit_config: \"cat /etc/origin/master/master-config.yaml\"\n        tests:\n          test_items:\n            - path: \"{.kubernetesMasterConfig.insecure-bind-address}\"\n              set: false\n        remediation: |\n          Edit the kubernetes master config file /etc/origin/master/master-config.yaml\n          and remove the insecure-bind-address entry.\n\n          kubernetesMasterConfig:\n            apiServerArguments:\n               insecure-bind-address:\n               - 127.0.0.1\n        scored: true\n\n      - id: 1.6\n        text: \"Prevent insecure port access\"\n        audit_config: \"cat /etc/origin/master/master-config.yaml\"\n        tests:\n          test_items:\n            - path: \"{.kubernetesMasterConfig.apiServerArguments.insecure-port}\"\n              set: false\n        remediation: |\n         Edit the kubernetes master config file /etc/origin/master/master-config.yaml\n         and remove the insecure-port entry.\n\n         kubernetesMasterConfig:\n           apiServerArguments:\n             insecure-port:\n             - 0\n        scored: true\n\n      - id: 1.7\n        text: \"Use Secure Ports for API Server Traffic\"\n        audit_config: \"cat /etc/origin/master/master-config.yaml\"\n        tests:\n          bin_op: or\n          test_items:\n            - path: \"{.kubernetesMasterConfig.apiServerArguments.secure-port}\"\n              set: false\n            - path: \"{.kubernetesMasterConfig.apiServerArguments.secure-port}\"\n              compare:\n                op: noteq\n                value: \"0\"\n        remediation: |\n         Edit the kubernetes master config file /etc/origin/master/master-config.yaml\n         and either remove the secure-port parameter or set it to a different (non-zero)\n         desired port.\n\n         kubernetesMasterConfig:\n           apiServerArguments:\n             secure-port:\n             - 8443\n        scored: true\n\n      - id: 1.8\n        text: \"Do not expose API server profiling data\"\n        type: \"skip\"\n        scored: true\n\n      - id: 1.9\n        text: \"Verify repair-malformed-updates argument for API compatibility\"\n        audit_config: \"cat /etc/origin/master/master-config.yaml\"\n        tests:\n          bin_op: or\n          test_items:\n            - path: \"{.repair-malformed-updates}\"\n              set: false\n            - path: \"{.repair-malformed-updates}\"\n              compare:\n                op: eq\n                value: \"true\"\n        remediation: |\n         Edit the kubernetes master config file /etc/origin/master/master-config.yaml\n         and remove the repair-malformed-updates entry or set repair-malformed-updates=true.\n        scored: true\n\n      - id: 1.10\n        text: \"Verify that the AlwaysAdmit admission controller is disabled\"\n        audit_config: \"cat /etc/origin/master/master-config.yaml\"\n        tests:\n          test_items:\n            - path: \"{.AlwaysAdmit}\"\n              set: false\n        remediation: |\n          Edit the kubernetes master config file /etc/origin/master/master-config.yaml\n          and remove the entry below.\n\n          AlwaysAdmit:\n            configuration:\n              kind: DefaultAdmissionConfig\n              apiVersion: v1\n              disable: false\n        scored: true\n\n      - id: 1.11\n        text: \"Manage the AlwaysPullImages admission controller\"\n        audit_config: \"cat /etc/origin/master/master-config.yaml\"\n        tests:\n          test_items:\n            - path: \"{.admissionConfig.pluginConfig.configuration.disable}\"\n              compare:\n                op: eq\n                value: \"false\"\n        remediation: |\n          Edit the kubernetes master config file /etc/origin/master/master-config.yaml\n          and add the entry below.\n\n          admissionConfig:\n            pluginConfig:\n              AlwaysPullImages:\n                configuration:\n                  kind: DefaultAdmissionConfig\n                  apiVersion: v1\n                  disable: false\n        scored: true\n\n      - id: 1.12\n        text: \"Use Security Context Constraints instead of DenyEscalatingExec admission\"\n        type: \"skip\"\n        scored: true\n\n      - id: 1.13\n        text: \"Use Security Context Constraints instead of the SecurityContextDeny admission controller\"\n        type: \"skip\"\n        scored: true\n\n      - id: 1.14\n        text: \"Manage the NamespaceLifecycle admission controller\"\n        audit_config: \"cat /etc/origin/master/master-config.yaml\"\n        tests:\n          test_items:\n            - path: \"{.NamespaceLifecycle}\"\n              set: false\n        remediation: |\n          Edit the kubernetes master config file /etc/origin/master/master-config.yaml\n          and remove the following entry.\n\n          NamespaceLifecycle:\n            configuration:\n              kind: DefaultAdmissionConfig\n              apiVersion: v1\n              disable: true\n        scored: true\n\n      - id: 1.15\n        text: \"Configure API server auditing - audit log file path\"\n        audit_config: \"cat /etc/origin/master/master-config.yaml\"\n        tests:\n          test_items:\n            - path: \"{.auditConfig.enabled}\"\n              compare:\n                op: eq\n                value: \"true\"\n        remediation: |\n          Edit the Openshift master config file /etc/origin/master/master-config.yaml, update the following entry and restart the API server.\n\n          auditConfig:\n            auditFilePath: \"\"/etc/origin/master/audit-ocp.log\"\"\n            enabled: true\n            maximumFileRetentionDays: 30\n            maximumFileSizeMegabytes: 10\n            maximumRetainedFiles: 10\n\n          Make the same changes in the inventory/ansible variables so the changes are not\n          lost when an upgrade occurs.\n        scored: true\n\n      - id: 1.16\n        text: \"Configure API server auditing - audit log retention\"\n        audit_config: \"cat /etc/origin/master/master-config.yaml\"\n        tests:\n          test_items:\n            - path: \"{.auditConfig.maximumFileRetentionDays}\"\n              compare:\n                op: gte\n                value: 30\n        remediation: |\n          Edit the Openshift master config file /etc/origin/master/master-config.yaml,\n          update the maximumFileRetentionDays entry and restart the API server.\n\n          auditConfig:\n            auditFilePath: \"\"/etc/origin/master/audit-ocp.log\"\"\n            enabled: true\n            maximumFileRetentionDays: 30\n            maximumFileSizeMegabytes: 10\n            maximumRetainedFiles: 10\n\n          Make the same changes in the inventory/ansible variables so the changes are not\n          lost when an upgrade occurs.\n        scored: true\n\n      - id: 1.17\n        text: \"Configure API server auditing - audit log backup retention\"\n        audit_config: \"cat /etc/origin/master/master-config.yaml\"\n        tests:\n          test_items:\n            - path: \"{.auditConfig.maximumRetainedFiles}\"\n              compare:\n                op: eq\n                value: \"10\"\n        remediation: |\n          Edit the Openshift master config file /etc/origin/master/master-config.yaml, update the maximumRetainedFiles entry,\n          set enabled to true and restart the API server.\n\n          auditConfig:\n            auditFilePath: \"\"/etc/origin/master/audit-ocp.log\"\"\n            enabled: true\n            maximumFileRetentionDays: 30\n            maximumFileSizeMegabytes: 10\n            maximumRetainedFiles: 10\n\n          Make the same changes in the inventory/ansible variables so the changes are not\n          lost when an upgrade occurs.\n        scored: true\n\n      - id: 1.18\n        text: \"Configure audit log file size\"\n        audit_config: \"cat /etc/origin/master/master-config.yaml\"\n        tests:\n          test_items:\n            - path: \"{.auditConfig.maximumFileSizeMegabytes}\"\n              compare:\n                op: eq\n                value: \"30\"\n        remediation: |\n          Edit the Openshift master config file /etc/origin/master/master-config.yaml, update the maximumFileSizeMegabytes entry,\n          set enabled to true and restart the API server.\n\n          auditConfig:\n            auditFilePath: \"\"/etc/origin/master/audit-ocp.log\"\"\n            enabled: true\n            maximumFileRetentionDays: 30\n            maximumFileSizeMegabytes: 10\n            maximumRetainedFiles: 10\n\n          Make the same changes in the inventory/ansible variables so the changes are not\n          lost when an upgrade occurs.\n        scored: true\n\n      - id: 1.19\n        text: \"Verify that authorization-mode is not set to AlwaysAllow\"\n        audit_config: \"cat /etc/origin/master/master-config.yaml\"\n        tests:\n          test_items:\n            - path: \"{.kubernetesMasterConfig.apiServerArguments.authorization-mode}\"\n              set: false\n        remediation: |\n          Edit the Openshift master config file /etc/origin/master/master-config.yaml and remove the authorization-mode\n          entry.\n\n          kubernetesMasterConfig:\n            apiServerArguments:\n               authorization-mode:\n                 - AllowAll\n        scored: true\n\n      - id: 1.20\n        text: \"Verify that the token-auth-file flag is not set\"\n        audit_config: \"cat /etc/origin/master/master-config.yaml\"\n        tests:\n          test_items:\n            - path: \"{.kubernetesMasterConfig.apiServerArguments.token-auth-file}\"\n              set: false\n        remediation: |\n          Edit the Openshift master config file /etc/origin/master/master-config.yaml and remove the token-auth-file\n          entry under apiserverArguments section.\n\n          kubernetesMasterConfig:\n            apiServerArguments:\n               token-auth-file:\n                 - /path/to/file\n        scored: true\n\n      - id: 1.21\n        text: \"Verify the API server certificate authority\"\n        audit_config: \"cat /etc/origin/master/master-config.yaml\"\n        tests:\n          test_items:\n            - path: \"{.kubernetesMasterConfig.apiServerArguments.kubelet-certificat-authority}\"\n              set: false\n        remediation: |\n          Edit the Openshift master config file /etc/origin/master/master-config.yaml and remove the following\n          configuration under apiserverArguments section.\n\n          kubernetesMasterConfig:\n            apiServerArguments:\n               kubelet-certificat-authority:\n                 - /path/to/ca\n        scored: true\n\n      - id: 1.22\n        text: \"Verify the API server client certificate and client key\"\n        audit_config: \"cat /etc/origin/master/master-config.yaml\"\n        tests:\n          bin_op: and\n          test_items:\n            - path: \"{.kubeletClientInfo.keyFile}\"\n              compare:\n                op: eq\n                value: \"master.kubelet-client.key\"\n            - path: \"{.kubeletClientInfo.certFile}\"\n              compare:\n                op: eq\n                value: \"master.kubelet-client.crt\"\n        remediation: |\n          Edit the Openshift master config file /etc/origin/master/master-config.yaml and add the following\n          configuration under kubeletClientInfo\n\n          kubeletClientInfo:\n            ca: ca-bundle.crt\n            certFile: master.kubelet-client.crt\n            keyFile: master.kubelet-client.key\n            port: 10250\n        scored: true\n\n      - id: 1.23\n        text: \"Verify that the service account lookup flag is not set\"\n        type: \"skip\"\n        scored: true\n\n      - id: 1.24\n        text: \"Verify the PodSecurityPolicy is disabled to ensure use of SecurityContextConstraints\"\n        type: \"skip\"\n        scored: true\n\n      - id: 1.25\n        text: \"Verify that the service account key file argument is not set\"\n        audit_config: \"cat /etc/origin/master/master-config.yaml\"\n        tests:\n          bin_op: and\n          test_items:\n            - path: \"{.serviceAccountConfig.privateKeyFile}\"\n              compare:\n                op: eq\n                value: \"serviceaccounts.private.key\"\n            - path: \"{.serviceAccountConfig.publicKeyFiles}\"\n              compare:\n                op: has\n                value: \"serviceaccounts.public.key\"\n        remediation: |\n          OpenShift API server does not use the service-account-key-file argument.\n          Even if value is set in master-config.yaml, it will not be used to verify\n          service account tokens, as it is in upstream Kubernetes. The ServiceAccount\n          token authenticator is configured with serviceAccountConfig.publicKeyFiles in\n          the master-config.yaml. OpenShift does not reuse the apiserver TLS key.\n\n          Edit the Openshift master config file /etc/origin/master/master-config.yaml and set the privateKeyFile\n          and publicKeyFile configuration under serviceAccountConfig.\n\n            serviceAccountConfig:\n              limitSecretReferences: false\n              managedNames:\n                - default\n                - builder\n                - deployer\n              masterCA: ca-bundle.crt\n              privateKeyFile: serviceaccounts.private.key\n              publicKeyFiles:\n                - serviceaccounts.public.key\n\n          Verify that privateKeyFile and publicKeyFile exist and set.\n        scored: true\n\n      - id: 1.26\n        text: \"Verify the certificate and key used for communication with etcd\"\n        audit_config: \"cat /etc/origin/master/master-config.yaml\"\n        tests:\n          bin_op: and\n          test_items:\n            - path: \"{.etcdClientInfo.certFile}\"\n              compare:\n                op: eq\n                value: \"master.etcd-client.crt\"\n            - path: \"{.etcdClientInfo.keyFile}\"\n              compare:\n                op: eq\n                value: \"master.etcd-client.key\"\n        remediation: |\n          Edit the Openshift master config file /etc/origin/master/master-config.yaml and set keyFile and certFile\n          under etcdClientInfo like below.\n\n            etcdClientInfo:\n              ca: master.etcd-ca.crt\n              certFile: master.etcd-client.crt\n              keyFile: master.etcd-client.key\n        scored: true\n\n      - id: 1.27\n        text: \"Verify that the ServiceAccount admission controller is enabled\"\n        audit_config: \"cat /etc/origin/master/master-config.yaml\"\n        tests:\n          bin_op: or\n          test_items:\n            - path: \"{.ServiceAccount.configuration.disable}\"\n              set: false\n            - path: \"{.ServiceAccount.configuration.disable}\"\n              compare:\n                op: eq\n                value: \"false\"\n        remediation: |\n          Edit the Openshift master config file /etc/origin/master/master-config.yaml and enable ServiceAccount\n          admission control policy.\n\n            ServiceAccount:\n              configuration:\n                kind: DefaultAdmissionConfig\n                apiVersion: v1\n                disable: false\n        scored: true\n\n      - id: 1.28\n        text: \"Verify the certificate and key used to encrypt API server traffic\"\n        audit_config: \"cat /etc/origin/master/master-config.yaml\"\n        tests:\n          bin_op: and\n          test_items:\n            - path: \"{.servingInfo.certFile}\"\n              compare:\n                op: eq\n                value: \"master.server.crt\"\n            - path: \"{.servingInfo.keyFile}\"\n              compare:\n                op: eq\n                value: \"master.server.key\"\n        remediation: |\n          Edit the Openshift master config file /etc/origin/master/master-config.yaml and set keyFile and certFile under servingInfo.\n\n            servingInfo:\n              bindAddress: 0.0.0.0:8443\n              bindNetwork: tcp4\n              certFile: master.server.crt\n              clientCA: ca.crt\n              keyFile: master.server.key\n              maxRequestsInFlight: 500\n              requestTimeoutSeconds: 3600\n        scored: true\n\n      - id: 1.29\n        text: \"Verify that the --client-ca-file argument is not set\"\n        audit_config: \"cat /etc/origin/master/master-config.yaml\"\n        tests:\n          test_items:\n            - path: \"{.servingInfo.clientCA}\"\n              set: false\n        remediation: |\n          Edit the Openshift master config file /etc/origin/master/master-config.yaml and set clientCA under servingInfo.\n\n            servingInfo:\n              bindAddress: 0.0.0.0:8443\n              bindNetwork: tcp4\n              certFile: master.server.crt\n              clientCA: ca.crt\n              keyFile: master.server.key\n              maxRequestsInFlight: 500\n              requestTimeoutSeconds: 3600\n        scored: true\n\n      - id: 1.30\n        text: \"Verify the CA used for communication with etcd\"\n        audit_config: \"cat /etc/origin/master/master-config.yaml\"\n        tests:\n          test_items:\n            - path: \"{.etcdClientInfo.ca}\"\n              compare:\n                op: eq\n                value: \"master.etcd-ca.crt\"\n        remediation: |\n          Edit the Openshift master config file /etc/origin/master/master-config.yaml and set ca under etcdClientInfo.\n\n            etcdClientInfo:\n              ca: master.etcd-ca.crt\n              certFile: master.etcd-client.crt\n              keyFile: master.etcd-client.key\n        scored: true\n\n      - id: 1.31\n        text: \"Verify that the authorization-mode argument is not set\"\n        type: \"skip\"\n        scored: true\n\n      - id: 1.32\n        text: \"Verify that the NodeRestriction admission controller is enabled\"\n        audit_config: \"cat /etc/origin/master/master-config.yaml\"\n        tests:\n          bin_op: or\n          test_items:\n            - path: \"{.NodeRestriction.configuration.disable}\"\n              set: false\n            - path: \"{.NodeRestriction.configuration.disable}\"\n              compare:\n                op: eq\n                value: \"false\"\n        remediation: |\n          Edit the Openshift master config file /etc/origin/master/master-config.yaml and enable NodeRestriction ca under etcdClientInfo.\n\n            NodeRestriction:\n              configuration:\n                kind: DefaultAdmissionConfig\n                apiVersion: v1\n                disable: false\n        scored: true\n\n      - id: 1.33\n        text: \"Configure encryption of data at rest in etcd datastore\"\n        audit_config: \"cat /etc/origin/master/master-config.yaml\"\n        tests:\n          test_items:\n            - path: \"{.kubernetesMasterConfig.apiServerArguments.experimental-encryption-provider-config}\"\n        remediation: |\n          Follow the instructions in the documentation to configure encryption.\n          https://docs.openshift.com/container-platform/3.10/admin_guide/encrypting_data.html\n        scored: true\n\n      - id: 1.34\n        text: \"Set the encryption provider to aescbc for etcd data at rest\"\n\n        audit_config: \"grep -A1 experimental-encryption-provider-config /etc/origin/master/master-config.yaml | sed -n '2p' | awk '{ print $2 }' | xargs cat\"\n        tests:\n          bin_op: and\n          test_items:\n            - path: \"{.resources[*].providers[*].aescbc.keys[*]}}\"\n              compare:\n                op: has\n                value: \"secret\"\n            - path: \"{.resources[*].providers[*].aescbc.keys[*]}}\"\n              compare:\n                op: has\n                value: \"name\"\n        remediation: |\n          Edit the Openshift master config file /etc/origin/master/master-config.yaml and set aescbc as the first provider in encryption provider config.\n          See https://docs.openshift.com/container-platform/3.10/admin_guide/encrypting_data.html.\n        scored: true\n\n      - id: 1.35\n        text: \"Enable the EventRateLimit plugin\"\n        audit_config: \"cat /etc/origin/master/master-config.yaml\"\n        tests:\n          test_items:\n            - path: \"{.admissionConfig.pluginConfig.AlwaysPullImages.configuration.disable}\"\n              compare:\n                op: eq\n                value: \"false\"\n        remediation: |\n          Follow the documentation to enable the EventRateLimit plugin.\n          https://docs.openshift.com/container-platform/3.10/architecture/additional_concepts/admission_controllers.html#admission-controllers-general-admission-rules\n        scored: true\n\n      - id: 1.36\n        text: \"Configure advanced auditing\"\n        audit_config: \"cat /etc/origin/master/master-config.yaml\"\n        tests:\n          bin_op: or\n          test_items:\n            - path: \"{.kubernetesMasterConfig.apiServerArguments.feature-gates.AdvancedAuditing}\"\n              compare:\n                op: eq\n                value: \"true\"\n            - path: \"{.kubernetesMasterConfig.apiServerArguments.feature-gates.AdvancedAuditing}\"\n              set: false\n        remediation: |\n          Edit the Openshift master config file /etc/origin/master/master-config.yaml and enable AdvancedAuditing,\n\n          kubernetesMasterConfig:\n            apiServerArguments:\n              feature-gates:\n                - AdvancedAuditing=true\n        scored: true\n\n      # Review 1.1.37 in Aquasec shared doc, the tests are net zero.\n      - id: 1.37\n        text: \"Adjust the request timeout argument for your cluster resources\"\n        audit: \"grep request-timeout /etc/origin/master/master-config.yaml\"\n        type: \"manual\"\n        remediation: |\n          [Manual test]\n          change the request-timeout value in the  /etc/origin/master/master-config.yaml\n        scored: true\n\n\n  - id: 2\n    text: \"Scheduler\"\n    checks:\n      - id: 2.1\n        text: \"Verify that Scheduler profiling is not exposed to the web\"\n        type: \"skip\"\n        scored: true\n\n\n  - id: 3\n    text: \"Controller Manager\"\n    checks:\n      - id: 3.1\n        text: \"Adjust the terminated-pod-gc-threshold argument as needed\"\n        audit_config: \"cat /etc/origin/master/master-config.yaml\"\n        tests:\n          test_items:\n            - path: \"{.kubernetesMasterConfig.controllerArguments.terminated-pod-gc-threshold}\"\n              compare:\n                op: eq\n                value: \"12500\"\n        remediation: |\n          Edit the Openshift master config file /etc/origin/master/master-config.yaml  and enable terminated-pod-gc-threshold.\n\n            kubernetesMasterConfig:\n              controllerArguments:\n                 terminated-pod-gc-threshold:\n                 - true\n\n          Enabling the \"terminated-pod-gc-threshold\" settings is optional.\n        scored: true\n\n      - id: 3.2\n        text: \"Verify that Controller profiling is not exposed to the web\"\n        type: \"skip\"\n        scored: true\n\n      - id: 3.3\n        text: \"Verify that the --use-service-account-credentials argument is set to true\"\n        audit_config: \"cat /etc/origin/master/master-config.yaml\"\n        tests:\n          bin_op: or\n          test_items:\n            - path: \"{.kubernetesMasterConfig.controllerArguments.use-service-account-credentials}\"\n              set: false\n            - path: \"{.kubernetesMasterConfig.controllerArguments.use-service-account-credentials}\"\n              compare:\n                op: eq\n                value: \"true\"\n        remediation: |\n          Edit the Openshift master config file /etc/origin/master/master-config.yaml and set use-service-account-credentials\n          to true under controllerArguments section.\n\n          kubernetesMasterConfig:\n            controllerArguments:\n               use-service-account-credentials:\n                 - true\n        scored: true\n\n\n      - id: 3.4\n        text: \"Verify that the --service-account-private-key-file argument is set as appropriate\"\n        audit: |\n          grep -A9 serviceAccountConfig /etc/origin/master/master-config.yaml | grep privateKeyFile;\n          grep -A2 service-account-private-key-file /etc/origin/master/master-config.yaml\n        audit_config: \"cat /etc/origin/master/master-config.yaml\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"privateKeyFile: serviceaccounts.private.key\"\n              path: \"{.serviceAccountConfig.privateKeyFile}\"\n              compare:\n                op: eq\n                value: \"serviceaccounts.private.key\"\n            - flag: \"service-account-private-key-file\"\n              set: false\n        remediation: |\n          Edit the Openshift master config file /etc/origin/master/master-config.yaml and remove service-account-private-key-file\n        scored: true\n\n\n      - id: 3.5\n        text: \"Verify that the --root-ca-file argument is set as appropriate\"\n        audit_config: \"cat /etc/origin/master/master-config.yaml\"\n        tests:\n          bin_op: and\n          test_items:\n            - path: \"{.serviceAccountConfig.root-ca-file}\"\n              compare:\n                op: eq\n                value: \"/etc/origin/master/ca-bundle.crt\"\n            - path: \"{.serviceAccountConfig.masterCA}\"\n              compare:\n                op: eq\n                value: \"ca-bundle.crt\"\n        remediation: |\n          Reset to OpenShift defaults OpenShift starts kube-controller-manager with\n          root-ca-file=/etc/origin/master/ca-bundle.crt by default. OpenShift Advanced\n          Installation creates this certificate authority and configuration without any\n          configuration required.\n\n          https://docs.openshift.com/container-platform/3.10/admin_guide/service_accounts.html\"\n        scored: true\n\n      - id: 3.6\n        text: \"Verify that Security Context Constraints are applied to Your Pods and Containers\"\n        type: \"skip\"\n        scored: false\n\n      - id: 3.7\n        text: \"Manage certificate rotation\"\n        audit_config: \"cat /etc/origin/master/master-config.yaml\"\n        tests:\n          test_items:\n            - path: \"{.kubeletArguments.feature-gates.RotateKubeletServerCertificate}\"\n              compare:\n                op: eq\n                value: \"true\"\n        remediation: |\n          If you decide not to enable the RotateKubeletServerCertificate feature,\n          be sure to use the Ansible playbooks provided with the OpenShift installer to\n          automate re-deploying certificates.\n        scored: true\n\n\n  - id: 4\n    text: \"Configuration Files\"\n    checks:\n      - id: 4.1\n        text: \"Verify the OpenShift default permissions for the API server pod specification file\"\n        audit: \"stat -c permissions=%a /etc/origin/node/pods/apiserver.yaml\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command.\n\n          chmod 600 /etc/origin/node/pods/apiserver.yaml\n        scored: true\n\n      - id: 4.2\n        text: \"Verify the OpenShift default file ownership for the API server pod specification file\"\n        audit: \"stat -c %U:%G /etc/origin/node/pods/apiserver.yaml\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command on the master node.\n\n          chown root:root /etc/origin/node/pods/apiserver.yaml\n        scored: true\n\n      - id: 4.3\n        text: \"Verify the OpenShift default file permissions for the controller manager pod specification file\"\n        audit: \"stat -c permissions=%a /etc/origin/node/pods/controller.yaml\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command on the master node.\n\n          chmod 600 /etc/origin/node/pods/controller.yaml\n        scored: true\n\n      - id: 4.4\n        text: \"Verify the OpenShift default ownership for the controller manager pod specification file\"\n        audit: \"stat -c %U:%G /etc/origin/node/pods/controller.yaml\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command on the master node.\n\n          chown root:root /etc/origin/node/pods/controller.yaml\n        scored: true\n\n      - id: 4.5\n        text: \"Verify the OpenShift default permissions for the scheduler pod specification file\"\n        audit: \"stat -c permissions=%a /etc/origin/node/pods/controller.yaml\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command.\n\n          chmod 600 stat -c permissions=%a /etc/origin/node/pods/controller.yaml\n        scored: true\n\n      - id: 4.6\n        text: \"Verify the scheduler pod specification file ownership set by OpenShift\"\n        audit: \"stat -c %U:%G /etc/origin/node/pods/controller.yaml\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command on the master node.\n\n          chown root:root /etc/origin/node/pods/controller.yaml\n        scored: true\n\n      - id: 4.7\n        text: \"Verify the OpenShift default etcd pod specification file permissions\"\n        audit: \"stat -c permissions=%a /etc/origin/node/pods/etcd.yaml\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command.\n\n          chmod 600 /etc/origin/node/pods/etcd.yaml\n        scored: true\n\n      - id: 4.8\n        text: \"Verify the OpenShift default etcd pod specification file ownership\"\n        audit: \"stat -c %U:%G /etc/origin/node/pods/etcd.yaml\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command on the master node.\n\n          chown root:root /etc/origin/node/pods/etcd.yaml\n        scored: true\n\n      - id: 4.9\n        text: \"Verify the default OpenShift Container Network Interface file permissions\"\n        audit: \"stat -c permissions=%a /etc/origin/openvswitch/ /etc/cni/net.d/\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command.\n\n          chmod 644 -R /etc/origin/openvswitch/ /etc/cni/net.d/\n        scored: true\n\n      - id: 4.10\n        text: \"Verify the default OpenShift Container Network Interface file ownership\"\n        audit: \"stat -c %U:%G /etc/origin/openvswitch/ /etc/cni/net.d/\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command on the master node.\n\n          chown root:root /etc/origin/openvswitch/ /etc/cni/net.d/\n        scored: true\n\n      - id: 4.11\n        text: \"Verify the default OpenShift etcd data directory permissions\"\n        audit: \"stat -c permissions=%a /var/lib/etcd\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"700\"\n        remediation: |\n          On the etcd server node, get the etcd data directory, passed as an argument --data-dir ,\n          from the below command:\n          ps -ef | grep etcd\n          Run the below command (based on the etcd data directory found above). For example,\n          chmod 700 /var/lib/etcd\n        scored: true\n\n      - id: 4.12\n        text: \"Verify the default OpenShift etcd data directory ownership\"\n        audit: \"stat -c %U:%G /var/lib/etcd\"\n        tests:\n          test_items:\n            - flag: \"etcd:etcd\"\n        remediation: |\n          Run the below command on the master node.\n\n          chown etcd:etcd /var/lib/etcd\n        scored: true\n\n      - id: 4.13\n        text: \"Verify the default OpenShift admin.conf file permissions\"\n        audit: \"stat -c permissions=%a /etc/origin/master/admin.kubeconfig\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command.\n\n          chmod 644 /etc/origin/master/admin.kubeconfig\"\n        scored: true\n\n      - id: 4.14\n        text: \"Verify the default OpenShift admin.conf file ownership\"\n        audit: \"stat -c %U:%G /etc/origin/master/admin.kubeconfig\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command on the master node.\n\n          chown root:root /etc/origin/master/admin.kubeconfig\n        scored: true\n\n      - id: 4.15\n        text: \"Verify the default OpenShift scheduler.conf file permissions\"\n        audit: \"stat -c permissions=%a /etc/origin/master/openshift-master.kubeconfig\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command.\n\n          chmod 644 /etc/origin/master/openshift-master.kubeconfig\n        scored: true\n\n      - id: 4.16\n        text: \"Verify the default OpenShift scheduler.conf file ownership\"\n        audit: \"stat -c %U:%G /etc/origin/master/openshift-master.kubeconfig\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command on the master node.\n\n          chown root:root /etc/origin/master/openshift-master.kubeconfig\n        scored: true\n\n      - id: 4.17\n        text: \"Verify the default Openshift controller-manager.conf file permissions\"\n        audit: \"stat -c permissions=%a /etc/origin/master/openshift-master.kubeconfig\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command.\n\n          chmod 644 /etc/origin/master/openshift-master.kubeconfig\n        scored: true\n\n      - id: 4.18\n        text: \"Ensure that the controller-manager.conf file ownership is set to root:root (Scored)\"\n        audit: \"stat -c %U:%G /etc/origin/master/openshift-master.kubeconfig\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n              compare:\n                op: eq\n                value: \"root:root\"\n              set: true\n        remediation: |\n          Run the below command on the master node.\n\n          chown root:root /etc/origin/master/openshift-master.kubeconfig\n        scored: true\n\n\n  - id: 5\n    text: \"Etcd\"\n    checks:\n      - id: 5.1\n        text: \"Verify the default OpenShift cert-file and key-file configuration\"\n        audit: \"/bin/sh -c '/usr/local/bin/master-exec etcd etcd grep ETCD_CERT_FILE=/etc/etcd/server.crt /proc/1/environ; /usr/local/bin/master-exec etcd etcd grep ETCD_KEY_FILE=/etc/etcd/server.key /proc/1/environ; grep ETCD_CERT_FILE=/etc/etcd/server.crt /etc/etcd/etcd.conf; grep ETCD_KEY_FILE=/etc/etcd/server.key /etc/etcd/etcd.conf'\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"Binary file /proc/1/environ matches\"\n            - flag: \"ETCD_CERT_FILE\"\n              compare:\n                op: eq\n                value: \"/etc/etcd/server.crt\"\n            - flag: \"ETCD_KEY_FILE\"\n              compare:\n                op: eq\n                value: \"/etc/etcd/server.key\"\n        remediation: |\n          Reset to the OpenShift default configuration.\n        scored: true\n\n      - id: 5.2\n        text: \"Verify the default OpenShift setting for the client-cert-auth argument\"\n        audit: \"/bin/sh -c '/usr/local/bin/master-exec etcd etcd grep ETCD_CLIENT_CERT_AUTH=true /proc/1/environ; grep ETCD_CLIENT_CERT_AUTH /etc/etcd/etcd.conf'\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"Binary file /proc/1/environ matches\"\n            - flag: \"ETCD_CLIENT_CERT_AUTH\"\n              compare:\n                op: eq\n                value: \"true\"\n        remediation: |\n          Reset to the OpenShift default configuration.\n        scored: true\n\n      - id: 5.3\n        text: \"Verify the OpenShift default values for etcd_auto_tls\"\n        audit: \"/bin/sh -c '/usr/local/bin/master-exec etcd etcd grep ETCD_AUTO_TLS /proc/1/environ; grep ETCD_AUTO_TLS /etc/etcd/etcd.conf'\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"ETCD_AUTO_TLS\"\n              compare:\n                op: eq\n                value: \"false\"\n        remediation: |\n          Reset to the OpenShift default configuration.\n        scored: true\n\n      - id: 5.4\n        text: \"Verify the OpenShift default peer-cert-file and peer-key-file arguments for etcd\"\n        audit: \"/bin/sh -c '/usr/local/bin/master-exec etcd etcd grep ETCD_PEER_CERT_FILE=/etc/etcd/peer.crt /proc/1/environ; /usr/local/bin/master-exec etcd etcd grep ETCD_PEER_KEY_FILE=/etc/etcd/peer.key /proc/1/environ; grep ETCD_PEER_CERT_FILE /etc/etcd/etcd.conf; grep ETCD_PEER_KEY_FILE /etc/etcd/etcd.conf'\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"Binary file /proc/1/environ matches\"\n            - flag: \"ETCD_PEER_CERT_FILE\"\n              compare:\n                op: eq\n                value: \"/etc/etcd/peer.crt\"\n            - flag: \"ETCD_PEER_KEY_FILE\"\n              compare:\n                op: eq\n                value: \"/etc/etcd/peer.key\"\n        remediation: |\n          Reset to the OpenShift default configuration.\n        scored: true\n\n      - id: 5.5\n        text: \"Verify the OpenShift default configuration for the peer-client-cert-auth\"\n        audit: \"/bin/sh -c '/usr/local/bin/master-exec etcd etcd grep ETCD_PEER_CLIENT_CERT_AUTH=true /proc/1/environ; grep ETCD_PEER_CLIENT_CERT_AUTH /etc/etcd/etcd.conf'\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"Binary file /proc/1/environ matches\"\n            - flag: \"ETCD_PEER_CLIENT_CERT_AUTH\"\n              compare:\n                op: eq\n                value: \"true\"\n        remediation: |\n          Reset to the OpenShift default configuration.\n        scored: true\n\n      - id: 5.6\n        text: \"Verify the OpenShift default configuration for the peer-auto-tls argument\"\n        audit: \"/bin/sh -c '/usr/local/bin/master-exec etcd etcd grep ETCD_PEER_AUTO_TLS /proc/1/environ; grep ETCD_PEER_AUTO_TLS /etc/etcd/etcd.conf'\"\n        tests:\n          test_items:\n            - flag: \"ETCD_PEER_AUTO_TLS\"\n              compare:\n                op: noteq\n                value: \"true\"\n        remediation: |\n          Reset to the OpenShift default configuration.\n        scored: true\n\n      - id: 5.7\n        text: \"Optionally modify the wal-dir argument\"\n        type: \"skip\"\n        scored: true\n\n      - id: 5.8\n        text: \"Optionally modify the max-wals argument\"\n        type: \"skip\"\n        scored: true\n\n      - id: 5.9\n        text: \"Verify the OpenShift default configuration for the etcd Certificate Authority\"\n        audit: \"openssl x509 -in /etc/origin/master/master.etcd-ca.crt -subject -issuer -noout | sed 's/@/ /'\"\n        tests:\n          test_items:\n            - flag: \"issuer= /CN=etcd-signer\"\n        remediation: |\n          Reset to the OpenShift default configuration.\n        scored: false\n\n\n  - id: 6\n    text: \"General Security Primitives\"\n    checks:\n      - id: 6.1\n        text: \"Ensure that the cluster-admin role is only used where required\"\n        type: \"manual\"\n        remediation: |\n          [Manual test]\n          Review users, groups, serviceaccounts bound to cluster-admin:\n          oc get clusterrolebindings | grep cluster-admin\n\n          Review users and groups bound to cluster-admin and decide whether they require\n          such access. Consider creating least-privilege roles for users and service accounts\n        scored: false\n\n      - id: 6.2\n        text: \"Verify Security Context Constraints as in use\"\n        type: \"manual\"\n        remediation: |\n          [Manual test]\n          Review Security Context Constraints:\n          oc get scc\n\n          Use OpenShift's Security Context Constraint feature, which has been contributed\n          to Kubernetes as Pod Security Policies. PSPs are still beta in Kubernetes 1.10.\n          OpenShift ships with two SCCs: restricted and privileged.\n\n          The two default SCCs will be created when the master is started. The restricted\n          SCC is granted to all authenticated users by default.\n\n           https://docs.openshift.com/container-platform/3.10/admin_guide/manage_scc.html\"\n        scored: false\n\n      - id: 6.3\n        text: \"Use OpenShift projects to maintain boundaries between resources\"\n        type: \"manual\"\n        remediation: |\n          [Manual test]\n          Review projects:\n          oc get projects\n        scored: false\n\n      - id: 6.4\n        text: \"Create network segmentation using the Multi-tenant plugin or Network Policies\"\n        type: \"manual\"\n        remediation: |\n          [Manual test]\n          Verify on masters the plugin being used:\n          grep networkPluginName /etc/origin/master/master-config.yaml\n\n          OpenShift provides multi-tenant networking isolation (using Open vSwich and\n          vXLAN), to segregate network traffic between containers belonging to different\n          tenants (users or applications) while running on a shared cluster. Red Hat also\n          works with 3rd-party SDN vendors to provide the same level of capabilities\n          integrated with OpenShift. OpenShift SDN is included a part of OpenShift\n          subscription.\n\n          OpenShift supports Kubernetes NetworkPolicy. Administrator must configure\n          NetworkPolicies if desired.\n\n          https://docs.openshift.com/container-platform/3.10/architecture/networking/sdn.html#architecture-additional-concepts-sdn\n\n          Ansible Inventory variable: os_sdn_network_plugin_name:\n          https://docs.openshift.com/container-platform/3.10/install/configuring_inventory_file.html\n        scored: false\n\n      - id: 6.5\n        text: \"Enable seccomp and configure custom Security Context Constraints\"\n        type: \"manual\"\n        remediation: |\n          [Manual test]\n          Verify SCCs that have been configured with seccomp:\n          oc get scc -ocustom-columns=NAME:.metadata.name,SECCOMP-PROFILES:.seccompProfiles\n\n          OpenShift does not enable seccomp by default. To configure seccomp profiles that\n          are applied to pods run by the SCC, follow the instructions in the\n          documentation:\n\n          https://docs.openshift.com/container-platform/3.9/admin_guide/seccomp.html#admin-guide-seccomp\n        scored: false\n\n      - id: 6.6\n        text: \"Review Security Context Constraints\"\n        type: \"manual\"\n        remediation: |\n          [Manual test]\n          Review SCCs:\n          oc describe scc\n\n          Use OpenShift's Security Context Constraint feature, which has been contributed\n          to Kubernetes as Pod Security Policies. PSPs are still beta in Kubernetes 1.10.\n\n          OpenShift ships with two SCCs: restricted and privileged. The two default SCCs\n          will be created when the master is started. The restricted SCC is granted to\n          all authenticated users by default.\n\n          All pods are run under the restricted SCC by default. Running a pod under any\n          other SCC requires an account with cluster admin capabilities to grant access\n          for the service account.\n\n          SecurityContextConstraints limit what securityContext is applied to pods and\n          containers.\n\n          https://docs.openshift.com/container-platform/3.10/admin_guide/manage_scc.html\n        scored: false\n\n      - id: 6.7\n        text: \"Manage Image Provenance using ImagePolicyWebhook admission controller\"\n        type: \"manual\"\n        remediation: |\n          [Manual test]\n          Review imagePolicyConfig in /etc/origin/master/master-config.yaml.\n        scored: false\n\n      - id: 6.8\n        text: \"Configure Network policies as appropriate\"\n        type: \"manual\"\n        remediation: |\n          [Manual test]\n          If ovs-networkplugin is used, review network policies:\n          oc get networkpolicies\n\n          OpenShift supports Kubernetes NetworkPolicy via ovs-networkpolicy plugin.\n          If choosing ovs-multitenant plugin, each namespace is isolated in its own\n          netnamespace by default.\n        scored: false\n\n      - id: 6.9\n        text: \"Use Security Context Constraints as compensating controls for privileged containers\"\n        type: \"manual\"\n        remediation: |\n          [Manual test]\n          1) Determine all sccs allowing privileged containers:\n             oc get scc -ocustom-columns=NAME:.metadata.name,ALLOWS_PRIVILEGED:.allowPrivilegedContainer\n          2) Review users and groups assigned to sccs allowing priviliged containers:\n             oc describe sccs <from (1)>\n\n          Use OpenShift's Security Context Constraint feature, which has been contributed\n          to Kubernetes as Pod Security Policies. PSPs are still beta in Kubernetes 1.10.\n\n          OpenShift ships with two SCCs: restricted and privileged. The two default SCCs\n          will be created when the master is started. The restricted SCC is granted to all\n          authenticated users by default.\n\n          Similar scenarios are documented in the SCC\n          documentation, which outlines granting SCC access to specific serviceaccounts.\n          Administrators may create least-restrictive SCCs based on individual container\n          needs.\n\n          For example, if a container only requires running as the root user, the anyuid\n          SCC can be used, which will not expose additional access granted by running\n          privileged containers.\n\n          https://docs.openshift.com/container-platform/3.10/admin_guide/manage_scc.html\n        scored: false\n"
  },
  {
    "path": "cfg/rh-0.7/node.yaml",
    "content": "---\ncontrols:\nversion: \"rh-0.7\"\nid: 2\ntext: \"Worker Node Security Configuration\"\ntype: \"node\"\ngroups:\n  - id: 7\n    text: \"Kubelet\"\n    checks:\n      - id: 7.1\n        text: \"Use Security Context Constraints to manage privileged containers as needed\"\n        type: \"skip\"\n        scored: true\n\n      - id: 7.2\n        text: \"Ensure anonymous-auth is not disabled\"\n        type: \"skip\"\n        scored: true\n\n      - id: 7.3\n        text: \"Verify that the --authorization-mode argument is set to WebHook\"\n        audit_config: \"cat /etc/origin/node/node-config.yaml\"\n        tests:\n          bin_op: or\n          test_items:\n            - path: \"{.kubeletArguments.authorization-mode}\"\n              set: false\n            - path: \"{.kubeletArguments.authorization-mode}\"\n              compare:\n                op: has\n                value: \"Webhook\"\n        remediation: |\n          Edit the Openshift node config file /etc/origin/node/node-config.yaml and remove authorization-mode under\n          kubeletArguments in /etc/origin/node/node-config.yaml or set it to \"Webhook\".\n        scored: true\n\n      - id: 7.4\n        text: \"Verify the OpenShift default for the client-ca-file argument\"\n        audit_config: \"cat /etc/origin/node/node-config.yaml\"\n        tests:\n          test_items:\n            - path: \"{.PodManifestConfig.client-ca-file}\"\n              set: false\n        remediation: |\n          Edit the Openshift node config file /etc/origin/node/node-config.yaml and remove any configuration returned by the following:\n          grep -A1 client-ca-file /etc/origin/node/node-config.yaml\n\n          Reset to the OpenShift default.\n          See https://github.com/openshift/openshift-ansible/blob/release-3.10/roles/openshift_node_group/templates/node-config.yaml.j2#L65\n          The config file does not have this defined in kubeletArgument, but in PodManifestConfig.\n        scored: true\n\n      - id: 7.5\n        text: \"Verify the OpenShift default setting for the read-only-port argument\"\n        audit_config: \"cat /etc/origin/node/node-config.yaml\"\n        tests:\n          bin_op: or\n          test_items:\n            - path: \"{.kubeletArguments.read-only-port}\"\n              set: false\n            - path: \"{.kubeletArguments.read-only-port}\"\n              compare:\n                op: eq\n                value: \"0\"\n        remediation: |\n          Edit the Openshift node config file /etc/origin/node/node-config.yaml and removed so that the OpenShift default is applied.\n        scored: true\n\n      - id: 7.6\n        text: \"Adjust the streaming-connection-idle-timeout argument\"\n        audit_config: \"cat /etc/origin/node/node-config.yaml\"\n        tests:\n          bin_op: or\n          test_items:\n            - path: \"{.kubeletArguments.streaming-connection-idle-timeout}\"\n              set: false\n            - path: \"{.kubeletArguments.streaming-connection-idle-timeout}\"\n              compare:\n                op: eq\n                value: \"5m\"\n        remediation: |\n          Edit the Openshift node config file /etc/origin/node/node-config.yaml and set the streaming-connection-timeout\n          value like the following in node-config.yaml.\n\n          kubeletArguments:\n            streaming-connection-idle-timeout:\n               - \"5m\"\n        scored: true\n\n      - id: 7.7\n        text: \"Verify the OpenShift defaults for the protect-kernel-defaults argument\"\n        type: \"skip\"\n        scored: true\n\n      - id: 7.8\n        text: \"Verify the OpenShift default value of true for the make-iptables-util-chains argument\"\n        audit_config: \"cat /etc/origin/node/node-config.yaml\"\n        tests:\n          bin_op: or\n          test_items:\n            - path: \"{.kubeletArguments.make-iptables-util-chains}\"\n              set: false\n            - path: \"{.kubeletArguments.make-iptables-util-chains}\"\n              compare:\n                op: eq\n                value: \"true\"\n        remediation: |\n          Edit the Openshift node config file /etc/origin/node/node-config.yaml and reset make-iptables-util-chains to the OpenShift\n          default value of true.\n        scored: true\n\n      - id: 7.9\n        text: \"Verify that the --keep-terminated-pod-volumes argument is set to false\"\n        audit_config: \"cat /etc/origin/node/node-config.yaml\"\n        tests:\n          bin_op: or\n          test_items:\n            - path: \"{.kubeletArguments.keep-terminated-pod-volumes}\"\n              set: false\n            - path: \"{.kubeletArguments.keep-terminated-pod-volumes}\"\n              compare:\n                op: eq\n                value: \"false\"\n        remediation: |\n          Reset to the OpenShift defaults\n        scored: true\n\n      - id: 7.10\n        text: \"Verify the OpenShift defaults for the hostname-override argument\"\n        type: \"skip\"\n        scored: true\n\n      - id: 7.11\n        text: \"Set the --event-qps argument to 0\"\n        audit_config: \"cat /etc/origin/node/node-config.yaml\"\n        tests:\n          bin_op: or\n          test_items:\n            - path: \"{.kubeletArguments.event-qps}\"\n              set: false\n            - path: \"{.kubeletArguments.event-qps}\"\n              compare:\n                op: eq\n                value: \"0\"\n        remediation: |\n          Edit the Openshift node config file /etc/origin/node/node-config.yaml set the event-qps argument to 0 in\n          the kubeletArguments section of.\n        scored: true\n\n      - id: 7.12\n        text: \"Verify the OpenShift cert-dir flag for HTTPS traffic\"\n        audit_config: \"cat /etc/origin/node/node-config.yaml\"\n        tests:\n          test_items:\n            - path: \"{.kubeletArguments.cert-dir}\"\n              compare:\n                op: has\n                value: \"/etc/origin/node/certificates\"\n        remediation: |\n          Reset to the OpenShift default values.\n        scored: true\n\n      - id: 7.13\n        text: \"Verify the OpenShift default of 0 for the cadvisor-port argument\"\n        audit_config: \"cat /etc/origin/node/node-config.yaml\"\n        tests:\n          bin_op: or\n          test_items:\n            - path: \"{.kubeletArguments.cadvisor-port}\"\n              set: false\n            - path: \"{.kubeletArguments.cadvisor-port}\"\n              compare:\n                op: eq\n                value: \"0\"\n        remediation: |\n          Edit the Openshift node config file /etc/origin/node/node-config.yaml and remove the cadvisor-port flag\n          if it is set in the  kubeletArguments section.\n        scored: true\n\n      - id: 7.14\n        text: \"Verify that the RotateKubeletClientCertificate argument is set to true\"\n        audit_config: \"cat /etc/origin/node/node-config.yaml\"\n        tests:\n          test_items:\n            - path: \"{.kubeletArguments.feature-gates}\"\n              compare:\n                op: has\n                value: \"RotateKubeletClientCertificate=true\"\n        remediation: |\n          Edit the Openshift node config file /etc/origin/node/node-config.yaml and set RotateKubeletClientCertificate to true.\n        scored: true\n\n      - id: 7.15\n        text: \"Verify that the RotateKubeletServerCertificate argument is set to true\"\n        audit_config: \"cat /etc/origin/node/node-config.yaml\"\n        tests:\n          test_items:\n            - path: \"{.kubeletArguments.feature-gates}\"\n              compare:\n                op: has\n                value: \"RotateKubeletServerCertificate=true\"\n        remediation: |\n          Edit the Openshift node config file /etc/origin/node/node-config.yaml and set RotateKubeletServerCertificate to true.\n        scored: true\n\n\n  - id: 8\n    text: \"Configuration Files\"\n    checks:\n      - id: 8.1\n        text: \"Verify the OpenShift default permissions for the kubelet.conf file\"\n        audit: \"stat -c permissions=%a  /etc/origin/node/node.kubeconfig\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command on each worker node.\n          chmod 644 /etc/origin/node/node.kubeconfig\n        scored: true\n\n      - id: 8.2\n        text: \"Verify the kubeconfig file ownership of root:root\"\n        audit: \"stat -c %U:%G /etc/origin/node/node.kubeconfig\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n          remediation: |\n            Run the below command on each worker node.\n            chown root:root /etc/origin/node/node.kubeconfig\n          scored: true\n\n      - id: 8.3\n        text: \"Verify the kubelet service file permissions of 644\"\n        audit: \"stat -c permissions=%a $kubeletsvc\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command on each worker node.\n          chmod 644 $kubeletsvc\n        scored: true\n\n      - id: 8.4\n        text: \"Verify the kubelet service file ownership of root:root\"\n        audit: \"stat -c %U:%G $kubeletsvc\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n          remediation: |\n            Run the below command on each worker node.\n            chown root:root $kubeletsvc\n          scored: true\n\n      - id: 8.5\n        text: \"Verify the OpenShift default permissions for the proxy kubeconfig file\"\n        audit: \"stat -c permissions=%a /etc/origin/node/node.kubeconfig\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command on each worker node.\n          chmod 644 /etc/origin/node/node.kubeconfig\n        scored: true\n\n      - id: 8.6\n        text: \"Verify the proxy kubeconfig file ownership of root:root\"\n        audit: \"stat -c %U:%G /etc/origin/node/node.kubeconfig\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n          remediation: |\n            Run the below command on each worker node.\n            chown root:root /etc/origin/node/node.kubeconfig\n          scored: true\n\n      - id: 8.7\n        text: \"Verify the OpenShift default permissions for the certificate authorities file.\"\n        audit: \"stat -c permissions=%a /etc/origin/node/client-ca.crt\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command on each worker node.\n          chmod 644 /etc/origin/node/client-ca.crt\n        scored: true\n\n      - id: 8.8\n        text: \"Verify the client certificate authorities file ownership of root:root\"\n        audit: \"stat -c %U:%G /etc/origin/node/client-ca.crt\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n          remediation: |\n            Run the below command on each worker node.\n            chown root:root /etc/origin/node/client-ca.crt\n          scored: true\n"
  },
  {
    "path": "cfg/rh-1.0/config.yaml",
    "content": "---\n## Version-specific settings that override the values in cfg/config.yaml\n"
  },
  {
    "path": "cfg/rh-1.0/controlplane.yaml",
    "content": "---\ncontrols:\nversion: rh-1.0\nid: 3\ntext: \"Control Plane Configuration\"\ntype: \"controlplane\"\ngroups:\n  - id: 3.1\n    text: \"Authentication and Authorization\"\n    checks:\n      - id: 3.1.1\n        text: \"Client certificate authentication should not be used for users (Manual)\"\n        audit: |\n          # To verify user authentication is enabled\n          oc describe authentication\n          # To verify that an identity provider is configured\n          oc get identity\n          # To verify that a custom cluster-admin user exists\n          oc get clusterrolebindings -o=custom-columns=NAME:.metadata.name,ROLE:.roleRef.name,SUBJECT:.subjects[*].kind | grep cluster-admin | grep User\n          # To verity that kbueadmin is removed, no results should be returned\n          oc get secrets kubeadmin -n kube-system\n        type: manual\n        remediation: |\n          Configure an identity provider for the OpenShift cluster.\n          Understanding identity provider configuration | Authentication | OpenShift\n          Container Platform 4.5. Once an identity provider has been defined,\n          you can use RBAC to define and apply permissions.\n          After you define an identity provider and create a new cluster-admin user,\n          remove the kubeadmin user to improve cluster security.\n        scored: false\n\n  - id: 3.2\n    text: \"Logging\"\n    checks:\n      - id: 3.2.1\n        text: \"Ensure that a minimal audit policy is created (Manual)\"\n        audit: |\n          #To view kube apiserver log files\n          oc adm node-logs --role=master --path=kube-apiserver/\n          #To view openshift apiserver log files\n          oc adm node-logs --role=master --path=openshift-apiserver/\n          #To verify kube apiserver audit config\n          oc get configmap config -n openshift-kube-apiserver -ojson | jq -r '.data[\"config.yaml\"]' | jq '.auditConfig[]?'\n          #To verify openshift apiserver audit config\n          oc get configmap config -n openshift-apiserver -ojson | jq -r '.data[\"config.yaml\"]' | jq '.auditConfig[]?'\n        type: manual\n        remediation: |\n          No remediation required.\n        scored: false\n\n      - id: 3.2.2\n        text: \"Ensure that the audit policy covers key security concerns (Manual)\"\n        audit: |\n          #To verify openshift apiserver audit config\n          oc get configmap config -n openshift-kube-apiserver -ojson | jq -r '.data[\"config.yaml\"]' | jq '.auditConfig.policyConfiguration.rules[]?'\n          #To verify kube apiserver audit config\n          oc get configmap config -n openshift-apiserver -ojson | jq -r '.data[\"config.yaml\"]' | jq '.auditConfig.policyConfiguration.rules[]?'\n        type: manual\n        remediation: |\n          In OpenShift 4.6 and higher, if appropriate for your needs,\n          modify the audit policy.\n        scored: false\n"
  },
  {
    "path": "cfg/rh-1.0/etcd.yaml",
    "content": "---\ncontrols:\nversion: rh-1.0\nid: 2\ntext: \"Etcd Node Configuration\"\ntype: \"etcd\"\ngroups:\n  - id: 2\n    text: \"Etcd Node Configuration Files\"\n    checks:\n      - id: 2.1\n        text: \"Ensure that the --cert-file and --key-file arguments are set as appropriate (Manual)\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n          # Get the pod name in the openshift-etcd namespace\n          POD_NAME=$(oc get pods -n openshift-etcd -l app=etcd --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n          if [ -z \"$POD_NAME\" ]; then\n          echo \"No matching file found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-etcd -c etcd \"$POD_NAME\" -- ps -o command= -C etcd | sed 's/.*\\(--cert-file=[^ ]*\\).*/\\1/'\n          oc exec -n openshift-etcd -c etcd \"$POD_NAME\" -- ps -o command= -C etcd | sed 's/.*\\(--key-file=[^ ]*\\).*/\\1/'\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"file\"\n              compare:\n                op: regex\n                value: '\\/etc\\/kubernetes\\/static-pod-certs\\/secrets\\/etcd-all-serving\\/etcd-serving-.*\\.(?:crt|key)'\n        remediation: |\n          OpenShift does not use the etcd-certfile or etcd-keyfile flags.\n          Certificates for etcd are managed by the etcd cluster operator.\n        scored: false\n\n      - id: 2.2\n        text: \"Ensure that the --client-cert-auth argument is set to true (Manual)\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n          # Get the pod name in the openshift-etcd namespace\n          POD_NAME=$(oc get pods -n openshift-etcd -l app=etcd --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n          if [ -z \"$POD_NAME\" ]; then\n          echo \"No matching file found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-etcd -c etcd \"$POD_NAME\" -- ps -o command= -C etcd | sed 's/.*\\(--client-cert-auth=[^ ]*\\).*/\\1/'\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"--client-cert-auth\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          This setting is managed by the cluster etcd operator. No remediation required.\"\n        scored: false\n\n      - id: 2.3\n        text: \"Ensure that the --auto-tls argument is not set to true (Manual)\"\n        audit: |\n          # Returns 0 if found, 1 if not found\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n          # Get the pod name in the openshift-etcd namespace\n          POD_NAME=$(oc get pods -n openshift-etcd -l app=etcd --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n          if [ -z \"$POD_NAME\" ]; then\n          echo \"No matching file found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-etcd -c etcd \"$POD_NAME\" -- ps -o command= -C etcd | grep -- --auto-tls=true 2>/dev/null ; echo exit_code=$?\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"exit_code\"\n              compare:\n                op: eq\n                value: \"1\"\n        remediation: |\n          This setting is managed by the cluster etcd operator. No remediation required.\n        scored: false\n\n      - id: 2.4\n        text: \"Ensure that the --peer-cert-file and --peer-key-file arguments are set as appropriate (Manual)\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n          # Get the pod name in the openshift-etcd namespace\n          POD_NAME=$(oc get pods -n openshift-etcd -l app=etcd --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n          if [ -z \"$POD_NAME\" ]; then\n          echo \"No matching file found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-etcd -c etcd \"$POD_NAME\" -- ps -o command= -C etcd | sed 's/.*\\(--peer-cert-file=[^ ]*\\).*/\\1/'\n          oc exec -n openshift-etcd -c etcd \"$POD_NAME\" -- ps -o command= -C etcd | sed 's/.*\\(--peer-key-file=[^ ]*\\).*/\\1/'\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"file\"\n              compare:\n                op: regex\n                value: '\\/etc\\/kubernetes\\/static-pod-certs\\/secrets\\/etcd-all-peer\\/etcd-peer-.*\\.(?:crt|key)'\n        remediation: |\n          None. This configuration is managed by the etcd operator.\n        scored: false\n\n      - id: 2.5\n        text: \"Ensure that the --peer-client-cert-auth argument is set to true (Manual)\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n          # Get the pod name in the openshift-etcd namespace\n          POD_NAME=$(oc get pods -n openshift-etcd -l app=etcd --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n          if [ -z \"$POD_NAME\" ]; then\n          echo \"No matching file found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-etcd -c etcd \"$POD_NAME\" -- ps -o command= -C etcd | sed 's/.*\\(--peer-client-cert-auth=[^ ]*\\).*/\\1/'\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"--peer-client-cert-auth\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          This setting is managed by the cluster etcd operator. No remediation required.\n        scored: false\n\n      - id: 2.6\n        text: \"Ensure that the --peer-auto-tls argument is not set to true (Manual)\"\n        audit: |\n          # Returns 0 if found, 1 if not found\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n          # Get the pod name in the openshift-etcd namespace\n          POD_NAME=$(oc get pods -n openshift-etcd -l app=etcd --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n          if [ -z \"$POD_NAME\" ]; then\n          echo \"No matching file found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-etcd -c etcd \"$POD_NAME\" -- ps -o command= -C etcd | grep -- --peer-auto-tls=true 2>/dev/null ; echo exit_code=$?\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"exit_code\"\n              compare:\n                op: eq\n                value: \"1\"\n        remediation: |\n          This setting is managed by the cluster etcd operator. No remediation required.\n        scored: false\n\n      - id: 2.7\n        text: \"Ensure that a unique Certificate Authority is used for etcd (Manual)\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n          # Get the pod name in the openshift-etcd namespace\n          POD_NAME=$(oc get pods -n openshift-etcd -l app=etcd --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n          if [ -z \"$POD_NAME\" ]; then\n          echo \"No matching file found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-etcd -c etcd \"$POD_NAME\" -- ps -o command= -C etcd | sed 's/.*\\(--trusted-ca-file=[^ ]*\\).*/\\1/'\n          oc exec -n openshift-etcd -c etcd \"$POD_NAME\" -- ps -o command= -C etcd | sed 's/.*\\(--peer-trusted-ca-file=[^ ]*\\).*/\\1/'\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"file\"\n              compare:\n                op: regex\n                value: '\\/etc\\/kubernetes\\/static-pod-certs\\/configmaps\\/etcd-(?:serving|peer-client)-ca\\/ca-bundle\\.(?:crt|key)'\n        remediation: |\n          None required. Certificates for etcd are managed by the OpenShift cluster etcd operator.\n        scored: false\n"
  },
  {
    "path": "cfg/rh-1.0/master.yaml",
    "content": "---\ncontrols:\nversion: rh-1.0\nid: 1\ntext: \"Master Node Security Configuration\"\ntype: \"master\"\ngroups:\n  - id: 1.1\n    text: \"Master Node Configuration Files\"\n    checks:\n      - id: 1.1.1\n        text: \"Ensure that the API server pod specification file permissions are set to 644 or more restrictive (Manual)\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n\n          # Get the pod name in the openshift-kube-apiserver namespace\n          POD_NAME=$(oc get pods -n openshift-kube-apiserver -l app=openshift-kube-apiserver --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n              echo \"No matching pods found on the current node.\"\n          else\n             # Execute the stat command\n             oc exec -n openshift-kube-apiserver \"$POD_NAME\" -- stat -c \"$POD_NAME %n permissions=%a\" /etc/kubernetes/static-pod-resources/kube-apiserver-pod.yaml\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          No remediation required; file permissions are managed by the operator.\n        scored: false\n\n      - id: 1.1.2\n        text: \"Ensure that the API server pod specification file ownership is set to root:root (Manual)\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n\n          # Get the pod name in the openshift-kube-apiserver namespace\n          POD_NAME=$(oc get pods -n openshift-kube-apiserver -l app=openshift-kube-apiserver --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n              echo \"No matching pods found on the current node.\"\n          else\n             # Execute the stat command\n             oc exec -n openshift-kube-apiserver \"$POD_NAME\" -- stat -c \"$POD_NAME %n %U:%G\" /etc/kubernetes/static-pod-resources/kube-apiserver-pod.yaml\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          No remediation required; file permissions are managed by the operator.\n        scored: false\n\n      - id: 1.1.3\n        text: \"Ensure that the controller manager pod specification file permissions are set to 644 or more restrictive (Manual)\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n\n          # Get the pod name in the openshift-kube-controller-manager namespace\n          POD_NAME=$(oc get pods -n openshift-kube-controller-manager -l app=kube-controller-manager --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n             echo \"No matching pods found on the current node.\"\n          else\n            # Execute the stat command\n            oc exec -n openshift-kube-controller-manager \"$POD_NAME\" -- stat -c \"$POD_NAME %n permissions=%a\" /etc/kubernetes/static-pod-resources/kube-controller-manager-pod.yaml\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          No remediation required; file permissions are managed by the operator.\n        scored: false\n\n      - id: 1.1.4\n        text: \"Ensure that the controller manager pod specification file ownership is set to root:root (Manual)\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n\n          # Get the pod name in the openshift-kube-controller-manager namespace\n          POD_NAME=$(oc get pods -n openshift-kube-controller-manager -l app=kube-controller-manager --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n            echo \"No matching pods found on the current node.\"\n          else\n           # Execute the stat command\n           oc exec -n openshift-kube-controller-manager \"$POD_NAME\" -- stat -c \"$POD_NAME %n %U:%G\" /etc/kubernetes/static-pod-resources/kube-controller-manager-pod.yaml\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          No remediation required; file permissions are managed by the operator.\n        scored: false\n\n      - id: 1.1.5\n        text: \"Ensure that the scheduler pod specification file permissions are set to 644 or more restrictive (Manual)\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n\n          # Get the pod name in the openshift-kube-scheduler namespace\n          POD_NAME=$(oc get pods -n openshift-kube-scheduler -l app=openshift-kube-scheduler --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n           echo \"No matching pods found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-kube-scheduler \"$POD_NAME\" -- stat -c \"$POD_NAME %n permissions=%a\" /etc/kubernetes/static-pod-resources/kube-scheduler-pod.yaml\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          No remediation required; file permissions are managed by the operator.\n        scored: false\n\n      - id: 1.1.6\n        text: \"Ensure that the scheduler pod specification file ownership is set to root:root (Manual))\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n\n          # Get the pod name in the openshift-kube-scheduler namespace\n          POD_NAME=$(oc get pods -n openshift-kube-scheduler -l app=openshift-kube-scheduler --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n           echo \"No matching pods found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-kube-scheduler \"$POD_NAME\" -- stat -c \"$POD_NAME %n %U:%G\" /etc/kubernetes/static-pod-resources/kube-scheduler-pod.yaml\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          No remediation required; file permissions are managed by the operator.\n        scored: false\n\n      - id: 1.1.7\n        text: \"Ensure that the etcd pod specification file permissions are set to 644 or more restrictive (Manual))\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n\n          # Get the pod name in the openshift-etcd namespace\n          POD_NAME=$(oc get pods -n openshift-etcd -l app=etcd --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n           echo \"No matching pods found on the current node.\"\n          else\n          # Execute the stat command\n          oc rsh -n openshift-etcd \"$POD_NAME\" stat -c \"$POD_NAME %n permissions=%a\" /etc/kubernetes/manifests/etcd-pod.yaml\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          No remediation required; file permissions are managed by the operator.\n        scored: false\n\n      - id: 1.1.8\n        text: \"Ensure that the etcd pod specification file ownership is set to root:root (Manual)\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n\n          # Get the pod name in the openshift-etcd namespace\n          POD_NAME=$(oc get pods -n openshift-etcd -l app=etcd --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n           echo \"No matching pods found on the current node.\"\n          else\n          # Execute the stat command\n          oc rsh -n openshift-etcd \"$POD_NAME\" stat -c \"$POD_NAME %n %U:%G\" /etc/kubernetes/manifests/etcd-pod.yaml\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          No remediation required; file permissions are managed by the operator.\n        scored: false\n\n      - id: 1.1.9\n        text: \"Ensure that the Container Network Interface file permissions are set to 644 or more restrictive (Manual)\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n          # For CNI multus\n          # Get the pod name in the openshift-multus namespace\n          POD_NAME=$(oc get pods -n openshift-multus -l app=multus --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n           echo \"No matching pods found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-multus \"$POD_NAME\"  -- /bin/bash -c \"stat -c \\\"$i %n permissions=%a\\\" /host/etc/cni/net.d/*.conf\";  2>/dev/null\n          oc exec -n openshift-multus \"$POD_NAME\"  -- /bin/bash -c \"stat -c \\\"$i %n permissions=%a\\\" /host/var/run/multus/cni/net.d/*.conf\";  2>/dev/null\n          fi\n          # For SDN pods\n          POD_NAME=$(oc get pods -n openshift-sdn -l app=sdn --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n           echo \"No matching pods found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-sdn \"$POD_NAME\"  -- find /var/lib/cni/networks/openshift-sdn -type f -exec stat -c \"$i %n permissions=%a\" {} \\; 2>/dev/null\n          oc exec -n openshift-sdn \"$POD_NAME\"  -- find /var/run/openshift-sdn -type f -exec stat -c \"$i %n permissions=%a\" {} \\; 2>/dev/null\n          fi\n\n          # For OVS pods\n          POD_NAME=$(oc get pods -n openshift-sdn -l app=ovs --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n           echo \"No matching pods found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-sdn \"$POD_NAME\"  -- find /var/run/openvswitch -type f -exec stat -c \"$i %n permissions=%a\" {} \\; 2>/dev/null\n          oc exec -n openshift-sdn \"$POD_NAME\"  -- find /etc/openvswitch -type f -exec stat -c \"$i %n permissions=%a\" {} \\; 2>/dev/null\n          oc exec -n openshift-sdn \"$POD_NAME\"  -- find /run/openvswitch -type f -exec stat -c \"$i %n permissions=%a\" {} \\; 2>/dev/null\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          No remediation required; file permissions are managed by the operator.\n        scored: false\n\n      - id: 1.1.10\n        text: \"Ensure that the Container Network Interface file ownership is set to root:root (Manual)\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n          # For CNI multus\n          # Get the pod name in the openshift-multus namespace\n          POD_NAME=$(oc get pods -n openshift-multus -l app=multus --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n           echo \"No matching pods found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-multus \"$POD_NAME\" -- /bin/bash -c \"stat -c '$i %n %U:%G' /host/etc/cni/net.d/*.conf\" 2>/dev/null\n          oc exec -n openshift-multus $i -- /bin/bash -c \"stat -c '$i %n %U:%G' /host/var/run/multus/cni/net.d/*.conf\"  2>/dev/null\n          fi\n          # For SDN pods\n          POD_NAME=$(oc get pods -n openshift-sdn -l app=sdn --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n           echo \"No matching pods found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-sdn \"$POD_NAME\"  -- find /var/lib/cni/networks/openshift-sdn -type f -exec stat -c \"$i %n %U:%G\" {} \\; 2>/dev/null\n          oc exec -n openshift-sdn \"$POD_NAME\"  -- find /var/run/openshift-sdn -type f -exec stat -c \"$i %n %U:%G\" {} \\; 2>/dev/null\n          fi\n          # For OVS pods in 4.5\n          POD_NAME=$(oc get pods -n openshift-sdn -l app=ovs --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n           echo \"No matching pods found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-sdn \"$POD_NAME\"  -- find /var/run/openvswitch -type f -exec stat -c \"$i %n %U:%G\" {} \\; 2>/dev/null\n          oc exec -n openshift-sdn \"$POD_NAME\"  -- find /etc/openvswitch -type f -exec stat -c \"$i %n %U:%G\" {} \\; 2>/dev/null\n          oc exec -n openshift-sdn \"$POD_NAME\"  -- find /run/openvswitch -type f -exec stat -c \"$i %n %U:%G\" {} \\; 2>/dev/null\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          No remediation required; file permissions are managed by the operator.\n        scored: false\n\n      - id: 1.1.11\n        text: \"Ensure that the etcd data directory permissions are set to 700 or more restrictive (Manual)\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n\n          # Get the pod name in the openshift-etcd namespace\n          POD_NAME=$(oc get pods -n openshift-etcd -l app=etcd --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n          echo \"No matching pods found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-etcd \"$POD_NAME\" -- stat -c \"$POD_NAME %n permissions=%a\" /var/lib/etcd/member\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"700\"\n        remediation: |\n          No remediation required; file permissions are managed by the operator.\n        scored: false\n\n      - id: 1.1.12\n        text: \"Ensure that the etcd data directory ownership is set to etcd:etcd (Manual)\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n\n          # Get the pod name in the openshift-etcd namespace\n          POD_NAME=$(oc get pods -n openshift-etcd -l app=etcd --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n          echo \"No matching pods found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-etcd \"$POD_NAME\" -- stat -c \"$POD_NAME %n %U:%G\" /var/lib/etcd/member\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          No remediation required; file permissions are managed by the operator.\n        scored: false\n\n      - id: 1.1.13\n        text: \"Ensure that the admin.conf file permissions are set to 644 or more restrictive (Manual))\"\n        audit: |\n          NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')\n          oc debug node/$NODE_NAME -- chroot /host stat -c \"$NODE_NAME %n permissions=%a\" /etc/kubernetes/kubeconfig 2> /dev/null\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          No remediation required; file permissions are managed by the operator.\n        scored: false\n\n      - id: 1.1.14\n        text: \"Ensure that the admin.conf file ownership is set to root:root (Manual)\"\n        audit: |\n          NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')\n          oc debug node/$NODE_NAME -- chroot /host stat -c \"$NODE_NAME %n %U:%G\" /etc/kubernetes/kubeconfig 2> /dev/null\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          No remediation required; file permissions are managed by the operator.\n        scored: false\n\n      - id: 1.1.15\n        text: \"Ensure that the scheduler.conf file permissions are set to 644 or more restrictive (Manual)\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n\n          # Get the pod name in the openshift-kube-scheduler namespace\n          POD_NAME=$(oc get pods -n openshift-kube-scheduler -l app=openshift-kube-scheduler --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n          echo \"No matching pods found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-kube-scheduler \"$POD_NAME\" -- stat -c \"$POD_NAME %n permissions=%a\" /etc/kubernetes/static-pod-resources/configmaps/scheduler-kubeconfig/kubeconfig\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          No remediation required; file permissions are managed by the operator.\n        scored: false\n\n      - id: 1.1.16\n        text: \"Ensure that the scheduler.conf file ownership is set to root:root (Manual)\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n\n          # Get the pod name in the openshift-kube-scheduler namespace\n          POD_NAME=$(oc get pods -n openshift-kube-scheduler -l app=openshift-kube-scheduler --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n          echo \"No matching pods found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-kube-scheduler \"$POD_NAME\" -- stat -c \"$POD_NAME %n %U:%G\" /etc/kubernetes/static-pod-resources/configmaps/scheduler-kubeconfig/kubeconfig\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          No remediation required; file permissions are managed by the operator.\n        scored: false\n\n      - id: 1.1.17\n        text: \"Ensure that the controller-manager.conf file permissions are set to 644 or more restrictive (Manual)\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n\n          # Get the pod name in the openshift-kube-controller-manager namespace\n          POD_NAME=$(oc get pods -n openshift-kube-controller-manager -l app=kube-controller-manager --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n          echo \"No matching pods found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-kube-controller-manager \"$POD_NAME\" -- stat -c \"$POD_NAME %n permissions=%a\" /etc/kubernetes/static-pod-resources/configmaps/controller-manager-kubeconfig/kubeconfig\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          No remediation required; file permissions are managed by the operator.\n        scored: false\n\n      - id: 1.1.18\n        text: \"Ensure that the controller-manager.conf file ownership is set to root:root (Manual)\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n\n          # Get the pod name in the openshift-kube-controller-manager namespace\n          POD_NAME=$(oc get pods -n openshift-kube-controller-manager -l app=kube-controller-manager --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n          echo \"No matching pods found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-kube-controller-manager \"$POD_NAME\" -- stat -c \"$POD_NAME %n %U:%G\" /etc/kubernetes/static-pod-resources/configmaps/controller-manager-kubeconfig/kubeconfig\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          No remediation required; file permissions are managed by the operator.\n        scored: false\n\n      - id: 1.1.19\n        text: \"Ensure that the Kubernetes PKI directory and file ownership is set to root:root (Manual)\"\n        audit: |\n          # Should return root:root for all files and directories\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n\n          # Get the pod name in the openshift-kube-controller-manager namespace\n          POD_NAME=$(oc get pods -n openshift-kube-apiserver -l app=openshift-kube-apiserver --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n          echo \"No matching pods found on the current node.\"\n          else\n          # echo $i static-pod-certs\n          oc exec -n openshift-kube-apiserver \"$POD_NAME\" -c kube-apiserver -- find /etc/kubernetes/static-pod-certs -type d -wholename '*/secrets*' -exec stat -c \"$i %n %U:%G\" {} \\;\n          oc exec -n openshift-kube-apiserver \"$POD_NAME\" -c kube-apiserver -- find /etc/kubernetes/static-pod-certs -type f -wholename '*/secrets*' -exec stat -c \"$i %n %U:%G\" {} \\;\n          # echo $i static-pod-resources\n          oc exec -n openshift-kube-apiserver \"$POD_NAME\" -c kube-apiserver -- find /etc/kubernetes/static-pod-resources -type d -wholename '*/secrets*' -exec stat -c \"$i %n %U:%G\" {} \\;\n          oc exec -n openshift-kube-apiserver \"$POD_NAME\" -c kube-apiserver -- find /etc/kubernetes/static-pod-resources -type f -wholename '*/secrets*' -exec stat -c \"$i %n %U:%G\" {} \\;\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          No remediation required; file permissions are managed by the operator.\n        scored: false\n\n      - id: 1.1.20\n        text: \"Ensure that the OpenShift PKI certificate file permissions are set to 644 or more restrictive (Manual)\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n\n          # Get the pod name in the openshift-kube-apiserver namespace\n          POD_NAME=$(oc get pods -n openshift-kube-apiserver -l app=openshift-kube-apiserver --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n          echo \"No matching pods found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-kube-apiserver \"$POD_NAME\" -c kube-apiserver -- find /etc/kubernetes/static-pod-certs -type f -wholename '*/secrets/*.crt' -exec stat -c \"$POD_NAME %n permissions=%a\" {} \\;\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          No remediation required; file permissions are managed by the operator.\n        scored: false\n\n      - id: 1.1.21\n        text: \"Ensure that the OpenShift PKI key file permissions are set to 600 (Manual)\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n\n          # Get the pod name in the openshift-kube-apiserver namespace\n          POD_NAME=$(oc get pods -n openshift-kube-apiserver -l app=openshift-kube-apiserver --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n          echo \"No matching pods found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-kube-apiserver \"$POD_NAME\" -c kube-apiserver -- find /etc/kubernetes/static-pod-certs -type f -wholename '*/secrets/*.key' -exec stat -c \"$POD_NAME %n permissions=%a\" {} \\;\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          No remediation required; file permissions are managed by the operator.\n        scored: false\n\n  - id: 1.2\n    text: \"API Server\"\n    checks:\n      - id: 1.2.1\n        text: \"Ensure that anonymous requests are authorized (Manual)\"\n        audit: |\n          # To verify that userGroups include system:unauthenticated\n          oc get configmap config -n openshift-kube-apiserver -ojson | jq -r '.data[\"config.yaml\"]' | jq '.auditConfig.policyConfiguration.rules[]?'\n          # To verify that userGroups include system:unauthenticated\n          oc get configmap config -n openshift-apiserver -ojson | jq -r '.data[\"config.yaml\"]' | jq '.auditConfig.policyConfiguration.rules[]?.userGroups'\n          # To verify RBAC is enabled\n          oc get clusterrolebinding\n          oc get clusterrole\n          oc get rolebinding\n          oc get role\n        tests:\n          test_items:\n            - flag: \"system:unauthenticated\"\n        remediation: |\n          None required. The default configuration should not be modified.\n        scored: false\n\n      - id: 1.2.2\n        text: \"Ensure that the --basic-auth-file argument is not set (Manual)\"\n        audit: |\n          oc -n openshift-kube-apiserver get cm config -o yaml | grep --color \"basic-auth\"\n          oc -n openshift-apiserver get cm config -o yaml | grep --color \"basic-auth\"\n          # Add | awk '$3 != \"AVAILABLE\" { if ($3){print \"available=true\"}else{print \"available=false\"} }; to create AVAILABLE = true/false form\n          oc get clusteroperator authentication | awk '$3 != \"AVAILABLE\" { if ($3){print \"available=true\"}else{print \"available=false\"} }'\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"basic-auth-file\"\n              set: false\n            - flag: \"available\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          None required. --basic-auth-file cannot be configured on OpenShift.\n        scored: false\n\n      - id: 1.2.3\n        text: \"Ensure that the --token-auth-file parameter is not set (Manual)\"\n        audit: |\n          # Verify that the token-auth-file flag is not present\n          oc get configmap config -n openshift-kube-apiserver -ojson | jq -r '.data[\"config.yaml\"]' | jq '.apiServerArguments'\n          oc get configmap config -n openshift-apiserver -ojson | jq -r '.data[\"config.yaml\"]' | jq '.apiServerArguments'\n          oc get kubeapiservers.operator.openshift.io cluster -o json | jq '.spec.observedConfig.apiServerArguments'\n          #Verify that the authentication operator is running\n          oc get clusteroperator authentication | awk '$3 != \"AVAILABLE\" { if ($3){print \"available=true\"}else{print \"available=false\"} }'\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"token-auth-file\"\n              set: false\n            - flag: \"available\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          None is required.\n        scored: false\n\n      - id: 1.2.4\n        text: \"Use https for kubelet connections (Manual)\"\n        audit: |\n          #for 4.5\n          oc get configmap config -n openshift-kube-apiserver -ojson | jq -r '.data[\"config.yaml\"]' | jq '.kubeletClientInfo'\n          #for 4.6\n          oc get configmap config -n openshift-kube-apiserver -ojson | jq -r '.data[\"config.yaml\"]' | jq '.apiServerArguments'\n          #for both 4.5 and 4.6\n          oc -n openshift-apiserver describe secret serving-cert\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"/etc/kubernetes/static-pod-resources/secrets/kubelet-client/tls.crt\"\n            - flag: \"/etc/kubernetes/static-pod-resources/secrets/kubelet-client/tls.key\"\n        remediation: |\n          No remediation is required.\n          OpenShift platform components use X.509 certificates for authentication.\n          OpenShift manages the CAs and certificates for platform components. This is not configurable.\n        scored: false\n\n      - id: 1.2.5\n        text: \"Ensure that the kubelet uses certificates to authenticate (Manual)\"\n        audit: |\n          #for 4.5\n          oc get configmap config -n openshift-kube-apiserver -ojson | jq -r '.data[\"config.yaml\"]' | jq '.kubeletClientInfo'\n          #for 4.6\n          oc get configmap config -n openshift-kube-apiserver -ojson | jq -r '.data[\"config.yaml\"]' | jq '.apiServerArguments'\n          #for both 4.5 and 4.6\n          oc -n openshift-apiserver describe secret serving-cert\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"/etc/kubernetes/static-pod-resources/secrets/kubelet-client/tls.crt\"\n            - flag: \"/etc/kubernetes/static-pod-resources/secrets/kubelet-client/tls.key\"\n        remediation: |\n          No remediation is required.\n          OpenShift platform components use X.509 certificates for authentication.\n          OpenShift manages the CAs and certificates for platform components.\n          This is not configurable.\n        scored: false\n\n      - id: 1.2.6\n        text: \"Verify that the kubelet certificate authority is set as appropriate (Manual)\"\n        audit: |\n          # for 4.5\n          oc get configmap config -n openshift-kube-apiserver -ojson | jq -r '.data[\"config.yaml\"]' | jq '.kubeletClientInfo'\n          # for 4.6\n          oc get configmap config -n openshift-kube-apiserver -ojson | jq -r '.data[\"config.yaml\"]' | jq '.apiServerArguments'\n        tests:\n          test_items:\n            - flag: \"/etc/kubernetes/static-pod-resources/configmaps/kubelet-serving-ca/ca-bundle.crt\"\n        remediation: |\n          No remediation is required.\n          OpenShift platform components use X.509 certificates for authentication.\n          OpenShift manages the CAs and certificates for platform components.\n          This is not configurable.\n        scored: false\n\n      - id: 1.2.7\n        text: \"Ensure that the --authorization-mode argument is not set to AlwaysAllow (Manual)\"\n        audit: |\n          # To verify that the authorization-mode argument is not used\n          oc get configmap config -n openshift-kube-apiserver -ojson | jq -r '.data[\"config.yaml\"]' | jq '.apiServerArguments'\n          oc get configmap config -n openshift-apiserver -ojson | jq -r '.data[\"config.yaml\"]' | jq '.apiServerArguments'\n          #Check that no overrides are configured\n          oc get kubeapiservers.operator.openshift.io cluster -o json | jq -r '.spec.unsupportedConfigOverrides'\n          # To verify RBAC is configured:\n          oc get clusterrolebinding\n          oc get clusterrole\n          oc get rolebinding\n          oc get role\n        audit_config: |\n          oc get configmap config -n openshift-kube-apiserver -ojson | jq -r '.data[\"config.yaml\"]' | jq '.apiServerArguments'\n        tests:\n          bin_op: or\n          test_items:\n            - path: \"{.authorization-mode}\"\n              compare:\n                op: nothave\n                value: \"AlwaysAllow\"\n            - path: \"{.authorization-mode}\"\n              flag: \"authorization-mode\"\n              set: false\n        remediation: |\n          None. RBAC is always on and the OpenShift API server does not use the values assigned to the flag authorization-mode.\n        scored: false\n\n      - id: 1.2.8\n        text: \"Verify that the Node authorizer is enabled (Manual)\"\n        audit: |\n          # For OCP 4.5 and earlier verify that authorization-mode is not used\n          oc get configmap config -n openshift-kube-apiserver -ojson | jq -r '.data[\"config.yaml\"]' | jq '.apiServerArguments'\n          oc get kubeapiservers.operator.openshift.io cluster -o json | jq '.spec.observedConfig.apiServerArguments'\n          # For OCP 4.5 and earlier verify that authorization-mode is not used\n          NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')\n          oc debug node/$NODE_NAME -- chroot /host cat /etc/kubernetes/kubelet.conf | grep authorization-mode 2> /dev/null\n          oc debug node/$NODE_NAME -- chroot /host ps -aux | grep kubelet | grep authorization-mode 2> /dev/null\n          #Check that no overrides are configured\n          oc get kubeapiservers.operator.openshift.io cluster -o json | jq -r '.spec.unsupportedConfigOverrides'\n        audit_config: |\n          oc get configmap config -n openshift-kube-apiserver -ojson | jq -r '.data[\"config.yaml\"]' | jq '.apiServerArguments'\n        tests:\n          bin_op: or\n          test_items:\n            - path: \"{.authorization-mode}\"\n              compare:\n                op: has\n                value: \"Node\"\n            - path: \"{.authorization-mode}\"\n              flag: \"authorization-mode\"\n              set: false\n        remediation: |\n          No remediation is required.\n        scored: false\n\n      - id: 1.2.9\n        text: \"Verify that RBAC is enabled (Manual)\"\n        audit: |\n          # For 4.5 To verify that the authorization-mode argument is not used\n          oc get configmap config -n openshift-kube-apiserver -ojson | jq -r '.data[\"config.yaml\"]' | jq '.apiServerArguments'\n          oc get configmap config -n openshift-apiserver -ojson | jq -r '.data[\"config.yaml\"]' | jq '.apiServerArguments'\n          #Check that no overrides are configured\n          oc get kubeapiservers.operator.openshift.io cluster -o json | jq -r '.spec.unsupportedConfigOverrides'\n          # To verify RBAC is used\n          oc get clusterrolebinding\n          oc get clusterrole\n          oc get rolebinding\n          oc get role\n          # For 4.6, verify that the authorization-mode argument includes RBAC\n        audit_config: |\n          oc get configmap config -n openshift-kube-apiserver -ojson | jq -r '.data[\"config.yaml\"]' | jq '.apiServerArguments'\n        tests:\n          bin_op: or\n          test_items:\n            - path: \"{.authorization-mode}\"\n              compare:\n                op: has\n                value: \"RBAC\"\n            - path: \"{.authorization-mode}\"\n              flag: \"authorization-mode\"\n              set: false\n        remediation: |\n          None. It is not possible to disable RBAC.\n        scored: false\n\n      - id: 1.2.10\n        text: \"Ensure that the APIPriorityAndFairness feature gate is enabled (Manual)\"\n        audit: |\n          #Verify the APIPriorityAndFairness feature-gate\n          oc get kubeapiservers.operator.openshift.io cluster -o json | jq '.spec.observedConfig.apiServerArguments'\n          #Verify the set of admission-plugins for OCP 4.6 and higher\n          oc -n openshift-kube-apiserver get configmap config -o json | jq -r '.data.\"config.yaml\"' | jq '.apiServerArguments.\"enable-admission-plugins\"'\n          #Check that no overrides are configured\n          oc get kubeapiservers.operator.openshift.io cluster -o json | jq -r '.spec.unsupportedConfigOverrides'\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"APIPriorityAndFairness=true\"\n            - flag: \"EventRateLimit\"\n              set: false\n        remediation: |\n          No remediation is required\n        scored: false\n\n      - id: 1.2.11\n        text: \"Ensure that the admission control plugin AlwaysAdmit is not set (Manual)\"\n        audit: |\n          #Verify the set of admission-plugins for OCP 4.6 and higher\n          oc -n openshift-kube-apiserver get configmap config -o json | jq -r '.data.\"config.yaml\"' | jq '.apiServerArguments.\"enable-admission-plugins\"'\n          #Check that no overrides are configured\n          oc get kubeapiservers.operator.openshift.io cluster -o json | jq -r '.spec.unsupportedConfigOverrides'\n        tests:\n          test_items:\n            - flag: \"AlwaysAdmit\"\n              set: false\n        remediation: |\n          No remediation is required. The AlwaysAdmit admission controller cannot be enabled in OpenShift.\n        scored: false\n\n      - id: 1.2.12\n        text: \"Ensure that the admission control plugin AlwaysPullImages is set (Manual)\"\n        audit: |\n          #Verify the set of admissi    on-plugins for OCP 4.6 and higher\n          oc -n openshift-kube-apiserver get configmap config -o json | jq -r '.data.\"config.yaml\"' | jq '.apiServerArguments.\"enable-admission-plugins\"'\n          #Check that no overrides are configured\n          oc get kubeapiservers.operator.openshift.io cluster -o json | jq -r '.spec.unsupportedConfigOverrides'\n        tests:\n          test_items:\n            - flag: \"AlwaysPullImages\"\n              set: false\n        remediation: |\n          None required.\n        scored: false\n\n      - id: 1.2.13\n        text: \"Ensure that the admission control plugin SecurityContextDeny is not set (Manual)\"\n        audit: |\n          #Verify the set of admission-plugins for OCP 4.6 and higher\n          oc -n openshift-kube-apiserver get configmap config -o json | jq -r '.data.\"config.yaml\"' | jq '.apiServerArguments.\"enable-admission-plugins\"'\n          output=$(oc -n openshift-kube-apiserver get configmap config -o json | jq -r '.data.\"config.yaml\"' | jq '.apiServerArguments.\"enable-admission-plugins\"')\n          [ \"$output\" == \"null\" ] && echo \"ocp 4.5 has SecurityContextDeny and SecurityContextConstraint compiled\" || echo $output\n          #Check that no overrides are configured\n          oc get kubeapiservers.operator.openshift.io cluster -o json | jq -r '.spec.unsupportedConfigOverrides'\n          #Verify that SecurityContextConstraints are deployed\n          oc get scc\n          oc describe scc restricted\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"SecurityContextConstraint\"\n              set: true\n            - flag: \"anyuid\"\n            - flag: \"hostaccess\"\n            - flag: \"hostmount-anyuid\"\n            - flag: \"hostnetwork\"\n            - flag: \"node-exporter\"\n            - flag: \"nonroot\"\n            - flag: \"privileged\"\n            - flag: \"restricted\"\n        remediation: |\n          None required. The Security Context Constraint admission controller cannot be disabled in OpenShift 4.\n        scored: false\n\n      - id: 1.2.14\n        text: \"Ensure that the admission control plugin ServiceAccount is set (Manual)\"\n        audit: |\n          #Verify the list of admission controllers for 4.6 and higher\n          oc -n openshift-kube-apiserver get configmap config -o json | jq -r '.data.\"config.yaml\"' | jq '.apiServerArguments.\"enable-admission-plugins\"'\n          output=$(oc -n openshift-kube-apiserver get configmap config -o json | jq -r '.data.\"config.yaml\"' | jq '.apiServerArguments.\"enable-admission-plugins\"')\n          [ \"$output\" == \"null\" ] && echo \"ocp 4.5 has ServiceAccount compiled\" || echo $output\n          #Check that no overrides are configured\n          oc get kubeapiservers.operator.openshift.io cluster -o json | jq -r '.spec.unsupportedConfigOverrides'\n          #Verify that Service Accounts are present\n          oc get sa -A\n        tests:\n          test_items:\n            - flag: \"ServiceAccount\"\n              set: true\n        remediation: |\n          None required. OpenShift is configured to use service accounts by default.\n        scored: false\n\n      - id: 1.2.15\n        text: \"Ensure that the admission control plugin NamespaceLifecycle is set (Manual)\"\n        audit: |\n          #Verify the list of admission controllers for 4.6 and higher\n          oc -n openshift-kube-apiserver get configmap config -o json | jq -r '.data.\"config.yaml\"' | jq '.apiServerArguments.\"enable-admission-plugins\"'\n          output=$(oc -n openshift-kube-apiserver get configmap config -o json | jq -r '.data.\"config.yaml\"' | jq '.apiServerArguments.\"enable-admission-plugins\"')\n          [ \"$output\" == \"null\" ] && echo \"ocp 4.5 has NamespaceLifecycle compiled\" || echo $output\n          #Check that no overrides are configured\n          oc get kubeapiservers.operator.openshift.io cluster -o json | jq -r '.spec.unsupportedConfigOverrides'\n        tests:\n          test_items:\n            - flag: \"NamespaceLifecycle\"\n        remediation: |\n          Ensure that the --disable-admission-plugins parameter does not include NamespaceLifecycle.\n        scored: false\n\n      - id: 1.2.16\n        text: \"Ensure that the admission control plugin SecurityContextConstraint is set (Manual)\"\n        audit: |\n          #Verify the set of admission-plugins for OCP 4.6 and higher\n          oc -n openshift-kube-apiserver get configmap config -o json | jq -r '.data.\"config.yaml\"' | jq '.apiServerArguments.\"enable-admission-plugins\"'\n          output=$(oc -n openshift-kube-apiserver get configmap config -o json | jq -r '.data.\"config.yaml\"' | jq '.apiServerArguments.\"enable-admission-plugins\"')\n          [ \"$output\" == \"null\" ] && echo \"ocp 4.5 has SecurityContextConstraint compiled\" || echo $output\n          #Check that no overrides are configured\n          oc get kubeapiservers.operator.openshift.io cluster -o json | jq -r '.spec.unsupportedConfigOverrides'\n          #Verify that SecurityContextConstraints are deployed\n          oc get scc\n          oc describe scc restricted\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"SecurityContextConstraint\"\n            - flag: \"anyuid\"\n            - flag: \"hostaccess\"\n            - flag: \"hostmount-anyuid\"\n            - flag: \"hostnetwork\"\n            - flag: \"node-exporter\"\n            - flag: \"nonroot\"\n            - flag: \"privileged\"\n            - flag: \"restricted\"\n        remediation: |\n          None required. Security Context Constraints are enabled by default in OpenShift and cannot be disabled.\n        scored: false\n\n      - id: 1.2.17\n        text: \"Ensure that the admission control plugin NodeRestriction is set (Manual)\"\n        audit: |\n          # For 4.5, review the control plane manifest https://github.com/openshift/origin/blob/release-4.5/vendor/k8s.io/kubernetes/cmd/kubeadm/app/phases/controlplane/manifests.go#L132\n          #Verify the set of admission-plugins for OCP 4.6 and higher\n          oc -n openshift-kube-apiserver get configmap config -o json | jq -r '.data.\"config.yaml\"' | jq '.apiServerArguments.\"enable-admission-plugins\"'\n          output=$(oc -n openshift-kube-apiserver get configmap config -o json | jq -r '.data.\"config.yaml\"' | jq '.apiServerArguments.\"enable-admission-plugins\"')\n          [ \"$output\" == \"null\" ] && echo \"ocp 4.5 has NodeRestriction compiled\" || echo $output\n          #Check that no overrides are configured\n          oc get kubeapiservers.operator.openshift.io cluster -o json | jq -r '.spec.unsupportedConfigOverrides'\n        tests:\n          test_items:\n            - flag: \"NodeRestriction\"\n        remediation: |\n          The NodeRestriction plugin cannot be disabled.\n        scored: false\n\n      - id: 1.2.18\n        text: \"Ensure that the --insecure-bind-address argument is not set (Manual)\"\n        audit: |\n          # InsecureBindAddress=true should not be in the results\n          oc get kubeapiservers.operator.openshift.io cluster -o jsonpath='{range .spec.observedConfig.apiServerArguments.feature-gates[*]}{@}{\"\\n\"}{end}'\n          # Result should be only 6443\n          oc -n openshift-kube-apiserver get endpoints -o jsonpath='{.items[*].subsets[*].ports[*].port}'\n          # Result should be only 8443\n          oc -n openshift-apiserver get endpoints -o jsonpath='{.items[*].subsets[*].ports[*].port}'\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"insecure-bind-address\"\n              set: false\n            - flag: 6443\n            - flag: 8443\n        remediation: |\n          None required.\n        scored: false\n\n      - id: 1.2.19\n        text: \"Ensure that the --insecure-port argument is set to 0 (Manual)\"\n        audit: |\n          # Should return 6443\n          oc -n openshift-kube-apiserver get endpoints -o jsonpath='{.items[*].subsets[*].ports[*].port}'\n          # For OCP 4.6 and above\n          oc get configmap config -n openshift-kube-apiserver -ojson | jq -r '.data[\"config.yaml\"]' | jq '.apiServerArguments[\"insecure-port\"]'\n          output=$(oc get configmap config -n openshift-kube-apiserver -ojson | jq -r '.data[\"config.yaml\"]' | jq '.apiServerArguments[\"insecure-port\"]')\n          [ \"$output\" == \"null\" ] && echo \"ocp 4.5 has insecure-port set to \\\"0\\\" compiled\" || echo $output\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"\\\"0\\\"\"\n            - flag: \"6443\"\n        remediation: |\n          None required. The configuration is managed by the API server operator.\n        scored: false\n\n      - id: 1.2.20\n        text: \"Ensure that the --secure-port argument is not set to 0 (Manual)\"\n        audit: |\n          oc get kubeapiservers.operator.openshift.io cluster -o json | jq '.spec.observedConfig'\n          # Should return only 6443\n          echo ports=`oc get pods -n openshift-kube-apiserver -l app=openshift-kube-apiserver -o jsonpath='{.items[*].spec.containers[?(@.name==\"kube-apiserver\")].ports[*].containerPort}'`\n        tests:\n          bin_op: and\n          test_items:\n            - flag: '\"bindAddress\": \"0.0.0.0:6443\"'\n            - flag: \"ports\"\n              compare:\n                op: regex\n                value: '\\s*(?:6443\\s*){1,}$'\n        remediation: |\n          None required.\n        scored: false\n\n      - id: 1.2.21\n        text: \"Ensure that the healthz endpoint is protected by RBAC (Manual)\"\n        type: manual\n        audit: |\n          # Verify endpoints\n          oc -n openshift-kube-apiserver describe endpoints\n          # Check config for ports, livenessProbe, readinessProbe, healthz\n          oc -n openshift-kube-apiserver get cm kube-apiserver-pod -o json | jq -r '.data.\"pod.yaml\"' | jq '.spec.containers'\n          # Test to validate RBAC enabled on the apiserver endpoint; check with non-admin role\n          oc project openshift-kube-apiserver POD=$(oc get pods -n openshift-kube-apiserver -l app=openshift-kube-apiserver -o jsonpath='{.items[0].metadata.name}') PORT=$(oc get pods -n openshift-kube-apiserver -l app=openshift-kube-apiserver -o jsonpath='{.items[0].spec.containers[0].ports[0].hostPort}')\n          # Following should return 403 Forbidden\n          oc rsh -n openshift-kube-apiserver ${POD} curl https://localhost:${PORT}/metrics -k\n          # Create a service account to test RBAC\n          oc create -n openshift-kube-apiserver sa permission-test-sa\n          # Should return 403 Forbidden\n          SA_TOKEN=$(oc sa -n openshift-kube-apiserver get-token permission-test-sa)\n          oc rsh -n openshift-kube-apiserver ${POD} curl https://localhost:${PORT}/metrics -H \"Authorization: Bearer $SA_TOKEN\" -k\n          # Cleanup\n          oc delete -n openshift-kube-apiserver sa permission-test-sa\n          # As cluster admin, should succeed\n          CLUSTER_ADMIN_TOKEN=$(oc whoami -t)\n          oc rsh -n openshift-kube-apiserver ${POD} curl https://localhost:${PORT}/metrics -H \"Authorization: Bearer $CLUSTER_ADMIN_TOKEN\" -k\n        remediation: |\n          None required as profiling data is protected by RBAC.\n        scored: false\n\n      - id: 1.2.22\n        text: \"Ensure that the --audit-log-path argument is set (Manual)\"\n        audit: |\n          # Should return “/var/log/kube-apiserver/audit.log\"\n          output=$(oc get configmap config -n openshift-kube-apiserver -o jsonpath=\"{['.data.config\\.yaml']}\" | jq '.auditConfig.auditFilePath')\n          [ \"$output\" != \"\" ] && [ \"$output\" != \"null\" ] && echo \"$output\" || true\n          output=$(oc get configmap config -n openshift-kube-apiserver -o json | jq -r '.data[\"config.yaml\"]' | jq -r '.apiServerArguments[\"audit-log-path\"][]?')\n          [ \"$output\" != \"\" ] && [ \"$output\" != \"null\" ] && echo \"$output\" || true\n          POD=$(oc get pods -n openshift-kube-apiserver -l app=openshift-kube-apiserver -o jsonpath='{.items[0].metadata.name}')\n          oc rsh -n openshift-kube-apiserver -c kube-apiserver $POD ls /var/log/kube-apiserver/audit.log 2>/dev/null\n          # Should return 0\n          echo exit_code=$?\n          # Should return \"/var/log/openshift-apiserver/audit.log\"\n          output=$(oc get configmap config -n openshift-apiserver -o jsonpath=\"{['.data.config\\.yaml']}\" | jq '.auditConfig.auditFilePath')\n          [ \"$output\" != \"\" ] && [ \"$output\" != \"null\" ] && echo \"$output\" || true\n          output=$(oc get configmap config -n openshift-apiserver -o json | jq -r '.data[\"config.yaml\"]' | jq -r '.apiServerArguments[\"audit-log-path\"][]?')\n          [ \"$output\" != \"\" ] && [ \"$output\" != \"null\" ] && echo \"$output\" || true\n          POD=$(oc get pods -n openshift-apiserver -l apiserver=true -o jsonpath='{.items[0].metadata.name}')\n          oc rsh -n openshift-apiserver $POD ls /var/log/openshift-apiserver/audit.log 2>/dev/null\n          # Should return 0\n          echo exit_code=$?\n        use_multiple_values: true\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"/var/log/kube-apiserver/audit.log\"\n            - flag: \"/var/log/openshift-apiserver/audit.log\"\n            - flag: \"exit_code=0\"\n            - flag: \"null\"\n        remediation: |\n          None required. This is managed by the cluster apiserver operator.\n        scored: false\n\n      - id: 1.2.23\n        text: \"Ensure that the audit logs are forwarded off the cluster for retention (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the documentation for log forwarding. Forwarding logs to third party systems\n          https://docs.openshift.com/container-platform/4.5/logging/cluster-logging-external.html\n        scored: false\n\n      - id: 1.2.24\n        text: \"Ensure that the maximumRetainedFiles argument is set to 10 or as appropriate (Manual)\"\n        audit: |\n          #NOTICE\n          output=$(oc get configmap config -n openshift-kube-apiserver -o json | jq -r '.data[\"config.yaml\"]' | jq -r .auditConfig.maximumRetainedFiles)\n          [ \"$output\" != \"\" ] && [ \"$output\" != \"null\" ] && echo \"maximumRetainedFiles=$output\" || true\n          output=$(oc get configmap config -n openshift-apiserver -o json | jq -r '.data[\"config.yaml\"]' | jq -r .auditConfig.maximumRetainedFiles)\n          [ \"$output\" != \"\" ] && [ \"$output\" != \"null\" ] && echo \"maximumRetainedFiles=$output\" || true\n          output=$(oc get configmap config -n openshift-kube-apiserver -o json | jq -r '.data[\"config.yaml\"]' | jq -r '.apiServerArguments[\"audit-log-maxbackup\"][]?')\n          [ \"$output\" != \"\" ] && [ \"$output\" != \"null\" ] && echo \"audit-log-maxbackup=$output\" || true\n          output=$(oc get configmap config -n openshift-apiserver -o json | jq -r '.data[\"config.yaml\"]' | jq -r '.apiServerArguments[\"audit-log-maxbackup\"][]?')\n          [ \"$output\" != \"\" ] && [ \"$output\" != \"null\" ] && echo \"audit-log-maxbackup=$output\" || true\n        use_multiple_values: true\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"maximumRetainedFiles\"\n              compare:\n                op: gte\n                value: 10\n            - flag: \"audit-log-maxbackup\"\n              compare:\n                op: gte\n                value: 10\n        remediation: |\n          Set the maximumRetainedFiles parameter to 10 or as an appropriate number of files. maximumRetainedFiles: 10\n        scored: false\n\n      - id: 1.2.25\n        text: \"Ensure that the maximumFileSizeMegabytes argument is set to 100 or as appropriate (Manual)\"\n        audit: |\n          #NOTICE\n          output=$(oc get configmap config -n openshift-kube-apiserver -o json | jq -r '.data[\"config.yaml\"]' | jq -r .auditConfig.maximumFileSizeMegabytes)\n          [ \"$output\" != \"\" ] && [ \"$output\" != \"null\" ] && echo \"maximumFileSizeMegabytes=$output\" || true\n          output=$(oc get configmap config -n openshift-apiserver -o json | jq -r '.data[\"config.yaml\"]' | jq -r .auditConfig.maximumFileSizeMegabytes)\n          [ \"$output\" != \"\" ] && [ \"$output\" != \"null\" ] && echo \"maximumFileSizeMegabytes=$output\" || true\n          output=$(oc get configmap config -n openshift-kube-apiserver -o json | jq -r '.data[\"config.yaml\"]' | jq -r '.apiServerArguments[\"audit-log-maxsize\"][]?')\n          [ \"$output\" != \"\" ] && [ \"$output\" != \"null\" ] && echo \"audit-log-maxsize=$output\" || true\n          output=$(oc get configmap config -n openshift-apiserver -o json | jq -r '.data[\"config.yaml\"]' | jq -r '.apiServerArguments[\"audit-log-maxsize\"][]?')\n          [ \"$output\" != \"\" ] && [ \"$output\" != \"null\" ] && echo \"audit-log-maxsize=$output\" || true\n        use_multiple_values: true\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"maximumFileSizeMegabytes\"\n              compare:\n                op: gte\n                value: 100\n            - flag: \"audit-log-maxsize\"\n              compare:\n                op: gte\n                value: 100\n        remediation: |\n          Set the audit-log-maxsize parameter to 100 or as an appropriate number.\n          maximumFileSizeMegabytes: 100\n        scored: false\n\n      - id: 1.2.26\n        text: \"Ensure that the --request-timeout argument is set as appropriate (Manual)\"\n        audit: |\n          echo requestTimeoutSeconds=`oc get configmap config -n openshift-kube-apiserver -ojson | jq -r '.data[\"config.yaml\"]' | jq -r .servingInfo.requestTimeoutSeconds`\n        tests:\n          test_items:\n            - flag: \"requestTimeoutSeconds\"\n        remediation: |\n          TBD\n        scored: false\n\n      - id: 1.2.27\n        text: \"Ensure that the --service-account-lookup argument is set to true (Manual)\"\n        audit: |\n          # For OCP 4.5\n          oc get configmap config -n openshift-kube-apiserver -ojson | jq -r '.data[\"config.yaml\"]' | jq '.apiServerArguments' | grep service-account-lookup\n          # For OCP 4.6 and above\n          oc get configmap config -n openshift-kube-apiserver -ojson | jq -r '.data[\"config.yaml\"]' | jq -r '.apiServerArguments[\"service-account-lookup\"]'\n          output=$(oc get configmap config -n openshift-kube-apiserver -ojson | jq -r '.data[\"config.yaml\"]' | jq -r '.apiServerArguments[\"service-account-lookup\"][0]')\n          [ \"$output\" == \"null\" ] && echo \"ocp 4.5 has service-account-lookup=true compiled\" || echo service-account-lookup=$output\n        tests:\n          test_items:\n            - flag: \"service-account-lookup=true\"\n        remediation: |\n          TBD\n        scored: false\n\n      - id: 1.2.28\n        text: \"Ensure that the --service-account-key-file argument is set as appropriate (Manual)\"\n        audit: |\n          oc get configmap config -n openshift-kube-apiserver -ojson | jq -r '.data[\"config.yaml\"]' | jq -r .serviceAccountPublicKeyFiles[]\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"/etc/kubernetes/static-pod-resources/configmaps/sa-token-signing-certs\"\n            - flag: \"/etc/kubernetes/static-pod-resources/configmaps/bound-sa-token-signing-certs\"\n        remediation: |\n          The OpenShift API server does not use the service-account-key-file argument.\n          The ServiceAccount token authenticator is configured with serviceAccountConfig.publicKeyFiles.\n          OpenShift does not reuse the apiserver TLS key. This is not configurable.\n        scored: false\n\n      - id: 1.2.29\n        text: \"Ensure that the --etcd-certfile and --etcd-keyfile arguments are set as appropriate (Manual)\"\n        audit: |\n          # etcd Certificate File\n          oc get configmap config -n openshift-kube-apiserver -ojson | jq -r '.data[\"config.yaml\"]' | jq -r .storageConfig.certFile\n          # etcd Key File\n          oc get configmap config -n openshift-kube-apiserver -ojson | jq -r '.data[\"config.yaml\"]' | jq -r .storageConfig.keyFile\n          # NOTICE 4.6 extention\n          oc get configmap config -n openshift-kube-apiserver -ojson | jq -r '.data[\"config.yaml\"]' | jq -r '.apiServerArguments[\"etcd-certfile\"]'\n          oc get configmap config -n openshift-kube-apiserver -ojson | jq -r '.data[\"config.yaml\"]' | jq -r '.apiServerArguments[\"etcd-keyfile\"]'\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"/etc/kubernetes/static-pod-resources/secrets/etcd-client/tls.crt\"\n            - flag: \"/etc/kubernetes/static-pod-resources/secrets/etcd-client/tls.key\"\n        remediation: |\n          OpenShift automatically manages TLS and client certificate authentication for etcd.\n          This is not configurable.\n        scored: false\n\n      - id: 1.2.30\n        text: \"Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Manual)\"\n        audit: |\n          # TLS Cert File - openshift-kube-apiserver\n          oc get configmap config -n openshift-kube-apiserver -ojson | jq -r '.data[\"config.yaml\"]' | jq -r .servingInfo.certFile\n          # TLS Key File\n          oc get configmap config -n openshift-kube-apiserver -ojson | jq -r '.data[\"config.yaml\"]' | jq -r '.servingInfo.keyFile'\n          # NOTECI 4.6 extention\n          oc get configmap config -n openshift-kube-apiserver -ojson | jq -r '.data[\"config.yaml\"]' | jq -r '.apiServerArguments[\"tls-cert-file\"]'\n          oc get configmap config -n openshift-kube-apiserver -ojson | jq -r '.data[\"config.yaml\"]' | jq -r '.apiServerArguments[\"tls-private-key-file\"]'\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"/etc/kubernetes/static-pod-certs/secrets/service-network-serving-certkey/tls.crt\"\n            - flag: \"/etc/kubernetes/static-pod-certs/secrets/service-network-serving-certkey/tls.key\"\n        remediation: |\n          OpenShift automatically manages TLS authentication for the API server communication with the node/kublet.\n          This is not configurable. You may optionally set a custom default certificate to be used by the API server\n          when serving content in order to enable clients to access the API server at a different host name or without\n          the need to distribute the cluster-managed certificate authority (CA) certificates to the clients.\n          Follow the directions in the OpenShift documentation User-provided certificates for the API server\n        scored: false\n\n      - id: 1.2.31\n        text: \"Ensure that the --client-ca-file argument is set as appropriate (Manual)\"\n        audit: |\n          oc get configmap config -n openshift-kube-apiserver -ojson | jq -r '.data[\"config.yaml\"]' | jq -r .servingInfo.clientCA\n          oc get configmap config -n openshift-kube-apiserver -ojson | jq -r '.data[\"config.yaml\"]' | jq -r '.apiServerArguments[\"client-ca-file\"]'\n        tests:\n          test_items:\n            - flag: \"/etc/kubernetes/static-pod-certs/configmaps/client-ca/ca-bundle.crt\"\n        remediation: |\n          OpenShift automatically manages TLS authentication for the API server communication with the node/kublet.\n          This is not configurable. You may optionally set a custom default certificate to be used by the API\n          server when serving content in order to enable clients to access the API server at a different host name\n          or without the need to distribute the cluster-managed certificate authority (CA) certificates to the clients.\n\n          User-provided certificates must be provided in a kubernetes.io/tls type Secret in the openshift-config namespace.\n          Update the API server cluster configuration,\n          the apiserver/cluster resource, to enable the use of the user-provided certificate.\n        scored: false\n\n      - id: 1.2.32\n        text: \"Ensure that the --etcd-cafile argument is set as appropriate (Manual)\"\n        audit: |\n          #etcd CA File\n          oc get configmap config -n openshift-kube-apiserver -ojson | jq -r '.data[\"config.yaml\"]' | jq -r .storageConfig.ca\n          oc get configmap config -n openshift-kube-apiserver -ojson | jq -r '.data[\"config.yaml\"]' | jq -r '.apiServerArguments[\"etcd-cafile\"]'\n        tests:\n          test_items:\n            - flag: \"/etc/kubernetes/static-pod-resources/configmaps/etcd-serving-ca/ca-bundle.crt\"\n        remediation: |\n          None required. OpenShift generates the etcd-cafile and sets the arguments appropriately in the API server. Communication with etcd is secured by the etcd serving CA.\n        scored: false\n\n      - id: 1.2.33\n        text: \"Ensure that the --encryption-provider-config argument is set as appropriate (Manual)\"\n        audit: |\n          # encrypt the etcd datastore\n          oc get openshiftapiserver -o=jsonpath='{range.items[0].status.conditions[?(@.type==\"Encrypted\")]}{.reason}{\"\\n\"}{.message}{\"\\n\"}'\n        tests:\n          test_items:\n            - flag: \"EncryptionCompleted\"\n        remediation: |\n          Follow the OpenShift documentation for Encrypting etcd data | Authentication | OpenShift Container Platform 4.5\n          https://docs.openshift.com/container-platform/4.5/security/encrypting-etcd.html\n        scored: false\n\n      - id: 1.2.34\n        text: \"Ensure that encryption providers are appropriately configured (Manual)\"\n        audit: |\n          # encrypt the etcd datastore\n          oc get openshiftapiserver -o=jsonpath='{range.items[0].status.conditions[?(@.type==\"Encrypted\")]}{.reason}{\"\\n\"}{.message}{\"\\n\"}'\n        tests:\n          test_items:\n            - flag: \"EncryptionCompleted\"\n        remediation: |\n          Follow the Kubernetes documentation and configure a EncryptionConfig file.\n          In this file, choose aescbc, kms or secretbox as the encryption provider.\n        scored: false\n\n      - id: 1.2.35\n        text: \"Ensure that the API Server only makes use of Strong Cryptographic Ciphers (Manual)\"\n        type: manual\n        audit: |\n          # verify cipher suites\n          oc get cm -n openshift-authentication v4-0-config-system-cliconfig -o jsonpath='{.data.v4\\-0\\-config\\-system\\-cliconfig}' | jq .servingInfo\n          oc get kubeapiservers.operator.openshift.io cluster -o json |jq.spec.observedConfig.servingInfo\n          oc get openshiftapiservers.operator.openshift.io cluster -o json |jq.spec.observedConfig.servingInfo\n          oc describe --namespace=openshift-ingress-operator ingresscontroller/default\n        remediation: |\n          Verify that the tlsSecurityProfile is set to the value you chose.\n          Note: The HAProxy Ingress controller image does not support TLS 1.3\n          and because the Modern profile requires TLS 1.3, it is not supported.\n          The Ingress Operator converts the Modern profile to Intermediate.\n          The Ingress Operator also converts the TLS 1.0 of an Old or Custom profile to 1.1,\n          and TLS 1.3 of a Custom profile to 1.2.\n        scored: false\n\n  - id: 1.3\n    text: \"Controller Manager\"\n    checks:\n      - id: 1.3.1\n        text: \"Ensure that garbage collection is configured as appropriate (Manual)\"\n        type: manual\n        remediation: |\n          To configure, follow the directions in Configuring garbage collection for containers and images\n          https://docs.openshift.com/container-platform/4.5/nodes/nodes/nodes-nodes-garbage-collection.html#nodes-nodes-garbage-collection-configuring_nodes-nodes-configuring\n        scored: false\n\n      - id: 1.3.2\n        text: \"Ensure that controller manager healthz endpoints are protected by RBAC (Manual)\"\n        type: manual\n        audit: |\n          # Verify configuration for ports, livenessProbe, readinessProbe, healthz\n          oc -n openshift-kube-controller-manager get cm kube-controller-manager-pod -o json | jq -r '.data.\"pod.yaml\"' | jq '.spec.containers'\n          # Verify endpoints\n          oc -n openshift-kube-controller-manager describe endpoints\n          # Test to validate RBAC enabled on the controller endpoint; check with non-admin role\n          oc project openshift-kube-controller-manage\n          POD=$(oc get pods -n openshift-kube-controller-manager -l app=kube-controller-manager -o jsonpath='{.items[0].metadata.name}')\n          PORT=$(oc get pods -n openshift-kube-controller-manager -l app=kube-controller-manager -o jsonpath='{.items[0].spec.containers[0].ports[0].hostPort}')\n          # Following should return 403 Forbidden\n          oc rsh -n openshift-kube-controller-manager ${POD} curl https://localhost:${PORT}/metrics -k\n          # Create a service account to test RBAC\n          oc create -n openshift-kube-controller-manager sa permission-test-sa\n          # Should return 403 Forbidden\n          SA_TOKEN=$(oc sa -n openshift-kube-controller-manager get-token permission-test-sa)\n          oc rsh -n openshift-kube-controller-manager ${POD} curl https://localhost:${PORT}/metrics -H \"Authorization: Bearer $SA_TOKEN\" -k\n          # Cleanup\n          oc delete -n openshift-kube-controller-manager sa permission-test-sa\n          # As cluster admin, should succeed\n          CLUSTER_ADMIN_TOKEN=$(oc whoami -t)\n          oc rsh -n openshift-kube-controller-manager ${POD} curl https://localhost:${PORT}/metrics -H \"Authorization: Bearer $CLUSTER_ADMIN_TOKEN\" -k\n        remediation: |\n          None required; profiling is protected by RBAC.\n        scored: false\n\n      - id: 1.3.3\n        text: \"Ensure that the --use-service-account-credentials argument is set to true (Manual)\"\n        audit: |\n          echo use-service-account-credentials=`oc get configmaps config -n openshift-kube-controller-manager -ojson | jq -r '.data[\"config.yaml\"]' | jq -r '.extendedArguments[\"use-service-account-credentials\"][]'`\n        tests:\n          test_items:\n            - flag: \"use-service-account-credentials\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          The OpenShift Controller Manager operator manages and updates the OpenShift Controller Manager.\n          The Kubernetes Controller Manager operator manages and updates the Kubernetes Controller Manager deployed on top of OpenShift.\n          This operator is configured via KubeControllerManager custom resource.\n        scored: false\n\n      - id: 1.3.4\n        text: \"Ensure that the --service-account-private-key-file argument is set as appropriate (Manual)\"\n        audit: |\n          oc get configmaps config -n openshift-kube-controller-manager -ojson | jq -r '.data[\"config.yaml\"]' | jq -r '.extendedArguments[\"service-account-private-key-file\"][]'\n        tests:\n          test_items:\n            - flag: \"/etc/kubernetes/static-pod-resources/secrets/service-account-private-key/service-account.key\"\n        remediation: |\n          None required.\n          OpenShift manages the service account credentials for the scheduler automatically.\n        scored: false\n\n      - id: 1.3.5\n        text: \"Ensure that the --root-ca-file argument is set as appropriate (Manual)\"\n        audit: |\n          oc get configmaps config -n openshift-kube-controller-manager -ojson | jq -r '.data[\"config.yaml\"]' | jq -r '.extendedArguments[\"root-ca-file\"][]'\n        tests:\n          test_items:\n            - flag: \"/etc/kubernetes/static-pod-resources/configmaps/serviceaccount-ca/ca-bundle.crt\"\n        remediation: |\n          None required.\n          Certificates for OpenShift platform components are automatically created and rotated by the OpenShift Container Platform.\n        scored: false\n\n      - id: 1.3.6\n        text: \"Ensure that the RotateKubeletServerCertificate argument is set to true (Manual)\"\n        audit: |\n          oc get configmaps config -n openshift-kube-controller-manager -ojson | jq -r '.data[\"config.yaml\"]' | jq -r '.extendedArguments[\"feature-gates\"][]'\n        tests:\n          test_items:\n            - flag: \"RotateKubeletServerCertificate\"\n              compare:\n                op: eq\n                value: \"true\"\n        remediation: |\n          None required.\n          Certificates for OpenShift platform components are automatically created and rotated by the OpenShift Container Platform.\n        scored: false\n\n      - id: 1.3.7\n        text: \"Ensure that the --bind-address argument is set to 127.0.0.1 (Manual)\"\n        audit: |\n          echo port=`oc get configmaps config -n openshift-kube-controller-manager -ojson | jq -r '.data[\"config.yaml\"]' | jq '.extendedArguments[\"port\"][]'`\n          echo secure-port=`oc get configmaps config -n openshift-kube-controller-manager -ojson | jq -r '.data[\"config.yaml\"]' | jq '.extendedArguments[\"secure-port\"][]'`\n          #Following should fail with a http code 403\n          POD=$(oc get pods -n openshift-kube-controller-manager -l app=kube-controller-manager -o jsonpath='{.items[0].metadata.name}')\n          oc rsh -n openshift-kube-controller-manager -c kube-controller-manager $POD curl https://localhost:10257/metrics -k\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"secure-port\"\n              compare:\n                op: eq\n                value: \"\\\"10257\\\"\"\n            - flag: \"port\"\n              compare:\n                op: eq\n                value: \"\\\"0\\\"\"\n            - flag: \"\\\"code\\\": 403\"\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the master node and ensure the correct value for the --bind-address parameter\n        scored: false\n\n  - id: 1.4\n    text: \"Scheduler\"\n    checks:\n      - id: 1.4.1\n        text: \"Ensure that the healthz endpoints for the scheduler are protected by RBAC (Manual)\"\n        type: manual\n        audit: |\n          # check configuration for ports, livenessProbe, readinessProbe, healthz\n          oc -n openshift-kube-scheduler get cm kube-scheduler-pod -o json | jq -r '.data.\"pod.yaml\"' | jq '.spec.containers'\n          # Test to verify endpoints\n          oc -n openshift-kube-scheduler describe endpoints\n          # Test to validate RBAC enabled on the scheduler endpoint; check with non-admin role\n          oc project openshift-kube-scheduler\n          POD=$(oc get pods -l app=openshift-kube-scheduler -o jsonpath='{.items[0].metadata.name}')\n          PORT=$(oc get pod $POD -o jsonpath='{.spec.containers[0].livenessProbe.httpGet.port}')\n          # Should return 403 Forbidden\n          oc rsh ${POD} curl http://localhost:${PORT}/metrics -k\n          # Create a service account to test RBAC\n          oc create sa permission-test-sa\n          # Should return 403 Forbidden\n          SA_TOKEN=$(oc sa get-token permission-test-sa)\n          oc rsh ${POD} curl http://localhost:${PORT}/metrics -H \"Authorization: Bearer $SA_TOKEN\" -k\n          # Cleanup\n          oc delete sa permission-test-sa\n          # As cluster admin, should succeed\n          CLUSTER_ADMIN_TOKEN=$(oc whoami -t)\n          oc rsh ${POD} curl http://localhost:${PORT}/metrics -H \"Authorization: Bearer $CLUSTER_ADMIN_TOKEN\" -k\n        remediation: |\n          A fix to this issue: https://bugzilla.redhat.com/show_bug.cgi?id=1889488 None required.\n          Profiling is protected by RBAC and cannot be disabled.\n        scored: false\n\n      - id: 1.4.2\n        text: \"Verify that the scheduler API service is protected by authentication and authorization (Manual)\"\n        type: manual\n        audit: |\n          # To verify endpoints\n          oc -n openshift-kube-scheduler describe endpoints\n          # To verify that bind-adress is not used in the configuration and that port is set to 0\n          oc -n openshift-kube-scheduler get cm kube-scheduler-pod -o json | jq -r '.data.\"pod.yaml\"' | jq '.spec.containers'\n          # To test for RBAC:\n          oc project openshift-kube-scheduler\n          POD=$(oc get pods -l app=openshift-kube-scheduler -o jsonpath='{.items[0].metadata.name}')\n          POD_IP=$(oc get pods -l app=openshift-kube-scheduler -o jsonpath='{.items[0].status.podIP}')\n          PORT=$(oc get pod $POD -o jsonpath='{.spec.containers[0].livenessProbe.httpGet.port}')\n          # Should return a 403\n          oc rsh ${POD} curl http://${POD_IP}:${PORT}/metrics\n          # Create a service account to test RBAC\n          oc create sa permission-test-sa\n          # Should return 403 Forbidden\n          SA_TOKEN=$(oc sa get-token permission-test-sa)\n          oc rsh ${POD} curl http://localhost:${PORT}/metrics -H \"Authorization: Bearer $SA_TOKEN\" -k\n          # Cleanup\n          oc delete sa permission-test-sa\n          # As cluster admin, should succeed\n          CLUSTER_ADMIN_TOKEN=$(oc whoami -t)\n          oc rsh ${POD} curl http://localhost:${PORT}/metrics -H \"Authorization: Bearer $CLUSTER_ADMIN_TOKEN\" -k\n        remediation: |\n          By default, the --bind-address argument is not present,\n          the readinessProbe and livenessProbe arguments are set to 10251 and the port argument is set to 0.\n          Check the status of this issue: https://bugzilla.redhat.com/show_bug.cgi?id=1889488\n        scored: false\n"
  },
  {
    "path": "cfg/rh-1.0/node.yaml",
    "content": "---\ncontrols:\nversion: rh-1.0\nid: 4\ntext: \"Worker Node Security Configuration\"\ntype: \"node\"\ngroups:\n  - id: 4.1\n    text: \"Worker Node Configuration Files\"\n    checks:\n      - id: 4.1.1\n        text: \"Ensure that the kubelet service file permissions are set to 644 or more restrictive (Automated)\"\n        audit: |\n          NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')\n          oc debug node/$NODE_NAME -- chroot /host stat -c \"$NODE_NAME %n permissions=%a\" /etc/systemd/system/kubelet.service 2> /dev/null\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          By default, the kubelet service file has permissions of 644.\n        scored: true\n\n      - id: 4.1.2\n        text: \"Ensure that the kubelet service file ownership is set to root:root (Automated)\"\n        audit: |\n          # Should return root:root for each node\n          NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')\n          oc debug node/$NODE_NAME -- chroot /host stat -c \"$NODE_NAME %n %U:%G\" /etc/systemd/system/kubelet.service 2> /dev/null\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          By default, the kubelet service file has ownership of root:root.\n        scored: true\n\n      - id: 4.1.3\n        text: \"If proxy kubeconfig file exists ensure permissions are set to 644 or more restrictive (Manual)\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n          # Get the pod name in the openshift-sdn namespace\n          POD_NAME=$(oc get pods -n openshift-sdn -l app=sdn --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n          echo \"No matching pods found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-sdn \"$POD_NAME\" -- stat -Lc \"$i %n permissions=%a\" /config/kube-proxy-config.yaml  2>/dev/null\n          fi\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"permissions\"\n              set: true\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          None needed.\n        scored: false\n\n      - id: 4.1.4\n        text: \"Ensure that the proxy kubeconfig file ownership is set to root:root (Manual)\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n          # Get the pod name in the openshift-sdn namespace\n          POD_NAME=$(oc get pods -n openshift-sdn -l app=sdn --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n          echo \"No matching pods found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-sdn \"$POD_NAME\"  -- stat -Lc \"$i %n %U:%G\" /config/kube-proxy-config.yaml  2>/dev/null\n          fi\n        use_multiple_values: true\n        tests:\n          bin_op: or\n          test_items:\n            - flag: root:root\n        remediation: |\n          None required. The configuration is managed by OpenShift operators.\n        scored: false\n\n      - id: 4.1.5\n        text: \"Ensure that the --kubeconfig kubelet.conf file permissions are set to 644 or more restrictive (Manual)\"\n        audit: |\n          # Check permissions\n          NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')\n          oc debug node/$NODE_NAME -- chroot /host stat -c \"$NODE_NAME %n permissions=%a\" /etc/kubernetes/kubelet.conf 2> /dev/null\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          None required.\n        scored: false\n\n      - id: 4.1.6\n        text: \"Ensure that the --kubeconfig kubelet.conf file ownership is set to root:root (Manual)\"\n        audit: |\n          NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')\n          oc debug node/$NODE_NAME -- chroot /host stat -c \"$NODE_NAME %n %U:%G\" /etc/kubernetes/kubelet.conf 2> /dev/null\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          None required.\n        scored: false\n\n      - id: 4.1.7\n        text: \"Ensure that the certificate authorities file permissions are set to 644 or more restrictive (Automated)\"\n        audit: |\n          NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')\n          oc debug node/$NODE_NAME -- chroot /host stat -c \"$NODE_NAME %n permissions=%a\" /etc/kubernetes/kubelet-ca.crt 2> /dev/null\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          None required.\n        scored: true\n\n      - id: 4.1.8\n        text: \"Ensure that the client certificate authorities file ownership is set to root:root (Automated)\"\n        audit: |\n          NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')\n          oc debug node/$NODE_NAME -- chroot /host stat -c \"$NODE_NAME %n %U:%G\" /etc/kubernetes/kubelet-ca.crt 2> /dev/null\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          None required.\n        scored: true\n\n      - id: 4.1.9\n        text: \"Ensure that the kubelet --config configuration file has permissions set to 644 or more restrictive (Automated)\"\n        audit: |\n          NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')\n          oc debug node/$NODE_NAME -- chroot /host stat -c \"$NODE_NAME %n permissions=%a\" /var/lib/kubelet/kubeconfig 2> /dev/null\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          None required.\n        scored: true\n\n      - id: 4.1.10\n        text: \"Ensure that the kubelet configuration file ownership is set to root:root (Automated)\"\n        audit: |\n          NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')\n          oc debug node/$NODE_NAME -- chroot /host stat -c \"$NODE_NAME %n %U:%G\" /var/lib/kubelet/kubeconfig 2> /dev/null\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          None required.\n        scored: true\n\n  - id: 4.2\n    text: \"Kubelet\"\n    checks:\n      - id: 4.2.1\n        text: \"Ensure that the --anonymous-auth argument is set to false (Automated)\"\n        audit: |\n          NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')\n          oc debug node/$NODE_NAME -- chroot /host grep -B4 -A1 anonymous /etc/kubernetes/kubelet.conf 2> /dev/null\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"enabled: true\"\n              set: false\n        remediation: |\n          Follow the instructions in the documentation to create a Kubelet config CRD\n          and set the anonymous-auth is set to false.\n        scored: true\n\n      - id: 4.2.2\n        text: \"Ensure that the --authorization-mode argument is not set to AlwaysAllow (Manual)\"\n        type: manual\n        # Takes a lot of time for connection to fail and\n        audit: |\n          POD=$(oc -n openshift-kube-apiserver get pod -l app=openshift-kube-apiserver -o jsonpath='{.items[0].metadata.name}')\n          TOKEN=$(oc whoami -t)\n          NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')\n          oc exec -n openshift-kube-apiserver $POD -- curl -sS https://172.25.0.1/api/v1/nodes/$NODE_NAME/proxy/configz -k -H \"Authorization:Bearer $TOKEN\" | jq -r '.kubeletconfig.authorization.mode' 2> /dev/null\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"Connection timed out\"\n        remediation: |\n          None required. Unauthenticated/Unauthorized users have no access to OpenShift nodes.\n        scored: false\n\n      - id: 4.2.3\n        text: \"Ensure that the --client-ca-file argument is set as appropriate (Automated)\"\n        audit: |\n          NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')\n          oc debug node/$NODE_NAME -- chroot /host grep clientCAFile /etc/kubernetes/kubelet.conf 2> /dev/null\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: '\"clientCAFile\": \"/etc/kubernetes/kubelet-ca.crt\"'\n        remediation: |\n          None required. Changing the clientCAFile value is unsupported.\n        scored: true\n\n      - id: 4.2.4\n        text: \"Verify that the read only port is not used or is set to 0 (Automated)\"\n        audit: |\n          echo `oc -n openshift-kube-apiserver get cm kube-apiserver-pod -o yaml | grep --color read-only-port` 2> /dev/null\n          echo `oc -n openshift-kube-apiserver get cm config -o yaml | grep --color \"read-only-port\"` 2> /dev/null\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"read-only-port\"\n              compare:\n                op: has\n                value: \"[\\\"0\\\"]\"\n            - flag: \"read-only-port\"\n              set: false\n        remediation: |\n          In earlier versions of OpenShift 4, the read-only-port argument is not used.\n          Follow the instructions in the documentation to create a Kubelet config CRD\n          and set the --read-only-port is set to 0.\n        scored: true\n\n      - id: 4.2.5\n        text: \"Ensure that the --streaming-connection-idle-timeout argument is not set to 0 (Automated)\"\n        audit: |\n          # Should return 1 for node\n          NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')\n          oc debug node/${NODE_NAME} -- chroot /host ps -ef | grep kubelet | grep streaming-connection-idle-timeout 2> /dev/null\n          echo exit_code=$?\n          # Should return 1 for node\n          oc debug node/${NODE_NAME} -- chroot /host grep streamingConnectionIdleTimeout /etc/kubernetes/kubelet.conf 2> /dev/null\n          echo exit_code=$?\n        use_multiple_values: true\n        tests:\n          bin_op: or\n          test_items:\n            - flag: --streaming-connection-idle-timeout\n              compare:\n                op: noteq\n                value: 0\n            - flag: streamingConnectionIdleTimeout\n              compare:\n                op: noteq\n                value: 0s\n            - flag: \"exit_code\"\n              compare:\n                op: eq\n                value: 1\n        remediation: |\n          Follow the instructions in the documentation to create a Kubelet config CRD and set\n          the --streaming-connection-idle-timeout to the desired value. Do not set the value to 0.\n        scored: true\n\n      - id: 4.2.6\n        text: \"Ensure that the --protect-kernel-defaults argument is not set (Manual)\"\n        audit: |\n          NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')\n          oc debug node/$NODE_NAME -- chroot /host more /etc/kubernetes/kubelet.conf 2> /dev/null\n        tests:\n          test_items:\n            - flag: protectKernelDefaults\n              set: false\n        remediation: |\n          None required. The OpenShift 4 kubelet modifies the system tunable;\n          using the protect-kernel-defaults flag will cause the kubelet to fail on start if the tunables\n          don't match the kubelet configuration and the OpenShift node will fail to start.\n        scored: false\n\n      - id: 4.2.7\n        text: \"Ensure that the --make-iptables-util-chains argument is set to true (Manual)\"\n        audit: |\n          /bin/bash\n          flag=make-iptables-util-chains\n          opt=makeIPTablesUtilChains\n          # look at each machineconfigpool\n          while read -r pool nodeconfig; do\n            # true by default\n            value='true'\n            # first look for the flag\n            oc get machineconfig $nodeconfig -o json | jq -r '.spec.config.systemd[][] | select(.name==\"kubelet.service\") | .contents' | sed -n \"/^ExecStart=/,/^\\$/ { /^\\\\s*--$flag=false/ q 100 }\"\n            # if the above command exited with 100, the flag was false\n            [ $? == 100 ] && value='false'\n            # now look in the yaml KubeletConfig\n            yamlconfig=$(oc get machineconfig $nodeconfig -o json | jq -r '.spec.config.storage.files[] | select(.path==\"/etc/kubernetes/kubelet.conf\") | .contents.source ' | sed 's/^data:,//' | while read; do echo -e ${REPLY//%/\\\\x}; done)\n            echo \"$yamlconfig\" | sed -n \"/^$opt:\\\\s*false\\\\s*$/ q 100\"\n            [ $? == 100 ] && value='false'\n            echo \"Pool $pool has $flag ($opt) set to $value\"\n          done < <(oc get machineconfigpools -o json | jq -r '.items[] | select(.status.machineCount>0) | .metadata.name + \" \" + .spec.configuration.name')\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"set to true\"\n        remediation: |\n          None required. The --make-iptables-util-chains argument is set to true by default.\n        scored: false\n\n      - id: 4.2.8\n        text: \"Ensure that the --hostname-override argument is not set (Manual)\"\n        audit: |\n          echo `oc get machineconfig 01-worker-kubelet -o yaml | grep hostname-override`\n          echo `oc get machineconfig 01-master-kubelet -o yaml | grep hostname-override`\n        tests:\n          test_items:\n            - flag: hostname-override\n              set: false\n        remediation: |\n          By default, --hostname-override argument is not set.\n        scored: false\n\n      - id: 4.2.9\n        text: \"Ensure that the kubeAPIQPS [--event-qps] argument is set to 0 or a level which ensures appropriate event capture (Manual)\"\n        audit: |\n          NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')\n          oc debug node/${NODE_NAME} -- chroot /host cat /etc/kubernetes/kubelet.conf;\n          oc get machineconfig 01-worker-kubelet -o yaml | grep --color kubeAPIQPS%3A%2050\n          oc get machineconfig 01-master-kubelet -o yaml | grep --color kubeAPIQPS%3A%2050\n        type: \"manual\"\n        remediation: |\n          Follow the documentation to edit kubelet parameters\n          https://docs.openshift.com/container-platform/4.5/scalability_and_performance/recommended-host-practices.html#create-a-kubeletconfig-crd-to-edit-kubelet-parameters\n          KubeAPIQPS: <QPS>\n        scored: false\n\n      - id: 4.2.10\n        text: \"Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Automated)\"\n        audit: |\n          oc get configmap config -n openshift-kube-apiserver -o json \\\n            | jq -r '.data[\"config.yaml\"]' \\\n            | jq -r '.apiServerArguments |\n                .[\"kubelet-client-certificate\"][0],\n                .[\"kubelet-client-key\"][0]\n              '\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"/etc/kubernetes/static-pod-certs/secrets/kubelet-client/tls.crt\"\n            - flag: \"/etc/kubernetes/static-pod-certs/secrets/kubelet-client/tls.key\"\n        remediation: |\n          OpenShift automatically manages TLS authentication for the API server communication with the node/kublet.\n          This is not configurable.\n        scored: true\n\n      - id: 4.2.11\n        text: \"Ensure that the --rotate-certificates argument is not set to false (Manual)\"\n        audit: |\n          #Verify the rotateKubeletClientCertificate feature gate is not set to false\n          NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')\n          oc debug node/${NODE_NAME} -- chroot /host cat /etc/kubernetes/kubelet.conf | grep RotateKubeletClientCertificate 2> /dev/null\n          # Verify the rotateCertificates argument is set to true\n          oc debug node/${NODE_NAME} -- chroot host grep rotate /etc/kubernetes/kubelet.conf 2> /dev/null\n        use_multiple_values: true\n        tests:\n          bin_op: or\n          test_items:\n            - flag: rotateCertificates\n              compare:\n                op: eq\n                value: true\n            - flag: rotateKubeletClientCertificates\n              compare:\n                op: noteq\n                value: false\n            - flag: rotateKubeletClientCertificates\n              set: false\n        remediation: |\n          None required.\n        scored: false\n\n      - id: 4.2.12\n        text: \"Verify that the RotateKubeletServerCertificate argument is set to true (Manual)\"\n        audit: |\n          #Verify the rotateKubeletServerCertificate feature gate is on\n          NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')\n          oc debug node/${NODE_NAME} -- chroot /host grep RotateKubeletServerCertificate /etc/kubernetes/kubelet.conf 2> /dev/null\n          # Verify the rotateCertificates argument is set to true\n          oc debug node/${NODE_NAME} -- chroot host grep rotate /etc/kubernetes/kubelet.conf 2> /dev/null\n        use_multiple_values: true\n        tests:\n          bin_op: or\n          test_items:\n            - flag: rotateCertificates\n              compare:\n                op: eq\n                value: true\n            - flag: RotateKubeletServerCertificate\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          By default, kubelet server certificate rotation is disabled.\n        scored: false\n\n      - id: 4.2.13\n        text: \"Ensure that the Kubelet only makes use of Strong Cryptographic Ciphers (Manual)\"\n        audit: |\n          # needs verification\n          # verify cipher suites\n          oc describe --namespace=openshift-ingress-operator ingresscontroller/default\n          oc get kubeapiservers.operator.openshift.io cluster -o json |jq .spec.observedConfig.servingInfo\n          oc get openshiftapiservers.operator.openshift.io cluster -o json |jq .spec.observedConfig.servingInfo\n          oc get cm -n openshift-authentication v4-0-config-system-cliconfig -o jsonpath='{.data.v4\\-0\\-config\\-system\\-cliconfig}' | jq .servingInfo\n          #check value for tlsSecurityProfile; null is returned if default is used\n          oc get kubeapiservers.operator.openshift.io cluster -o json |jq .spec.tlsSecurityProfile\n        type: manual\n        remediation: |\n          Follow the directions above and in the OpenShift documentation to configure the tlsSecurityProfile.\n          Configuring Ingress\n        scored: false\n"
  },
  {
    "path": "cfg/rh-1.0/policies.yaml",
    "content": "---\ncontrols:\nversion: rh-1.0\nid: 5\ntext: \"Kubernetes Policies\"\ntype: \"policies\"\ngroups:\n  - id: 5.1\n    text: \"RBAC and Service Accounts\"\n    checks:\n      - id: 5.1.1\n        text: \"Ensure that the cluster-admin role is only used where required (Manual)\"\n        type: \"manual\"\n        audit: |\n          #To get a list of users and service accounts with the cluster-admin role\n          oc get clusterrolebindings -o=customcolumns=NAME:.metadata.name,ROLE:.roleRef.name,SUBJECT:.subjects[*].kind |\n          grep cluster-admin\n          #To verity that kbueadmin is removed, no results should be returned\n          oc get secrets kubeadmin -n kube-system\n        remediation: |\n          Identify all clusterrolebindings to the cluster-admin role. Check if they are used and\n          if they need this role or if they could use a role with fewer privileges.\n          Where possible, first bind users to a lower privileged role and then remove the\n          clusterrolebinding to the cluster-admin role :\n          kubectl delete clusterrolebinding [name]\n        scored: false\n\n      - id: 5.1.2\n        text: \"Minimize access to secrets (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove get, list and watch access to secret objects in the cluster.\n        scored: false\n\n      - id: 5.1.3\n        text: \"Minimize wildcard use in Roles and ClusterRoles (Manual)\"\n        type: \"manual\"\n        audit: |\n          #needs verification\n          oc get roles --all-namespaces -o yaml\n          for i in $(oc get roles -A -o jsonpath='{.items[*].metadata.name}'); do oc\n          describe clusterrole ${i}; done\n          #Retrieve the cluster\troles defined in the cluster and review\tfor\twildcards\n          oc get clusterroles -o yaml\n          for i in $(oc get clusterroles -o jsonpath='{.items[*].metadata.name}'); do\n          oc describe clusterrole ${i}; done\n        remediation: |\n          Where possible replace any use of wildcards in clusterroles and roles with specific\n          objects or actions.\n        scored: false\n\n      - id: 5.1.4\n        text: \"Minimize access to create pods (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove create access to pod objects in the cluster.\n        scored: false\n\n      - id: 5.1.5\n        text: \"Ensure that default service accounts are not actively used. (Manual)\"\n        type: \"manual\"\n        remediation: |\n          None required.\n        scored: false\n\n      - id: 5.1.6\n        text: \"Ensure that Service Account Tokens are only mounted where necessary (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Modify the definition of pods and service accounts which do not need to mount service\n          account tokens to disable it.\n        scored: false\n\n  - id: 5.2\n    text: \"Pod Security Policies\"\n    checks:\n      - id: 5.2.1\n        text: \"Minimize the admission of privileged containers (Manual)\"\n        audit: |\n          # needs verification\n          oc get scc -o=custom-columns=NAME:.metadata.name,allowPrivilegedContainer:.allowPrivilegedContainer\n        tests:\n          test_items:\n            - flag: \"false\"\n        remediation: |\n          Create a SCC as described in the OpenShift documentation, ensuring that the Allow\n          Privileged field is set to false.\n        scored: false\n\n      - id: 5.2.2\n        text: \"Minimize the admission of containers wishing to share the host process ID namespace (Manual)\"\n        audit: |\n          oc get scc -o=custom-columns=NAME:.metadata.name,allowHostPID:.allowHostPID\n        tests:\n          test_items:\n            - flag: \"false\"\n        remediation: |\n          Create a SCC as described in the OpenShift documentation, ensuring that the Allow Host\n          PID field is set to false.\n        scored: false\n\n      - id: 5.2.3\n        text: \"Minimize the admission of containers wishing to share the host IPC namespace (Manual)\"\n        audit: |\n          oc get scc -o=custom-columns=NAME:.metadata.name,allowHostIPC:.allowHostIPC\n        tests:\n          test_items:\n            - flag: \"false\"\n        remediation: |\n          Create a SCC as described in the OpenShift documentation, ensuring that the Allow Host\n          IPC field is set to false.\n        scored: false\n\n      - id: 5.2.4\n        text: \"Minimize the admission of containers wishing to share the host network namespace (Manual)\"\n        audit: |\n          oc get scc -o=custom-columns=NAME:.metadata.name,allowHostNetwork:.allowHostNetwork\n        tests:\n          test_items:\n            - flag: \"false\"\n        remediation: |\n          Create a SCC as described in the OpenShift documentation, ensuring that the Allow Host\n          Network field is omitted or set to false.\n        scored: false\n\n      - id: 5.2.5\n        text: \"Minimize the admission of containers with allowPrivilegeEscalation (Manual)\"\n        audit: |\n          oc get scc -o=custom-columns=NAME:.metadata.name,allowPrivilegeEscalation:.allowPrivilegeEscalation\n        tests:\n          test_items:\n            - flag: \"false\"\n        remediation: |\n          Create a SCC as described in the OpenShift documentation, ensuring that the Allow\n          Privilege Escalation field is omitted or set to false.\n        scored: false\n\n      - id: 5.2.6\n        text: \"Minimize the admission of root containers (Manual)\"\n        audit: |\n          # needs verification # | awk 'NR>1 {gsub(\"map\\\\[type:\", \"\", $2); gsub(\"\\\\]$\", \"\", $2); print $1 \":\" $2}'\n          oc get scc -o=custom-columns=NAME:.metadata.name,runAsUser:.runAsUser.type\n          #For SCCs with MustRunAs verify that the range of UIDs does not include 0\n          oc get scc -o=custom-columns=NAME:.metadata.name,uidRangeMin:.runAsUser.uidRangeMin,uidRangeMax:.runAsUser.uidRangeMax\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"MustRunAsNonRoot\"\n            - flag: \"MustRunAs\"\n              compare:\n                op: nothave\n                value: 0\n        remediation: |\n          None required. By default, OpenShift includes the non-root SCC with the the Run As User\n          Strategy is set to either MustRunAsNonRoot. If additional SCCs are appropriate, follow the\n          OpenShift documentation to create custom SCCs.\n        scored: false\n\n      - id: 5.2.7\n        text: \"Minimize the admission of containers with the NET_RAW capability (Manual)\"\n        audit: |\n          # needs verification\n          oc get scc -o=custom-columns=NAME:.metadata.name,requiredDropCapabilities:.requiredDropCapabilities\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"ALL\"\n            - flag: \"NET_RAW\"\n        remediation: |\n          Create a SCC as described in the OpenShift documentation, ensuring that the Required\n          Drop Capabilities is set to include either NET_RAW or ALL.\n        scored: false\n\n      - id: 5.2.8\n        text: \"Minimize the admission of containers with added capabilities (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that Allowed Capabilities is set to an empty array for every SCC in the cluster\n          except for the privileged SCC.\n        scored: false\n\n      - id: 5.2.9\n        text: \"Minimize the admission of containers with capabilities assigned (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Review the use of capabilites in applications running on your cluster. Where a namespace\n          contains applications which do not require any Linux capabities to operate consider\n          adding a SCC which forbids the admission of containers which do not drop all capabilities.\n        scored: false\n\n  - id: 5.3\n    text: \"Network Policies and CNI\"\n    checks:\n      - id: 5.3.1\n        text: \"Ensure that the CNI in use supports Network Policies (Manual)\"\n        type: \"manual\"\n        remediation: |\n          None required.\n        scored: false\n\n      - id: 5.3.2\n        text: \"Ensure that all Namespaces have Network Policies defined (Manual)\"\n        type: \"manual\"\n        audit: |\n          #Run the following command and review the NetworkPolicy objects created in the cluster.\n          oc -n all get networkpolicy\n        remediation: |\n          Follow the documentation and create NetworkPolicy objects as you need them.\n        scored: false\n\n  - id: 5.4\n    text: \"Secrets Management\"\n    checks:\n      - id: 5.4.1\n        text: \"Prefer using secrets as files over secrets as environment variables (Manual)\"\n        type: \"manual\"\n        audit: |\n          #Run the following command to find references to objects which use environment variables defined from secrets.\n          oc get all -o jsonpath='{range .items[?(@..secretKeyRef)]} {.kind}\n          {.metadata.name} {\"\\n\"}{end}' -A\n        remediation: |\n          If possible, rewrite application code to read secrets from mounted secret files, rather than\n          from environment variables.\n        scored: false\n\n      - id: 5.4.2\n        text: \"Consider external secret storage (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Refer to the secrets management options offered by your cloud provider or a third-party\n          secrets management solution.\n        scored: false\n\n  - id: 5.5\n    text: \"Extensible Admission Control\"\n    checks:\n      - id: 5.5.1\n        text: \"Configure Image Provenance using ImagePolicyWebhook admission controller (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the OpenShift documentation: [Image configuration resources](https://docs.openshift.com/container-platform/4.5/openshift_images/image-configuration.html\n        scored: false\n\n  - id: 5.7\n    text: \"General Policies\"\n    checks:\n      - id: 5.7.1\n        text: \"Create administrative boundaries between resources using namespaces (Manual)\"\n        type: \"manual\"\n        audit: |\n          #Run the following command and review the namespaces created in the cluster.\n          oc get namespaces\n          #Ensure that these namespaces are the ones you need and are adequately administered as per your requirements.\n        remediation: |\n          Follow the documentation and create namespaces for objects in your deployment as you need\n          them.\n        scored: false\n\n      - id: 5.7.2\n        text: \"Ensure that the seccomp profile is set to docker/default in your pod definitions (Manual)\"\n        type: \"manual\"\n        remediation: |\n          To enable the default seccomp profile, use the reserved value /runtime/default that will\n          make sure that the pod uses the default policy available on the host.\n        scored: false\n\n      - id: 5.7.3\n        text: \"Apply Security Context to Your Pods and Containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and apply security contexts to your pods. For a\n          suggested list of security contexts, you may refer to the CIS Security Benchmark for Docker\n          Containers.\n        scored: false\n\n      - id: 5.7.4\n        text: \"The default namespace should not be used (Manual)\"\n        type: \"manual\"\n        audit: |\n          #Run this command to list objects in default namespace\n          oc project default\n          oc get all\n          #The only entries there should be system managed resources such as the kubernetes and openshift service\n        remediation: |\n          Ensure that namespaces are created to allow for appropriate segregation of Kubernetes\n          resources and that all new resources are created in a specific namespace.\n        scored: false\n"
  },
  {
    "path": "cfg/rh-1.4/config.yaml",
    "content": "---\n## Version-specific settings that override the values in cfg/config.yaml\n"
  },
  {
    "path": "cfg/rh-1.4/controlplane.yaml",
    "content": "---\ncontrols:\nversion: rh-1.4\nid: 3\ntext: \"Control Plane Configuration\"\ntype: \"controlplane\"\ngroups:\n  - id: 3.1\n    text: \"Authentication and Authorization\"\n    checks:\n      - id: 3.1.1\n        text: \"Client certificate authentication should not be used for users (Manual)\"\n        audit: |\n          # To verify user authentication is enabled\n          oc describe authentication\n          # To verify that an identity provider is configured\n          oc get identity\n          # To verify that a custom cluster-admin user exists\n          oc get clusterrolebindings -o=custom-columns=NAME:.metadata.name,ROLE:.roleRef.name,SUBJECT:.subjects[*].kind | grep cluster-admin | grep User\n          # To verity that kbueadmin is removed, no results should be returned\n          oc get secrets kubeadmin -n kube-system\n        type: manual\n        remediation: |\n          Configure an identity provider for the OpenShift cluster.\n          Understanding identity provider configuration | Authentication | OpenShift\n          Container Platform 4.5. Once an identity provider has been defined,\n          you can use RBAC to define and apply permissions.\n          After you define an identity provider and create a new cluster-admin user,\n          remove the kubeadmin user to improve cluster security.\n        scored: false\n\n  - id: 3.2\n    text: \"Logging\"\n    checks:\n      - id: 3.2.1\n        text: \"Ensure that a minimal audit policy is created (Manual)\"\n        audit: |\n          #To view kube apiserver log files\n          oc adm node-logs --role=master --path=kube-apiserver/\n          #To view openshift apiserver log files\n          oc adm node-logs --role=master --path=openshift-apiserver/\n          #To verify kube apiserver audit config\n          oc get configmap config -n openshift-kube-apiserver -ojson | jq -r '.data[\"config.yaml\"]' | jq '.auditConfig[]?'\n          #To verify openshift apiserver audit config\n          oc get configmap config -n openshift-apiserver -ojson | jq -r '.data[\"config.yaml\"]' | jq '.auditConfig[]?'\n        type: manual\n        remediation: |\n          No remediation required.\n        scored: false\n\n      - id: 3.2.2\n        text: \"Ensure that the audit policy covers key security concerns (Manual)\"\n        audit: |\n          #To verify openshift apiserver audit config\n          oc get configmap config -n openshift-kube-apiserver -ojson | jq -r '.data[\"config.yaml\"]' | jq '.auditConfig.policyConfiguration.rules[]?'\n          #To verify kube apiserver audit config\n          oc get configmap config -n openshift-apiserver -ojson | jq -r '.data[\"config.yaml\"]' | jq '.auditConfig.policyConfiguration.rules[]?'\n        type: manual\n        remediation: |\n          In OpenShift 4.6 and higher, if appropriate for your needs,\n          modify the audit policy.\n        scored: false\n"
  },
  {
    "path": "cfg/rh-1.4/etcd.yaml",
    "content": "---\ncontrols:\nversion: rh-1.4\nid: 2\ntext: \"Etcd\"\ntype: \"etcd\"\ngroups:\n  - id: 2\n    text: \"Etcd\"\n    checks:\n      - id: 2.1\n        text: \"Ensure that the --cert-file and --key-file arguments are set as appropriate (Manual)\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n          # Get the pod name in the openshift-etcd namespace\n          POD_NAME=$(oc get pods -n openshift-etcd -l app=etcd --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n          if [ -z \"$POD_NAME\" ]; then\n          echo \"No matching file found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-etcd -c etcd \"$POD_NAME\" -- ps -o command= -C etcd | sed 's/.*\\(--cert-file=[^ ]*\\).*/\\1/'\n          oc exec -n openshift-etcd -c etcd \"$POD_NAME\" -- ps -o command= -C etcd | sed 's/.*\\(--key-file=[^ ]*\\).*/\\1/'\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"file\"\n              compare:\n                op: regex\n                value: '\\/etc\\/kubernetes\\/static-pod-certs\\/secrets\\/etcd-all-(serving|certs)\\/etcd-serving-.*\\.(?:crt|key)'\n        remediation: |\n          OpenShift does not use the etcd-certfile or etcd-keyfile flags.\n          Certificates for etcd are managed by the etcd cluster operator.\n        scored: true\n\n      - id: 2.2\n        text: \"Ensure that the --client-cert-auth argument is set to true (Manual)\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n          # Get the pod name in the openshift-etcd namespace\n          POD_NAME=$(oc get pods -n openshift-etcd -l app=etcd --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n          if [ -z \"$POD_NAME\" ]; then\n          echo \"No matching file found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-etcd -c etcd \"$POD_NAME\" -- ps -o command= -C etcd | sed 's/.*\\(--client-cert-auth=[^ ]*\\).*/\\1/'\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"--client-cert-auth\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          This setting is managed by the cluster etcd operator. No remediation required.\"\n        scored: true\n\n      - id: 2.3\n        text: \"Ensure that the --auto-tls argument is not set to true (Manual)\"\n        audit: |\n          # Returns 0 if found, 1 if not found\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n          # Get the pod name in the openshift-etcd namespace\n          POD_NAME=$(oc get pods -n openshift-etcd -l app=etcd --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n          if [ -z \"$POD_NAME\" ]; then\n          echo \"No matching file found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-etcd -c etcd \"$POD_NAME\" -- ps -o command= -C etcd | grep -- --auto-tls=true 2>/dev/null ; echo exit_code=$?\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"exit_code\"\n              compare:\n                op: eq\n                value: \"1\"\n        remediation: |\n          This setting is managed by the cluster etcd operator. No remediation required.\n        scored: true\n\n      - id: 2.4\n        text: \"Ensure that the --peer-cert-file and --peer-key-file arguments are set as appropriate (Manual)\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n          # Get the pod name in the openshift-etcd namespace\n          POD_NAME=$(oc get pods -n openshift-etcd -l app=etcd --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n          if [ -z \"$POD_NAME\" ]; then\n          echo \"No matching file found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-etcd -c etcd \"$POD_NAME\" -- ps -o command= -C etcd | sed 's/.*\\(--peer-cert-file=[^ ]*\\).*/\\1/'\n          oc exec -n openshift-etcd -c etcd \"$POD_NAME\" -- ps -o command= -C etcd | sed 's/.*\\(--peer-key-file=[^ ]*\\).*/\\1/'\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"file\"\n              compare:\n                op: regex\n                value: '\\/etc\\/kubernetes\\/static-pod-certs\\/secrets\\/etcd-all-(peer|certs)\\/etcd-peer-.*\\.(?:crt|key)'\n        remediation: |\n          None. This configuration is managed by the etcd operator.\n        scored: true\n\n      - id: 2.5\n        text: \"Ensure that the --peer-client-cert-auth argument is set to true (Manual)\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n          # Get the pod name in the openshift-etcd namespace\n          POD_NAME=$(oc get pods -n openshift-etcd -l app=etcd --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n          if [ -z \"$POD_NAME\" ]; then\n          echo \"No matching file found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-etcd -c etcd \"$POD_NAME\" -- ps -o command= -C etcd | sed 's/.*\\(--peer-client-cert-auth=[^ ]*\\).*/\\1/'\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"--peer-client-cert-auth\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          This setting is managed by the cluster etcd operator. No remediation required.\n        scored: true\n\n      - id: 2.6\n        text: \"Ensure that the --peer-auto-tls argument is not set to true (Manual)\"\n        audit: |\n          # Returns 0 if found, 1 if not found\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n          # Get the pod name in the openshift-etcd namespace\n          POD_NAME=$(oc get pods -n openshift-etcd -l app=etcd --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n          if [ -z \"$POD_NAME\" ]; then\n          echo \"No matching file found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-etcd -c etcd \"$POD_NAME\" -- ps -o command= -C etcd | grep -- --peer-auto-tls=true 2>/dev/null ; echo exit_code=$?\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"exit_code\"\n              compare:\n                op: eq\n                value: \"1\"\n        remediation: |\n          This setting is managed by the cluster etcd operator. No remediation required.\n        scored: true\n\n      - id: 2.7\n        text: \"Ensure that a unique Certificate Authority is used for etcd (Manual)\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n          # Get the pod name in the openshift-etcd namespace\n          POD_NAME=$(oc get pods -n openshift-etcd -l app=etcd --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n          if [ -z \"$POD_NAME\" ]; then\n          echo \"No matching file found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-etcd -c etcd \"$POD_NAME\" -- ps -o command= -C etcd | sed 's/.*\\(--trusted-ca-file=[^ ]*\\).*/\\1/'\n          oc exec -n openshift-etcd -c etcd \"$POD_NAME\" -- ps -o command= -C etcd | sed 's/.*\\(--peer-trusted-ca-file=[^ ]*\\).*/\\1/'\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"file\"\n              compare:\n                op: regex\n                value: '\\/etc\\/kubernetes\\/static-pod-certs\\/configmaps\\/(?:etcd-(?:serving|peer-client)-ca\\/ca-bundle\\.crt|etcd-all-bundles\\/server-ca-bundle\\.crt)'\n        remediation: |\n          None required. Certificates for etcd are managed by the OpenShift cluster etcd operator.\n        scored: true\n"
  },
  {
    "path": "cfg/rh-1.4/master.yaml",
    "content": "---\ncontrols:\nversion: rh-1.4\nid: 1\ntext: \"Control Plane Components\"\ntype: \"master\"\ngroups:\n  - id: 1.1\n    text: \"Master Node Configuration Files\"\n    checks:\n      - id: 1.1.1\n        text: \"Ensure that the API server pod specification file permissions are set to 600 or more restrictive (Manual)\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n\n          # Get the pod name in the openshift-kube-apiserver namespace\n          POD_NAME=$(oc get pods -n openshift-kube-apiserver -l app=openshift-kube-apiserver --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n              echo \"No matching pods found on the current node.\"\n          else\n             # Execute the stat command\n             oc exec -n openshift-kube-apiserver \"$POD_NAME\" -- stat -c \"$POD_NAME %n permissions=%a\" /etc/kubernetes/static-pod-resources/kube-apiserver-pod.yaml\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          No remediation required; file permissions are managed by the operator.\n        scored: true\n\n      - id: 1.1.2\n        text: \"Ensure that the API server pod specification file ownership is set to root:root (Manual)\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n\n          # Get the pod name in the openshift-kube-apiserver namespace\n          POD_NAME=$(oc get pods -n openshift-kube-apiserver -l app=openshift-kube-apiserver --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n              echo \"No matching pods found on the current node.\"\n          else\n             # Execute the stat command\n             oc exec -n openshift-kube-apiserver \"$POD_NAME\" -- stat -c \"$POD_NAME %n %U:%G\" /etc/kubernetes/static-pod-resources/kube-apiserver-pod.yaml\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          No remediation required; file permissions are managed by the operator.\n        scored: true\n\n      - id: 1.1.3\n        text: \"Ensure that the controller manager pod specification file permissions are set to 600 or more restrictive (Manual)\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n\n          # Get the pod name in the openshift-kube-controller-manager namespace\n          POD_NAME=$(oc get pods -n openshift-kube-controller-manager -l app=kube-controller-manager --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n             echo \"No matching pods found on the current node.\"\n          else\n            # Execute the stat command\n            oc exec -n openshift-kube-controller-manager \"$POD_NAME\" -- stat -c \"$POD_NAME %n permissions=%a\" /etc/kubernetes/static-pod-resources/kube-controller-manager-pod.yaml\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          No remediation required; file permissions are managed by the operator.\n        scored: true\n\n      - id: 1.1.4\n        text: \"Ensure that the controller manager pod specification file ownership is set to root:root (Manual)\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n\n          # Get the pod name in the openshift-kube-controller-manager namespace\n          POD_NAME=$(oc get pods -n openshift-kube-controller-manager -l app=kube-controller-manager --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n            echo \"No matching pods found on the current node.\"\n          else\n           # Execute the stat command\n           oc exec -n openshift-kube-controller-manager \"$POD_NAME\" -- stat -c \"$POD_NAME %n %U:%G\" /etc/kubernetes/static-pod-resources/kube-controller-manager-pod.yaml\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          No remediation required; file permissions are managed by the operator.\n        scored: true\n\n      - id: 1.1.5\n        text: \"Ensure that the scheduler pod specification file permissions are set to 600 or more restrictive (Manual)\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n\n          # Get the pod name in the openshift-kube-scheduler namespace\n          POD_NAME=$(oc get pods -n openshift-kube-scheduler -l app=openshift-kube-scheduler --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n           echo \"No matching pods found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-kube-scheduler \"$POD_NAME\" -- stat -c \"$POD_NAME %n permissions=%a\" /etc/kubernetes/static-pod-resources/kube-scheduler-pod.yaml\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          No remediation required; file permissions are managed by the operator.\n        scored: true\n\n      - id: 1.1.6\n        text: \"Ensure that the scheduler pod specification file ownership is set to root:root (Manual))\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n\n          # Get the pod name in the openshift-kube-scheduler namespace\n          POD_NAME=$(oc get pods -n openshift-kube-scheduler -l app=openshift-kube-scheduler --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n           echo \"No matching pods found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-kube-scheduler \"$POD_NAME\" -- stat -c \"$POD_NAME %n %U:%G\" /etc/kubernetes/static-pod-resources/kube-scheduler-pod.yaml\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          No remediation required; file permissions are managed by the operator.\n        scored: true\n\n      - id: 1.1.7\n        text: \"Ensure that the etcd pod specification file permissions are set to 600 or more restrictive (Manual))\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n\n          # Get the pod name in the openshift-etcd namespace\n          POD_NAME=$(oc get pods -n openshift-etcd -l app=etcd --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n           echo \"No matching pods found on the current node.\"\n          else\n          # Execute the stat command\n          oc rsh -n openshift-etcd \"$POD_NAME\" stat -c \"$POD_NAME %n permissions=%a\" /etc/kubernetes/manifests/etcd-pod.yaml\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          No remediation required; file permissions are managed by the operator.\n        scored: true\n\n      - id: 1.1.8\n        text: \"Ensure that the etcd pod specification file ownership is set to root:root (Manual)\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n\n          # Get the pod name in the openshift-etcd namespace\n          POD_NAME=$(oc get pods -n openshift-etcd -l app=etcd --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n           echo \"No matching pods found on the current node.\"\n          else\n          # Execute the stat command\n          oc rsh -n openshift-etcd \"$POD_NAME\" stat -c \"$POD_NAME %n %U:%G\" /etc/kubernetes/manifests/etcd-pod.yaml\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          No remediation required; file permissions are managed by the operator.\n        scored: true\n\n      - id: 1.1.9\n        text: \"Ensure that the Container Network Interface file permissions are set to 600 or more restrictive (Manual)\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n          # For CNI multus\n          # Get the pod name in the openshift-multus namespace\n          POD_NAME=$(oc get pods -n openshift-multus -l app=multus --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n           echo \"No matching pods found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-multus \"$POD_NAME\"  -- /bin/bash -c \"stat -c \\\"$i %n permissions=%a\\\" /host/etc/cni/net.d/*.conf\";  2>/dev/null\n          oc exec -n openshift-multus \"$POD_NAME\"  -- /bin/bash -c \"stat -c \\\"$i %n permissions=%a\\\" /host/var/run/multus/cni/net.d/*.conf\";  2>/dev/null\n          fi\n          # For SDN pods\n          POD_NAME=$(oc get pods -n openshift-sdn -l app=sdn --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n           echo \"No matching pods found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-sdn \"$POD_NAME\"  -- find /var/lib/cni/networks/openshift-sdn -type f -exec stat -c \"$i %n permissions=%a\" {} \\; 2>/dev/null\n          oc exec -n openshift-sdn \"$POD_NAME\"  -- find /var/run/openshift-sdn -type f -exec stat -c \"$i %n permissions=%a\" {} \\; 2>/dev/null\n          fi\n\n          # For OVS pods\n          POD_NAME=$(oc get pods -n openshift-sdn -l app=ovs --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n           echo \"No matching pods found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-sdn \"$POD_NAME\"  -- find /var/run/openvswitch -type f -exec stat -c \"$i %n permissions=%a\" {} \\; 2>/dev/null\n          oc exec -n openshift-sdn \"$POD_NAME\"  -- find /etc/openvswitch -type f -exec stat -c \"$i %n permissions=%a\" {} \\; 2>/dev/null\n          oc exec -n openshift-sdn \"$POD_NAME\"  -- find /run/openvswitch -type f -exec stat -c \"$i %n permissions=%a\" {} \\; 2>/dev/null\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          No remediation required; file permissions are managed by the operator.\n        scored: true\n\n      - id: 1.1.10\n        text: \"Ensure that the Container Network Interface file ownership is set to root:root (Manual)\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n          # For CNI multus\n          # Get the pod name in the openshift-multus namespace\n          POD_NAME=$(oc get pods -n openshift-multus -l app=multus --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n           echo \"No matching pods found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-multus \"$POD_NAME\" -- /bin/bash -c \"stat -c '$i %n %U:%G' /host/etc/cni/net.d/*.conf\" 2>/dev/null\n          oc exec -n openshift-multus $i -- /bin/bash -c \"stat -c '$i %n %U:%G' /host/var/run/multus/cni/net.d/*.conf\"  2>/dev/null\n          fi\n          # For SDN pods\n          POD_NAME=$(oc get pods -n openshift-sdn -l app=sdn --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n           echo \"No matching pods found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-sdn \"$POD_NAME\"  -- find /var/lib/cni/networks/openshift-sdn -type f -exec stat -c \"$i %n %U:%G\" {} \\; 2>/dev/null\n          oc exec -n openshift-sdn \"$POD_NAME\"  -- find /var/run/openshift-sdn -type f -exec stat -c \"$i %n %U:%G\" {} \\; 2>/dev/null\n          fi\n          # For OVS pods in 4.5\n          POD_NAME=$(oc get pods -n openshift-sdn -l app=ovs --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n           echo \"No matching pods found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-sdn \"$POD_NAME\"  -- find /var/run/openvswitch -type f -exec stat -c \"$i %n %U:%G\" {} \\; 2>/dev/null\n          oc exec -n openshift-sdn \"$POD_NAME\"  -- find /etc/openvswitch -type f -exec stat -c \"$i %n %U:%G\" {} \\; 2>/dev/null\n          oc exec -n openshift-sdn \"$POD_NAME\"  -- find /run/openvswitch -type f -exec stat -c \"$i %n %U:%G\" {} \\; 2>/dev/null\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          No remediation required; file permissions are managed by the operator.\n        scored: true\n\n      - id: 1.1.11\n        text: \"Ensure that the etcd data directory permissions are set to 700 or more restrictive (Manual)\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n\n          # Get the pod name in the openshift-etcd namespace\n          POD_NAME=$(oc get pods -n openshift-etcd -l app=etcd --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n          echo \"No matching pods found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-etcd \"$POD_NAME\" -- stat -c \"$POD_NAME %n permissions=%a\" /var/lib/etcd/member\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"700\"\n        remediation: |\n          No remediation required; file permissions are managed by the operator.\n        scored: true\n\n      - id: 1.1.12\n        text: \"Ensure that the etcd data directory ownership is set to etcd:etcd (Manual)\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n\n          # Get the pod name in the openshift-etcd namespace\n          POD_NAME=$(oc get pods -n openshift-etcd -l app=etcd --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n          echo \"No matching pods found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-etcd \"$POD_NAME\" -- stat -c \"$POD_NAME %n %U:%G\" /var/lib/etcd/member\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          No remediation required; file permissions are managed by the operator.\n        scored: true\n\n      - id: 1.1.13\n        text: \"Ensure that the kubeconfig file permissions are set to 600 or more restrictive (Manual)\"\n        audit: |\n          NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')\n          oc debug node/$NODE_NAME -- chroot /host stat -c \"$NODE_NAME %n permissions=%a\" /etc/kubernetes/kubeconfig 2> /dev/null\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          No remediation required; file permissions are managed by the operator.\n        scored: true\n\n      - id: 1.1.14\n        text: \"Ensure that the kubeconfig file ownership is set to root:root (Manual)\"\n        audit: |\n          NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')\n          oc debug node/$NODE_NAME -- chroot /host stat -c \"$NODE_NAME %n %U:%G\" /etc/kubernetes/kubeconfig 2> /dev/null\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          No remediation required; file permissions are managed by the operator.\n        scored: true\n\n      - id: 1.1.15\n        text: \"Ensure that the scheduler kubeconfig file permissions are set to 600 or more restrictive (Manual)\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n\n          # Get the pod name in the openshift-kube-scheduler namespace\n          POD_NAME=$(oc get pods -n openshift-kube-scheduler -l app=openshift-kube-scheduler --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n          echo \"No matching pods found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-kube-scheduler \"$POD_NAME\" -- stat -c \"$POD_NAME %n permissions=%a\" /etc/kubernetes/static-pod-resources/configmaps/scheduler-kubeconfig/kubeconfig\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          No remediation required; file permissions are managed by the operator.\n        scored: true\n\n      - id: 1.1.16\n        text: \"Ensure that the scheduler kubeconfig file ownership is set to root:root (Manual)\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n\n          # Get the pod name in the openshift-kube-scheduler namespace\n          POD_NAME=$(oc get pods -n openshift-kube-scheduler -l app=openshift-kube-scheduler --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n          echo \"No matching pods found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-kube-scheduler \"$POD_NAME\" -- stat -c \"$POD_NAME %n %U:%G\" /etc/kubernetes/static-pod-resources/configmaps/scheduler-kubeconfig/kubeconfig\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          No remediation required; file permissions are managed by the operator.\n        scored: true\n\n      - id: 1.1.17\n        text: \"Ensure that the controller-manager kubeconfig file permissions are set to 600 or more restrictive (Manual)\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n\n          # Get the pod name in the openshift-kube-controller-manager namespace\n          POD_NAME=$(oc get pods -n openshift-kube-controller-manager -l app=kube-controller-manager --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n          echo \"No matching pods found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-kube-controller-manager \"$POD_NAME\" -- stat -c \"$POD_NAME %n permissions=%a\" /etc/kubernetes/static-pod-resources/configmaps/controller-manager-kubeconfig/kubeconfig\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          No remediation required; file permissions are managed by the operator.\n        scored: true\n\n      - id: 1.1.18\n        text: \"Ensure that the controller-manager kubeconfig file ownership is set to root:root (Manual)\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n\n          # Get the pod name in the openshift-kube-controller-manager namespace\n          POD_NAME=$(oc get pods -n openshift-kube-controller-manager -l app=kube-controller-manager --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n          echo \"No matching pods found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-kube-controller-manager \"$POD_NAME\" -- stat -c \"$POD_NAME %n %U:%G\" /etc/kubernetes/static-pod-resources/configmaps/controller-manager-kubeconfig/kubeconfig\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          No remediation required; file permissions are managed by the operator.\n        scored: true\n\n      - id: 1.1.19\n        text: \"Ensure that the OpenShift PKI directory and file ownership is set to root:root (Manual)\"\n        audit: |\n          # Should return root:root for all files and directories\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n\n          # Get the pod name in the openshift-kube-controller-manager namespace\n          POD_NAME=$(oc get pods -n openshift-kube-apiserver -l app=openshift-kube-apiserver --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n          echo \"No matching pods found on the current node.\"\n          else\n          # echo $i static-pod-certs\n          oc exec -n openshift-kube-apiserver \"$POD_NAME\" -c kube-apiserver -- find /etc/kubernetes/static-pod-certs -type d -wholename '*/secrets*' -exec stat -c \"$i %n %U:%G\" {} \\;\n          oc exec -n openshift-kube-apiserver \"$POD_NAME\" -c kube-apiserver -- find /etc/kubernetes/static-pod-certs -type f -wholename '*/secrets*' -exec stat -c \"$i %n %U:%G\" {} \\;\n          # echo $i static-pod-resources\n          oc exec -n openshift-kube-apiserver \"$POD_NAME\" -c kube-apiserver -- find /etc/kubernetes/static-pod-resources -type d -wholename '*/secrets*' -exec stat -c \"$i %n %U:%G\" {} \\;\n          oc exec -n openshift-kube-apiserver \"$POD_NAME\" -c kube-apiserver -- find /etc/kubernetes/static-pod-resources -type f -wholename '*/secrets*' -exec stat -c \"$i %n %U:%G\" {} \\;\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          No remediation required; file permissions are managed by the operator.\n        scored: true\n\n      - id: 1.1.20\n        text: \"Ensure that the OpenShift PKI certificate file permissions are set to 600 or more restrictive (Manual)\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n\n          # Get the pod name in the openshift-kube-apiserver namespace\n          POD_NAME=$(oc get pods -n openshift-kube-apiserver -l app=openshift-kube-apiserver --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n          echo \"No matching pods found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-kube-apiserver \"$POD_NAME\" -c kube-apiserver -- find /etc/kubernetes/static-pod-certs -type f -wholename '*/secrets/*.crt' -exec stat -c \"$POD_NAME %n permissions=%a\" {} \\;\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          No remediation required; file permissions are managed by the operator.\n        scored: true\n\n      - id: 1.1.21\n        text: \"Ensure that the OpenShift PKI key file permissions are set to 600 (Manual)\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n\n          # Get the pod name in the openshift-kube-apiserver namespace\n          POD_NAME=$(oc get pods -n openshift-kube-apiserver -l app=openshift-kube-apiserver --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n          echo \"No matching pods found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-kube-apiserver \"$POD_NAME\" -c kube-apiserver -- find /etc/kubernetes/static-pod-certs -type f -wholename '*/secrets/*.key' -exec stat -c \"$POD_NAME %n permissions=%a\" {} \\;\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          No remediation required; file permissions are managed by the operator.\n        scored: true\n\n  - id: 1.2\n    text: \"API Server\"\n    checks:\n      - id: 1.2.1\n        text: \"Ensure that anonymous requests are authorized (Manual)\"\n        audit: |\n          found=0\n\n          echo \"# ClusterRoleBindings granting permissions to system:unauthenticated\"\n          crb_out=\"$(oc get clusterrolebindings -o json 2>/dev/null \\\n            | jq -r '.items[]\n              | select(.subjects[]? | select(.kind==\"Group\" and .name==\"system:unauthenticated\"))\n              | .metadata.name + \" -> \" + .roleRef.kind + \"/\" + .roleRef.name' \\\n            | sort -u)\"\n          if [ -n \"$crb_out\" ]; then\n            echo \"$crb_out\"\n            found=1\n          else\n            echo \"(none)\"\n          fi\n\n          echo\n          echo \"# Namespaced RoleBindings granting permissions to system:unauthenticated\"\n          rb_out=\"$(oc get rolebindings -A -o json 2>/dev/null \\\n            | jq -r '.items[]\n              | select(.subjects[]? | select(.kind==\"Group\" and .name==\"system:unauthenticated\"))\n              | (.metadata.namespace + \"/\" + .metadata.name) + \" -> \" + .roleRef.kind + \"/\" + .roleRef.name' \\\n            | sort -u)\"\n          if [ -n \"$rb_out\" ]; then\n            echo \"$rb_out\"\n            found=1\n          else\n            echo \"(none)\"\n          fi\n\n          # Provide a simple flag for the test harness\n          if [ $found -eq 1 ]; then\n            echo \"unauthenticated_bindings_present\"\n          else\n            echo \"unauthenticated_bindings_missing\"\n          fi\n        tests:\n          test_items:\n            - flag: \"unauthenticated_bindings_present\"\n              set: true\n        remediation: |\n          None required. The default configuration should not be modified.\n        scored: true\n\n      - id: 1.2.2\n        text: \"Ensure that the --basic-auth-file argument is not set (Manual)\"\n        audit: |\n          oc -n openshift-kube-apiserver get cm config -o yaml | grep --color \"basic-auth\"\n          oc -n openshift-apiserver get cm config -o yaml | grep --color \"basic-auth\"\n          oc get clusteroperator authentication | awk '$3 != \"AVAILABLE\" { if ($3){print \"available=true\"}else{print \"available=false\"} }'\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"basic-auth-file\"\n              set: false\n            - flag: \"available\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          None required. --basic-auth-file cannot be configured on OpenShift.\n        scored: true\n\n      - id: 1.2.3\n        text: \"Ensure that the --token-auth-file parameter is not set (Manual)\"\n        audit: |\n          oc get configmap config -n openshift-kube-apiserver -ojson | jq -r '.data[\"config.yaml\"]' | jq '.apiServerArguments'\n          oc get configmap config -n openshift-apiserver -ojson | jq -r '.data[\"config.yaml\"]' | jq '.apiServerArguments'\n          oc get kubeapiservers.operator.openshift.io cluster -o json | jq '.spec.observedConfig.apiServerArguments'\n          oc get clusteroperator authentication | awk '$3 != \"AVAILABLE\" { if ($3){print \"available=true\"}else{print \"available=false\"} }'\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"token-auth-file\"\n              set: false\n            - flag: \"available\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          None is required.\n        scored: true\n\n      - id: 1.2.4\n        text: \"Use HTTPS for kubelet connections (Manual)\"\n        audit: |\n          CFG=$(oc -n openshift-kube-apiserver get cm config -o jsonpath='{.data.config\\.yaml}')\n\n          # Extract kubelet client cert/key paths (support both layouts)\n          CERT_FILE=$(printf '%s\\n' \"$CFG\" \\\n          | grep -Eo '/etc/kubernetes/static-pod-(resources/kube-apiserver-certs|certs)/secrets/kubelet-client/tls\\.crt' \\\n          | head -n1)\n\n          KEY_FILE=$(printf '%s\\n' \"$CFG\" \\\n          | grep -Eo '/etc/kubernetes/static-pod-(resources/kube-apiserver-certs|certs)/secrets/kubelet-client/tls\\.key' \\\n          | head -n1)\n\n          # 1) pass/fail on presence of both files\n          if [ -n \"$CERT_FILE\" ] && [ -n \"$KEY_FILE\" ]; then\n            echo \"pass\"\n          else\n            echo \"fail\"\n          fi\n          KUBELET_HTTPS=$(printf '%s\\n' \"$CFG\" \\\n            | grep -Eo '(^|[[:space:]])kubelet-https:[[:space:]]*(true|false)' \\\n            | awk -F: '{print $2}' \\\n            | tr -d '[:space:]' \\\n            | head -n1)\n\n          if [ \"$KUBELET_HTTPS\" = \"false\" ]; then\n            echo \"false\"\n          else\n           echo \"true\"\n          fi\n\n          oc -n openshift-apiserver describe secret serving-cert | grep -E 'tls\\.crt|tls\\.key|Type:'\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"pass\"\n            - flag: \"true\"\n            - flag: \"kubernetes.io/tls\"\n            - flag: \"tls.crt\"\n            - flag: \"tls.key\"\n        remediation: |\n          OpenShift does not use the legacy --kubelet-https flag; TLS is enforced via\n          kubelet client cert/key arguments and cluster CAs. Ensure:\n            - apiServerArguments.kubelet-client-certificate[0] points to a real file\n            - apiServerArguments.kubelet-client-key[0] points to a real file\n            - The openshift-apiserver 'serving-cert' secret is type kubernetes.io/tls and contains tls.crt and tls.key\n        scored: false\n\n      - id: 1.2.5\n        text: \"Ensure that the kubelet uses certificates to authenticate (Manual)\"\n        audit: |\n          oc get configmap config -n openshift-kube-apiserver -ojson | jq -r '.data[\"config.yaml\"]' | jq '.apiServerArguments[\"kubelet-client-certificate\"]'\n          oc get configmap config -n openshift-kube-apiserver -ojson | jq -r'.data[\"config.yaml\"]' | jq '.apiServerArguments[\"kubelet-client-key\"]'\n          oc -n openshift-apiserver describe secret serving-cert\n        tests:\n          test_items:\n            - flag: \"/etc/kubernetes/static-pod-certs/secrets/kubelet-client/tls.crt\"\n            - flag: \"/etc/kubernetes/static-pod-certs/secrets/kubelet-client/tls.key\"\n            - flag: \"kubernetes.io/tls\"\n        remediation: |\n          No remediation is required.\n          OpenShift automatically manages kubelet authentication using X.509 certificates issued by the internal platform CA.\n          Manual modification of these certificates is not supported and can disrupt platform components.\n        scored: true\n\n      - id: 1.2.6\n        text: \"Verify that the kubelet certificate authority is set as appropriate (Manual)\"\n        audit: |\n          oc get configmap config -n openshift-kube-apiserver -ojson \\\n            | jq -r '.data[\"config.yaml\"]' \\\n            | jq '.apiServerArguments[\"kubelet-certificate-authority\"]'\n        tests:\n          test_items:\n            - flag: \"/etc/kubernetes/static-pod-resources/configmaps/kubelet-serving-ca/ca-bundle.crt\"\n        remediation: |\n          No remediation is required.\n          OpenShift uses internal X.509 certificates and platform-managed CAs to verify kubelet server identities.\n          This is not user-configurable and should not be modified.\n        scored: true\n\n      - id: 1.2.7\n        text: \"Ensure that the --authorization-mode argument is not set to AlwaysAllow (Manual)\"\n        audit: |\n          oc get configmap config -n openshift-kube-apiserver -o json \\\n            | jq -r '.data[\"config.yaml\"]' \\\n            | jq '.apiServerArguments[\"authorization-mode\"]'\n        audit_config: |\n          oc get configmap config -n openshift-kube-apiserver -ojson | jq -r '.data[\"config.yaml\"]' | jq '.apiServerArguments'\n        tests:\n          bin_op: or\n          test_items:\n            - path: \"{.authorization-mode}\"\n              compare:\n                op: nothave\n                value: \"AlwaysAllow\"\n            - path: \"{.authorization-mode}\"\n              flag: \"authorization-mode\"\n              set: false\n        remediation: |\n          No remediation required.\n          OpenShift does not support the 'AlwaysAllow' authorization mode.\n          The API server is bootstrapped with secure authorization mechanisms including RBAC and Node by default.\n        scored: true\n\n      - id: 1.2.8\n        text: \"Verify that RBAC is enabled (Manual)\"\n        audit: |\n          oc get configmap config -n openshift-kube-apiserver -o json \\\n            | jq -r '.data[\"config.yaml\"]' \\\n            | jq '.apiServerArguments[\"authorization-mode\"]'\n        audit_config: |\n          oc get configmap config -n openshift-kube-apiserver -ojson | jq -r '.data[\"config.yaml\"]' | jq '.apiServerArguments'\n        tests:\n          bin_op: or\n          test_items:\n            - path: \"{.authorization-mode}\"\n              compare:\n                op: has\n                value: \"RBAC\"\n            - path: \"{.authorization-mode}\"\n              flag: \"authorization-mode\"\n              set: false\n        remediation: |\n          No remediation is required.\n          OpenShift is configured at bootstrap time to use Role-Based Access Control (RBAC) as the default authorization mode.\n          RBAC is always enabled, and cannot be disabled through configuration.\n        scored: true\n\n\n      - id: 1.2.9\n        text: \"Ensure that the APIPriorityAndFairness feature gate is enabled (Manual)\"\n        audit: |\n          oc get kubeapiservers.operator.openshift.io cluster -o json | jq '.spec.observedConfig.apiServerArguments'\n          oc -n openshift-kube-apiserver get configmap config -o json | jq -r '.data.\"config.yaml\"' | jq '.apiServerArguments.\"enable-admission-plugins\"'\n          oc get kubeapiservers.operator.openshift.io cluster -o json | jq -r '.spec.unsupportedConfigOverrides'\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"APIPriorityAndFairness=true\"\n            - flag: \"EventRateLimit\"\n              set: false\n        remediation: |\n          No remediation is required\n        scored: true\n\n      - id: 1.2.10\n        text: \"Ensure that the admission control plugin AlwaysAdmit is not set (Manual)\"\n        audit: |\n          oc -n openshift-kube-apiserver get configmap config -o json | jq -r '.data.\"config.yaml\"' | jq '.apiServerArguments.\"enable-admission-plugins\"'\n        tests:\n          test_items:\n            - flag: \"AlwaysAdmit\"\n              set: false\n        remediation: |\n          No remediation is required. The AlwaysAdmit admission controller cannot be enabled in OpenShift.\n        scored: true\n\n      - id: 1.2.11\n        text: \"Ensure that the admission control plugin AlwaysPullImages is set (Manual)\"\n        audit: |\n          oc -n openshift-kube-apiserver get configmap config -o json | jq -r '.data.\"config.yaml\"' | jq '.apiServerArguments.\"enable-admission-plugins\"'\n        tests:\n          test_items:\n            - flag: \"AlwaysPullImages\"\n              set: false\n        remediation: |\n          None required.\n        scored: true\n\n      - id: 1.2.12\n        text: \"Ensure that the admission control plugin ServiceAccount is set (Manual)\"\n        audit: |\n          oc -n openshift-kube-apiserver get configmap config -o json | jq -r '.data.\"config.yaml\"' | jq '.apiServerArguments.\"enable-admission-plugins\"'\n        tests:\n          test_items:\n            - flag: \"ServiceAccount\"\n              set: true\n        remediation: |\n          None required. OpenShift is configured to use service accounts by default.\n        scored: true\n\n      - id: 1.2.13\n        text: \"Ensure that the admission control plugin NamespaceLifecycle is set (Manual)\"\n        audit: |\n          oc -n openshift-kube-apiserver get configmap config -o json | jq -r '.data.\"config.yaml\"' | jq '.apiServerArguments.\"enable-admission-plugins\"'\n          output=$(oc -n openshift-kube-apiserver get configmap config -o json | jq -r '.data.\"config.yaml\"' | jq '.apiServerArguments.\"enable-admission-plugins\"')\n          [ \"$output\" == \"null\" ] && echo \"ocp 4.5 has NamespaceLifecycle compiled\" || echo $output\n        tests:\n          test_items:\n            - flag: \"NamespaceLifecycle\"\n        remediation: |\n          Ensure that the --disable-admission-plugins parameter does not include NamespaceLifecycle.\n        scored: true\n\n      - id: 1.2.14\n        text: \"Ensure that the admission control plugin SecurityContextConstraint is set (Manual)\"\n        audit: |\n          oc -n openshift-kube-apiserver get configmap config -o json | jq -r '.data.\"config.yaml\"' | jq '.apiServerArguments.\"enable-admission-plugins\"'\n          output=$(oc -n openshift-kube-apiserver get configmap config -o json | jq -r '.data.\"config.yaml\"' | jq '.apiServerArguments.\"enable-admission-plugins\"')\n          [ \"$output\" == \"null\" ] && echo \"ocp 4.5 has SecurityContextConstraint compiled\" || echo $output\n        tests:\n          test_items:\n            - flag: \"security.openshift.io/SecurityContextConstraint\"\n        remediation: |\n          None required. Security Context Constraints are enabled by default in OpenShift and cannot be disabled.\n        scored: true\n\n      - id: 1.2.15\n        text: \"Ensure that the admission control plugin NodeRestriction is set (Manual)\"\n        audit: |\n          oc -n openshift-kube-apiserver get configmap config -o json | jq -r '.data.\"config.yaml\"' | jq '.apiServerArguments.\"enable-admission-plugins\"'\n          output=$(oc -n openshift-kube-apiserver get configmap config -o json | jq -r '.data.\"config.yaml\"' | jq '.apiServerArguments.\"enable-admission-plugins\"')\n          [ \"$output\" == \"null\" ] && echo \"ocp 4.5 has NodeRestriction compiled\" || echo $output\n        tests:\n          test_items:\n            - flag: \"NodeRestriction\"\n        remediation: |\n          The NodeRestriction plugin cannot be disabled.\n        scored: true\n\n      - id: 1.2.16\n        text: \"Ensure that the --insecure-bind-address argument is not set (manual)\"\n        audit: |\n          # Get the insecure-bind-address value\n          insecure_bind_address=$(oc get kubeapiservers.operator.openshift.io cluster -ojson \\\n            | jq -r '.spec.observedConfig.apiServerArguments[\"insecure-bind-address\"][]?')\n\n          # Get port from openshift-kube-apiserver\n          kube_api_port=$(oc -n openshift-kube-apiserver get endpoints -o jsonpath='{.items[*].subsets[*].ports[*].port}')\n\n          # Get port from openshift-apiserver\n          openshift_api_port=$(oc -n openshift-apiserver get endpoints -o jsonpath='{.items[*].subsets[*].ports[*].port}')\n\n          # Evaluate logic\n          [[ -z \"$insecure_bind_address\" ]] && \\\n          [[ \"$kube_api_port\" == *\"6443\"* ]] && \\\n          [[ \"$openshift_api_port\" == *\"8443\"* ]] && echo \"pass\" || echo \"fail\"\n        tests:\n          test_items:\n            - flag: \"pass\"\n        remediation: |\n          No remediation is required.\n          By default, OpenShift uses secure HTTPS ports (6443 and 8443) for all API communications.\n          The API servers are not configured to expose insecure ports and are isolated within the pod network.\n        scored: true\n\n\n      - id: 1.2.17\n        text: \"Ensure that the --insecure-port argument is set to 0 (Manual)\"\n        audit: |\n          oc -n openshift-kube-apiserver get endpoints -o jsonpath='{.items[*].subsets[*].ports[*].port}'\n        tests:\n          test_items:\n            - flag: \"6443\"\n        remediation: |\n          None required. The configuration is managed by the API server operator.\n        scored: true\n\n      - id: 1.2.18\n        text: \"Ensure that the --secure-port argument is not set to 0 (Manual)\"\n        audit: |\n          BIND_ADDR=$(oc get kubeapiservers.operator.openshift.io cluster -o json \\\n            | jq -r '.spec.observedConfig.servingInfo.bindAddress')\n\n          PORTS=$(oc get pods -n openshift-kube-apiserver -l app=openshift-kube-apiserver \\\n            -o jsonpath='{.items[*].spec.containers[?(@.name==\"kube-apiserver\")].ports[*].containerPort}')\n\n          if [ \"$BIND_ADDR\" = \"0.0.0.0:6443\" ] && echo \"$PORTS\" | grep -q '\\b6443\\b'; then\n            echo \"pass\"\n          else\n            echo \"fail\"\n          fi\n        tests:\n          test_items:\n            - flag: \"pass\"\n        remediation: |\n          None required. OpenShift serves the API securely over port 6443 with TLS, authentication, and authorization.\n          The insecure API port is not exposed or configurable by default.\n        scored: true\n\n      - id: 1.2.19\n        text: \"Ensure that the healthz endpoint is protected by RBAC (Manual)\"\n        type: manual\n        remediation: |\n          None required as profiling data is protected by RBAC.\n        scored: false\n\n      - id: 1.2.20\n        text: \"Ensure that the --audit-log-path argument is set (Manual)\"\n        audit: |\n          # Get kube-apiserver audit log path\n          kube_path=$(oc get configmap config -n openshift-kube-apiserver -ojson \\\n            | jq -r '.data[\"config.yaml\"]' \\\n            | jq -r '.apiServerArguments[\"audit-log-path\"][]?')\n\n          # Get OpenShift apiserver audit log path\n          os_path=$(oc get configmap config -n openshift-apiserver -ojson \\\n            | jq -r '.data[\"config.yaml\"]' \\\n            | jq -r '.apiServerArguments[\"audit-log-path\"][]?')\n\n          # Check if log file exists in kube-apiserver pod\n          kube_pod=$(oc get pods -n openshift-kube-apiserver -l app=openshift-kube-apiserver -o jsonpath='{.items[0].metadata.name}')\n          oc rsh -n openshift-kube-apiserver -c kube-apiserver $kube_pod ls \"$kube_path\" >/dev/null 2>&1\n          kube_exists=$?\n\n          # Check if log file exists in openshift-apiserver pod\n          os_pod=$(oc get pods -n openshift-apiserver -l apiserver=true -o jsonpath='{.items[0].metadata.name}')\n          oc rsh -n openshift-apiserver $os_pod ls \"$os_path\" >/dev/null 2>&1\n          os_exists=$?\n\n          # Evaluate all conditions\n          [[ \"$kube_path\" == \"/var/log/kube-apiserver/audit.log\" ]] && \\\n          [[ \"$os_path\" == \"/var/log/openshift-apiserver/audit.log\" ]] && \\\n          [[ $kube_exists -eq 0 ]] && \\\n          [[ $os_exists -eq 0 ]] && echo \"pass\" || echo \"fail\"\n        tests:\n          test_items:\n            - flag: \"pass\"\n        remediation: |\n          No remediation is required.\n          OpenShift manages audit logging automatically via the apiserver configuration.\n          By default, the audit log paths are:\n          - /var/log/kube-apiserver/audit.log\n          - /var/log/openshift-apiserver/audit.log\n        scored: true\n\n      - id: 1.2.21\n        text: \"Ensure that the audit logs are forwarded off the cluster for retention (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the documentation for log forwarding. Forwarding logs to third party systems\n          https://docs.openshift.com/container-platform/4.5/logging/cluster-logging-external.html\n        scored: false\n\n      - id: 1.2.22\n        text: \"Ensure that the maximumRetainedFiles argument is set to 10 or as appropriate (Manual)\"\n        audit: |\n          VALUE=$(oc get configmap config -n openshift-kube-apiserver -ojson \\\n            | jq -r '.data[\"config.yaml\"]' \\\n            | jq -r '.apiServerArguments[\"audit-log-maxbackup\"][0] // empty')\n\n          if [ -n \"$VALUE\" ] && [ \"$VALUE\" -ge 10 ]; then\n            echo \"pass (current=$VALUE)\"\n          else\n            echo \"fail (current=$VALUE)\"\n          fi\n        tests:\n          test_items:\n            - flag: \"pass\"\n        remediation: |\n          No remediation required.\n          By default, OpenShift retains 10 audit log backup files.\n          This provides sufficient log history for incident investigation and audit review.\n        scored: true\n\n      - id: 1.2.23\n        text: \"Ensure that the maximumFileSizeMegabytes argument is set to 100 (Manual)\"\n        audit: |\n          VALUE=$(oc get configmap config -n openshift-kube-apiserver -ojson \\\n            | jq -r '.data[\"config.yaml\"]' \\\n            | jq -r '.apiServerArguments[\"audit-log-maxsize\"][0] // empty')\n\n          if [ -n \"$VALUE\" ] && [ \"$VALUE\" -ge 100 ]; then\n            echo \"pass (current=$VALUE)\"\n          else\n            echo \"fail (current=$VALUE)\"\n          fi\n        tests:\n          test_items:\n            - flag: \"pass\"\n        remediation: |\n          Set the audit-log-maxsize parameter to 100 or as an appropriate number.\n          maximumFileSizeMegabytes: 100\n        scored: true\n\n      - id: 1.2.24\n        text: \"Ensure that the --request-timeout argument is set (Manual)\"\n        audit: |\n          VALUE=$(oc get configmap config -n openshift-kube-apiserver -ojson \\\n            | jq -r '.data[\"config.yaml\"]' \\\n            | jq -r '.apiServerArguments[\"min-request-timeout\"][0] // empty')\n\n          if [ -n \"$VALUE\" ] && [ \"$VALUE\" -eq 3600 ]; then\n            echo \"pass (current=$VALUE)\"\n          else\n            echo \"fail (current=$VALUE)\"\n          fi\n        tests:\n          test_items:\n            - flag: \"pass\"\n        remediation: |\n          TBD\n        scored: true\n\n      - id: 1.2.25\n        text: \"Ensure that the --service-account-lookup argument is set to true (Manual)\"\n        audit: |\n          oc get configmap config -n openshift-kube-apiserver -ojson | jq -r\n          '.data[\"config.yaml\"]' | jq '.apiServerArguments.\"service-account-lookup\"[]'\n        tests:\n          test_items:\n            - flag: \"true\"\n        remediation: |\n          TBD\n        scored: true\n\n      - id: 1.2.26\n        text: \"Ensure that the --service-account-key-file argument is set as appropriate (Manual)\"\n        audit: |\n          oc get configmap config -n openshift-kube-apiserver -ojson | jq -r '.data[\"config.yaml\"]' | jq -r .serviceAccountPublicKeyFiles[]\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"/etc/kubernetes/static-pod-resources/configmaps/sa-token-signing-certs\"\n            - flag: \"/etc/kubernetes/static-pod-resources/configmaps/bound-sa-token-signing-certs\"\n        remediation: |\n          The OpenShift API server does not use the service-account-key-file argument.\n          The ServiceAccount token authenticator is configured with serviceAccountConfig.publicKeyFiles.\n          OpenShift does not reuse the apiserver TLS key. This is not configurable.\n        scored: true\n\n      - id: 1.2.27\n        text: \"Ensure that the --etcd-certfile and --etcd-keyfile arguments are set as appropriate (Manual)\"\n        audit: |\n          oc get configmap config -n openshift-kube-apiserver -ojson \\\n            | jq -r '.data[\"config.yaml\"]' \\\n            | jq -r '.apiServerArguments[\"etcd-certfile\"][]?'\n\n          oc get configmap config -n openshift-kube-apiserver -ojson \\\n            | jq -r '.data[\"config.yaml\"]' \\\n            | jq -r '.apiServerArguments[\"etcd-keyfile\"][]?'\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"/etc/kubernetes/static-pod-resources/secrets/etcd-client/tls.crt\"\n            - flag: \"/etc/kubernetes/static-pod-resources/secrets/etcd-client/tls.key\"\n        remediation: |\n          No remediation is required.\n          OpenShift automatically manages X.509 client certificates and TLS encryption for secure communication with etcd.\n          These settings are handled by the platform and should not be manually modified.\n        scored: true\n\n      - id: 1.2.28\n        text: \"Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Manual)\"\n        audit: |\n          oc get configmap config -n openshift-kube-apiserver -ojson \\\n            | jq -r '.data[\"config.yaml\"]' \\\n            | jq -r '.apiServerArguments[\"tls-cert-file\"][]?'\n\n          oc get configmap config -n openshift-kube-apiserver -ojson \\\n            | jq -r '.data[\"config.yaml\"]' \\\n            | jq -r '.apiServerArguments[\"tls-private-key-file\"][]?'\n\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"/etc/kubernetes/static-pod-certs/secrets/service-network-serving-certkey/tls.crt\"\n            - flag: \"/etc/kubernetes/static-pod-certs/secrets/service-network-serving-certkey/tls.key\"\n        remediation: |\n          No remediation is required. OpenShift automatically configures the API server with valid X.509 certificates and TLS keys.\n          These are used to encrypt traffic between the API server and clients, including kubelets and users.\n          Certificate rotation and lifecycle management are handled by the OpenShift platform.\n        scored: true\n\n\n      - id: 1.2.29\n        text: \"Ensure that the --client-ca-file argument is set as appropriate (Manual)\"\n        audit: |\n          oc get configmap config -n openshift-kube-apiserver -ojson | \\\n          jq -r '.data[\"config.yaml\"]' | \\\n          jq -r .servingInfo.clientCA\n        tests:\n          test_items:\n            - flag: \"/etc/kubernetes/static-pod-certs/configmaps/client-ca/ca-bundle.crt\"\n        remediation: |\n          OpenShift automatically manages TLS authentication for the API server communication with the node/kublet.\n          This is not configurable. You may optionally set a custom default certificate to be used by the API\n          server when serving content in order to enable clients to access the API server at a different host name\n          or without the need to distribute the cluster-managed certificate authority (CA) certificates to the clients.\n\n          User-provided certificates must be provided in a kubernetes.io/tls type Secret in the openshift-config namespace.\n          Update the API server cluster configuration,\n          the apiserver/cluster resource, to enable the use of the user-provided certificate.\n        scored: true\n\n      - id: 1.2.30\n        text: \"Ensure that the --etcd-cafile argument is set as appropriate (Manual)\"\n        audit: |\n          oc get configmap config -n openshift-kube-apiserver -ojson | \\\n            jq -r '.data[\"config.yaml\"]' | \\\n            jq -r '.apiServerArguments[\"etcd-cafile\"]'\n        tests:\n          test_items:\n            - flag: \"/etc/kubernetes/static-pod-resources/configmaps/etcd-serving-ca/ca-bundle.crt\"\n        remediation: |\n          None required. OpenShift generates the etcd-cafile and sets the arguments appropriately in the API server. Communication with etcd is secured by the etcd serving CA.\n        scored: true\n\n      - id: 1.2.31\n        text: \"Ensure that encryption providers are appropriately configured (Manual)\"\n        audit: |\n          oc get openshiftapiserver -o=jsonpath='{range .items[0].status.conditions[?(@.type==\"Encrypted\")]}{.reason}{\"\\n\"}{.message}{\"\\n\"}'\n        tests:\n          test_items:\n            - flag: \"EncryptionCompleted\"\n        remediation: |\n          Follow the Kubernetes documentation and configure a EncryptionConfig file.\n          In this file, choose aescbc, kms or secretbox as the encryption provider.\n        scored: true\n\n      - id: 1.2.32\n        text: \"Ensure that the API Server only makes use of Strong Cryptographic Ciphers (Manual)\"\n        type: manual\n        audit: |\n          oc get cm -n openshift-authentication v4-0-config-system-cliconfig -o jsonpath='{.data.v4\\-0\\-config\\-system\\-cliconfig}' | jq .servingInfo\n          oc get kubeapiservers.operator.openshift.io cluster -o json |jq.spec.observedConfig.servingInfo\n          oc get openshiftapiservers.operator.openshift.io cluster -o json |jq.spec.observedConfig.servingInfo\n          oc describe --namespace=openshift-ingress-operator ingresscontroller/default\n        remediation: |\n          Verify that the tlsSecurityProfile is set to the value you chose.\n          Note: The HAProxy Ingress controller image does not support TLS 1.3\n          and because the Modern profile requires TLS 1.3, it is not supported.\n          The Ingress Operator converts the Modern profile to Intermediate.\n          The Ingress Operator also converts the TLS 1.0 of an Old or Custom profile to 1.1,\n          and TLS 1.3 of a Custom profile to 1.2.\n        scored: false\n\n      - id: 1.2.33\n        text: \"Ensure unsupported configuration overrides are not used (Manual)\"\n        audit: |\n          oc get kubeapiserver/cluster -o jsonpath='{.spec.unsupportedConfigOverrides}'\n        tests:\n          test_items:\n            - flag: \"null\"\n        remediation: |\n          No remediation is required.\n          OpenShift has deprecated and disabled unsupportedConfigOverrides.\n          This field should remain null and must not be used in any supported configuration.\n        scored: true\n\n  - id: 1.3\n    text: \"Controller Manager\"\n    checks:\n\n      - id: 1.3.1\n        text: \"Ensure that controller manager healthz endpoints are protected by RBAC (Manual)\"\n        type: manual\n        audit: |\n          # Verify configuration for ports, livenessProbe, readinessProbe, healthz\n          oc -n openshift-kube-controller-manager get cm kube-controller-manager-pod -o json | jq -r '.data.\"pod.yaml\"' | jq '.spec.containers'\n          # Verify endpoints\n          oc -n openshift-kube-controller-manager describe endpoints\n          # Test to validate RBAC enabled on the controller endpoint; check with non-admin role\n          oc project openshift-kube-controller-manage\n          POD=$(oc get pods -n openshift-kube-controller-manager -l app=kube-controller-manager -o jsonpath='{.items[0].metadata.name}')\n          PORT=$(oc get pods -n openshift-kube-controller-manager -l app=kube-controller-manager -o jsonpath='{.items[0].spec.containers[0].ports[0].hostPort}')\n          # Following should return 403 Forbidden\n          oc rsh -n openshift-kube-controller-manager ${POD} curl https://localhost:${PORT}/metrics -k\n          # Create a service account to test RBAC\n          oc create -n openshift-kube-controller-manager sa permission-test-sa\n          # Should return 403 Forbidden\n          SA_TOKEN=$(oc sa -n openshift-kube-controller-manager get-token permission-test-sa)\n          oc rsh -n openshift-kube-controller-manager ${POD} curl https://localhost:${PORT}/metrics -H \"Authorization: Bearer $SA_TOKEN\" -k\n          # Cleanup\n          oc delete -n openshift-kube-controller-manager sa permission-test-sa\n          # As cluster admin, should succeed\n          CLUSTER_ADMIN_TOKEN=$(oc whoami -t)\n          oc rsh -n openshift-kube-controller-manager ${POD} curl https://localhost:${PORT}/metrics -H \"Authorization: Bearer $CLUSTER_ADMIN_TOKEN\" -k\n        remediation: |\n          None required; profiling is protected by RBAC.\n        scored: false\n\n      - id: 1.3.2\n        text: \"Ensure that the --use-service-account-credentials argument is set to true (Manual)\"\n        audit: |\n          oc get configmaps config -n openshift-kube-controller-manager -ojson | \\\n          jq -r '.data[\"config.yaml\"]' | \\\n          jq -r '.extendedArguments[\"use-service-account-credentials\"][]'\n        tests:\n          test_items:\n            - flag: \"true\"\n        remediation: |\n          The OpenShift Controller Manager operator manages and updates the OpenShift Controller Manager.\n          The Kubernetes Controller Manager operator manages and updates the Kubernetes Controller Manager deployed on top of OpenShift.\n          This operator is configured via KubeControllerManager custom resource.\n        scored: true\n\n      - id: 1.3.3\n        text: \"Ensure that the --service-account-private-key-file argument is set as appropriate (Manual)\"\n        audit: |\n          oc get configmaps config -n openshift-kube-controller-manager -ojson | \\\n            jq -r '.data[\"config.yaml\"]' | \\\n            jq -r '.extendedArguments[\"service-account-private-key-file\"][]'\n        tests:\n          test_items:\n            - flag: \"/etc/kubernetes/static-pod-resources/secrets/service-account-private-key/service-account.key\"\n        remediation: |\n          None required.\n          OpenShift manages the service account credentials for the scheduler automatically.\n        scored: true\n\n      - id: 1.3.4\n        text: \"Ensure that the --root-ca-file argument is set as appropriate (Manual)\"\n        audit: |\n          oc get configmaps config -n openshift-kube-controller-manager -ojson | \\\n            jq -r '.data[\"config.yaml\"]' | \\\n            jq -r '.extendedArguments[\"root-ca-file\"][]'\n        tests:\n          test_items:\n            - flag: \"/etc/kubernetes/static-pod-resources/configmaps/serviceaccount-ca/ca-bundle.crt\"\n        remediation: |\n          None required.\n          Certificates for OpenShift platform components are automatically created and rotated by the OpenShift Container Platform.\n        scored: true\n\n      - id: 1.3.5\n        text: \"Ensure that the --bind-address argument is set to 127.0.0.1 (Manual)\"\n        audit: |\n          oc get configmaps config -n openshift-kube-controller-manager -ojson \\\n            | jq -r '.data[\"config.yaml\"]' \\\n            | jq -r '.extendedArguments[\"secure-port\"][]?'\n\n          export POD=$(oc get pods -n openshift-kube-controller-manager -l app=kube-controller-manager -o jsonpath='{.items[0].metadata.name}')\n          oc rsh -n openshift-kube-controller-manager -c kube-controller-manager $POD curl -k -s -o /dev/null -w \"%{http_code}\" https://localhost:10257/metrics\n          unset POD\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"10257\"\n            - flag: \"403\"\n        remediation: |\n          No remediation is required.\n          By default, OpenShift does not expose an insecure bind address.\n          The kube-controller-manager uses secure-port 10257 and restricts unauthenticated access to the /metrics endpoint.\n        scored: true\n\n\n  - id: 1.4\n    text: \"Scheduler\"\n    checks:\n      - id: 1.4.1\n        text: \"Ensure that the healthz endpoints for the scheduler are protected by RBAC (Manual)\"\n        type: manual\n        audit: |\n          # check configuration for ports, livenessProbe, readinessProbe, healthz\n          oc -n openshift-kube-scheduler get cm kube-scheduler-pod -o json | jq -r '.data.\"pod.yaml\"' | jq '.spec.containers'\n          # Test to verify endpoints\n          oc -n openshift-kube-scheduler describe endpoints\n          # Test to validate RBAC enabled on the scheduler endpoint; check with non-admin role\n          oc project openshift-kube-scheduler\n          POD=$(oc get pods -l app=openshift-kube-scheduler -o jsonpath='{.items[0].metadata.name}')\n          PORT=$(oc get pod $POD -o jsonpath='{.spec.containers[0].livenessProbe.httpGet.port}')\n          # Should return 403 Forbidden\n          oc rsh ${POD} curl http://localhost:${PORT}/metrics -k\n          # Create a service account to test RBAC\n          oc create sa permission-test-sa\n          # Should return 403 Forbidden\n          SA_TOKEN=$(oc sa get-token permission-test-sa)\n          oc rsh ${POD} curl http://localhost:${PORT}/metrics -H \"Authorization: Bearer $SA_TOKEN\" -k\n          # Cleanup\n          oc delete sa permission-test-sa\n          # As cluster admin, should succeed\n          CLUSTER_ADMIN_TOKEN=$(oc whoami -t)\n          oc rsh ${POD} curl http://localhost:${PORT}/metrics -H \"Authorization: Bearer $CLUSTER_ADMIN_TOKEN\" -k\n        remediation: |\n          A fix to this issue: https://bugzilla.redhat.com/show_bug.cgi?id=1889488 None required.\n          Profiling is protected by RBAC and cannot be disabled.\n        scored: false\n\n      - id: 1.4.2\n        text: \"Verify that the scheduler API service is protected by RBAC (Manual)\"\n        type: manual\n        audit: |\n          echo \"Describing kube-scheduler endpoints...\"\n          oc -n openshift-kube-scheduler describe endpoints\n\n          echo \"Checking pod configuration for kube-scheduler to confirm no --bind-address or insecure arguments...\"\n          oc -n openshift-kube-scheduler get cm kube-scheduler-pod -o json \\\n            | jq -r '.data[\"pod.yaml\"]' \\\n            | jq '.spec.containers[] | select(.name==\"kube-scheduler\") | .args'\n\n          echo \"Testing access to metrics endpoint as unauthenticated user...\"\n          oc project openshift-kube-scheduler\n          export POD=$(oc get pods -l app=openshift-kube-scheduler -o jsonpath='{.items[0].metadata.name}')\n          export POD_IP=$(oc get pods -l app=openshift-kube-scheduler -o jsonpath='{.items[0].status.podIP}')\n          export PORT=$(oc get pod $POD -o jsonpath='{.spec.containers[0].livenessProbe.httpGet.port}')\n          oc rsh $POD curl -k -s -o /dev/null -w \"%{http_code}\" https://$POD_IP:$PORT/metrics\n\n          echo \"Testing access with unprivileged service account...\"\n          oc create sa permission-test-sa\n          export SA_TOKEN=$(oc create token permission-test-sa)\n          oc rsh $POD curl -k -s -o /dev/null -w \"%{http_code}\" https://$POD_IP:$PORT/metrics -H \"Authorization: Bearer $SA_TOKEN\"\n\n          echo \"Testing access with cluster-admin...\"\n          export CLUSTER_ADMIN_TOKEN=$(oc whoami -t)\n          oc rsh $POD curl -k -s -o /dev/null -w \"%{http_code}\" https://$POD_IP:$PORT/metrics -H \"Authorization: Bearer $CLUSTER_ADMIN_TOKEN\"\n\n          # Cleanup\n          unset CLUSTER_ADMIN_TOKEN POD PORT SA_TOKEN POD_IP\n          oc delete sa permission-test-sa\n        remediation: |\n          By default, the --bind-address argument is not present,\n          the readinessProbe and livenessProbe arguments are set to 10251 and the port argument is set to 0.\n          Check the status of this issue: https://bugzilla.redhat.com/show_bug.cgi?id=1889488\n        scored: false\n"
  },
  {
    "path": "cfg/rh-1.4/node.yaml",
    "content": "---\ncontrols:\nversion: rh-1.4\nid: 4\ntext: \"Worker Nodes\"\ntype: \"node\"\ngroups:\n  - id: 4.1\n    text: \"Worker Node Configuration Files\"\n    checks:\n      - id: 4.1.1\n        text: \"Ensure that the kubelet service file permissions are set to 644 or more restrictive (Automated)\"\n        audit: |\n          NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')\n          oc debug node/$NODE_NAME -- chroot /host stat -c \"$NODE_NAME %n permissions=%a\" /etc/systemd/system/kubelet.service 2> /dev/null\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          By default, the kubelet service file has permissions of 644.\n        scored: true\n\n      - id: 4.1.2\n        text: \"Ensure that the kubelet service file ownership is set to root:root (Automated)\"\n        audit: |\n          # Should return root:root for each node\n          NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')\n          oc debug node/$NODE_NAME -- chroot /host stat -c \"$NODE_NAME %n %U:%G\" /etc/systemd/system/kubelet.service 2> /dev/null\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          By default, the kubelet service file has ownership of root:root.\n        scored: true\n\n      - id: 4.1.3\n        text: \"If proxy kube proxy configuration file exists ensure permissions are set to 644 or more restrictive (Manual)\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n          # Get the pod name in the openshift-sdn namespace\n          POD_NAME=$(oc get pods -n openshift-sdn -l app=sdn --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n          echo \"No matching pods found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-sdn \"$POD_NAME\" -- stat -Lc \"$i %n permissions=%a\" /config/kube-proxy-config.yaml  2>/dev/null\n          fi\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              set: true\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          None needed.\n        scored: true\n\n      - id: 4.1.4\n        text: \"If proxy kubeconfig file exists ensure ownership is set to root:root (Manual)\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n          # Get the pod name in the openshift-sdn namespace\n          POD_NAME=$(oc get pods -n openshift-sdn -l app=sdn --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n          echo \"No matching pods found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-sdn \"$POD_NAME\"  -- stat -Lc \"$i %n %U:%G\" /config/kube-proxy-config.yaml  2>/dev/null\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          None required. The configuration is managed by OpenShift operators.\n        scored: true\n\n      - id: 4.1.5\n        text: \"Ensure that the --kubeconfig kubelet.conf file permissions are set to 644 or more restrictive (Manual)\"\n        audit: |\n          # Check permissions\n          NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')\n          oc debug node/$NODE_NAME -- chroot /host stat -c \"$NODE_NAME %n permissions=%a\" /etc/kubernetes/kubelet.conf 2> /dev/null\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          None required.\n        scored: true\n\n      - id: 4.1.6\n        text: \"Ensure that the --kubeconfig kubelet.conf file ownership is set to root:root (Manual)\"\n        audit: |\n          NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')\n          oc debug node/$NODE_NAME -- chroot /host stat -c \"$NODE_NAME %n %U:%G\" /etc/kubernetes/kubelet.conf 2> /dev/null\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          None required.\n        scored: true\n\n      - id: 4.1.7\n        text: \"Ensure that the certificate authorities file permissions are set to 644 or more restrictive\"\n        audit: |\n          NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')\n          oc get --raw /api/v1/nodes/$NODE_NAME/proxy/configz | jq '.kubeletconfig.authentication.x509.clientCAFile'\n          oc debug node/$NODE_NAME -- chroot /host stat -c \"$NODE_NAME permissions=%a\" /etc/kubernetes/kubelet-ca.crt 2> /dev/null\n        tests:\n          test_items:\n            - flag: \"/etc/kubernetes/kubelet-ca.crt\"\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          No remediation required. OpenShift sets /etc/kubernetes/kubelet-ca.crt to 644 by default.\n          If permissions are more permissive than 644, update with: chmod 644 /etc/kubernetes/kubelet-ca.crt\n        scored: true\n\n\n      - id: 4.1.8\n        text: \"Ensure that the client certificate authorities file ownership is set to root:root (Automated)\"\n        audit: |\n          NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')\n          oc debug node/$NODE_NAME -- chroot /host stat -c \"$NODE_NAME %n %U:%G\" /etc/kubernetes/kubelet-ca.crt 2> /dev/null\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          None required.\n        scored: true\n\n      - id: 4.1.9\n        text: \"Ensure that the kubelet --config configuration file has permissions set to 600 or more restrictive (Automated)\"\n        audit: |\n          NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')\n          oc debug node/$NODE_NAME -- chroot /host stat -c \"$NODE_NAME %n permissions=%a\" /var/lib/kubelet/config.json 2> /dev/null\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          None required.\n        scored: true\n\n      - id: 4.1.10\n        text: \"Ensure that the kubelet configuration file ownership is set to root:root (Automated)\"\n        audit: |\n          NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')\n          oc debug node/$NODE_NAME -- chroot /host stat -c \"$NODE_NAME %n %U:%G\" /var/lib/kubelet/config.json 2> /dev/null\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          None required.\n        scored: true\n\n  - id: 4.2\n    text: \"Kubelet\"\n    checks:\n      - id: 4.2.1\n        text: \"Activate Garbage collection in OpenShift Container Platform 4, as appropriate (Manual)\"\n        audit: |\n          echo \"Retrieving and inspecting garbage collection configuration from node-local kubelet configz...\"\n\n          NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')\n          oc get --raw /api/v1/nodes/$NODE_NAME/proxy/configz | jq '.kubeletconfig'\n        tests:\n          test_items:\n            - flag: \"evictionHard\"\n            - flag: \"imageGCHighThresholdPercent\"\n            - flag: \"imageGCLowThresholdPercent\"\n            - flag: \"imageMinimumGCAge\"\n        remediation: |\n          OpenShift manages node garbage collection through KubeletConfig custom resources per MachineConfigPool.\n          To configure or adjust garbage collection thresholds, follow the documentation:\n          https://docs.openshift.com/container-platform/latest/nodes/nodes/nodes-nodes-garbage-collection.html\n\n          Example: Create or modify a KubeletConfig object to include:\n          ---\n          evictionHard:\n            \"memory.available\": \"200Mi\"\n            \"nodefs.available\": \"10%\"\n            \"imagefs.available\": \"15%\"\n          imageGCHighThresholdPercent: 85\n          imageGCLowThresholdPercent: 80\n          imageMinimumGCAge: \"2m0s\"\n\n          Then apply the `KubeletConfig` to the appropriate `MachineConfigPool`.\n        scored: true\n\n      - id: 4.2.2\n        text: \"Ensure that the --anonymous-auth argument is set to false (Automated)\"\n        audit: |\n          echo \"Checking if anonymous-auth is disabled in kubelet configuration on the current node...\"\n\n          NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')\n          oc get --raw /api/v1/nodes/$NODE_NAME/proxy/configz | jq '.kubeletconfig.authentication.anonymous.enabled'\n        tests:\n          test_items:\n            - flag: \"false\"\n        remediation: |\n          By default, OpenShift sets anonymous-auth to false in Kubelet configuration.\n          If this value is found to be true, create or patch a KubeletConfig object with:\n\n          ---\n          kind: KubeletConfig\n          apiVersion: machineconfiguration.openshift.io/v1\n          metadata:\n            name: disable-anonymous-auth\n          spec:\n            kubeletConfig:\n              authentication:\n                anonymous:\n                  enabled: false\n\n          Then apply this KubeletConfig to the appropriate MachineConfigPool.\n          See OpenShift documentation on configuring node-level security settings.\n        scored: true\n\n      - id: 4.2.3\n        text: \"Ensure that the --authorization-mode argument is not set to AlwaysAllow (Automated)\"\n        audit: |\n          echo \"Checking kubelet authorization mode on the current node...\"\n\n          NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')\n          oc get --raw /api/v1/nodes/$NODE_NAME/proxy/configz | jq '.kubeletconfig.authorization.mode'\n        tests:\n          test_items:\n            - flag: AlwaysAllow\n              set: false\n        remediation: |\n          No remediation required. By default, OpenShift uses secure authorization modes such as 'Webhook' and does not allow AlwaysAllow.\n          If AlwaysAllow is found, the node must be reconfigured using a KubeletConfig applied through the appropriate MachineConfigPool.\n        scored: true\n\n\n      - id: 4.2.4\n        text: \"Ensure that the --client-ca-file argument is set as appropriate (Automated)\"\n        audit: |\n          echo \"Checking Kubelet 'clientCAFile' setting on current node...\"\n\n          NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')\n          oc get --raw /api/v1/nodes/$NODE_NAME/proxy/configz \\\n            | jq '.kubeletconfig.authentication.x509.clientCAFile'\n        tests:\n          test_items:\n            - flag: \"/etc/kubernetes/kubelet-ca.crt\"\n        remediation: |\n          No remediation required. OpenShift sets the clientCAFile by default to /etc/kubernetes/kubelet-ca.crt.\n          Manual modification is unsupported and unnecessary as OpenShift manages Kubelet certificate authentication via the Machine Config Operator.\n        scored: true\n\n\n      - id: 4.2.5\n        text: \"Verify that the read only port is not used or is set to 0 (Automated)\"\n        audit: |\n          echo \"Checking 'kubelet-read-only-port' argument in openshift-kube-apiserver config...\"\n\n          oc -n openshift-kube-apiserver get configmap config -o json \\\n            | jq -r '.data[\"config.yaml\"]' \\\n            | yq '.apiServerArguments.\"kubelet-read-only-port\"[0]'\n        tests:\n          test_items:\n            - flag: \"0\"\n        remediation: |\n          No remediation is required if the read-only port is set to 0.\n          If this value is not set to 0 (or the argument is missing), create a KubeletConfig object and apply it to the appropriate MachineConfigPool to disable the read-only port.\n\n          Example KubeletConfig:\n          ---\n          apiVersion: machineconfiguration.openshift.io/v1\n          kind: KubeletConfig\n          metadata:\n            name: disable-readonly-port\n          spec:\n            kubeletConfig:\n              readOnlyPort: 0\n        scored: true\n\n\n      - id: 4.2.6\n        text: \"Ensure that the --streaming-connection-idle-timeout argument is not set to 0 (automated)\"\n        audit: |\n          NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')\n          oc get --raw /api/v1/nodes/$NODE_NAME/proxy/configz \\\n            | jq '.kubeletconfig'\n        tests:\n          test_items:\n            - path: \".streamingConnectionIdleTimeout\"\n              compare:\n                op: noteq\n                value: \"0s\"\n        remediation: |\n          By default, OpenShift sets streamingConnectionIdleTimeout to 4h0m0s.\n          If it is manually set to \"0s\", this disables timeouts — which is insecure.\n\n          To remediate, create a `KubeletConfig` CR with a safer timeout (e.g., 1h0m0s):\n          ---\n          apiVersion: machineconfiguration.openshift.io/v1\n          kind: KubeletConfig\n          metadata:\n            name: set-streaming-timeout\n          spec:\n            kubeletConfig:\n              streamingConnectionIdleTimeout: \"1h0m0s\"\n        scored: true\n\n      - id: 4.2.7\n        text: \"Ensure that the --make-iptables-util-chains argument is set to true (manual)\"\n        audit: |\n          echo \"Checking 'makeIPTablesUtilChains' setting in Kubelet config on current node...\"\n\n          NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')\n          oc get --raw /api/v1/nodes/$NODE_NAME/proxy/configz \\\n            | jq '.kubeletconfig'\n        tests:\n          test_items:\n            - path: \".makeIPTablesUtilChains\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          No remediation is required.\n          By default, OpenShift sets makeIPTablesUtilChains to true.\n          This allows Kubelet to manage iptables rules and keep them in sync with the dynamic pod network configuration.\n        scored: true\n\n\n      - id: 4.2.8\n        text: \"Ensure that the kubeAPIQPS [--event-qps] argument is set to 0 or a level which ensures appropriate event capture (manual)\"\n        audit: |\n          echo \"Checking 'kubeAPIQPS' setting in Kubelet config on current node...\"\n\n          NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')\n          oc get --raw /api/v1/nodes/$NODE_NAME/proxy/configz \\\n            | jq '.kubeletconfig'\n        tests:\n          test_items:\n            - path: \".kubeAPIQPS\"\n              compare:\n                op: gte\n                value: 1\n        remediation: |\n          OpenShift sets kubeAPIQPS to a default of 50, which is appropriate in most environments.\n          If kubeAPIQPS is set to 0, event rate limiting is disabled, which can overwhelm the kubelet with excessive events.\n\n          To configure a proper limit, create or modify a `KubeletConfig` resource with an appropriate value:\n\n          ---\n          apiVersion: machineconfiguration.openshift.io/v1\n          kind: KubeletConfig\n          metadata:\n            name: set-kubeapiqps\n          spec:\n            kubeletConfig:\n              kubeAPIQPS: 50\n        scored: true\n\n\n      - id: 4.2.9\n        text: \"Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (manual)\"\n        audit: |\n          oc get configmap config -n openshift-kube-apiserver -ojson \\\n            | jq -r '.data[\"config.yaml\"]' \\\n            | jq -r '.apiServerArguments[\"kubelet-client-certificate\"][]?'\n\n          oc get configmap config -n openshift-kube-apiserver -ojson \\\n            | jq -r '.data[\"config.yaml\"]' \\\n            | jq -r '.apiServerArguments[\"kubelet-client-key\"][]?'\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"/etc/kubernetes/static-pod-certs/secrets/kubelet-client/tls.crt\"\n            - flag: \"/etc/kubernetes/static-pod-certs/secrets/kubelet-client/tls.key\"\n        remediation: |\n          No remediation is required. OpenShift manages secure TLS connections to kubelets by default using its internal certificate authority.\n          These X.509 certificates are rotated and validated automatically by the platform.\n          Manual modifications to the TLS paths or keys are not supported and can lead to cluster issues.\n        scored: true\n\n\n      - id: 4.2.10\n        text: \"Ensure that the --rotate-certificates argument is not set to false (manual)\"\n        audit: |\n          NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')\n          oc get --raw /api/v1/nodes/$NODE_NAME/proxy/configz \\\n            | jq '.kubeletconfig'\n        tests:\n          test_items:\n            - path: \".rotateCertificates\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          No remediation required. By default, OpenShift enables certificate rotation via rotateCertificates=true.\n          If disabled, you must either enable rotation via KubeletConfig or implement external certificate renewal.\n\n          Example remediation using KubeletConfig:\n          ---\n          apiVersion: machineconfiguration.openshift.io/v1\n          kind: KubeletConfig\n          metadata:\n            name: enable-cert-rotation\n          spec:\n            kubeletConfig:\n              rotateCertificates: true\n        scored: true\n\n      - id: 4.2.11\n        text: \"Verify that the RotateKubeletServerCertificate argument is set to true (manual)\"\n        audit: |\n          echo \"Checking that RotateKubeletServerCertificate is enabled in kubelet config on current node...\"\n\n          NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')\n\n          echo \"Verifying feature gate: RotateKubeletServerCertificate\"\n          oc get --raw /api/v1/nodes/$NODE_NAME/proxy/configz \\\n            | jq '.kubeletconfig.featureGates.RotateKubeletServerCertificate'\n\n          echo \"Verifying that certificate rotation is enabled\"\n          oc get --raw /api/v1/nodes/$NODE_NAME/proxy/configz \\\n            | jq '.kubeletconfig.rotateCertificates'\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"RotateKubeletServerCertificate\"\n              compare:\n                op: eq\n                value: true\n            - flag: \"rotateCertificates\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          No remediation is required. OpenShift enables RotateKubeletServerCertificate by default and manages certificate rotation automatically.\n          If the feature gate or rotation setting is disabled, configure a `KubeletConfig` CR and apply it to the MachineConfigPool:\n\n          ---\n          apiVersion: machineconfiguration.openshift.io/v1\n          kind: KubeletConfig\n          metadata:\n            name: enable-server-cert-rotation\n          spec:\n            kubeletConfig:\n              rotateCertificates: true\n              featureGates:\n                RotateKubeletServerCertificate: true\n        scored: true\n\n      - id: 4.2.13\n        text: \"Ensure that the Kubelet only makes use of Strong Cryptographic Ciphers (Manual)\"\n        audit: |\n          # needs verification\n          # verify cipher suites\n          oc describe --namespace=openshift-ingress-operator ingresscontroller/default\n          oc get kubeapiservers.operator.openshift.io cluster -o json |jq .spec.observedConfig.servingInfo\n          oc get openshiftapiservers.operator.openshift.io cluster -o json |jq .spec.observedConfig.servingInfo\n          oc get cm -n openshift-authentication v4-0-config-system-cliconfig -o jsonpath='{.data.v4\\-0\\-config\\-system\\-cliconfig}' | jq .servingInfo\n          #check value for tlsSecurityProfile; null is returned if default is used\n          oc get kubeapiservers.operator.openshift.io cluster -o json |jq .spec.tlsSecurityProfile\n        type: manual\n        remediation: |\n          Follow the directions above and in the OpenShift documentation to configure the tlsSecurityProfile.\n          Configuring Ingress\n        scored: false\n"
  },
  {
    "path": "cfg/rh-1.4/policies.yaml",
    "content": "---\ncontrols:\nversion: rh-1.4\nid: 5\ntext: \"Policies\"\ntype: \"policies\"\ngroups:\n  - id: 5.1\n    text: \"RBAC and Service Accounts\"\n    checks:\n      - id: 5.1.1\n        text: \"Ensure that the cluster-admin role is only used where required (Manual)\"\n        type: \"manual\"\n        audit: |\n          #To get a list of users and service accounts with the cluster-admin role\n          oc get clusterrolebindings -o=customcolumns=NAME:.metadata.name,ROLE:.roleRef.name,SUBJECT:.subjects[*].kind |\n          grep cluster-admin\n          #To verity that kbueadmin is removed, no results should be returned\n          oc get secrets kubeadmin -n kube-system\n        remediation: |\n          Identify all clusterrolebindings to the cluster-admin role. Check if they are used and if they need this role or if they could use a role with fewer privileges.\n          Where possible, first bind users to a lower privileged role and then remove the clusterrolebinding to the cluster-admin role :\n            oc delete clusterrolebinding [name]\n        scored: false\n\n      - id: 5.1.2\n        text: \"Minimize access to secrets (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove get, list and watch access to secret objects in the cluster.\n        scored: false\n\n      - id: 5.1.3\n        text: \"Minimize wildcard use in Roles and ClusterRoles (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible replace any use of wildcards in clusterroles and roles with specific\n          objects or actions.\n        scored: false\n\n      - id: 5.1.4\n        text: \"Minimize access to create pods (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove create access to pod objects in the cluster.\n        scored: false\n\n      - id: 5.1.5\n        text: \"Ensure that default service accounts are not actively used. (Manual)\"\n        type: \"manual\"\n        remediation: |\n          None required.\n        scored: false\n\n      - id: 5.1.6\n        text: \"Ensure that Service Account Tokens are only mounted where necessary (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Modify the definition of pods and service accounts which do not need to mount service\n          account tokens to disable it.\n        scored: false\n\n  - id: 5.2\n    text: \"Security Context Constraints (SCCs)\"\n    checks:\n      - id: 5.2.1\n        text: \"Minimize the admission of privileged containers (Manual)\"\n        audit: |\n          oc get scc -o json \\\n          | jq -r '[.items[] | select(.allowPrivilegedContainer==false) | .metadata.name]\n                   | length\n                   | if . > 0 then \"pass\" else \"fail\" end'\n        tests:\n          test_items:\n            - flag: \"pass\"\n        remediation: |\n          If no SCCs exist that restrict privileged containers, create one by running:\n\n          oc create -f - <<EOF\n          apiVersion: security.openshift.io/v1\n          kind: SecurityContextConstraints\n          metadata:\n            name: restricted-no-priv\n          allowPrivilegedContainer: false\n          runAsUser:\n            type: MustRunAsRange\n          seLinuxContext:\n            type: MustRunAs\n          users: []\n          groups:\n          - system:authenticated\n          EOF\n\n          Then apply appropriate RBAC to assign this SCC only to necessary service accounts, groups, or users.\n          Carefully avoid assigning `allowPrivilegedContainer: true` in any SCC that is broadly bound.\n        scored: true\n\n      - id: 5.2.2\n        text: \"Minimize the admission of containers wishing to share the host process ID namespace (Manual)\"\n        audit: |\n          oc get scc -o json \\\n            | jq -r '[.items[] | select(.allowHostPID==true) | .metadata.name]\n                     | length\n                     | if . > 0 then \"pass\" else \"fail\" end'\n        tests:\n          test_items:\n            - flag: \"pass\"\n        remediation: |\n          If SCCs with `allowHostPID: true` exist, ensure they are restricted to trusted service accounts only.\n\n          To create a restrictive SCC that prevents host PID sharing:\n\n          ---\n          apiVersion: security.openshift.io/v1\n          kind: SecurityContextConstraints\n          metadata:\n            name: restricted-no-hostpid\n          allowHostPID: false\n          runAsUser:\n            type: MustRunAsRange\n          seLinuxContext:\n            type: MustRunAs\n          users: []\n          groups:\n          - system:authenticated\n          ---\n\n          Apply the SCC and bind it only to users or groups that do **not** need hostPID access.\n        scored: true\n\n      - id: 5.2.3\n        text: \"Minimize the admission of containers wishing to share the host IPC namespace (Manual)\"\n        audit: |\n          oc get scc -o json \\\n            | jq -r '[.items[] | select(.allowHostIPC==false) | .metadata.name]\n                     | length\n                     | if . > 0 then \"pass\" else \"fail\" end'\n        tests:\n          test_items:\n            - flag: \"pass\"\n        remediation: |\n          If no SCCs restrict hostIPC usage, create one that explicitly sets allowHostIPC: false:\n\n          ---\n          apiVersion: security.openshift.io/v1\n          kind: SecurityContextConstraints\n          metadata:\n            name: restricted-no-hostipc\n          allowHostIPC: false\n          runAsUser:\n            type: MustRunAsRange\n          seLinuxContext:\n            type: MustRunAs\n          users: []\n          groups:\n          - system:authenticated\n          ---\n\n          Then assign this SCC to general workloads and ensure any SCCs allowing hostIPC are tightly scoped via RBAC.\n        scored: true\n\n      - id: 5.2.4\n        text: \"Minimize the admission of containers wishing to share the host network namespace (manual)\"\n        audit: |\n          oc get scc -o json \\\n            | jq -r '[.items[] | select(.allowHostNetwork==false) | .metadata.name]\n                     | length\n                     | if . > 0 then \"pass\" else \"fail\" end'\n        tests:\n          test_items:\n            - flag: \"pass\"\n        remediation: |\n          If no SCCs restrict host networking, create one by running:\n\n          ---\n          apiVersion: security.openshift.io/v1\n          kind: SecurityContextConstraints\n          metadata:\n            name: restricted-no-hostnetwork\n          allowHostNetwork: false\n          runAsUser:\n            type: MustRunAsRange\n          seLinuxContext:\n            type: MustRunAs\n          users: []\n          groups:\n          - system:authenticated\n          ---\n\n          Ensure only workloads that require `hostNetwork: true` (e.g., CNI, infra pods) are allowed to use SCCs where it is explicitly enabled. Restrict access to such SCCs using RBAC.\n        scored: true\n\n      - id: 5.2.5\n        text: \"Minimize the admission of containers with allowPrivilegeEscalation (manual)\"\n        audit: |\n          oc get scc -o json \\\n            | jq -r '[.items[] | select(.allowPrivilegeEscalation==false) | .metadata.name]\n                     | length\n                     | if . > 0 then \"pass\" else \"fail\" end'\n        tests:\n          test_items:\n            - flag: \"pass\"\n        remediation: |\n          If no SCCs exist that restrict the use of privilege escalation, create a custom SCC:\n\n          ---\n          apiVersion: security.openshift.io/v1\n          kind: SecurityContextConstraints\n          metadata:\n            name: restricted-no-priv-escalation\n          allowPrivilegeEscalation: false\n          runAsUser:\n            type: MustRunAsRange\n          seLinuxContext:\n            type: MustRunAs\n          users: []\n          groups:\n          - system:authenticated\n          ---\n\n          Assign this SCC only to workloads and users that **do not require** the ability to escalate privileges.\n          Use RBAC to restrict access to SCCs where `allowPrivilegeEscalation` is `true` to only trusted service accounts or admin roles.\n        scored: true\n\n\n      - id: 5.2.6\n        text: \"Minimize the admission of root containers (manual)\"\n        audit: |\n          sccs=$(oc get scc -o json | jq -r '.items[] | select(.runAsUser.type == \"MustRunAsNonRoot\") | .metadata.name')\n          if [[ -n \"$sccs\" ]]; then\n            echo \"pass\"\n          else\n            echo \"fail\"\n          fi\n        tests:\n          test_items:\n            - flag: \"pass\"\n        remediation: |\n          If no SCC is found with `runAsUser.type: MustRunAsNonRoot`, create one as follows:\n\n          ---\n          apiVersion: security.openshift.io/v1\n          kind: SecurityContextConstraints\n          metadata:\n            name: restricted-nonroot\n          allowPrivilegeEscalation: false\n          runAsUser:\n            type: MustRunAsNonRoot\n          seLinuxContext:\n            type: MustRunAs\n          users: []\n          groups:\n          - system:authenticated\n          ---\n\n          Assign this SCC only to workloads that must not run as root.\n          If an SCC allows `RunAsAny`, audit and restrict access using RBAC to prevent misuse.\n        scored: true\n\n      - id: 5.2.7\n        text: \"Minimize the admission of containers with the NET_RAW capability (manual)\"\n        audit: |\n          oc get scc -o json \\\n          | jq -r '[.items[]\n                    | select((.requiredDropCapabilities // []) | index(\"ALL\"))\n                    | .metadata.name]\n                   | length\n                   | if . > 0 then \"pass\" else \"fail\" end'\n        tests:\n          test_items:\n            - flag: \"pass\"\n        remediation: |\n          If no SCCs drop ALL capabilities, create a custom SCC that explicitly drops NET_RAW:\n\n          ---\n          apiVersion: security.openshift.io/v1\n          kind: SecurityContextConstraints\n          metadata:\n            name: restricted-no-netraw\n          requiredDropCapabilities:\n          - NET_RAW\n          allowPrivilegedContainer: false\n          runAsUser:\n            type: MustRunAsRange\n          seLinuxContext:\n            type: MustRunAs\n          users: []\n          groups:\n          - system:authenticated\n          ---\n\n          Apply this SCC to workloads that do not require NET_RAW.\n          If NET_RAW is required (e.g., for low-level networking apps), isolate those workloads with a specific SCC and restrict access via RBAC.\n        scored: true\n\n\n      - id: 5.2.8\n        text: \"Minimize the admission of containers with added capabilities (manual)\"\n        audit: |\n          oc get scc -o json \\\n          | jq -r '[.items[]\n                    | select(.allowedCapabilities == null)\n                    | .metadata.name]\n                   | length\n                   | if . > 0 then \"pass\" else \"fail\" end'\n          oc get scc -o json \\\n          | jq -r '[.items[]\n                    | select(.defaultAddCapabilities == null)\n                    | .metadata.name]\n                   | length\n                   | if . > 0 then \"true\" else \"false\" end'\n        tests:\n          test_items:\n            - flag: \"pass\"\n            - flag: \"true\"\n        remediation: |\n          If no SCCs restrict added capabilities, create a custom SCC as shown below:\n\n          ---\n          apiVersion: security.openshift.io/v1\n          kind: SecurityContextConstraints\n          metadata:\n            name: restricted-no-added-caps\n          allowPrivilegedContainer: false\n          allowedCapabilities: []\n          defaultAddCapabilities: []\n          runAsUser:\n            type: MustRunAsRange\n          seLinuxContext:\n            type: MustRunAs\n          users: []\n          groups:\n          - system:authenticated\n          ---\n\n          Assign this SCC to workloads that do **not** require elevated capabilities.\n          Create separate SCCs for workloads that require specific capabilities, and use RBAC to tightly restrict access to them.\n        scored: true\n\n      - id: 5.2.9\n        text: \"Minimize the admission of containers with capabilities assigned (manual)\"\n        audit: |\n          oc get scc -o json \\\n          | jq -r '[.items[]\n                    | select((.requiredDropCapabilities // []) | index(\"ALL\"))\n                    | .metadata.name]\n                   | length\n                   | if . > 0 then \"true\" else \"false\" end'\n        tests:\n          test_items:\n            - flag: \"true\"\n        remediation: |\n          If no SCCs drop all capabilities, create one that sets 'requiredDropCapabilities: [ALL]':\n\n          ---\n          apiVersion: security.openshift.io/v1\n          kind: SecurityContextConstraints\n          metadata:\n            name: restricted-drop-all-capabilities\n          requiredDropCapabilities:\n          - ALL\n          allowPrivilegedContainer: false\n          runAsUser:\n            type: MustRunAsRange\n          seLinuxContext:\n            type: MustRunAs\n          users: []\n          groups:\n          - system:authenticated\n          ---\n\n          Apply this SCC to general-purpose workloads that do not require elevated Linux capabilities.\n          If certain workloads require capabilities, create a separate SCC with minimal permissions and scope it using RBAC.\n        scored: true\n\n      - id: 5.2.10\n        text: \"Minimize access to privileged Security Context Constraints (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Remove any users and groups who do not need access to an SCC, following the\n          principle of least privilege.\n          You can remove users and groups from an SCC using the oc edit scc $NAME\n          command.\n          Additionally, you can create your own SCCs that contain the container functionality you\n          need for a particular use case and assign that SCC to users and groups if the default\n          SCCs are not appropriate for your use case.\n        scored: false\n\n\n  - id: 5.3\n    text: \"Network Policies and CNI\"\n    checks:\n      - id: 5.3.1\n        text: \"Ensure that the CNI in use supports Network Policies (Manual)\"\n        type: \"manual\"\n        remediation: |\n          None required.\n        scored: false\n\n      - id: 5.3.2\n        text: \"Ensure that all Namespaces have Network Policies defined (Manual)\"\n        type: \"manual\"\n        audit: |\n          #Run the following command and review the NetworkPolicy objects created in the cluster.\n          oc -n all get networkpolicy\n        remediation: |\n          Follow the documentation and create NetworkPolicy objects as you need them.\n        scored: false\n\n  - id: 5.4\n    text: \"Secrets Management\"\n    checks:\n      - id: 5.4.1\n        text: \"Prefer using secrets as files over secrets as environment variables (Manual)\"\n        type: \"manual\"\n        audit: |\n          #Run the following command to find references to objects which use environment variables defined from secrets.\n          oc get all -o jsonpath='{range .items[?(@..secretKeyRef)]} {.kind}\n          {.metadata.name} {\"\\n\"}{end}' -A\n        remediation: |\n          If possible, rewrite application code to read secrets from mounted secret files, rather than\n          from environment variables.\n        scored: false\n\n      - id: 5.4.2\n        text: \"Consider external secret storage (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Refer to the secrets management options offered by your cloud provider or a third-party\n          secrets management solution.\n        scored: false\n\n  - id: 5.5\n    text: \"Extensible Admission Control\"\n    checks:\n      - id: 5.5.1\n        text: \"Configure Image Provenance using image controller configuration parameters (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the OpenShift documentation: [Image configuration resources](https://docs.openshift.com/container-platform/4.5/openshift_images/image-configuration.html\n        scored: false\n\n  - id: 5.7\n    text: \"General Policies\"\n    checks:\n      - id: 5.7.1\n        text: \"Create administrative boundaries between resources using namespaces (Manual)\"\n        type: \"manual\"\n        audit: |\n          #Run the following command and review the namespaces created in the cluster.\n          oc get namespaces\n          #Ensure that these namespaces are the ones you need and are adequately administered as per your requirements.\n        remediation: |\n          Follow the documentation and create namespaces for objects in your deployment as you need\n          them.\n        scored: false\n\n      - id: 5.7.2\n        text: \"Ensure that the seccomp profile is set to docker/default in your pod definitions (Manual)\"\n        type: \"manual\"\n        remediation: |\n          To enable the default seccomp profile, use the reserved value /runtime/default that will\n          make sure that the pod uses the default policy available on the host.\n        scored: false\n\n      - id: 5.7.3\n        text: \"Apply Security Context to Your Pods and Containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and apply security contexts to your pods. For a\n          suggested list of security contexts, you may refer to the CIS Security Benchmark for Docker\n          Containers.\n        scored: false\n\n      - id: 5.7.4\n        text: \"The default namespace should not be used (Manual)\"\n        type: \"manual\"\n        audit: |\n          #Run this command to list objects in default namespace\n          oc project default\n          oc get all\n          #The only entries there should be system managed resources such as the kubernetes and openshift service\n        remediation: |\n          Ensure that namespaces are created to allow for appropriate segregation of Kubernetes\n          resources and that all new resources are created in a specific namespace.\n        scored: false\n"
  },
  {
    "path": "cfg/rh-1.8/config.yaml",
    "content": "---\n## Version-specific settings that override the values in cfg/config.yaml\n"
  },
  {
    "path": "cfg/rh-1.8/controlplane.yaml",
    "content": "---\ncontrols:\nversion: rh-1.8\nid: 3\ntext: \"Control Plane Configuration\"\ntype: \"controlplane\"\ngroups:\n  - id: 3.1\n    text: \"Authentication and Authorization\"\n    checks:\n      - id: 3.1.1\n        text: \"Client certificate authentication should not be used for users (Manual)\"\n        audit: |\n          # To verify user authentication is enabled\n          oc describe authentication\n          # To verify that an identity provider is configured\n          oc get identity\n          # To verify that a custom cluster-admin user exists\n          oc get clusterrolebindings -o=custom-columns=NAME:.metadata.name,ROLE:.roleRef.name,SUBJECT:.subjects[*].kind | grep cluster-admin | grep User\n          # To verity that kbueadmin is removed, no results should be returned\n          oc get secrets kubeadmin -n kube-system\n        type: manual\n        remediation: |\n          Configure an identity provider for the OpenShift cluster.\n          Understanding identity provider configuration | Authentication | OpenShift\n          Container Platform 4.5. Once an identity provider has been defined,\n          you can use RBAC to define and apply permissions.\n          After you define an identity provider and create a new cluster-admin user,\n          remove the kubeadmin user to improve cluster security.\n        scored: false\n\n  - id: 3.2\n    text: \"Logging\"\n    checks:\n      - id: 3.2.1\n        text: \"Ensure that a minimal audit policy is created (Manual)\"\n        audit: |\n          #To view kube apiserver log files\n          oc adm node-logs --role=master --path=kube-apiserver/\n          #To view openshift apiserver log files\n          oc adm node-logs --role=master --path=openshift-apiserver/\n          #To verify kube apiserver audit config\n          oc get configmap config -n openshift-kube-apiserver -ojson | jq -r '.data[\"config.yaml\"]' | jq '.auditConfig[]?'\n          #To verify openshift apiserver audit config\n          oc get configmap config -n openshift-apiserver -ojson | jq -r '.data[\"config.yaml\"]' | jq '.auditConfig[]?'\n        type: manual\n        remediation: |\n          No remediation required.\n        scored: false\n\n      - id: 3.2.2\n        text: \"Ensure that the audit policy covers key security concerns (Manual)\"\n        audit: |\n          #To verify openshift apiserver audit config\n          oc get configmap config -n openshift-kube-apiserver -ojson | jq -r '.data[\"config.yaml\"]' | jq '.auditConfig.policyConfiguration.rules[]?'\n          #To verify kube apiserver audit config\n          oc get configmap config -n openshift-apiserver -ojson | jq -r '.data[\"config.yaml\"]' | jq '.auditConfig.policyConfiguration.rules[]?'\n        type: manual\n        remediation: |\n          In OpenShift 4.6 and higher, if appropriate for your needs,\n          modify the audit policy.\n        scored: false\n"
  },
  {
    "path": "cfg/rh-1.8/etcd.yaml",
    "content": "---\ncontrols:\nversion: rh-1.8\nid: 2\ntext: \"Etcd\"\ntype: \"etcd\"\ngroups:\n  - id: 2\n    text: \"Etcd\"\n    checks:\n      - id: 2.1\n        text: \"Ensure that the --cert-file and --key-file arguments are set as appropriate (Manual)\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n          # Get the pod name in the openshift-etcd namespace\n          POD_NAME=$(oc get pods -n openshift-etcd -l app=etcd --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n          if [ -z \"$POD_NAME\" ]; then\n          echo \"No matching file found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-etcd -c etcd \"$POD_NAME\" -- ps -o command= -C etcd | sed 's/.*\\(--cert-file=[^ ]*\\).*/\\1/'\n          oc exec -n openshift-etcd -c etcd \"$POD_NAME\" -- ps -o command= -C etcd | sed 's/.*\\(--key-file=[^ ]*\\).*/\\1/'\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"file\"\n              compare:\n                op: regex\n                value: '\\/etc\\/kubernetes\\/static-pod-certs\\/secrets\\/etcd-all-(serving|certs)\\/etcd-serving-.*\\.(?:crt|key)'\n        remediation: |\n          OpenShift does not use the etcd-certfile or etcd-keyfile flags.\n          Certificates for etcd are managed by the etcd cluster operator.\n        scored: true\n\n      - id: 2.2\n        text: \"Ensure that the --client-cert-auth argument is set to true (Manual)\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n          # Get the pod name in the openshift-etcd namespace\n          POD_NAME=$(oc get pods -n openshift-etcd -l app=etcd --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n          if [ -z \"$POD_NAME\" ]; then\n          echo \"No matching file found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-etcd -c etcd \"$POD_NAME\" -- ps -o command= -C etcd | sed 's/.*\\(--client-cert-auth=[^ ]*\\).*/\\1/'\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"--client-cert-auth\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          This setting is managed by the cluster etcd operator. No remediation required.\"\n        scored: true\n\n      - id: 2.3\n        text: \"Ensure that the --auto-tls argument is not set to true (Manual)\"\n        audit: |\n          # Returns 0 if found, 1 if not found\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n          # Get the pod name in the openshift-etcd namespace\n          POD_NAME=$(oc get pods -n openshift-etcd -l app=etcd --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n          if [ -z \"$POD_NAME\" ]; then\n          echo \"No matching file found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-etcd -c etcd \"$POD_NAME\" -- ps -o command= -C etcd | grep -- --auto-tls=true 2>/dev/null ; echo exit_code=$?\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"exit_code\"\n              compare:\n                op: eq\n                value: \"1\"\n        remediation: |\n          This setting is managed by the cluster etcd operator. No remediation required.\n        scored: true\n\n      - id: 2.4\n        text: \"Ensure that the --peer-cert-file and --peer-key-file arguments are set as appropriate (Manual)\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n          # Get the pod name in the openshift-etcd namespace\n          POD_NAME=$(oc get pods -n openshift-etcd -l app=etcd --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n          if [ -z \"$POD_NAME\" ]; then\n          echo \"No matching file found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-etcd -c etcd \"$POD_NAME\" -- ps -o command= -C etcd | sed 's/.*\\(--peer-cert-file=[^ ]*\\).*/\\1/'\n          oc exec -n openshift-etcd -c etcd \"$POD_NAME\" -- ps -o command= -C etcd | sed 's/.*\\(--peer-key-file=[^ ]*\\).*/\\1/'\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"file\"\n              compare:\n                op: regex\n                value: '\\/etc\\/kubernetes\\/static-pod-certs\\/secrets\\/etcd-all-(peer|certs)\\/etcd-peer-.*\\.(?:crt|key)'\n        remediation: |\n          None. This configuration is managed by the etcd operator.\n        scored: true\n\n      - id: 2.5\n        text: \"Ensure that the --peer-client-cert-auth argument is set to true (Manual)\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n          # Get the pod name in the openshift-etcd namespace\n          POD_NAME=$(oc get pods -n openshift-etcd -l app=etcd --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n          if [ -z \"$POD_NAME\" ]; then\n          echo \"No matching file found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-etcd -c etcd \"$POD_NAME\" -- ps -o command= -C etcd | sed 's/.*\\(--peer-client-cert-auth=[^ ]*\\).*/\\1/'\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"--peer-client-cert-auth\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          This setting is managed by the cluster etcd operator. No remediation required.\n        scored: true\n\n      - id: 2.6\n        text: \"Ensure that the --peer-auto-tls argument is not set to true (Manual)\"\n        audit: |\n          # Returns 0 if found, 1 if not found\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n          # Get the pod name in the openshift-etcd namespace\n          POD_NAME=$(oc get pods -n openshift-etcd -l app=etcd --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n          if [ -z \"$POD_NAME\" ]; then\n          echo \"No matching file found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-etcd -c etcd \"$POD_NAME\" -- ps -o command= -C etcd | grep -- --peer-auto-tls=true 2>/dev/null ; echo exit_code=$?\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"exit_code\"\n              compare:\n                op: eq\n                value: \"1\"\n        remediation: |\n          This setting is managed by the cluster etcd operator. No remediation required.\n        scored: true\n\n      - id: 2.7\n        text: \"Ensure that a unique Certificate Authority is used for etcd (Manual)\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n          # Get the pod name in the openshift-etcd namespace\n          POD_NAME=$(oc get pods -n openshift-etcd -l app=etcd --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n          if [ -z \"$POD_NAME\" ]; then\n          echo \"No matching file found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-etcd -c etcd \"$POD_NAME\" -- ps -o command= -C etcd | sed 's/.*\\(--trusted-ca-file=[^ ]*\\).*/\\1/'\n          oc exec -n openshift-etcd -c etcd \"$POD_NAME\" -- ps -o command= -C etcd | sed 's/.*\\(--peer-trusted-ca-file=[^ ]*\\).*/\\1/'\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"file\"\n              compare:\n                op: regex\n                value: '\\/etc\\/kubernetes\\/static-pod-certs\\/configmaps\\/(?:etcd-(?:serving|peer-client)-ca\\/ca-bundle\\.crt|etcd-all-bundles\\/server-ca-bundle\\.crt)'\n        remediation: |\n          None required. Certificates for etcd are managed by the OpenShift cluster etcd operator.\n        scored: true\n"
  },
  {
    "path": "cfg/rh-1.8/master.yaml",
    "content": "---\ncontrols:\nversion: rh-1.8\nid: 1\ntext: \"Control Plane Components\"\ntype: \"master\"\ngroups:\n  - id: 1.1\n    text: \"Master Node Configuration Files\"\n    checks:\n      - id: 1.1.1\n        text: \"Ensure that the API server pod specification file permissions are set to 600 or more restrictive (Manual)\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n\n          # Get the pod name in the openshift-kube-apiserver namespace\n          POD_NAME=$(oc get pods -n openshift-kube-apiserver -l app=openshift-kube-apiserver --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n              echo \"No matching pods found on the current node.\"\n          else\n             # Execute the stat command\n             oc exec -n openshift-kube-apiserver \"$POD_NAME\" -- stat -c \"$POD_NAME %n permissions=%a\" /etc/kubernetes/static-pod-resources/kube-apiserver-pod.yaml\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          No remediation required; file permissions are managed by the operator.\n        scored: true\n\n      - id: 1.1.2\n        text: \"Ensure that the API server pod specification file ownership is set to root:root (Manual)\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n\n          # Get the pod name in the openshift-kube-apiserver namespace\n          POD_NAME=$(oc get pods -n openshift-kube-apiserver -l app=openshift-kube-apiserver --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n              echo \"No matching pods found on the current node.\"\n          else\n             # Execute the stat command\n             oc exec -n openshift-kube-apiserver \"$POD_NAME\" -- stat -c \"$POD_NAME %n %U:%G\" /etc/kubernetes/static-pod-resources/kube-apiserver-pod.yaml\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          No remediation required; file permissions are managed by the operator.\n        scored: true\n\n      - id: 1.1.3\n        text: \"Ensure that the controller manager pod specification file permissions are set to 600 or more restrictive (Manual)\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n\n          # Get the pod name in the openshift-kube-controller-manager namespace\n          POD_NAME=$(oc get pods -n openshift-kube-controller-manager -l app=kube-controller-manager --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n             echo \"No matching pods found on the current node.\"\n          else\n            # Execute the stat command\n            oc exec -n openshift-kube-controller-manager \"$POD_NAME\" -- stat -c \"$POD_NAME %n permissions=%a\" /etc/kubernetes/static-pod-resources/kube-controller-manager-pod.yaml\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          No remediation required; file permissions are managed by the operator.\n        scored: true\n\n      - id: 1.1.4\n        text: \"Ensure that the controller manager pod specification file ownership is set to root:root (Manual)\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n\n          # Get the pod name in the openshift-kube-controller-manager namespace\n          POD_NAME=$(oc get pods -n openshift-kube-controller-manager -l app=kube-controller-manager --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n            echo \"No matching pods found on the current node.\"\n          else\n           # Execute the stat command\n           oc exec -n openshift-kube-controller-manager \"$POD_NAME\" -- stat -c \"$POD_NAME %n %U:%G\" /etc/kubernetes/static-pod-resources/kube-controller-manager-pod.yaml\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          No remediation required; file permissions are managed by the operator.\n        scored: true\n\n      - id: 1.1.5\n        text: \"Ensure that the scheduler pod specification file permissions are set to 600 or more restrictive (Manual)\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n\n          # Get the pod name in the openshift-kube-scheduler namespace\n          POD_NAME=$(oc get pods -n openshift-kube-scheduler -l app=openshift-kube-scheduler --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n           echo \"No matching pods found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-kube-scheduler \"$POD_NAME\" -- stat -c \"$POD_NAME %n permissions=%a\" /etc/kubernetes/static-pod-resources/kube-scheduler-pod.yaml\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          No remediation required; file permissions are managed by the operator.\n        scored: true\n\n      - id: 1.1.6\n        text: \"Ensure that the scheduler pod specification file ownership is set to root:root (Manual))\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n\n          # Get the pod name in the openshift-kube-scheduler namespace\n          POD_NAME=$(oc get pods -n openshift-kube-scheduler -l app=openshift-kube-scheduler --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n           echo \"No matching pods found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-kube-scheduler \"$POD_NAME\" -- stat -c \"$POD_NAME %n %U:%G\" /etc/kubernetes/static-pod-resources/kube-scheduler-pod.yaml\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          No remediation required; file permissions are managed by the operator.\n        scored: true\n\n      - id: 1.1.7\n        text: \"Ensure that the etcd pod specification file permissions are set to 600 or more restrictive (Manual))\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n\n          # Get the pod name in the openshift-etcd namespace\n          POD_NAME=$(oc get pods -n openshift-etcd -l app=etcd --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n           echo \"No matching pods found on the current node.\"\n          else\n          # Execute the stat command\n          oc rsh -n openshift-etcd \"$POD_NAME\" stat -c \"$POD_NAME %n permissions=%a\" /etc/kubernetes/manifests/etcd-pod.yaml\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          No remediation required; file permissions are managed by the operator.\n        scored: true\n\n      - id: 1.1.8\n        text: \"Ensure that the etcd pod specification file ownership is set to root:root (Manual)\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n\n          # Get the pod name in the openshift-etcd namespace\n          POD_NAME=$(oc get pods -n openshift-etcd -l app=etcd --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n           echo \"No matching pods found on the current node.\"\n          else\n          # Execute the stat command\n          oc rsh -n openshift-etcd \"$POD_NAME\" stat -c \"$POD_NAME %n %U:%G\" /etc/kubernetes/manifests/etcd-pod.yaml\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          No remediation required; file permissions are managed by the operator.\n        scored: true\n\n      - id: 1.1.9\n        text: \"Ensure that the Container Network Interface file permissions are set to 600 or more restrictive (Manual)\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n          # For CNI multus\n          # Get the pod name in the openshift-multus namespace\n          POD_NAME=$(oc get pods -n openshift-multus -l app=multus --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n           echo \"No matching pods found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-multus \"$POD_NAME\"  -- /bin/bash -c \"stat -c \\\"$i %n permissions=%a\\\" /host/etc/cni/net.d/*.conf\";  2>/dev/null\n          oc exec -n openshift-multus \"$POD_NAME\"  -- /bin/bash -c \"stat -c \\\"$i %n permissions=%a\\\" /host/var/run/multus/cni/net.d/*.conf\";  2>/dev/null\n          fi\n          # For SDN pods\n          POD_NAME=$(oc get pods -n openshift-sdn -l app=sdn --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n           echo \"No matching pods found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-sdn \"$POD_NAME\"  -- find /var/lib/cni/networks/openshift-sdn -type f -exec stat -c \"$i %n permissions=%a\" {} \\; 2>/dev/null\n          oc exec -n openshift-sdn \"$POD_NAME\"  -- find /var/run/openshift-sdn -type f -exec stat -c \"$i %n permissions=%a\" {} \\; 2>/dev/null\n          fi\n\n          # For OVS pods\n          POD_NAME=$(oc get pods -n openshift-sdn -l app=ovs --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n           echo \"No matching pods found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-sdn \"$POD_NAME\"  -- find /var/run/openvswitch -type f -exec stat -c \"$i %n permissions=%a\" {} \\; 2>/dev/null\n          oc exec -n openshift-sdn \"$POD_NAME\"  -- find /etc/openvswitch -type f -exec stat -c \"$i %n permissions=%a\" {} \\; 2>/dev/null\n          oc exec -n openshift-sdn \"$POD_NAME\"  -- find /run/openvswitch -type f -exec stat -c \"$i %n permissions=%a\" {} \\; 2>/dev/null\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          No remediation required; file permissions are managed by the operator.\n        scored: true\n\n      - id: 1.1.10\n        text: \"Ensure that the Container Network Interface file ownership is set to root:root (Manual)\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n          # For CNI multus\n          # Get the pod name in the openshift-multus namespace\n          POD_NAME=$(oc get pods -n openshift-multus -l app=multus --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n           echo \"No matching pods found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-multus \"$POD_NAME\" -- /bin/bash -c \"stat -c '$i %n %U:%G' /host/etc/cni/net.d/*.conf\" 2>/dev/null\n          oc exec -n openshift-multus $i -- /bin/bash -c \"stat -c '$i %n %U:%G' /host/var/run/multus/cni/net.d/*.conf\"  2>/dev/null\n          fi\n          # For SDN pods\n          POD_NAME=$(oc get pods -n openshift-sdn -l app=sdn --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n           echo \"No matching pods found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-sdn \"$POD_NAME\"  -- find /var/lib/cni/networks/openshift-sdn -type f -exec stat -c \"$i %n %U:%G\" {} \\; 2>/dev/null\n          oc exec -n openshift-sdn \"$POD_NAME\"  -- find /var/run/openshift-sdn -type f -exec stat -c \"$i %n %U:%G\" {} \\; 2>/dev/null\n          fi\n          # For OVS pods in 4.5\n          POD_NAME=$(oc get pods -n openshift-sdn -l app=ovs --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n           echo \"No matching pods found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-sdn \"$POD_NAME\"  -- find /var/run/openvswitch -type f -exec stat -c \"$i %n %U:%G\" {} \\; 2>/dev/null\n          oc exec -n openshift-sdn \"$POD_NAME\"  -- find /etc/openvswitch -type f -exec stat -c \"$i %n %U:%G\" {} \\; 2>/dev/null\n          oc exec -n openshift-sdn \"$POD_NAME\"  -- find /run/openvswitch -type f -exec stat -c \"$i %n %U:%G\" {} \\; 2>/dev/null\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          No remediation required; file permissions are managed by the operator.\n        scored: true\n\n      - id: 1.1.11\n        text: \"Ensure that the etcd data directory permissions are set to 700 or more restrictive (Manual)\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n\n          # Get the pod name in the openshift-etcd namespace\n          POD_NAME=$(oc get pods -n openshift-etcd -l app=etcd --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n          echo \"No matching pods found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-etcd \"$POD_NAME\" -- stat -c \"$POD_NAME %n permissions=%a\" /var/lib/etcd/member\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"700\"\n        remediation: |\n          No remediation required; file permissions are managed by the operator.\n        scored: true\n\n      - id: 1.1.12\n        text: \"Ensure that the etcd data directory ownership is set to etcd:etcd (Manual)\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n\n          # Get the pod name in the openshift-etcd namespace\n          POD_NAME=$(oc get pods -n openshift-etcd -l app=etcd --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n          echo \"No matching pods found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-etcd \"$POD_NAME\" -- stat -c \"$POD_NAME %n %U:%G\" /var/lib/etcd/member\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          No remediation required; file permissions are managed by the operator.\n        scored: true\n\n      - id: 1.1.13\n        text: \"Ensure that the kubeconfig file permissions are set to 600 or more restrictive (Manual)\"\n        audit: |\n          NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')\n          oc debug node/$NODE_NAME -- chroot /host stat -c \"$NODE_NAME %n permissions=%a\" /etc/kubernetes/kubeconfig 2> /dev/null\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          No remediation required; file permissions are managed by the operator.\n        scored: true\n\n      - id: 1.1.14\n        text: \"Ensure that the kubeconfig file ownership is set to root:root (Manual)\"\n        audit: |\n          NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')\n          oc debug node/$NODE_NAME -- chroot /host stat -c \"$NODE_NAME %n %U:%G\" /etc/kubernetes/kubeconfig 2> /dev/null\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          No remediation required; file permissions are managed by the operator.\n        scored: true\n\n      - id: 1.1.15\n        text: \"Ensure that the scheduler kubeconfig file permissions are set to 600 or more restrictive (Manual)\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n\n          # Get the pod name in the openshift-kube-scheduler namespace\n          POD_NAME=$(oc get pods -n openshift-kube-scheduler -l app=openshift-kube-scheduler --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n          echo \"No matching pods found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-kube-scheduler \"$POD_NAME\" -- stat -c \"$POD_NAME %n permissions=%a\" /etc/kubernetes/static-pod-resources/configmaps/scheduler-kubeconfig/kubeconfig\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          No remediation required; file permissions are managed by the operator.\n        scored: true\n\n      - id: 1.1.16\n        text: \"Ensure that the scheduler kubeconfig file ownership is set to root:root (Manual)\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n\n          # Get the pod name in the openshift-kube-scheduler namespace\n          POD_NAME=$(oc get pods -n openshift-kube-scheduler -l app=openshift-kube-scheduler --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n          echo \"No matching pods found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-kube-scheduler \"$POD_NAME\" -- stat -c \"$POD_NAME %n %U:%G\" /etc/kubernetes/static-pod-resources/configmaps/scheduler-kubeconfig/kubeconfig\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          No remediation required; file permissions are managed by the operator.\n        scored: true\n\n      - id: 1.1.17\n        text: \"Ensure that the controller-manager kubeconfig file permissions are set to 600 or more restrictive (Manual)\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n\n          # Get the pod name in the openshift-kube-controller-manager namespace\n          POD_NAME=$(oc get pods -n openshift-kube-controller-manager -l app=kube-controller-manager --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n          echo \"No matching pods found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-kube-controller-manager \"$POD_NAME\" -- stat -c \"$POD_NAME %n permissions=%a\" /etc/kubernetes/static-pod-resources/configmaps/controller-manager-kubeconfig/kubeconfig\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          No remediation required; file permissions are managed by the operator.\n        scored: true\n\n      - id: 1.1.18\n        text: \"Ensure that the controller-manager kubeconfig file ownership is set to root:root (Manual)\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n\n          # Get the pod name in the openshift-kube-controller-manager namespace\n          POD_NAME=$(oc get pods -n openshift-kube-controller-manager -l app=kube-controller-manager --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n          echo \"No matching pods found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-kube-controller-manager \"$POD_NAME\" -- stat -c \"$POD_NAME %n %U:%G\" /etc/kubernetes/static-pod-resources/configmaps/controller-manager-kubeconfig/kubeconfig\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          No remediation required; file permissions are managed by the operator.\n        scored: true\n\n      - id: 1.1.19\n        text: \"Ensure that the OpenShift PKI directory and file ownership is set to root:root (Manual)\"\n        audit: |\n          # Should return root:root for all files and directories\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n\n          # Get the pod name in the openshift-kube-controller-manager namespace\n          POD_NAME=$(oc get pods -n openshift-kube-apiserver -l app=openshift-kube-apiserver --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n          echo \"No matching pods found on the current node.\"\n          else\n          # echo $i static-pod-certs\n          oc exec -n openshift-kube-apiserver \"$POD_NAME\" -c kube-apiserver -- find /etc/kubernetes/static-pod-certs -type d -wholename '*/secrets*' -exec stat -c \"$i %n %U:%G\" {} \\;\n          oc exec -n openshift-kube-apiserver \"$POD_NAME\" -c kube-apiserver -- find /etc/kubernetes/static-pod-certs -type f -wholename '*/secrets*' -exec stat -c \"$i %n %U:%G\" {} \\;\n          # echo $i static-pod-resources\n          oc exec -n openshift-kube-apiserver \"$POD_NAME\" -c kube-apiserver -- find /etc/kubernetes/static-pod-resources -type d -wholename '*/secrets*' -exec stat -c \"$i %n %U:%G\" {} \\;\n          oc exec -n openshift-kube-apiserver \"$POD_NAME\" -c kube-apiserver -- find /etc/kubernetes/static-pod-resources -type f -wholename '*/secrets*' -exec stat -c \"$i %n %U:%G\" {} \\;\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          No remediation required; file permissions are managed by the operator.\n        scored: true\n\n      - id: 1.1.20\n        text: \"Ensure that the OpenShift PKI certificate file permissions are set to 600 or more restrictive (Manual)\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n\n          # Get the pod name in the openshift-kube-apiserver namespace\n          POD_NAME=$(oc get pods -n openshift-kube-apiserver -l app=openshift-kube-apiserver --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n          echo \"No matching pods found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-kube-apiserver \"$POD_NAME\" -c kube-apiserver -- find /etc/kubernetes/static-pod-certs -type f -wholename '*/secrets/*.crt' -exec stat -c \"$POD_NAME %n permissions=%a\" {} \\;\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          No remediation required; file permissions are managed by the operator.\n        scored: true\n\n      - id: 1.1.21\n        text: \"Ensure that the OpenShift PKI key file permissions are set to 600 (Manual)\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n\n          # Get the pod name in the openshift-kube-apiserver namespace\n          POD_NAME=$(oc get pods -n openshift-kube-apiserver -l app=openshift-kube-apiserver --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n          echo \"No matching pods found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-kube-apiserver \"$POD_NAME\" -c kube-apiserver -- find /etc/kubernetes/static-pod-certs -type f -wholename '*/secrets/*.key' -exec stat -c \"$POD_NAME %n permissions=%a\" {} \\;\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          No remediation required; file permissions are managed by the operator.\n        scored: true\n\n  - id: 1.2\n    text: \"API Server\"\n    checks:\n      - id: 1.2.1\n        text: \"Ensure that anonymous requests are authorized (Manual)\"\n        audit: |\n          found=0\n\n          echo \"# ClusterRoleBindings granting permissions to system:unauthenticated\"\n          crb_out=\"$(oc get clusterrolebindings -o json 2>/dev/null \\\n            | jq -r '.items[]\n              | select(.subjects[]? | select(.kind==\"Group\" and .name==\"system:unauthenticated\"))\n              | .metadata.name + \" -> \" + .roleRef.kind + \"/\" + .roleRef.name' \\\n            | sort -u)\"\n          if [ -n \"$crb_out\" ]; then\n            echo \"$crb_out\"\n            found=1\n          else\n            echo \"(none)\"\n          fi\n\n          echo\n          echo \"# Namespaced RoleBindings granting permissions to system:unauthenticated\"\n          rb_out=\"$(oc get rolebindings -A -o json 2>/dev/null \\\n            | jq -r '.items[]\n              | select(.subjects[]? | select(.kind==\"Group\" and .name==\"system:unauthenticated\"))\n              | (.metadata.namespace + \"/\" + .metadata.name) + \" -> \" + .roleRef.kind + \"/\" + .roleRef.name' \\\n            | sort -u)\"\n          if [ -n \"$rb_out\" ]; then\n            echo \"$rb_out\"\n            found=1\n          else\n            echo \"(none)\"\n          fi\n\n          # Provide a simple flag for the test harness\n          if [ $found -eq 1 ]; then\n            echo \"unauthenticated_bindings_present\"\n          else\n            echo \"unauthenticated_bindings_missing\"\n          fi\n        tests:\n          test_items:\n            - flag: \"unauthenticated_bindings_present\"\n              set: true\n        remediation: |\n          None required. The default configuration should not be modified.\n        scored: true\n\n      - id: 1.2.2\n        text: \"Use HTTPS for kubelet connections (Manual)\"\n        audit: |\n          CFG=$(oc -n openshift-kube-apiserver get cm config -o jsonpath='{.data.config\\.yaml}')\n\n          # Extract kubelet client cert/key paths (support both layouts)\n          CERT_FILE=$(printf '%s\\n' \"$CFG\" \\\n          | grep -Eo '/etc/kubernetes/static-pod-(resources/kube-apiserver-certs|certs)/secrets/kubelet-client/tls\\.crt' \\\n          | head -n1)\n\n          KEY_FILE=$(printf '%s\\n' \"$CFG\" \\\n          | grep -Eo '/etc/kubernetes/static-pod-(resources/kube-apiserver-certs|certs)/secrets/kubelet-client/tls\\.key' \\\n          | head -n1)\n\n          # 1) pass/fail on presence of both files\n          if [ -n \"$CERT_FILE\" ] && [ -n \"$KEY_FILE\" ]; then\n            echo \"pass\"\n          else\n            echo \"fail\"\n          fi\n          KUBELET_HTTPS=$(printf '%s\\n' \"$CFG\" \\\n            | grep -Eo '(^|[[:space:]])kubelet-https:[[:space:]]*(true|false)' \\\n            | awk -F: '{print $2}' \\\n            | tr -d '[:space:]' \\\n            | head -n1)\n\n          if [ \"$KUBELET_HTTPS\" = \"false\" ]; then\n            echo \"false\"\n          else\n           echo \"true\"\n          fi\n\n          oc -n openshift-apiserver describe secret serving-cert | grep -E 'tls\\.crt|tls\\.key|Type:'\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"pass\"\n            - flag: \"true\"\n            - flag: \"kubernetes.io/tls\"\n            - flag: \"tls.crt\"\n            - flag: \"tls.key\"\n        remediation: |\n          OpenShift does not use the legacy --kubelet-https flag; TLS is enforced via\n          kubelet client cert/key arguments and cluster CAs. Ensure:\n            - apiServerArguments.kubelet-client-certificate[0] points to a real file\n            - apiServerArguments.kubelet-client-key[0] points to a real file\n            - The openshift-apiserver 'serving-cert' secret is type kubernetes.io/tls and contains tls.crt and tls.key\n        scored: false\n\n      - id: 1.2.3\n        text: \"Ensure that the kubelet uses certificates to authenticate (Manual)\"\n        audit: |\n          oc get configmap config -n openshift-kube-apiserver -ojson | jq -r '.data[\"config.yaml\"]' | jq '.apiServerArguments[\"kubelet-client-certificate\"]'\n          oc get configmap config -n openshift-kube-apiserver -ojson | jq -r'.data[\"config.yaml\"]' | jq '.apiServerArguments[\"kubelet-client-key\"]'\n          oc -n openshift-apiserver describe secret serving-cert\n        tests:\n          test_items:\n            - flag: \"/etc/kubernetes/static-pod-certs/secrets/kubelet-client/tls.crt\"\n            - flag: \"/etc/kubernetes/static-pod-certs/secrets/kubelet-client/tls.key\"\n            - flag: \"kubernetes.io/tls\"\n        remediation: |\n          No remediation is required.\n          OpenShift automatically manages kubelet authentication using X.509 certificates issued by the internal platform CA.\n          Manual modification of these certificates is not supported and can disrupt platform components.\n        scored: true\n\n      - id: 1.2.4\n        text: \"Verify that the kubelet certificate authority is set as appropriate (Manual)\"\n        audit: |\n          oc get configmap config -n openshift-kube-apiserver -ojson \\\n            | jq -r '.data[\"config.yaml\"]' \\\n            | jq '.apiServerArguments[\"kubelet-certificate-authority\"]'\n        tests:\n          test_items:\n            - flag: \"/etc/kubernetes/static-pod-resources/configmaps/kubelet-serving-ca/ca-bundle.crt\"\n        remediation: |\n          No remediation is required.\n          OpenShift uses internal X.509 certificates and platform-managed CAs to verify kubelet server identities.\n          This is not user-configurable and should not be modified.\n        scored: true\n\n      - id: 1.2.5\n        text: \"Ensure that the --authorization-mode argument is not set to AlwaysAllow (Manual)\"\n        audit: |\n          oc get configmap config -n openshift-kube-apiserver -o json \\\n            | jq -r '.data[\"config.yaml\"]' \\\n            | jq '.apiServerArguments[\"authorization-mode\"]'\n        audit_config: |\n          oc get configmap config -n openshift-kube-apiserver -ojson | jq -r '.data[\"config.yaml\"]' | jq '.apiServerArguments'\n        tests:\n          bin_op: or\n          test_items:\n            - path: \"{.authorization-mode}\"\n              compare:\n                op: nothave\n                value: \"AlwaysAllow\"\n            - path: \"{.authorization-mode}\"\n              flag: \"authorization-mode\"\n              set: false\n        remediation: |\n          No remediation required.\n          OpenShift does not support the 'AlwaysAllow' authorization mode.\n          The API server is bootstrapped with secure authorization mechanisms including RBAC and Node by default.\n        scored: true\n\n      - id: 1.2.6\n        text: \"Verify that RBAC is enabled (Manual)\"\n        audit: |\n          oc get configmap config -n openshift-kube-apiserver -o json \\\n            | jq -r '.data[\"config.yaml\"]' \\\n            | jq '.apiServerArguments[\"authorization-mode\"]'\n        audit_config: |\n          oc get configmap config -n openshift-kube-apiserver -ojson | jq -r '.data[\"config.yaml\"]' | jq '.apiServerArguments'\n        tests:\n          bin_op: or\n          test_items:\n            - path: \"{.authorization-mode}\"\n              compare:\n                op: has\n                value: \"RBAC\"\n            - path: \"{.authorization-mode}\"\n              flag: \"authorization-mode\"\n              set: false\n        remediation: |\n          No remediation is required.\n          OpenShift is configured at bootstrap time to use Role-Based Access Control (RBAC) as the default authorization mode.\n          RBAC is always enabled, and cannot be disabled through configuration.\n        scored: true\n\n\n      - id: 1.2.7\n        text: \"Ensure that the APIPriorityAndFairness feature gate is enabled (Manual)\"\n        audit: |\n          oc get kubeapiservers.operator.openshift.io cluster -o json | jq '.spec.observedConfig.apiServerArguments'\n        tests:\n          test_items:\n            - flag: \"APIPriorityAndFairness=true\"\n        remediation: |\n          No remediation is required\n        scored: true\n\n      - id: 1.2.8\n        text: \"Ensure that the admission control plugin AlwaysAdmit is not set (Manual)\"\n        audit: |\n          oc -n openshift-kube-apiserver get configmap config -o json | jq -r '.data.\"config.yaml\"' | jq '.apiServerArguments.\"enable-admission-plugins\"'\n        tests:\n          test_items:\n            - flag: \"AlwaysAdmit\"\n              set: false\n        remediation: |\n          No remediation is required. The AlwaysAdmit admission controller cannot be enabled in OpenShift.\n        scored: true\n\n      - id: 1.2.9\n        text: \"Ensure that the admission control plugin AlwaysPullImages is set (Manual)\"\n        audit: |\n          oc -n openshift-kube-apiserver get configmap config -o json | jq -r '.data.\"config.yaml\"' | jq '.apiServerArguments.\"enable-admission-plugins\"'\n        tests:\n          test_items:\n            - flag: \"AlwaysPullImages\"\n              set: false\n        remediation: |\n          None required.\n        scored: true\n\n      - id: 1.2.10\n        text: \"Ensure that the admission control plugin ServiceAccount is set (Manual)\"\n        audit: |\n          oc -n openshift-kube-apiserver get configmap config -o json | jq -r '.data.\"config.yaml\"' | jq '.apiServerArguments.\"enable-admission-plugins\"'\n        tests:\n          test_items:\n            - flag: \"ServiceAccount\"\n              set: true\n        remediation: |\n          None required. OpenShift is configured to use service accounts by default.\n        scored: true\n\n      - id: 1.2.11\n        text: \"Ensure that the admission control plugin NamespaceLifecycle is set (Manual)\"\n        audit: |\n          oc -n openshift-kube-apiserver get configmap config -o json | jq -r '.data.\"config.yaml\"' | jq '.apiServerArguments.\"enable-admission-plugins\"'\n          output=$(oc -n openshift-kube-apiserver get configmap config -o json | jq -r '.data.\"config.yaml\"' | jq '.apiServerArguments.\"enable-admission-plugins\"')\n          [ \"$output\" == \"null\" ] && echo \"ocp 4.5 has NamespaceLifecycle compiled\" || echo $output\n        tests:\n          test_items:\n            - flag: \"NamespaceLifecycle\"\n        remediation: |\n          Ensure that the --disable-admission-plugins parameter does not include NamespaceLifecycle.\n        scored: true\n\n      - id: 1.2.12\n        text: \"Ensure that the admission control plugin SecurityContextConstraint is set (Manual)\"\n        audit: |\n          oc -n openshift-kube-apiserver get configmap config -o json | jq -r '.data.\"config.yaml\"' | jq '.apiServerArguments.\"enable-admission-plugins\"'\n          output=$(oc -n openshift-kube-apiserver get configmap config -o json | jq -r '.data.\"config.yaml\"' | jq '.apiServerArguments.\"enable-admission-plugins\"')\n          [ \"$output\" == \"null\" ] && echo \"ocp 4.5 has SecurityContextConstraint compiled\" || echo $output\n        tests:\n          test_items:\n            - flag: \"security.openshift.io/SecurityContextConstraint\"\n        remediation: |\n          None required. Security Context Constraints are enabled by default in OpenShift and cannot be disabled.\n        scored: true\n\n      - id: 1.2.13\n        text: \"Ensure that the admission control plugin NodeRestriction is set (Manual)\"\n        audit: |\n          oc -n openshift-kube-apiserver get configmap config -o json | jq -r '.data.\"config.yaml\"' | jq '.apiServerArguments.\"enable-admission-plugins\"'\n          output=$(oc -n openshift-kube-apiserver get configmap config -o json | jq -r '.data.\"config.yaml\"' | jq '.apiServerArguments.\"enable-admission-plugins\"')\n          [ \"$output\" == \"null\" ] && echo \"ocp 4.5 has NodeRestriction compiled\" || echo $output\n        tests:\n          test_items:\n            - flag: \"NodeRestriction\"\n        remediation: |\n          The NodeRestriction plugin cannot be disabled.\n        scored: true\n\n      - id: 1.2.14\n        text: \"Ensure that the --insecure-bind-address argument is not set (manual)\"\n        audit: |\n          # Get the insecure-bind-address value\n          insecure_bind_address=$(oc get kubeapiservers.operator.openshift.io cluster -ojson \\\n            | jq -r '.spec.observedConfig.apiServerArguments[\"insecure-bind-address\"][]?')\n\n          # Get port from openshift-kube-apiserver\n          kube_api_port=$(oc -n openshift-kube-apiserver get endpoints -o jsonpath='{.items[*].subsets[*].ports[*].port}')\n\n          # Get port from openshift-apiserver\n          openshift_api_port=$(oc -n openshift-apiserver get endpoints -o jsonpath='{.items[*].subsets[*].ports[*].port}')\n\n          # Evaluate logic\n          [[ -z \"$insecure_bind_address\" ]] && \\\n          [[ \"$kube_api_port\" == *\"6443\"* ]] && \\\n          [[ \"$openshift_api_port\" == *\"8443\"* ]] && echo \"pass\" || echo \"fail\"\n        tests:\n          test_items:\n            - flag: \"pass\"\n        remediation: |\n          No remediation is required.\n          By default, OpenShift uses secure HTTPS ports (6443 and 8443) for all API communications.\n          The API servers are not configured to expose insecure ports and are isolated within the pod network.\n        scored: true\n\n\n      - id: 1.2.15\n        text: \"Ensure that the --insecure-port argument is set to 0 (Manual)\"\n        audit: |\n          oc -n openshift-kube-apiserver get endpoints -o jsonpath='{.items[*].subsets[*].ports[*].port}'\n        tests:\n          test_items:\n            - flag: \"6443\"\n        remediation: |\n          None required. The configuration is managed by the API server operator.\n        scored: true\n\n      - id: 1.2.16\n        text: \"Ensure that the --secure-port argument is not set to 0 (Manual)\"\n        audit: |\n          BIND_ADDR=$(oc get kubeapiservers.operator.openshift.io cluster -o json \\\n            | jq -r '.spec.observedConfig.servingInfo.bindAddress')\n\n          PORTS=$(oc get pods -n openshift-kube-apiserver -l app=openshift-kube-apiserver \\\n            -o jsonpath='{.items[*].spec.containers[?(@.name==\"kube-apiserver\")].ports[*].containerPort}')\n\n          if [ \"$BIND_ADDR\" = \"0.0.0.0:6443\" ] && echo \"$PORTS\" | grep -q '\\b6443\\b'; then\n            echo \"pass\"\n          else\n            echo \"fail\"\n          fi\n        tests:\n          test_items:\n            - flag: \"pass\"\n        remediation: |\n          None required. OpenShift serves the API securely over port 6443 with TLS, authentication, and authorization.\n          The insecure API port is not exposed or configurable by default.\n        scored: true\n\n      - id: 1.2.17\n        text: \"Ensure that the healthz endpoint is protected by RBAC (Manual)\"\n        type: manual\n        remediation: |\n          None required as profiling data is protected by RBAC.\n        scored: false\n\n      - id: 1.2.18\n        text: \"Ensure that the --audit-log-path argument is set (Manual)\"\n        audit: |\n          # Get kube-apiserver audit log path\n          kube_path=$(oc get configmap config -n openshift-kube-apiserver -ojson \\\n            | jq -r '.data[\"config.yaml\"]' \\\n            | jq -r '.apiServerArguments[\"audit-log-path\"][]?')\n\n          # Get OpenShift apiserver audit log path\n          os_path=$(oc get configmap config -n openshift-apiserver -ojson \\\n            | jq -r '.data[\"config.yaml\"]' \\\n            | jq -r '.apiServerArguments[\"audit-log-path\"][]?')\n\n          # Check if log file exists in kube-apiserver pod\n          kube_pod=$(oc get pods -n openshift-kube-apiserver -l app=openshift-kube-apiserver -o jsonpath='{.items[0].metadata.name}')\n          oc rsh -n openshift-kube-apiserver -c kube-apiserver $kube_pod ls \"$kube_path\" >/dev/null 2>&1\n          kube_exists=$?\n\n          # Check if log file exists in openshift-apiserver pod\n          os_pod=$(oc get pods -n openshift-apiserver -l apiserver=true -o jsonpath='{.items[0].metadata.name}')\n          oc rsh -n openshift-apiserver $os_pod ls \"$os_path\" >/dev/null 2>&1\n          os_exists=$?\n\n          # Evaluate all conditions\n          [[ \"$kube_path\" == \"/var/log/kube-apiserver/audit.log\" ]] && \\\n          [[ \"$os_path\" == \"/var/log/openshift-apiserver/audit.log\" ]] && \\\n          [[ $kube_exists -eq 0 ]] && \\\n          [[ $os_exists -eq 0 ]] && echo \"pass\" || echo \"fail\"\n        tests:\n          test_items:\n            - flag: \"pass\"\n        remediation: |\n          No remediation is required.\n          OpenShift manages audit logging automatically via the apiserver configuration.\n          By default, the audit log paths are:\n          - /var/log/kube-apiserver/audit.log\n          - /var/log/openshift-apiserver/audit.log\n        scored: true\n\n      - id: 1.2.19\n        text: \"Ensure that the audit logs are forwarded off the cluster for retention (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the documentation for log forwarding. Forwarding logs to third party systems\n          https://docs.openshift.com/container-platform/4.5/logging/cluster-logging-external.html\n        scored: false\n\n      - id: 1.2.20\n        text: \"Ensure that the maximumRetainedFiles argument is set to 10 or as appropriate (Manual)\"\n        audit: |\n          VALUE=$(oc get configmap config -n openshift-kube-apiserver -ojson \\\n            | jq -r '.data[\"config.yaml\"]' \\\n            | jq -r '.apiServerArguments[\"audit-log-maxbackup\"][0] // empty')\n\n          if [ -n \"$VALUE\" ] && [ \"$VALUE\" -ge 10 ]; then\n            echo \"pass (current=$VALUE)\"\n          else\n            echo \"fail (current=$VALUE)\"\n          fi\n        tests:\n          test_items:\n            - flag: \"pass\"\n        remediation: |\n          No remediation required.\n          By default, OpenShift retains 10 audit log backup files.\n          This provides sufficient log history for incident investigation and audit review.\n        scored: true\n\n      - id: 1.2.21\n        text: \"Configure Kubernetes API Server Maximum Audit Log Size (Manual)\"\n        audit: |\n          VALUE=$(oc get configmap config -n openshift-kube-apiserver -ojson \\\n            | jq -r '.data[\"config.yaml\"]' \\\n            | jq -r '.apiServerArguments[\"audit-log-maxsize\"][0] // empty')\n\n          if [ -n \"$VALUE\" ] && [ \"$VALUE\" -ge 100 ]; then\n            echo \"pass (current=$VALUE)\"\n          else\n            echo \"fail (current=$VALUE)\"\n          fi\n        tests:\n          test_items:\n            - flag: \"pass\"\n        remediation: |\n          Set the audit-log-maxsize parameter to 100 or as an appropriate number.\n          maximumFileSizeMegabytes: 100\n        scored: true\n\n      - id: 1.2.22\n        text: \"Ensure that the --request-timeout argument is set (Manual)\"\n        audit: |\n          VALUE=$(oc get configmap config -n openshift-kube-apiserver -ojson \\\n            | jq -r '.data[\"config.yaml\"]' \\\n            | jq -r '.apiServerArguments[\"min-request-timeout\"][0] // empty')\n\n          if [ -n \"$VALUE\" ] && [ \"$VALUE\" -eq 3600 ]; then\n            echo \"pass (current=$VALUE)\"\n          else\n            echo \"fail (current=$VALUE)\"\n          fi\n        tests:\n          test_items:\n            - flag: \"pass\"\n        remediation: |\n          TBD\n        scored: true\n\n      - id: 1.2.23\n        text: \"Ensure that the --service-account-lookup argument is set to true (Manual)\"\n        audit: |\n          oc get configmap config -n openshift-kube-apiserver -ojson | jq -r\n          '.data[\"config.yaml\"]' | jq '.apiServerArguments.\"service-account-lookup\"[]'\n        tests:\n          test_items:\n            - flag: \"true\"\n        remediation: |\n          TBD\n        scored: true\n\n      - id: 1.2.24\n        text: \"Ensure that the --service-account-key-file argument is set as appropriate (Manual)\"\n        audit: |\n          oc get configmap config -n openshift-kube-apiserver -ojson | jq -r '.data[\"config.yaml\"]' | jq -r .serviceAccountPublicKeyFiles[]\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"/etc/kubernetes/static-pod-resources/configmaps/sa-token-signing-certs\"\n            - flag: \"/etc/kubernetes/static-pod-resources/configmaps/bound-sa-token-signing-certs\"\n        remediation: |\n          The OpenShift API server does not use the service-account-key-file argument.\n          The ServiceAccount token authenticator is configured with serviceAccountConfig.publicKeyFiles.\n          OpenShift does not reuse the apiserver TLS key. This is not configurable.\n        scored: true\n\n      - id: 1.2.25\n        text: \"Ensure that the --etcd-certfile and --etcd-keyfile arguments are set as appropriate (Manual)\"\n        audit: |\n          oc get configmap config -n openshift-kube-apiserver -ojson \\\n            | jq -r '.data[\"config.yaml\"]' \\\n            | jq -r '.apiServerArguments[\"etcd-certfile\"][]?'\n\n          oc get configmap config -n openshift-kube-apiserver -ojson \\\n            | jq -r '.data[\"config.yaml\"]' \\\n            | jq -r '.apiServerArguments[\"etcd-keyfile\"][]?'\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"/etc/kubernetes/static-pod-resources/secrets/etcd-client/tls.crt\"\n            - flag: \"/etc/kubernetes/static-pod-resources/secrets/etcd-client/tls.key\"\n        remediation: |\n          No remediation is required.\n          OpenShift automatically manages X.509 client certificates and TLS encryption for secure communication with etcd.\n          These settings are handled by the platform and should not be manually modified.\n        scored: true\n\n      - id: 1.2.26\n        text: \"Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Manual)\"\n        audit: |\n          oc get configmap config -n openshift-kube-apiserver -ojson \\\n            | jq -r '.data[\"config.yaml\"]' \\\n            | jq -r '.apiServerArguments[\"tls-cert-file\"][]?'\n\n          oc get configmap config -n openshift-kube-apiserver -ojson \\\n            | jq -r '.data[\"config.yaml\"]' \\\n            | jq -r '.apiServerArguments[\"tls-private-key-file\"][]?'\n\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"/etc/kubernetes/static-pod-certs/secrets/service-network-serving-certkey/tls.crt\"\n            - flag: \"/etc/kubernetes/static-pod-certs/secrets/service-network-serving-certkey/tls.key\"\n        remediation: |\n          No remediation is required. OpenShift automatically configures the API server with valid X.509 certificates and TLS keys.\n          These are used to encrypt traffic between the API server and clients, including kubelets and users.\n          Certificate rotation and lifecycle management are handled by the OpenShift platform.\n        scored: true\n\n\n      - id: 1.2.27\n        text: \"Ensure that the --client-ca-file argument is set as appropriate (Manual)\"\n        audit: |\n          oc get configmap config -n openshift-kube-apiserver -ojson | \\\n          jq -r '.data[\"config.yaml\"]' | \\\n          jq -r .servingInfo.clientCA\n        tests:\n          test_items:\n            - flag: \"/etc/kubernetes/static-pod-certs/configmaps/client-ca/ca-bundle.crt\"\n        remediation: |\n          OpenShift automatically manages TLS authentication for the API server communication with the node/kublet.\n          This is not configurable. You may optionally set a custom default certificate to be used by the API\n          server when serving content in order to enable clients to access the API server at a different host name\n          or without the need to distribute the cluster-managed certificate authority (CA) certificates to the clients.\n\n          User-provided certificates must be provided in a kubernetes.io/tls type Secret in the openshift-config namespace.\n          Update the API server cluster configuration,\n          the apiserver/cluster resource, to enable the use of the user-provided certificate.\n        scored: true\n\n      - id: 1.2.28\n        text: \"Ensure that the --etcd-cafile argument is set as appropriate (Manual)\"\n        audit: |\n          oc get configmap config -n openshift-kube-apiserver -ojson | \\\n            jq -r '.data[\"config.yaml\"]' | \\\n            jq -r '.apiServerArguments[\"etcd-cafile\"]'\n        tests:\n          test_items:\n            - flag: \"/etc/kubernetes/static-pod-resources/configmaps/etcd-serving-ca/ca-bundle.crt\"\n        remediation: |\n          None required. OpenShift generates the etcd-cafile and sets the arguments appropriately in the API server. Communication with etcd is secured by the etcd serving CA.\n        scored: true\n\n      - id: 1.2.29\n        text: \"Ensure that encryption providers are appropriately configured (Manual)\"\n        audit: |\n          oc get openshiftapiserver -o=jsonpath='{range .items[0].status.conditions[?(@.type==\"Encrypted\")]}{.reason}{\"\\n\"}{.message}{\"\\n\"}'\n        tests:\n          test_items:\n            - flag: \"EncryptionCompleted\"\n        remediation: |\n          Follow the Kubernetes documentation and configure a EncryptionConfig file.\n          In this file, choose aescbc, kms or secretbox as the encryption provider.\n        scored: true\n\n      - id: 1.2.30\n        text: \"Ensure that the API Server only makes use of Strong Cryptographic Ciphers (Manual)\"\n        type: manual\n        audit: |\n          oc get cm -n openshift-authentication v4-0-config-system-cliconfig -o jsonpath='{.data.v4\\-0\\-config\\-system\\-cliconfig}' | jq .servingInfo\n          oc get kubeapiservers.operator.openshift.io cluster -o json |jq.spec.observedConfig.servingInfo\n          oc get openshiftapiservers.operator.openshift.io cluster -o json |jq.spec.observedConfig.servingInfo\n          oc describe --namespace=openshift-ingress-operator ingresscontroller/default\n        remediation: |\n          Verify that the tlsSecurityProfile is set to the value you chose.\n          Note: The HAProxy Ingress controller image does not support TLS 1.3\n          and because the Modern profile requires TLS 1.3, it is not supported.\n          The Ingress Operator converts the Modern profile to Intermediate.\n          The Ingress Operator also converts the TLS 1.0 of an Old or Custom profile to 1.1,\n          and TLS 1.3 of a Custom profile to 1.2.\n        scored: false\n\n      - id: 1.2.31\n        text: \"Ensure unsupported configuration overrides are not used (Manual)\"\n        audit: |\n          oc get kubeapiserver/cluster -o jsonpath='{.spec.unsupportedConfigOverrides}'\n        tests:\n          test_items:\n            - flag: \"null\"\n        remediation: |\n          No remediation is required.\n          OpenShift has deprecated and disabled unsupportedConfigOverrides.\n          This field should remain null and must not be used in any supported configuration.\n        scored: true\n\n  - id: 1.3\n    text: \"Controller Manager\"\n    checks:\n\n      - id: 1.3.1\n        text: \"Ensure that controller manager healthz endpoints are protected by RBAC (Manual)\"\n        type: manual\n        audit: |\n          # Verify configuration for ports, livenessProbe, readinessProbe, healthz\n          oc -n openshift-kube-controller-manager get cm kube-controller-manager-pod -o json | jq -r '.data.\"pod.yaml\"' | jq '.spec.containers'\n          # Verify endpoints\n          oc -n openshift-kube-controller-manager describe endpoints\n          # Test to validate RBAC enabled on the controller endpoint; check with non-admin role\n          oc project openshift-kube-controller-manage\n          POD=$(oc get pods -n openshift-kube-controller-manager -l app=kube-controller-manager -o jsonpath='{.items[0].metadata.name}')\n          PORT=$(oc get pods -n openshift-kube-controller-manager -l app=kube-controller-manager -o jsonpath='{.items[0].spec.containers[0].ports[0].hostPort}')\n          # Following should return 403 Forbidden\n          oc rsh -n openshift-kube-controller-manager ${POD} curl https://localhost:${PORT}/metrics -k\n          # Create a service account to test RBAC\n          oc create -n openshift-kube-controller-manager sa permission-test-sa\n          # Should return 403 Forbidden\n          SA_TOKEN=$(oc sa -n openshift-kube-controller-manager get-token permission-test-sa)\n          oc rsh -n openshift-kube-controller-manager ${POD} curl https://localhost:${PORT}/metrics -H \"Authorization: Bearer $SA_TOKEN\" -k\n          # Cleanup\n          oc delete -n openshift-kube-controller-manager sa permission-test-sa\n          # As cluster admin, should succeed\n          CLUSTER_ADMIN_TOKEN=$(oc whoami -t)\n          oc rsh -n openshift-kube-controller-manager ${POD} curl https://localhost:${PORT}/metrics -H \"Authorization: Bearer $CLUSTER_ADMIN_TOKEN\" -k\n        remediation: |\n          None required; profiling is protected by RBAC.\n        scored: false\n\n      - id: 1.3.2\n        text: \"Ensure that the --use-service-account-credentials argument is set to true (Manual)\"\n        audit: |\n          oc get configmaps config -n openshift-kube-controller-manager -ojson | \\\n          jq -r '.data[\"config.yaml\"]' | \\\n          jq -r '.extendedArguments[\"use-service-account-credentials\"][]'\n        tests:\n          test_items:\n            - flag: \"true\"\n        remediation: |\n          The OpenShift Controller Manager operator manages and updates the OpenShift Controller Manager.\n          The Kubernetes Controller Manager operator manages and updates the Kubernetes Controller Manager deployed on top of OpenShift.\n          This operator is configured via KubeControllerManager custom resource.\n        scored: true\n\n      - id: 1.3.3\n        text: \"Ensure that the --service-account-private-key-file argument is set as appropriate (Manual)\"\n        audit: |\n          oc get configmaps config -n openshift-kube-controller-manager -ojson | \\\n            jq -r '.data[\"config.yaml\"]' | \\\n            jq -r '.extendedArguments[\"service-account-private-key-file\"][]'\n        tests:\n          test_items:\n            - flag: \"/etc/kubernetes/static-pod-resources/secrets/service-account-private-key/service-account.key\"\n        remediation: |\n          None required.\n          OpenShift manages the service account credentials for the scheduler automatically.\n        scored: true\n\n      - id: 1.3.4\n        text: \"Ensure that the --root-ca-file argument is set as appropriate (Manual)\"\n        audit: |\n          oc get configmaps config -n openshift-kube-controller-manager -ojson | \\\n            jq -r '.data[\"config.yaml\"]' | \\\n            jq -r '.extendedArguments[\"root-ca-file\"][]'\n        tests:\n          test_items:\n            - flag: \"/etc/kubernetes/static-pod-resources/configmaps/serviceaccount-ca/ca-bundle.crt\"\n        remediation: |\n          None required.\n          Certificates for OpenShift platform components are automatically created and rotated by the OpenShift Container Platform.\n        scored: true\n\n\n  - id: 1.4\n    text: \"Scheduler\"\n    checks:\n      - id: 1.4.1\n        text: \"Ensure that the healthz endpoints for the scheduler are protected by RBAC (Manual)\"\n        type: manual\n        audit: |\n          # check configuration for ports, livenessProbe, readinessProbe, healthz\n          oc -n openshift-kube-scheduler get cm kube-scheduler-pod -o json | jq -r '.data.\"pod.yaml\"' | jq '.spec.containers'\n          # Test to verify endpoints\n          oc -n openshift-kube-scheduler describe endpoints\n          # Test to validate RBAC enabled on the scheduler endpoint; check with non-admin role\n          oc project openshift-kube-scheduler\n          POD=$(oc get pods -l app=openshift-kube-scheduler -o jsonpath='{.items[0].metadata.name}')\n          PORT=$(oc get pod $POD -o jsonpath='{.spec.containers[0].livenessProbe.httpGet.port}')\n          # Should return 403 Forbidden\n          oc rsh ${POD} curl http://localhost:${PORT}/metrics -k\n          # Create a service account to test RBAC\n          oc create sa permission-test-sa\n          # Should return 403 Forbidden\n          SA_TOKEN=$(oc sa get-token permission-test-sa)\n          oc rsh ${POD} curl http://localhost:${PORT}/metrics -H \"Authorization: Bearer $SA_TOKEN\" -k\n          # Cleanup\n          oc delete sa permission-test-sa\n          # As cluster admin, should succeed\n          CLUSTER_ADMIN_TOKEN=$(oc whoami -t)\n          oc rsh ${POD} curl http://localhost:${PORT}/metrics -H \"Authorization: Bearer $CLUSTER_ADMIN_TOKEN\" -k\n        remediation: |\n          A fix to this issue: https://bugzilla.redhat.com/show_bug.cgi?id=1889488 None required.\n          Profiling is protected by RBAC and cannot be disabled.\n        scored: false\n\n      - id: 1.4.2\n        text: \"Verify that the scheduler API service is protected by RBAC (Manual)\"\n        type: manual\n        audit: |\n          echo \"Describing kube-scheduler endpoints...\"\n          oc -n openshift-kube-scheduler describe endpoints\n\n          echo \"Checking pod configuration for kube-scheduler to confirm no --bind-address or insecure arguments...\"\n          oc -n openshift-kube-scheduler get cm kube-scheduler-pod -o json \\\n            | jq -r '.data[\"pod.yaml\"]' \\\n            | jq '.spec.containers[] | select(.name==\"kube-scheduler\") | .args'\n\n          echo \"Testing access to metrics endpoint as unauthenticated user...\"\n          oc project openshift-kube-scheduler\n          export POD=$(oc get pods -l app=openshift-kube-scheduler -o jsonpath='{.items[0].metadata.name}')\n          export POD_IP=$(oc get pods -l app=openshift-kube-scheduler -o jsonpath='{.items[0].status.podIP}')\n          export PORT=$(oc get pod $POD -o jsonpath='{.spec.containers[0].livenessProbe.httpGet.port}')\n          oc rsh $POD curl -k -s -o /dev/null -w \"%{http_code}\" https://$POD_IP:$PORT/metrics\n\n          echo \"Testing access with unprivileged service account...\"\n          oc create sa permission-test-sa\n          export SA_TOKEN=$(oc create token permission-test-sa)\n          oc rsh $POD curl -k -s -o /dev/null -w \"%{http_code}\" https://$POD_IP:$PORT/metrics -H \"Authorization: Bearer $SA_TOKEN\"\n\n          echo \"Testing access with cluster-admin...\"\n          export CLUSTER_ADMIN_TOKEN=$(oc whoami -t)\n          oc rsh $POD curl -k -s -o /dev/null -w \"%{http_code}\" https://$POD_IP:$PORT/metrics -H \"Authorization: Bearer $CLUSTER_ADMIN_TOKEN\"\n\n          # Cleanup\n          unset CLUSTER_ADMIN_TOKEN POD PORT SA_TOKEN POD_IP\n          oc delete sa permission-test-sa\n        remediation: |\n          By default, the --bind-address argument is not present,\n          the readinessProbe and livenessProbe arguments are set to 10251 and the port argument is set to 0.\n          Check the status of this issue: https://bugzilla.redhat.com/show_bug.cgi?id=1889488\n        scored: false\n"
  },
  {
    "path": "cfg/rh-1.8/node.yaml",
    "content": "---\ncontrols:\nversion: rh-1.8\nid: 4\ntext: \"Worker Nodes\"\ntype: \"node\"\ngroups:\n  - id: 4.1\n    text: \"Worker Node Configuration Files\"\n    checks:\n      - id: 4.1.1\n        text: \"Ensure that the kubelet service file permissions are set to 644 or more restrictive (Automated)\"\n        audit: |\n          NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')\n          oc debug node/$NODE_NAME -- chroot /host stat -c \"$NODE_NAME %n permissions=%a\" /etc/systemd/system/kubelet.service 2> /dev/null\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          By default, the kubelet service file has permissions of 644.\n        scored: true\n\n      - id: 4.1.2\n        text: \"Ensure that the kubelet service file ownership is set to root:root (Automated)\"\n        audit: |\n          # Should return root:root for each node\n          NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')\n          oc debug node/$NODE_NAME -- chroot /host stat -c \"$NODE_NAME %n %U:%G\" /etc/systemd/system/kubelet.service 2> /dev/null\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          By default, the kubelet service file has ownership of root:root.\n        scored: true\n\n      - id: 4.1.3\n        text: \"If proxy kube proxy configuration file exists ensure permissions are set to 644 or more restrictive (Manual)\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n          # Get the pod name in the openshift-sdn namespace\n          POD_NAME=$(oc get pods -n openshift-sdn -l app=sdn --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n          echo \"No matching pods found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-sdn \"$POD_NAME\" -- stat -Lc \"$i %n permissions=%a\" /config/kube-proxy-config.yaml  2>/dev/null\n          fi\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              set: true\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          None needed.\n        scored: true\n\n      - id: 4.1.4\n        text: \"If proxy kubeconfig file exists ensure ownership is set to root:root (Manual)\"\n        audit: |\n          # Get the node name where the pod is running\n          NODE_NAME=$(oc get pod \"$HOSTNAME\" -o=jsonpath='{.spec.nodeName}')\n          # Get the pod name in the openshift-sdn namespace\n          POD_NAME=$(oc get pods -n openshift-sdn -l app=sdn --field-selector spec.nodeName=\"$NODE_NAME\" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)\n\n          if [ -z \"$POD_NAME\" ]; then\n          echo \"No matching pods found on the current node.\"\n          else\n          # Execute the stat command\n          oc exec -n openshift-sdn \"$POD_NAME\"  -- stat -Lc \"$i %n %U:%G\" /config/kube-proxy-config.yaml  2>/dev/null\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          None required. The configuration is managed by OpenShift operators.\n        scored: true\n\n      - id: 4.1.5\n        text: \"Ensure that the --kubeconfig kubelet.conf file permissions are set to 644 or more restrictive (Manual)\"\n        audit: |\n          # Check permissions\n          NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')\n          oc debug node/$NODE_NAME -- chroot /host stat -c \"$NODE_NAME %n permissions=%a\" /etc/kubernetes/kubelet.conf 2> /dev/null\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          None required.\n        scored: true\n\n      - id: 4.1.6\n        text: \"Ensure that the --kubeconfig kubelet.conf file ownership is set to root:root (Manual)\"\n        audit: |\n          NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')\n          oc debug node/$NODE_NAME -- chroot /host stat -c \"$NODE_NAME %n %U:%G\" /etc/kubernetes/kubelet.conf 2> /dev/null\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          None required.\n        scored: true\n\n      - id: 4.1.7\n        text: \"Ensure that the certificate authorities file permissions are set to 644 or more restrictive\"\n        audit: |\n          NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')\n          oc get --raw /api/v1/nodes/$NODE_NAME/proxy/configz | jq '.kubeletconfig.authentication.x509.clientCAFile'\n          oc debug node/$NODE_NAME -- chroot /host stat -c \"$NODE_NAME permissions=%a\" /etc/kubernetes/kubelet-ca.crt 2> /dev/null\n        tests:\n          test_items:\n            - flag: \"/etc/kubernetes/kubelet-ca.crt\"\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          No remediation required. OpenShift sets /etc/kubernetes/kubelet-ca.crt to 644 by default.\n          If permissions are more permissive than 644, update with: chmod 644 /etc/kubernetes/kubelet-ca.crt\n        scored: true\n\n\n      - id: 4.1.8\n        text: \"Ensure that the client certificate authorities file ownership is set to root:root (Automated)\"\n        audit: |\n          NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')\n          oc debug node/$NODE_NAME -- chroot /host stat -c \"$NODE_NAME %n %U:%G\" /etc/kubernetes/kubelet-ca.crt 2> /dev/null\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          None required.\n        scored: true\n\n      - id: 4.1.9\n        text: \"Ensure that the kubelet --config configuration file has permissions set to 600 or more restrictive (Automated)\"\n        audit: |\n          NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')\n          oc debug node/$NODE_NAME -- chroot /host stat -c \"$NODE_NAME %n permissions=%a\" /var/data/kubelet/config.json 2> /dev/null\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          None required.\n        scored: true\n\n      - id: 4.1.10\n        text: \"Ensure that the kubelet configuration file ownership is set to root:root (Automated)\"\n        audit: |\n          NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')\n          oc debug node/$NODE_NAME -- chroot /host stat -c \"$NODE_NAME %n %U:%G\" /var/data/kubelet/config.json 2> /dev/null\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          None required.\n        scored: true\n\n  - id: 4.2\n    text: \"Kubelet\"\n    checks:\n      - id: 4.2.1\n        text: \"Activate Garbage collection in OpenShift Container Platform 4, as appropriate (Manual)\"\n        audit: |\n          echo \"Retrieving and inspecting garbage collection configuration from node-local kubelet configz...\"\n\n          NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')\n          oc get --raw /api/v1/nodes/$NODE_NAME/proxy/configz | jq '.kubeletconfig'\n        tests:\n          test_items:\n            - flag: \"evictionHard\"\n            - flag: \"imageGCHighThresholdPercent\"\n            - flag: \"imageGCLowThresholdPercent\"\n            - flag: \"imageMinimumGCAge\"\n        remediation: |\n          OpenShift manages node garbage collection through KubeletConfig custom resources per MachineConfigPool.\n          To configure or adjust garbage collection thresholds, follow the documentation:\n          https://docs.openshift.com/container-platform/latest/nodes/nodes/nodes-nodes-garbage-collection.html\n\n          Example: Create or modify a KubeletConfig object to include:\n          ---\n          evictionHard:\n            \"memory.available\": \"200Mi\"\n            \"nodefs.available\": \"10%\"\n            \"imagefs.available\": \"15%\"\n          imageGCHighThresholdPercent: 85\n          imageGCLowThresholdPercent: 80\n          imageMinimumGCAge: \"2m0s\"\n\n          Then apply the `KubeletConfig` to the appropriate `MachineConfigPool`.\n        scored: true\n\n      - id: 4.2.2\n        text: \"Ensure that the --anonymous-auth argument is set to false (Automated)\"\n        audit: |\n          echo \"Checking if anonymous-auth is disabled in kubelet configuration on the current node...\"\n\n          NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')\n          oc get --raw /api/v1/nodes/$NODE_NAME/proxy/configz | jq '.kubeletconfig.authentication.anonymous.enabled'\n        tests:\n          test_items:\n            - flag: \"false\"\n        remediation: |\n          By default, OpenShift sets anonymous-auth to false in Kubelet configuration.\n          If this value is found to be true, create or patch a KubeletConfig object with:\n\n          ---\n          kind: KubeletConfig\n          apiVersion: machineconfiguration.openshift.io/v1\n          metadata:\n            name: disable-anonymous-auth\n          spec:\n            kubeletConfig:\n              authentication:\n                anonymous:\n                  enabled: false\n\n          Then apply this KubeletConfig to the appropriate MachineConfigPool.\n          See OpenShift documentation on configuring node-level security settings.\n        scored: true\n\n      - id: 4.2.3\n        text: \"Ensure that the --authorization-mode argument is not set to AlwaysAllow (Automated)\"\n        audit: |\n          echo \"Checking kubelet authorization mode on the current node...\"\n\n          NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')\n          oc get --raw /api/v1/nodes/$NODE_NAME/proxy/configz | jq '.kubeletconfig.authorization.mode'\n        tests:\n          test_items:\n            - flag: AlwaysAllow\n              set: false\n        remediation: |\n          No remediation required. By default, OpenShift uses secure authorization modes such as 'Webhook' and does not allow AlwaysAllow.\n          If AlwaysAllow is found, the node must be reconfigured using a KubeletConfig applied through the appropriate MachineConfigPool.\n        scored: true\n\n\n      - id: 4.2.4\n        text: \"Ensure that the --client-ca-file argument is set as appropriate (Automated)\"\n        audit: |\n          echo \"Checking Kubelet 'clientCAFile' setting on current node...\"\n\n          NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')\n          oc get --raw /api/v1/nodes/$NODE_NAME/proxy/configz \\\n            | jq '.kubeletconfig.authentication.x509.clientCAFile'\n        tests:\n          test_items:\n            - flag: \"/etc/kubernetes/kubelet-ca.crt\"\n        remediation: |\n          No remediation required. OpenShift sets the clientCAFile by default to /etc/kubernetes/kubelet-ca.crt.\n          Manual modification is unsupported and unnecessary as OpenShift manages Kubelet certificate authentication via the Machine Config Operator.\n        scored: true\n\n\n      - id: 4.2.5\n        text: \"Verify that the read only port is not used or is set to 0 (Automated)\"\n        audit: |\n          echo \"Checking 'kubelet-read-only-port' argument in openshift-kube-apiserver config...\"\n\n          oc -n openshift-kube-apiserver get configmap config -o json \\\n            | jq -r '.data[\"config.yaml\"]' \\\n            | yq '.apiServerArguments.\"kubelet-read-only-port\"[0]'\n        tests:\n          test_items:\n            - flag: \"0\"\n        remediation: |\n          No remediation is required if the read-only port is set to 0.\n          If this value is not set to 0 (or the argument is missing), create a KubeletConfig object and apply it to the appropriate MachineConfigPool to disable the read-only port.\n\n          Example KubeletConfig:\n          ---\n          apiVersion: machineconfiguration.openshift.io/v1\n          kind: KubeletConfig\n          metadata:\n            name: disable-readonly-port\n          spec:\n            kubeletConfig:\n              readOnlyPort: 0\n        scored: true\n\n\n      - id: 4.2.6\n        text: \"Ensure that the --streaming-connection-idle-timeout argument is not set to 0 (automated)\"\n        audit: |\n          NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')\n          oc get --raw /api/v1/nodes/$NODE_NAME/proxy/configz \\\n            | jq '.kubeletconfig'\n        tests:\n          test_items:\n            - path: \".streamingConnectionIdleTimeout\"\n              compare:\n                op: noteq\n                value: \"0s\"\n        remediation: |\n          By default, OpenShift sets streamingConnectionIdleTimeout to 4h0m0s.\n          If it is manually set to \"0s\", this disables timeouts — which is insecure.\n\n          To remediate, create a `KubeletConfig` CR with a safer timeout (e.g., 1h0m0s):\n          ---\n          apiVersion: machineconfiguration.openshift.io/v1\n          kind: KubeletConfig\n          metadata:\n            name: set-streaming-timeout\n          spec:\n            kubeletConfig:\n              streamingConnectionIdleTimeout: \"1h0m0s\"\n        scored: true\n\n      - id: 4.2.7\n        text: \"Ensure that the --make-iptables-util-chains argument is set to true (manual)\"\n        audit: |\n          echo \"Checking 'makeIPTablesUtilChains' setting in Kubelet config on current node...\"\n\n          NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')\n          oc get --raw /api/v1/nodes/$NODE_NAME/proxy/configz \\\n            | jq '.kubeletconfig'\n        tests:\n          test_items:\n            - path: \".makeIPTablesUtilChains\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          No remediation is required.\n          By default, OpenShift sets makeIPTablesUtilChains to true.\n          This allows Kubelet to manage iptables rules and keep them in sync with the dynamic pod network configuration.\n        scored: true\n\n\n      - id: 4.2.8\n        text: \"Ensure that the kubeAPIQPS [--event-qps] argument is set to 0 or a level which ensures appropriate event capture (manual)\"\n        audit: |\n          echo \"Checking 'kubeAPIQPS' setting in Kubelet config on current node...\"\n\n          NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')\n          oc get --raw /api/v1/nodes/$NODE_NAME/proxy/configz \\\n            | jq '.kubeletconfig'\n        tests:\n          test_items:\n            - path: \".kubeAPIQPS\"\n              compare:\n                op: gte\n                value: 1\n        remediation: |\n          OpenShift sets kubeAPIQPS to a default of 50, which is appropriate in most environments.\n          If kubeAPIQPS is set to 0, event rate limiting is disabled, which can overwhelm the kubelet with excessive events.\n\n          To configure a proper limit, create or modify a `KubeletConfig` resource with an appropriate value:\n\n          ---\n          apiVersion: machineconfiguration.openshift.io/v1\n          kind: KubeletConfig\n          metadata:\n            name: set-kubeapiqps\n          spec:\n            kubeletConfig:\n              kubeAPIQPS: 50\n        scored: true\n\n\n      - id: 4.2.9\n        text: \"Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (manual)\"\n        audit: |\n          oc get configmap config -n openshift-kube-apiserver -ojson \\\n            | jq -r '.data[\"config.yaml\"]' \\\n            | jq -r '.apiServerArguments[\"kubelet-client-certificate\"][]?'\n\n          oc get configmap config -n openshift-kube-apiserver -ojson \\\n            | jq -r '.data[\"config.yaml\"]' \\\n            | jq -r '.apiServerArguments[\"kubelet-client-key\"][]?'\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"/etc/kubernetes/static-pod-certs/secrets/kubelet-client/tls.crt\"\n            - flag: \"/etc/kubernetes/static-pod-certs/secrets/kubelet-client/tls.key\"\n        remediation: |\n          No remediation is required. OpenShift manages secure TLS connections to kubelets by default using its internal certificate authority.\n          These X.509 certificates are rotated and validated automatically by the platform.\n          Manual modifications to the TLS paths or keys are not supported and can lead to cluster issues.\n        scored: true\n\n\n      - id: 4.2.10\n        text: \"Ensure that the --rotate-certificates argument is not set to false (manual)\"\n        audit: |\n          NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')\n          oc get --raw /api/v1/nodes/$NODE_NAME/proxy/configz \\\n            | jq '.kubeletconfig'\n        tests:\n          test_items:\n            - path: \".rotateCertificates\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          No remediation required. By default, OpenShift enables certificate rotation via rotateCertificates=true.\n          If disabled, you must either enable rotation via KubeletConfig or implement external certificate renewal.\n\n          Example remediation using KubeletConfig:\n          ---\n          apiVersion: machineconfiguration.openshift.io/v1\n          kind: KubeletConfig\n          metadata:\n            name: enable-cert-rotation\n          spec:\n            kubeletConfig:\n              rotateCertificates: true\n        scored: true\n\n      - id: 4.2.11\n        text: \"Verify that the RotateKubeletServerCertificate argument is set to true (manual)\"\n        audit: |\n          echo \"Checking that RotateKubeletServerCertificate is enabled in kubelet config on current node...\"\n\n          NODE_NAME=$(oc get pod $HOSTNAME -o=jsonpath='{.spec.nodeName}')\n\n          echo \"Verifying feature gate: RotateKubeletServerCertificate\"\n          oc get --raw /api/v1/nodes/$NODE_NAME/proxy/configz \\\n            | jq '.kubeletconfig.featureGates.RotateKubeletServerCertificate'\n\n          echo \"Verifying that certificate rotation is enabled\"\n          oc get --raw /api/v1/nodes/$NODE_NAME/proxy/configz \\\n            | jq '.kubeletconfig.rotateCertificates'\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"RotateKubeletServerCertificate\"\n              compare:\n                op: eq\n                value: true\n            - flag: \"rotateCertificates\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          No remediation is required. OpenShift enables RotateKubeletServerCertificate by default and manages certificate rotation automatically.\n          If the feature gate or rotation setting is disabled, configure a `KubeletConfig` CR and apply it to the MachineConfigPool:\n\n          ---\n          apiVersion: machineconfiguration.openshift.io/v1\n          kind: KubeletConfig\n          metadata:\n            name: enable-server-cert-rotation\n          spec:\n            kubeletConfig:\n              rotateCertificates: true\n              featureGates:\n                RotateKubeletServerCertificate: true\n        scored: true\n\n      - id: 4.2.13\n        text: \"Ensure that the Kubelet only makes use of Strong Cryptographic Ciphers (Manual)\"\n        audit: |\n          # needs verification\n          # verify cipher suites\n          oc describe --namespace=openshift-ingress-operator ingresscontroller/default\n          oc get kubeapiservers.operator.openshift.io cluster -o json |jq .spec.observedConfig.servingInfo\n          oc get openshiftapiservers.operator.openshift.io cluster -o json |jq .spec.observedConfig.servingInfo\n          oc get cm -n openshift-authentication v4-0-config-system-cliconfig -o jsonpath='{.data.v4\\-0\\-config\\-system\\-cliconfig}' | jq .servingInfo\n          #check value for tlsSecurityProfile; null is returned if default is used\n          oc get kubeapiservers.operator.openshift.io cluster -o json |jq .spec.tlsSecurityProfile\n        type: manual\n        remediation: |\n          Follow the directions above and in the OpenShift documentation to configure the tlsSecurityProfile.\n          Configuring Ingress\n        scored: false\n"
  },
  {
    "path": "cfg/rh-1.8/policies.yaml",
    "content": "---\ncontrols:\nversion: rh-1.8\nid: 5\ntext: \"Policies\"\ntype: \"policies\"\ngroups:\n  - id: 5.1\n    text: \"RBAC and Service Accounts\"\n    checks:\n      - id: 5.1.1\n        text: \"Ensure that the cluster-admin role is only used where required (Manual)\"\n        type: \"manual\"\n        audit: |\n          #To get a list of users and service accounts with the cluster-admin role\n          oc get clusterrolebindings -o=customcolumns=NAME:.metadata.name,ROLE:.roleRef.name,SUBJECT:.subjects[*].kind |\n          grep cluster-admin\n          #To verity that kbueadmin is removed, no results should be returned\n          oc get secrets kubeadmin -n kube-system\n        remediation: |\n          Identify all clusterrolebindings to the cluster-admin role. Check if they are used and if they need this role or if they could use a role with fewer privileges.\n          Where possible, first bind users to a lower privileged role and then remove the clusterrolebinding to the cluster-admin role :\n            oc delete clusterrolebinding [name]\n        scored: false\n\n      - id: 5.1.2\n        text: \"Minimize access to secrets (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove get, list and watch access to secret objects in the cluster.\n        scored: false\n\n      - id: 5.1.3\n        text: \"Minimize wildcard use in Roles and ClusterRoles (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible replace any use of wildcards in clusterroles and roles with specific\n          objects or actions.\n        scored: false\n\n      - id: 5.1.4\n        text: \"Minimize access to create pods (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove create access to pod objects in the cluster.\n        scored: false\n\n      - id: 5.1.5\n        text: \"Ensure that default service accounts are not actively used. (Manual)\"\n        type: \"manual\"\n        remediation: |\n          None required.\n        scored: false\n\n      - id: 5.1.6\n        text: \"Ensure that Service Account Tokens are only mounted where necessary (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Modify the definition of pods and service accounts which do not need to mount service\n          account tokens to disable it.\n        scored: false\n\n  - id: 5.2\n    text: \"Security Context Constraints (SCCs)\"\n    checks:\n      - id: 5.2.1\n        text: \"Minimize the admission of privileged containers (Manual)\"\n        audit: |\n          oc get scc -o json \\\n          | jq -r '[.items[] | select(.allowPrivilegedContainer==false) | .metadata.name]\n                   | length\n                   | if . > 0 then \"pass\" else \"fail\" end'\n        tests:\n          test_items:\n            - flag: \"pass\"\n        remediation: |\n          If no SCCs exist that restrict privileged containers, create one by running:\n\n          oc create -f - <<EOF\n          apiVersion: security.openshift.io/v1\n          kind: SecurityContextConstraints\n          metadata:\n            name: restricted-no-priv\n          allowPrivilegedContainer: false\n          runAsUser:\n            type: MustRunAsRange\n          seLinuxContext:\n            type: MustRunAs\n          users: []\n          groups:\n          - system:authenticated\n          EOF\n\n          Then apply appropriate RBAC to assign this SCC only to necessary service accounts, groups, or users.\n          Carefully avoid assigning `allowPrivilegedContainer: true` in any SCC that is broadly bound.\n        scored: true\n\n      - id: 5.2.2\n        text: \"Minimize the admission of containers wishing to share the host process ID namespace (Manual)\"\n        audit: |\n          oc get scc -o json \\\n            | jq -r '[.items[] | select(.allowHostPID==true) | .metadata.name]\n                     | length\n                     | if . > 0 then \"pass\" else \"fail\" end'\n        tests:\n          test_items:\n            - flag: \"pass\"\n        remediation: |\n          If SCCs with `allowHostPID: true` exist, ensure they are restricted to trusted service accounts only.\n\n          To create a restrictive SCC that prevents host PID sharing:\n\n          ---\n          apiVersion: security.openshift.io/v1\n          kind: SecurityContextConstraints\n          metadata:\n            name: restricted-no-hostpid\n          allowHostPID: false\n          runAsUser:\n            type: MustRunAsRange\n          seLinuxContext:\n            type: MustRunAs\n          users: []\n          groups:\n          - system:authenticated\n          ---\n\n          Apply the SCC and bind it only to users or groups that do **not** need hostPID access.\n        scored: true\n\n      - id: 5.2.3\n        text: \"Minimize the admission of containers wishing to share the host IPC namespace (Manual)\"\n        audit: |\n          oc get scc -o json \\\n            | jq -r '[.items[] | select(.allowHostIPC==false) | .metadata.name]\n                     | length\n                     | if . > 0 then \"pass\" else \"fail\" end'\n        tests:\n          test_items:\n            - flag: \"pass\"\n        remediation: |\n          If no SCCs restrict hostIPC usage, create one that explicitly sets allowHostIPC: false:\n\n          ---\n          apiVersion: security.openshift.io/v1\n          kind: SecurityContextConstraints\n          metadata:\n            name: restricted-no-hostipc\n          allowHostIPC: false\n          runAsUser:\n            type: MustRunAsRange\n          seLinuxContext:\n            type: MustRunAs\n          users: []\n          groups:\n          - system:authenticated\n          ---\n\n          Then assign this SCC to general workloads and ensure any SCCs allowing hostIPC are tightly scoped via RBAC.\n        scored: true\n\n      - id: 5.2.4\n        text: \"Minimize the admission of containers wishing to share the host network namespace (manual)\"\n        audit: |\n          oc get scc -o json \\\n            | jq -r '[.items[] | select(.allowHostNetwork==false) | .metadata.name]\n                     | length\n                     | if . > 0 then \"pass\" else \"fail\" end'\n        tests:\n          test_items:\n            - flag: \"pass\"\n        remediation: |\n          If no SCCs restrict host networking, create one by running:\n\n          ---\n          apiVersion: security.openshift.io/v1\n          kind: SecurityContextConstraints\n          metadata:\n            name: restricted-no-hostnetwork\n          allowHostNetwork: false\n          runAsUser:\n            type: MustRunAsRange\n          seLinuxContext:\n            type: MustRunAs\n          users: []\n          groups:\n          - system:authenticated\n          ---\n\n          Ensure only workloads that require `hostNetwork: true` (e.g., CNI, infra pods) are allowed to use SCCs where it is explicitly enabled. Restrict access to such SCCs using RBAC.\n        scored: true\n\n      - id: 5.2.5\n        text: \"Minimize the admission of containers with allowPrivilegeEscalation (manual)\"\n        audit: |\n          oc get scc -o json \\\n            | jq -r '[.items[] | select(.allowPrivilegeEscalation==false) | .metadata.name]\n                     | length\n                     | if . > 0 then \"pass\" else \"fail\" end'\n        tests:\n          test_items:\n            - flag: \"pass\"\n        remediation: |\n          If no SCCs exist that restrict the use of privilege escalation, create a custom SCC:\n\n          ---\n          apiVersion: security.openshift.io/v1\n          kind: SecurityContextConstraints\n          metadata:\n            name: restricted-no-priv-escalation\n          allowPrivilegeEscalation: false\n          runAsUser:\n            type: MustRunAsRange\n          seLinuxContext:\n            type: MustRunAs\n          users: []\n          groups:\n          - system:authenticated\n          ---\n\n          Assign this SCC only to workloads and users that **do not require** the ability to escalate privileges.\n          Use RBAC to restrict access to SCCs where `allowPrivilegeEscalation` is `true` to only trusted service accounts or admin roles.\n        scored: true\n\n\n      - id: 5.2.6\n        text: \"Minimize the admission of root containers (manual)\"\n        audit: |\n          sccs=$(oc get scc -o json | jq -r '.items[] | select(.runAsUser.type == \"MustRunAsNonRoot\") | .metadata.name')\n          if [[ -n \"$sccs\" ]]; then\n            echo \"pass\"\n          else\n            echo \"fail\"\n          fi\n        tests:\n          test_items:\n            - flag: \"pass\"\n        remediation: |\n          If no SCC is found with `runAsUser.type: MustRunAsNonRoot`, create one as follows:\n\n          ---\n          apiVersion: security.openshift.io/v1\n          kind: SecurityContextConstraints\n          metadata:\n            name: restricted-nonroot\n          allowPrivilegeEscalation: false\n          runAsUser:\n            type: MustRunAsNonRoot\n          seLinuxContext:\n            type: MustRunAs\n          users: []\n          groups:\n          - system:authenticated\n          ---\n\n          Assign this SCC only to workloads that must not run as root.\n          If an SCC allows `RunAsAny`, audit and restrict access using RBAC to prevent misuse.\n        scored: true\n\n      - id: 5.2.7\n        text: \"Minimize the admission of containers with the NET_RAW capability (manual)\"\n        audit: |\n          oc get scc -o json \\\n          | jq -r '[.items[]\n                    | select((.requiredDropCapabilities // []) | index(\"ALL\"))\n                    | .metadata.name]\n                   | length\n                   | if . > 0 then \"pass\" else \"fail\" end'\n        tests:\n          test_items:\n            - flag: \"pass\"\n        remediation: |\n          If no SCCs drop ALL capabilities, create a custom SCC that explicitly drops NET_RAW:\n\n          ---\n          apiVersion: security.openshift.io/v1\n          kind: SecurityContextConstraints\n          metadata:\n            name: restricted-no-netraw\n          requiredDropCapabilities:\n          - NET_RAW\n          allowPrivilegedContainer: false\n          runAsUser:\n            type: MustRunAsRange\n          seLinuxContext:\n            type: MustRunAs\n          users: []\n          groups:\n          - system:authenticated\n          ---\n\n          Apply this SCC to workloads that do not require NET_RAW.\n          If NET_RAW is required (e.g., for low-level networking apps), isolate those workloads with a specific SCC and restrict access via RBAC.\n        scored: true\n\n\n      - id: 5.2.8\n        text: \"Minimize the admission of containers with added capabilities (manual)\"\n        audit: |\n          oc get scc -o json \\\n          | jq -r '[.items[]\n                    | select(.allowedCapabilities == null)\n                    | .metadata.name]\n                   | length\n                   | if . > 0 then \"pass\" else \"fail\" end'\n          oc get scc -o json \\\n          | jq -r '[.items[]\n                    | select(.defaultAddCapabilities == null)\n                    | .metadata.name]\n                   | length\n                   | if . > 0 then \"true\" else \"false\" end'\n        tests:\n          test_items:\n            - flag: \"pass\"\n            - flag: \"true\"\n        remediation: |\n          If no SCCs restrict added capabilities, create a custom SCC as shown below:\n\n          ---\n          apiVersion: security.openshift.io/v1\n          kind: SecurityContextConstraints\n          metadata:\n            name: restricted-no-added-caps\n          allowPrivilegedContainer: false\n          allowedCapabilities: []\n          defaultAddCapabilities: []\n          runAsUser:\n            type: MustRunAsRange\n          seLinuxContext:\n            type: MustRunAs\n          users: []\n          groups:\n          - system:authenticated\n          ---\n\n          Assign this SCC to workloads that do **not** require elevated capabilities.\n          Create separate SCCs for workloads that require specific capabilities, and use RBAC to tightly restrict access to them.\n        scored: true\n\n      - id: 5.2.9\n        text: \"Minimize the admission of containers with capabilities assigned (manual)\"\n        audit: |\n          oc get scc -o json \\\n          | jq -r '[.items[]\n                    | select((.requiredDropCapabilities // []) | index(\"ALL\"))\n                    | .metadata.name]\n                   | length\n                   | if . > 0 then \"true\" else \"false\" end'\n        tests:\n          test_items:\n            - flag: \"true\"\n        remediation: |\n          If no SCCs drop all capabilities, create one that sets 'requiredDropCapabilities: [ALL]':\n\n          ---\n          apiVersion: security.openshift.io/v1\n          kind: SecurityContextConstraints\n          metadata:\n            name: restricted-drop-all-capabilities\n          requiredDropCapabilities:\n          - ALL\n          allowPrivilegedContainer: false\n          runAsUser:\n            type: MustRunAsRange\n          seLinuxContext:\n            type: MustRunAs\n          users: []\n          groups:\n          - system:authenticated\n          ---\n\n          Apply this SCC to general-purpose workloads that do not require elevated Linux capabilities.\n          If certain workloads require capabilities, create a separate SCC with minimal permissions and scope it using RBAC.\n        scored: true\n\n      - id: 5.2.10\n        text: \"Minimize access to privileged Security Context Constraints (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Remove any users and groups who do not need access to an SCC, following the\n          principle of least privilege.\n          You can remove users and groups from an SCC using the oc edit scc $NAME\n          command.\n          Additionally, you can create your own SCCs that contain the container functionality you\n          need for a particular use case and assign that SCC to users and groups if the default\n          SCCs are not appropriate for your use case.\n        scored: false\n\n\n  - id: 5.3\n    text: \"Network Policies and CNI\"\n    checks:\n      - id: 5.3.1\n        text: \"Ensure that the CNI in use supports Network Policies (Manual)\"\n        type: \"manual\"\n        remediation: |\n          None required.\n        scored: false\n\n      - id: 5.3.2\n        text: \"Ensure that all Namespaces have Network Policies defined (Manual)\"\n        type: \"manual\"\n        audit: |\n          #Run the following command and review the NetworkPolicy objects created in the cluster.\n          oc -n all get networkpolicy\n        remediation: |\n          Follow the documentation and create NetworkPolicy objects as you need them.\n        scored: false\n\n  - id: 5.4\n    text: \"Secrets Management\"\n    checks:\n      - id: 5.4.1\n        text: \"Prefer using secrets as files over secrets as environment variables (Manual)\"\n        type: \"manual\"\n        audit: |\n          #Run the following command to find references to objects which use environment variables defined from secrets.\n          oc get all -o jsonpath='{range .items[?(@..secretKeyRef)]} {.kind}\n          {.metadata.name} {\"\\n\"}{end}' -A\n        remediation: |\n          If possible, rewrite application code to read secrets from mounted secret files, rather than\n          from environment variables.\n        scored: false\n\n      - id: 5.4.2\n        text: \"Consider external secret storage (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Refer to the secrets management options offered by your cloud provider or a third-party\n          secrets management solution.\n        scored: false\n\n  - id: 5.5\n    text: \"Extensible Admission Control\"\n    checks:\n      - id: 5.5.1\n        text: \"Configure Image Provenance using image controller configuration parameters (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the OpenShift documentation: [Image configuration resources](https://docs.openshift.com/container-platform/4.5/openshift_images/image-configuration.html\n        scored: false\n\n  - id: 5.7\n    text: \"General Policies\"\n    checks:\n      - id: 5.7.1\n        text: \"Create administrative boundaries between resources using namespaces (Manual)\"\n        type: \"manual\"\n        audit: |\n          #Run the following command and review the namespaces created in the cluster.\n          oc get namespaces\n          #Ensure that these namespaces are the ones you need and are adequately administered as per your requirements.\n        remediation: |\n          Follow the documentation and create namespaces for objects in your deployment as you need\n          them.\n        scored: false\n\n      - id: 5.7.2\n        text: \"Ensure that the seccomp profile is set to docker/default in your pod definitions (Manual)\"\n        type: \"manual\"\n        remediation: |\n          To enable the default seccomp profile, use the reserved value /runtime/default that will\n          make sure that the pod uses the default policy available on the host.\n        scored: false\n\n      - id: 5.7.3\n        text: \"Apply Security Context to Your Pods and Containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and apply security contexts to your pods. For a\n          suggested list of security contexts, you may refer to the CIS Security Benchmark for Docker\n          Containers.\n        scored: false\n\n      - id: 5.7.4\n        text: \"The default namespace should not be used (Manual)\"\n        type: \"manual\"\n        audit: |\n          #Run this command to list objects in default namespace\n          oc project default\n          oc get all\n          #The only entries there should be system managed resources such as the kubernetes and openshift service\n        remediation: |\n          Ensure that namespaces are created to allow for appropriate segregation of Kubernetes\n          resources and that all new resources are created in a specific namespace.\n        scored: false\n"
  },
  {
    "path": "cfg/rke-cis-1.23/config.yaml",
    "content": "---\n## Version-specific settings that override the values in cfg/config.yaml\n"
  },
  {
    "path": "cfg/rke-cis-1.23/controlplane.yaml",
    "content": "---\ncontrols:\nversion: \"rke-cis-1.23\"\nid: 3\ntext: \"Control Plane Configuration\"\ntype: \"controlplane\"\ngroups:\n  - id: 3.1\n    text: \"Authentication and Authorization\"\n    checks:\n      - id: 3.1.1\n        text: \"Client certificate authentication should not be used for users (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Alternative mechanisms provided by Kubernetes such as the use of OIDC should be\n          implemented in place of client certificates.\n        scored: false\n\n  - id: 3.2\n    text: \"Logging\"\n    checks:\n      - id: 3.2.1\n        text: \"Ensure that a minimal audit policy is created (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-policy-file\"\n              set: true\n        remediation: |\n          Create an audit policy file for your cluster.\n        scored: true\n\n      - id: 3.2.2\n        text: \"Ensure that the audit policy covers key security concerns (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Review the audit policy provided for the cluster and ensure that it covers\n          at least the following areas,\n          - Access to Secrets managed by the cluster. Care should be taken to only\n            log Metadata for requests to Secrets, ConfigMaps, and TokenReviews, in\n            order to avoid risk of logging sensitive data.\n          - Modification of Pod and Deployment objects.\n          - Use of `pods/exec`, `pods/portforward`, `pods/proxy` and `services/proxy`.\n          For most requests, minimally logging at the Metadata level is recommended\n          (the most basic level of logging).\n        scored: false\n"
  },
  {
    "path": "cfg/rke-cis-1.23/etcd.yaml",
    "content": "---\ncontrols:\nversion: \"rke-cis-1.23\"\nid: 2\ntext: \"Etcd Node Configuration\"\ntype: \"etcd\"\ngroups:\n  - id: 2\n    text: \"Etcd Node Configuration\"\n    checks:\n      - id: 2.1\n        text: \"Ensure that the --cert-file and --key-file arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--cert-file\"\n              env: \"ETCD_CERT_FILE\"\n              set: true\n            - flag: \"--key-file\"\n              env: \"ETCD_KEY_FILE\"\n              set: true\n        remediation: |\n          Follow the etcd service documentation and configure TLS encryption.\n          Then, edit the etcd pod specification file /etc/kubernetes/manifests/etcd.yaml\n          on the master node and set the below parameters.\n          --cert-file=</path/to/ca-file>\n          --key-file=</path/to/key-file>\n        scored: true\n\n      - id: 2.2\n        text: \"Ensure that the --client-cert-auth argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--client-cert-auth\"\n              set: true\n            - flag: \"--client-cert-auth\"\n              env: \"ETCD_CLIENT_CERT_AUTH\"\n              compare:\n                op: eq\n                value: true\n              set: true\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and set the below parameter.\n          --client-cert-auth=\"true\"\n        scored: true\n\n      - id: 2.3\n        text: \"Ensure that the --auto-tls argument is not set to true (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--auto-tls\"\n              env: \"ETCD_AUTO_TLS\"\n              set: false\n            - flag: \"--auto-tls\"\n              env: \"ETCD_AUTO_TLS\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and either remove the --auto-tls parameter or set it to false.\n            --auto-tls=false\n        scored: true\n\n      - id: 2.4\n        text: \"Ensure that the --peer-cert-file and --peer-key-file arguments are\n        set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--peer-cert-file\"\n              env: \"ETCD_PEER_CERT_FILE\"\n              set: true\n            - flag: \"--peer-key-file\"\n              env: \"ETCD_PEER_KEY_FILE\"\n              set: true\n        remediation: |\n          Follow the etcd service documentation and configure peer TLS encryption as appropriate\n          for your etcd cluster.\n          Then, edit the etcd pod specification file $etcdconf on the\n          master node and set the below parameters.\n          --peer-client-file=</path/to/peer-cert-file>\n          --peer-key-file=</path/to/peer-key-file>\n        scored: true\n\n      - id: 2.5\n        text: \"Ensure that the --peer-client-cert-auth argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--peer-client-cert-auth\"\n              set: true\n            - flag: \"--peer-client-cert-auth\"\n              env: \"ETCD_PEER_CLIENT_CERT_AUTH\"\n              compare:\n                op: eq\n                value: true\n              set: true\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and set the below parameter.\n          --peer-client-cert-auth=true\n        scored: true\n\n      - id: 2.6\n        text: \"Ensure that the --peer-auto-tls argument is not set to true (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--peer-auto-tls\"\n              env: \"ETCD_PEER_AUTO_TLS\"\n              set: false\n            - flag: \"--peer-auto-tls\"\n              env: \"ETCD_PEER_AUTO_TLS\"\n              compare:\n                op: eq\n                value: false\n              set: false\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and either remove the --peer-auto-tls parameter or set it to false.\n          --peer-auto-tls=false\n        scored: true\n\n      - id: 2.7\n        text: \"Ensure that a unique Certificate Authority is used for etcd (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--trusted-ca-file\"\n              env: \"ETCD_TRUSTED_CA_FILE\"\n              set: true\n        remediation: |\n          [Manual test]\n          Follow the etcd documentation and create a dedicated certificate authority setup for the\n          etcd service.\n          Then, edit the etcd pod specification file $etcdconf on the\n          master node and set the below parameter.\n          --trusted-ca-file=</path/to/ca-file>\n        scored: true\n"
  },
  {
    "path": "cfg/rke-cis-1.23/master.yaml",
    "content": "---\ncontrols:\nversion: \"rke-cis-1.23\"\nid: 1\ntext: \"Control Plane Security Configuration\"\ntype: \"master\"\ngroups:\n  - id: 1.1\n    text: \"Control Plane Node Configuration Files\"\n    checks:\n      - id: 1.1.1\n        text: \"Ensure that the API server pod specification file permissions are set to 644 or more restrictive (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/sh -c 'if test -e $apiserverconf; then stat -c permissions=%a $apiserverconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Clusters provisioned by RKE do not require or maintain a configuration file for kube-apiserver.\n          All configuration is passed in as arguments at container run time.\n        scored: true\n\n      - id: 1.1.2\n        text: \"Ensure that the API server pod specification file ownership is set to root:root (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/sh -c 'if test -e $apiserverconf; then stat -c %U:%G $apiserverconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Cluster provisioned by RKE doesn't require or maintain a configuration file for kube-apiserver.\n          All configuration is passed in as arguments at container run time.\n        scored: true\n\n      - id: 1.1.3\n        text: \"Ensure that the controller manager pod specification file permissions are set to 644 or more restrictive (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerconf; then stat -c permissions=%a $controllermanagerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Cluster provisioned by RKE doesn't require or maintain a configuration file for controller-manager.\n          All configuration is passed in as arguments at container run time.\n        scored: true\n\n      - id: 1.1.4\n        text: \"Ensure that the controller manager pod specification file ownership is set to root:root (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerconf; then stat -c %U:%G $controllermanagerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Cluster provisioned by RKE doesn't require or maintain a configuration file for controller-manager.\n          All configuration is passed in as arguments at container run time.\n        scored: true\n\n      - id: 1.1.5\n        text: \"Ensure that the scheduler pod specification file permissions are set to 644 or more restrictive (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/sh -c 'if test -e $schedulerconf; then stat -c permissions=%a $schedulerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Cluster provisioned by RKE doesn't require or maintain a configuration file for scheduler.\n          All configuration is passed in as arguments at container run time.\n        scored: true\n\n      - id: 1.1.6\n        text: \"Ensure that the scheduler pod specification file ownership is set to root:root (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/sh -c 'if test -e $schedulerconf; then stat -c %U:%G $schedulerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Cluster provisioned by RKE doesn't require or maintain a configuration file for scheduler.\n          All configuration is passed in as arguments at container run time.\n        scored: true\n\n      - id: 1.1.7\n        text: \"Ensure that the etcd pod specification file permissions are set to 644 or more restrictive (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/sh -c 'if test -e $etcdconf; then find $etcdconf -name '*etcd*' | xargs stat -c permissions=%a; fi'\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Cluster provisioned by RKE doesn't require or maintain a configuration file for etcd.\n          All configuration is passed in as arguments at container run time.\n        scored: true\n\n      - id: 1.1.8\n        text: \"Ensure that the etcd pod specification file ownership is set to root:root (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/sh -c 'if test -e $etcdconf; then find $etcdconf -name '*etcd*' | xargs stat -c %U:%G; fi'\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Cluster provisioned by RKE doesn't require or maintain a configuration file for etcd.\n          All configuration is passed in as arguments at container run time.\n        scored: true\n\n      - id: 1.1.9\n        text: \"Ensure that the Container Network Interface file permissions are set to 644 or more restrictive (Manual)\"\n        audit: |\n          ps -ef | grep $kubeletbin | grep -- --cni-conf-dir | sed 's%.*cni-conf-dir[= ]\\([^ ]*\\).*%\\1%' | xargs -I{} find {} -mindepth 1 | xargs --no-run-if-empty stat -c permissions=%a\n          find /var/lib/cni/networks -type f 2> /dev/null | xargs --no-run-if-empty stat -c permissions=%a\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chmod 644 <path/to/cni/files>\n        scored: false\n\n      - id: 1.1.10\n        text: \"Ensure that the Container Network Interface file ownership is set to root:root (Manual)\"\n        audit: |\n          ps -ef | grep $kubeletbin | grep -- --cni-conf-dir | sed 's%.*cni-conf-dir[= ]\\([^ ]*\\).*%\\1%' | xargs -I{} find {} -mindepth 1 | xargs --no-run-if-empty stat -c %U:%G\n          find /var/lib/cni/networks -type f 2> /dev/null | xargs --no-run-if-empty stat -c %U:%G\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root <path/to/cni/files>\n        scored: false\n\n      - id: 1.1.11\n        text: \"Ensure that the etcd data directory permissions are set to 700 or more restrictive (Automated)\"\n        audit: stat -c %a /var/lib/etcd\n        tests:\n          test_items:\n            - flag: \"700\"\n              compare:\n                op: eq\n                value: \"700\"\n              set: true\n        remediation: |\n          On the etcd server node, get the etcd data directory, passed as an argument --data-dir,\n          from the command 'ps -ef | grep etcd'.\n          Run the below command (based on the etcd data directory found above). For example,\n          chmod 700 /var/lib/etcd\n        scored: true\n\n      - id: 1.1.12\n        text: \"Ensure that the etcd data directory ownership is set to etcd:etcd (Automated)\"\n        type: \"skip\"\n        audit: \"stat -c %U:%G /node/var/lib/etcd\"\n        tests:\n          test_items:\n            - flag: \"etcd:etcd\"\n              set: true\n        remediation: |\n          On the etcd server node, get the etcd data directory, passed as an argument --data-dir,\n          from the command 'ps -ef | grep etcd'.\n          Run the below command (based on the etcd data directory found above).\n          For example, chown etcd:etcd /var/lib/etcd\n        scored: true\n\n      - id: 1.1.13\n        text: \"Ensure that the admin.conf file permissions are set to 600 or more restrictive (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/sh -c 'if test -e /etc/kubernetes/admin.conf; then stat -c permissions=%a /etc/kubernetes/admin.conf; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          A cluster provisioned by RKE does not store the kubernetes default kubeconfig credentials file on the nodes.\n        scored: true\n\n      - id: 1.1.14\n        text: \"Ensure that the admin.conf file ownership is set to root:root (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/sh -c 'if test -e /etc/kubernetes/admin.conf; then stat -c %U:%G /etc/kubernetes/admin.conf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Cluster provisioned by RKE does not store the kubernetes default kubeconfig credentials file on the nodes.\n        scored: true\n\n      - id: 1.1.15\n        text: \"Ensure that the scheduler.conf file permissions are set to 644 or more restrictive (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/sh -c 'if test -e $schedulerkubeconfig; then stat -c permissions=%a $schedulerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Cluster provisioned by RKE doesn't require or maintain a configuration file for scheduler.\n          All configuration is passed in as arguments at container run time.\n        scored: true\n\n      - id: 1.1.16\n        text: \"Ensure that the scheduler.conf file ownership is set to root:root (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/sh -c 'if test -e $schedulerkubeconfig; then stat -c %U:%G $schedulerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Cluster provisioned by RKE doesn't require or maintain a configuration file for scheduler.\n          All configuration is passed in as arguments at container run time.\n        scored: true\n\n      - id: 1.1.17\n        text: \"Ensure that the controller-manager.conf file permissions are set to 644 or more restrictive (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerkubeconfig; then stat -c permissions=%a $controllermanagerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Cluster provisioned by RKE doesn't require or maintain a configuration file for controller-manager.\n          All configuration is passed in as arguments at container run time.\n        scored: true\n\n      - id: 1.1.18\n        text: \"Ensure that the controller-manager.conf file ownership is set to root:root (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerkubeconfig; then stat -c %U:%G $controllermanagerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Cluster provisioned by RKE doesn't require or maintain a configuration file for controller-manager.\n          All configuration is passed in as arguments at container run time.\n        scored: true\n\n      - id: 1.1.19\n        text: \"Ensure that the Kubernetes PKI directory and file ownership is set to root:root (Automated)\"\n        audit: \"check_files_owner_in_dir.sh /etc/kubernetes/ssl\"\n        tests:\n          test_items:\n            - flag: \"true\"\n              compare:\n                op: eq\n                value: \"true\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown -R root:root /etc/kubernetes/pki/\n        scored: true\n\n      - id: 1.1.20\n        text: \"Ensure that the Kubernetes PKI certificate file permissions are set to 644 or more restrictive (Manual)\"\n        audit: \"find /etc/kubernetes/pki/ -name '*.crt' | xargs stat -c permissions=%a\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod -R 644 /etc/kubernetes/pki/*.crt\n        scored: false\n\n      - id: 1.1.21\n        text: \"Ensure that the Kubernetes PKI key file permissions are set to 600 (Manual)\"\n        audit: \"find /etc/kubernetes/pki/ -name '*.key' | xargs stat -c permissions=%a\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod -R 600 /etc/kubernetes/pki/*.key\n        scored: false\n\n  - id: 1.2\n    text: \"API Server\"\n    checks:\n      - id: 1.2.1\n        text: \"Ensure that the --anonymous-auth argument is set to false (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--anonymous-auth\"\n              compare:\n                op: eq\n                value: false\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the below parameter.\n          --anonymous-auth=false\n        scored: true\n\n      - id: 1.2.2\n        text: \"Ensure that the --token-auth-file parameter is not set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--token-auth-file\"\n              set: false\n        remediation: |\n          Follow the documentation and configure alternate mechanisms for authentication. Then,\n          edit the API server pod specification file $apiserverconf\n          on the control plane node and remove the --token-auth-file=<filename> parameter.\n        scored: true\n\n      - id: 1.2.3\n        text: \"Ensure that the --DenyServiceExternalIPs is not set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: nothave\n                value: \"DenyServiceExternalIPs\"\n              set: true\n            - flag: \"--enable-admission-plugins\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and remove the `DenyServiceExternalIPs`\n          from enabled admission plugins.\n        scored: true\n\n      - id: 1.2.4\n        text: \"Ensure that the --kubelet-https argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--kubelet-https\"\n              compare:\n                op: eq\n                value: true\n            - flag: \"--kubelet-https\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and remove the --kubelet-https parameter.\n        scored: true\n\n      - id: 1.2.5\n        text: \"Ensure that the --kubelet-client-certificate and --kubelet-client-key arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--kubelet-client-certificate\"\n              set: true\n            - flag: \"--kubelet-client-key\"\n              set: true\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection between the\n          apiserver and kubelets. Then, edit API server pod specification file\n          $apiserverconf on the control plane node and set the\n          kubelet client certificate and key parameters as below.\n          --kubelet-client-certificate=<path/to/client-certificate-file>\n          --kubelet-client-key=<path/to/client-key-file>\n        scored: true\n\n      - id: 1.2.6\n        text: \"Ensure that the --kubelet-certificate-authority argument is set as appropriate (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--kubelet-certificate-authority\"\n              set: true\n        remediation: |\n          Follow the Kubernetes documentation and setup the TLS connection between\n          the apiserver and kubelets. Then, edit the API server pod specification file\n          $apiserverconf on the control plane node and set the\n          --kubelet-certificate-authority parameter to the path to the cert file for the certificate authority.\n          --kubelet-certificate-authority=<ca-string>\n          When generating serving certificates, functionality could break in conjunction with hostname overrides which are required for certain cloud providers.\n        scored: true\n\n      - id: 1.2.7\n        text: \"Ensure that the --authorization-mode argument is not set to AlwaysAllow (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: nothave\n                value: \"AlwaysAllow\"\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --authorization-mode parameter to values other than AlwaysAllow.\n          One such example could be as below.\n          --authorization-mode=RBAC\n        scored: true\n\n      - id: 1.2.8\n        text: \"Ensure that the --authorization-mode argument includes Node (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: has\n                value: \"Node\"\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --authorization-mode parameter to a value that includes Node.\n          --authorization-mode=Node,RBAC\n        scored: true\n\n      - id: 1.2.9\n        text: \"Ensure that the --authorization-mode argument includes RBAC (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: has\n                value: \"RBAC\"\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --authorization-mode parameter to a value that includes RBAC,\n          for example `--authorization-mode=Node,RBAC`.\n        scored: true\n\n      - id: 1.2.10\n        text: \"Ensure that the admission control plugin EventRateLimit is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"EventRateLimit\"\n              set: true\n        remediation: |\n          Follow the Kubernetes documentation and set the desired limits in a configuration file.\n          Then, edit the API server pod specification file $apiserverconf\n          and set the below parameters.\n          --enable-admission-plugins=...,EventRateLimit,...\n          --admission-control-config-file=<path/to/configuration/file>\n        scored: false\n\n      - id: 1.2.11\n        text: \"Ensure that the admission control plugin AlwaysAdmit is not set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: nothave\n                value: AlwaysAdmit\n              set: true\n            - flag: \"--enable-admission-plugins\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and either remove the --enable-admission-plugins parameter, or set it to a\n          value that does not include AlwaysAdmit.\n        scored: true\n\n      - id: 1.2.12\n        text: \"Ensure that the admission control plugin AlwaysPullImages is set (Manual)\"\n        type: \"manual\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"AlwaysPullImages\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --enable-admission-plugins parameter to include\n          AlwaysPullImages.\n          --enable-admission-plugins=...,AlwaysPullImages,...\n        scored: false\n\n      - id: 1.2.13\n        text: \"Ensure that the admission control plugin SecurityContextDeny is set if PodSecurityPolicy is not used (Manual)\"\n        type: \"manual\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"SecurityContextDeny\"\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"PodSecurityPolicy\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --enable-admission-plugins parameter to include\n          SecurityContextDeny, unless PodSecurityPolicy is already in place.\n          --enable-admission-plugins=...,SecurityContextDeny,...\n        scored: false\n\n      - id: 1.2.14\n        text: \"Ensure that the admission control plugin ServiceAccount is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--disable-admission-plugins\"\n              compare:\n                op: nothave\n                value: \"ServiceAccount\"\n              set: true\n            - flag: \"--disable-admission-plugins\"\n              set: false\n        remediation: |\n          Follow the documentation and create ServiceAccount objects as per your environment.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and ensure that the --disable-admission-plugins parameter is set to a\n          value that does not include ServiceAccount.\n        scored: true\n\n      - id: 1.2.15\n        text: \"Ensure that the admission control plugin NamespaceLifecycle is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--disable-admission-plugins\"\n              compare:\n                op: nothave\n                value: \"NamespaceLifecycle\"\n              set: true\n            - flag: \"--disable-admission-plugins\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --disable-admission-plugins parameter to\n          ensure it does not include NamespaceLifecycle.\n        scored: true\n\n      - id: 1.2.16\n        text: \"Ensure that the admission control plugin NodeRestriction is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"NodeRestriction\"\n              set: true\n        remediation: |\n          Follow the Kubernetes documentation and configure NodeRestriction plug-in on kubelets.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --enable-admission-plugins parameter to a\n          value that includes NodeRestriction.\n          --enable-admission-plugins=...,NodeRestriction,...\n        scored: true\n\n      - id: 1.2.17\n        text: \"Ensure that the --secure-port argument is not set to 0 (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--secure-port\"\n              compare:\n                op: gt\n                value: 0\n              set: true\n            - flag: \"--secure-port\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and either remove the --secure-port parameter or\n          set it to a different (non-zero) desired port.\n        scored: true\n\n      - id: 1.2.18\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the below parameter.\n          --profiling=false\n        scored: true\n\n      - id: 1.2.19\n        text: \"Ensure that the --audit-log-path argument is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-path\"\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --audit-log-path parameter to a suitable path and\n          file where you would like audit logs to be written, for example,\n          --audit-log-path=/var/log/apiserver/audit.log\n        scored: true\n\n      - id: 1.2.20\n        text: \"Ensure that the --audit-log-maxage argument is set to 30 or as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxage\"\n              compare:\n                op: gte\n                value: 30\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --audit-log-maxage parameter to 30\n          or as an appropriate number of days, for example,\n          --audit-log-maxage=30\n        scored: true\n\n      - id: 1.2.21\n        text: \"Ensure that the --audit-log-maxbackup argument is set to 10 or as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxbackup\"\n              compare:\n                op: gte\n                value: 10\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --audit-log-maxbackup parameter to 10 or to an appropriate\n          value. For example,\n          --audit-log-maxbackup=10\n        scored: true\n\n      - id: 1.2.22\n        text: \"Ensure that the --audit-log-maxsize argument is set to 100 or as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxsize\"\n              compare:\n                op: gte\n                value: 100\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --audit-log-maxsize parameter to an appropriate size in MB.\n          For example, to set it as 100 MB, --audit-log-maxsize=100\n        scored: true\n\n      - id: 1.2.23\n        text: \"Ensure that the --request-timeout argument is set as appropriate (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        type: manual\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          and set the below parameter as appropriate and if needed.\n          For example, --request-timeout=300s\n        scored: false\n\n      - id: 1.2.24\n        text: \"Ensure that the --service-account-lookup argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--service-account-lookup\"\n              set: false\n            - flag: \"--service-account-lookup\"\n              compare:\n                op: eq\n                value: true\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the below parameter.\n          --service-account-lookup=true\n          Alternatively, you can delete the --service-account-lookup parameter from this file so\n          that the default takes effect.\n        scored: true\n\n      - id: 1.2.25\n        text: \"Ensure that the --service-account-key-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--service-account-key-file\"\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --service-account-key-file parameter\n          to the public key file for service accounts. For example,\n          --service-account-key-file=<filename>\n        scored: true\n\n      - id: 1.2.26\n        text: \"Ensure that the --etcd-certfile and --etcd-keyfile arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--etcd-certfile\"\n              set: true\n            - flag: \"--etcd-keyfile\"\n              set: true\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection between the apiserver and etcd.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the etcd certificate and key file parameters.\n          --etcd-certfile=<path/to/client-certificate-file>\n          --etcd-keyfile=<path/to/client-key-file>\n        scored: true\n\n      - id: 1.2.27\n        text: \"Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--tls-cert-file\"\n              set: true\n            - flag: \"--tls-private-key-file\"\n              set: true\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection on the apiserver.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the TLS certificate and private key file parameters.\n          --tls-cert-file=<path/to/tls-certificate-file>\n          --tls-private-key-file=<path/to/tls-key-file>\n        scored: true\n\n      - id: 1.2.28\n        text: \"Ensure that the --client-ca-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--client-ca-file\"\n              set: true\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection on the apiserver.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the client certificate authority file.\n          --client-ca-file=<path/to/client-ca-file>\n        scored: true\n\n      - id: 1.2.29\n        text: \"Ensure that the --etcd-cafile argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--etcd-cafile\"\n              set: true\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection between the apiserver and etcd.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the etcd certificate authority file parameter.\n          --etcd-cafile=<path/to/ca-file>\n        scored: true\n\n      - id: 1.2.30\n        text: \"Ensure that the --encryption-provider-config argument is set as appropriate (Manual)\"\n        type: \"skip\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--encryption-provider-config\"\n              set: true\n        remediation: |\n          Follow the Kubernetes documentation and configure a EncryptionConfig file.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --encryption-provider-config parameter to the path of that file.\n          For example, --encryption-provider-config=</path/to/EncryptionConfig/File>\n        scored: false\n\n      - id: 1.2.31\n        text: \"Ensure that encryption providers are appropriately configured (Manual)\"\n        type: \"skip\"\n        audit: |\n          ENCRYPTION_PROVIDER_CONFIG=$(ps -ef | grep $apiserverbin | grep -- --encryption-provider-config | sed 's%.*encryption-provider-config[= ]\\([^ ]*\\).*%\\1%')\n          if test -e $ENCRYPTION_PROVIDER_CONFIG; then grep -A1 'providers:' $ENCRYPTION_PROVIDER_CONFIG | tail -n1 | grep -o \"[A-Za-z]*\" | sed 's/^/provider=/'; fi\n        tests:\n          test_items:\n            - flag: \"provider\"\n              compare:\n                op: valid_elements\n                value: \"aescbc,kms,secretbox\"\n        remediation: |\n          Follow the Kubernetes documentation and configure a EncryptionConfig file.\n          In this file, choose aescbc, kms or secretbox as the encryption provider.\n          Enabling encryption changes how data can be recovered as data is encrypted.\n        scored: false\n\n      - id: 1.2.32\n        text: \"Ensure that the API Server only makes use of Strong Cryptographic Ciphers (Manual)\"\n        type: \"manual\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--tls-cipher-suites\"\n              compare:\n                op: valid_elements\n                value: \"TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,TLS_CHACHA20_POLY1305_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,TLS_RSA_WITH_3DES_EDE_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_256_GCM_SHA384\"\n        remediation: |\n          Edit the API server pod specification file /etc/kubernetes/manifests/kube-apiserver.yaml\n          on the control plane node and set the below parameter.\n          --tls-cipher-suites=TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,TLS_CHACHA20_POLY1305_SHA256,\n          TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,\n          TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,\n          TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,\n          TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,\n          TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,\n          TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,TLS_RSA_WITH_3DES_EDE_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA,\n          TLS_RSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_256_GCM_SHA384\n        scored: false\n\n  - id: 1.3\n    text: \"Controller Manager\"\n    checks:\n      - id: 1.3.1\n        text: \"Ensure that the --terminated-pod-gc-threshold argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--terminated-pod-gc-threshold\"\n              set: true\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the --terminated-pod-gc-threshold to an appropriate threshold,\n          for example, --terminated-pod-gc-threshold=10\n        scored: true\n\n      - id: 1.3.2\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n              set: true\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the below parameter.\n          --profiling=false\n        scored: true\n\n      - id: 1.3.3\n        text: \"Ensure that the --use-service-account-credentials argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--use-service-account-credentials\"\n              compare:\n                op: noteq\n                value: false\n              set: true\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node to set the below parameter.\n          --use-service-account-credentials=true\n        scored: true\n\n      - id: 1.3.4\n        text: \"Ensure that the --service-account-private-key-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--service-account-private-key-file\"\n              set: true\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the --service-account-private-key-file parameter\n          to the private key file for service accounts.\n          --service-account-private-key-file=<filename>\n        scored: true\n\n      - id: 1.3.5\n        text: \"Ensure that the --root-ca-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--root-ca-file\"\n              set: true\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the --root-ca-file parameter to the certificate bundle file`.\n          --root-ca-file=<path/to/file>\n        scored: true\n\n      - id: 1.3.6\n        text: \"Ensure that the RotateKubeletServerCertificate argument is set to true (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--feature-gates\"\n              compare:\n                op: nothave\n                value: \"RotateKubeletServerCertificate=false\"\n              set: true\n            - flag: \"--feature-gates\"\n              set: false\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the --feature-gates parameter to include RotateKubeletServerCertificate=true.\n          --feature-gates=RotateKubeletServerCertificate=true\n          Cluster provisioned by RKE handles certificate rotation directly through RKE.\n        scored: true\n\n      - id: 1.3.7\n        text: \"Ensure that the --bind-address argument is set to 127.0.0.1 (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--bind-address\"\n              compare:\n                op: eq\n                value: \"127.0.0.1\"\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and ensure the correct value for the --bind-address parameter\n        scored: true\n\n  - id: 1.4\n    text: \"Scheduler\"\n    checks:\n      - id: 1.4.1\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: \"/bin/ps -ef | grep $schedulerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n              set: true\n        remediation: |\n          Edit the Scheduler pod specification file $schedulerconf file\n          on the control plane node and set the below parameter.\n          --profiling=false\n        scored: true\n\n      - id: 1.4.2\n        text: \"Ensure that the --bind-address argument is set to 127.0.0.1 (Automated)\"\n        audit: \"/bin/ps -ef | grep $schedulerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--bind-address\"\n              compare:\n                op: eq\n                value: \"127.0.0.1\"\n        remediation: |\n          Edit the Scheduler pod specification file $schedulerconf\n          on the control plane node and ensure the correct value for the --bind-address parameter\n        scored: true\n"
  },
  {
    "path": "cfg/rke-cis-1.23/node.yaml",
    "content": "---\ncontrols:\nversion: \"rke-cis-1.23\"\nid: 4\ntext: \"Worker Node Security Configuration\"\ntype: \"node\"\ngroups:\n  - id: 4.1\n    text: \"Worker Node Configuration Files\"\n    checks:\n      - id: 4.1.1\n        text: \"Ensure that the kubelet service file permissions are set to 644 or more restrictive (Automated)\"\n        type: \"skip\"\n        audit: '/bin/sh -c ''if test -e $kubeletsvc; then stat -c permissions=%a $kubeletsvc; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Cluster provisioned by RKE doesn’t require or maintain a configuration file for the kubelet service.\n          All configuration is passed in as arguments at container run time.\n        scored: true\n\n      - id: 4.1.2\n        text: \"Ensure that the kubelet service file ownership is set to root:root (Automated)\"\n        type: \"skip\"\n        audit: '/bin/sh -c ''if test -e $kubeletsvc; then stat -c %U:%G $kubeletsvc; fi'' '\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Cluster provisioned by RKE doesn’t require or maintain a configuration file for the kubelet service.\n          All configuration is passed in as arguments at container run time.\n        scored: true\n\n      - id: 4.1.3\n        text: \"If proxy kubeconfig file exists ensure permissions are set to 644 or more restrictive (Manual)\"\n        audit: '/bin/sh -c ''if test -e $proxykubeconfig; then stat -c permissions=%a $proxykubeconfig; fi'' '\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"permissions\"\n              set: true\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chmod 644 $proxykubeconfig\n        scored: true\n\n      - id: 4.1.4\n        text: \"If proxy kubeconfig file exists ensure ownership is set to root:root (Manual)\"\n        audit: '/bin/sh -c ''if test -e $proxykubeconfig; then stat -c %U:%G $proxykubeconfig; fi'' '\n        tests:\n          bin_op: or\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example, chown root:root $proxykubeconfig\n        scored: true\n\n      - id: 4.1.5\n        text: \"Ensure that the --kubeconfig kubelet.conf file permissions are set to 644 or more restrictive (Automated)\"\n        audit: '/bin/sh -c ''if test -e /node$kubeletkubeconfig; then stat -c permissions=%a /node$kubeletkubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chmod 644 $kubeletkubeconfig\n        scored: true\n\n      - id: 4.1.6\n        text: \"Ensure that the --kubeconfig kubelet.conf file ownership is set to root:root (Automated)\"\n        audit: '/bin/sh -c ''if test -e /node$kubeletkubeconfig; then stat -c %U:%G /node$kubeletkubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chown root:root $kubeletkubeconfig\n        scored: true\n\n      - id: 4.1.7\n        text: \"Ensure that the certificate authorities file permissions are set to 644 or more restrictive (Automated)\"\n        audit: \"stat -c permissions=%a /etc/kubernetes/ssl/kube-ca.pem\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the following command to modify the file permissions of the\n          --client-ca-file chmod 644 <filename>\n        scored: true\n\n      - id: 4.1.8\n        text: \"Ensure that the client certificate authorities file ownership is set to root:root (Automated)\"\n        audit: \"stat -c %U:%G /etc/kubernetes/ssl/kube-ca.pem\"\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the following command to modify the ownership of the --client-ca-file.\n          chown root:root <filename>\n        scored: true\n\n      - id: 4.1.9\n        text: \"Ensure that the kubelet --config configuration file has permissions set to 644 or more restrictive (Automated)\"\n        type: \"skip\"\n        audit: '/bin/sh -c ''if test -e $kubeletconf; then stat -c permissions=%a $kubeletconf; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Clusters provisioned by RKE doesn’t require or maintain a configuration file for the kubelet.\n          All configuration is passed in as arguments at container run time.\n\n          Clusters provisioned by RKE doesn’t require or maintain a configuration file for the kubelet.\n          All configuration is passed in as arguments at container run time.\n        scored: true\n\n      - id: 4.1.10\n        text: \"Ensure that the kubelet --config configuration file ownership is set to root:root (Automated)\"\n        type: \"skip\"\n        audit: '/bin/sh -c ''if test -e $kubeletconf; then stat -c %U:%G $kubeletconf; fi'' '\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Clusters provisioned by RKE doesn’t require or maintain a configuration file for the kubelet.\n          All configuration is passed in as arguments at container run time.\n\n          Clusters provisioned by RKE doesn’t require or maintain a configuration file for the kubelet.\n          All configuration is passed in as arguments at container run time.\n        scored: true\n\n  - id: 4.2\n    text: \"Kubelet\"\n    checks:\n      - id: 4.2.1\n        text: \"Ensure that the --anonymous-auth argument is set to false (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/sh -c 'if test -e $kubeletconf; then /bin/cat $kubeletconf; fi' \"\n        tests:\n          test_items:\n            - flag: \"--anonymous-auth\"\n              path: '{.authentication.anonymous.enabled}'\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          If using a Kubelet config file, edit the file to set `authentication: anonymous: enabled` to\n          `false`.\n          If using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          `--anonymous-auth=false`\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.2\n        text: \"Ensure that the --authorization-mode argument is not set to AlwaysAllow (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/sh -c 'if test -e $kubeletconf; then /bin/cat $kubeletconf; fi' \"\n        tests:\n          test_items:\n            - flag: --authorization-mode\n              path: '{.authorization.mode}'\n              compare:\n                op: nothave\n                value: AlwaysAllow\n        remediation: |\n          If using a Kubelet config file, edit the file to set `authorization.mode` to Webhook. If\n          using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_AUTHZ_ARGS variable.\n          --authorization-mode=Webhook\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.3\n        text: \"Ensure that the --client-ca-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/sh -c 'if test -e $kubeletconf; then /bin/cat $kubeletconf; fi' \"\n        tests:\n          test_items:\n            - flag: --client-ca-file\n              path: '{.authentication.x509.clientCAFile}'\n        remediation: |\n          If using a Kubelet config file, edit the file to set `authentication.x509.clientCAFile` to\n          the location of the client CA file.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_AUTHZ_ARGS variable.\n          --client-ca-file=<path/to/client-ca-file>\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.4\n        text: \"Ensure that the --read-only-port argument is set to 0 (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/sh -c 'if test -e $kubeletconf; then /bin/cat $kubeletconf; fi' \"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--read-only-port\"\n              path: '{.readOnlyPort}'\n              compare:\n                op: eq\n                value: 0\n            - flag: \"--read-only-port\"\n              path: '{.readOnlyPort}'\n              set: false\n        remediation: |\n          If using a Kubelet config file, edit the file to set `readOnlyPort` to 0.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --read-only-port=0\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.5\n        text: \"Ensure that the --streaming-connection-idle-timeout argument is not set to 0 (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/sh -c 'if test -e $kubeletconf; then /bin/cat $kubeletconf; fi' \"\n        tests:\n          test_items:\n            - flag: --streaming-connection-idle-timeout\n              path: '{.streamingConnectionIdleTimeout}'\n              compare:\n                op: noteq\n                value: 0\n            - flag: --streaming-connection-idle-timeout\n              path: '{.streamingConnectionIdleTimeout}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to set `streamingConnectionIdleTimeout` to a\n          value other than 0.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --streaming-connection-idle-timeout=5m\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.6\n        text: \"Ensure that the --protect-kernel-defaults argument is set to true (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/sh -c 'if test -e $kubeletconf; then /bin/cat $kubeletconf; fi' \"\n        tests:\n          test_items:\n            - flag: --protect-kernel-defaults\n              path: '{.protectKernelDefaults}'\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          If using a Kubelet config file, edit the file to set `protectKernelDefaults` to `true`.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --protect-kernel-defaults=true\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n          System level configurations are required prior to provisioning the cluster in order for this argument to be set to true.\n        scored: true\n\n      - id: 4.2.7\n        text: \"Ensure that the --make-iptables-util-chains argument is set to true (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/sh -c 'if test -e $kubeletconf; then /bin/cat $kubeletconf; fi' \"\n        tests:\n          test_items:\n            - flag: --make-iptables-util-chains\n              path: '{.makeIPTablesUtilChains}'\n              compare:\n                op: eq\n                value: true\n            - flag: --make-iptables-util-chains\n              path: '{.makeIPTablesUtilChains}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to set `makeIPTablesUtilChains` to `true`.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          remove the --make-iptables-util-chains argument from the\n          KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.8\n        text: \"Ensure that the --hostname-override argument is not set (Manual)\"\n        # This is one of those properties that can only be set as a command line argument.\n        # To check if the property is set as expected, we need to parse the kubelet command\n        # instead reading the Kubelet Configuration file.\n        type: \"skip\"\n        audit: \"/bin/ps -fC $kubeletbin \"\n        tests:\n          test_items:\n            - flag: --hostname-override\n              set: false\n        remediation: |\n          Edit the kubelet service file $kubeletsvc\n          on each worker node and remove the --hostname-override argument from the\n          KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n          Clusters provisioned by RKE set the --hostname-override to avoid any hostname configuration errors\n        scored: false\n\n      - id: 4.2.9\n        text: \"Ensure that the --event-qps argument is set to 0 or a level which ensures appropriate event capture (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/sh -c 'if test -e $kubeletconf; then /bin/cat $kubeletconf; fi' \"\n        tests:\n          test_items:\n            - flag: --event-qps\n              path: '{.eventRecordQPS}'\n              compare:\n                op: eq\n                value: 0\n        remediation: |\n          If using a Kubelet config file, edit the file to set `eventRecordQPS` to an appropriate level.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.10\n        text: \"Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Manual)\"\n        type: \"skip\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/sh -c 'if test -e $kubeletconf; then /bin/cat $kubeletconf; fi' \"\n        tests:\n          test_items:\n            - flag: --tls-cert-file\n              path: '{.tlsCertFile}'\n            - flag: --tls-private-key-file\n              path: '{.tlsPrivateKeyFile}'\n        remediation: |\n          If using a Kubelet config file, edit the file to set `tlsCertFile` to the location\n          of the certificate file to use to identify this Kubelet, and `tlsPrivateKeyFile`\n          to the location of the corresponding private key file.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameters in KUBELET_CERTIFICATE_ARGS variable.\n          --tls-cert-file=<path/to/tls-certificate-file>\n          --tls-private-key-file=<path/to/tls-key-file>\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n          When generating serving certificates, functionality could break in conjunction with hostname overrides which are required for certain cloud providers.\n        scored: false\n\n      - id: 4.2.11\n        text: \"Ensure that the --rotate-certificates argument is not set to false (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/sh -c 'if test -e $kubeletconf; then /bin/cat $kubeletconf; fi' \"\n        tests:\n          test_items:\n            - flag: --rotate-certificates\n              path: '{.rotateCertificates}'\n              compare:\n                op: eq\n                value: true\n            - flag: --rotate-certificates\n              path: '{.rotateCertificates}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to add the line `rotateCertificates` to `true` or\n          remove it altogether to use the default value.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          remove --rotate-certificates=false argument from the KUBELET_CERTIFICATE_ARGS\n          variable.\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.12\n        text: \"Verify that the RotateKubeletServerCertificate argument is set to true (Manual)\"\n        type: \"skip\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/sh -c 'if test -e $kubeletconf; then /bin/cat $kubeletconf; fi' \"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: RotateKubeletServerCertificate\n              path: '{.featureGates.RotateKubeletServerCertificate}'\n              compare:\n                op: nothave\n                value: false\n            - flag: RotateKubeletServerCertificate\n              path: '{.featureGates.RotateKubeletServerCertificate}'\n              set: false\n        remediation: |\n          Edit the kubelet service file $kubeletsvc\n          on each worker node and set the below parameter in KUBELET_CERTIFICATE_ARGS variable.\n          --feature-gates=RotateKubeletServerCertificate=true\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n          Clusters provisioned by RKE handles certificate rotation directly through RKE.\n        scored: false\n\n      - id: 4.2.13\n        text: \"Ensure that the Kubelet only makes use of Strong Cryptographic Ciphers (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/sh -c 'if test -e $kubeletconf; then /bin/cat $kubeletconf; fi' \"\n        tests:\n          test_items:\n            - flag: --tls-cipher-suites\n              path: '{range .tlsCipherSuites[:]}{}{'',''}{end}'\n              compare:\n                op: valid_elements\n                value: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\n        remediation: |\n          If using a Kubelet config file, edit the file to set `tlsCipherSuites` to\n          TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\n          or to a subset of these values.\n          If using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the --tls-cipher-suites parameter as follows, or to a subset of these values.\n          --tls-cipher-suites=TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n"
  },
  {
    "path": "cfg/rke-cis-1.23/policies.yaml",
    "content": "---\ncontrols:\nversion: \"rke-cis-1.23\"\nid: 5\ntext: \"Kubernetes Policies\"\ntype: \"policies\"\ngroups:\n  - id: 5.1\n    text: \"RBAC and Service Accounts\"\n    checks:\n      - id: 5.1.1\n        text: \"Ensure that the cluster-admin role is only used where required (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Identify all clusterrolebindings to the cluster-admin role. Check if they are used and\n          if they need this role or if they could use a role with fewer privileges.\n          Where possible, first bind users to a lower privileged role and then remove the\n          clusterrolebinding to the cluster-admin role :\n          kubectl delete clusterrolebinding [name]\n        scored: false\n\n      - id: 5.1.2\n        text: \"Minimize access to secrets (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove get, list and watch access to Secret objects in the cluster.\n        scored: false\n\n      - id: 5.1.3\n        text: \"Minimize wildcard use in Roles and ClusterRoles (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible replace any use of wildcards in clusterroles and roles with specific\n          objects or actions.\n        scored: false\n\n      - id: 5.1.4\n        text: \"Minimize access to create pods (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove create access to pod objects in the cluster.\n        scored: false\n\n      - id: 5.1.5\n        text: \"Ensure that default service accounts are not actively used. (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Create explicit service accounts wherever a Kubernetes workload requires specific access\n          to the Kubernetes API server.\n          Modify the configuration of each default service account to include this value\n          automountServiceAccountToken: false\n        scored: false\n\n      - id: 5.1.6\n        text: \"Ensure that Service Account Tokens are only mounted where necessary (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Modify the definition of pods and service accounts which do not need to mount service\n          account tokens to disable it.\n        scored: false\n\n      - id: 5.1.7\n        text: \"Avoid use of system:masters group (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Remove the system:masters group from all users in the cluster.\n        scored: false\n\n      - id: 5.1.8\n        text: \"Limit use of the Bind, Impersonate and Escalate permissions in the Kubernetes cluster (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove the impersonate, bind and escalate rights from subjects.\n        scored: false\n\n  - id: 5.2\n    text: \"Pod Security Standards\"\n    checks:\n      - id: 5.2.1\n        text: \"Ensure that the cluster has at least one active policy control mechanism in place (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that either Pod Security Admission or an external policy control system is in place\n          for every namespace which contains user workloads.\n        scored: false\n\n      - id: 5.2.2\n        text: \"Minimize the admission of privileged containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of privileged containers.\n        scored: false\n\n      - id: 5.2.3\n        text: \"Minimize the admission of containers wishing to share the host process ID namespace (Automated)\"\n        type: \"skip\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of `hostPID` containers.\n        scored: false\n\n      - id: 5.2.4\n        text: \"Minimize the admission of containers wishing to share the host IPC namespace (Automated)\"\n        type: \"skip\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of `hostIPC` containers.\n        scored: false\n\n      - id: 5.2.5\n        text: \"Minimize the admission of containers wishing to share the host network namespace (Automated)\"\n        type: \"skip\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of `hostNetwork` containers.\n        scored: false\n\n      - id: 5.2.6\n        text: \"Minimize the admission of containers with allowPrivilegeEscalation (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers with `.spec.allowPrivilegeEscalation` set to `true`.\n        scored: false\n\n      - id: 5.2.7\n        text: \"Minimize the admission of root containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Create a policy for each namespace in the cluster, ensuring that either `MustRunAsNonRoot`\n          or `MustRunAs` with the range of UIDs not including 0, is set.\n        scored: false\n\n      - id: 5.2.8\n        text: \"Minimize the admission of containers with the NET_RAW capability (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers with the `NET_RAW` capability.\n        scored: false\n\n      - id: 5.2.9\n        text: \"Minimize the admission of containers with added capabilities (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that `allowedCapabilities` is not present in policies for the cluster unless\n          it is set to an empty array.\n        scored: false\n\n      - id: 5.2.10\n        text: \"Minimize the admission of containers with capabilities assigned (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Review the use of capabilites in applications running on your cluster. Where a namespace\n          contains applications which do not require any Linux capabities to operate consider adding\n          a PSP which forbids the admission of containers which do not drop all capabilities.\n        scored: false\n\n      - id: 5.2.11\n        text: \"Minimize the admission of Windows HostProcess containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers that have `.securityContext.windowsOptions.hostProcess` set to `true`.\n        scored: false\n\n      - id: 5.2.12\n        text: \"Minimize the admission of HostPath volumes (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers with `hostPath` volumes.\n        scored: false\n\n      - id: 5.2.13\n        text: \"Minimize the admission of containers which use HostPorts (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers which use `hostPort` sections.\n        scored: false\n\n  - id: 5.3\n    text: \"Network Policies and CNI\"\n    checks:\n      - id: 5.3.1\n        text: \"Ensure that the CNI in use supports NetworkPolicies (Manual)\"\n        type: \"manual\"\n        remediation: |\n          If the CNI plugin in use does not support network policies, consideration should be given to\n          making use of a different plugin, or finding an alternate mechanism for restricting traffic\n          in the Kubernetes cluster.\n        scored: false\n\n      - id: 5.3.2\n        text: \"Ensure that all Namespaces have NetworkPolicies defined (Manual)\"\n        type: \"skip\"\n        remediation: |\n          Follow the documentation and create NetworkPolicy objects as you need them.\n        scored: false\n\n  - id: 5.4\n    text: \"Secrets Management\"\n    checks:\n      - id: 5.4.1\n        text: \"Prefer using Secrets as files over Secrets as environment variables (Manual)\"\n        type: \"manual\"\n        remediation: |\n          If possible, rewrite application code to read Secrets from mounted secret files, rather than\n          from environment variables.\n        scored: false\n\n      - id: 5.4.2\n        text: \"Consider external secret storage (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Refer to the Secrets management options offered by your cloud provider or a third-party\n          secrets management solution.\n        scored: false\n\n  - id: 5.5\n    text: \"Extensible Admission Control\"\n    checks:\n      - id: 5.5.1\n        text: \"Configure Image Provenance using ImagePolicyWebhook admission controller (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and setup image provenance.\n        scored: false\n\n  - id: 5.7\n    text: \"General Policies\"\n    checks:\n      - id: 5.7.1\n        text: \"Create administrative boundaries between resources using namespaces (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the documentation and create namespaces for objects in your deployment as you need\n          them.\n        scored: false\n\n      - id: 5.7.2\n        text: \"Ensure that the seccomp profile is set to docker/default in your Pod definitions (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Use `securityContext` to enable the docker/default seccomp profile in your pod definitions.\n          An example is as below:\n            securityContext:\n              seccompProfile:\n                type: RuntimeDefault\n        scored: false\n\n      - id: 5.7.3\n        text: \"Apply SecurityContext to your Pods and Containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and apply SecurityContexts to your Pods. For a\n          suggested list of SecurityContexts, you may refer to the CIS Security Benchmark for Docker\n          Containers.\n        scored: false\n\n      - id: 5.7.4\n        text: \"The default namespace should not be used (Manual)\"\n        type: \"skip\"\n        remediation: |\n          Ensure that namespaces are created to allow for appropriate segregation of Kubernetes\n          resources and that all new resources are created in a specific namespace.\n        scored: false\n"
  },
  {
    "path": "cfg/rke-cis-1.24/config.yaml",
    "content": "---\n## Version-specific settings that override the values in cfg/config.yaml\n"
  },
  {
    "path": "cfg/rke-cis-1.24/controlplane.yaml",
    "content": "---\ncontrols:\nversion: \"rke-cis-1.24\"\nid: 3\ntext: \"Control Plane Configuration\"\ntype: \"controlplane\"\ngroups:\n  - id: 3.1\n    text: \"Authentication and Authorization\"\n    checks:\n      - id: 3.1.1\n        text: \"Client certificate authentication should not be used for users (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Alternative mechanisms provided by Kubernetes such as the use of OIDC should be\n          implemented in place of client certificates.\n        scored: false\n\n  - id: 3.2\n    text: \"Logging\"\n    checks:\n      - id: 3.2.1\n        text: \"Ensure that a minimal audit policy is created (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-policy-file\"\n              set: true\n        remediation: |\n          Create an audit policy file for your cluster.\n        scored: true\n\n      - id: 3.2.2\n        text: \"Ensure that the audit policy covers key security concerns (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Review the audit policy provided for the cluster and ensure that it covers\n          at least the following areas,\n          - Access to Secrets managed by the cluster. Care should be taken to only\n            log Metadata for requests to Secrets, ConfigMaps, and TokenReviews, in\n            order to avoid risk of logging sensitive data.\n          - Modification of Pod and Deployment objects.\n          - Use of `pods/exec`, `pods/portforward`, `pods/proxy` and `services/proxy`.\n          For most requests, minimally logging at the Metadata level is recommended\n          (the most basic level of logging).\n        scored: false\n"
  },
  {
    "path": "cfg/rke-cis-1.24/etcd.yaml",
    "content": "---\ncontrols:\nversion: \"rke-cis-1.24\"\nid: 2\ntext: \"Etcd Node Configuration\"\ntype: \"etcd\"\ngroups:\n  - id: 2\n    text: \"Etcd Node Configuration\"\n    checks:\n      - id: 2.1\n        text: \"Ensure that the --cert-file and --key-file arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--cert-file\"\n              env: \"ETCD_CERT_FILE\"\n              set: true\n            - flag: \"--key-file\"\n              env: \"ETCD_KEY_FILE\"\n              set: true\n        remediation: |\n          Follow the etcd service documentation and configure TLS encryption.\n          Then, edit the etcd pod specification file /etc/kubernetes/manifests/etcd.yaml\n          on the master node and set the below parameters.\n          --cert-file=</path/to/ca-file>\n          --key-file=</path/to/key-file>\n        scored: true\n\n      - id: 2.2\n        text: \"Ensure that the --client-cert-auth argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--client-cert-auth\"\n              set: true\n            - flag: \"--client-cert-auth\"\n              env: \"ETCD_CLIENT_CERT_AUTH\"\n              compare:\n                op: eq\n                value: true\n              set: true\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and set the below parameter.\n          --client-cert-auth=\"true\"\n        scored: true\n\n      - id: 2.3\n        text: \"Ensure that the --auto-tls argument is not set to true (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--auto-tls\"\n              env: \"ETCD_AUTO_TLS\"\n              set: false\n            - flag: \"--auto-tls\"\n              env: \"ETCD_AUTO_TLS\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and either remove the --auto-tls parameter or set it to false.\n            --auto-tls=false\n        scored: true\n\n      - id: 2.4\n        text: \"Ensure that the --peer-cert-file and --peer-key-file arguments are\n        set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--peer-cert-file\"\n              env: \"ETCD_PEER_CERT_FILE\"\n              set: true\n            - flag: \"--peer-key-file\"\n              env: \"ETCD_PEER_KEY_FILE\"\n              set: true\n        remediation: |\n          Follow the etcd service documentation and configure peer TLS encryption as appropriate\n          for your etcd cluster.\n          Then, edit the etcd pod specification file $etcdconf on the\n          master node and set the below parameters.\n          --peer-client-file=</path/to/peer-cert-file>\n          --peer-key-file=</path/to/peer-key-file>\n        scored: true\n\n      - id: 2.5\n        text: \"Ensure that the --peer-client-cert-auth argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--peer-client-cert-auth\"\n              set: true\n            - flag: \"--peer-client-cert-auth\"\n              env: \"ETCD_PEER_CLIENT_CERT_AUTH\"\n              compare:\n                op: eq\n                value: true\n              set: true\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and set the below parameter.\n          --peer-client-cert-auth=true\n        scored: true\n\n      - id: 2.6\n        text: \"Ensure that the --peer-auto-tls argument is not set to true (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--peer-auto-tls\"\n              env: \"ETCD_PEER_AUTO_TLS\"\n              set: false\n            - flag: \"--peer-auto-tls\"\n              env: \"ETCD_PEER_AUTO_TLS\"\n              compare:\n                op: eq\n                value: false\n              set: false\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and either remove the --peer-auto-tls parameter or set it to false.\n          --peer-auto-tls=false\n        scored: true\n\n      - id: 2.7\n        text: \"Ensure that a unique Certificate Authority is used for etcd (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--trusted-ca-file\"\n              env: \"ETCD_TRUSTED_CA_FILE\"\n              set: true\n        remediation: |\n          [Manual test]\n          Follow the etcd documentation and create a dedicated certificate authority setup for the\n          etcd service.\n          Then, edit the etcd pod specification file $etcdconf on the\n          master node and set the below parameter.\n          --trusted-ca-file=</path/to/ca-file>\n        scored: true\n"
  },
  {
    "path": "cfg/rke-cis-1.24/master.yaml",
    "content": "---\ncontrols:\nversion: \"rke-cis-1.24\"\nid: 1\ntext: \"Control Plane Security Configuration\"\ntype: \"master\"\ngroups:\n  - id: 1.1\n    text: \"Control Plane Node Configuration Files\"\n    checks:\n      - id: 1.1.1\n        text: \"Ensure that the API server pod specification file permissions are set to 644 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $apiserverconf; then stat -c permissions=%a $apiserverconf;else echo \\\"File not found\\\"; fi'\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n            - flag: \"File not found\"\n        remediation: |\n          Cluster provisioned by RKE doesn't require or maintain a configuration file for kube-apiserver.\n          All configuration is passed in as arguments at container run time.\n        scored: true\n\n      - id: 1.1.2\n        text: \"Ensure that the API server pod specification file ownership is set to root:root (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/sh -c 'if test -e $apiserverconf; then stat -c %U:%G $apiserverconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chown root:root $apiserverconf\n        scored: true\n\n      - id: 1.1.3\n        text: \"Ensure that the controller manager pod specification file permissions are set to 600 or more restrictive (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerconf; then stat -c permissions=%a $controllermanagerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chmod 600 $controllermanagerconf\n        scored: true\n\n      - id: 1.1.4\n        text: \"Ensure that the controller manager pod specification file ownership is set to root:root (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerconf; then stat -c %U:%G $controllermanagerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chown root:root $controllermanagerconf\n        scored: true\n\n      - id: 1.1.5\n        text: \"Ensure that the scheduler pod specification file permissions are set to 600 or more restrictive (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/sh -c 'if test -e $schedulerconf; then stat -c permissions=%a $schedulerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chmod 600 $schedulerconf\n        scored: true\n\n      - id: 1.1.6\n        text: \"Ensure that the scheduler pod specification file ownership is set to root:root (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/sh -c 'if test -e $schedulerconf; then stat -c %U:%G $schedulerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chown root:root $schedulerconf\n        scored: true\n\n      - id: 1.1.7\n        text: \"Ensure that the etcd pod specification file permissions are set to 600 or more restrictive (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/sh -c 'if test -e $etcdconf; then find $etcdconf -name '*etcd*' | xargs stat -c permissions=%a; fi'\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod 600 $etcdconf\n        scored: true\n\n      - id: 1.1.8\n        text: \"Ensure that the etcd pod specification file ownership is set to root:root (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/sh -c 'if test -e $etcdconf; then find $etcdconf -name '*etcd*' | xargs stat -c %U:%G; fi'\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root $etcdconf\n        scored: true\n\n      - id: 1.1.9\n        text: \"Ensure that the Container Network Interface file permissions are set to 600 or more restrictive (Manual)\"\n        audit: |\n          ps -ef | grep $kubeletbin | grep -- --cni-conf-dir | sed 's%.*cni-conf-dir[= ]\\([^ ]*\\).*%\\1%' | xargs -I{} find {} -mindepth 1 | xargs --no-run-if-empty stat -c permissions=%a\n          find /var/lib/cni/networks -type f 2> /dev/null | xargs --no-run-if-empty stat -c permissions=%a\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chmod 600 <path/to/cni/files>\n        scored: false\n\n      - id: 1.1.10\n        text: \"Ensure that the Container Network Interface file ownership is set to root:root (Automated)\"\n        audit: |\n          ps -ef | grep $kubeletbin | grep -- --cni-conf-dir | sed 's%.*cni-conf-dir[= ]\\([^ ]*\\).*%\\1%' | xargs -I{} find {} -mindepth 1 | xargs --no-run-if-empty stat -c %U:%G\n          find /var/lib/cni/networks -type f 2> /dev/null | xargs --no-run-if-empty stat -c %U:%G\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root <path/to/cni/files>\n        scored: true\n\n      - id: 1.1.11\n        text: \"Ensure that the etcd data directory permissions are set to 700 or more restrictive (Automated)\"\n        audit: stat -c %a /var/lib/etcd\n        tests:\n          test_items:\n            - flag: \"700\"\n              compare:\n                op: eq\n                value: \"700\"\n              set: true\n        remediation: |\n          On the etcd server node, get the etcd data directory, passed as an argument --data-dir,\n          from the command 'ps -ef | grep etcd'.\n          Run the below command (based on the etcd data directory found above). For example,\n          chmod 700 /var/lib/etcd\n        scored: true\n\n      - id: 1.1.12\n        text: \"Ensure that the etcd data directory ownership is set to etcd:etcd (Automated)\"\n        type: \"skip\"\n        audit: \"stat -c %U:%G /node/var/lib/etcd\"\n        tests:\n          test_items:\n            - flag: \"etcd:etcd\"\n              set: true\n        remediation: |\n          On the etcd server node, get the etcd data directory, passed as an argument --data-dir,\n          from the command 'ps -ef | grep etcd'.\n          Run the below command (based on the etcd data directory found above).\n          For example, chown etcd:etcd /var/lib/etcd\n        scored: true\n\n      - id: 1.1.13\n        text: \"Ensure that the admin.conf file permissions are set to 600 or more restrictive (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/sh -c 'if test -e /etc/kubernetes/admin.conf; then stat -c permissions=%a /etc/kubernetes/admin.conf; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chmod 600 /etc/kubernetes/admin.conf\n        scored: true\n\n      - id: 1.1.14\n        text: \"Ensure that the admin.conf file ownership is set to root:root (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/sh -c 'if test -e /etc/kubernetes/admin.conf; then stat -c %U:%G /etc/kubernetes/admin.conf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chown root:root /etc/kubernetes/admin.conf\n        scored: true\n\n      - id: 1.1.15\n        text: \"Ensure that the scheduler.conf file permissions are set to 600 or more restrictive (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/sh -c 'if test -e $schedulerkubeconfig; then stat -c permissions=%a $schedulerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod 600 $schedulerkubeconfig\n        scored: true\n\n      - id: 1.1.16\n        text: \"Ensure that the scheduler.conf file ownership is set to root:root (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/sh -c 'if test -e $schedulerkubeconfig; then stat -c %U:%G $schedulerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root $schedulerkubeconfig\n        scored: true\n\n      - id: 1.1.17\n        text: \"Ensure that the controller-manager.conf file permissions are set to 600 or more restrictive (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerkubeconfig; then stat -c permissions=%a $controllermanagerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod 600 $controllermanagerkubeconfig\n        scored: true\n\n      - id: 1.1.18\n        text: \"Ensure that the controller-manager.conf file ownership is set to root:root (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerkubeconfig; then stat -c %U:%G $controllermanagerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root $controllermanagerkubeconfig\n        scored: true\n\n      - id: 1.1.19\n        text: \"Ensure that the Kubernetes PKI directory and file ownership is set to root:root (Automated)\"\n        audit: \"check_files_owner_in_dir.sh /etc/kubernetes/ssl\"\n        tests:\n          test_items:\n            - flag: \"true\"\n              compare:\n                op: eq\n                value: \"true\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown -R root:root /etc/kubernetes/pki/\n        scored: true\n\n      - id: 1.1.20\n        text: \"Ensure that the Kubernetes PKI certificate file permissions are set to 600 or more restrictive (Automated)\"\n        audit: |\n          if test -n \"$(find /etc/kubernetes/ssl/ -name '*.pem' ! -name '*key.pem')\"; then find /etc/kubernetes/ssl/  -name '*.pem' ! -name '*key.pem' | xargs stat -c permissions=%a;else echo \"File not found\"; fi\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"File not found\"\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          find /etc/kubernetes/ssl/  -name '*.pem' ! -name '*key.pem' -exec chmod -R 600 {} +\n        scored: true\n\n      - id: 1.1.21\n        text: \"Ensure that the Kubernetes PKI key file permissions are set to 600 (Automated)\"\n        audit: |\n          if test -n \"$(find /etc/kubernetes/ssl/ -name '*.pem')\"; then find /etc/kubernetes/ssl/  -name '*.pem' | xargs stat -c permissions=%a;else echo \\\"File not found\\\"; fi\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n            - flag: \"File not found\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          find /etc/kubernetes/ssl/ -name '*key.pem' -exec chmod -R 600 {} +\n        scored: true\n\n  - id: 1.2\n    text: \"API Server\"\n    checks:\n      - id: 1.2.1\n        text: \"Ensure that the --anonymous-auth argument is set to false (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--anonymous-auth\"\n              compare:\n                op: eq\n                value: false\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the below parameter.\n          --anonymous-auth=false\n        scored: true\n\n      - id: 1.2.2\n        text: \"Ensure that the --token-auth-file parameter is not set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--token-auth-file\"\n              set: false\n        remediation: |\n          Follow the documentation and configure alternate mechanisms for authentication. Then,\n          edit the API server pod specification file $apiserverconf\n          on the control plane node and remove the --token-auth-file=<filename> parameter.\n        scored: true\n\n      - id: 1.2.3\n        text: \"Ensure that the --DenyServiceExternalIPs is not set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: nothave\n                value: \"DenyServiceExternalIPs\"\n              set: true\n            - flag: \"--enable-admission-plugins\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and remove the `DenyServiceExternalIPs`\n          from enabled admission plugins.\n        scored: true\n\n      - id: 1.2.4\n        text: \"Ensure that the --kubelet-https argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--kubelet-https\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Edit the API server pod specification file /etc/kubernetes/manifests/kube-apiserver.yaml\n          on the control plane node and remove the --kubelet-https parameter.\n        scored: true\n\n      - id: 1.2.5\n        text: \"Ensure that the --kubelet-client-certificate and --kubelet-client-key arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--kubelet-client-certificate\"\n              set: true\n            - flag: \"--kubelet-client-key\"\n              set: true\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection between the\n          apiserver and kubelets. Then, edit API server pod specification file\n          $apiserverconf on the control plane node and set the\n          kubelet client certificate and key parameters as below.\n          --kubelet-client-certificate=<path/to/client-certificate-file>\n          --kubelet-client-key=<path/to/client-key-file>\n        scored: true\n\n      - id: 1.2.6\n        text: \"Ensure that the --kubelet-certificate-authority argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--kubelet-certificate-authority\"\n              set: true\n        remediation: |\n          Follow the Kubernetes documentation and setup the TLS connection between\n          the apiserver and kubelets. Then, edit the API server pod specification file\n          $apiserverconf on the control plane node and set the\n          --kubelet-certificate-authority parameter to the path to the cert file for the certificate authority.\n          --kubelet-certificate-authority=<ca-string>\n          When generating serving certificates, functionality could break in conjunction with hostname overrides which are required for certain cloud providers.\n        scored: true\n\n      - id: 1.2.7\n        text: \"Ensure that the --authorization-mode argument is not set to AlwaysAllow (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: nothave\n                value: \"AlwaysAllow\"\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --authorization-mode parameter to values other than AlwaysAllow.\n          One such example could be as below.\n          --authorization-mode=RBAC\n        scored: true\n\n      - id: 1.2.8\n        text: \"Ensure that the --authorization-mode argument includes Node (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: has\n                value: \"Node\"\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --authorization-mode parameter to a value that includes Node.\n          --authorization-mode=Node,RBAC\n        scored: true\n\n      - id: 1.2.9\n        text: \"Ensure that the --authorization-mode argument includes RBAC (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: has\n                value: \"RBAC\"\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --authorization-mode parameter to a value that includes RBAC,\n          for example `--authorization-mode=Node,RBAC`.\n        scored: true\n\n      - id: 1.2.10\n        text: \"Ensure that the admission control plugin EventRateLimit is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"EventRateLimit\"\n              set: true\n        remediation: |\n          Follow the Kubernetes documentation and set the desired limits in a configuration file.\n          Then, edit the API server pod specification file $apiserverconf\n          and set the below parameters.\n          --enable-admission-plugins=...,EventRateLimit,...\n          --admission-control-config-file=<path/to/configuration/file>\n        scored: true\n\n      - id: 1.2.11\n        text: \"Ensure that the admission control plugin AlwaysAdmit is not set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: nothave\n                value: AlwaysAdmit\n              set: true\n            - flag: \"--enable-admission-plugins\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and either remove the --enable-admission-plugins parameter, or set it to a\n          value that does not include AlwaysAdmit.\n        scored: true\n\n      - id: 1.2.12\n        text: \"Ensure that the admission control plugin AlwaysPullImages is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"AlwaysPullImages\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --enable-admission-plugins parameter to include\n          AlwaysPullImages.\n          --enable-admission-plugins=...,AlwaysPullImages,...\n        scored: true\n\n      - id: 1.2.13\n        text: \"Ensure that the admission control plugin SecurityContextDeny is set if PodSecurityPolicy is not used (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"SecurityContextDeny\"\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"PodSecurityPolicy\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --enable-admission-plugins parameter to include\n          SecurityContextDeny, unless PodSecurityPolicy is already in place.\n          --enable-admission-plugins=...,SecurityContextDeny,...\n        scored: true\n\n      - id: 1.2.14\n        text: \"Ensure that the admission control plugin ServiceAccount is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--disable-admission-plugins\"\n              compare:\n                op: nothave\n                value: \"ServiceAccount\"\n              set: true\n            - flag: \"--disable-admission-plugins\"\n              set: false\n        remediation: |\n          Follow the documentation and create ServiceAccount objects as per your environment.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and ensure that the --disable-admission-plugins parameter is set to a\n          value that does not include ServiceAccount.\n        scored: true\n\n      - id: 1.2.15\n        text: \"Ensure that the admission control plugin NamespaceLifecycle is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--disable-admission-plugins\"\n              compare:\n                op: nothave\n                value: \"NamespaceLifecycle\"\n              set: true\n            - flag: \"--disable-admission-plugins\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --disable-admission-plugins parameter to\n          ensure it does not include NamespaceLifecycle.\n        scored: true\n\n      - id: 1.2.16\n        text: \"Ensure that the admission control plugin NodeRestriction is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"NodeRestriction\"\n              set: true\n        remediation: |\n          Follow the Kubernetes documentation and configure NodeRestriction plug-in on kubelets.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --enable-admission-plugins parameter to a\n          value that includes NodeRestriction.\n          --enable-admission-plugins=...,NodeRestriction,...\n        scored: true\n\n      - id: 1.2.17\n        text: \"Ensure that the --secure-port argument is not set to 0 (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--secure-port\"\n              compare:\n                op: gt\n                value: 0\n              set: true\n            - flag: \"--secure-port\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and either remove the --secure-port parameter or\n          set it to a different (non-zero) desired port.\n        scored: true\n\n      - id: 1.2.18\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the below parameter.\n          --profiling=false\n        scored: true\n\n      - id: 1.2.19\n        text: \"Ensure that the --audit-log-path argument is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-path\"\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --audit-log-path parameter to a suitable path and\n          file where you would like audit logs to be written, for example,\n          --audit-log-path=/var/log/apiserver/audit.log\n        scored: true\n\n      - id: 1.2.20\n        text: \"Ensure that the --audit-log-maxage argument is set to 30 or as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxage\"\n              compare:\n                op: gte\n                value: 30\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --audit-log-maxage parameter to 30\n          or as an appropriate number of days, for example,\n          --audit-log-maxage=30\n        scored: true\n\n      - id: 1.2.21\n        text: \"Ensure that the --audit-log-maxbackup argument is set to 10 or as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxbackup\"\n              compare:\n                op: gte\n                value: 10\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --audit-log-maxbackup parameter to 10 or to an appropriate\n          value. For example,\n          --audit-log-maxbackup=10\n        scored: true\n\n      - id: 1.2.22\n        text: \"Ensure that the --audit-log-maxsize argument is set to 100 or as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxsize\"\n              compare:\n                op: gte\n                value: 100\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --audit-log-maxsize parameter to an appropriate size in MB.\n          For example, to set it as 100 MB, --audit-log-maxsize=100\n        scored: true\n\n      - id: 1.2.23\n        text: \"Ensure that the --request-timeout argument is set as appropriate (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        type: manual\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          and set the below parameter as appropriate and if needed.\n          For example, --request-timeout=300s\n        scored: false\n\n      - id: 1.2.24\n        text: \"Ensure that the --service-account-lookup argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--service-account-lookup\"\n              set: false\n            - flag: \"--service-account-lookup\"\n              compare:\n                op: eq\n                value: true\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the below parameter.\n          --service-account-lookup=true\n          Alternatively, you can delete the --service-account-lookup parameter from this file so\n          that the default takes effect.\n        scored: true\n\n      - id: 1.2.25\n        text: \"Ensure that the --service-account-key-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--service-account-key-file\"\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --service-account-key-file parameter\n          to the public key file for service accounts. For example,\n          --service-account-key-file=<filename>\n        scored: true\n\n      - id: 1.2.26\n        text: \"Ensure that the --etcd-certfile and --etcd-keyfile arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--etcd-certfile\"\n              set: true\n            - flag: \"--etcd-keyfile\"\n              set: true\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection between the apiserver and etcd.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the etcd certificate and key file parameters.\n          --etcd-certfile=<path/to/client-certificate-file>\n          --etcd-keyfile=<path/to/client-key-file>\n        scored: true\n\n      - id: 1.2.27\n        text: \"Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--tls-cert-file\"\n              set: true\n            - flag: \"--tls-private-key-file\"\n              set: true\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection on the apiserver.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the TLS certificate and private key file parameters.\n          --tls-cert-file=<path/to/tls-certificate-file>\n          --tls-private-key-file=<path/to/tls-key-file>\n        scored: true\n\n      - id: 1.2.28\n        text: \"Ensure that the --client-ca-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--client-ca-file\"\n              set: true\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection on the apiserver.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the client certificate authority file.\n          --client-ca-file=<path/to/client-ca-file>\n        scored: true\n\n      - id: 1.2.29\n        text: \"Ensure that the --etcd-cafile argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--etcd-cafile\"\n              set: true\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection between the apiserver and etcd.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the etcd certificate authority file parameter.\n          --etcd-cafile=<path/to/ca-file>\n        scored: true\n\n      - id: 1.2.30\n        text: \"Ensure that the --encryption-provider-config argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--encryption-provider-config\"\n              set: true\n        remediation: |\n          Follow the Kubernetes documentation and configure a EncryptionConfig file.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --encryption-provider-config parameter to the path of that file.\n          For example, --encryption-provider-config=</path/to/EncryptionConfig/File>\n        scored: true\n\n      - id: 1.2.31\n        text: \"Ensure that encryption providers are appropriately configured (Automated)\"\n        audit: |\n          ENCRYPTION_PROVIDER_CONFIG=$(ps -ef | grep $apiserverbin | grep -- --encryption-provider-config | sed 's%.*encryption-provider-config[= ]\\([^ ]*\\).*%\\1%')\n          if test -e $ENCRYPTION_PROVIDER_CONFIG; then grep -A1 'providers:' $ENCRYPTION_PROVIDER_CONFIG | tail -n1 | grep -o \"[A-Za-z]*\" | sed 's/^/provider=/'; fi\n        tests:\n          test_items:\n            - flag: \"provider\"\n              compare:\n                op: valid_elements\n                value: \"aescbc,kms,secretbox\"\n        remediation: |\n          Follow the Kubernetes documentation and configure a EncryptionConfig file.\n          In this file, choose aescbc, kms or secretbox as the encryption provider.\n          Enabling encryption changes how data can be recovered as data is encrypted.\n        scored: true\n\n      - id: 1.2.32\n        text: \"Ensure that the API Server only makes use of Strong Cryptographic Ciphers (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--tls-cipher-suites\"\n              compare:\n                op: valid_elements\n                value: \"TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,TLS_CHACHA20_POLY1305_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,TLS_RSA_WITH_3DES_EDE_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_256_GCM_SHA384\"\n        remediation: |\n          Edit the API server pod specification file /etc/kubernetes/manifests/kube-apiserver.yaml\n          on the control plane node and set the below parameter.\n          --tls-cipher-suites=TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,TLS_CHACHA20_POLY1305_SHA256,\n          TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,\n          TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,\n          TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,\n          TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,\n          TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,\n          TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,TLS_RSA_WITH_3DES_EDE_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA,\n          TLS_RSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_256_GCM_SHA384\n        scored: true\n\n  - id: 1.3\n    text: \"Controller Manager\"\n    checks:\n      - id: 1.3.1\n        text: \"Ensure that the --terminated-pod-gc-threshold argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--terminated-pod-gc-threshold\"\n              set: true\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the --terminated-pod-gc-threshold to an appropriate threshold,\n          for example, --terminated-pod-gc-threshold=10\n        scored: true\n\n      - id: 1.3.2\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n              set: true\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the below parameter.\n          --profiling=false\n        scored: true\n\n      - id: 1.3.3\n        text: \"Ensure that the --use-service-account-credentials argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--use-service-account-credentials\"\n              compare:\n                op: noteq\n                value: false\n              set: true\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node to set the below parameter.\n          --use-service-account-credentials=true\n        scored: true\n\n      - id: 1.3.4\n        text: \"Ensure that the --service-account-private-key-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--service-account-private-key-file\"\n              set: true\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the --service-account-private-key-file parameter\n          to the private key file for service accounts.\n          --service-account-private-key-file=<filename>\n        scored: true\n\n      - id: 1.3.5\n        text: \"Ensure that the --root-ca-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--root-ca-file\"\n              set: true\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the --root-ca-file parameter to the certificate bundle file`.\n          --root-ca-file=<path/to/file>\n        scored: true\n\n      - id: 1.3.6\n        text: \"Ensure that the RotateKubeletServerCertificate argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--feature-gates\"\n              compare:\n                op: nothave\n                value: \"RotateKubeletServerCertificate=false\"\n              set: true\n            - flag: \"--feature-gates\"\n              set: false\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the --feature-gates parameter to include RotateKubeletServerCertificate=true.\n          --feature-gates=RotateKubeletServerCertificate=true\n          Cluster provisioned by RKE handles certificate rotation directly through RKE.\n        scored: true\n\n      - id: 1.3.7\n        text: \"Ensure that the --bind-address argument is set to 127.0.0.1 (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--bind-address\"\n              compare:\n                op: eq\n                value: \"127.0.0.1\"\n              set: true\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and ensure the correct value for the --bind-address parameter\n        scored: true\n\n  - id: 1.4\n    text: \"Scheduler\"\n    checks:\n      - id: 1.4.1\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: \"/bin/ps -ef | grep $schedulerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n              set: true\n        remediation: |\n          Edit the Scheduler pod specification file $schedulerconf file\n          on the control plane node and set the below parameter.\n          --profiling=false\n        scored: true\n\n      - id: 1.4.2\n        text: \"Ensure that the --bind-address argument is set to 127.0.0.1 (Automated)\"\n        audit: \"/bin/ps -ef | grep $schedulerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--bind-address\"\n              compare:\n                op: eq\n                value: \"127.0.0.1\"\n              set: true\n        remediation: |\n          Edit the Scheduler pod specification file $schedulerconf\n          on the control plane node and ensure the correct value for the --bind-address parameter\n        scored: true\n"
  },
  {
    "path": "cfg/rke-cis-1.24/node.yaml",
    "content": "---\ncontrols:\nversion: \"rke-cis-1.24\"\nid: 4\ntext: \"Worker Node Security Configuration\"\ntype: \"node\"\ngroups:\n  - id: 4.1\n    text: \"Worker Node Configuration Files\"\n    checks:\n      - id: 4.1.1\n        text: \"Ensure that the kubelet service file permissions are set to 600 or more restrictive (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletsvc; then stat -c permissions=%a $kubeletsvc; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example, chmod 600 $kubeletsvc\n        scored: true\n\n      - id: 4.1.2\n        text: \"Ensure that the kubelet service file ownership is set to root:root (Automated)\"\n        type: \"skip\"\n        audit: '/bin/sh -c ''if test -e $kubeletsvc; then stat -c %U:%G $kubeletsvc; fi'' '\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chown root:root $kubeletsvc\n        scored: true\n\n      - id: 4.1.3\n        text: \"If proxy kubeconfig file exists ensure permissions are set to 600 or more restrictive (Automated)\"\n        audit: '/bin/sh -c ''if test -e $proxykubeconfig; then stat -c permissions=%a $proxykubeconfig; fi'' '\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"permissions\"\n              set: true\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chmod 600 $proxykubeconfig\n        scored: true\n\n      - id: 4.1.4\n        text: \"If proxy kubeconfig file exists ensure ownership is set to root:root (Automated)\"\n        audit: '/bin/sh -c ''if test -e $proxykubeconfig; then stat -c %U:%G $proxykubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example, chown root:root $proxykubeconfig\n        scored: true\n\n      - id: 4.1.5\n        text: \"Ensure that the --kubeconfig kubelet.conf file permissions are set to 600 or more restrictive (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletkubeconfig; then stat -c permissions=%a $kubeletkubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chmod 600 $kubeletkubeconfig\n        scored: true\n\n      - id: 4.1.6\n        text: \"Ensure that the --kubeconfig kubelet.conf file ownership is set to root:root (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletkubeconfig; then stat -c %U:%G $kubeletkubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chown root:root $kubeletkubeconfig\n        scored: true\n\n      - id: 4.1.7\n        text: \"Ensure that the certificate authorities file permissions are set to 600 or more restrictive (Automated)\"\n        audit: '/bin/sh -c \"if test -e /etc/kubernetes/ssl/kube-ca.pem; then stat -c permissions=%a /etc/kubernetes/ssl/kube-ca.pem; else echo \\\"File not found\\\"; fi\"'\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n            - flag: \"File not found\"\n        remediation: |\n          Run the following command to modify the file permissions of the\n          --client-ca-file chmod 600 <filename>\n        scored: true\n      - id: 4.1.8\n        text: \"Ensure that the client certificate authorities file ownership is set to root:root (Automated)\"\n        audit: '/bin/sh -c \"if test -e /etc/kubernetes/ssl/kube-ca.pem; then stat -c %U:%G /etc/kubernetes/ssl/kube-ca.pem; else echo \\\"File not found\\\"; fi\"'\n        tests:\n          bin_op: or\n          test_items:\n            - flag: root:root\n            - flag: \"File not found\"\n        remediation: |\n          Run the following command to modify the ownership of the --client-ca-file.\n          chown root:root <filename>\n        scored: true\n\n      - id: 4.1.9\n        text: \"If the kubelet config.yaml configuration file is being used validate permissions set to 600 or more restrictive (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletconf; then stat -c permissions=%a $kubeletconf; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Cluster provisioned by RKE doesn't require or maintain a configuration file for the kubelet.\n          All configuration is passed in as arguments at container run time.\n        scored: true\n\n      - id: 4.1.10\n        text: \"If the kubelet config.yaml configuration file is being used validate file ownership is set to root:root (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletconf; then stat -c %U:%G $kubeletconf; fi'' '\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Cluster provisioned by RKE doesn’t require or maintain a configuration file for the kubelet.\n          All configuration is passed in as arguments at container run time.\n        scored: true\n\n  - id: 4.2\n    text: \"Kubelet\"\n    checks:\n      - id: 4.2.1\n        text: \"Ensure that the --anonymous-auth argument is set to false (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/sh -c 'if test -e $kubeletconf; then /bin/cat $kubeletconf; fi' \"\n        tests:\n          test_items:\n            - flag: \"--anonymous-auth\"\n              path: '{.authentication.anonymous.enabled}'\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          If using a Kubelet config file, edit the file to set `authentication: anonymous: enabled` to\n          `false`.\n          If using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          `--anonymous-auth=false`\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.2\n        text: \"Ensure that the --authorization-mode argument is not set to AlwaysAllow (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/sh -c 'if test -e $kubeletconf; then /bin/cat $kubeletconf; fi' \"\n        tests:\n          test_items:\n            - flag: --authorization-mode\n              path: '{.authorization.mode}'\n              compare:\n                op: nothave\n                value: AlwaysAllow\n        remediation: |\n          If using a Kubelet config file, edit the file to set `authorization.mode` to Webhook. If\n          using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_AUTHZ_ARGS variable.\n          --authorization-mode=Webhook\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.3\n        text: \"Ensure that the --client-ca-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/sh -c 'if test -e $kubeletconf; then /bin/cat $kubeletconf; fi' \"\n        tests:\n          test_items:\n            - flag: --client-ca-file\n              path: '{.authentication.x509.clientCAFile}'\n        remediation: |\n          If using a Kubelet config file, edit the file to set `authentication.x509.clientCAFile` to\n          the location of the client CA file.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_AUTHZ_ARGS variable.\n          --client-ca-file=<path/to/client-ca-file>\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.4\n        text: \"Verify that the --read-only-port argument is set to 0 (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/sh -c 'if test -e $kubeletconf; then /bin/cat $kubeletconf; fi' \"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--read-only-port\"\n              path: '{.readOnlyPort}'\n              compare:\n                op: eq\n                value: 0\n            - flag: \"--read-only-port\"\n              path: '{.readOnlyPort}'\n              set: false\n        remediation: |\n          If using a Kubelet config file, edit the file to set `readOnlyPort` to 0.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --read-only-port=0\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.5\n        text: \"Ensure that the --streaming-connection-idle-timeout argument is not set to 0 (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/sh -c 'if test -e $kubeletconf; then /bin/cat $kubeletconf; fi' \"\n        tests:\n          test_items:\n            - flag: --streaming-connection-idle-timeout\n              path: '{.streamingConnectionIdleTimeout}'\n              compare:\n                op: noteq\n                value: 0\n            - flag: --streaming-connection-idle-timeout\n              path: '{.streamingConnectionIdleTimeout}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to set `streamingConnectionIdleTimeout` to a\n          value other than 0.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --streaming-connection-idle-timeout=5m\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.6\n        text: \"Ensure that the --protect-kernel-defaults argument is set to true (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/sh -c 'if test -e $kubeletconf; then /bin/cat $kubeletconf; fi' \"\n        tests:\n          test_items:\n            - flag: --protect-kernel-defaults\n              path: '{.protectKernelDefaults}'\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          If using a Kubelet config file, edit the file to set `protectKernelDefaults` to `true`.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --protect-kernel-defaults=true\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n          System level configurations are required prior to provisioning the cluster in order for this argument to be set to true.\n        scored: true\n\n      - id: 4.2.7\n        text: \"Ensure that the --make-iptables-util-chains argument is set to true (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/sh -c 'if test -e $kubeletconf; then /bin/cat $kubeletconf; fi' \"\n        tests:\n          test_items:\n            - flag: --make-iptables-util-chains\n              path: '{.makeIPTablesUtilChains}'\n              compare:\n                op: eq\n                value: true\n            - flag: --make-iptables-util-chains\n              path: '{.makeIPTablesUtilChains}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to set `makeIPTablesUtilChains` to `true`.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          remove the --make-iptables-util-chains argument from the\n          KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.8\n        text: \"Ensure that the --hostname-override argument is not set (Manual)\"\n        # This is one of those properties that can only be set as a command line argument.\n        # To check if the property is set as expected, we need to parse the kubelet command\n        # instead reading the Kubelet Configuration file.\n        type: \"skip\"\n        audit: \"/bin/ps -fC $kubeletbin \"\n        tests:\n          test_items:\n            - flag: --hostname-override\n              set: false\n        remediation: |\n          Edit the kubelet service file $kubeletsvc\n          on each worker node and remove the --hostname-override argument from the\n          KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n          Clusters provisioned by RKE set the --hostname-override to avoid any hostname configuration errors\n        scored: false\n\n      - id: 4.2.9\n        text: \"Ensure that the eventRecordQPS argument is set to a level which ensures appropriate event capture (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/sh -c 'if test -e $kubeletconf; then /bin/cat $kubeletconf; fi' \"\n        tests:\n          test_items:\n            - flag: --event-qps\n              path: '{.eventRecordQPS}'\n              compare:\n                op: eq\n                value: 0\n        remediation: |\n          If using a Kubelet config file, edit the file to set `eventRecordQPS` to an appropriate level.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.10\n        text: \"Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/sh -c 'if test -e $kubeletconf; then /bin/cat $kubeletconf; fi' \"\n        tests:\n          test_items:\n            - flag: --tls-cert-file\n              path: '{.tlsCertFile}'\n            - flag: --tls-private-key-file\n              path: '{.tlsPrivateKeyFile}'\n        remediation: |\n          If using a Kubelet config file, edit the file to set `tlsCertFile` to the location\n          of the certificate file to use to identify this Kubelet, and `tlsPrivateKeyFile`\n          to the location of the corresponding private key file.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameters in KUBELET_CERTIFICATE_ARGS variable.\n          --tls-cert-file=<path/to/tls-certificate-file>\n          --tls-private-key-file=<path/to/tls-key-file>\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n          When generating serving certificates, functionality could break in conjunction with hostname overrides which are required for certain cloud providers.\n        scored: true\n\n      - id: 4.2.11\n        text: \"Ensure that the --rotate-certificates argument is not set to false (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/sh -c 'if test -e $kubeletconf; then /bin/cat $kubeletconf; fi' \"\n        tests:\n          test_items:\n            - flag: --rotate-certificates\n              path: '{.rotateCertificates}'\n              compare:\n                op: eq\n                value: true\n            - flag: --rotate-certificates\n              path: '{.rotateCertificates}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to add the line `rotateCertificates` to `true` or\n          remove it altogether to use the default value.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          remove --rotate-certificates=false argument from the KUBELET_CERTIFICATE_ARGS\n          variable.\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.12\n        text: \"Verify that the RotateKubeletServerCertificate argument is set to true (Manual)\"\n        type: \"skip\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/sh -c 'if test -e $kubeletconf; then /bin/cat $kubeletconf; fi' \"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: RotateKubeletServerCertificate\n              path: '{.featureGates.RotateKubeletServerCertificate}'\n              compare:\n                op: nothave\n                value: false\n            - flag: RotateKubeletServerCertificate\n              path: '{.featureGates.RotateKubeletServerCertificate}'\n              set: false\n        remediation: |\n          Edit the kubelet service file $kubeletsvc\n          on each worker node and set the below parameter in KUBELET_CERTIFICATE_ARGS variable.\n          --feature-gates=RotateKubeletServerCertificate=true\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n          Clusters provisioned by RKE handles certificate rotation directly through RKE.\n        scored: false\n\n      - id: 4.2.13\n        text: \"Ensure that the Kubelet only makes use of Strong Cryptographic Ciphers (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/sh -c 'if test -e $kubeletconf; then /bin/cat $kubeletconf; fi' \"\n        tests:\n          test_items:\n            - flag: --tls-cipher-suites\n              path: '{range .tlsCipherSuites[:]}{}{'',''}{end}'\n              compare:\n                op: valid_elements\n                value: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\n        remediation: |\n          If using a Kubelet config file, edit the file to set `tlsCipherSuites` to\n          TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\n          or to a subset of these values.\n          If using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the --tls-cipher-suites parameter as follows, or to a subset of these values.\n          --tls-cipher-suites=TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n"
  },
  {
    "path": "cfg/rke-cis-1.24/policies.yaml",
    "content": "---\ncontrols:\nversion: \"rke-cis-1.24\"\nid: 5\ntext: \"Kubernetes Policies\"\ntype: \"policies\"\ngroups:\n  - id: 5.1\n    text: \"RBAC and Service Accounts\"\n    checks:\n      - id: 5.1.1\n        text: \"Ensure that the cluster-admin role is only used where required (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Identify all clusterrolebindings to the cluster-admin role. Check if they are used and\n          if they need this role or if they could use a role with fewer privileges.\n          Where possible, first bind users to a lower privileged role and then remove the\n          clusterrolebinding to the cluster-admin role :\n          kubectl delete clusterrolebinding [name]\n        scored: false\n\n      - id: 5.1.2\n        text: \"Minimize access to secrets (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove get, list and watch access to Secret objects in the cluster.\n        scored: false\n\n      - id: 5.1.3\n        text: \"Minimize wildcard use in Roles and ClusterRoles (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible replace any use of wildcards in clusterroles and roles with specific\n          objects or actions.\n        scored: false\n\n      - id: 5.1.4\n        text: \"Minimize access to create pods (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove create access to pod objects in the cluster.\n        scored: false\n\n      - id: 5.1.5\n        text: \"Ensure that default service accounts are not actively used. (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Create explicit service accounts wherever a Kubernetes workload requires specific access\n          to the Kubernetes API server.\n          Modify the configuration of each default service account to include this value\n          automountServiceAccountToken: false\n        scored: false\n\n      - id: 5.1.6\n        text: \"Ensure that Service Account Tokens are only mounted where necessary (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Modify the definition of pods and service accounts which do not need to mount service\n          account tokens to disable it.\n        scored: false\n\n      - id: 5.1.7\n        text: \"Avoid use of system:masters group (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Remove the system:masters group from all users in the cluster.\n        scored: false\n\n      - id: 5.1.8\n        text: \"Limit use of the Bind, Impersonate and Escalate permissions in the Kubernetes cluster (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove the impersonate, bind and escalate rights from subjects.\n        scored: false\n\n  - id: 5.2\n    text: \"Pod Security Standards\"\n    checks:\n      - id: 5.2.1\n        text: \"Ensure that the cluster has at least one active policy control mechanism in place (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that either Pod Security Admission or an external policy control system is in place\n          for every namespace which contains user workloads.\n        scored: false\n\n      - id: 5.2.2\n        text: \"Minimize the admission of privileged containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of privileged containers.\n        scored: false\n\n      - id: 5.2.3\n        text: \"Minimize the admission of containers wishing to share the host process ID namespace (Automated)\"\n        audit: |\n          kubectl get psp -o json | jq .items[] | jq -r 'select((.spec.hostPID == null) or (.spec.hostPID == false))' | jq .metadata.name | wc -l | xargs -I {} echo '--count={}'\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"kubectl: not found\"\n            - flag: \"jq: not found\"\n            - flag: count\n              compare:\n                op: gt\n                value: 0\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of `hostPID` containers.\n        scored: true\n\n      - id: 5.2.4\n        text: \"Minimize the admission of containers wishing to share the host IPC namespace (Automated)\"\n        audit: |\n          kubectl get psp -o json | jq .items[] | jq -r 'select((.spec.hostIPC == null) or (.spec.hostIPC == false))' | jq .metadata.name | wc -l | xargs -I {} echo '--count={}'\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"kubectl: not found\"\n            - flag: \"jq: not found\"\n            - flag: count\n              compare:\n                op: gt\n                value: 0\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of `hostIPC` containers.\n        scored: true\n\n      - id: 5.2.5\n        text: \"Minimize the admission of containers wishing to share the host network namespace (Automated)\"\n        audit: |\n          kubectl get psp -o json | jq .items[] | jq -r 'select((.spec.hostNetwork == null) or (.spec.hostNetwork == false))' | jq .metadata.name | wc -l | xargs -I {} echo '--count={}'\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"kubectl: not found\"\n            - flag: \"jq: not found\"\n            - flag: count\n              compare:\n                op: gt\n                value: 0\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of `hostNetwork` containers.\n        scored: true\n\n      - id: 5.2.6\n        text: \"Minimize the admission of containers with allowPrivilegeEscalation (Automated)\"\n        audit: |\n          kubectl get psp -o json | jq .items[] | jq -r 'select((.spec.allowPrivilegeEscalation == null) or (.spec.allowPrivilegeEscalation == false))' | jq .metadata.name | wc -l | xargs -I {} echo '--count={}'\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"kubectl: not found\"\n            - flag: \"jq: not found\"\n            - flag: count\n              compare:\n                op: gt\n                value: 0\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers with `.spec.allowPrivilegeEscalation` set to `true`.\n        scored: true\n\n      - id: 5.2.7\n        text: \"Minimize the admission of root containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Create a policy for each namespace in the cluster, ensuring that either `MustRunAsNonRoot`\n          or `MustRunAs` with the range of UIDs not including 0, is set.\n        scored: false\n\n      - id: 5.2.8\n        text: \"Minimize the admission of containers with the NET_RAW capability (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers with the `NET_RAW` capability.\n        scored: false\n\n      - id: 5.2.9\n        text: \"Minimize the admission of containers with added capabilities (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that `allowedCapabilities` is not present in policies for the cluster unless\n          it is set to an empty array.\n        scored: false\n\n      - id: 5.2.10\n        text: \"Minimize the admission of containers with capabilities assigned (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Review the use of capabilites in applications running on your cluster. Where a namespace\n          contains applications which do not require any Linux capabities to operate consider adding\n          a PSP which forbids the admission of containers which do not drop all capabilities.\n        scored: false\n\n      - id: 5.2.11\n        text: \"Minimize the admission of Windows HostProcess containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers that have `.securityContext.windowsOptions.hostProcess` set to `true`.\n        scored: false\n\n      - id: 5.2.12\n        text: \"Minimize the admission of HostPath volumes (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers with `hostPath` volumes.\n        scored: false\n\n      - id: 5.2.13\n        text: \"Minimize the admission of containers which use HostPorts (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers which use `hostPort` sections.\n        scored: false\n\n  - id: 5.3\n    text: \"Network Policies and CNI\"\n    checks:\n      - id: 5.3.1\n        text: \"Ensure that the CNI in use supports NetworkPolicies (Manual)\"\n        type: \"manual\"\n        remediation: |\n          If the CNI plugin in use does not support network policies, consideration should be given to\n          making use of a different plugin, or finding an alternate mechanism for restricting traffic\n          in the Kubernetes cluster.\n        scored: false\n\n      - id: 5.3.2\n        text: \"Ensure that all Namespaces have NetworkPolicies defined (Manual)\"\n        type: \"skip\"\n        remediation: |\n          Follow the documentation and create NetworkPolicy objects as you need them.\n        scored: false\n\n  - id: 5.4\n    text: \"Secrets Management\"\n    checks:\n      - id: 5.4.1\n        text: \"Prefer using Secrets as files over Secrets as environment variables (Manual)\"\n        type: \"manual\"\n        remediation: |\n          If possible, rewrite application code to read Secrets from mounted secret files, rather than\n          from environment variables.\n        scored: false\n\n      - id: 5.4.2\n        text: \"Consider external secret storage (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Refer to the Secrets management options offered by your cloud provider or a third-party\n          secrets management solution.\n        scored: false\n\n  - id: 5.5\n    text: \"Extensible Admission Control\"\n    checks:\n      - id: 5.5.1\n        text: \"Configure Image Provenance using ImagePolicyWebhook admission controller (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and setup image provenance.\n        scored: false\n\n  - id: 5.7\n    text: \"General Policies\"\n    checks:\n      - id: 5.7.1\n        text: \"Create administrative boundaries between resources using namespaces (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the documentation and create namespaces for objects in your deployment as you need\n          them.\n        scored: false\n\n      - id: 5.7.2\n        text: \"Ensure that the seccomp profile is set to docker/default in your Pod definitions (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Use `securityContext` to enable the docker/default seccomp profile in your pod definitions.\n          An example is as below:\n            securityContext:\n              seccompProfile:\n                type: RuntimeDefault\n        scored: false\n\n      - id: 5.7.3\n        text: \"Apply SecurityContext to your Pods and Containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and apply SecurityContexts to your Pods. For a\n          suggested list of SecurityContexts, you may refer to the CIS Security Benchmark for Docker\n          Containers.\n        scored: false\n\n      - id: 5.7.4\n        text: \"The default namespace should not be used (Automated)\"\n        audit: |\n          #!/bin/bash\n          set -eE\n          handle_error() {\n              echo \"false\"\n          }\n          trap 'handle_error' ERR\n          count=$(kubectl get all -n default -o json | jq .items[] | jq -r 'select((.metadata.name!=\"kubernetes\"))' | jq .metadata.name | wc -l)\n          if [[ ${count} -gt 0 ]]; then\n              echo \"false\"\n              exit\n          fi\n          echo \"true\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"kubectl: not found\"\n            - flag: \"jq: not found\"\n            - flag: \"true\"\n        remediation: |\n          Ensure that namespaces are created to allow for appropriate segregation of Kubernetes\n          resources and that all new resources are created in a specific namespace.\n        scored: true\n"
  },
  {
    "path": "cfg/rke-cis-1.7/config.yaml",
    "content": "---\n## Version-specific settings that override the values in cfg/config.yaml\n"
  },
  {
    "path": "cfg/rke-cis-1.7/controlplane.yaml",
    "content": "---\ncontrols:\nversion: \"rke-cis-1.7\"\nid: 3\ntext: \"Control Plane Configuration\"\ntype: \"controlplane\"\ngroups:\n  - id: 3.1\n    text: \"Authentication and Authorization\"\n    checks:\n      - id: 3.1.1\n        text: \"Client certificate authentication should not be used for users (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Alternative mechanisms provided by Kubernetes such as the use of OIDC should be\n          implemented in place of client certificates.\n        scored: false\n      - id: 3.1.2\n        text: \"Service account token authentication should not be used for users (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Alternative mechanisms provided by Kubernetes such as the use of OIDC should be implemented\n          in place of service account tokens.\n        scored: false\n      - id: 3.1.3\n        text: \"Bootstrap token authentication should not be used for users (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Alternative mechanisms provided by Kubernetes such as the use of OIDC should be implemented\n          in place of bootstrap tokens.\n        scored: false\n\n  - id: 3.2\n    text: \"Logging\"\n    checks:\n      - id: 3.2.1\n        text: \"Ensure that a minimal audit policy is created (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-policy-file\"\n              set: true\n        remediation: |\n          Create an audit policy file for your cluster.\n        scored: true\n\n      - id: 3.2.2\n        text: \"Ensure that the audit policy covers key security concerns (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Review the audit policy provided for the cluster and ensure that it covers\n          at least the following areas,\n          - Access to Secrets managed by the cluster. Care should be taken to only\n            log Metadata for requests to Secrets, ConfigMaps, and TokenReviews, in\n            order to avoid risk of logging sensitive data.\n          - Modification of Pod and Deployment objects.\n          - Use of `pods/exec`, `pods/portforward`, `pods/proxy` and `services/proxy`.\n          For most requests, minimally logging at the Metadata level is recommended\n          (the most basic level of logging).\n        scored: false\n"
  },
  {
    "path": "cfg/rke-cis-1.7/etcd.yaml",
    "content": "---\ncontrols:\nversion: \"rke-cis-1.7\"\nid: 2\ntext: \"Etcd Node Configuration\"\ntype: \"etcd\"\ngroups:\n  - id: 2\n    text: \"Etcd Node Configuration\"\n    checks:\n      - id: 2.1\n        text: \"Ensure that the --cert-file and --key-file arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--cert-file\"\n              env: \"ETCD_CERT_FILE\"\n            - flag: \"--key-file\"\n              env: \"ETCD_KEY_FILE\"\n        remediation: |\n          Follow the etcd service documentation and configure TLS encryption.\n          Then, edit the etcd pod specification file /etc/kubernetes/manifests/etcd.yaml\n          on the master node and set the below parameters.\n          --cert-file=</path/to/ca-file>\n          --key-file=</path/to/key-file>\n        scored: true\n\n      - id: 2.2\n        text: \"Ensure that the --client-cert-auth argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--client-cert-auth\"\n              env: \"ETCD_CLIENT_CERT_AUTH\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and set the below parameter.\n          --client-cert-auth=\"true\"\n        scored: true\n\n      - id: 2.3\n        text: \"Ensure that the --auto-tls argument is not set to true (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--auto-tls\"\n              env: \"ETCD_AUTO_TLS\"\n              set: false\n            - flag: \"--auto-tls\"\n              env: \"ETCD_AUTO_TLS\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and either remove the --auto-tls parameter or set it to false.\n            --auto-tls=false\n        scored: true\n\n      - id: 2.4\n        text: \"Ensure that the --peer-cert-file and --peer-key-file arguments are\n        set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--peer-cert-file\"\n              env: \"ETCD_PEER_CERT_FILE\"\n            - flag: \"--peer-key-file\"\n              env: \"ETCD_PEER_KEY_FILE\"\n        remediation: |\n          Follow the etcd service documentation and configure peer TLS encryption as appropriate\n          for your etcd cluster.\n          Then, edit the etcd pod specification file $etcdconf on the\n          master node and set the below parameters.\n          --peer-client-file=</path/to/peer-cert-file>\n          --peer-key-file=</path/to/peer-key-file>\n        scored: true\n\n      - id: 2.5\n        text: \"Ensure that the --peer-client-cert-auth argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--peer-client-cert-auth\"\n              env: \"ETCD_PEER_CLIENT_CERT_AUTH\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and set the below parameter.\n          --peer-client-cert-auth=true\n        scored: true\n\n      - id: 2.6\n        text: \"Ensure that the --peer-auto-tls argument is not set to true (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--peer-auto-tls\"\n              env: \"ETCD_PEER_AUTO_TLS\"\n              set: false\n            - flag: \"--peer-auto-tls\"\n              env: \"ETCD_PEER_AUTO_TLS\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and either remove the --peer-auto-tls parameter or set it to false.\n          --peer-auto-tls=false\n        scored: true\n\n      - id: 2.7\n        text: \"Ensure that a unique Certificate Authority is used for etcd (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--trusted-ca-file\"\n              env: \"ETCD_TRUSTED_CA_FILE\"\n              set: true\n        remediation: |\n          [Manual test]\n          Follow the etcd documentation and create a dedicated certificate authority setup for the\n          etcd service.\n          Then, edit the etcd pod specification file $etcdconf on the\n          master node and set the below parameter.\n          --trusted-ca-file=</path/to/ca-file>\n        scored: true\n"
  },
  {
    "path": "cfg/rke-cis-1.7/master.yaml",
    "content": "---\ncontrols:\nversion: \"rke-cis-1.7\"\nid: 1\ntext: \"Control Plane Security Configuration\"\ntype: \"master\"\ngroups:\n  - id: 1.1\n    text: \"Control Plane Node Configuration Files\"\n    checks:\n      - id: 1.1.1\n        text: \"Ensure that the API server pod specification file permissions are set to 600 or more restrictive (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/sh -c 'if test -e $apiserverconf; then stat -c permissions=%a $apiserverconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the\n          control plane node.\n          For example, chmod 600 $apiserverconf\n          Not Applicable -  Cluster provisioned by RKE doesn't require or maintain a configuration file for kube-apiserver.\n          All configuration is passed in as arguments at container run time.\n        scored: true\n\n      - id: 1.1.2\n        text: \"Ensure that the API server pod specification file ownership is set to root:root (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/sh -c 'if test -e $apiserverconf; then stat -c %U:%G $apiserverconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chown root:root $apiserverconf\n          Not Applicable -  Cluster provisioned by RKE doesn't require or maintain a configuration file for kube-apiserver.\n          All configuration is passed in as arguments at container run time.\n        scored: true\n\n      - id: 1.1.3\n        text: \"Ensure that the controller manager pod specification file permissions are set to 600 or more restrictive (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerconf; then stat -c permissions=%a $controllermanagerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chmod 600 $controllermanagerconf\n          Not Applicable -  Cluster provisioned by RKE doesn't require or maintain a configuration file for kube-apiserver.\n          All configuration is passed in as arguments at container run time.\n        scored: true\n\n      - id: 1.1.4\n        text: \"Ensure that the controller manager pod specification file ownership is set to root:root (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerconf; then stat -c %U:%G $controllermanagerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chown root:root $controllermanagerconf\n          Not Applicable -  Cluster provisioned by RKE doesn't require or maintain a configuration file for kube-apiserver.\n          All configuration is passed in as arguments at container run time.\n        scored: true\n\n      - id: 1.1.5\n        text: \"Ensure that the scheduler pod specification file permissions are set to 600 or more restrictive (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/sh -c 'if test -e $schedulerconf; then stat -c permissions=%a $schedulerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chmod 600 $schedulerconf\n          Not Applicable -  Cluster provisioned by RKE doesn't require or maintain a configuration file for kube-apiserver.\n          All configuration is passed in as arguments at container run time.\n        scored: true\n\n      - id: 1.1.6\n        text: \"Ensure that the scheduler pod specification file ownership is set to root:root (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/sh -c 'if test -e $schedulerconf; then stat -c %U:%G $schedulerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chown root:root $schedulerconf\n          Not Applicable -  Cluster provisioned by RKE doesn't require or maintain a configuration file for kube-apiserver.\n          All configuration is passed in as arguments at container run time.\n        scored: true\n\n      - id: 1.1.7\n        text: \"Ensure that the etcd pod specification file permissions are set to 600 or more restrictive (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/sh -c 'if test -e $etcdconf; then find $etcdconf -name '*etcd*' | xargs stat -c permissions=%a; fi'\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod 600 $etcdconf\n          Not Applicable -  Cluster provisioned by RKE doesn't require or maintain a configuration file for kube-apiserver.\n          All configuration is passed in as arguments at container run time.\n        scored: true\n\n      - id: 1.1.8\n        text: \"Ensure that the etcd pod specification file ownership is set to root:root (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/sh -c 'if test -e $etcdconf; then find $etcdconf -name '*etcd*' | xargs stat -c %U:%G; fi'\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root $etcdconf\n          Not Applicable -  Cluster provisioned by RKE doesn't require or maintain a configuration file for kube-apiserver.\n          All configuration is passed in as arguments at container run time.\n        scored: true\n\n      - id: 1.1.9\n        text: \"Ensure that the Container Network Interface file permissions are set to 600 or more restrictive (Manual)\"\n        audit: |\n          ps -ef | grep $kubeletbin | grep -- --cni-conf-dir | sed 's%.*cni-conf-dir[= ]\\([^ ]*\\).*%\\1%' | xargs -I{} find {} -mindepth 1 | xargs --no-run-if-empty stat -c permissions=%a\n          find /var/lib/cni/networks -type f 2> /dev/null | xargs --no-run-if-empty stat -c permissions=%a\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chmod 600 <path/to/cni/files>\n        scored: false\n\n      - id: 1.1.10\n        text: \"Ensure that the Container Network Interface file ownership is set to root:root (Manual)\"\n        audit: |\n          ps -ef | grep $kubeletbin | grep -- --cni-conf-dir | sed 's%.*cni-conf-dir[= ]\\([^ ]*\\).*%\\1%' | xargs -I{} find {} -mindepth 1 | xargs --no-run-if-empty stat -c %U:%G\n          find /var/lib/cni/networks -type f 2> /dev/null | xargs --no-run-if-empty stat -c %U:%G\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root <path/to/cni/files>\n        scored: false\n\n      - id: 1.1.11\n        text: \"Ensure that the etcd data directory permissions are set to 700 or more restrictive (Automated)\"\n        audit: '/bin/sh -c \"if test -e /var/lib/etcd; then stat -c %a /var/lib/etcd; else echo \\\"Directory not found\\\"; fi\"'\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"700\"\n            - flag: \"Directory not found\"\n        remediation: |\n          On the etcd server node, get the etcd data directory, passed as an argument --data-dir,\n          from the command 'ps -ef | grep etcd'.\n          Run the below command (based on the etcd data directory found above). For example,\n          chmod 700 /var/lib/etcd\n        scored: true\n\n      - id: 1.1.12\n        text: \"Ensure that the etcd data directory ownership is set to etcd:etcd (Automated)\"\n        type: \"skip\"\n        audit: \"stat -c %U:%G /node/var/lib/etcd\"\n        tests:\n          test_items:\n            - flag: \"etcd:etcd\"\n              set: true\n        remediation: |\n          On the etcd server node, get the etcd data directory, passed as an argument --data-dir,\n          from the command 'ps -ef | grep etcd'.\n          Run the below command (based on the etcd data directory found above).\n          For example, chown etcd:etcd /var/lib/etcd\n          Permissive - A system service account is required for etcd data directory ownership.\n          Refer to Rancher's hardening guide for more details on how to configure this ownership.\n        scored: true\n\n      - id: 1.1.13\n        text: \"Ensure that the admin.conf file permissions are set to 600 or more restrictive (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/sh -c 'if test -e /etc/kubernetes/admin.conf; then stat -c permissions=%a /etc/kubernetes/admin.conf; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chmod 600 /etc/kubernetes/admin.conf\n          Not Applicable -  Cluster provisioned by RKE does not store the kubernetes default kubeconfig credentials file on the nodes.\n        scored: true\n\n      - id: 1.1.14\n        text: \"Ensure that the admin.conf file ownership is set to root:root (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/sh -c 'if test -e /etc/kubernetes/admin.conf; then stat -c %U:%G /etc/kubernetes/admin.conf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chown root:root /etc/kubernetes/admin.conf\n          Not Applicable -  Cluster provisioned by RKE does not store the kubernetes default kubeconfig credentials file on the nodes.\n        scored: true\n\n      - id: 1.1.15\n        text: \"Ensure that the scheduler.conf file permissions are set to 600 or more restrictive (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/sh -c 'if test -e $schedulerkubeconfig; then stat -c permissions=%a $schedulerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod 600 $schedulerkubeconfig\n          Not Applicable -  Cluster provisioned by RKE doesn't require or maintain a configuration file for scheduler.\n          All configuration is passed in as arguments at container run time.\n        scored: true\n\n      - id: 1.1.16\n        text: \"Ensure that the scheduler.conf file ownership is set to root:root (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/sh -c 'if test -e $schedulerkubeconfig; then stat -c %U:%G $schedulerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root $schedulerkubeconfig\n          Not Applicable -  Cluster provisioned by RKE doesn't require or maintain a configuration file for scheduler.\n          All configuration is passed in as arguments at container run time.\n        scored: true\n\n      - id: 1.1.17\n        text: \"Ensure that the controller-manager.conf file permissions are set to 600 or more restrictive (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerkubeconfig; then stat -c permissions=%a $controllermanagerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod 600 $controllermanagerkubeconfig\n          Not Applicable -  Cluster provisioned by RKE doesn't require or maintain a configuration file for controller-manager.\n          All configuration is passed in as arguments at container run time.\n        scored: true\n\n      - id: 1.1.18\n        text: \"Ensure that the controller-manager.conf file ownership is set to root:root (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerkubeconfig; then stat -c %U:%G $controllermanagerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root $controllermanagerkubeconfig\n          Not Applicable -  Cluster provisioned by RKE doesn't require or maintain a configuration file for controller-manager.\n          All configuration is passed in as arguments at container run time.\n        scored: true\n\n      - id: 1.1.19\n        text: \"Ensure that the Kubernetes PKI directory and file ownership is set to root:root (Automated)\"\n        audit: \"check_files_owner_in_dir.sh /etc/kubernetes/ssl\"\n        tests:\n          test_items:\n            - flag: \"true\"\n              compare:\n                op: eq\n                value: \"true\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown -R root:root /etc/kubernetes/ssl/\n        scored: true\n\n      - id: 1.1.20\n        text: \"Ensure that the Kubernetes PKI certificate file permissions are set to 600 or more restrictive (Manual)\"\n        audit: \"find /etc/kubernetes/ssl/  -name '*.pem' ! -name '*key.pem' | xargs stat -c permissions=%a\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          find /etc/kubernetes/ssl/  -name '*.pem' ! -name '*key.pem' -exec chmod -R 600 {} +\n        scored: false\n\n      - id: 1.1.21\n        text: \"Ensure that the Kubernetes PKI key file permissions are set to 600 (Manual)\"\n        audit: \"find /etc/kubernetes/ssl/ -name '*key.pem' | xargs stat -c permissions=%a\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          find /etc/kubernetes/ssl/ -name '*key.pem' -exec chmod -R 600 {} +\n        scored: false\n\n  - id: 1.2\n    text: \"API Server\"\n    checks:\n      - id: 1.2.1\n        text: \"Ensure that the --anonymous-auth argument is set to false (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--anonymous-auth\"\n              compare:\n                op: eq\n                value: false\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the below parameter.\n          --anonymous-auth=false\n        scored: true\n\n      - id: 1.2.2\n        text: \"Ensure that the --token-auth-file parameter is not set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--token-auth-file\"\n              set: false\n        remediation: |\n          Follow the documentation and configure alternate mechanisms for authentication. Then,\n          edit the API server pod specification file $apiserverconf\n          on the control plane node and remove the --token-auth-file=<filename> parameter.\n        scored: true\n\n      - id: 1.2.3\n        text: \"Ensure that the --DenyServiceExternalIPs is not set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: nothave\n                value: \"DenyServiceExternalIPs\"\n              set: true\n            - flag: \"--enable-admission-plugins\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and remove the `DenyServiceExternalIPs`\n          from enabled admission plugins.\n        scored: true\n\n      - id: 1.2.4\n        text: \"Ensure that the --kubelet-client-certificate and --kubelet-client-key arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--kubelet-client-certificate\"\n            - flag: \"--kubelet-client-key\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection between the\n          apiserver and kubelets. Then, edit API server pod specification file\n          $apiserverconf on the control plane node and set the\n          kubelet client certificate and key parameters as below.\n          --kubelet-client-certificate=<path/to/client-certificate-file>\n          --kubelet-client-key=<path/to/client-key-file>\n        scored: true\n\n      - id: 1.2.5\n        text: \"Ensure that the --kubelet-certificate-authority argument is set as appropriate (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--kubelet-certificate-authority\"\n              set: true\n        remediation: |\n          Follow the Kubernetes documentation and setup the TLS connection between\n          the apiserver and kubelets. Then, edit the API server pod specification file\n          $apiserverconf on the control plane node and set the\n          --kubelet-certificate-authority parameter to the path to the cert file for the certificate authority.\n          --kubelet-certificate-authority=<ca-string>\n          Permissive - When generating serving certificates, functionality could break in conjunction with hostname overrides which are required for certain cloud providers.\n        scored: true\n\n      - id: 1.2.6\n        text: \"Ensure that the --authorization-mode argument is not set to AlwaysAllow (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: nothave\n                value: \"AlwaysAllow\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --authorization-mode parameter to values other than AlwaysAllow.\n          One such example could be as below.\n          --authorization-mode=RBAC\n        scored: true\n\n      - id: 1.2.7\n        text: \"Ensure that the --authorization-mode argument includes Node (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: has\n                value: \"Node\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --authorization-mode parameter to a value that includes Node.\n          --authorization-mode=Node,RBAC\n        scored: true\n\n      - id: 1.2.8\n        text: \"Ensure that the --authorization-mode argument includes RBAC (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: has\n                value: \"RBAC\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --authorization-mode parameter to a value that includes RBAC,\n          for example `--authorization-mode=Node,RBAC`.\n        scored: true\n\n      - id: 1.2.9\n        text: \"Ensure that the admission control plugin EventRateLimit is set (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"EventRateLimit\"\n        remediation: |\n          Follow the Kubernetes documentation and set the desired limits in a configuration file.\n          Then, edit the API server pod specification file $apiserverconf\n          and set the below parameters.\n          --enable-admission-plugins=...,EventRateLimit,...\n          --admission-control-config-file=<path/to/configuration/file>\n        scored: false\n\n      - id: 1.2.10\n        text: \"Ensure that the admission control plugin AlwaysAdmit is not set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: nothave\n                value: AlwaysAdmit\n            - flag: \"--enable-admission-plugins\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and either remove the --enable-admission-plugins parameter, or set it to a\n          value that does not include AlwaysAdmit.\n        scored: true\n\n      - id: 1.2.11\n        text: \"Ensure that the admission control plugin AlwaysPullImages is set (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"AlwaysPullImages\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --enable-admission-plugins parameter to include\n          AlwaysPullImages.\n          --enable-admission-plugins=...,AlwaysPullImages,...\n        scored: false\n\n      - id: 1.2.12\n        text: \"Ensure that the admission control plugin SecurityContextDeny is set if PodSecurityPolicy is not used (Manual)\"\n        type: \"skip\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"SecurityContextDeny\"\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"PodSecurityPolicy\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --enable-admission-plugins parameter to include\n          SecurityContextDeny, unless PodSecurityPolicy is already in place.\n          --enable-admission-plugins=...,SecurityContextDeny,...\n          Permissive - Enabling Pod Security Policy can cause applications to unexpectedly fail.\n        scored: false\n\n      - id: 1.2.13\n        text: \"Ensure that the admission control plugin ServiceAccount is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--disable-admission-plugins\"\n              compare:\n                op: nothave\n                value: \"ServiceAccount\"\n            - flag: \"--disable-admission-plugins\"\n              set: false\n        remediation: |\n          Follow the documentation and create ServiceAccount objects as per your environment.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and ensure that the --disable-admission-plugins parameter is set to a\n          value that does not include ServiceAccount.\n        scored: true\n\n      - id: 1.2.14\n        text: \"Ensure that the admission control plugin NamespaceLifecycle is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--disable-admission-plugins\"\n              compare:\n                op: nothave\n                value: \"NamespaceLifecycle\"\n            - flag: \"--disable-admission-plugins\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --disable-admission-plugins parameter to\n          ensure it does not include NamespaceLifecycle.\n        scored: true\n\n      - id: 1.2.15\n        text: \"Ensure that the admission control plugin NodeRestriction is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"NodeRestriction\"\n        remediation: |\n          Follow the Kubernetes documentation and configure NodeRestriction plug-in on kubelets.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --enable-admission-plugins parameter to a\n          value that includes NodeRestriction.\n          --enable-admission-plugins=...,NodeRestriction,...\n        scored: true\n\n      - id: 1.2.16\n        text: \"Ensure that the --secure-port argument is not set to 0 - NoteThis recommendation is obsolete and will be deleted per the consensus process (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--secure-port\"\n              compare:\n                op: gt\n                value: 0\n            - flag: \"--secure-port\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and either remove the --secure-port parameter or\n          set it to a different (non-zero) desired port.\n        scored: true\n\n      - id: 1.2.17\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the below parameter.\n          --profiling=false\n        scored: true\n\n      - id: 1.2.18\n        text: \"Ensure that the --audit-log-path argument is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-path\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --audit-log-path parameter to a suitable path and\n          file where you would like audit logs to be written, for example,\n          --audit-log-path=/var/log/apiserver/audit.log\n        scored: true\n\n      - id: 1.2.19\n        text: \"Ensure that the --audit-log-maxage argument is set to 30 or as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxage\"\n              compare:\n                op: gte\n                value: 30\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --audit-log-maxage parameter to 30\n          or as an appropriate number of days, for example,\n          --audit-log-maxage=30\n        scored: true\n\n      - id: 1.2.20\n        text: \"Ensure that the --audit-log-maxbackup argument is set to 10 or as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxbackup\"\n              compare:\n                op: gte\n                value: 10\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --audit-log-maxbackup parameter to 10 or to an appropriate\n          value. For example,\n          --audit-log-maxbackup=10\n        scored: true\n\n      - id: 1.2.21\n        text: \"Ensure that the --audit-log-maxsize argument is set to 100 or as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxsize\"\n              compare:\n                op: gte\n                value: 100\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --audit-log-maxsize parameter to an appropriate size in MB.\n          For example, to set it as 100 MB, --audit-log-maxsize=100\n        scored: true\n\n      - id: 1.2.22\n        text: \"Ensure that the --request-timeout argument is set as appropriate (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        type: manual\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          and set the below parameter as appropriate and if needed.\n          For example, --request-timeout=300s\n        scored: false\n\n      - id: 1.2.23\n        text: \"Ensure that the --service-account-lookup argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--service-account-lookup\"\n              set: false\n            - flag: \"--service-account-lookup\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the below parameter.\n          --service-account-lookup=true\n          Alternatively, you can delete the --service-account-lookup parameter from this file so\n          that the default takes effect.\n        scored: true\n\n      - id: 1.2.24\n        text: \"Ensure that the --service-account-key-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--service-account-key-file\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --service-account-key-file parameter\n          to the public key file for service accounts. For example,\n          --service-account-key-file=<filename>\n        scored: true\n\n      - id: 1.2.25\n        text: \"Ensure that the --etcd-certfile and --etcd-keyfile arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--etcd-certfile\"\n            - flag: \"--etcd-keyfile\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection between the apiserver and etcd.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the etcd certificate and key file parameters.\n          --etcd-certfile=<path/to/client-certificate-file>\n          --etcd-keyfile=<path/to/client-key-file>\n        scored: true\n\n      - id: 1.2.26\n        text: \"Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--tls-cert-file\"\n            - flag: \"--tls-private-key-file\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection on the apiserver.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the TLS certificate and private key file parameters.\n          --tls-cert-file=<path/to/tls-certificate-file>\n          --tls-private-key-file=<path/to/tls-key-file>\n        scored: true\n\n      - id: 1.2.27\n        text: \"Ensure that the --client-ca-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--client-ca-file\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection on the apiserver.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the client certificate authority file.\n          --client-ca-file=<path/to/client-ca-file>\n        scored: true\n\n      - id: 1.2.28\n        text: \"Ensure that the --etcd-cafile argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--etcd-cafile\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection between the apiserver and etcd.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the etcd certificate authority file parameter.\n          --etcd-cafile=<path/to/ca-file>\n        scored: true\n\n      - id: 1.2.29\n        text: \"Ensure that the --encryption-provider-config argument is set as appropriate (Manual)\"\n        type: \"skip\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--encryption-provider-config\"\n        remediation: |\n          Follow the Kubernetes documentation and configure a EncryptionConfig file.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --encryption-provider-config parameter to the path of that file.\n          For example, --encryption-provider-config=</path/to/EncryptionConfig/File>\n          Permissive - Enabling encryption changes how data can be recovered as data is encrypted.\n        scored: false\n\n      - id: 1.2.30\n        text: \"Ensure that encryption providers are appropriately configured (Manual)\"\n        type: \"skip\"\n        audit: |\n          ENCRYPTION_PROVIDER_CONFIG=$(ps -ef | grep $apiserverbin | grep -- --encryption-provider-config | sed 's%.*encryption-provider-config[= ]\\([^ ]*\\).*%\\1%')\n          if test -e $ENCRYPTION_PROVIDER_CONFIG; then grep -A1 'providers:' $ENCRYPTION_PROVIDER_CONFIG | tail -n1 | grep -o \"[A-Za-z]*\" | sed 's/^/provider=/'; fi\n        tests:\n          test_items:\n            - flag: \"provider\"\n              compare:\n                op: valid_elements\n                value: \"aescbc,kms,secretbox\"\n        remediation: |\n          Follow the Kubernetes documentation and configure a EncryptionConfig file.\n          In this file, choose aescbc, kms or secretbox as the encryption provider.\n          Permissive - Enabling encryption changes how data can be recovered as data is encrypted.\n        scored: false\n\n      - id: 1.2.31\n        text: \"Ensure that the API Server only makes use of Strong Cryptographic Ciphers (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--tls-cipher-suites\"\n              compare:\n                op: valid_elements\n                value: \"TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,TLS_CHACHA20_POLY1305_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,TLS_RSA_WITH_3DES_EDE_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_256_GCM_SHA384\"\n        remediation: |\n          Edit the API server pod specification file /etc/kubernetes/manifests/kube-apiserver.yaml\n          on the control plane node and set the below parameter.\n          --tls-cipher-suites=TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,TLS_CHACHA20_POLY1305_SHA256,\n          TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,\n          TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,\n          TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,\n          TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,\n          TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,\n          TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,TLS_RSA_WITH_3DES_EDE_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA,\n          TLS_RSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_256_GCM_SHA384\n        scored: false\n\n  - id: 1.3\n    text: \"Controller Manager\"\n    checks:\n      - id: 1.3.1\n        text: \"Ensure that the --terminated-pod-gc-threshold argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--terminated-pod-gc-threshold\"\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the --terminated-pod-gc-threshold to an appropriate threshold,\n          for example, --terminated-pod-gc-threshold=10\n        scored: true\n\n      - id: 1.3.2\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the below parameter.\n          --profiling=false\n        scored: true\n\n      - id: 1.3.3\n        text: \"Ensure that the --use-service-account-credentials argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--use-service-account-credentials\"\n              compare:\n                op: noteq\n                value: false\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node to set the below parameter.\n          --use-service-account-credentials=true\n        scored: true\n\n      - id: 1.3.4\n        text: \"Ensure that the --service-account-private-key-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--service-account-private-key-file\"\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the --service-account-private-key-file parameter\n          to the private key file for service accounts.\n          --service-account-private-key-file=<filename>\n        scored: true\n\n      - id: 1.3.5\n        text: \"Ensure that the --root-ca-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--root-ca-file\"\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the --root-ca-file parameter to the certificate bundle file`.\n          --root-ca-file=<path/to/file>\n        scored: true\n\n      - id: 1.3.6\n        text: \"Ensure that the RotateKubeletServerCertificate argument is set to true (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--feature-gates\"\n              compare:\n                op: nothave\n                value: \"RotateKubeletServerCertificate=false\"\n              set: true\n            - flag: \"--feature-gates\"\n              set: false\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the --feature-gates parameter to include RotateKubeletServerCertificate=true.\n          --feature-gates=RotateKubeletServerCertificate=true\n          Cluster provisioned by RKE handles certificate rotation directly through RKE.\n        scored: true\n\n      - id: 1.3.7\n        text: \"Ensure that the --bind-address argument is set to 127.0.0.1 (Automated)\"\n        audit: '/bin/sh -c \"if test -e $controllermanagerbin; then /bin/ps -ef | grep $controllermanagerbin | grep -v grep; else echo \\\"Controller manager binary not found\\\"; fi\"'\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--bind-address\"\n              compare:\n                op: eq\n                value: \"127.0.0.1\"\n              set: true\n            - flag: \"Controller manager binary not found\"\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and ensure the correct value for the --bind-address parameter\n        scored: true\n\n  - id: 1.4\n    text: \"Scheduler\"\n    checks:\n      - id: 1.4.1\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: \"/bin/ps -ef | grep $schedulerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the Scheduler pod specification file $schedulerconf file\n          on the control plane node and set the below parameter.\n          --profiling=false\n        scored: true\n\n      - id: 1.4.2\n        text: \"Ensure that the --bind-address argument is set to 127.0.0.1 (Automated)\"\n        audit: '/bin/sh -c \"if test -e $schedulerbin; then /bin/ps -ef | grep $schedulerbin | grep -v grep; else echo \\\"Scheduler binary not found\\\"; fi\"'\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--bind-address\"\n              compare:\n                op: eq\n                value: \"127.0.0.1\"\n              set: true\n            - flag: \"Scheduler binary not found\"\n        remediation: |\n          Edit the Scheduler pod specification file $schedulerconf\n          on the control plane node and ensure the correct value for the --bind-address parameter\n        scored: true\n"
  },
  {
    "path": "cfg/rke-cis-1.7/node.yaml",
    "content": "---\ncontrols:\nversion: \"rke-cis-1.7\"\nid: 4\ntext: \"Worker Node Security Configuration\"\ntype: \"node\"\ngroups:\n  - id: 4.1\n    text: \"Worker Node Configuration Files\"\n    checks:\n      - id: 4.1.1\n        text: \"Ensure that the kubelet service file permissions are set to 600 or more restrictive (Automated)\"\n        type: \"skip\"\n        audit: '/bin/sh -c ''if test -e $kubeletsvc; then stat -c permissions=%a $kubeletsvc; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example, chmod 600 $kubeletsvc\n          Not Applicable - Clusters provisioned by RKE doesn’t require or maintain a configuration file for the kubelet service.\n          All configuration is passed in as arguments at container run time.\n        scored: true\n\n      - id: 4.1.2\n        text: \"Ensure that the kubelet service file ownership is set to root:root (Automated)\"\n        type: \"skip\"\n        audit: '/bin/sh -c ''if test -e $kubeletsvc; then stat -c %U:%G $kubeletsvc; fi'' '\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chown root:root $kubeletsvc\n          Not Applicable - Clusters provisioned by RKE doesn’t require or maintain a configuration file for the kubelet service.\n           All configuration is passed in as arguments at container run time.\n        scored: true\n\n      - id: 4.1.3\n        text: \"If proxy kubeconfig file exists ensure permissions are set to 600 or more restrictive (Automated)\"\n        audit: '/bin/sh -c ''if test -e $proxykubeconfig; then stat -c permissions=%a $proxykubeconfig; fi'' '\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"permissions\"\n              set: true\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chmod 600 $proxykubeconfig\n        scored: true\n\n      - id: 4.1.4\n        text: \"If proxy kubeconfig file exists ensure ownership is set to root:root (Automated)\"\n        audit: '/bin/sh -c ''if test -e $proxykubeconfig; then stat -c %U:%G $proxykubeconfig; fi'' '\n        tests:\n          bin_op: or\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example, chown root:root $proxykubeconfig\n        scored: true\n\n      - id: 4.1.5\n        text: \"Ensure that the --kubeconfig kubelet.conf file permissions are set to 600 or more restrictive (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletkubeconfig; then stat -c permissions=%a $kubeletkubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chmod 600 $kubeletkubeconfig\n        scored: true\n\n      - id: 4.1.6\n        text: \"Ensure that the --kubeconfig kubelet.conf file ownership is set to root:root (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletkubeconfig; then stat -c %U:%G $kubeletkubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chown root:root $kubeletkubeconfig\n        scored: true\n\n      - id: 4.1.7\n        text: \"Ensure that the certificate authorities file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"stat -c permissions=%a /etc/kubernetes/ssl/kube-ca.pem\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the following command to modify the file permissions of the\n          --client-ca-file chmod 600 <filename>\n        scored: true\n\n      - id: 4.1.8\n        text: \"Ensure that the client certificate authorities file ownership is set to root:root (Automated)\"\n        audit: \"stat -c %U:%G /etc/kubernetes/ssl/kube-ca.pem\"\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the following command to modify the ownership of the --client-ca-file.\n          chown root:root <filename>\n        scored: true\n\n      - id: 4.1.9\n        text: \"If the kubelet config.yaml configuration file is being used validate permissions set to 600 or more restrictive (Automated)\"\n        type: \"skip\"\n        audit: '/bin/sh -c ''if test -e $kubeletconf; then stat -c permissions=%a $kubeletconf; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the following command (using the config file location identified in the Audit step)\n          chmod 600 $kubeletconf\n          Not Applicable - Clusters provisioned by RKE do not require or maintain a configuration file for the kubelet.\n          All configuration is passed in as arguments at container run time.\n        scored: true\n\n      - id: 4.1.10\n        text: \"If the kubelet config.yaml configuration file is being used validate file ownership is set to root:root (Manual)\"\n        type: \"skip\"\n        audit: '/bin/sh -c ''if test -e $kubeletconf; then stat -c %U:%G $kubeletconf; fi'' '\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the following command (using the config file location identified in the Audit step)\n          chown root:root $kubeletconf\n          Not Applicable - Clusters provisioned by RKE doesn’t require or maintain a configuration file for the kubelet.\n          All configuration is passed in as arguments at container run time.\n        scored: false\n\n  - id: 4.2\n    text: \"Kubelet\"\n    checks:\n      - id: 4.2.1\n        text: \"Ensure that the --anonymous-auth argument is set to false (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/sh -c 'if test -e $kubeletconf; then /bin/cat $kubeletconf; fi' \"\n        tests:\n          test_items:\n            - flag: \"--anonymous-auth\"\n              path: '{.authentication.anonymous.enabled}'\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          If using a Kubelet config file, edit the file to set `authentication: anonymous: enabled` to\n          `false`.\n          If using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          `--anonymous-auth=false`\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.2\n        text: \"Ensure that the --authorization-mode argument is not set to AlwaysAllow (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/sh -c 'if test -e $kubeletconf; then /bin/cat $kubeletconf; fi' \"\n        tests:\n          test_items:\n            - flag: --authorization-mode\n              path: '{.authorization.mode}'\n              compare:\n                op: nothave\n                value: AlwaysAllow\n        remediation: |\n          If using a Kubelet config file, edit the file to set `authorization.mode` to Webhook. If\n          using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_AUTHZ_ARGS variable.\n          --authorization-mode=Webhook\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.3\n        text: \"Ensure that the --client-ca-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/sh -c 'if test -e $kubeletconf; then /bin/cat $kubeletconf; fi' \"\n        tests:\n          test_items:\n            - flag: --client-ca-file\n              path: '{.authentication.x509.clientCAFile}'\n        remediation: |\n          If using a Kubelet config file, edit the file to set `authentication.x509.clientCAFile` to\n          the location of the client CA file.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_AUTHZ_ARGS variable.\n          --client-ca-file=<path/to/client-ca-file>\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.4\n        text: \"Verify that the --read-only-port argument is set to 0 (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/sh -c 'if test -e $kubeletconf; then /bin/cat $kubeletconf; fi' \"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--read-only-port\"\n              path: '{.readOnlyPort}'\n              compare:\n                op: eq\n                value: 0\n            - flag: \"--read-only-port\"\n              path: '{.readOnlyPort}'\n              set: false\n        remediation: |\n          If using a Kubelet config file, edit the file to set `readOnlyPort` to 0.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --read-only-port=0\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.5\n        text: \"Ensure that the --streaming-connection-idle-timeout argument is not set to 0 (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/sh -c 'if test -e $kubeletconf; then /bin/cat $kubeletconf; fi' \"\n        tests:\n          test_items:\n            - flag: --streaming-connection-idle-timeout\n              path: '{.streamingConnectionIdleTimeout}'\n              compare:\n                op: noteq\n                value: 0\n            - flag: --streaming-connection-idle-timeout\n              path: '{.streamingConnectionIdleTimeout}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to set `streamingConnectionIdleTimeout` to a\n          value other than 0.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --streaming-connection-idle-timeout=5m\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.6\n        text: \"Ensure that the --make-iptables-util-chains argument is set to true (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/sh -c 'if test -e $kubeletconf; then /bin/cat $kubeletconf; fi' \"\n        tests:\n          test_items:\n            - flag: --make-iptables-util-chains\n              path: '{.makeIPTablesUtilChains}'\n              compare:\n                op: eq\n                value: true\n            - flag: --make-iptables-util-chains\n              path: '{.makeIPTablesUtilChains}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to set `makeIPTablesUtilChains` to `true`.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          remove the --make-iptables-util-chains argument from the\n          KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.7\n        text: \"Ensure that the --hostname-override argument is not set (Manual)\"\n        # This is one of those properties that can only be set as a command line argument.\n        # To check if the property is set as expected, we need to parse the kubelet command\n        # instead reading the Kubelet Configuration file.\n        type: \"skip\"\n        audit: \"/bin/ps -fC $kubeletbin \"\n        tests:\n          test_items:\n            - flag: --hostname-override\n              set: false\n        remediation: |\n          Edit the kubelet service file $kubeletsvc\n          on each worker node and remove the --hostname-override argument from the\n          KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n          Not Applicable - Clusters provisioned by RKE set the --hostname-override to avoid any hostname configuration errors\n        scored: false\n\n      - id: 4.2.8\n        text: \"Ensure that the eventRecordQPS argument is set to a level which ensures appropriate event capture (Manual)\"\n        type: \"skip\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/sh -c 'if test -e $kubeletconf; then /bin/cat $kubeletconf; fi' \"\n        tests:\n          test_items:\n            - flag: --event-qps\n              path: '{.eventRecordQPS}'\n              compare:\n                op: gte\n                value: 0\n            - flag: --event-qps\n              path: '{.eventRecordQPS}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to set `eventRecordQPS` to an appropriate level.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.9\n        text: \"Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Manual)\"\n        type: \"skip\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/sh -c 'if test -e $kubeletconf; then /bin/cat $kubeletconf; fi' \"\n        tests:\n          test_items:\n            - flag: --tls-cert-file\n              path: '{.tlsCertFile}'\n            - flag: --tls-private-key-file\n              path: '{.tlsPrivateKeyFile}'\n        remediation: |\n          If using a Kubelet config file, edit the file to set `tlsCertFile` to the location\n          of the certificate file to use to identify this Kubelet, and `tlsPrivateKeyFile`\n          to the location of the corresponding private key file.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameters in KUBELET_CERTIFICATE_ARGS variable.\n          --tls-cert-file=<path/to/tls-certificate-file>\n          --tls-private-key-file=<path/to/tls-key-file>\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n          Permissive - When generating serving certificates, functionality could break in conjunction with hostname overrides which are required for certain cloud providers.\n        scored: false\n\n      - id: 4.2.10\n        text: \"Ensure that the --rotate-certificates argument is not set to false (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/sh -c 'if test -e $kubeletconf; then /bin/cat $kubeletconf; fi' \"\n        tests:\n          test_items:\n            - flag: --rotate-certificates\n              path: '{.rotateCertificates}'\n              compare:\n                op: eq\n                value: true\n            - flag: --rotate-certificates\n              path: '{.rotateCertificates}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to add the line `rotateCertificates` to `true` or\n          remove it altogether to use the default value.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          remove --rotate-certificates=false argument from the KUBELET_CERTIFICATE_ARGS\n          variable.\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.11\n        text: \"Verify that the RotateKubeletServerCertificate argument is set to true (Manual)\"\n        type: \"skip\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/sh -c 'if test -e $kubeletconf; then /bin/cat $kubeletconf; fi' \"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: RotateKubeletServerCertificate\n              path: '{.featureGates.RotateKubeletServerCertificate}'\n              compare:\n                op: nothave\n                value: false\n            - flag: RotateKubeletServerCertificate\n              path: '{.featureGates.RotateKubeletServerCertificate}'\n              set: false\n        remediation: |\n          Edit the kubelet service file $kubeletsvc\n          on each worker node and set the below parameter in KUBELET_CERTIFICATE_ARGS variable.\n          --feature-gates=RotateKubeletServerCertificate=true\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n          Not Applicable - Clusters provisioned by RKE handles certificate rotation directly through RKE.\n        scored: false\n\n      - id: 4.2.12\n        text: \"Ensure that the Kubelet only makes use of Strong Cryptographic Ciphers (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/sh -c 'if test -e $kubeletconf; then /bin/cat $kubeletconf; fi' \"\n        tests:\n          test_items:\n            - flag: --tls-cipher-suites\n              path: '{range .tlsCipherSuites[:]}{}{'',''}{end}'\n              compare:\n                op: valid_elements\n                value: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\n        remediation: |\n          If using a Kubelet config file, edit the file to set `tlsCipherSuites` to\n          TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\n          or to a subset of these values.\n          If using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the --tls-cipher-suites parameter as follows, or to a subset of these values.\n          --tls-cipher-suites=TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.13\n        text: \"Ensure that a limit is set on pod PIDs (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/sh -c 'if test -e $kubeletconf; then /bin/cat $kubeletconf; fi' \"\n        tests:\n          test_items:\n            - flag: --pod-max-pids\n              path: '{.podPidsLimit}'\n        remediation: |\n          Decide on an appropriate level for this parameter and set it,\n          either via the --pod-max-pids command line parameter or the PodPidsLimit configuration file setting.\n        scored: false\n"
  },
  {
    "path": "cfg/rke-cis-1.7/policies.yaml",
    "content": "---\ncontrols:\nversion: \"rke-cis-1.7\"\nid: 5\ntext: \"Kubernetes Policies\"\ntype: \"policies\"\ngroups:\n  - id: 5.1\n    text: \"RBAC and Service Accounts\"\n    checks:\n      - id: 5.1.1\n        text: \"Ensure that the cluster-admin role is only used where required (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Identify all clusterrolebindings to the cluster-admin role. Check if they are used and\n          if they need this role or if they could use a role with fewer privileges.\n          Where possible, first bind users to a lower privileged role and then remove the\n          clusterrolebinding to the cluster-admin role :\n          kubectl delete clusterrolebinding [name]\n        scored: false\n\n      - id: 5.1.2\n        text: \"Minimize access to secrets (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove get, list and watch access to Secret objects in the cluster.\n        scored: false\n\n      - id: 5.1.3\n        text: \"Minimize wildcard use in Roles and ClusterRoles (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible replace any use of wildcards in clusterroles and roles with specific\n          objects or actions.\n        scored: false\n\n      - id: 5.1.4\n        text: \"Minimize access to create pods (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove create access to pod objects in the cluster.\n        scored: false\n\n      - id: 5.1.5\n        text: \"Ensure that default service accounts are not actively used. (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Create explicit service accounts wherever a Kubernetes workload requires specific access\n          to the Kubernetes API server.\n          Modify the configuration of each default service account to include this value\n          automountServiceAccountToken: false\n        scored: false\n\n      - id: 5.1.6\n        text: \"Ensure that Service Account Tokens are only mounted where necessary (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Modify the definition of pods and service accounts which do not need to mount service\n          account tokens to disable it.\n        scored: false\n\n      - id: 5.1.7\n        text: \"Avoid use of system:masters group (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Remove the system:masters group from all users in the cluster.\n        scored: false\n\n      - id: 5.1.8\n        text: \"Limit use of the Bind, Impersonate and Escalate permissions in the Kubernetes cluster (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove the impersonate, bind and escalate rights from subjects.\n        scored: false\n\n      - id: 5.1.9\n        text: \"Minimize access to create persistent volumes (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove create access to PersistentVolume objects in the cluster.\n        scored: false\n\n      - id: 5.1.10\n        text: \"Minimize access to the proxy sub-resource of nodes (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove access to the proxy sub-resource of node objects.\n        scored: false\n\n      - id: 5.1.11\n        text: \"Minimize access to the approval sub-resource of certificatesigningrequests objects (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove access to the approval sub-resource of certificatesigningrequest objects.\n        scored: false\n\n      - id: 5.1.12\n        text: \"Minimize access to webhook configuration objects (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove access to the validatingwebhookconfigurations or mutatingwebhookconfigurations objects\n        scored: false\n\n      - id: 5.1.13\n        text: \"Minimize access to the service account token creation (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove access to the token sub-resource of serviceaccount objects.\n        scored: false\n\n  - id: 5.2\n    text: \"Pod Security Standards\"\n    checks:\n      - id: 5.2.1\n        text: \"Ensure that the cluster has at least one active policy control mechanism in place (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that either Pod Security Admission or an external policy control system is in place\n          for every namespace which contains user workloads.\n        scored: false\n\n      - id: 5.2.2\n        text: \"Minimize the admission of privileged containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of privileged containers.\n        scored: false\n\n      - id: 5.2.3\n        text: \"Minimize the admission of containers wishing to share the host process ID namespace (Automated)\"\n        type: \"skip\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of `hostPID` containers.\n          Permissive - Enabling Pod Security Policy can cause applications to unexpectedly fail.\n        scored: false\n\n      - id: 5.2.4\n        text: \"Minimize the admission of containers wishing to share the host IPC namespace (Automated)\"\n        type: \"skip\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of `hostIPC` containers.\n          Permissive - Enabling Pod Security Policy can cause applications to unexpectedly fail.\n        scored: false\n\n      - id: 5.2.5\n        text: \"Minimize the admission of containers wishing to share the host network namespace (Automated)\"\n        type: \"skip\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of `hostNetwork` containers.\n          Permissive - Enabling Pod Security Policy can cause applications to unexpectedly fail.\n        scored: false\n\n      - id: 5.2.6\n        text: \"Minimize the admission of containers with allowPrivilegeEscalation (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers with `.spec.allowPrivilegeEscalation` set to `true`.\n        scored: false\n\n      - id: 5.2.7\n        text: \"Minimize the admission of root containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Create a policy for each namespace in the cluster, ensuring that either `MustRunAsNonRoot`\n          or `MustRunAs` with the range of UIDs not including 0, is set.\n        scored: false\n\n      - id: 5.2.8\n        text: \"Minimize the admission of containers with the NET_RAW capability (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers with the `NET_RAW` capability.\n        scored: false\n\n      - id: 5.2.9\n        text: \"Minimize the admission of containers with added capabilities (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that `allowedCapabilities` is not present in policies for the cluster unless\n          it is set to an empty array.\n        scored: false\n\n      - id: 5.2.10\n        text: \"Minimize the admission of containers with capabilities assigned (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Review the use of capabilites in applications running on your cluster. Where a namespace\n          contains applications which do not require any Linux capabities to operate consider adding\n          a PSP which forbids the admission of containers which do not drop all capabilities.\n        scored: false\n\n      - id: 5.2.11\n        text: \"Minimize the admission of Windows HostProcess containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers that have `.securityContext.windowsOptions.hostProcess` set to `true`.\n        scored: false\n\n      - id: 5.2.12\n        text: \"Minimize the admission of HostPath volumes (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers with `hostPath` volumes.\n        scored: false\n\n      - id: 5.2.13\n        text: \"Minimize the admission of containers which use HostPorts (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers which use `hostPort` sections.\n        scored: false\n\n  - id: 5.3\n    text: \"Network Policies and CNI\"\n    checks:\n      - id: 5.3.1\n        text: \"Ensure that the CNI in use supports NetworkPolicies (Manual)\"\n        type: \"manual\"\n        remediation: |\n          If the CNI plugin in use does not support network policies, consideration should be given to\n          making use of a different plugin, or finding an alternate mechanism for restricting traffic\n          in the Kubernetes cluster.\n        scored: false\n\n      - id: 5.3.2\n        text: \"Ensure that all Namespaces have NetworkPolicies defined (Manual)\"\n        type: \"skip\"\n        remediation: |\n          Follow the documentation and create NetworkPolicy objects as you need them.\n          Permissive - Enabling Network Policies can prevent certain applications from communicating with each other.\n        scored: false\n\n  - id: 5.4\n    text: \"Secrets Management\"\n    checks:\n      - id: 5.4.1\n        text: \"Prefer using Secrets as files over Secrets as environment variables (Manual)\"\n        type: \"manual\"\n        remediation: |\n          If possible, rewrite application code to read Secrets from mounted secret files, rather than\n          from environment variables.\n        scored: false\n\n      - id: 5.4.2\n        text: \"Consider external secret storage (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Refer to the Secrets management options offered by your cloud provider or a third-party\n          secrets management solution.\n        scored: false\n\n  - id: 5.5\n    text: \"Extensible Admission Control\"\n    checks:\n      - id: 5.5.1\n        text: \"Configure Image Provenance using ImagePolicyWebhook admission controller (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and setup image provenance.\n        scored: false\n\n  - id: 5.7\n    text: \"General Policies\"\n    checks:\n      - id: 5.7.1\n        text: \"Create administrative boundaries between resources using namespaces (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the documentation and create namespaces for objects in your deployment as you need\n          them.\n        scored: false\n\n      - id: 5.7.2\n        text: \"Ensure that the seccomp profile is set to docker/default in your Pod definitions (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Use `securityContext` to enable the docker/default seccomp profile in your pod definitions.\n          An example is as below:\n            securityContext:\n              seccompProfile:\n                type: RuntimeDefault\n        scored: false\n\n      - id: 5.7.3\n        text: \"Apply SecurityContext to your Pods and Containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and apply SecurityContexts to your Pods. For a\n          suggested list of SecurityContexts, you may refer to the CIS Security Benchmark for Docker\n          Containers.\n        scored: false\n\n      - id: 5.7.4\n        text: \"The default namespace should not be used (Manual)\"\n        type: \"skip\"\n        remediation: |\n          Ensure that namespaces are created to allow for appropriate segregation of Kubernetes\n          resources and that all new resources are created in a specific namespace.\n          Permissive - Kubernetes provides a default namespace.\n        scored: false\n"
  },
  {
    "path": "cfg/rke2-cis-1.23/config.yaml",
    "content": "---\n## Version-specific settings that override the values in cfg/config.yaml\n"
  },
  {
    "path": "cfg/rke2-cis-1.23/controlplane.yaml",
    "content": "---\ncontrols:\nversion: \"rke2-cis-1.23\"\nid: 3\ntext: \"Control Plane Configuration\"\ntype: \"controlplane\"\ngroups:\n  - id: 3.1\n    text: \"Authentication and Authorization\"\n    checks:\n      - id: 3.1.1\n        text: \"Client certificate authentication should not be used for users (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Alternative mechanisms provided by Kubernetes such as the use of OIDC should be\n          implemented in place of client certificates.\n        scored: false\n\n  - id: 3.2\n    text: \"Logging\"\n    checks:\n      - id: 3.2.1\n        text: \"Ensure that a minimal audit policy is created (Automated)\"\n        audit: \"/bin/ps -ef | grep kube-apiserver | grep -v grep | grep -o audit-policy-file\"\n        type: \"skip\"\n        tests:\n          test_items:\n            - flag: \"--audit-policy-file\"\n              compare:\n                op: eq\n                value: \"--audit-policy-file\"\n              set: true\n        remediation: |\n          Create an audit policy file for your cluster.\n        scored: true\n\n      - id: 3.2.2\n        text: \"Ensure that the audit policy covers key security concerns (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Review the audit policy provided for the cluster and ensure that it covers\n          at least the following areas,\n          - Access to Secrets managed by the cluster. Care should be taken to only\n            log Metadata for requests to Secrets, ConfigMaps, and TokenReviews, in\n            order to avoid risk of logging sensitive data.\n          - Modification of Pod and Deployment objects.\n          - Use of `pods/exec`, `pods/portforward`, `pods/proxy` and `services/proxy`.\n          For most requests, minimally logging at the Metadata level is recommended\n          (the most basic level of logging).\n        scored: false\n"
  },
  {
    "path": "cfg/rke2-cis-1.23/etcd.yaml",
    "content": "---\ncontrols:\nversion: \"rke2-cis-1.23\"\nid: 2\ntext: \"Etcd Node Configuration\"\ntype: \"etcd\"\ngroups:\n  - id: 2\n    text: \"Etcd Node Configuration\"\n    checks:\n      - id: 2.1\n        text: \"Ensure that the --cert-file and --key-file arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--cert-file\"\n              env: \"ETCD_CERT_FILE\"\n            - flag: \"--key-file\"\n              env: \"ETCD_KEY_FILE\"\n        remediation: |\n          Follow the etcd service documentation and configure TLS encryption.\n          Then, edit the etcd pod specification file /etc/kubernetes/manifests/etcd.yaml\n          on the master node and set the below parameters.\n          --cert-file=</path/to/ca-file>\n          --key-file=</path/to/key-file>\n        scored: true\n        type: \"skip\"\n\n      - id: 2.2\n        text: \"Ensure that the --client-cert-auth argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--client-cert-auth\"\n              env: \"ETCD_CLIENT_CERT_AUTH\"\n              compare:\n                op: eq\n                value: true\n        type: \"skip\"\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and set the below parameter.\n          --client-cert-auth=\"true\"\n        scored: true\n\n      - id: 2.3\n        text: \"Ensure that the --auto-tls argument is not set to true (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--auto-tls\"\n              env: \"ETCD_AUTO_TLS\"\n              set: false\n            - flag: \"--auto-tls\"\n              env: \"ETCD_AUTO_TLS\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and either remove the --auto-tls parameter or set it to false.\n            --auto-tls=false\n        scored: true\n\n      - id: 2.4\n        text: \"Ensure that the --peer-cert-file and --peer-key-file arguments are\n        set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--peer-cert-file\"\n              env: \"ETCD_PEER_CERT_FILE\"\n              set: true\n            - flag: \"--peer-key-file\"\n              env: \"ETCD_PEER_KEY_FILE\"\n              set: true\n        remediation: |\n          Follow the etcd service documentation and configure peer TLS encryption as appropriate\n          for your etcd cluster.\n          Then, edit the etcd pod specification file $etcdconf on the\n          master node and set the below parameters.\n          --peer-client-file=</path/to/peer-cert-file>\n          --peer-key-file=</path/to/peer-key-file>\n        scored: true\n        type: \"skip\"\n\n      - id: 2.5\n        text: \"Ensure that the --peer-client-cert-auth argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--peer-client-cert-auth\"\n              env: \"ETCD_PEER_CLIENT_CERT_AUTH\"\n              compare:\n                op: eq\n                value: true\n              set: true\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and set the below parameter.\n          --peer-client-cert-auth=true\n        scored: true\n        type: \"skip\"\n\n      - id: 2.6\n        text: \"Ensure that the --peer-auto-tls argument is not set to true (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--peer-auto-tls\"\n              env: \"ETCD_PEER_AUTO_TLS\"\n              set: false\n            - flag: \"--peer-auto-tls\"\n              env: \"ETCD_PEER_AUTO_TLS\"\n              compare:\n                op: eq\n                value: false\n              set: true\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and either remove the --peer-auto-tls parameter or set it to false.\n          --peer-auto-tls=false\n        scored: true\n\n      - id: 2.7\n        text: \"Ensure that a unique Certificate Authority is used for etcd (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        audit_config: \"cat /var/lib/rancher/rke2/server/db/etcd/config\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--trusted-ca-file\"\n              env: \"ETCD_TRUSTED_CA_FILE\"\n            - path: \"{.peer-transport-security.trusted-ca-file}\"\n              compare:\n                op: eq\n                value: \"/var/lib/rancher/rke2/server/tls/etcd/peer-ca.crt\"\n              set: true\n        remediation: |\n          [Manual test]\n          Follow the etcd documentation and create a dedicated certificate authority setup for the\n          etcd service.\n          Then, edit the etcd pod specification file $etcdconf on the\n          master node and set the below parameter.\n          --trusted-ca-file=</path/to/ca-file>\n        scored: false\n"
  },
  {
    "path": "cfg/rke2-cis-1.23/master.yaml",
    "content": "---\ncontrols:\nversion: \"rke2-cis-1.23\"\nid: 1\ntext: \"Control Plane Security Configuration\"\ntype: \"master\"\ngroups:\n  - id: 1.1\n    text: \"Control Plane Node Configuration Files\"\n    checks:\n      - id: 1.1.1\n        text: \"Ensure that the API server pod specification file permissions are set to 644 or more restrictive (Automated)\"\n        audit: \"stat -c permissions=%a /var/lib/rancher/rke2/agent/pod-manifests/kube-apiserver.yaml\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: eq\n                value: \"644\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the\n          control plane node.\n          For example, chmod 644 $apiserverconf\n        scored: true\n\n      - id: 1.1.2\n        text: \"Ensure that the API server pod specification file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $apiserverconf; then stat -c %U:%G $apiserverconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n              compare:\n                op: eq\n                value: \"root:root\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chown root:root $apiserverconf\n        scored: true\n\n      - id: 1.1.3\n        text: \"Ensure that the controller manager pod specification file permissions are set to 644 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerconf; then stat -c permissions=%a $controllermanagerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"644\"\n              compare:\n                op: eq\n                value: \"644\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chmod 644 $controllermanagerconf\n        scored: true\n\n      - id: 1.1.4\n        text: \"Ensure that the controller manager pod specification file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerconf; then stat -c %U:%G $controllermanagerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n              compare:\n                op: eq\n                value: \"root:root\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chown root:root $controllermanagerconf\n        scored: true\n\n      - id: 1.1.5\n        text: \"Ensure that the scheduler pod specification file permissions are set to 644 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerconf; then stat -c permissions=%a $schedulerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"644\"\n              compare:\n                op: eq\n                value: \"644\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chmod 644 $schedulerconf\n        scored: true\n\n      - id: 1.1.6\n        text: \"Ensure that the scheduler pod specification file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerconf; then stat -c %U:%G $schedulerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chown root:root $schedulerconf\n        scored: true\n\n      - id: 1.1.7\n        text: \"Ensure that the etcd pod specification file permissions are set to 644 or more restrictive (Automated)\"\n        audit: |\n          /bin/sh -c '\n            if [ -e \"$etcdconf\" ]; then\n              stat -c \"permissions=%a %n\" \"$etcdconf\"\n            else\n              echo \"Directory not found\"\n            fi\n          '\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n            - flag: \"Directory not found\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod 644 $etcdconf\n        scored: true\n\n      - id: 1.1.8\n        text: \"Ensure that the etcd pod specification file ownership is set to root:root (Automated)\"\n        audit: |\n          /bin/sh -c '\n            if [ -e $etcdconf ]; then\n              stat -c \"ownership=%U:%G %n\" $etcdconf\n            else\n              echo \"Directory not found\"\n            fi\n            '\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"ownership\"\n              compare:\n                op: eq\n                value: \"root:root\"\n              set: true\n            - flag: \"Directory not found\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root $etcdconf\n        scored: true\n\n      - id: 1.1.9\n        text: \"Ensure that the Container Network Interface file permissions are set to 644 or more restrictive (Manual)\"\n        audit: |\n          ps -fC ${kubeletbin:-kubelet} | grep -- --cni-conf-dir || echo \"/etc/cni/net.d\" | sed 's%.*cni-conf-dir[= ]\\([^ ]*\\).*%\\1%' | xargs -I{} find {} -mindepth 1 | xargs --no-run-if-empty stat -c permissions=%a\n          find /var/lib/cni/networks -type f 2> /dev/null | xargs --no-run-if-empty stat -c permissions=%a\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chmod 644 <path/to/cni/files>\n        scored: false\n\n      - id: 1.1.10\n        text: \"Ensure that the Container Network Interface file ownership is set to root:root (Manual)\"\n        audit: |\n          ps -fC ${kubeletbin:-kubelet} | grep -- --cni-conf-dir || echo \"/etc/cni/net.d\" | sed 's%.*cni-conf-dir[= ]\\([^ ]*\\).*%\\1%' | xargs -I{} find {} -mindepth 1 | xargs --no-run-if-empty stat -c %U:%G\n          find /var/lib/cni/networks -type f 2> /dev/null | xargs --no-run-if-empty stat -c %U:%G\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root <path/to/cni/files>\n        scored: false\n\n      - id: 1.1.11\n        text: \"Ensure that the etcd data directory permissions are set to 700 or more restrictive (Automated)\"\n        audit: |\n           /bin/sh -c 'if [ -d \"/var/lib/rancher/rke2/server/db/etcd\" ]; then\n            stat -c \"permissions=%a\" \"/var/lib/rancher/rke2/server/db/etcd\"\n           else\n            echo \"Directory not found\"\n           fi'\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"700\"\n              set: true\n            - flag: \"Directory not found\"\n        remediation: |\n          On the etcd server node, get the etcd data directory, passed as an argument --data-dir,\n          from the command 'ps -ef | grep etcd'.\n          Run the below command (based on the etcd data directory found above). For example,\n          chmod 700 /var/lib/etcd\n        scored: true\n\n      - id: 1.1.12\n        text: \"Ensure that the etcd data directory ownership is set to etcd:etcd (Automated)\"\n        type: \"skip\"\n        audit: \"stat -c %U:%G /var/lib/rancher/rke2/server/db/etcd\"\n        tests:\n          test_items:\n            - flag: \"etcd:etcd\"\n        remediation: |\n          On the etcd server node, get the etcd data directory, passed as an argument --data-dir,\n          from the command 'ps -ef | grep etcd'.\n          Run the below command (based on the etcd data directory found above).\n          For example, chown etcd:etcd /var/lib/etcd\n        scored: true\n\n      - id: 1.1.13\n        text: \"Ensure that the admin.conf file permissions are set to 644 or more restrictive (Automated)\"\n        audit: \"stat -c permissions=%a /var/lib/rancher/rke2/server/cred/admin.kubeconfig\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chmod 600 /etc/kubernetes/admin.conf\n        scored: true\n\n      - id: 1.1.14\n        text: \"Ensure that the admin.conf file ownership is set to root:root (Automated)\"\n        audit: \"stat -c %U:%G /var/lib/rancher/rke2/server/cred/admin.kubeconfig\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n              compare:\n                op: eq\n                value: \"root:root\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chown root:root /etc/kubernetes/admin.conf\n        scored: true\n\n      - id: 1.1.15\n        text: \"Ensure that the scheduler.conf file permissions are set to 644 or more restrictive (Automated)\"\n        audit: \"stat -c %a $schedulerkubeconfig\"\n        tests:\n          test_items:\n            - flag: \"644\"\n              compare:\n                op: eq\n                value: \"644\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod 644 $schedulerkubeconfig\n        scored: true\n\n      - id: 1.1.16\n        text: \"Ensure that the scheduler.conf file ownership is set to root:root (Automated)\"\n        audit: \"stat -c %U:%G $schedulerkubeconfig\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n              compare:\n                op: eq\n                value: \"root:root\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root $schedulerkubeconfig\n        scored: true\n\n      - id: 1.1.17\n        text: \"Ensure that the controller-manager.conf file permissions are set to 644 or more restrictive (Automated)\"\n        audit: \"stat -c %a $controllermanagerkubeconfig\"\n        tests:\n          test_items:\n            - flag: \"644\"\n              compare:\n                op: eq\n                value: \"644\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod 644 $controllermanagerkubeconfig\n        scored: true\n\n      - id: 1.1.18\n        text: \"Ensure that the controller-manager.conf file ownership is set to root:root (Automated)\"\n        audit: \"stat -c %U:%G $controllermanagerkubeconfig\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n              compare:\n                op: eq\n                value: \"root:root\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root $controllermanagerkubeconfig\n        scored: true\n\n      - id: 1.1.19\n        text: \"Ensure that the Kubernetes PKI directory and file ownership is set to root:root (Automated)\"\n        audit: \"stat -c %U:%G /var/lib/rancher/rke2/server/tls\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n              compare:\n                op: eq\n                value: \"root:root\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown -R root:root /etc/kubernetes/pki/\n        scored: true\n\n      - id: 1.1.20\n        text: \"Ensure that the Kubernetes PKI certificate file permissions are set to 644 or more restrictive (Manual)\"\n        audit: \"stat -c permissions=%a /var/lib/rancher/rke2/server/tls/*.crt\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod -R 644 /var/lib/rancher/rke2/server/tls/*.crt\n        scored: false\n\n      - id: 1.1.21\n        text: \"Ensure that the Kubernetes PKI key file permissions are set to 600 (Manual)\"\n        audit: \"stat -c permissions=%a /var/lib/rancher/rke2/server/tls/*.key\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: eq\n                value: \"600\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod -R 600 /var/lib/rancher/rke2/server/tls/*.key\n        scored: false\n\n  - id: 1.2\n    text: \"API Server\"\n    checks:\n      - id: 1.2.1\n        text: \"Ensure that the --anonymous-auth argument is set to false (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        type: manual\n        tests:\n          test_items:\n            - flag: \"--anonymous-auth\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the below parameter.\n          --anonymous-auth=false\n        scored: false\n\n      - id: 1.2.2\n        text: \"Ensure that the --token-auth-file parameter is not set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--token-auth-file\"\n              set: false\n        remediation: |\n          Follow the documentation and configure alternate mechanisms for authentication. Then,\n          edit the API server pod specification file $apiserverconf\n          on the control plane node and remove the --token-auth-file=<filename> parameter.\n        scored: true\n\n      - id: 1.2.3\n        text: \"Ensure that the --DenyServiceExternalIPs is not set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: nothave\n                value: \"DenyServiceExternalIPs\"\n              set: true\n            - flag: \"--enable-admission-plugins\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and remove the `DenyServiceExternalIPs`\n          from enabled admission plugins.\n        scored: true\n\n      - id: 1.2.4\n        text: \"Ensure that the --kubelet-https argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--kubelet-https\"\n              compare:\n                op: eq\n                value: true\n            - flag: \"--kubelet-https\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and remove the --kubelet-https parameter.\n        scored: true\n\n      - id: 1.2.5\n        text: \"Ensure that the --kubelet-client-certificate and --kubelet-client-key arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--kubelet-client-certificate\"\n              set: true\n            - flag: \"--kubelet-client-key\"\n              set: true\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection between the\n          apiserver and kubelets. Then, edit API server pod specification file\n          $apiserverconf on the control plane node and set the\n          kubelet client certificate and key parameters as below.\n          --kubelet-client-certificate=<path/to/client-certificate-file>\n          --kubelet-client-key=<path/to/client-key-file>\n        scored: true\n\n      - id: 1.2.6\n        text: \"Ensure that the --kubelet-certificate-authority argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--kubelet-certificate-authority\"\n              set: true\n        remediation: |\n          Follow the Kubernetes documentation and setup the TLS connection between\n          the apiserver and kubelets. Then, edit the API server pod specification file\n          $apiserverconf on the control plane node and set the\n          --kubelet-certificate-authority parameter to the path to the cert file for the certificate authority.\n          --kubelet-certificate-authority=<ca-string>\n        scored: true\n\n      - id: 1.2.7\n        text: \"Ensure that the --authorization-mode argument is not set to AlwaysAllow (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: nothave\n                value: \"AlwaysAllow\"\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --authorization-mode parameter to values other than AlwaysAllow.\n          One such example could be as below.\n          --authorization-mode=RBAC\n        scored: true\n\n      - id: 1.2.8\n        text: \"Ensure that the --authorization-mode argument includes Node (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: has\n                value: \"Node\"\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --authorization-mode parameter to a value that includes Node.\n          --authorization-mode=Node,RBAC\n        scored: true\n\n      - id: 1.2.9\n        text: \"Ensure that the --authorization-mode argument includes RBAC (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: has\n                value: \"RBAC\"\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --authorization-mode parameter to a value that includes RBAC,\n          for example `--authorization-mode=Node,RBAC`.\n        scored: true\n\n      - id: 1.2.10\n        text: \"Ensure that the admission control plugin EventRateLimit is set (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"EventRateLimit\"\n              set: true\n        remediation: |\n          Follow the Kubernetes documentation and set the desired limits in a configuration file.\n          Then, edit the API server pod specification file $apiserverconf\n          and set the below parameters.\n          --enable-admission-plugins=...,EventRateLimit,...\n          --admission-control-config-file=<path/to/configuration/file>\n        scored: false\n\n      - id: 1.2.11\n        text: \"Ensure that the admission control plugin AlwaysAdmit is not set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: nothave\n                value: AlwaysAdmit\n              set: true\n            - flag: \"--enable-admission-plugins\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and either remove the --enable-admission-plugins parameter, or set it to a\n          value that does not include AlwaysAdmit.\n        scored: true\n\n      - id: 1.2.12\n        text: \"Ensure that the admission control plugin AlwaysPullImages is set (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"AlwaysPullImages\"\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --enable-admission-plugins parameter to include\n          AlwaysPullImages.\n          --enable-admission-plugins=...,AlwaysPullImages,...\n        scored: false\n\n      - id: 1.2.13\n        text: \"Ensure that the admission control plugin SecurityContextDeny is set if PodSecurityPolicy is not used (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"SecurityContextDeny\"\n              set: true\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"PodSecurityPolicy\"\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --enable-admission-plugins parameter to include\n          SecurityContextDeny, unless PodSecurityPolicy is already in place.\n          --enable-admission-plugins=...,SecurityContextDeny,...\n        scored: false\n\n      - id: 1.2.14\n        text: \"Ensure that the admission control plugin ServiceAccount is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--disable-admission-plugins\"\n              compare:\n                op: nothave\n                value: \"ServiceAccount\"\n            - flag: \"--disable-admission-plugins\"\n              set: false\n        remediation: |\n          Follow the documentation and create ServiceAccount objects as per your environment.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and ensure that the --disable-admission-plugins parameter is set to a\n          value that does not include ServiceAccount.\n        scored: true\n\n      - id: 1.2.15\n        text: \"Ensure that the admission control plugin NamespaceLifecycle is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--disable-admission-plugins\"\n              compare:\n                op: nothave\n                value: \"NamespaceLifecycle\"\n            - flag: \"--disable-admission-plugins\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --disable-admission-plugins parameter to\n          ensure it does not include NamespaceLifecycle.\n        scored: true\n\n      - id: 1.2.16\n        text: \"Ensure that the admission control plugin NodeRestriction is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"NodeRestriction\"\n              set: true\n        remediation: |\n          Follow the Kubernetes documentation and configure NodeRestriction plug-in on kubelets.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --enable-admission-plugins parameter to a\n          value that includes NodeRestriction.\n          --enable-admission-plugins=...,NodeRestriction,...\n        scored: true\n\n      - id: 1.2.17\n        text: \"Ensure that the --secure-port argument is not set to 0 (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--secure-port\"\n              compare:\n                op: gt\n                value: 0\n              set: true\n            - flag: \"--secure-port\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and either remove the --secure-port parameter or\n          set it to a different (non-zero) desired port.\n        scored: true\n\n      - id: 1.2.18\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the below parameter.\n          --profiling=false\n        scored: true\n\n      - id: 1.2.19\n        text: \"Ensure that the --audit-log-path argument is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        type: \"skip\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-path\"\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --audit-log-path parameter to a suitable path and\n          file where you would like audit logs to be written, for example,\n          --audit-log-path=/var/log/apiserver/audit.log\n        scored: true\n\n      - id: 1.2.20\n        text: \"Ensure that the --audit-log-maxage argument is set to 30 or as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        type: \"skip\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxage\"\n              compare:\n                op: gte\n                value: 30\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --audit-log-maxage parameter to 30\n          or as an appropriate number of days, for example,\n          --audit-log-maxage=30\n        scored: true\n\n      - id: 1.2.21\n        text: \"Ensure that the --audit-log-maxbackup argument is set to 10 or as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        type: \"skip\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxbackup\"\n              compare:\n                op: gte\n                value: 10\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --audit-log-maxbackup parameter to 10 or to an appropriate\n          value. For example,\n          --audit-log-maxbackup=10\n        scored: true\n\n      - id: 1.2.22\n        text: \"Ensure that the --audit-log-maxsize argument is set to 100 or as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        type: \"skip\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxsize\"\n              compare:\n                op: gte\n                value: 100\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --audit-log-maxsize parameter to an appropriate size in MB.\n          For example, to set it as 100 MB, --audit-log-maxsize=100\n        scored: true\n\n      - id: 1.2.23\n        text: \"Ensure that the --request-timeout argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--request-timeout\"\n              set: false\n            - flag: \"--request-timeout\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          and set the below parameter as appropriate and if needed.\n          For example, --request-timeout=300s\n        scored: true\n\n      - id: 1.2.24\n        text: \"Ensure that the --service-account-lookup argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--service-account-lookup\"\n              set: false\n            - flag: \"--service-account-lookup\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the below parameter.\n          --service-account-lookup=true\n          Alternatively, you can delete the --service-account-lookup parameter from this file so\n          that the default takes effect.\n        scored: true\n\n      - id: 1.2.25\n        text: \"Ensure that the --service-account-key-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--service-account-key-file\"\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --service-account-key-file parameter\n          to the public key file for service accounts. For example,\n          --service-account-key-file=<filename>\n        scored: true\n\n      - id: 1.2.26\n        text: \"Ensure that the --etcd-certfile and --etcd-keyfile arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--etcd-certfile\"\n              set: true\n            - flag: \"--etcd-keyfile\"\n              set: true\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection between the apiserver and etcd.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the etcd certificate and key file parameters.\n          --etcd-certfile=<path/to/client-certificate-file>\n          --etcd-keyfile=<path/to/client-key-file>\n        scored: true\n\n      - id: 1.2.27\n        text: \"Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--tls-cert-file\"\n              set: true\n            - flag: \"--tls-private-key-file\"\n              set: true\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection on the apiserver.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the TLS certificate and private key file parameters.\n          --tls-cert-file=<path/to/tls-certificate-file>\n          --tls-private-key-file=<path/to/tls-key-file>\n        scored: true\n\n      - id: 1.2.28\n        text: \"Ensure that the --client-ca-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--client-ca-file\"\n              set: true\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection on the apiserver.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the client certificate authority file.\n          --client-ca-file=<path/to/client-ca-file>\n        scored: true\n\n      - id: 1.2.29\n        text: \"Ensure that the --etcd-cafile argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--etcd-cafile\"\n              set: true\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection between the apiserver and etcd.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the etcd certificate authority file parameter.\n          --etcd-cafile=<path/to/ca-file>\n        scored: true\n\n      - id: 1.2.30\n        text: \"Ensure that the --encryption-provider-config argument is set as appropriate (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--encryption-provider-config\"\n        remediation: |\n          Follow the Kubernetes documentation and configure a EncryptionConfig file.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --encryption-provider-config parameter to the path of that file.\n          For example, --encryption-provider-config=</path/to/EncryptionConfig/File>\n        scored: false\n\n      - id: 1.2.31\n        text: \"Ensure that encryption providers are appropriately configured (Manual)\"\n        type: \"skip\"\n        audit: |\n          ENCRYPTION_PROVIDER_CONFIG=$(ps -ef | grep $apiserverbin | grep -- --encryption-provider-config | sed 's%.*encryption-provider-config[= ]\\([^ ]*\\).*%\\1%')\n          if test -e $ENCRYPTION_PROVIDER_CONFIG; then grep -A1 'providers:' $ENCRYPTION_PROVIDER_CONFIG | tail -n1 | grep -o \"[A-Za-z]*\" | sed 's/^/provider=/'; fi\n        tests:\n          test_items:\n            - flag: \"provider\"\n              compare:\n                op: valid_elements\n                value: \"aescbc,kms,secretbox\"\n        remediation: |\n          Follow the Kubernetes documentation and configure a EncryptionConfig file.\n          In this file, choose aescbc, kms or secretbox as the encryption provider.\n        scored: false\n\n      - id: 1.2.32\n        text: \"Ensure that the API Server only makes use of Strong Cryptographic Ciphers (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--tls-cipher-suites\"\n              compare:\n                op: valid_elements\n                value: \"TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,TLS_CHACHA20_POLY1305_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,TLS_RSA_WITH_3DES_EDE_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_256_GCM_SHA384\"\n        remediation: |\n          Edit the API server pod specification file /etc/kubernetes/manifests/kube-apiserver.yaml\n          on the control plane node and set the below parameter.\n          --tls-cipher-suites=TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,TLS_CHACHA20_POLY1305_SHA256,\n          TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,\n          TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,\n          TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,\n          TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,\n          TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,\n          TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,TLS_RSA_WITH_3DES_EDE_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA,\n          TLS_RSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_256_GCM_SHA384\n        scored: false\n        type: skip\n\n  - id: 1.3\n    text: \"Controller Manager\"\n    checks:\n      - id: 1.3.1\n        text: \"Ensure that the --terminated-pod-gc-threshold argument is set as appropriate (Manual)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--terminated-pod-gc-threshold\"\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the --terminated-pod-gc-threshold to an appropriate threshold,\n          for example, --terminated-pod-gc-threshold=10\n        scored: false\n\n      - id: 1.3.2\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n              set: true\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the below parameter.\n          --profiling=false\n        scored: true\n\n      - id: 1.3.3\n        text: \"Ensure that the --use-service-account-credentials argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--use-service-account-credentials\"\n              compare:\n                op: noteq\n                value: false\n              set: true\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node to set the below parameter.\n          --use-service-account-credentials=true\n        scored: true\n\n      - id: 1.3.4\n        text: \"Ensure that the --service-account-private-key-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--service-account-private-key-file\"\n              set: true\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the --service-account-private-key-file parameter\n          to the private key file for service accounts.\n          --service-account-private-key-file=<filename>\n        scored: true\n\n      - id: 1.3.5\n        text: \"Ensure that the --root-ca-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--root-ca-file\"\n              set: true\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the --root-ca-file parameter to the certificate bundle file`.\n          --root-ca-file=<path/to/file>\n        scored: true\n\n      - id: 1.3.6\n        text: \"Ensure that the RotateKubeletServerCertificate argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--feature-gates\"\n              compare:\n                op: nothave\n                value: \"RotateKubeletServerCertificate=false\"\n              set: true\n            - flag: \"--feature-gates\"\n              set: false\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the --feature-gates parameter to include RotateKubeletServerCertificate=true.\n          --feature-gates=RotateKubeletServerCertificate=true\n        scored: true\n        type: skip\n\n      - id: 1.3.7\n        text: \"Ensure that the --bind-address argument is set to 127.0.0.1 (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--bind-address\"\n              compare:\n                op: eq\n                value: \"127.0.0.1\"\n              set: true\n            - flag: \"--bind-address\"\n              set: false\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and ensure the correct value for the --bind-address parameter\n        scored: true\n\n  - id: 1.4\n    text: \"Scheduler\"\n    checks:\n      - id: 1.4.1\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: \"/bin/ps -ef | grep $schedulerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n              set: true\n        remediation: |\n          Edit the Scheduler pod specification file $schedulerconf file\n          on the control plane node and set the below parameter.\n          --profiling=false\n        scored: true\n\n      - id: 1.4.2\n        text: \"Ensure that the --bind-address argument is set to 127.0.0.1 (Automated)\"\n        audit: \"/bin/ps -ef | grep $schedulerbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--bind-address\"\n              compare:\n                op: eq\n                value: \"127.0.0.1\"\n              set: true\n            - flag: \"--bind-address\"\n              set: false\n        remediation: |\n          Edit the Scheduler pod specification file $schedulerconf\n          on the control plane node and ensure the correct value for the --bind-address parameter\n        scored: true\n"
  },
  {
    "path": "cfg/rke2-cis-1.23/node.yaml",
    "content": "---\ncontrols:\nversion: \"rke2-cis-1.23\"\nid: 4\ntext: \"Worker Node Security Configuration\"\ntype: \"node\"\ngroups:\n  - id: 4.1\n    text: \"Worker Node Configuration Files\"\n    checks:\n      - id: 4.1.1\n        text: \"Ensure that the kubelet service file permissions are set to 644 or more restrictive (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletsvc; then stat -c permissions=%a $kubeletsvc; fi'' '\n        type: \"skip\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example, chmod 644 $kubeletsvc\n        scored: true\n\n      - id: 4.1.2\n        text: \"Ensure that the kubelet service file ownership is set to root:root (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletsvc; then stat -c %U:%G $kubeletsvc; fi'' '\n        type: \"skip\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chown root:root $kubeletsvc\n        scored: true\n\n      - id: 4.1.3\n        text: \"If proxy kubeconfig file exists ensure permissions are set to 644 or more restrictive (Manual)\"\n        audit: '/bin/sh -c ''if test -e $proxykubeconfig; then stat -c permissions=%a $proxykubeconfig; fi'' '\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"permissions\"\n              set: true\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chmod 644 $proxykubeconfig\n        scored: false\n\n      - id: 4.1.4\n        text: \"If proxy kubeconfig file exists ensure ownership is set to root:root (Manual)\"\n        audit: '/bin/sh -c ''if test -e $proxykubeconfig; then stat -c %U:%G $proxykubeconfig; fi'' '\n        tests:\n          bin_op: or\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example, chown root:root $proxykubeconfig\n        scored: false\n\n      - id: 4.1.5\n        text: \"Ensure that the --kubeconfig kubelet.conf file permissions are set to 644 or more restrictive (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletkubeconfig; then stat -c permissions=%a $kubeletkubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: \"644\"\n              compare:\n                op: eq\n                value: \"644\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chmod 644 $kubeletkubeconfig\n        scored: true\n\n      - id: 4.1.6\n        text: \"Ensure that the --kubeconfig kubelet.conf file ownership is set to root:root (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletkubeconfig; then stat -c %U:%G $kubeletkubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: root:root\n              set: true\n              compare:\n                op: eq\n                value: root:root\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chown root:root $kubeletkubeconfig\n        scored: true\n\n      - id: 4.1.7\n        text: \"Ensure that the certificate authorities file permissions are set to 644 or more restrictive (Manual)\"\n        audit: \"check_cafile_permissions.sh\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n              set: true\n        remediation: |\n          Run the following command to modify the file permissions of the\n          --client-ca-file chmod 644 <filename>\n        scored: false\n\n      - id: 4.1.8\n        text: \"Ensure that the client certificate authorities file ownership is set to root:root (Manual)\"\n        audit: \"check_cafile_ownership.sh\"\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the following command to modify the ownership of the --client-ca-file.\n          chown root:root <filename>\n        scored: false\n\n      - id: 4.1.9\n        text: \"Ensure that the kubelet --config configuration file has permissions set to 644 or more restrictive (Automated)\"\n        audit: |\n          /bin/sh -c 'if test -e \"$kubeletconf\"; then\n             stat -c \"permissions=%a\" \"$kubeletconf\"\n           else\n             echo \"File not found\"\n           fi'\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n              set: true\n            - flag: \"File not found\"\n        remediation: |\n          Run the following command (using the config file location identified in the Audit step)\n          chmod 644 $kubeletconf\n        scored: true\n\n      - id: 4.1.10\n        text: \"Ensure that the kubelet --config configuration file ownership is set to root:root (Automated)\"\n        audit: |\n          /bin/sh -c 'if test -e \"$kubeletconf\"; then\n              stat -c \"%U:%G\" \"$kubeletconf\"\n           else\n              echo \"File not found\"\n           fi'\n        tests:\n          bin_op: or\n          test_items:\n            - flag: root:root\n              set: true\n            - flag: File not found\n        remediation: |\n          Run the following command (using the config file location identified in the Audit step)\n          chown root:root $kubeletconf\n        scored: true\n\n  - id: 4.2\n    text: \"Kubelet\"\n    checks:\n      - id: 4.2.1\n        text: \"Ensure that the --anonymous-auth argument is set to false (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: \"--anonymous-auth\"\n              path: '{.authentication.anonymous.enabled}'\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          If using a Kubelet config file, edit the file to set `authentication: anonymous: enabled` to\n          `false`.\n          If using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          `--anonymous-auth=false`\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.2\n        text: \"Ensure that the --authorization-mode argument is not set to AlwaysAllow (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --authorization-mode\n              path: '{.authorization.mode}'\n              compare:\n                op: nothave\n                value: AlwaysAllow\n        remediation: |\n          If using a Kubelet config file, edit the file to set `authorization.mode` to Webhook. If\n          using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_AUTHZ_ARGS variable.\n          --authorization-mode=Webhook\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.3\n        text: \"Ensure that the --client-ca-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --client-ca-file\n              path: '{.authentication.x509.clientCAFile}'\n        remediation: |\n          If using a Kubelet config file, edit the file to set `authentication.x509.clientCAFile` to\n          the location of the client CA file.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_AUTHZ_ARGS variable.\n          --client-ca-file=<path/to/client-ca-file>\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.4\n        text: \"Ensure that the --read-only-port argument is set to 0 (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--read-only-port\"\n              path: '{.readOnlyPort}'\n              compare:\n                op: eq\n                value: 0\n            - flag: \"--read-only-port\"\n              path: '{.readOnlyPort}'\n              set: false\n        remediation: |\n          If using a Kubelet config file, edit the file to set `readOnlyPort` to 0.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --read-only-port=0\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.5\n        text: \"Ensure that the --streaming-connection-idle-timeout argument is not set to 0 (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --streaming-connection-idle-timeout\n              path: '{.streamingConnectionIdleTimeout}'\n              compare:\n                op: noteq\n                value: 0\n            - flag: --streaming-connection-idle-timeout\n              path: '{.streamingConnectionIdleTimeout}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to set `streamingConnectionIdleTimeout` to a\n          value other than 0.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --streaming-connection-idle-timeout=5m\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.6\n        text: \"Ensure that the --protect-kernel-defaults argument is set to true (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: --protect-kernel-defaults\n              path: '{.protectKernelDefaults}'\n              compare:\n                op: eq\n                value: true\n              set: true\n            - flag: --protect-kernel-defaults\n              path: '{.protectKernelDefaults}'\n              set: false\n        remediation: |\n          If using a Kubelet config file, edit the file to set `protectKernelDefaults` to `true`.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --protect-kernel-defaults=true\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.7\n        text: \"Ensure that the --make-iptables-util-chains argument is set to true (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --make-iptables-util-chains\n              path: '{.makeIPTablesUtilChains}'\n              compare:\n                op: eq\n                value: true\n            - flag: --make-iptables-util-chains\n              path: '{.makeIPTablesUtilChains}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to set `makeIPTablesUtilChains` to `true`.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          remove the --make-iptables-util-chains argument from the\n          KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.8\n        text: \"Ensure that the --hostname-override argument is not set (Manual)\"\n        # This is one of those properties that can only be set as a command line argument.\n        # To check if the property is set as expected, we need to parse the kubelet command\n        # instead reading the Kubelet Configuration file.\n        audit: \"/bin/ps -fC $kubeletbin \"\n        tests:\n          test_items:\n            - flag: --hostname-override\n              set: false\n        remediation: |\n          Edit the kubelet service file $kubeletsvc\n          on each worker node and remove the --hostname-override argument from the\n          KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n        type: skip\n\n      - id: 4.2.9\n        text: \"Ensure that the --event-qps argument is set to 0 or a level which ensures appropriate event capture (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --event-qps\n              path: '{.eventRecordQPS}'\n              compare:\n                op: eq\n                value: 0\n        remediation: |\n          If using a Kubelet config file, edit the file to set `eventRecordQPS` to an appropriate level.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.10\n        text: \"Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --tls-cert-file\n              path: '{.tlsCertFile}'\n            - flag: --tls-private-key-file\n              path: '{.tlsPrivateKeyFile}'\n        remediation: |\n          If using a Kubelet config file, edit the file to set `tlsCertFile` to the location\n          of the certificate file to use to identify this Kubelet, and `tlsPrivateKeyFile`\n          to the location of the corresponding private key file.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameters in KUBELET_CERTIFICATE_ARGS variable.\n          --tls-cert-file=<path/to/tls-certificate-file>\n          --tls-private-key-file=<path/to/tls-key-file>\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.11\n        text: \"Ensure that the --rotate-certificates argument is not set to false (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --rotate-certificates\n              path: '{.rotateCertificates}'\n              compare:\n                op: eq\n                value: true\n            - flag: --rotate-certificates\n              path: '{.rotateCertificates}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to add the line `rotateCertificates` to `true` or\n          remove it altogether to use the default value.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          remove --rotate-certificates=false argument from the KUBELET_CERTIFICATE_ARGS\n          variable.\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.12\n        text: \"Verify that the RotateKubeletServerCertificate argument is set to true (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: RotateKubeletServerCertificate\n              path: '{.featureGates.RotateKubeletServerCertificate}'\n              compare:\n                op: nothave\n                value: false\n            - flag: RotateKubeletServerCertificate\n              path: '{.featureGates.RotateKubeletServerCertificate}'\n              set: false\n        remediation: |\n          Edit the kubelet service file $kubeletsvc\n          on each worker node and set the below parameter in KUBELET_CERTIFICATE_ARGS variable.\n          --feature-gates=RotateKubeletServerCertificate=true\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.13\n        text: \"Ensure that the Kubelet only makes use of Strong Cryptographic Ciphers (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --tls-cipher-suites\n              path: '{range .tlsCipherSuites[:]}{}{'',''}{end}'\n              compare:\n                op: valid_elements\n                value: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\n        remediation: |\n          If using a Kubelet config file, edit the file to set `tlsCipherSuites` to\n          TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\n          or to a subset of these values.\n          If using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the --tls-cipher-suites parameter as follows, or to a subset of these values.\n          --tls-cipher-suites=TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n"
  },
  {
    "path": "cfg/rke2-cis-1.23/policies.yaml",
    "content": "---\ncontrols:\nversion: \"rke2-cis-1.23\"\nid: 5\ntext: \"Kubernetes Policies\"\ntype: \"policies\"\ngroups:\n  - id: 5.1\n    text: \"RBAC and Service Accounts\"\n    checks:\n      - id: 5.1.1\n        text: \"Ensure that the cluster-admin role is only used where required (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Identify all clusterrolebindings to the cluster-admin role. Check if they are used and\n          if they need this role or if they could use a role with fewer privileges.\n          Where possible, first bind users to a lower privileged role and then remove the\n          clusterrolebinding to the cluster-admin role :\n          kubectl delete clusterrolebinding [name]\n        scored: false\n\n      - id: 5.1.2\n        text: \"Minimize access to secrets (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove get, list and watch access to Secret objects in the cluster.\n        scored: false\n\n      - id: 5.1.3\n        text: \"Minimize wildcard use in Roles and ClusterRoles (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible replace any use of wildcards in clusterroles and roles with specific\n          objects or actions.\n        scored: false\n\n      - id: 5.1.4\n        text: \"Minimize access to create pods (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove create access to pod objects in the cluster.\n        scored: false\n\n      - id: 5.1.5\n        text: \"Ensure that default service accounts are not actively used. (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Create explicit service accounts wherever a Kubernetes workload requires specific access\n          to the Kubernetes API server.\n          Modify the configuration of each default service account to include this value\n          automountServiceAccountToken: false\n        scored: false\n\n      - id: 5.1.6\n        text: \"Ensure that Service Account Tokens are only mounted where necessary (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Modify the definition of pods and service accounts which do not need to mount service\n          account tokens to disable it.\n        scored: false\n\n      - id: 5.1.7\n        text: \"Avoid use of system:masters group (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Remove the system:masters group from all users in the cluster.\n        scored: false\n\n      - id: 5.1.8\n        text: \"Limit use of the Bind, Impersonate and Escalate permissions in the Kubernetes cluster (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove the impersonate, bind and escalate rights from subjects.\n        scored: false\n\n  - id: 5.2\n    text: \"Pod Security Standards\"\n    checks:\n      - id: 5.2.1\n        text: \"Ensure that the cluster has at least one active policy control mechanism in place (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that either Pod Security Admission or an external policy control system is in place\n          for every namespace which contains user workloads.\n        scored: false\n\n      - id: 5.2.2\n        text: \"Minimize the admission of privileged containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of privileged containers.\n        scored: false\n\n      - id: 5.2.3\n        text: \"Minimize the admission of containers wishing to share the host process ID namespace (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of `hostPID` containers.\n        scored: false\n\n      - id: 5.2.4\n        text: \"Minimize the admission of containers wishing to share the host IPC namespace (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of `hostIPC` containers.\n        scored: false\n\n      - id: 5.2.5\n        text: \"Minimize the admission of containers wishing to share the host network namespace (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of `hostNetwork` containers.\n        scored: false\n\n      - id: 5.2.6\n        text: \"Minimize the admission of containers with allowPrivilegeEscalation (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers with `.spec.allowPrivilegeEscalation` set to `true`.\n        scored: false\n\n      - id: 5.2.7\n        text: \"Minimize the admission of root containers (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Create a policy for each namespace in the cluster, ensuring that either `MustRunAsNonRoot`\n          or `MustRunAs` with the range of UIDs not including 0, is set.\n        scored: false\n\n      - id: 5.2.8\n        text: \"Minimize the admission of containers with the NET_RAW capability (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers with the `NET_RAW` capability.\n        scored: false\n\n      - id: 5.2.9\n        text: \"Minimize the admission of containers with added capabilities (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that `allowedCapabilities` is not present in policies for the cluster unless\n          it is set to an empty array.\n        scored: false\n\n      - id: 5.2.10\n        text: \"Minimize the admission of containers with capabilities assigned (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Review the use of capabilites in applications running on your cluster. Where a namespace\n          contains applications which do not require any Linux capabities to operate consider adding\n          a PSP which forbids the admission of containers which do not drop all capabilities.\n        scored: false\n\n      - id: 5.2.11\n        text: \"Minimize the admission of Windows HostProcess containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers that have `.securityContext.windowsOptions.hostProcess` set to `true`.\n        scored: false\n\n      - id: 5.2.12\n        text: \"Minimize the admission of HostPath volumes (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers with `hostPath` volumes.\n        scored: false\n\n      - id: 5.2.13\n        text: \"Minimize the admission of containers which use HostPorts (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers which use `hostPort` sections.\n        scored: false\n\n  - id: 5.3\n    text: \"Network Policies and CNI\"\n    checks:\n      - id: 5.3.1\n        text: \"Ensure that the CNI in use supports NetworkPolicies (Manual)\"\n        type: \"manual\"\n        remediation: |\n          If the CNI plugin in use does not support network policies, consideration should be given to\n          making use of a different plugin, or finding an alternate mechanism for restricting traffic\n          in the Kubernetes cluster.\n        scored: false\n\n      - id: 5.3.2\n        text: \"Ensure that all Namespaces have NetworkPolicies defined (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the documentation and create NetworkPolicy objects as you need them.\n        scored: false\n\n  - id: 5.4\n    text: \"Secrets Management\"\n    checks:\n      - id: 5.4.1\n        text: \"Prefer using Secrets as files over Secrets as environment variables (Manual)\"\n        type: \"manual\"\n        remediation: |\n          If possible, rewrite application code to read Secrets from mounted secret files, rather than\n          from environment variables.\n        scored: false\n\n      - id: 5.4.2\n        text: \"Consider external secret storage (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Refer to the Secrets management options offered by your cloud provider or a third-party\n          secrets management solution.\n        scored: false\n\n  - id: 5.5\n    text: \"Extensible Admission Control\"\n    checks:\n      - id: 5.5.1\n        text: \"Configure Image Provenance using ImagePolicyWebhook admission controller (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and setup image provenance.\n        scored: false\n\n  - id: 5.7\n    text: \"General Policies\"\n    checks:\n      - id: 5.7.1\n        text: \"Create administrative boundaries between resources using namespaces (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the documentation and create namespaces for objects in your deployment as you need\n          them.\n        scored: false\n\n      - id: 5.7.2\n        text: \"Ensure that the seccomp profile is set to docker/default in your Pod definitions (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Use `securityContext` to enable the docker/default seccomp profile in your pod definitions.\n          An example is as below:\n            securityContext:\n              seccompProfile:\n                type: RuntimeDefault\n        scored: false\n\n      - id: 5.7.3\n        text: \"Apply SecurityContext to your Pods and Containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and apply SecurityContexts to your Pods. For a\n          suggested list of SecurityContexts, you may refer to the CIS Security Benchmark for Docker\n          Containers.\n        scored: false\n\n      - id: 5.7.4\n        text: \"The default namespace should not be used (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that namespaces are created to allow for appropriate segregation of Kubernetes\n          resources and that all new resources are created in a specific namespace.\n        scored: false\n"
  },
  {
    "path": "cfg/rke2-cis-1.24/config.yaml",
    "content": "---\n## Version-specific settings that override the values in cfg/config.yaml\n"
  },
  {
    "path": "cfg/rke2-cis-1.24/controlplane.yaml",
    "content": "---\ncontrols:\nversion: \"rke2-cis-1.24\"\nid: 3\ntext: \"Control Plane Configuration\"\ntype: \"controlplane\"\ngroups:\n  - id: 3.1\n    text: \"Authentication and Authorization\"\n    checks:\n      - id: 3.1.1\n        text: \"Client certificate authentication should not be used for users (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Alternative mechanisms provided by Kubernetes such as the use of OIDC should be\n          implemented in place of client certificates.\n        scored: false\n\n  - id: 3.2\n    text: \"Logging\"\n    checks:\n      - id: 3.2.1\n        text: \"Ensure that a minimal audit policy is created (Automated)\"\n        audit: \"/bin/ps -ef | grep kube-apiserver | grep -v grep | grep -o audit-policy-file\"\n        type: \"skip\"\n        tests:\n          test_items:\n            - flag: \"--audit-policy-file\"\n              compare:\n                op: eq\n                value: \"--audit-policy-file\"\n              set: true\n        remediation: |\n          Create an audit policy file for your cluster.\n        scored: true\n\n      - id: 3.2.2\n        text: \"Ensure that the audit policy covers key security concerns (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Review the audit policy provided for the cluster and ensure that it covers\n          at least the following areas,\n          - Access to Secrets managed by the cluster. Care should be taken to only\n            log Metadata for requests to Secrets, ConfigMaps, and TokenReviews, in\n            order to avoid risk of logging sensitive data.\n          - Modification of Pod and Deployment objects.\n          - Use of `pods/exec`, `pods/portforward`, `pods/proxy` and `services/proxy`.\n          For most requests, minimally logging at the Metadata level is recommended\n          (the most basic level of logging).\n        scored: false\n"
  },
  {
    "path": "cfg/rke2-cis-1.24/etcd.yaml",
    "content": "---\ncontrols:\nversion: \"rke2-cis-1.24\"\nid: 2\ntext: \"Etcd Node Configuration\"\ntype: \"etcd\"\ngroups:\n  - id: 2\n    text: \"Etcd Node Configuration\"\n    checks:\n      - id: 2.1\n        text: \"Ensure that the --cert-file and --key-file arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--cert-file\"\n              env: \"ETCD_CERT_FILE\"\n            - flag: \"--key-file\"\n              env: \"ETCD_KEY_FILE\"\n        remediation: |\n          Follow the etcd service documentation and configure TLS encryption.\n          Then, edit the etcd pod specification file /etc/kubernetes/manifests/etcd.yaml\n          on the master node and set the below parameters.\n          --cert-file=</path/to/ca-file>\n          --key-file=</path/to/key-file>\n        scored: true\n        type: \"skip\"\n\n      - id: 2.2\n        text: \"Ensure that the --client-cert-auth argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--client-cert-auth\"\n              env: \"ETCD_CLIENT_CERT_AUTH\"\n              compare:\n                op: eq\n                value: true\n        type: \"skip\"\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and set the below parameter.\n          --client-cert-auth=\"true\"\n        scored: true\n\n      - id: 2.3\n        text: \"Ensure that the --auto-tls argument is not set to true (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--auto-tls\"\n              env: \"ETCD_AUTO_TLS\"\n              set: false\n            - flag: \"--auto-tls\"\n              env: \"ETCD_AUTO_TLS\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and either remove the --auto-tls parameter or set it to false.\n            --auto-tls=false\n        scored: true\n\n      - id: 2.4\n        text: \"Ensure that the --peer-cert-file and --peer-key-file arguments are\n        set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--peer-cert-file\"\n              env: \"ETCD_PEER_CERT_FILE\"\n              set: true\n            - flag: \"--peer-key-file\"\n              env: \"ETCD_PEER_KEY_FILE\"\n              set: true\n        remediation: |\n          Follow the etcd service documentation and configure peer TLS encryption as appropriate\n          for your etcd cluster.\n          Then, edit the etcd pod specification file $etcdconf on the\n          master node and set the below parameters.\n          --peer-client-file=</path/to/peer-cert-file>\n          --peer-key-file=</path/to/peer-key-file>\n        scored: true\n        type: \"skip\"\n\n      - id: 2.5\n        text: \"Ensure that the --peer-client-cert-auth argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--peer-client-cert-auth\"\n              env: \"ETCD_PEER_CLIENT_CERT_AUTH\"\n              compare:\n                op: eq\n                value: true\n              set: true\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and set the below parameter.\n          --peer-client-cert-auth=true\n        scored: true\n        type: \"skip\"\n\n      - id: 2.6\n        text: \"Ensure that the --peer-auto-tls argument is not set to true (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--peer-auto-tls\"\n              env: \"ETCD_PEER_AUTO_TLS\"\n              set: false\n            - flag: \"--peer-auto-tls\"\n              env: \"ETCD_PEER_AUTO_TLS\"\n              compare:\n                op: eq\n                value: false\n              set: true\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and either remove the --peer-auto-tls parameter or set it to false.\n          --peer-auto-tls=false\n        scored: true\n\n      - id: 2.7\n        text: \"Ensure that a unique Certificate Authority is used for etcd (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        audit_config: \"cat /var/lib/rancher/rke2/server/db/etcd/config\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--trusted-ca-file\"\n              env: \"ETCD_TRUSTED_CA_FILE\"\n            - path: \"{.peer-transport-security.trusted-ca-file}\"\n              compare:\n                op: eq\n                value: \"/var/lib/rancher/rke2/server/tls/etcd/peer-ca.crt\"\n              set: true\n        remediation: |\n          [Manual test]\n          Follow the etcd documentation and create a dedicated certificate authority setup for the\n          etcd service.\n          Then, edit the etcd pod specification file $etcdconf on the\n          master node and set the below parameter.\n          --trusted-ca-file=</path/to/ca-file>\n        scored: false\n"
  },
  {
    "path": "cfg/rke2-cis-1.24/master.yaml",
    "content": "---\ncontrols:\nversion: \"rke2-cis-1.24\"\nid: 1\ntext: \"Control Plane Security Configuration\"\ntype: \"master\"\ngroups:\n  - id: 1.1\n    text: \"Control Plane Node Configuration Files\"\n    checks:\n      - id: 1.1.1\n        text: \"Ensure that the API server pod specification file permissions are set to 644 or more restrictive (Automated)\"\n        audit: \"stat -c permissions=%a /var/lib/rancher/rke2/agent/pod-manifests/kube-apiserver.yaml\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: eq\n                value: \"644\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the\n          control plane node.\n          For example, chmod 644 $apiserverconf\n        scored: true\n\n      - id: 1.1.2\n        text: \"Ensure that the API server pod specification file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $apiserverconf; then stat -c %U:%G $apiserverconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n              compare:\n                op: eq\n                value: \"root:root\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chown root:root $apiserverconf\n        scored: true\n\n      - id: 1.1.3\n        text: \"Ensure that the controller manager pod specification file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerconf; then stat -c permissions=%a $controllermanagerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"644\"\n              compare:\n                op: eq\n                value: \"600\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chmod 600 $controllermanagerconf\n        scored: true\n\n      - id: 1.1.4\n        text: \"Ensure that the controller manager pod specification file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerconf; then stat -c %U:%G $controllermanagerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n              compare:\n                op: eq\n                value: \"root:root\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chown root:root $controllermanagerconf\n        scored: true\n\n      - id: 1.1.5\n        text: \"Ensure that the scheduler pod specification file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerconf; then stat -c permissions=%a $schedulerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"600\"\n              compare:\n                op: eq\n                value: \"600\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chmod 600 $schedulerconf\n        scored: true\n\n      - id: 1.1.6\n        text: \"Ensure that the scheduler pod specification file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerconf; then stat -c %U:%G $schedulerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chown root:root $schedulerconf\n        scored: true\n\n      - id: 1.1.7\n        text: \"Ensure that the etcd pod specification file permissions are set to 644 or more restrictive (Automated)\"\n        audit: |\n          /bin/sh -c '\n            if [ -e \"$etcdconf\" ]; then\n              stat -c \"permissions=%a %n\" \"$etcdconf\"\n            else\n              echo \"Directory not found\"\n            fi\n          '\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n            - flag: \"Directory not found\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod 644 $etcdconf\n        scored: true\n\n      - id: 1.1.8\n        text: \"Ensure that the etcd pod specification file ownership is set to root:root (Automated)\"\n        audit: |\n          /bin/sh -c '\n            if [ -e $etcdconf ]; then\n              stat -c \"ownership=%U:%G %n\" $etcdconf\n            else\n              echo \"Directory not found\"\n            fi\n          '\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"ownership\"\n              compare:\n                op: eq\n                value: \"root:root\"\n              set: true\n            - flag: \"Directory not found\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root $etcdconf\n        scored: true\n\n      - id: 1.1.9\n        text: \"Ensure that the Container Network Interface file permissions are set to 600 or more restrictive (Manual)\"\n        audit: |\n          ps -fC ${kubeletbin:-kubelet} | grep -- --cni-conf-dir || echo \"/etc/cni/net.d\" | sed 's%.*cni-conf-dir[= ]\\([^ ]*\\).*%\\1%' | xargs -I{} find {} -mindepth 1 | xargs --no-run-if-empty stat -c permissions=%a\n          find /var/lib/cni/networks -type f 2> /dev/null | xargs --no-run-if-empty stat -c permissions=%a\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chmod 600 <path/to/cni/files>\n        scored: false\n\n      - id: 1.1.10\n        text: \"Ensure that the Container Network Interface file ownership is set to root:root (Manual)\"\n        audit: |\n          '/bin/sh -c \"if [[ -e /etc/cni/net.d ]]; then\n          ps -fC \"${kubeletbin:-kubelet}\" | grep -- --cni-conf-dir || echo \"/etc/cni/net.d\" | sed 's%.*cni-conf-dir[= ]\\([^ ]*\\).*%\\1%' | xargs -I{} find {} -mindepth 1 | xargs --no-run-if-empty stat -c %U:%G\n          find /var/lib/cni/networks -type f 2> /dev/null | xargs --no-run-if-empty stat -c %U:%G\n          else\n          echo \"File not found\"\n          fi'\n        use_multiple_values: true\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"root:root\"\n            - flag: \"File not found\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root <path/to/cni/files>\n        scored: false\n\n      - id: 1.1.11\n        text: \"Ensure that the etcd data directory permissions are set to 700 or more restrictive (Automated)\"\n        audit: |\n          /bin/sh -c 'if [ -d \"/var/lib/rancher/rke2/server/db/etcd\" ]; then\n           stat -c \"permissions=%a\" \"/var/lib/rancher/rke2/server/db/etcd\"\n          else\n           echo \"Directory not found\"\n          fi'\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"700\"\n              set: true\n            - flag: \"Directory not found\"\n        remediation: |\n          On the etcd server node, get the etcd data directory, passed as an argument --data-dir,\n          from the command 'ps -ef | grep etcd'.\n          Run the below command (based on the etcd data directory found above). For example,\n          chmod 700 /var/lib/etcd\n        scored: true\n\n      - id: 1.1.12\n        text: \"Ensure that the etcd data directory ownership is set to etcd:etcd (Automated)\"\n        type: \"skip\"\n        audit: \"stat -c %U:%G /var/lib/rancher/rke2/server/db/etcd\"\n        tests:\n          test_items:\n            - flag: \"etcd:etcd\"\n        remediation: |\n          On the etcd server node, get the etcd data directory, passed as an argument --data-dir,\n          from the command 'ps -ef | grep etcd'.\n          Run the below command (based on the etcd data directory found above).\n          For example, chown etcd:etcd /var/lib/etcd\n        scored: true\n\n      - id: 1.1.13\n        text: \"Ensure that the admin.conf file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"stat -c permissions=%a /var/lib/rancher/rke2/server/cred/admin.kubeconfig\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chmod 600 /etc/kubernetes/admin.conf\n        scored: true\n\n      - id: 1.1.14\n        text: \"Ensure that the admin.conf file ownership is set to root:root (Automated)\"\n        audit: \"stat -c %U:%G /var/lib/rancher/rke2/server/cred/admin.kubeconfig\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n              compare:\n                op: eq\n                value: \"root:root\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chown root:root /etc/kubernetes/admin.conf\n        scored: true\n\n      - id: 1.1.15\n        text: \"Ensure that the scheduler.conf file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"stat -c %a $schedulerkubeconfig\"\n        tests:\n          test_items:\n            - flag: \"600\"\n              compare:\n                op: eq\n                value: \"600\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod 600 $schedulerkubeconfig\n        scored: true\n\n      - id: 1.1.16\n        text: \"Ensure that the scheduler.conf file ownership is set to root:root (Automated)\"\n        audit: \"stat -c %U:%G $schedulerkubeconfig\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n              compare:\n                op: eq\n                value: \"root:root\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root $schedulerkubeconfig\n        scored: true\n\n      - id: 1.1.17\n        text: \"Ensure that the controller-manager.conf file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"stat -c %a $controllermanagerkubeconfig\"\n        tests:\n          test_items:\n            - flag: \"600\"\n              compare:\n                op: eq\n                value: \"600\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod 600 $controllermanagerkubeconfig\n        scored: true\n\n      - id: 1.1.18\n        text: \"Ensure that the controller-manager.conf file ownership is set to root:root (Automated)\"\n        audit: \"stat -c %U:%G $controllermanagerkubeconfig\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n              compare:\n                op: eq\n                value: \"root:root\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root $controllermanagerkubeconfig\n        scored: true\n\n      - id: 1.1.19\n        text: \"Ensure that the Kubernetes PKI directory and file ownership is set to root:root (Automated)\"\n        audit: \"stat -c %U:%G /var/lib/rancher/rke2/server/tls\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n              compare:\n                op: eq\n                value: \"root:root\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown -R root:root /etc/kubernetes/pki/\n        scored: true\n\n      - id: 1.1.20\n        text: \"Ensure that the Kubernetes PKI certificate file permissions are set to 600 or more restrictive (Manual)\"\n        audit: \"stat -c permissions=%a /var/lib/rancher/rke2/server/tls/*.crt\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod -R 600 /var/lib/rancher/rke2/server/tls/*.crt\n        scored: false\n\n      - id: 1.1.21\n        text: \"Ensure that the Kubernetes PKI key file permissions are set to 600 (Manual)\"\n        audit: |\n          '/bin/sh -c if test -e \"/var/lib/rancher/rke2/server/tls/*.key\"; then\n          stat -c \"%a\" \"/var/lib/rancher/rke2/server/tls/*.key\"\n          else\n          echo \"File not found\"\n          fi'\n        use_multiple_values: true\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"permissions\"\n            - flag: \"File not found\"\n              compare:\n                op: eq\n                value: \"600\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod -R 600 /var/lib/rancher/rke2/server/tls/*.key\n        scored: false\n\n  - id: 1.2\n    text: \"API Server\"\n    checks:\n      - id: 1.2.1\n        text: \"Ensure that the --anonymous-auth argument is set to false (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        type: manual\n        tests:\n          test_items:\n            - flag: \"--anonymous-auth\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the below parameter.\n          --anonymous-auth=false\n        scored: false\n\n      - id: 1.2.2\n        text: \"Ensure that the --token-auth-file parameter is not set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--token-auth-file\"\n              set: false\n        remediation: |\n          Follow the documentation and configure alternate mechanisms for authentication. Then,\n          edit the API server pod specification file $apiserverconf\n          on the control plane node and remove the --token-auth-file=<filename> parameter.\n        scored: true\n\n      - id: 1.2.3\n        text: \"Ensure that the --DenyServiceExternalIPs is not set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: nothave\n                value: \"DenyServiceExternalIPs\"\n              set: true\n            - flag: \"--enable-admission-plugins\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and remove the `DenyServiceExternalIPs`\n          from enabled admission plugins.\n        scored: true\n\n      - id: 1.2.4\n        text: \"Ensure that the --kubelet-https argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--kubelet-https\"\n              compare:\n                op: eq\n                value: true\n            - flag: \"--kubelet-https\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and remove the --kubelet-https parameter.\n        scored: true\n\n      - id: 1.2.5\n        text: \"Ensure that the --kubelet-client-certificate and --kubelet-client-key arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--kubelet-client-certificate\"\n              set: true\n            - flag: \"--kubelet-client-key\"\n              set: true\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection between the\n          apiserver and kubelets. Then, edit API server pod specification file\n          $apiserverconf on the control plane node and set the\n          kubelet client certificate and key parameters as below.\n          --kubelet-client-certificate=<path/to/client-certificate-file>\n          --kubelet-client-key=<path/to/client-key-file>\n        scored: true\n\n      - id: 1.2.6\n        text: \"Ensure that the --kubelet-certificate-authority argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--kubelet-certificate-authority\"\n              set: true\n        remediation: |\n          Follow the Kubernetes documentation and setup the TLS connection between\n          the apiserver and kubelets. Then, edit the API server pod specification file\n          $apiserverconf on the control plane node and set the\n          --kubelet-certificate-authority parameter to the path to the cert file for the certificate authority.\n          --kubelet-certificate-authority=<ca-string>\n        scored: true\n\n      - id: 1.2.7\n        text: \"Ensure that the --authorization-mode argument is not set to AlwaysAllow (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: nothave\n                value: \"AlwaysAllow\"\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --authorization-mode parameter to values other than AlwaysAllow.\n          One such example could be as below.\n          --authorization-mode=RBAC\n        scored: true\n\n      - id: 1.2.8\n        text: \"Ensure that the --authorization-mode argument includes Node (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: has\n                value: \"Node\"\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --authorization-mode parameter to a value that includes Node.\n          --authorization-mode=Node,RBAC\n        scored: true\n\n      - id: 1.2.9\n        text: \"Ensure that the --authorization-mode argument includes RBAC (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: has\n                value: \"RBAC\"\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --authorization-mode parameter to a value that includes RBAC,\n          for example `--authorization-mode=Node,RBAC`.\n        scored: true\n\n      - id: 1.2.10\n        text: \"Ensure that the admission control plugin EventRateLimit is set (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"EventRateLimit\"\n              set: true\n        remediation: |\n          Follow the Kubernetes documentation and set the desired limits in a configuration file.\n          Then, edit the API server pod specification file $apiserverconf\n          and set the below parameters.\n          --enable-admission-plugins=...,EventRateLimit,...\n          --admission-control-config-file=<path/to/configuration/file>\n        scored: false\n\n      - id: 1.2.11\n        text: \"Ensure that the admission control plugin AlwaysAdmit is not set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: nothave\n                value: AlwaysAdmit\n              set: true\n            - flag: \"--enable-admission-plugins\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and either remove the --enable-admission-plugins parameter, or set it to a\n          value that does not include AlwaysAdmit.\n        scored: true\n\n      - id: 1.2.12\n        text: \"Ensure that the admission control plugin AlwaysPullImages is set (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"AlwaysPullImages\"\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --enable-admission-plugins parameter to include\n          AlwaysPullImages.\n          --enable-admission-plugins=...,AlwaysPullImages,...\n        scored: false\n\n      - id: 1.2.13\n        text: \"Ensure that the admission control plugin SecurityContextDeny is set if PodSecurityPolicy is not used (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"SecurityContextDeny\"\n              set: true\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"PodSecurityPolicy\"\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --enable-admission-plugins parameter to include\n          SecurityContextDeny, unless PodSecurityPolicy is already in place.\n          --enable-admission-plugins=...,SecurityContextDeny,...\n        scored: false\n\n      - id: 1.2.14\n        text: \"Ensure that the admission control plugin ServiceAccount is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--disable-admission-plugins\"\n              compare:\n                op: nothave\n                value: \"ServiceAccount\"\n            - flag: \"--disable-admission-plugins\"\n              set: false\n        remediation: |\n          Follow the documentation and create ServiceAccount objects as per your environment.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and ensure that the --disable-admission-plugins parameter is set to a\n          value that does not include ServiceAccount.\n        scored: true\n\n      - id: 1.2.15\n        text: \"Ensure that the admission control plugin NamespaceLifecycle is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--disable-admission-plugins\"\n              compare:\n                op: nothave\n                value: \"NamespaceLifecycle\"\n            - flag: \"--disable-admission-plugins\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --disable-admission-plugins parameter to\n          ensure it does not include NamespaceLifecycle.\n        scored: true\n\n      - id: 1.2.16\n        text: \"Ensure that the admission control plugin NodeRestriction is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"NodeRestriction\"\n              set: true\n        remediation: |\n          Follow the Kubernetes documentation and configure NodeRestriction plug-in on kubelets.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --enable-admission-plugins parameter to a\n          value that includes NodeRestriction.\n          --enable-admission-plugins=...,NodeRestriction,...\n        scored: true\n\n      - id: 1.2.17\n        text: \"Ensure that the --secure-port argument is not set to 0 (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--secure-port\"\n              compare:\n                op: gt\n                value: 0\n              set: true\n            - flag: \"--secure-port\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and either remove the --secure-port parameter or\n          set it to a different (non-zero) desired port.\n        scored: true\n\n      - id: 1.2.18\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the below parameter.\n          --profiling=false\n        scored: true\n\n      - id: 1.2.19\n        text: \"Ensure that the --audit-log-path argument is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        type: \"skip\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-path\"\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --audit-log-path parameter to a suitable path and\n          file where you would like audit logs to be written, for example,\n          --audit-log-path=/var/log/apiserver/audit.log\n        scored: true\n\n      - id: 1.2.20\n        text: \"Ensure that the --audit-log-maxage argument is set to 30 or as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        type: \"skip\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxage\"\n              compare:\n                op: gte\n                value: 30\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --audit-log-maxage parameter to 30\n          or as an appropriate number of days, for example,\n          --audit-log-maxage=30\n        scored: true\n\n      - id: 1.2.21\n        text: \"Ensure that the --audit-log-maxbackup argument is set to 10 or as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        type: \"skip\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxbackup\"\n              compare:\n                op: gte\n                value: 10\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --audit-log-maxbackup parameter to 10 or to an appropriate\n          value. For example,\n          --audit-log-maxbackup=10\n        scored: true\n\n      - id: 1.2.22\n        text: \"Ensure that the --audit-log-maxsize argument is set to 100 or as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        type: \"skip\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxsize\"\n              compare:\n                op: gte\n                value: 100\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --audit-log-maxsize parameter to an appropriate size in MB.\n          For example, to set it as 100 MB, --audit-log-maxsize=100\n        scored: true\n\n      - id: 1.2.23\n        text: \"Ensure that the --request-timeout argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--request-timeout\"\n              set: false\n            - flag: \"--request-timeout\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          and set the below parameter as appropriate and if needed.\n          For example, --request-timeout=300s\n        scored: true\n\n      - id: 1.2.24\n        text: \"Ensure that the --service-account-lookup argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--service-account-lookup\"\n              set: false\n            - flag: \"--service-account-lookup\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the below parameter.\n          --service-account-lookup=true\n          Alternatively, you can delete the --service-account-lookup parameter from this file so\n          that the default takes effect.\n        scored: true\n\n      - id: 1.2.25\n        text: \"Ensure that the --service-account-key-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--service-account-key-file\"\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --service-account-key-file parameter\n          to the public key file for service accounts. For example,\n          --service-account-key-file=<filename>\n        scored: true\n\n      - id: 1.2.26\n        text: \"Ensure that the --etcd-certfile and --etcd-keyfile arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--etcd-certfile\"\n              set: true\n            - flag: \"--etcd-keyfile\"\n              set: true\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection between the apiserver and etcd.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the etcd certificate and key file parameters.\n          --etcd-certfile=<path/to/client-certificate-file>\n          --etcd-keyfile=<path/to/client-key-file>\n        scored: true\n\n      - id: 1.2.27\n        text: \"Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--tls-cert-file\"\n              set: true\n            - flag: \"--tls-private-key-file\"\n              set: true\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection on the apiserver.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the TLS certificate and private key file parameters.\n          --tls-cert-file=<path/to/tls-certificate-file>\n          --tls-private-key-file=<path/to/tls-key-file>\n        scored: true\n\n      - id: 1.2.28\n        text: \"Ensure that the --client-ca-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--client-ca-file\"\n              set: true\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection on the apiserver.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the client certificate authority file.\n          --client-ca-file=<path/to/client-ca-file>\n        scored: true\n\n      - id: 1.2.29\n        text: \"Ensure that the --etcd-cafile argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--etcd-cafile\"\n              set: true\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection between the apiserver and etcd.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the etcd certificate authority file parameter.\n          --etcd-cafile=<path/to/ca-file>\n        scored: true\n\n      - id: 1.2.30\n        text: \"Ensure that the --encryption-provider-config argument is set as appropriate (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--encryption-provider-config\"\n        remediation: |\n          Follow the Kubernetes documentation and configure a EncryptionConfig file.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --encryption-provider-config parameter to the path of that file.\n          For example, --encryption-provider-config=</path/to/EncryptionConfig/File>\n        scored: false\n\n      - id: 1.2.31\n        text: \"Ensure that encryption providers are appropriately configured (Manual)\"\n        type: \"skip\"\n        audit: |\n          ENCRYPTION_PROVIDER_CONFIG=$(ps -ef | grep $apiserverbin | grep -- --encryption-provider-config | sed 's%.*encryption-provider-config[= ]\\([^ ]*\\).*%\\1%')\n          if test -e $ENCRYPTION_PROVIDER_CONFIG; then grep -A1 'providers:' $ENCRYPTION_PROVIDER_CONFIG | tail -n1 | grep -o \"[A-Za-z]*\" | sed 's/^/provider=/'; fi\n        tests:\n          test_items:\n            - flag: \"provider\"\n              compare:\n                op: valid_elements\n                value: \"aescbc,kms,secretbox\"\n        remediation: |\n          Follow the Kubernetes documentation and configure a EncryptionConfig file.\n          In this file, choose aescbc, kms or secretbox as the encryption provider.\n        scored: false\n\n      - id: 1.2.32\n        text: \"Ensure that the API Server only makes use of Strong Cryptographic Ciphers (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--tls-cipher-suites\"\n              compare:\n                op: valid_elements\n                value: \"TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,TLS_CHACHA20_POLY1305_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,TLS_RSA_WITH_3DES_EDE_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_256_GCM_SHA384\"\n        remediation: |\n          Edit the API server pod specification file /etc/kubernetes/manifests/kube-apiserver.yaml\n          on the control plane node and set the below parameter.\n          --tls-cipher-suites=TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,TLS_CHACHA20_POLY1305_SHA256,\n          TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,\n          TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,\n          TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,\n          TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,\n          TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,\n          TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,TLS_RSA_WITH_3DES_EDE_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA,\n          TLS_RSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_256_GCM_SHA384\n        scored: false\n        type: skip\n\n  - id: 1.3\n    text: \"Controller Manager\"\n    checks:\n      - id: 1.3.1\n        text: \"Ensure that the --terminated-pod-gc-threshold argument is set as appropriate (Manual)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--terminated-pod-gc-threshold\"\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the --terminated-pod-gc-threshold to an appropriate threshold,\n          for example, --terminated-pod-gc-threshold=10\n        scored: false\n\n      - id: 1.3.2\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n              set: true\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the below parameter.\n          --profiling=false\n        scored: true\n\n      - id: 1.3.3\n        text: \"Ensure that the --use-service-account-credentials argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--use-service-account-credentials\"\n              compare:\n                op: noteq\n                value: false\n              set: true\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node to set the below parameter.\n          --use-service-account-credentials=true\n        scored: true\n\n      - id: 1.3.4\n        text: \"Ensure that the --service-account-private-key-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--service-account-private-key-file\"\n              set: true\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the --service-account-private-key-file parameter\n          to the private key file for service accounts.\n          --service-account-private-key-file=<filename>\n        scored: true\n\n      - id: 1.3.5\n        text: \"Ensure that the --root-ca-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--root-ca-file\"\n              set: true\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the --root-ca-file parameter to the certificate bundle file`.\n          --root-ca-file=<path/to/file>\n        scored: true\n\n      - id: 1.3.6\n        text: \"Ensure that the RotateKubeletServerCertificate argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--feature-gates\"\n              compare:\n                op: nothave\n                value: \"RotateKubeletServerCertificate=false\"\n              set: true\n            - flag: \"--feature-gates\"\n              set: false\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the --feature-gates parameter to include RotateKubeletServerCertificate=true.\n          --feature-gates=RotateKubeletServerCertificate=true\n        scored: false\n        type: skip\n\n      - id: 1.3.7\n        text: \"Ensure that the --bind-address argument is set to 127.0.0.1 (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--bind-address\"\n              compare:\n                op: eq\n                value: \"127.0.0.1\"\n              set: true\n            - flag: \"--bind-address\"\n              set: false\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and ensure the correct value for the --bind-address parameter\n        scored: true\n\n  - id: 1.4\n    text: \"Scheduler\"\n    checks:\n      - id: 1.4.1\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: \"/bin/ps -ef | grep $schedulerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n              set: true\n        remediation: |\n          Edit the Scheduler pod specification file $schedulerconf file\n          on the control plane node and set the below parameter.\n          --profiling=false\n        scored: true\n\n      - id: 1.4.2\n        text: \"Ensure that the --bind-address argument is set to 127.0.0.1 (Automated)\"\n        audit: \"/bin/ps -ef | grep $schedulerbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--bind-address\"\n              compare:\n                op: eq\n                value: \"127.0.0.1\"\n              set: true\n            - flag: \"--bind-address\"\n              set: false\n        remediation: |\n          Edit the Scheduler pod specification file $schedulerconf\n          on the control plane node and ensure the correct value for the --bind-address parameter\n        scored: true\n"
  },
  {
    "path": "cfg/rke2-cis-1.24/node.yaml",
    "content": "---\ncontrols:\nversion: \"rke2-cis-1.24\"\nid: 4\ntext: \"Worker Node Security Configuration\"\ntype: \"node\"\ngroups:\n  - id: 4.1\n    text: \"Worker Node Configuration Files\"\n    checks:\n      - id: 4.1.1\n        text: \"Ensure that the kubelet service file permissions are set to 600 or more restrictive (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletsvc; then stat -c permissions=%a $kubeletsvc; fi'' '\n        type: \"skip\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example, chmod 600 $kubeletsvc\n        scored: true\n\n      - id: 4.1.2\n        text: \"Ensure that the kubelet service file ownership is set to root:root (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletsvc; then stat -c %U:%G $kubeletsvc; fi'' '\n        type: \"skip\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chown root:root $kubeletsvc\n        scored: true\n\n      - id: 4.1.3\n        text: \"If proxy kubeconfig file exists ensure permissions are set to 600 or more restrictive (Manual)\"\n        audit: '/bin/sh -c ''if test -e $proxykubeconfig; then stat -c permissions=%a $proxykubeconfig; fi'' '\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"permissions\"\n              set: true\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chmod 600 $proxykubeconfig\n        scored: false\n\n      - id: 4.1.4\n        text: \"If proxy kubeconfig file exists ensure ownership is set to root:root (Manual)\"\n        audit: '/bin/sh -c ''if test -e $proxykubeconfig; then stat -c %U:%G $proxykubeconfig; fi'' '\n        tests:\n          bin_op: or\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example, chown root:root $proxykubeconfig\n        scored: false\n\n      - id: 4.1.5\n        text: \"Ensure that the --kubeconfig kubelet.conf file permissions are set to 600 or more restrictive (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletkubeconfig; then stat -c permissions=%a $kubeletkubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: \"600\"\n              compare:\n                op: eq\n                value: \"600\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chmod 600 $kubeletkubeconfig\n        scored: true\n\n      - id: 4.1.6\n        text: \"Ensure that the --kubeconfig kubelet.conf file ownership is set to root:root (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletkubeconfig; then stat -c %U:%G $kubeletkubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: root:root\n              set: true\n              compare:\n                op: eq\n                value: root:root\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chown root:root $kubeletkubeconfig\n        scored: true\n\n      - id: 4.1.7\n        text: \"Ensure that the certificate authorities file permissions are set to 600 or more restrictive (Manual)\"\n        audit: \"check_cafile_permissions.sh\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n              set: true\n        remediation: |\n          Run the following command to modify the file permissions of the\n          --client-ca-file chmod 600 <filename>\n        scored: false\n\n      - id: 4.1.8\n        text: \"Ensure that the client certificate authorities file ownership is set to root:root (Manual)\"\n        audit: \"check_cafile_ownership.sh\"\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the following command to modify the ownership of the --client-ca-file.\n          chown root:root <filename>\n        scored: false\n\n      - id: 4.1.9\n        text: \"If the kubelet config.yaml configuration file is being used validate permissions set to 600 or more restrictive (Automated)\"\n        audit: |\n          /bin/sh -c 'if test -e \"$kubeletconf\"; then\n             stat -c \"permissions=%a\" \"$kubeletconf\"\n           else\n             echo \"File not found\"\n           fi'\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n              set: true\n            - flag: \"File not found\"\n        remediation: |\n          Run the following command (using the config file location identified in the Audit step)\n          chmod 600 $kubeletconf\n        scored: true\n\n      - id: 4.1.10\n        text: \"If the kubelet config.yaml configuration file is being used validate file ownership is set to root:root (Automated)\"\n        audit: |\n          /bin/sh -c 'if test -e \"$kubeletconf\"; then\n              stat -c \"%U:%G\" \"$kubeletconf\"\n          else\n              echo \"File not found\"\n          fi'\n        tests:\n          bin_op: or\n          test_items:\n            - flag: root:root\n              set: true\n            - flag: \"File not found\"\n        remediation: |\n          Run the following command (using the config file location identified in the Audit step)\n          chown root:root $kubeletconf\n        scored: true\n\n  - id: 4.2\n    text: \"Kubelet\"\n    checks:\n      - id: 4.2.1\n        text: \"Ensure that the --anonymous-auth argument is set to false (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: \"--anonymous-auth\"\n              path: '{.authentication.anonymous.enabled}'\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          If using a Kubelet config file, edit the file to set `authentication: anonymous: enabled` to\n          `false`.\n          If using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          `--anonymous-auth=false`\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.2\n        text: \"Ensure that the --authorization-mode argument is not set to AlwaysAllow (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --authorization-mode\n              path: '{.authorization.mode}'\n              compare:\n                op: nothave\n                value: AlwaysAllow\n        remediation: |\n          If using a Kubelet config file, edit the file to set `authorization.mode` to Webhook. If\n          using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_AUTHZ_ARGS variable.\n          --authorization-mode=Webhook\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.3\n        text: \"Ensure that the --client-ca-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --client-ca-file\n              path: '{.authentication.x509.clientCAFile}'\n        remediation: |\n          If using a Kubelet config file, edit the file to set `authentication.x509.clientCAFile` to\n          the location of the client CA file.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_AUTHZ_ARGS variable.\n          --client-ca-file=<path/to/client-ca-file>\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.4\n        text: \"Verify that the --read-only-port argument is set to 0 (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--read-only-port\"\n              path: '{.readOnlyPort}'\n              compare:\n                op: eq\n                value: 0\n            - flag: \"--read-only-port\"\n              path: '{.readOnlyPort}'\n              set: false\n        remediation: |\n          If using a Kubelet config file, edit the file to set `readOnlyPort` to 0.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --read-only-port=0\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.5\n        text: \"Ensure that the --streaming-connection-idle-timeout argument is not set to 0 (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --streaming-connection-idle-timeout\n              path: '{.streamingConnectionIdleTimeout}'\n              compare:\n                op: noteq\n                value: 0\n            - flag: --streaming-connection-idle-timeout\n              path: '{.streamingConnectionIdleTimeout}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to set `streamingConnectionIdleTimeout` to a\n          value other than 0.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --streaming-connection-idle-timeout=5m\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.6\n        text: \"Ensure that the --protect-kernel-defaults argument is set to true (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: --protect-kernel-defaults\n              path: '{.protectKernelDefaults}'\n              compare:\n                op: eq\n                value: true\n              set: true\n            - flag: --protect-kernel-defaults\n              path: '{.protectKernelDefaults}'\n              set: false\n        remediation: |\n          If using a Kubelet config file, edit the file to set `protectKernelDefaults` to `true`.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --protect-kernel-defaults=true\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.7\n        text: \"Ensure that the --make-iptables-util-chains argument is set to true (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --make-iptables-util-chains\n              path: '{.makeIPTablesUtilChains}'\n              compare:\n                op: eq\n                value: true\n            - flag: --make-iptables-util-chains\n              path: '{.makeIPTablesUtilChains}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to set `makeIPTablesUtilChains` to `true`.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          remove the --make-iptables-util-chains argument from the\n          KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.8\n        text: \"Ensure that the --hostname-override argument is not set (Manual)\"\n        # This is one of those properties that can only be set as a command line argument.\n        # To check if the property is set as expected, we need to parse the kubelet command\n        # instead reading the Kubelet Configuration file.\n        audit: \"/bin/ps -fC $kubeletbin \"\n        tests:\n          test_items:\n            - flag: --hostname-override\n              set: false\n        remediation: |\n          Edit the kubelet service file $kubeletsvc\n          on each worker node and remove the --hostname-override argument from the\n          KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n        type: skip\n\n      - id: 4.2.9\n        text: \"Ensure that the eventRecordQPS argument is set to a level which ensures appropriate event capture (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --event-qps\n              path: '{.eventRecordQPS}'\n              compare:\n                op: eq\n                value: 0\n        remediation: |\n          If using a Kubelet config file, edit the file to set `eventRecordQPS` to an appropriate level.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.10\n        text: \"Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --tls-cert-file\n              path: '{.tlsCertFile}'\n            - flag: --tls-private-key-file\n              path: '{.tlsPrivateKeyFile}'\n        remediation: |\n          If using a Kubelet config file, edit the file to set `tlsCertFile` to the location\n          of the certificate file to use to identify this Kubelet, and `tlsPrivateKeyFile`\n          to the location of the corresponding private key file.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameters in KUBELET_CERTIFICATE_ARGS variable.\n          --tls-cert-file=<path/to/tls-certificate-file>\n          --tls-private-key-file=<path/to/tls-key-file>\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.11\n        text: \"Ensure that the --rotate-certificates argument is not set to false (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --rotate-certificates\n              path: '{.rotateCertificates}'\n              compare:\n                op: eq\n                value: true\n            - flag: --rotate-certificates\n              path: '{.rotateCertificates}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to add the line `rotateCertificates` to `true` or\n          remove it altogether to use the default value.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          remove --rotate-certificates=false argument from the KUBELET_CERTIFICATE_ARGS\n          variable.\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.12\n        text: \"Verify that the RotateKubeletServerCertificate argument is set to true (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: RotateKubeletServerCertificate\n              path: '{.featureGates.RotateKubeletServerCertificate}'\n              compare:\n                op: nothave\n                value: false\n            - flag: RotateKubeletServerCertificate\n              path: '{.featureGates.RotateKubeletServerCertificate}'\n              set: false\n        remediation: |\n          Edit the kubelet service file $kubeletsvc\n          on each worker node and set the below parameter in KUBELET_CERTIFICATE_ARGS variable.\n          --feature-gates=RotateKubeletServerCertificate=true\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n        type: skip\n      - id: 4.2.13\n        text: \"Ensure that the Kubelet only makes use of Strong Cryptographic Ciphers (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --tls-cipher-suites\n              path: '{range .tlsCipherSuites[:]}{}{'',''}{end}'\n              compare:\n                op: valid_elements\n                value: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\n        remediation: |\n          If using a Kubelet config file, edit the file to set `tlsCipherSuites` to\n          TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\n          or to a subset of these values.\n          If using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the --tls-cipher-suites parameter as follows, or to a subset of these values.\n          --tls-cipher-suites=TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n"
  },
  {
    "path": "cfg/rke2-cis-1.24/policies.yaml",
    "content": "---\ncontrols:\nversion: \"rke2-cis-1.24\"\nid: 5\ntext: \"Kubernetes Policies\"\ntype: \"policies\"\ngroups:\n  - id: 5.1\n    text: \"RBAC and Service Accounts\"\n    checks:\n      - id: 5.1.1\n        text: \"Ensure that the cluster-admin role is only used where required (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Identify all clusterrolebindings to the cluster-admin role. Check if they are used and\n          if they need this role or if they could use a role with fewer privileges.\n          Where possible, first bind users to a lower privileged role and then remove the\n          clusterrolebinding to the cluster-admin role :\n          kubectl delete clusterrolebinding [name]\n        scored: false\n\n      - id: 5.1.2\n        text: \"Minimize access to secrets (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove get, list and watch access to Secret objects in the cluster.\n        scored: false\n\n      - id: 5.1.3\n        text: \"Minimize wildcard use in Roles and ClusterRoles (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible replace any use of wildcards in clusterroles and roles with specific\n          objects or actions.\n        scored: false\n\n      - id: 5.1.4\n        text: \"Minimize access to create pods (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove create access to pod objects in the cluster.\n        scored: false\n\n      - id: 5.1.5\n        text: \"Ensure that default service accounts are not actively used. (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Create explicit service accounts wherever a Kubernetes workload requires specific access\n          to the Kubernetes API server.\n          Modify the configuration of each default service account to include this value\n          automountServiceAccountToken: false\n        scored: false\n\n      - id: 5.1.6\n        text: \"Ensure that Service Account Tokens are only mounted where necessary (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Modify the definition of pods and service accounts which do not need to mount service\n          account tokens to disable it.\n        scored: false\n\n      - id: 5.1.7\n        text: \"Avoid use of system:masters group (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Remove the system:masters group from all users in the cluster.\n        scored: false\n\n      - id: 5.1.8\n        text: \"Limit use of the Bind, Impersonate and Escalate permissions in the Kubernetes cluster (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove the impersonate, bind and escalate rights from subjects.\n        scored: false\n\n  - id: 5.2\n    text: \"Pod Security Standards\"\n    checks:\n      - id: 5.2.1\n        text: \"Ensure that the cluster has at least one active policy control mechanism in place (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that either Pod Security Admission or an external policy control system is in place\n          for every namespace which contains user workloads.\n        scored: false\n\n      - id: 5.2.2\n        text: \"Minimize the admission of privileged containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of privileged containers.\n        scored: false\n\n      - id: 5.2.3\n        text: \"Minimize the admission of containers wishing to share the host process ID namespace (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of `hostPID` containers.\n        scored: false\n\n      - id: 5.2.4\n        text: \"Minimize the admission of containers wishing to share the host IPC namespace (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of `hostIPC` containers.\n        scored: false\n\n      - id: 5.2.5\n        text: \"Minimize the admission of containers wishing to share the host network namespace (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of `hostNetwork` containers.\n        scored: false\n\n      - id: 5.2.6\n        text: \"Minimize the admission of containers with allowPrivilegeEscalation (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers with `.spec.allowPrivilegeEscalation` set to `true`.\n        scored: false\n\n      - id: 5.2.7\n        text: \"Minimize the admission of root containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Create a policy for each namespace in the cluster, ensuring that either `MustRunAsNonRoot`\n          or `MustRunAs` with the range of UIDs not including 0, is set.\n        scored: false\n\n      - id: 5.2.8\n        text: \"Minimize the admission of containers with the NET_RAW capability (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers with the `NET_RAW` capability.\n        scored: false\n\n      - id: 5.2.9\n        text: \"Minimize the admission of containers with added capabilities (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that `allowedCapabilities` is not present in policies for the cluster unless\n          it is set to an empty array.\n        scored: false\n\n      - id: 5.2.10\n        text: \"Minimize the admission of containers with capabilities assigned (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Review the use of capabilites in applications running on your cluster. Where a namespace\n          contains applications which do not require any Linux capabities to operate consider adding\n          a PSP which forbids the admission of containers which do not drop all capabilities.\n        scored: false\n\n      - id: 5.2.11\n        text: \"Minimize the admission of Windows HostProcess containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers that have `.securityContext.windowsOptions.hostProcess` set to `true`.\n        scored: false\n\n      - id: 5.2.12\n        text: \"Minimize the admission of HostPath volumes (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers with `hostPath` volumes.\n        scored: false\n\n      - id: 5.2.13\n        text: \"Minimize the admission of containers which use HostPorts (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers which use `hostPort` sections.\n        scored: false\n\n  - id: 5.3\n    text: \"Network Policies and CNI\"\n    checks:\n      - id: 5.3.1\n        text: \"Ensure that the CNI in use supports NetworkPolicies (Manual)\"\n        type: \"manual\"\n        remediation: |\n          If the CNI plugin in use does not support network policies, consideration should be given to\n          making use of a different plugin, or finding an alternate mechanism for restricting traffic\n          in the Kubernetes cluster.\n        scored: false\n\n      - id: 5.3.2\n        text: \"Ensure that all Namespaces have NetworkPolicies defined (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the documentation and create NetworkPolicy objects as you need them.\n        scored: false\n\n  - id: 5.4\n    text: \"Secrets Management\"\n    checks:\n      - id: 5.4.1\n        text: \"Prefer using Secrets as files over Secrets as environment variables (Manual)\"\n        type: \"manual\"\n        remediation: |\n          If possible, rewrite application code to read Secrets from mounted secret files, rather than\n          from environment variables.\n        scored: false\n\n      - id: 5.4.2\n        text: \"Consider external secret storage (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Refer to the Secrets management options offered by your cloud provider or a third-party\n          secrets management solution.\n        scored: false\n\n  - id: 5.5\n    text: \"Extensible Admission Control\"\n    checks:\n      - id: 5.5.1\n        text: \"Configure Image Provenance using ImagePolicyWebhook admission controller (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and setup image provenance.\n        scored: false\n\n  - id: 5.7\n    text: \"General Policies\"\n    checks:\n      - id: 5.7.1\n        text: \"Create administrative boundaries between resources using namespaces (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the documentation and create namespaces for objects in your deployment as you need\n          them.\n        scored: false\n\n      - id: 5.7.2\n        text: \"Ensure that the seccomp profile is set to docker/default in your Pod definitions (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Use `securityContext` to enable the docker/default seccomp profile in your pod definitions.\n          An example is as below:\n            securityContext:\n              seccompProfile:\n                type: RuntimeDefault\n        scored: false\n\n      - id: 5.7.3\n        text: \"Apply SecurityContext to your Pods and Containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and apply SecurityContexts to your Pods. For a\n          suggested list of SecurityContexts, you may refer to the CIS Security Benchmark for Docker\n          Containers.\n        scored: false\n\n      - id: 5.7.4\n        text: \"The default namespace should not be used (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that namespaces are created to allow for appropriate segregation of Kubernetes\n          resources and that all new resources are created in a specific namespace.\n        scored: false\n"
  },
  {
    "path": "cfg/rke2-cis-1.7/config.yaml",
    "content": "---\n## Version-specific settings that override the values in cfg/config.yaml\n"
  },
  {
    "path": "cfg/rke2-cis-1.7/controlplane.yaml",
    "content": "---\ncontrols:\nversion: \"rke2-cis-1.7\"\nid: 3\ntext: \"Control Plane Configuration\"\ntype: \"controlplane\"\ngroups:\n  - id: 3.1\n    text: \"Authentication and Authorization\"\n    checks:\n      - id: 3.1.1\n        text: \"Client certificate authentication should not be used for users (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Alternative mechanisms provided by Kubernetes such as the use of OIDC should be\n          implemented in place of client certificates.\n        scored: false\n      - id: 3.1.2\n        text: \"Service account token authentication should not be used for users (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Alternative mechanisms provided by Kubernetes such as the use of OIDC should be implemented\n          in place of service account tokens.\n        scored: false\n      - id: 3.1.3\n        text: \"Bootstrap token authentication should not be used for users (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Alternative mechanisms provided by Kubernetes such as the use of OIDC should be implemented\n          in place of bootstrap tokens.\n        scored: false\n\n  - id: 3.2\n    text: \"Logging\"\n    checks:\n      - id: 3.2.1\n        text: \"Ensure that a minimal audit policy is created (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-policy-file\"\n              set: true\n        remediation: |\n          Create an audit policy file for your cluster.\n          Permissive.\n        scored: true\n\n      - id: 3.2.2\n        text: \"Ensure that the audit policy covers key security concerns (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Review the audit policy provided for the cluster and ensure that it covers\n          at least the following areas,\n          - Access to Secrets managed by the cluster. Care should be taken to only\n            log Metadata for requests to Secrets, ConfigMaps, and TokenReviews, in\n            order to avoid risk of logging sensitive data.\n          - Modification of Pod and Deployment objects.\n          - Use of `pods/exec`, `pods/portforward`, `pods/proxy` and `services/proxy`.\n          For most requests, minimally logging at the Metadata level is recommended\n          (the most basic level of logging).\n        scored: false\n"
  },
  {
    "path": "cfg/rke2-cis-1.7/etcd.yaml",
    "content": "---\ncontrols:\nversion: \"rke2-cis-1.7\"\nid: 2\ntext: \"Etcd Node Configuration\"\ntype: \"etcd\"\ngroups:\n  - id: 2\n    text: \"Etcd Node Configuration\"\n    checks:\n      - id: 2.1\n        text: \"Ensure that the --cert-file and --key-file arguments are set as appropriate (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--cert-file\"\n              env: \"ETCD_CERT_FILE\"\n            - flag: \"--key-file\"\n              env: \"ETCD_KEY_FILE\"\n        remediation: |\n          Follow the etcd service documentation and configure TLS encryption.\n          Then, edit the etcd pod specification file /etc/kubernetes/manifests/etcd.yaml\n          on the master node and set the below parameters.\n          --cert-file=</path/to/ca-file>\n          --key-file=</path/to/key-file>\n          Not Applicable.\n        scored: true\n\n      - id: 2.2\n        text: \"Ensure that the --client-cert-auth argument is set to true (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--client-cert-auth\"\n              env: \"ETCD_CLIENT_CERT_AUTH\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and set the below parameter.\n          --client-cert-auth=\"true\"\n          Not Applicable.\n        scored: true\n\n      - id: 2.3\n        text: \"Ensure that the --auto-tls argument is not set to true (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--auto-tls\"\n              env: \"ETCD_AUTO_TLS\"\n              set: false\n            - flag: \"--auto-tls\"\n              env: \"ETCD_AUTO_TLS\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and either remove the --auto-tls parameter or set it to false.\n            --auto-tls=false\n        scored: true\n\n      - id: 2.4\n        text: \"Ensure that the --peer-cert-file and --peer-key-file arguments are\n        set as appropriate (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--peer-cert-file\"\n              env: \"ETCD_PEER_CERT_FILE\"\n              set: true\n            - flag: \"--peer-key-file\"\n              env: \"ETCD_PEER_KEY_FILE\"\n              set: true\n        remediation: |\n          Follow the etcd service documentation and configure peer TLS encryption as appropriate\n          for your etcd cluster.\n          Then, edit the etcd pod specification file $etcdconf on the\n          master node and set the below parameters.\n          --peer-client-file=</path/to/peer-cert-file>\n          --peer-key-file=</path/to/peer-key-file>\n          Not Applicable.\n        scored: true\n\n      - id: 2.5\n        text: \"Ensure that the --peer-client-cert-auth argument is set to true (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--peer-client-cert-auth\"\n              env: \"ETCD_PEER_CLIENT_CERT_AUTH\"\n              compare:\n                op: eq\n                value: true\n              set: true\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and set the below parameter.\n          --peer-client-cert-auth=true\n          Not Applicable.\n        scored: true\n\n      - id: 2.6\n        text: \"Ensure that the --peer-auto-tls argument is not set to true (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--peer-auto-tls\"\n              env: \"ETCD_PEER_AUTO_TLS\"\n              set: false\n            - flag: \"--peer-auto-tls\"\n              env: \"ETCD_PEER_AUTO_TLS\"\n              compare:\n                op: eq\n                value: false\n              set: true\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and either remove the --peer-auto-tls parameter or set it to false.\n          --peer-auto-tls=false\n        scored: true\n\n      - id: 2.7\n        text: \"Ensure that a unique Certificate Authority is used for etcd (Automated)\"\n        audit: \"/bin/ps -ef | /bin/grep $etcdbin | /bin/grep -v grep\"\n        audit_config: \"cat /var/lib/rancher/rke2/server/db/etcd/config\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--trusted-ca-file\"\n              env: \"ETCD_TRUSTED_CA_FILE\"\n            - path: \"{.peer-transport-security.trusted-ca-file}\"\n              compare:\n                op: eq\n                value: \"/var/lib/rancher/rke2/server/tls/etcd/peer-ca.crt\"\n              set: true\n        remediation: |\n          [Manual test]\n          Follow the etcd documentation and create a dedicated certificate authority setup for the\n          etcd service.\n          Then, edit the etcd pod specification file $etcdconf on the\n          master node and set the below parameter.\n          --trusted-ca-file=</path/to/ca-file>\n        scored: true\n"
  },
  {
    "path": "cfg/rke2-cis-1.7/master.yaml",
    "content": "---\ncontrols:\nversion: \"rke2-cis-1.7\"\nid: 1\ntext: \"Control Plane Security Configuration\"\ntype: \"master\"\ngroups:\n  - id: 1.1\n    text: \"Control Plane Node Configuration Files\"\n    checks:\n      - id: 1.1.1\n        text: \"Ensure that the API server pod specification file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"stat -c permissions=%a /var/lib/rancher/rke2/agent/pod-manifests/kube-apiserver.yaml\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the\n          control plane node.\n          For example, chmod 600 $apiserverconf\n        scored: true\n\n      - id: 1.1.2\n        text: \"Ensure that the API server pod specification file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $apiserverconf; then stat -c %U:%G $apiserverconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n              compare:\n                op: eq\n                value: \"root:root\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chown root:root $apiserverconf\n        scored: true\n\n      - id: 1.1.3\n        text: \"Ensure that the controller manager pod specification file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerconf; then stat -c permissions=%a $controllermanagerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chmod 600 $controllermanagerconf\n        scored: true\n\n      - id: 1.1.4\n        text: \"Ensure that the controller manager pod specification file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerconf; then stat -c %U:%G $controllermanagerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n              compare:\n                op: eq\n                value: \"root:root\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chown root:root $controllermanagerconf\n        scored: true\n\n      - id: 1.1.5\n        text: \"Ensure that the scheduler pod specification file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerconf; then stat -c permissions=%a $schedulerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chmod 600 $schedulerconf\n        scored: true\n\n      - id: 1.1.6\n        text: \"Ensure that the scheduler pod specification file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerconf; then stat -c %U:%G $schedulerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chown root:root $schedulerconf\n        scored: true\n\n      - id: 1.1.7\n        text: \"Ensure that the etcd pod specification file permissions are set to 600 or more restrictive (Automated)\"\n        audit: |\n          /bin/sh -c '\n            if [ -e \"$etcdconf\" ]; then\n              stat -c \"permissions=%a %n\" \"$etcdconf\"\n            else\n              echo \"Directory not found\"\n            fi\n          '\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n              set: true\n            - flag: \"Directory not found\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod 600 $etcdconf\n        scored: true\n\n      - id: 1.1.8\n        text: \"Ensure that the etcd pod specification file ownership is set to root:root (Automated)\"\n        audit: |\n          /bin/sh -c '\n            if [ -e $etcdconf ]; then\n              stat -c \"ownership=%U:%G %n\" $etcdconf\n            else\n              echo \"Directory not found\"\n            fi\n          '\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"ownership\"\n              compare:\n                op: eq\n                value: \"root:root\"\n              set: true\n            - flag: \"Directory not found\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root $etcdconf\n        scored: true\n\n      - id: 1.1.9\n        text: \"Ensure that the Container Network Interface file permissions are set to 600 or more restrictive (Manual)\"\n        audit: |\n          ps -fC ${kubeletbin:-kubelet} | grep -- --cni-conf-dir || echo \"/etc/cni/net.d\" | sed 's%.*cni-conf-dir[= ]\\([^ ]*\\).*%\\1%' | xargs -I{} find {} -mindepth 1 | xargs --no-run-if-empty stat -c permissions=%a\n          find /var/lib/cni/networks -type f 2> /dev/null | xargs --no-run-if-empty stat -c permissions=%a\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chmod 600 <path/to/cni/files>\n        scored: false\n\n      - id: 1.1.10\n        text: \"Ensure that the Container Network Interface file ownership is set to root:root (Manual)\"\n        audit: |\n          ps -fC ${kubeletbin:-kubelet} | grep -- --cni-conf-dir || echo \"/etc/cni/net.d\" | sed 's%.*cni-conf-dir[= ]\\([^ ]*\\).*%\\1%' | xargs -I{} find {} -mindepth 1 | xargs --no-run-if-empty stat -c %U:%G\n          find /var/lib/cni/networks -type f 2> /dev/null | xargs --no-run-if-empty stat -c %U:%G\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root <path/to/cni/files>\n        scored: false\n\n      - id: 1.1.11\n        text: \"Ensure that the etcd data directory permissions are set to 700 or more restrictive (Automated)\"\n        audit: |\n          /bin/sh -c 'if [ -d \"/var/lib/rancher/rke2/server/db/etcd\" ]; then\n            stat -c \"permissions=%a\" \"/var/lib/rancher/rke2/server/db/etcd\"\n          else\n            echo \"Directory not found\"\n          fi'\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"700\"\n              set: true\n            - flag: \"Directory not found\"\n              set: true\n        remediation: |\n          On the etcd server node, get the etcd data directory, passed as an argument --data-dir,\n          from the command 'ps -ef | grep etcd'.\n          Run the below command (based on the etcd data directory found above). For example,\n          chmod 700 /var/lib/etcd\n        scored: true\n\n      - id: 1.1.12\n        text: \"Ensure that the etcd data directory ownership is set to etcd:etcd (Automated)\"\n        type: \"skip\"\n        audit: \"stat -c %U:%G /var/lib/rancher/rke2/server/db/etcd\"\n        tests:\n          test_items:\n            - flag: \"etcd:etcd\"\n        remediation: |\n          On the etcd server node, get the etcd data directory, passed as an argument --data-dir,\n          from the command 'ps -ef | grep etcd'.\n          Run the below command (based on the etcd data directory found above).\n          For example, chown etcd:etcd /var/lib/etcd\n        scored: true\n\n      - id: 1.1.13\n        text: \"Ensure that the admin.conf file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"stat -c permissions=%a /var/lib/rancher/rke2/server/cred/admin.kubeconfig\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chmod 600 /etc/kubernetes/admin.conf\n        scored: true\n\n      - id: 1.1.14\n        text: \"Ensure that the admin.conf file ownership is set to root:root (Automated)\"\n        audit: \"stat -c %U:%G /var/lib/rancher/rke2/server/cred/admin.kubeconfig\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n              compare:\n                op: eq\n                value: \"root:root\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chown root:root /etc/kubernetes/admin.conf\n        scored: true\n\n      - id: 1.1.15\n        text: \"Ensure that the scheduler.conf file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerkubeconfig; then stat -c permissions=%a $schedulerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"600\"\n              compare:\n                op: eq\n                value: \"600\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod 600 $schedulerkubeconfig\n        scored: true\n\n      - id: 1.1.16\n        text: \"Ensure that the scheduler.conf file ownership is set to root:root (Automated)\"\n        audit: \"stat -c %U:%G $schedulerkubeconfig\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n              compare:\n                op: eq\n                value: \"root:root\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root $schedulerkubeconfig\n        scored: true\n\n      - id: 1.1.17\n        text: \"Ensure that the controller-manager.conf file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerkubeconfig; then stat -c permissions=%a $controllermanagerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"600\"\n              compare:\n                op: eq\n                value: \"600\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod 600 $controllermanagerkubeconfig\n        scored: true\n\n      - id: 1.1.18\n        text: \"Ensure that the controller-manager.conf file ownership is set to root:root (Automated)\"\n        audit: \"stat -c %U:%G $controllermanagerkubeconfig\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n              compare:\n                op: eq\n                value: \"root:root\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root $controllermanagerkubeconfig\n        scored: true\n\n      - id: 1.1.19\n        text: \"Ensure that the Kubernetes PKI directory and file ownership is set to root:root (Automated)\"\n        audit: \"stat -c %U:%G /var/lib/rancher/rke2/server/tls\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n              compare:\n                op: eq\n                value: \"root:root\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown -R root:root /etc/kubernetes/pki/\n        scored: true\n\n      - id: 1.1.20\n        text: \"Ensure that the Kubernetes PKI certificate file permissions are set to 600 or more restrictive (Manual)\"\n        audit: \"stat -c permissions=%a /var/lib/rancher/rke2/server/tls/*.crt\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod -R 600 /var/lib/rancher/rke2/server/tls/*.crt\n        scored: false\n\n      - id: 1.1.21\n        text: \"Ensure that the Kubernetes PKI key file permissions are set to 600 (Manual)\"\n        audit: \"stat -c permissions=%a /var/lib/rancher/rke2/server/tls/*.key\"\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod -R 600 /var/lib/rancher/rke2/server/tls/*.key\n        scored: false\n\n  - id: 1.2\n    text: \"API Server\"\n    checks:\n      - id: 1.2.1\n        text: \"Ensure that the --anonymous-auth argument is set to false (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        type: manual\n        tests:\n          test_items:\n            - flag: \"--anonymous-auth\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the below parameter.\n          --anonymous-auth=false\n        scored: false\n\n      - id: 1.2.2\n        text: \"Ensure that the --token-auth-file parameter is not set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--token-auth-file\"\n              set: false\n        remediation: |\n          Follow the documentation and configure alternate mechanisms for authentication. Then,\n          edit the API server pod specification file $apiserverconf\n          on the control plane node and remove the --token-auth-file=<filename> parameter.\n        scored: true\n\n      - id: 1.2.3\n        text: \"Ensure that the --DenyServiceExternalIPs is not set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: nothave\n                value: \"DenyServiceExternalIPs\"\n              set: true\n            - flag: \"--enable-admission-plugins\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and remove the `DenyServiceExternalIPs`\n          from enabled admission plugins.\n        scored: true\n\n      - id: 1.2.4\n        text: \"Ensure that the --kubelet-client-certificate and --kubelet-client-key arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--kubelet-client-certificate\"\n              set: true\n            - flag: \"--kubelet-client-key\"\n              set: true\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection between the\n          apiserver and kubelets. Then, edit API server pod specification file\n          $apiserverconf on the control plane node and set the\n          kubelet client certificate and key parameters as below.\n          --kubelet-client-certificate=<path/to/client-certificate-file>\n          --kubelet-client-key=<path/to/client-key-file>\n        scored: true\n\n      - id: 1.2.5\n        text: \"Ensure that the --kubelet-certificate-authority argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--kubelet-certificate-authority\"\n              set: true\n        remediation: |\n          Follow the Kubernetes documentation and setup the TLS connection between\n          the apiserver and kubelets. Then, edit the API server pod specification file\n          $apiserverconf on the control plane node and set the\n          --kubelet-certificate-authority parameter to the path to the cert file for the certificate authority.\n          --kubelet-certificate-authority=<ca-string>\n        scored: true\n\n      - id: 1.2.6\n        text: \"Ensure that the --authorization-mode argument is not set to AlwaysAllow (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: nothave\n                value: \"AlwaysAllow\"\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --authorization-mode parameter to values other than AlwaysAllow.\n          One such example could be as below.\n          --authorization-mode=RBAC\n        scored: true\n\n      - id: 1.2.7\n        text: \"Ensure that the --authorization-mode argument includes Node (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: has\n                value: \"Node\"\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --authorization-mode parameter to a value that includes Node.\n          --authorization-mode=Node,RBAC\n        scored: true\n\n      - id: 1.2.8\n        text: \"Ensure that the --authorization-mode argument includes RBAC (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: has\n                value: \"RBAC\"\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --authorization-mode parameter to a value that includes RBAC,\n          for example `--authorization-mode=Node,RBAC`.\n        scored: true\n\n      - id: 1.2.9\n        text: \"Ensure that the admission control plugin EventRateLimit is set (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"EventRateLimit\"\n              set: true\n        remediation: |\n          Follow the Kubernetes documentation and set the desired limits in a configuration file.\n          Then, edit the API server pod specification file $apiserverconf\n          and set the below parameters.\n          --enable-admission-plugins=...,EventRateLimit,...\n          --admission-control-config-file=<path/to/configuration/file>\n        scored: false\n\n      - id: 1.2.10\n        text: \"Ensure that the admission control plugin AlwaysAdmit is not set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: nothave\n                value: AlwaysAdmit\n              set: true\n            - flag: \"--enable-admission-plugins\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and either remove the --enable-admission-plugins parameter, or set it to a\n          value that does not include AlwaysAdmit.\n        scored: true\n\n      - id: 1.2.11\n        text: \"Ensure that the admission control plugin AlwaysPullImages is set (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"AlwaysPullImages\"\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --enable-admission-plugins parameter to include\n          AlwaysPullImages.\n          --enable-admission-plugins=...,AlwaysPullImages,...\n        scored: false\n\n      - id: 1.2.12\n        text: \"Ensure that the admission control plugin SecurityContextDeny is set if PodSecurityPolicy is not used (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"SecurityContextDeny\"\n              set: true\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"PodSecurityPolicy\"\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --enable-admission-plugins parameter to include\n          SecurityContextDeny, unless PodSecurityPolicy is already in place.\n          --enable-admission-plugins=...,SecurityContextDeny,...\n        scored: false\n\n      - id: 1.2.13\n        text: \"Ensure that the admission control plugin ServiceAccount is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--disable-admission-plugins\"\n              compare:\n                op: nothave\n                value: \"ServiceAccount\"\n            - flag: \"--disable-admission-plugins\"\n              set: false\n        remediation: |\n          Follow the documentation and create ServiceAccount objects as per your environment.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and ensure that the --disable-admission-plugins parameter is set to a\n          value that does not include ServiceAccount.\n        scored: true\n\n      - id: 1.2.14\n        text: \"Ensure that the admission control plugin NamespaceLifecycle is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--disable-admission-plugins\"\n              compare:\n                op: nothave\n                value: \"NamespaceLifecycle\"\n            - flag: \"--disable-admission-plugins\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --disable-admission-plugins parameter to\n          ensure it does not include NamespaceLifecycle.\n        scored: true\n\n      - id: 1.2.15\n        text: \"Ensure that the admission control plugin NodeRestriction is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"NodeRestriction\"\n              set: true\n        remediation: |\n          Follow the Kubernetes documentation and configure NodeRestriction plug-in on kubelets.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --enable-admission-plugins parameter to a\n          value that includes NodeRestriction.\n          --enable-admission-plugins=...,NodeRestriction,...\n        scored: true\n\n      - id: 1.2.16\n        text: \"Ensure that the --secure-port argument is not set to 0 - NoteThis recommendation is obsolete and will be deleted per the consensus process (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--secure-port\"\n              compare:\n                op: gt\n                value: 0\n              set: true\n            - flag: \"--secure-port\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and either remove the --secure-port parameter or\n          set it to a different (non-zero) desired port.\n        scored: true\n\n      - id: 1.2.17\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the below parameter.\n          --profiling=false\n        scored: true\n\n      - id: 1.2.18\n        text: \"Ensure that the --audit-log-path argument is set (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-path\"\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --audit-log-path parameter to a suitable path and\n          file where you would like audit logs to be written, for example,\n          --audit-log-path=/var/log/apiserver/audit.log\n          Permissive.\n        scored: true\n\n      - id: 1.2.19\n        text: \"Ensure that the --audit-log-maxage argument is set to 30 or as appropriate (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxage\"\n              compare:\n                op: gte\n                value: 30\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --audit-log-maxage parameter to 30\n          or as an appropriate number of days, for example,\n          --audit-log-maxage=30\n          Permissive.\n        scored: true\n\n      - id: 1.2.20\n        text: \"Ensure that the --audit-log-maxbackup argument is set to 10 or as appropriate (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxbackup\"\n              compare:\n                op: gte\n                value: 10\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --audit-log-maxbackup parameter to 10 or to an appropriate\n          value. For example,\n          --audit-log-maxbackup=10\n          Permissive.\n        scored: true\n\n      - id: 1.2.21\n        text: \"Ensure that the --audit-log-maxsize argument is set to 100 or as appropriate (Automated)\"\n        type: \"skip\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxsize\"\n              compare:\n                op: gte\n                value: 100\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --audit-log-maxsize parameter to an appropriate size in MB.\n          For example, to set it as 100 MB, --audit-log-maxsize=100\n        scored: true\n\n      - id: 1.2.22\n        text: \"Ensure that the --request-timeout argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--request-timeout\"\n              set: false\n            - flag: \"--request-timeout\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          and set the below parameter as appropriate and if needed.\n          For example, --request-timeout=300s\n        scored: true\n\n      - id: 1.2.23\n        text: \"Ensure that the --service-account-lookup argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--service-account-lookup\"\n              set: false\n            - flag: \"--service-account-lookup\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the below parameter.\n          --service-account-lookup=true\n          Alternatively, you can delete the --service-account-lookup parameter from this file so\n          that the default takes effect.\n        scored: true\n\n      - id: 1.2.24\n        text: \"Ensure that the --service-account-key-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--service-account-key-file\"\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --service-account-key-file parameter\n          to the public key file for service accounts. For example,\n          --service-account-key-file=<filename>\n        scored: true\n\n      - id: 1.2.25\n        text: \"Ensure that the --etcd-certfile and --etcd-keyfile arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--etcd-certfile\"\n              set: true\n            - flag: \"--etcd-keyfile\"\n              set: true\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection between the apiserver and etcd.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the etcd certificate and key file parameters.\n          --etcd-certfile=<path/to/client-certificate-file>\n          --etcd-keyfile=<path/to/client-key-file>\n        scored: true\n\n      - id: 1.2.26\n        text: \"Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--tls-cert-file\"\n              set: true\n            - flag: \"--tls-private-key-file\"\n              set: true\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection on the apiserver.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the TLS certificate and private key file parameters.\n          --tls-cert-file=<path/to/tls-certificate-file>\n          --tls-private-key-file=<path/to/tls-key-file>\n        scored: true\n\n      - id: 1.2.27\n        text: \"Ensure that the --client-ca-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--client-ca-file\"\n              set: true\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection on the apiserver.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the client certificate authority file.\n          --client-ca-file=<path/to/client-ca-file>\n        scored: true\n\n      - id: 1.2.28\n        text: \"Ensure that the --etcd-cafile argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--etcd-cafile\"\n              set: true\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection between the apiserver and etcd.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the etcd certificate authority file parameter.\n          --etcd-cafile=<path/to/ca-file>\n        scored: true\n\n      - id: 1.2.29\n        text: \"Ensure that the --encryption-provider-config argument is set as appropriate (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--encryption-provider-config\"\n        remediation: |\n          Follow the Kubernetes documentation and configure a EncryptionConfig file.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --encryption-provider-config parameter to the path of that file.\n          For example, --encryption-provider-config=</path/to/EncryptionConfig/File>\n        scored: false\n\n      - id: 1.2.30\n        text: \"Ensure that encryption providers are appropriately configured (Manual)\"\n        type: \"skip\"\n        audit: |\n          ENCRYPTION_PROVIDER_CONFIG=$(ps -ef | grep $apiserverbin | grep -- --encryption-provider-config | sed 's%.*encryption-provider-config[= ]\\([^ ]*\\).*%\\1%')\n          if test -e $ENCRYPTION_PROVIDER_CONFIG; then grep -A1 'providers:' $ENCRYPTION_PROVIDER_CONFIG | tail -n1 | grep -o \"[A-Za-z]*\" | sed 's/^/provider=/'; fi\n        tests:\n          test_items:\n            - flag: \"provider\"\n              compare:\n                op: valid_elements\n                value: \"aescbc,kms,secretbox\"\n        remediation: |\n          Follow the Kubernetes documentation and configure a EncryptionConfig file.\n          In this file, choose aescbc, kms or secretbox as the encryption provider.\n          Permissive.\n        scored: false\n\n      - id: 1.2.31\n        text: \"Ensure that the API Server only makes use of Strong Cryptographic Ciphers (Manual)\"\n        type: skip\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--tls-cipher-suites\"\n              compare:\n                op: valid_elements\n                value: \"TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,TLS_CHACHA20_POLY1305_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,TLS_RSA_WITH_3DES_EDE_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_256_GCM_SHA384\"\n        remediation: |\n          Edit the API server pod specification file /etc/kubernetes/manifests/kube-apiserver.yaml\n          on the control plane node and set the below parameter.\n          --tls-cipher-suites=TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,TLS_CHACHA20_POLY1305_SHA256,\n          TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,\n          TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,\n          TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,\n          TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,\n          TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,\n          TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,TLS_RSA_WITH_3DES_EDE_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA,\n          TLS_RSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_256_GCM_SHA384\n          Not Applicable.\n        scored: false\n\n\n  - id: 1.3\n    text: \"Controller Manager\"\n    checks:\n      - id: 1.3.1\n        text: \"Ensure that the --terminated-pod-gc-threshold argument is set as appropriate (Manual)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--terminated-pod-gc-threshold\"\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the --terminated-pod-gc-threshold to an appropriate threshold,\n          for example, --terminated-pod-gc-threshold=10\n        scored: false\n\n      - id: 1.3.2\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n              set: true\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the below parameter.\n          --profiling=false\n        scored: true\n\n      - id: 1.3.3\n        text: \"Ensure that the --use-service-account-credentials argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--use-service-account-credentials\"\n              compare:\n                op: noteq\n                value: false\n              set: true\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node to set the below parameter.\n          --use-service-account-credentials=true\n        scored: true\n\n      - id: 1.3.4\n        text: \"Ensure that the --service-account-private-key-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--service-account-private-key-file\"\n              set: true\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the --service-account-private-key-file parameter\n          to the private key file for service accounts.\n          --service-account-private-key-file=<filename>\n        scored: true\n\n      - id: 1.3.5\n        text: \"Ensure that the --root-ca-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--root-ca-file\"\n              set: true\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the --root-ca-file parameter to the certificate bundle file`.\n          --root-ca-file=<path/to/file>\n        scored: true\n\n      - id: 1.3.6\n        text: \"Ensure that the RotateKubeletServerCertificate argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--feature-gates\"\n              compare:\n                op: nothave\n                value: \"RotateKubeletServerCertificate=false\"\n              set: true\n            - flag: \"--feature-gates\"\n              set: false\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the --feature-gates parameter to include RotateKubeletServerCertificate=true.\n          --feature-gates=RotateKubeletServerCertificate=true\n        scored: true\n        type: skip\n\n      - id: 1.3.7\n        text: \"Ensure that the --bind-address argument is set to 127.0.0.1 (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--bind-address\"\n              compare:\n                op: eq\n                value: \"127.0.0.1\"\n              set: true\n            - flag: \"--bind-address\"\n              set: false\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and ensure the correct value for the --bind-address parameter\n        scored: true\n\n  - id: 1.4\n    text: \"Scheduler\"\n    checks:\n      - id: 1.4.1\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: \"/bin/ps -ef | grep $schedulerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n              set: true\n        remediation: |\n          Edit the Scheduler pod specification file $schedulerconf file\n          on the control plane node and set the below parameter.\n          --profiling=false\n        scored: true\n\n      - id: 1.4.2\n        text: \"Ensure that the --bind-address argument is set to 127.0.0.1 (Automated)\"\n        audit: \"/bin/ps -ef | grep $schedulerbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--bind-address\"\n              compare:\n                op: eq\n                value: \"127.0.0.1\"\n              set: true\n            - flag: \"--bind-address\"\n              set: false\n        remediation: |\n          Edit the Scheduler pod specification file $schedulerconf\n          on the control plane node and ensure the correct value for the --bind-address parameter\n        scored: true\n"
  },
  {
    "path": "cfg/rke2-cis-1.7/node.yaml",
    "content": "---\ncontrols:\nversion: \"rke2-cis-1.7\"\nid: 4\ntext: \"Worker Node Security Configuration\"\ntype: \"node\"\ngroups:\n  - id: 4.1\n    text: \"Worker Node Configuration Files\"\n    checks:\n      - id: 4.1.1\n        text: \"Ensure that the kubelet service file permissions are set to 600 or more restrictive (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletsvc; then stat -c permissions=%a $kubeletsvc; fi'' '\n        type: \"skip\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example, chmod 600 $kubeletsvc\n          Not Applicable.\n        scored: true\n\n      - id: 4.1.2\n        text: \"Ensure that the kubelet service file ownership is set to root:root (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletsvc; then stat -c %U:%G $kubeletsvc; fi'' '\n        type: \"skip\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chown root:root $kubeletsvc\n          Not applicable.\n        scored: true\n\n      - id: 4.1.3\n        text: \"If proxy kubeconfig file exists ensure permissions are set to 600 or more restrictive (Manual)\"\n        audit: '/bin/sh -c ''if test -e $proxykubeconfig; then stat -c permissions=%a $proxykubeconfig; fi'' '\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chmod 600 $proxykubeconfig\n        scored: false\n\n      - id: 4.1.4\n        text: \"If proxy kubeconfig file exists ensure ownership is set to root:root (Manual)\"\n        audit: '/bin/sh -c ''if test -e $proxykubeconfig; then stat -c %U:%G $proxykubeconfig; fi'' '\n        tests:\n          bin_op: or\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example, chown root:root $proxykubeconfig\n        scored: false\n\n      - id: 4.1.5\n        text: \"Ensure that the --kubeconfig kubelet.conf file permissions are set to 600 or more restrictive (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletkubeconfig; then stat -c permissions=%a $kubeletkubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chmod 600 $kubeletkubeconfig\n        scored: true\n\n      - id: 4.1.6\n        text: \"Ensure that the --kubeconfig kubelet.conf file ownership is set to root:root (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletkubeconfig; then stat -c %U:%G $kubeletkubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: root:root\n              set: true\n              compare:\n                op: eq\n                value: root:root\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chown root:root $kubeletkubeconfig\n        scored: true\n\n      - id: 4.1.7\n        text: \"Ensure that the certificate authorities file permissions are set to 600 or more restrictive (Manual)\"\n        audit: \"check_cafile_permissions.sh\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n              set: true\n        remediation: |\n          Run the following command to modify the file permissions of the\n          --client-ca-file chmod 600 <filename>\n        scored: false\n\n      - id: 4.1.8\n        text: \"Ensure that the client certificate authorities file ownership is set to root:root (Manual)\"\n        audit: \"check_cafile_ownership.sh\"\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the following command to modify the ownership of the --client-ca-file.\n          chown root:root <filename>\n        scored: false\n\n      - id: 4.1.9\n        text: \"If the kubelet config.yaml configuration file is being used validate permissions set to 600 or more restrictive (Automated)\"\n        audit: |\n          /bin/sh -c 'if test -e \"$kubeletconf\"; then\n             stat -c \"permissions=%a\" \"$kubeletconf\"\n           else\n             echo \"File not found\"\n           fi'\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n              set: true\n            - flag: \"File not found\"\n        remediation: |\n          Run the following command (using the config file location identified in the Audit step)\n          chmod 600 $kubeletconf\n        scored: true\n\n      - id: 4.1.10\n        text: \"If the kubelet config.yaml configuration file is being used validate file ownership is set to root:root (Automated)\"\n        audit: |\n          /bin/sh -c 'if test -e \"$kubeletconf\"; then\n             stat -c \"%U:%G\" \"$kubeletconf\"\n          else\n             echo \"File not found\"\n          fi'\n        tests:\n          bin_op: or\n          test_items:\n            - flag: root:root\n              set: true\n            - flag: \"File not found\"\n        remediation: |\n          Run the following command (using the config file location identified in the Audit step)\n          chown root:root $kubeletconf\n        scored: true\n\n  - id: 4.2\n    text: \"Kubelet\"\n    checks:\n      - id: 4.2.1\n        text: \"Ensure that the --anonymous-auth argument is set to false (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: \"--anonymous-auth\"\n              path: '{.authentication.anonymous.enabled}'\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          If using a Kubelet config file, edit the file to set `authentication: anonymous: enabled` to\n          `false`.\n          If using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          `--anonymous-auth=false`\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.2\n        text: \"Ensure that the --authorization-mode argument is not set to AlwaysAllow (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --authorization-mode\n              path: '{.authorization.mode}'\n              compare:\n                op: nothave\n                value: AlwaysAllow\n        remediation: |\n          If using a Kubelet config file, edit the file to set `authorization.mode` to Webhook. If\n          using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_AUTHZ_ARGS variable.\n          --authorization-mode=Webhook\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.3\n        text: \"Ensure that the --client-ca-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --client-ca-file\n              path: '{.authentication.x509.clientCAFile}'\n        remediation: |\n          If using a Kubelet config file, edit the file to set `authentication.x509.clientCAFile` to\n          the location of the client CA file.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_AUTHZ_ARGS variable.\n          --client-ca-file=<path/to/client-ca-file>\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.4\n        text: \"Verify that the --read-only-port argument is set to 0 (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--read-only-port\"\n              path: '{.readOnlyPort}'\n              compare:\n                op: eq\n                value: 0\n            - flag: \"--read-only-port\"\n              path: '{.readOnlyPort}'\n              set: false\n        remediation: |\n          If using a Kubelet config file, edit the file to set `readOnlyPort` to 0.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --read-only-port=0\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.5\n        text: \"Ensure that the --streaming-connection-idle-timeout argument is not set to 0 (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --streaming-connection-idle-timeout\n              path: '{.streamingConnectionIdleTimeout}'\n              compare:\n                op: noteq\n                value: 0\n            - flag: --streaming-connection-idle-timeout\n              path: '{.streamingConnectionIdleTimeout}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to set `streamingConnectionIdleTimeout` to a\n          value other than 0.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --streaming-connection-idle-timeout=5m\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.6\n        text: \"Ensure that the --make-iptables-util-chains argument is set to true (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --make-iptables-util-chains\n              path: '{.makeIPTablesUtilChains}'\n              compare:\n                op: eq\n                value: true\n            - flag: --make-iptables-util-chains\n              path: '{.makeIPTablesUtilChains}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to set `makeIPTablesUtilChains` to `true`.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          remove the --make-iptables-util-chains argument from the\n          KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.7\n        text: \"Ensure that the --hostname-override argument is not set (Manual)\"\n        # This is one of those properties that can only be set as a command line argument.\n        # To check if the property is set as expected, we need to parse the kubelet command\n        # instead reading the Kubelet Configuration file.\n        audit: \"/bin/ps -fC $kubeletbin \"\n        type: skip\n        tests:\n          test_items:\n            - flag: --hostname-override\n              set: false\n        remediation: |\n          Edit the kubelet service file $kubeletsvc\n          on each worker node and remove the --hostname-override argument from the\n          KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n          Not Applicable.\n        scored: false\n\n      - id: 4.2.8\n        text: \"Ensure that the eventRecordQPS argument is set to a level which ensures appropriate event capture (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --event-qps\n              path: '{.eventRecordQPS}'\n              compare:\n                op: gte\n                value: 0\n            - flag: --event-qps\n              path: '{.eventRecordQPS}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to set `eventRecordQPS` to an appropriate level.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.9\n        text: \"Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --tls-cert-file\n              path: '{.tlsCertFile}'\n            - flag: --tls-private-key-file\n              path: '{.tlsPrivateKeyFile}'\n        remediation: |\n          If using a Kubelet config file, edit the file to set `tlsCertFile` to the location\n          of the certificate file to use to identify this Kubelet, and `tlsPrivateKeyFile`\n          to the location of the corresponding private key file.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameters in KUBELET_CERTIFICATE_ARGS variable.\n          --tls-cert-file=<path/to/tls-certificate-file>\n          --tls-private-key-file=<path/to/tls-key-file>\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.10\n        text: \"Ensure that the --rotate-certificates argument is not set to false (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --rotate-certificates\n              path: '{.rotateCertificates}'\n              compare:\n                op: eq\n                value: true\n            - flag: --rotate-certificates\n              path: '{.rotateCertificates}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to add the line `rotateCertificates` to `true` or\n          remove it altogether to use the default value.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          remove --rotate-certificates=false argument from the KUBELET_CERTIFICATE_ARGS\n          variable.\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.11\n        text: \"Verify that the RotateKubeletServerCertificate argument is set to true (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: RotateKubeletServerCertificate\n              path: '{.featureGates.RotateKubeletServerCertificate}'\n              compare:\n                op: nothave\n                value: false\n            - flag: RotateKubeletServerCertificate\n              path: '{.featureGates.RotateKubeletServerCertificate}'\n              set: false\n        remediation: |\n          Edit the kubelet service file $kubeletsvc\n          on each worker node and set the below parameter in KUBELET_CERTIFICATE_ARGS variable.\n          --feature-gates=RotateKubeletServerCertificate=true\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.12\n        text: \"Ensure that the Kubelet only makes use of Strong Cryptographic Ciphers (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --tls-cipher-suites\n              path: '{range .tlsCipherSuites[:]}{}{'',''}{end}'\n              compare:\n                op: valid_elements\n                value: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\n        remediation: |\n          If using a Kubelet config file, edit the file to set `tlsCipherSuites` to\n          TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\n          or to a subset of these values.\n          If using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the --tls-cipher-suites parameter as follows, or to a subset of these values.\n          --tls-cipher-suites=TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.13\n        text: \"Ensure that a limit is set on pod PIDs (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/cat $kubeletconf\"\n        tests:\n          test_items:\n            - flag: --pod-max-pids\n              path: '{.podPidsLimit}'\n        remediation: |\n          Decide on an appropriate level for this parameter and set it,\n          either via the --pod-max-pids command line parameter or the PodPidsLimit configuration file setting.\n        scored: false\n"
  },
  {
    "path": "cfg/rke2-cis-1.7/policies.yaml",
    "content": "---\ncontrols:\nversion: \"rke2-cis-1.7\"\nid: 5\ntext: \"Kubernetes Policies\"\ntype: \"policies\"\ngroups:\n  - id: 5.1\n    text: \"RBAC and Service Accounts\"\n    checks:\n      - id: 5.1.1\n        text: \"Ensure that the cluster-admin role is only used where required (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Identify all clusterrolebindings to the cluster-admin role. Check if they are used and\n          if they need this role or if they could use a role with fewer privileges.\n          Where possible, first bind users to a lower privileged role and then remove the\n          clusterrolebinding to the cluster-admin role :\n          kubectl delete clusterrolebinding [name]\n        scored: false\n\n      - id: 5.1.2\n        text: \"Minimize access to secrets (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove get, list and watch access to Secret objects in the cluster.\n        scored: false\n\n      - id: 5.1.3\n        text: \"Minimize wildcard use in Roles and ClusterRoles (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible replace any use of wildcards in clusterroles and roles with specific\n          objects or actions.\n        scored: false\n\n      - id: 5.1.4\n        text: \"Minimize access to create pods (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove create access to pod objects in the cluster.\n        scored: false\n\n      - id: 5.1.5\n        text: \"Ensure that default service accounts are not actively used. (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Create explicit service accounts wherever a Kubernetes workload requires specific access\n          to the Kubernetes API server.\n          Modify the configuration of each default service account to include this value\n          automountServiceAccountToken: false\n        scored: false\n\n      - id: 5.1.6\n        text: \"Ensure that Service Account Tokens are only mounted where necessary (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Modify the definition of pods and service accounts which do not need to mount service\n          account tokens to disable it.\n        scored: false\n\n      - id: 5.1.7\n        text: \"Avoid use of system:masters group (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Remove the system:masters group from all users in the cluster.\n        scored: false\n\n      - id: 5.1.8\n        text: \"Limit use of the Bind, Impersonate and Escalate permissions in the Kubernetes cluster (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove the impersonate, bind and escalate rights from subjects.\n        scored: false\n\n      - id: 5.1.9\n        text: \"Minimize access to create persistent volumes (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove create access to PersistentVolume objects in the cluster.\n        scored: false\n\n      - id: 5.1.10\n        text: \"Minimize access to the proxy sub-resource of nodes (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove access to the proxy sub-resource of node objects.\n        scored: false\n\n      - id: 5.1.11\n        text: \"Minimize access to the approval sub-resource of certificatesigningrequests objects (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove access to the approval sub-resource of certificatesigningrequest objects.\n        scored: false\n\n      - id: 5.1.12\n        text: \"Minimize access to webhook configuration objects (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove access to the validatingwebhookconfigurations or mutatingwebhookconfigurations objects\n        scored: false\n\n      - id: 5.1.13\n        text: \"Minimize access to the service account token creation (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove access to the token sub-resource of serviceaccount objects.\n        scored: false\n\n  - id: 5.2\n    text: \"Pod Security Standards\"\n    checks:\n      - id: 5.2.1\n        text: \"Ensure that the cluster has at least one active policy control mechanism in place (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that either Pod Security Admission or an external policy control system is in place\n          for every namespace which contains user workloads.\n        scored: false\n\n      - id: 5.2.2\n        text: \"Minimize the admission of privileged containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of privileged containers.\n        scored: false\n\n      - id: 5.2.3\n        text: \"Minimize the admission of containers wishing to share the host process ID namespace (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of `hostPID` containers.\n        scored: false\n\n      - id: 5.2.4\n        text: \"Minimize the admission of containers wishing to share the host IPC namespace (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of `hostIPC` containers.\n        scored: false\n\n      - id: 5.2.5\n        text: \"Minimize the admission of containers wishing to share the host network namespace (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of `hostNetwork` containers.\n        scored: false\n\n      - id: 5.2.6\n        text: \"Minimize the admission of containers with allowPrivilegeEscalation (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers with `.spec.allowPrivilegeEscalation` set to `true`.\n        scored: false\n\n      - id: 5.2.7\n        text: \"Minimize the admission of root containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Create a policy for each namespace in the cluster, ensuring that either `MustRunAsNonRoot`\n          or `MustRunAs` with the range of UIDs not including 0, is set.\n        scored: false\n\n      - id: 5.2.8\n        text: \"Minimize the admission of containers with the NET_RAW capability (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers with the `NET_RAW` capability.\n        scored: false\n\n      - id: 5.2.9\n        text: \"Minimize the admission of containers with added capabilities (Automated)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that `allowedCapabilities` is not present in policies for the cluster unless\n          it is set to an empty array.\n        scored: false\n\n      - id: 5.2.10\n        text: \"Minimize the admission of containers with capabilities assigned (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Review the use of capabilites in applications running on your cluster. Where a namespace\n          contains applications which do not require any Linux capabities to operate consider adding\n          a PSP which forbids the admission of containers which do not drop all capabilities.\n        scored: false\n\n      - id: 5.2.11\n        text: \"Minimize the admission of Windows HostProcess containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers that have `.securityContext.windowsOptions.hostProcess` set to `true`.\n        scored: false\n\n      - id: 5.2.12\n        text: \"Minimize the admission of HostPath volumes (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers with `hostPath` volumes.\n        scored: false\n\n      - id: 5.2.13\n        text: \"Minimize the admission of containers which use HostPorts (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers which use `hostPort` sections.\n        scored: false\n\n  - id: 5.3\n    text: \"Network Policies and CNI\"\n    checks:\n      - id: 5.3.1\n        text: \"Ensure that the CNI in use supports NetworkPolicies (Manual)\"\n        type: \"manual\"\n        remediation: |\n          If the CNI plugin in use does not support network policies, consideration should be given to\n          making use of a different plugin, or finding an alternate mechanism for restricting traffic\n          in the Kubernetes cluster.\n        scored: false\n\n      - id: 5.3.2\n        text: \"Ensure that all Namespaces have NetworkPolicies defined (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the documentation and create NetworkPolicy objects as you need them.\n        scored: false\n\n  - id: 5.4\n    text: \"Secrets Management\"\n    checks:\n      - id: 5.4.1\n        text: \"Prefer using Secrets as files over Secrets as environment variables (Manual)\"\n        type: \"manual\"\n        remediation: |\n          If possible, rewrite application code to read Secrets from mounted secret files, rather than\n          from environment variables.\n        scored: false\n\n      - id: 5.4.2\n        text: \"Consider external secret storage (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Refer to the Secrets management options offered by your cloud provider or a third-party\n          secrets management solution.\n        scored: false\n\n  - id: 5.5\n    text: \"Extensible Admission Control\"\n    checks:\n      - id: 5.5.1\n        text: \"Configure Image Provenance using ImagePolicyWebhook admission controller (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and setup image provenance.\n        scored: false\n\n  - id: 5.7\n    text: \"General Policies\"\n    checks:\n      - id: 5.7.1\n        text: \"Create administrative boundaries between resources using namespaces (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the documentation and create namespaces for objects in your deployment as you need\n          them.\n        scored: false\n\n      - id: 5.7.2\n        text: \"Ensure that the seccomp profile is set to docker/default in your Pod definitions (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Use `securityContext` to enable the docker/default seccomp profile in your pod definitions.\n          An example is as below:\n            securityContext:\n              seccompProfile:\n                type: RuntimeDefault\n        scored: false\n\n      - id: 5.7.3\n        text: \"Apply SecurityContext to your Pods and Containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and apply SecurityContexts to your Pods. For a\n          suggested list of SecurityContexts, you may refer to the CIS Security Benchmark for Docker\n          Containers.\n        scored: false\n\n      - id: 5.7.4\n        text: \"The default namespace should not be used (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that namespaces are created to allow for appropriate segregation of Kubernetes\n          resources and that all new resources are created in a specific namespace.\n        scored: false\n"
  },
  {
    "path": "cfg/rke2-cis-1.8/config.yaml",
    "content": "---\n## Version-specific settings that override the values in cfg/config.yaml\n"
  },
  {
    "path": "cfg/rke2-cis-1.8/controlplane.yaml",
    "content": "---\ncontrols:\nversion: \"rke2-cis-1.8\"\nid: 3\ntext: \"Control Plane Configuration\"\ntype: \"controlplane\"\ngroups:\n  - id: 3.1\n    text: \"Authentication and Authorization\"\n    checks:\n      - id: 3.1.1\n        text: \"Client certificate authentication should not be used for users (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Alternative mechanisms provided by Kubernetes such as the use of OIDC should be\n          implemented in place of client certificates.\n        scored: false\n\n      - id: 3.1.2\n        text: \"Service account token authentication should not be used for users (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Alternative mechanisms provided by Kubernetes such as the use of OIDC should be implemented\n          in place of service account tokens.\n        scored: false\n\n      - id: 3.1.3\n        text: \"Bootstrap token authentication should not be used for users (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Alternative mechanisms provided by Kubernetes such as the use of OIDC should be implemented\n          in place of bootstrap tokens.\n        scored: false\n\n  - id: 3.2\n    text: \"Logging\"\n    checks:\n      - id: 3.2.1\n        text: \"Ensure that a minimal audit policy is created (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-policy-file\"\n              set: true\n        remediation: |\n          Create an audit policy file for your cluster.\n        scored: true\n\n      - id: 3.2.2\n        text: \"Ensure that the audit policy covers key security concerns (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Review the audit policy provided for the cluster and ensure that it covers\n          at least the following areas,\n          - Access to Secrets managed by the cluster. Care should be taken to only\n            log Metadata for requests to Secrets, ConfigMaps, and TokenReviews, in\n            order to avoid risk of logging sensitive data.\n          - Modification of Pod and Deployment objects.\n          - Use of `pods/exec`, `pods/portforward`, `pods/proxy` and `services/proxy`.\n          For most requests, minimally logging at the Metadata level is recommended\n          (the most basic level of logging).\n        scored: false\n"
  },
  {
    "path": "cfg/rke2-cis-1.8/etcd.yaml",
    "content": "---\ncontrols:\nversion: \"rke2-cis-1.8\"\nid: 2\ntext: \"Etcd Node Configuration\"\ntype: \"etcd\"\ngroups:\n  - id: 2\n    text: \"Etcd Node Configuration\"\n    checks:\n      - id: 2.1\n        text: \"Ensure that the --cert-file and --key-file arguments are set as appropriate (Automated)\"\n        audit: \"cat $etcdconf\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"cert-file\"\n              path: \"{.client-transport-security.cert-file}\"\n              compare:\n                op: eq\n                value: \"/var/lib/rancher/rke2/server/tls/etcd/server-client.crt\"\n            - flag: \"key-file\"\n              path: \"{.client-transport-security.key-file}\"\n              compare:\n                op: eq\n                value: \"/var/lib/rancher/rke2/server/tls/etcd/server-client.key\"\n        remediation: |\n          Follow the etcd service documentation and configure TLS encryption.\n          Then, edit the etcd pod specification file /etc/kubernetes/manifests/etcd.yaml\n          on the master node and set the below parameters.\n          --cert-file=</path/to/ca-file>\n          --key-file=</path/to/key-file>\n        scored: true\n\n      - id: 2.2\n        text: \"Ensure that the --client-cert-auth argument is set to true (Automated)\"\n        audit: \"cat $etcdconf\"\n        tests:\n          test_items:\n            - flag: \"client-cert-auth\"\n              path: \"{.client-transport-security.client-cert-auth}\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and set the below parameter.\n          --client-cert-auth=\"true\"\n        scored: true\n\n      - id: 2.3\n        text: \"Ensure that the --auto-tls argument is not set to true (Automated)\"\n        audit: \"cat $etcdconf\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"auto-tls\"\n              path: \"{.client-transport-security.auto-tls}\"\n              compare:\n                op: noteq\n                value: true\n\n            - flag: \"auto-tls\"\n              path: \"{.client-transport-security.auto-tls}\"\n              set: false\n\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master node\n          and either remove the --auto-tls parameter or set it to false.\n\n            --auto-tls=false\n\n        scored: true\n\n      - id: 2.4\n        text: \"Ensure that the --peer-cert-file and --peer-key-file arguments are set as appropriate (Automated)\"\n        audit: \"cat $etcdconf\"\n        audit_config: \"cat $etcdconf\"\n        tests:\n          test_items:\n            - path: \"{.peer-transport-security.cert-file}\"\n              compare:\n                op: eq\n                value: \"/var/lib/rancher/rke2/server/tls/etcd/peer-server-client.crt\"\n            - path: \"{.peer-transport-security.key-file}\"\n              compare:\n                op: eq\n                value: \"/var/lib/rancher/rke2/server/tls/etcd/peer-server-client.key\"\n        remediation: |\n          Follow the etcd service documentation and configure peer TLS encryption as appropriate\n          for your etcd cluster.\n          Then, edit the etcd pod specification file $etcdconf on the\n          master node and set the below parameters.\n          --peer-client-file=</path/to/peer-cert-file>\n          --peer-key-file=</path/to/peer-key-file>\n        scored: true\n\n      - id: 2.5\n        text: \"Ensure that the --peer-client-cert-auth argument is set to true (Automated)\"\n        audit: \"cat $etcdconf\"\n        tests:\n          test_items:\n            - flag: \"client-cert-auth\"\n              path: \"{.peer-transport-security.client-cert-auth}\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and set the below parameter.\n          --peer-client-cert-auth=true\n        scored: true\n\n      - id: 2.6\n        text: \"Ensure that the --peer-auto-tls argument is not set to true (Automated)\"\n        audit: \"cat $etcdconf\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"peer-auto-tls\"\n              path: \"{.peer-transport-security.auto-tls}\"\n              compare:\n                op: noteq\n                value: true\n\n            - flag: \"peer-auto-tls\"\n              path: \"{.peer-transport-security.auto-tls}\"\n              set: false\n\n        remediation: |\n          Edit the etcd pod specification file $etcdconf on the master\n          node and either remove the --peer-auto-tls parameter or set it to false.\n          --peer-auto-tls=false\n        scored: true\n\n      - id: 2.7\n        text: \"Ensure that a unique Certificate Authority is used for etcd (Automated)\"\n        audit: \"cat $etcdconf\"\n        audit_config: \"cat $etcdconf\"\n        tests:\n          test_items:\n            - path: \"{.peer-transport-security.trusted-ca-file}\"\n              compare:\n                op: eq\n                value: \"/var/lib/rancher/rke2/server/tls/etcd/peer-ca.crt\"\n              set: true\n        remediation: |\n          [Manual test]\n          Follow the etcd documentation and create a dedicated certificate authority setup for the\n          etcd service.\n          Then, edit the etcd pod specification file $etcdconf on the\n          master node and set the below parameter.\n          --trusted-ca-file=</path/to/ca-file>\n        scored: true\n"
  },
  {
    "path": "cfg/rke2-cis-1.8/master.yaml",
    "content": "---\ncontrols:\nversion: \"rke2-cis-1.8\"\nid: 1\ntext: \"Control Plane Security Configuration\"\ntype: \"master\"\ngroups:\n  - id: 1.1\n    text: \"Control Plane Node Configuration Files\"\n    checks:\n      - id: 1.1.1\n        text: \"Ensure that the API server pod specification file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $apiserverconf; then stat -c permissions=%a $apiserverconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the\n          control plane node.\n          For example, chmod 600 $apiserverconf\n          Not Applicable -  Cluster provisioned by RKE doesn't require or maintain a configuration file for kube-apiserver.\n          All configuration is passed in as arguments at container run time.\n        scored: true\n\n      - id: 1.1.2\n        text: \"Ensure that the API server pod specification file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $apiserverconf; then stat -c %U:%G $apiserverconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chown root:root $apiserverconf\n          Not Applicable -  Cluster provisioned by RKE doesn't require or maintain a configuration file for kube-apiserver.\n          All configuration is passed in as arguments at container run time.\n        scored: true\n\n      - id: 1.1.3\n        text: \"Ensure that the controller manager pod specification file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerconf; then stat -c permissions=%a $controllermanagerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chmod 600 $controllermanagerconf\n          Not Applicable -  Cluster provisioned by RKE doesn't require or maintain a configuration file for kube-apiserver.\n          All configuration is passed in as arguments at container run time.\n        scored: true\n\n      - id: 1.1.4\n        text: \"Ensure that the controller manager pod specification file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerconf; then stat -c %U:%G $controllermanagerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chown root:root $controllermanagerconf\n          Not Applicable -  Cluster provisioned by RKE doesn't require or maintain a configuration file for kube-apiserver.\n          All configuration is passed in as arguments at container run time.\n        scored: true\n\n      - id: 1.1.5\n        text: \"Ensure that the scheduler pod specification file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerconf; then stat -c permissions=%a $schedulerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chmod 600 $schedulerconf\n          Not Applicable -  Cluster provisioned by RKE doesn't require or maintain a configuration file for kube-apiserver.\n          All configuration is passed in as arguments at container run time.\n        scored: true\n\n      - id: 1.1.6\n        text: \"Ensure that the scheduler pod specification file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerconf; then stat -c %U:%G $schedulerconf; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chown root:root $schedulerconf\n          Not Applicable -  Cluster provisioned by RKE doesn't require or maintain a configuration file for kube-apiserver.\n          All configuration is passed in as arguments at container run time.\n        scored: true\n\n      - id: 1.1.7\n        text: \"Ensure that the etcd pod specification file permissions are set to 600 or more restrictive (Automated)\"\n        audit: |\n          /bin/sh -c '\n          if [ -e \"$etcdconf\" ]; then\n            stat -c \"permissions=%a %n\" \"$etcdconf\"\n          else\n            echo \"Directory not found\"\n          fi\n          '\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n            - flag: \"Directory not found\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod 600 $etcdconf\n          Not Applicable -  Cluster provisioned by RKE doesn't require or maintain a configuration file for kube-apiserver.\n          All configuration is passed in as arguments at container run time.\n        scored: true\n\n      - id: 1.1.8\n        text: \"Ensure that the etcd pod specification file ownership is set to root:root (Automated)\"\n        audit: |\n          /bin/sh -c '\n          if [ -e \"$etcdconf\" ]; then\n          stat -c \"ownership=%U:%G %n\" \"$etcdconf\"\n          else\n            echo \"Directory not found\"\n          fi\n          '\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"ownership\"\n              compare:\n                op: eq\n                value: \"root:root\"\n              set: true\n            - flag: \"Directory not found\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root $etcdconf\n          Not Applicable -  Cluster provisioned by RKE doesn't require or maintain a configuration file for kube-apiserver.\n          All configuration is passed in as arguments at container run time.\n        scored: true\n\n      - id: 1.1.9\n        text: \"Ensure that the Container Network Interface file permissions are set to 600 or more restrictive (Manual)\"\n        audit: |\n          ps -ef | grep $kubeletbin | grep -- --cni-conf-dir | sed 's%.*cni-conf-dir[= ]\\([^ ]*\\).*%\\1%' | xargs -I{} find {} -mindepth 1 | xargs --no-run-if-empty stat -c permissions=%a\n          find /var/lib/cni/networks -type f 2> /dev/null | xargs --no-run-if-empty stat -c permissions=%a\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chmod 600 <path/to/cni/files>\n        scored: false\n\n      - id: 1.1.10\n        text: \"Ensure that the Container Network Interface file ownership is set to root:root (Manual)\"\n        audit: |\n          ps -ef | grep $kubeletbin | grep -- --cni-conf-dir | sed 's%.*cni-conf-dir[= ]\\([^ ]*\\).*%\\1%' | xargs -I{} find {} -mindepth 1 | xargs --no-run-if-empty stat -c %U:%G\n          find /var/lib/cni/networks -type f 2> /dev/null | xargs --no-run-if-empty stat -c %U:%G\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root <path/to/cni/files>\n        scored: false\n\n      - id: 1.1.11\n        text: \"Ensure that the etcd data directory permissions are set to 700 or more restrictive (Automated)\"\n        audit: |\n          /bin/sh -c 'if [ -e \"/var/lib/rancher/rke2/server/db/etcd\" ]; then\n            stat -c \"permissions=%a %n\" \"/var/lib/rancher/rke2/server/db/etcd\"\n          else\n            echo \"Directory not found: /var/lib/rancher/rke2/server/db/etcd\"\n          fi'\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"700\"\n              set: true\n            - flag: \"Directory not found: /var/lib/rancher/rke2/server/db/etcd\"\n        remediation: |\n          On the etcd server node, get the etcd data directory, passed as an argument --data-dir,\n          from the command 'ps -ef | grep etcd'.\n          Run the below command (based on the etcd data directory found above). For example,\n          chmod 700 /var/lib/etcd\n        scored: true\n\n      - id: 1.1.12\n        text: \"Ensure that the etcd data directory ownership is set to etcd:etcd (Automated)\"\n        audit: |\n          /bin/sh -c '\n          if [ -e \"$etcdconf\" ]; then\n            stat -c \"ownership=%U:%G %n\" \"$etcdconf\"\n          else\n            echo \"Directory not found\"\n          fi\n          '\n        type: \"skip\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"ownership\"\n              compare:\n                op: eq\n                value: \"root:root\"\n              set: true\n            - flag: \"Directory not found\"\n              set: true\n        remediation: |\n          On the etcd server node, get the etcd data directory, passed as an argument --data-dir,\n          from the command 'ps -ef | grep etcd'.\n          Run the below command (based on the etcd data directory found above).\n          For example, chown etcd:etcd /var/lib/etcd\n          Permissive - A system service account is required for etcd data directory ownership.\n          Refer to Rancher's hardening guide for more details on how to configure this ownership.\n        scored: true\n\n      - id: 1.1.13\n        text: \"Ensure that the admin.conf file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"stat -c permissions=%a /var/lib/rancher/rke2/server/cred/admin.kubeconfig\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chmod 600 /etc/kubernetes/admin.conf\n          Not Applicable -  Cluster provisioned by RKE does not store the kubernetes default kubeconfig credentials file on the nodes.\n        scored: true\n\n      - id: 1.1.14\n        text: \"Ensure that the admin.conf file ownership is set to root:root (Automated)\"\n        audit: \"stat -c %U:%G /var/lib/rancher/rke2/server/cred/admin.kubeconfig\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example, chown root:root /etc/kubernetes/admin.conf\n          Not Applicable -  Cluster provisioned by RKE does not store the kubernetes default kubeconfig credentials file on the nodes.\n        scored: true\n\n      - id: 1.1.15\n        text: \"Ensure that the scheduler.conf file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerkubeconfig; then stat -c permissions=%a $schedulerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod 600 $schedulerkubeconfig\n          Not Applicable -  Cluster provisioned by RKE doesn't require or maintain a configuration file for scheduler.\n          All configuration is passed in as arguments at container run time.\n        scored: true\n\n      - id: 1.1.16\n        text: \"Ensure that the scheduler.conf file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $schedulerkubeconfig; then stat -c %U:%G $schedulerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root $schedulerkubeconfig\n          Not Applicable -  Cluster provisioned by RKE doesn't require or maintain a configuration file for scheduler.\n          All configuration is passed in as arguments at container run time.\n        scored: true\n\n      - id: 1.1.17\n        text: \"Ensure that the controller-manager.conf file permissions are set to 600 or more restrictive (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerkubeconfig; then stat -c permissions=%a $controllermanagerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chmod 600 $controllermanagerkubeconfig\n          Not Applicable -  Cluster provisioned by RKE doesn't require or maintain a configuration file for controller-manager.\n          All configuration is passed in as arguments at container run time.\n        scored: true\n\n      - id: 1.1.18\n        text: \"Ensure that the controller-manager.conf file ownership is set to root:root (Automated)\"\n        audit: \"/bin/sh -c 'if test -e $controllermanagerkubeconfig; then stat -c %U:%G $controllermanagerkubeconfig; fi'\"\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root $controllermanagerkubeconfig\n          Not Applicable -  Cluster provisioned by RKE doesn't require or maintain a configuration file for controller-manager.\n          All configuration is passed in as arguments at container run time.\n        scored: true\n\n      - id: 1.1.19\n        text: \"Ensure that the Kubernetes PKI directory and file ownership is set to root:root (Automated)\"\n        audit: |\n          if test -d /var/lib/rancher/rke2/server/tls; then\n            find /var/lib/rancher/rke2/server/tls -exec stat -c \"%U:%G\" {} \\;\n          else\n            echo \"NA\"\n          fi\n        tests:\n          test_items:\n            - flag: \"root:root\"\n              set: true\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          chown root:root $controllermanagerkubeconfig\n          Not Applicable -  Cluster provisioned by RKE doesn't require or maintain a configuration file for controller-manager.\n          All configuration is passed in as arguments at container run time.\n        scored: true\n\n      - id: 1.1.20\n        text: \"Ensure that the Kubernetes PKI certificate file permissions are set to 600 or more restrictive (Manual)\"\n        audit: |\n          if [ -d /node/etc/kubernetes/ssl ]; then\n            find /node/etc/kubernetes/ssl -type f -name '*.pem' ! -name '*key.pem' \\\n              -exec stat -c 'permissions=%a %n' {} +\n          else\n            echo \"Directory not found: /node/etc/kubernetes/ssl\"\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          find /node/etc/kubernetes/ssl/  -name '*.pem' ! -name '*key.pem' -exec chmod -R 600 {} +\n        scored: false\n\n      - id: 1.1.21\n        text: \"Ensure that the Kubernetes PKI key file permissions are set to 600 (Manual)\"\n        audit: |\n          if [ -d /node/etc/kubernetes/ssl ]; then\n            find /node/etc/kubernetes/ssl -type f -name '*key.pem' -exec stat -c 'permissions=%a %n' {} +\n          else\n            echo \"Directory not found: /node/etc/kubernetes/ssl\"\n          fi\n        use_multiple_values: true\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the control plane node.\n          For example,\n          find /node/etc/kubernetes/ssl/ -name '*key.pem' -exec chmod -R 600 {} +\n        scored: false\n\n  - id: 1.2\n    text: \"API Server\"\n    checks:\n      - id: 1.2.1\n        text: \"Ensure that the --anonymous-auth argument is set to false (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--anonymous-auth\"\n              compare:\n                op: eq\n                value: false\n              set: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the below parameter.\n          --anonymous-auth=false\n        scored: true\n\n      - id: 1.2.2\n        text: \"Ensure that the --token-auth-file parameter is not set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--token-auth-file\"\n              set: false\n        remediation: |\n          Follow the documentation and configure alternate mechanisms for authentication. Then,\n          edit the API server pod specification file $apiserverconf\n          on the control plane node and remove the --token-auth-file=<filename> parameter.\n        scored: true\n\n      - id: 1.2.3\n        text: \"Ensure that the --DenyServiceExternalIPs is set (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"DenyServiceExternalIPs\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and add the `DenyServiceExternalIPs` plugin\n          to the enabled admission plugins, as such --enable-admission-plugin=DenyServiceExternalIPs.\n        scored: false\n\n      - id: 1.2.4\n        text: \"Ensure that the --kubelet-client-certificate and --kubelet-client-key arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--kubelet-client-certificate\"\n            - flag: \"--kubelet-client-key\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection between the\n          apiserver and kubelets. Then, edit API server pod specification file\n          $apiserverconf on the control plane node and set the\n          kubelet client certificate and key parameters as below.\n          --kubelet-client-certificate=<path/to/client-certificate-file>\n          --kubelet-client-key=<path/to/client-key-file>\n        scored: true\n\n      - id: 1.2.5\n        text: \"Ensure that the --kubelet-certificate-authority argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--kubelet-certificate-authority\"\n              set: true\n        remediation: |\n          Follow the Kubernetes documentation and setup the TLS connection between\n          the apiserver and kubelets. Then, edit the API server pod specification file\n          $apiserverconf on the control plane node and set the\n          --kubelet-certificate-authority parameter to the path to the cert file for the certificate authority.\n          --kubelet-certificate-authority=<ca-string>\n          Permissive - When generating serving certificates, functionality could break in conjunction with hostname overrides which are required for certain cloud providers.\n        scored: true\n\n      - id: 1.2.6\n        text: \"Ensure that the --authorization-mode argument is not set to AlwaysAllow (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: nothave\n                value: \"AlwaysAllow\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --authorization-mode parameter to values other than AlwaysAllow.\n          One such example could be as below.\n          --authorization-mode=RBAC\n        scored: true\n\n      - id: 1.2.7\n        text: \"Ensure that the --authorization-mode argument includes Node (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: has\n                value: \"Node\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --authorization-mode parameter to a value that includes Node.\n          --authorization-mode=Node,RBAC\n        scored: true\n\n      - id: 1.2.8\n        text: \"Ensure that the --authorization-mode argument includes RBAC (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: has\n                value: \"RBAC\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --authorization-mode parameter to a value that includes RBAC,\n          for example `--authorization-mode=Node,RBAC`.\n        scored: true\n\n      - id: 1.2.9\n        text: \"Ensure that the admission control plugin EventRateLimit is set (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"EventRateLimit\"\n        remediation: |\n          Follow the Kubernetes documentation and set the desired limits in a configuration file.\n          Then, edit the API server pod specification file $apiserverconf\n          and set the below parameters.\n          --enable-admission-plugins=...,EventRateLimit,...\n          --admission-control-config-file=<path/to/configuration/file>\n        scored: false\n\n      - id: 1.2.10\n        text: \"Ensure that the admission control plugin AlwaysAdmit is not set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: nothave\n                value: AlwaysAdmit\n            - flag: \"--enable-admission-plugins\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and either remove the --enable-admission-plugins parameter, or set it to a\n          value that does not include AlwaysAdmit.\n        scored: true\n\n      - id: 1.2.11\n        text: \"Ensure that the admission control plugin AlwaysPullImages is set (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"AlwaysPullImages\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --enable-admission-plugins parameter to include\n          AlwaysPullImages.\n          --enable-admission-plugins=...,AlwaysPullImages,...\n        scored: false\n\n      - id: 1.2.12\n        text: \"Ensure that the admission control plugin SecurityContextDeny is set if PodSecurityPolicy is not used (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"SecurityContextDeny\"\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"PodSecurityPolicy\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --enable-admission-plugins parameter to include\n          SecurityContextDeny, unless PodSecurityPolicy is already in place.\n          --enable-admission-plugins=...,SecurityContextDeny,...\n          Permissive - Enabling Pod Security Policy can cause applications to unexpectedly fail.\n        scored: false\n\n      - id: 1.2.13\n        text: \"Ensure that the admission control plugin ServiceAccount is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--disable-admission-plugins\"\n              compare:\n                op: nothave\n                value: \"ServiceAccount\"\n            - flag: \"--disable-admission-plugins\"\n              set: false\n        remediation: |\n          Follow the documentation and create ServiceAccount objects as per your environment.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and ensure that the --disable-admission-plugins parameter is set to a\n          value that does not include ServiceAccount.\n        scored: true\n\n      - id: 1.2.14\n        text: \"Ensure that the admission control plugin NamespaceLifecycle is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--disable-admission-plugins\"\n              compare:\n                op: nothave\n                value: \"NamespaceLifecycle\"\n            - flag: \"--disable-admission-plugins\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --disable-admission-plugins parameter to\n          ensure it does not include NamespaceLifecycle.\n        scored: true\n\n      - id: 1.2.15\n        text: \"Ensure that the admission control plugin NodeRestriction is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"NodeRestriction\"\n        remediation: |\n          Follow the Kubernetes documentation and configure NodeRestriction plug-in on kubelets.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --enable-admission-plugins parameter to a\n          value that includes NodeRestriction.\n          --enable-admission-plugins=...,NodeRestriction,...\n        scored: true\n\n      - id: 1.2.16\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the below parameter.\n          --profiling=false\n        scored: true\n\n      - id: 1.2.17\n        text: \"Ensure that the --audit-log-path argument is set (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-path\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --audit-log-path parameter to a suitable path and\n          file where you would like audit logs to be written, for example,\n          --audit-log-path=/var/log/apiserver/audit.log\n        scored: true\n\n      - id: 1.2.18\n        text: \"Ensure that the --audit-log-maxage argument is set to 30 or as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxage\"\n              compare:\n                op: gte\n                value: 30\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --audit-log-maxage parameter to 30\n          or as an appropriate number of days, for example,\n          --audit-log-maxage=30\n        scored: true\n\n      - id: 1.2.19\n        text: \"Ensure that the --audit-log-maxbackup argument is set to 10 or as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxbackup\"\n              compare:\n                op: gte\n                value: 10\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --audit-log-maxbackup parameter to 10 or to an appropriate\n          value. For example,\n          --audit-log-maxbackup=10\n        scored: true\n\n      - id: 1.2.20\n        text: \"Ensure that the --audit-log-maxsize argument is set to 100 or as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxsize\"\n              compare:\n                op: gte\n                value: 100\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --audit-log-maxsize parameter to an appropriate size in MB.\n          For example, to set it as 100 MB, --audit-log-maxsize=100\n        scored: true\n\n      - id: 1.2.21\n        text: \"Ensure that the --request-timeout argument is set as appropriate (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        type: manual\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          and set the below parameter as appropriate and if needed.\n          For example, --request-timeout=300s\n        scored: false\n\n      - id: 1.2.22\n        text: \"Ensure that the --service-account-lookup argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--service-account-lookup\"\n              set: false\n            - flag: \"--service-account-lookup\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the below parameter.\n          --service-account-lookup=true\n          Alternatively, you can delete the --service-account-lookup parameter from this file so\n          that the default takes effect.\n        scored: true\n\n      - id: 1.2.23\n        text: \"Ensure that the --service-account-key-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--service-account-key-file\"\n        remediation: |\n          Edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --service-account-key-file parameter\n          to the public key file for service accounts. For example,\n          --service-account-key-file=<filename>\n        scored: true\n\n      - id: 1.2.24\n        text: \"Ensure that the --etcd-certfile and --etcd-keyfile arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--etcd-certfile\"\n            - flag: \"--etcd-keyfile\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection between the apiserver and etcd.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the etcd certificate and key file parameters.\n          --etcd-certfile=<path/to/client-certificate-file>\n          --etcd-keyfile=<path/to/client-key-file>\n        scored: true\n\n      - id: 1.2.25\n        text: \"Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--tls-cert-file\"\n            - flag: \"--tls-private-key-file\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection on the apiserver.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the TLS certificate and private key file parameters.\n          --tls-cert-file=<path/to/tls-certificate-file>\n          --tls-private-key-file=<path/to/tls-key-file>\n        scored: true\n\n      - id: 1.2.26\n        text: \"Ensure that the --client-ca-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--client-ca-file\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection on the apiserver.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the client certificate authority file.\n          --client-ca-file=<path/to/client-ca-file>\n        scored: true\n\n      - id: 1.2.27\n        text: \"Ensure that the --etcd-cafile argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--etcd-cafile\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection between the apiserver and etcd.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the etcd certificate authority file parameter.\n          --etcd-cafile=<path/to/ca-file>\n        scored: true\n\n      - id: 1.2.28\n        text: \"Ensure that the --encryption-provider-config argument is set as appropriate (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--encryption-provider-config\"\n        remediation: |\n          Follow the Kubernetes documentation and configure a EncryptionConfig file.\n          Then, edit the API server pod specification file $apiserverconf\n          on the control plane node and set the --encryption-provider-config parameter to the path of that file.\n          For example, --encryption-provider-config=</path/to/EncryptionConfig/File>\n          Permissive - Enabling encryption changes how data can be recovered as data is encrypted.\n        scored: false\n\n      - id: 1.2.29\n        text: \"Ensure that encryption providers are appropriately configured (Manual)\"\n        audit: |\n          ENCRYPTION_PROVIDER_CONFIG=$(ps -ef | grep $apiserverbin | grep -- --encryption-provider-config | sed 's%.*encryption-provider-config[= ]\\([^ ]*\\).*%\\1%')\n          if test -e $ENCRYPTION_PROVIDER_CONFIG; then grep -A1 'providers:' $ENCRYPTION_PROVIDER_CONFIG | tail -n1 | grep -o \"[A-Za-z]*\" | sed 's/^/provider=/'; fi\n        tests:\n          test_items:\n            - flag: \"provider\"\n              compare:\n                op: valid_elements\n                value: \"aescbc,kms,secretbox\"\n        remediation: |\n          Follow the Kubernetes documentation and configure a EncryptionConfig file.\n          In this file, choose aescbc, kms or secretbox as the encryption provider.\n          Permissive - Enabling encryption changes how data can be recovered as data is encrypted.\n        scored: false\n\n      - id: 1.2.30\n        text: \"Ensure that the API Server only makes use of Strong Cryptographic Ciphers (Manual)\"\n        audit: \"/bin/ps -ef | grep $apiserverbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--tls-cipher-suites\"\n              compare:\n                op: valid_elements\n                value: \"TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,TLS_CHACHA20_POLY1305_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,TLS_RSA_WITH_3DES_EDE_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_256_GCM_SHA384\"\n        remediation: |\n          Edit the API server pod specification file /etc/kubernetes/manifests/kube-apiserver.yaml\n          on the control plane node and set the below parameter.\n          --tls-cipher-suites=TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,TLS_CHACHA20_POLY1305_SHA256,\n          TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,\n          TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,\n          TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,\n          TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,\n          TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,\n          TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,TLS_RSA_WITH_3DES_EDE_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA,\n          TLS_RSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_256_GCM_SHA384\n        scored: false\n\n  - id: 1.3\n    text: \"Controller Manager\"\n    checks:\n      - id: 1.3.1\n        text: \"Ensure that the --terminated-pod-gc-threshold argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--terminated-pod-gc-threshold\"\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the --terminated-pod-gc-threshold to an appropriate threshold,\n          for example, --terminated-pod-gc-threshold=10\n        scored: true\n\n      - id: 1.3.2\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the below parameter.\n          --profiling=false\n        scored: true\n\n      - id: 1.3.3\n        text: \"Ensure that the --use-service-account-credentials argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--use-service-account-credentials\"\n              compare:\n                op: noteq\n                value: false\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node to set the below parameter.\n          --use-service-account-credentials=true\n        scored: true\n\n      - id: 1.3.4\n        text: \"Ensure that the --service-account-private-key-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--service-account-private-key-file\"\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the --service-account-private-key-file parameter\n          to the private key file for service accounts.\n          --service-account-private-key-file=<filename>\n        scored: true\n\n      - id: 1.3.5\n        text: \"Ensure that the --root-ca-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--root-ca-file\"\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the --root-ca-file parameter to the certificate bundle file`.\n          --root-ca-file=<path/to/file>\n        scored: true\n\n      - id: 1.3.6\n        text: \"Ensure that the RotateKubeletServerCertificate argument is set to true (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--feature-gates\"\n              compare:\n                op: nothave\n                value: \"RotateKubeletServerCertificate=false\"\n              set: true\n            - flag: \"--feature-gates\"\n              set: false\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and set the --feature-gates parameter to include RotateKubeletServerCertificate=true.\n          --feature-gates=RotateKubeletServerCertificate=true\n          Cluster provisioned by RKE handles certificate rotation directly through RKE.\n        scored: true\n\n      - id: 1.3.7\n        text: \"Ensure that the --bind-address argument is set to 127.0.0.1 (Automated)\"\n        audit: \"/bin/ps -ef | grep $controllermanagerbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--bind-address\"\n              compare:\n                op: eq\n                value: \"127.0.0.1\"\n            - flag: \"--bind-address\"\n              set: false\n        remediation: |\n          Edit the Controller Manager pod specification file $controllermanagerconf\n          on the control plane node and ensure the correct value for the --bind-address parameter\n        scored: true\n\n  - id: 1.4\n    text: \"Scheduler\"\n    checks:\n      - id: 1.4.1\n        text: \"Ensure that the --profiling argument is set to false (Automated)\"\n        audit: \"/bin/ps -ef | grep $schedulerbin | grep -v grep\"\n        tests:\n          test_items:\n            - flag: \"--profiling\"\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          Edit the Scheduler pod specification file $schedulerconf file\n          on the control plane node and set the below parameter.\n          --profiling=false\n        scored: true\n\n      - id: 1.4.2\n        text: \"Ensure that the --bind-address argument is set to 127.0.0.1 (Automated)\"\n        audit: \"/bin/ps -ef | grep $schedulerbin | grep -v grep\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--bind-address\"\n              compare:\n                op: eq\n                value: \"127.0.0.1\"\n            - flag: \"--bind-address\"\n              set: false\n        remediation: |\n          Edit the Scheduler pod specification file $schedulerconf\n          on the control plane node and ensure the correct value for the --bind-address parameter\n        scored: true\n"
  },
  {
    "path": "cfg/rke2-cis-1.8/node.yaml",
    "content": "---\ncontrols:\nversion: \"rke2-cis-1.8\"\nid: 4\ntext: \"Worker Node Security Configuration\"\ntype: \"node\"\ngroups:\n  - id: 4.1\n    text: \"Worker Node Configuration Files\"\n    checks:\n      - id: 4.1.1\n        text: \"Ensure that the kubelet service file permissions are set to 600 or more restrictive (Automated)\"\n        audit: '/bin/sh -c \"if test -e $kubeletsvc; then stat -c permissions=%a $kubeletsvc; else echo \\\"File not found\\\"; fi\"'\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n            - flag: \"File not found\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example, chmod 600 $kubeletsvc\n          Not Applicable - Clusters provisioned by RKE doesn't require or maintain a configuration file for the kubelet service.\n          All configuration is passed in as arguments at container run time.\n        scored: true\n\n      - id: 4.1.2\n        text: \"Ensure that the kubelet service file ownership is set to root:root (Automated)\"\n        audit: '/bin/sh -c \"if test -e $kubeletsvc; then stat -c ownership=%U:%G $kubeletsvc; else echo \\\"File not found\\\"; fi\"'\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"ownership\"\n              compare:\n                op: eq\n                value: \"root:root\"\n            - flag: \"File not found\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chown root:root $kubeletsvc\n          Not Applicable - Clusters provisioned by RKE does not require or maintain a configuration file for the kubelet service.\n           All configuration is passed in as arguments at container run time.\n        scored: true\n\n      - id: 4.1.3\n        text: \"If proxy kubeconfig file exists ensure permissions are set to 600 or more restrictive (Automated)\"\n        audit: '/bin/sh -c ''if test -e $proxykubeconfig; then stat -c permissions=%a $proxykubeconfig; fi'' '\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"permissions\"\n              set: true\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chmod 600 $proxykubeconfig\n        scored: true\n\n      - id: 4.1.4\n        text: \"If proxy kubeconfig file exists ensure ownership is set to root:root (Automated)\"\n        audit: '/bin/sh -c ''if test -e $proxykubeconfig; then stat -c %U:%G $proxykubeconfig; fi'' '\n        tests:\n          bin_op: or\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example, chown root:root $proxykubeconfig\n        scored: true\n\n      - id: 4.1.5\n        text: \"Ensure that the --kubeconfig kubelet.conf file permissions are set to 600 or more restrictive (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletkubeconfig; then stat -c permissions=%a $kubeletkubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chmod 600 $kubeletkubeconfig\n        scored: true\n\n      - id: 4.1.6\n        text: \"Ensure that the --kubeconfig kubelet.conf file ownership is set to root:root (Automated)\"\n        audit: '/bin/sh -c ''if test -e $kubeletkubeconfig; then stat -c %U:%G $kubeletkubeconfig; fi'' '\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chown root:root $kubeletkubeconfig\n        scored: true\n\n      - id: 4.1.7\n        text: \"Ensure that the certificate authorities file permissions are set to 600 or more restrictive (Automated)\"\n        audit: |\n          if [ -f /var/lib/rancher/rke2/agent/client-ca.crt ]; then\n            stat -c permissions=%a /var/lib/rancher/rke2/agent/client-ca.crt\n          else\n            echo \"NA\"\n          fi\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n        remediation: |\n          Run the following command to modify the file permissions of the\n          --client-ca-file chmod 600 <filename>\n        scored: true\n\n      - id: 4.1.8\n        text: \"Ensure that the client certificate authorities file ownership is set to root:root (Automated)\"\n        audit: |\n          if [ -f /var/lib/rancher/rke2/agent/client-ca.crt ]; then\n            stat -c %U:%G /var/lib/rancher/rke2/agent/client-ca.crt\n          else\n            echo \"NA\"\n          fi\n        tests:\n          test_items:\n            - flag: root:root\n              compare:\n                op: eq\n                value: root:root\n        remediation: |\n          Run the following command to modify the ownership of the --client-ca-file.\n          chown root:root <filename>\n        scored: true\n\n      - id: 4.1.9\n        text: \"If the kubelet config.yaml configuration file is being used validate permissions set to 600 or more restrictive (Automated)\"\n        type: skip\n        audit: |\n          /bin/sh -c 'if test -e \"$kubeletconf\"; then\n            stat -c \"permissions=%a\" \"$kubeletconf\"\n          else\n            echo \"File not found\"\n          fi'\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"600\"\n            - flag: \"File not found\"\n        remediation: |\n          Run the following command (using the config file location identified in the Audit step)\n          chmod 600 $kubeletconf\n          Not Applicable - Clusters provisioned by RKE do not require or maintain a configuration file for the kubelet.\n          All configuration is passed in as arguments at container run time.\n        scored: false\n\n      - id: 4.1.10\n        text: \"If the kubelet config.yaml configuration file is being used validate file ownership is set to root:root (Manual)\"\n        type: skip\n        audit: |\n          /bin/sh -c 'if test -e \"$kubeletconf\"; then\n            stat -c \"%U:%G\" \"$kubeletconf\"\n          else\n            echo \"File not found\"\n          fi'\n        tests:\n          bin_op: or\n          test_items:\n            - flag: root:root\n            - flag: \"File not found\"\n        remediation: |\n          Run the following command (using the config file location identified in the Audit step)\n          chown root:root $kubeletconf\n          Not Applicable - Clusters provisioned by RKE does not require or maintain a configuration file for the kubelet.\n          All configuration is passed in as arguments at container run time.\n        scored: false\n\n  - id: 4.2\n    text: \"Kubelet\"\n    checks:\n      - id: 4.2.1\n        text: \"Ensure that the --anonymous-auth argument is set to false (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: /bin/sh -c 'if test -d $kubeletconf; then cat $kubeletconf/*; elif test -e $kubeletconf; then cat $kubeletconf; fi'\n        tests:\n          test_items:\n            - flag: \"anonymous-auth\"\n              path: '{.authentication.anonymous.enabled}'\n              compare:\n                op: eq\n                value: false\n        remediation: |\n          If using a Kubelet config file, edit the file to set `authentication: anonymous: enabled` to\n          `false`.\n          If using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          `--anonymous-auth=false`\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.2\n        text: \"Ensure that the --authorization-mode argument is not set to AlwaysAllow (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: /bin/sh -c 'if test -d $kubeletconf; then cat $kubeletconf/*; elif test -e $kubeletconf; then cat $kubeletconf; fi'\n        tests:\n          test_items:\n            - flag: authorization-mode\n              path: '{.authorization.mode}'\n              compare:\n                op: nothave\n                value: AlwaysAllow\n        remediation: |\n          If using a Kubelet config file, edit the file to set `authorization.mode` to Webhook. If\n          using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_AUTHZ_ARGS variable.\n          --authorization-mode=Webhook\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.3\n        text: \"Ensure that the --client-ca-file argument is set as appropriate (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: /bin/sh -c 'if test -d $kubeletconf; then cat $kubeletconf/*; elif test -e $kubeletconf; then cat $kubeletconf; fi'\n        tests:\n          test_items:\n            - flag: clientCAFile\n              path: \"{.authentication.x509.clientCAFile}\"\n              compare:\n                op: eq\n                value: \"/var/lib/rancher/rke2/agent/client-ca.crt\"\n        remediation: |\n          If using a Kubelet config file, edit the file to set `authentication.x509.clientCAFile` to\n          the location of the client CA file.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_AUTHZ_ARGS variable.\n          --client-ca-file=<path/to/client-ca-file>\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.4\n        text: \"Verify that the --read-only-port argument is set to 0 (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: /bin/sh -c 'if test -d $kubeletconf; then cat $kubeletconf/*; elif test -e $kubeletconf; then cat $kubeletconf; fi'\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--read-only-port\"\n              path: '{.readOnlyPort}'\n              compare:\n                op: eq\n                value: 0\n            - flag: \"--read-only-port\"\n              path: '{.readOnlyPort}'\n              set: false\n        remediation: |\n          If using a Kubelet config file, edit the file to set `readOnlyPort` to 0.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --read-only-port=0\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.5\n        text: \"Ensure that the --streaming-connection-idle-timeout argument is not set to 0 (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: /bin/sh -c 'if test -d $kubeletconf; then cat $kubeletconf/*; elif test -e $kubeletconf; then cat $kubeletconf; fi'\n        tests:\n          test_items:\n            - flag: --streaming-connection-idle-timeout\n              path: '{.streamingConnectionIdleTimeout}'\n              compare:\n                op: noteq\n                value: 0\n            - flag: --streaming-connection-idle-timeout\n              path: '{.streamingConnectionIdleTimeout}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to set `streamingConnectionIdleTimeout` to a\n          value other than 0.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --streaming-connection-idle-timeout=5m\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.6\n        text: \"Ensure that the --make-iptables-util-chains argument is set to true (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: /bin/sh -c 'if test -d $kubeletconf; then cat $kubeletconf/*; elif test -e $kubeletconf; then cat $kubeletconf; fi'\n        tests:\n          test_items:\n            - flag: --make-iptables-util-chains\n              path: '{.makeIPTablesUtilChains}'\n              compare:\n                op: eq\n                value: true\n            - flag: --make-iptables-util-chains\n              path: '{.makeIPTablesUtilChains}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to set `makeIPTablesUtilChains` to `true`.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          remove the --make-iptables-util-chains argument from the\n          KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.7\n        text: \"Ensure that the --hostname-override argument is not set (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin \"\n        audit_config: /bin/sh -c 'if test -d $kubeletconf; then cat $kubeletconf/*; elif test -e $kubeletconf; then cat $kubeletconf; fi'\n        tests:\n          test_items:\n            - flag: --hostname-override\n              set: false\n        remediation: |\n          Edit the kubelet service file $kubeletsvc\n          on each worker node and remove the --hostname-override argument from the\n          KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n          Not Applicable - Clusters provisioned by RKE set the --hostname-override to avoid any hostname configuration errors\n        scored: false\n\n      - id: 4.2.8\n        text: \"Ensure that the eventRecordQPS argument is set to a level which ensures appropriate event capture (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: /bin/sh -c 'if test -d $kubeletconf; then cat $kubeletconf/*; elif test -e $kubeletconf; then cat $kubeletconf; fi'\n        tests:\n          test_items:\n            - flag: --event-qps\n              path: '{.eventRecordQPS}'\n              compare:\n                op: gte\n                value: 0\n            - flag: --event-qps\n              path: '{.eventRecordQPS}'\n              set: false\n          bin_op: or\n        remediation: |\n          If using a Kubelet config file, edit the file to set `eventRecordQPS` to an appropriate level.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.9\n        text: \"Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: /bin/sh -c 'if test -d $kubeletconf; then cat $kubeletconf/*; elif test -e $kubeletconf; then cat $kubeletconf; fi'\n        tests:\n          test_items:\n            - flag: --tls-cert-file\n              path: '{.tlsCertFile}'\n            - flag: --tls-private-key-file\n              path: '{.tlsPrivateKeyFile}'\n        remediation: |\n          If using a Kubelet config file, edit the file to set `tlsCertFile` to the location\n          of the certificate file to use to identify this Kubelet, and `tlsPrivateKeyFile`\n          to the location of the corresponding private key file.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the below parameters in KUBELET_CERTIFICATE_ARGS variable.\n          --tls-cert-file=<path/to/tls-certificate-file>\n          --tls-private-key-file=<path/to/tls-key-file>\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n          Permissive - When generating serving certificates, functionality could break in conjunction with hostname overrides which are required for certain cloud providers.\n        scored: false\n\n      - id: 4.2.10\n        text: \"Ensure that the --rotate-certificates argument is not set to false (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: \"/bin/sh -c 'if test -d $kubeletconf; then cat $kubeletconf/*; elif test -f $kubeletconf; then cat $kubeletconf; fi'\"\n        tests:\n          bin_op: or\n          test_items:\n            - flag: \"--rotate-certificates=false\"\n              set: false\n            - path: \"{.rotateCertificates}\"\n              compare:\n                op: eq\n                value: true\n            - path: \"{.rotateCertificates}\"\n              set: false\n        remediation: |\n          If using a Kubelet config file, edit the file to add the line `rotateCertificates` to `true` or\n          remove it altogether to use the default value.\n          If using command line arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          remove --rotate-certificates=false argument from the KUBELET_CERTIFICATE_ARGS\n          variable.\n          Based on your system, restart the kubelet service. For example,\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.11\n        text: \"Verify that the RotateKubeletServerCertificate argument is set to true (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: /bin/sh -c 'if test -d $kubeletconf; then cat $kubeletconf/*; elif test -e $kubeletconf; then cat $kubeletconf; fi'\n        tests:\n          bin_op: or\n          test_items:\n            - flag: RotateKubeletServerCertificate\n              path: '{.featureGates.RotateKubeletServerCertificate}'\n              compare:\n                op: nothave\n                value: false\n            - flag: RotateKubeletServerCertificate\n              path: '{.featureGates.RotateKubeletServerCertificate}'\n              set: false\n        remediation: |\n          Edit the kubelet service file $kubeletsvc\n          on each worker node and set the below parameter in KUBELET_CERTIFICATE_ARGS variable.\n          --feature-gates=RotateKubeletServerCertificate=true\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n          Not Applicable - Clusters provisioned by RKE handles certificate rotation directly through RKE.\n        scored: false\n\n      - id: 4.2.12\n        text: \"Ensure that the Kubelet only makes use of Strong Cryptographic Ciphers (Automated)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: /bin/sh -c 'if test -d $kubeletconf; then cat $kubeletconf/*; elif test -e $kubeletconf; then cat $kubeletconf; fi'\n        tests:\n          test_items:\n            - flag: --tls-cipher-suites\n              path: '{range .tlsCipherSuites[:]}{}{'',''}{end}'\n              compare:\n                op: valid_elements\n                value: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\n        remediation: |\n          If using a Kubelet config file, edit the file to set `TLSCipherSuites` to\n          TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\n          or to a subset of these values.\n          If using executable arguments, edit the kubelet service file\n          $kubeletsvc on each worker node and\n          set the --tls-cipher-suites parameter as follows, or to a subset of these values.\n          --tls-cipher-suites=TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.13\n        text: \"Ensure that a limit is set on pod PIDs (Manual)\"\n        audit: \"/bin/ps -fC $kubeletbin\"\n        audit_config: /bin/sh -c 'if test -d $kubeletconf; then cat $kubeletconf/*; elif test -e $kubeletconf; then cat $kubeletconf; fi'\n        tests:\n          test_items:\n            - flag: --pod-max-pids\n              path: '{.podPidsLimit}'\n        remediation: |\n          Decide on an appropriate level for this parameter and set it,\n          either via the --pod-max-pids command line parameter or the PodPidsLimit configuration file setting.\n        scored: false\n"
  },
  {
    "path": "cfg/rke2-cis-1.8/policies.yaml",
    "content": "---\ncontrols:\nversion: \"rke2-cis-1.8\"\nid: 5\ntext: \"Kubernetes Policies\"\ntype: \"policies\"\ngroups:\n  - id: 5.1\n    text: \"RBAC and Service Accounts\"\n    checks:\n      - id: 5.1.1\n        text: \"Ensure that the cluster-admin role is only used where required (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Identify all clusterrolebindings to the cluster-admin role. Check if they are used and\n          if they need this role or if they could use a role with fewer privileges.\n          Where possible, first bind users to a lower privileged role and then remove the\n          clusterrolebinding to the cluster-admin role :\n          kubectl delete clusterrolebinding [name]\n        scored: false\n\n      - id: 5.1.2\n        text: \"Minimize access to secrets (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove get, list and watch access to Secret objects in the cluster.\n        scored: false\n\n      - id: 5.1.3\n        text: \"Minimize wildcard use in Roles and ClusterRoles (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible replace any use of wildcards in clusterroles and roles with specific\n          objects or actions.\n        scored: false\n\n      - id: 5.1.4\n        text: \"Minimize access to create pods (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove create access to pod objects in the cluster.\n        scored: false\n\n      - id: 5.1.5\n        text: \"Ensure that default service accounts are not actively used. (Manual)\"\n        type: \"manual\"\n        audit: check_for_default_sa.sh\n        remediation: |\n          Create explicit service accounts wherever a Kubernetes workload requires specific access\n          to the Kubernetes API server.\n          Modify the configuration of each default service account to include this value\n          automountServiceAccountToken: false\n          Permissive - Kubernetes provides default service accounts to be used.\n        scored: false\n\n      - id: 5.1.6\n        text: \"Ensure that Service Account Tokens are only mounted where necessary (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Modify the definition of pods and service accounts which do not need to mount service\n          account tokens to disable it.\n        scored: false\n\n      - id: 5.1.7\n        text: \"Avoid use of system:masters group (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Remove the system:masters group from all users in the cluster.\n        scored: false\n\n      - id: 5.1.8\n        text: \"Limit use of the Bind, Impersonate and Escalate permissions in the Kubernetes cluster (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove the impersonate, bind and escalate rights from subjects.\n        scored: false\n\n      - id: 5.1.9\n        text: \"Minimize access to create persistent volumes (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove create access to PersistentVolume objects in the cluster.\n        scored: false\n\n      - id: 5.1.10\n        text: \"Minimize access to the proxy sub-resource of nodes (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove access to the proxy sub-resource of node objects.\n        scored: false\n\n      - id: 5.1.11\n        text: \"Minimize access to the approval sub-resource of certificatesigningrequests objects (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove access to the approval sub-resource of certificatesigningrequest objects.\n        scored: false\n\n      - id: 5.1.12\n        text: \"Minimize access to webhook configuration objects (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove access to the validatingwebhookconfigurations or mutatingwebhookconfigurations objects\n        scored: false\n\n      - id: 5.1.13\n        text: \"Minimize access to the service account token creation (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove access to the token sub-resource of serviceaccount objects.\n        scored: false\n\n  - id: 5.2\n    text: \"Pod Security Standards\"\n    checks:\n      - id: 5.2.1\n        text: \"Ensure that the cluster has at least one active policy control mechanism in place (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that either Pod Security Admission or an external policy control system is in place\n          for every namespace which contains user workloads.\n        scored: false\n\n      - id: 5.2.2\n        text: \"Minimize the admission of privileged containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of privileged containers.\n        scored: false\n\n      - id: 5.2.3\n        text: \"Minimize the admission of containers wishing to share the host process ID namespace (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of `hostPID` containers.\n          Permissive - Enabling Pod Security Policy can cause applications to unexpectedly fail.\n        scored: true\n\n      - id: 5.2.4\n        text: \"Minimize the admission of containers wishing to share the host IPC namespace (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of `hostIPC` containers.\n          Permissive - Enabling Pod Security Policy can cause applications to unexpectedly fail.\n        scored: true\n\n      - id: 5.2.5\n        text: \"Minimize the admission of containers wishing to share the host network namespace (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of `hostNetwork` containers.\n          Permissive - Enabling Pod Security Policy can cause applications to unexpectedly fail.\n        scored: true\n\n      - id: 5.2.6\n        text: \"Minimize the admission of containers with allowPrivilegeEscalation (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers with `.spec.allowPrivilegeEscalation` set to `true`.\n        scored: false\n\n      - id: 5.2.7\n        text: \"Minimize the admission of root containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Create a policy for each namespace in the cluster, ensuring that either `MustRunAsNonRoot`\n          or `MustRunAs` with the range of UIDs not including 0, is set.\n        scored: false\n\n      - id: 5.2.8\n        text: \"Minimize the admission of containers with the NET_RAW capability (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers with the `NET_RAW` capability.\n        scored: false\n\n      - id: 5.2.9\n        text: \"Minimize the admission of containers with added capabilities (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that `allowedCapabilities` is not present in policies for the cluster unless\n          it is set to an empty array.\n        scored: false\n\n      - id: 5.2.10\n        text: \"Minimize the admission of containers with capabilities assigned (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Review the use of capabilites in applications running on your cluster. Where a namespace\n          contains applicaions which do not require any Linux capabities to operate consider adding\n          a PSP which forbids the admission of containers which do not drop all capabilities.\n        scored: false\n\n      - id: 5.2.11\n        text: \"Minimize the admission of Windows HostProcess containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers that have `.securityContext.windowsOptions.hostProcess` set to `true`.\n        scored: false\n\n      - id: 5.2.12\n        text: \"Minimize the admission of HostPath volumes (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers with `hostPath` volumes.\n        scored: false\n\n      - id: 5.2.13\n        text: \"Minimize the admission of containers which use HostPorts (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Add policies to each namespace in the cluster which has user workloads to restrict the\n          admission of containers which use `hostPort` sections.\n        scored: false\n\n  - id: 5.3\n    text: \"Network Policies and CNI\"\n    checks:\n      - id: 5.3.1\n        text: \"Ensure that the CNI in use supports NetworkPolicies (Manual)\"\n        type: \"manual\"\n        remediation: |\n          If the CNI plugin in use does not support network policies, consideration should be given to\n          making use of a different plugin, or finding an alternate mechanism for restricting traffic\n          in the Kubernetes cluster.\n        scored: false\n\n      - id: 5.3.2\n        text: \"Ensure that all Namespaces have NetworkPolicies defined (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the documentation and create NetworkPolicy objects as you need them.\n          Permissive - Enabling Network Policies can prevent certain applications from communicating with each other.\n        scored: false\n\n  - id: 5.4\n    text: \"Secrets Management\"\n    checks:\n      - id: 5.4.1\n        text: \"Prefer using Secrets as files over Secrets as environment variables (Manual)\"\n        type: \"manual\"\n        remediation: |\n          If possible, rewrite application code to read Secrets from mounted secret files, rather than\n          from environment variables.\n        scored: false\n\n      - id: 5.4.2\n        text: \"Consider external secret storage (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Refer to the Secrets management options offered by your cloud provider or a third-party\n          secrets management solution.\n        scored: false\n\n  - id: 5.5\n    text: \"Extensible Admission Control\"\n    checks:\n      - id: 5.5.1\n        text: \"Configure Image Provenance using ImagePolicyWebhook admission controller (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and setup image provenance.\n        scored: false\n\n  - id: 5.7\n    text: \"General Policies\"\n    checks:\n      - id: 5.7.1\n        text: \"Create administrative boundaries between resources using namespaces (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the documentation and create namespaces for objects in your deployment as you need\n          them.\n        scored: false\n\n      - id: 5.7.2\n        text: \"Ensure that the seccomp profile is set to docker/default in your Pod definitions (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Use `securityContext` to enable the docker/default seccomp profile in your pod definitions.\n          An example is as below:\n            securityContext:\n              seccompProfile:\n                type: RuntimeDefault\n        scored: false\n\n      - id: 5.7.3\n        text: \"Apply SecurityContext to your Pods and Containers (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and apply SecurityContexts to your Pods. For a\n          suggested list of SecurityContexts, you may refer to the CIS Security Benchmark for Docker\n          Containers.\n        scored: false\n\n      - id: 5.7.4\n        text: \"The default namespace should not be used (Manual)\"\n        type: \"manual\"\n        remediation: |\n          Ensure that namespaces are created to allow for appropriate segregation of Kubernetes\n          resources and that all new resources are created in a specific namespace.\n          Permissive - Kubernetes provides a default namespace.\n        scored: false\n"
  },
  {
    "path": "cfg/tkgi-1.2.53/config.yaml",
    "content": "---\n## Version-specific settings that override the values in cfg/config.yaml\n"
  },
  {
    "path": "cfg/tkgi-1.2.53/controlplane.yaml",
    "content": "---\ncontrols:\nversion: \"tkgi-1.2.53\"\nid: 3\ntext: \"Control Plane Configuration\"\ntype: \"controlplane\"\ngroups:\n  - id: 3.1\n    text: \"Authentication and Authorization\"\n    checks:\n      - id: 3.1.1\n        text: \"Client certificate authentication should not be used for users\"\n        audit: ps -ef | grep kube-apiserver | grep -- \"--oidc-issuer-url=\"\n        type: \"manual\"\n        remediation: |\n          Alternative mechanisms provided by Kubernetes such as the use of OIDC should be\n          implemented in place of client certificates.\n          Exception\n          This setting is site-specific. It can be set in the \"Configure created clusters to use UAA as the OIDC provider.\"\n          section of the \"UAA\"\n        scored: false\n\n  - id: 3.2\n    text: \"Logging\"\n    checks:\n      - id: 3.2.1\n        text: \"Ensure that a minimal audit policy is created\"\n        audit: ps -ef | grep kube-apiserver | grep -v tini | grep -- \"--audit-policy-file=\"\n        tests:\n          test_items:\n            - flag: \"--audit-policy-file\"\n        remediation: |\n          Create an audit policy file for your cluster.\n        scored: true\n\n      - id: 3.2.2\n        text: \"Ensure that the audit policy covers key security concerns\"\n        audit: |\n          diff /var/vcap/jobs/kube-apiserver/config/audit_policy.yml \\ <(echo \"--- apiVersion: audit.k8s.io/v1beta1 kind:\n          Policy rules: - level: None resources: - group: '' resources: - endpoints - services - services/status users: -\n          system:kube-proxy verbs: - watch - level: None resources: - group: '' resources: - nodes - nodes/status users: -\n          kubelet verbs: - get - level: None resources: - group: '' resources: - nodes - nodes/status userGroups: -\n          system:nodes verbs: - get - level: None namespaces: - kube-system resources: - group: '' resources: -\n          endpoints users: - system:kube-controller-manager - system:kube-scheduler - system:serviceaccount:kube-\n          system:endpoint-controller verbs: - get - update - level: None resources: - group: '' resources: - namespaces -\n          namespaces/status - namespaces/finalize users: - system:apiserver verbs: - get - level: None resources: -\n          group: metrics.k8s.io users: - system:kube-controller-manager verbs: - get - list - level: None\n          nonResourceURLs: - \\\"/healthz*\\\" - \\\"/version\\\" - \\\"/swagger*\\\" - level: None resources: - group: '' resources: -\n          events - level: Request omitStages: - RequestReceived resources: - group: '' resources: - nodes/status -\n          pods/status userGroups: - system:nodes verbs: - update - patch - level: Request omitStages: -\n          RequestReceived users: - system:serviceaccount:kube-system:namespace-controller verbs: - deletecollection -\n          level: Metadata omitStages: - RequestReceived resources: - group: '' resources: - secrets - configmaps - group:\n          authentication.k8s.io resources: - tokenreviews - level: Request omitStages: - RequestReceived resources: -\n          group: '' - group: admissionregistration.k8s.io - group: apiextensions.k8s.io - group: apiregistration.k8s.io -\n          group: apps - group: authentication.k8s.io - group: authorization.k8s.io - group: autoscaling - group: batch -\n          group: certificates.k8s.io - group: extensions - group: metrics.k8s.io - group: networking.k8s.io - group: policy -\n          group: rbac.authorization.k8s.io - group: settings.k8s.io - group: storage.k8s.io verbs: - get - list - watch - level:\n          RequestResponse omitStages: - RequestReceived resources: - group: '' - group: admissionregistration.k8s.io -\n          group: apiextensions.k8s.io - group: apiregistration.k8s.io - group: apps - group: authentication.k8s.io - group:\n          authorization.k8s.io - group: autoscaling - group: batch - group: certificates.k8s.io - group: extensions - group:\n          metrics.k8s.io - group: networking.k8s.io - group: policy - group: rbac.authorization.k8s.io - group:\n          settings.k8s.io - group: storage.k8s.io - level: Metadata omitStages: - RequestReceived \")\n        type: \"manual\"\n        remediation: |\n          Consider modification of the audit policy in use on the cluster to include these items, at a\n          minimum.\n        scored: false\n"
  },
  {
    "path": "cfg/tkgi-1.2.53/etcd.yaml",
    "content": "---\ncontrols:\nversion: \"tkgi-1.2.53\"\nid: 2\ntext: \"Etcd Node Configuration\"\ntype: \"etcd\"\ngroups:\n  - id: 2\n    text: \"Etcd Node Configuration Files\"\n    checks:\n      - id: 2.1\n        text: \"Ensure that the --cert-file and --key-file arguments are set as appropriate\"\n        audit: ps -ef | grep etcd | grep -- \"--cert-file=/var/vcap/jobs/etcd/config/etcd.crt\" | grep -- \"--key-file=/var/vcap/jobs/etcd/config/etcd.key\"\n        type: manual\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--cert-file\"\n            - flag: \"--key-file\"\n        remediation: |\n          Follow the etcd service documentation and configure TLS encryption.\n          Then, edit the etcd pod specification file /etc/kubernetes/manifests/etcd.yaml\n          on the master node and set the below parameters.\n          --cert-file=</path/to/ca-file>\n          --key-file=</path/to/key-file>\n        scored: false\n\n      - id: 2.2\n        text: \"Ensure that the --client-cert-auth argument is set to true\"\n        audit: ps -ef | grep etcd | grep -- \"--client\\-cert\\-auth\"\n        tests:\n          test_items:\n            - flag: \"--client-cert-auth\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Edit the etcd pod specification file etcd config on the master\n          node and set the below parameter.\n          --client-cert-auth=\"true\"\n        scored: true\n\n      - id: 2.3\n        text: \"Ensure that the --auto-tls argument is not set to true\"\n        audit: ps -ef | grep etcd | grep -v -- \"--auto-tls\"\n        tests:\n          test_items:\n            - flag: \"--auto-tls\"\n              compare:\n                op: eq\n                value: true\n              set: false\n        remediation: |\n          Edit the etcd pod specification file etcd config on the master\n          node and either remove the --auto-tls parameter or set it to false.\n            --auto-tls=false\n        scored: true\n\n      - id: 2.4\n        text: \"Ensure that the --peer-cert-file and --peer-key-file arguments are set as appropriate\"\n        audit: ps -ef | grep etcd | grep -- \"--peer-cert-file=/var/vcap/jobs/etcd/config/peer.crt\" | grep -- \"--peer-key-file=/var/vcap/jobs/etcd/config/peer.key\"\n        type: manual\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--peer-cert-file\"\n            - flag: \"--peer-key-file\"\n        remediation: |\n          Follow the etcd service documentation and configure peer TLS encryption as appropriate\n          for your etcd cluster.\n          Then, edit the etcd pod specification file etcd config on the\n          master node and set the below parameters.\n          --peer-client-file=</path/to/peer-cert-file>\n          --peer-key-file=</path/to/peer-key-file>\n        scored: false\n\n      - id: 2.5\n        text: \"Ensure that the --peer-client-cert-auth argument is set to true\"\n        audit: ps -ef | grep etcd | grep -- \"--peer\\-client\\-cert\\-auth\"\n        tests:\n          test_items:\n            - flag: \"--peer-client-cert-auth\"\n              compare:\n                op: eq\n                value: true\n        remediation: |\n          Edit the etcd pod specification file etcd config on the master\n          node and set the below parameter.\n          --peer-client-cert-auth=true\n        scored: true\n\n      - id: 2.6\n        text: \"Ensure that the --peer-auto-tls argument is not set to true\"\n        audit: ps -ef | grep etcd | grep -v -- \"--peer-auto-tls\"\n        tests:\n          test_items:\n            - flag: \"--peer-auto-tls\"\n              compare:\n                op: eq\n                value: true\n              set: false\n        remediation: |\n          Edit the etcd pod specification file etcd config on the master\n          node and either remove the --peer-auto-tls parameter or set it to false.\n          --peer-auto-tls=false\n        scored: true\n\n      - id: 2.7\n        text: \"Ensure that a unique Certificate Authority is used for etcd\"\n        audit: diff /var/vcap/jobs/kube-apiserver/config/kubernetes-ca.pem /var/vcap/jobs/etcd/config/etcd-ca.crt | grep -c\"^>\" | grep -v \"^0$\"\n        type: manual\n        tests:\n          test_items:\n            - flag: \"--trusted-ca-file\"\n        remediation: |\n          Follow the etcd documentation and create a dedicated certificate authority setup for the\n          etcd service.\n          Then, edit the etcd pod specification file etcd config on the\n          master node and set the below parameter.\n          --trusted-ca-file=</path/to/ca-file>\n        scored: false\n"
  },
  {
    "path": "cfg/tkgi-1.2.53/master.yaml",
    "content": "---\ncontrols:\nversion: \"tkgi-1.2.53\"\nid: 1\ntext: \"Master Node Security Configuration\"\ntype: \"master\"\ngroups:\n  - id: 1.1\n    text: \"Master Node Configuration Files\"\n    checks:\n      - id: 1.1.1\n        text: \"Ensure that the API server pod specification file permissions are set to 644 or more restrictive\"\n        audit: stat -c permissions=%a /var/vcap/jobs/kube-apiserver/config/bpm.yml\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the\n          master node.\n          For example, chmod 644 /var/vcap/jobs/kube-apiserver/config/bpm.yml\n        scored: true\n\n      - id: 1.1.2\n        text: \"Ensure that the API server pod specification file ownership is set to root:root\"\n        audit: stat -c %U:%G /var/vcap/jobs/kube-apiserver/config/bpm.yml\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the\n          master node.\n          For example, chown root:root /var/vcap/jobs/kube-apiserver/config/bpm.yml\n        scored: true\n\n      - id: 1.1.3\n        text: \"Ensure that the controller manager pod specification file permissions are set to 644 or more restrictive\"\n        audit: stat -c permissions=%a /var/vcap/jobs/kube-controller-manager/config/bpm.yml\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the\n          master node.\n          For example, chmod 644 /var/vcap/jobs/kube-apiserver/config/bpm.yml\n        scored: true\n\n      - id: 1.1.4\n        text: \"Ensure that the controller manager pod specification file ownership is set to root:root\"\n        audit: stat -c %U:%G /var/vcap/jobs/kube-controller-manager/config/bpm.yml\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the\n          master node.\n          For example, chown root:root /etc/kubernetes/manifests/kube-controller-manager.yaml\n        scored: true\n\n      - id: 1.1.5\n        text: \"Ensure that the scheduler pod specification file permissions are set to 644 or more restrictive\"\n        audit: stat -c permissions=%a /var/vcap/jobs/kube-scheduler/config/bpm.yml\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the\n          master node.\n          For example, chown 644 /var/vcap/jobs/kube-scheduler/config/bpm.yml\n        scored: true\n\n      - id: 1.1.6\n        text: \"Ensure that the scheduler pod specification file ownership is set to root:root\"\n        audit: stat -c %U:%G /var/vcap/jobs/kube-scheduler/config/bpm.yml\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chown root:root /var/vcap/jobs/kube-scheduler/config/bpm.yml\n        scored: true\n\n      - id: 1.1.7\n        text: \"Ensure that the etcd pod specification file permissions are set to 644 or more restrictive\"\n        audit: stat -c permissions=%a /var/vcap/jobs/etcd/config/bpm.yml\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chmod 644 stat -c permissions=%a /var/vcap/jobs/etcd/config/bpm.yml\n        scored: true\n\n      - id: 1.1.8\n        text: \"Ensure that the etcd pod specification file ownership is set to root:root\"\n        audit: stat -c %U:%G /var/vcap/jobs/etcd/config/bpm.yml\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chown root:root /var/vcap/jobs/etcd/config/bpm.yml\n        scored: true\n\n      - id: 1.1.9\n        text: \"Ensure that the Container Network Interface file permissions are set to 644 or more restrictive\"\n        audit: find ((CNI_DIR))/config/ -type f -not -perm 640 | awk 'END{print NR}' | grep \"^0$\"\n        type: manual\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chmod 644 <path/to/cni/files>\n        scored: false\n\n      - id: 1.1.10\n        text: \"Ensure that the Container Network Interface file ownership is set to root:root\"\n        audit: find ((CNI_DIR))/config/ -type f -not -user root -or -not -group root | awk 'END{print NR}' | grep \"^0$\"\n        type: manual\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chown root:root <path/to/cni/files>\n        scored: false\n\n      - id: 1.1.11\n        text: \"Ensure that the etcd data directory permissions are set to 700 or more restrictive\"\n        audit: stat -c permissions=%a /var/vcap/store/etcd/\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"700\"\n        remediation: |\n          Run the below command (based on the etcd data directory found above). For example,\n          chmod 700 /var/vcap/store/etcd/\n        scored: true\n\n      - id: 1.1.12\n        text: \"Ensure that the etcd data directory ownership is set to etcd:etcd\"\n        audit: stat -c %U:%G /var/vcap/store/etcd/\n        type: manual\n        tests:\n          test_items:\n            - flag: \"etcd:etcd\"\n        remediation: |\n          Run the below command (based on the etcd data directory found above).\n          For example, chown etcd:etcd /var/vcap/store/etcd/\n          Exception: All bosh processes run as vcap user\n          The etcd data directory ownership is vcap:vcap\n        scored: false\n\n      - id: 1.1.13\n        text: \"Ensure that the admin.conf file permissions are set to 644 or more restrictive\"\n        audit: stat -c permissions=%a /etc/kubernetes/admin.conf\n        type: manual\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chmod 644 /etc/kubernetes/admin.conf\n          Exception\n          kubeadm is not used to provision/bootstrap the cluster. kubeadm and associated config files do not exist on master\n          Reference: https://kubernetes.io/docs/reference/setup-tools/kubeadm/implementation-details/#generate-\n          kubeconfig-files-for-control-plane-components\n        scored: false\n\n      - id: 1.1.14\n        text: \"Ensure that the admin.conf file ownership is set to root:root\"\n        audit: stat -c %U:%G /etc/kubernetes/admin.conf\n        type: manual\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chown root:root /etc/kubernetes/admin.conf\n          Exception\n          kubeadm is not used to provision/bootstrap the cluster. kubeadm and associated config files do not exist on\n          master\n          Reference: https://kubernetes.io/docs/reference/setup-tools/kubeadm/implementation-details/#generate-\n          kubeconfig-files-for-control-plane-components\n        scored: false\n\n      - id: 1.1.15\n        text: \"Ensure that the scheduler configuration file permissions are set to 644\"\n        audit: stat -c permissions=%a /etc/kubernetes/scheduler.conf\n        type: manual\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chmod 644 /etc/kubernetes/scheduler.conf\n          Exception\n          kubeadm is not used to provision/bootstrap the cluster. kubeadm and associated config files do not exist on\n          master\n          Reference: https://kubernetes.io/docs/reference/setup-tools/kubeadm/implementation-details/#generate-\n          kubeconfig-files-for-control-plane-components\n        scored: false\n\n      - id: 1.1.16\n        text: \"Ensure that the scheduler configuration file ownership is set to root:root\"\n        audit: stat -c %U:%G /etc/kubernetes/scheduler.conf\n        type: manual\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chown root:root /etc/kubernetes/scheduler.conf\n          Exception\n          kubeadm is not used to provision/bootstrap the cluster. kubeadm and associated config files do not exist on\n          master\n          Reference: https://kubernetes.io/docs/reference/setup-tools/kubeadm/implementation-details/#generate-\n          kubeconfig-files-for-control-plane-components\n        scored: false\n\n      - id: 1.1.17\n        text: \"Ensure that the controller manager configuration file permissions are set to 644\"\n        audit: stat -c permissions=%a /etc/kubernetes/controller-manager.conf\n        type: manual\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chmod 644 /etc/kubernetes/controller-manager.conf\n          Exception\n          kubeadm is not used to provision/bootstrap the cluster. kubeadm and associated config files do not exist on\n          master\n          Reference: https://kubernetes.io/docs/reference/setup-tools/kubeadm/implementation-details/#generate-\n          kubeconfig-files-for-control-plane-components\n        scored: false\n\n      - id: 1.1.18\n        text: \"Ensure that the controller manager configuration file ownership is set to root:root\"\n        audit: stat -c %U:%G /etc/kubernetes/controller-manager.conf\n        type: manual\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chown root:root /etc/kubernetes/controller-manager.conf\n          Exception\n          kubeadm is not used to provision/bootstrap the cluster. kubeadm and associated config files do not exist on\n          master\n          Reference: https://kubernetes.io/docs/reference/setup-tools/kubeadm/implementation-details/#generate-\n          kubeconfig-files-for-control-plane-components\n        scored: false\n\n      - id: 1.1.19\n        text: \"Ensure that the Kubernetes PKI directory and file ownership is set to root:root\"\n        audit: |\n          find -L /var/vcap/jobs/kube-apiserver/config /var/vcap/jobs/kube-controller-manager/config /var/vcap/jobs/kube-\n          scheduler/config ((CNI_DIR))/config /var/vcap/jobs/etcd/config | sort -u | xargs ls -ld | awk '{ print $3 \" \" $4}' |\n          grep -c -v \"root root\" | grep \"^0$\"\n        type: manual\n        tests:\n          test_items:\n            - flag: \"root:root\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chown -R root:root /etc/kubernetes/pki/\n          Exception\n          Files are group owned by vcap\n        scored: false\n\n      - id: 1.1.20\n        text: \"Ensure that the Kubernetes PKI certificate file permissions are set to 644 or more restrictive\"\n        audit: |\n          find -L /var/vcap/jobs/kube-apiserver/config \\( -name '*.crt' -or -name '*.pem' \\) -and -not -perm 640 | grep -v\n          \"packages/golang\" | grep -v \"packages/ncp_rootfs\" | awk 'END{print NR}' | grep \"^0$\"\n        type: manual\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chmod -R 644 /etc/kubernetes/pki/*.crt\n          Exception\n          Ignoring packages/golang as the package includes test certs used by golang. Ignoring packages/ncp_rootfs on\n          TKG1 with NSX-T container plugin uses the package is used as the overlay filesystem `mount | grep\n          \"packages/ncp_rootfs\"`\n        scored: false\n\n      - id: 1.1.21\n        text: \"Ensure that the Kubernetes PKI key file permissions are set to 600\"\n        audit: |\n          find -L /var/vcap/jobs/kube-apiserver/config -name '*.key' -and -not -perm 600 | awk 'END{print NR}' | grep \"^0$\"\n        type: manual\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: eq\n                value: \"600\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the master node.\n          For example,\n          chmod -R 600 /etc/kubernetes/pki/*.key\n          Exception\n          Permission on etcd .key files is set to 640, to allow read access to vcap group\n        scored: false\n\n  - id: 1.2\n    text: \"API Server\"\n    checks:\n      - id: 1.2.1\n        text: \"Ensure that the --anonymous-auth argument is set to false\"\n        audit: ps -ef | grep kube-apiserver | grep -- \"--anonymous-auth=false\"\n        type: manual\n        tests:\n          test_items:\n            - flag: \"--anonymous-auth=false\"\n        remediation: |\n          Edit the API server pod specification file kube-apiserver\n          on the master node and set the below parameter.\n          --anonymous-auth=false\n          Exception\n          The flag is set to true to enable API discoveribility.\n          \"Starting in 1.6, the ABAC and RBAC authorizers require explicit authorization of the system:anonymous user or the\n          system:unauthenticated group, so legacy policy rules that grant access to the * user or * group do not include\n          anonymous users.\"\n          -authorization-mode is set to RBAC\n        scored: false\n\n      - id: 1.2.2\n        text: \"Ensure that the --basic-auth-file argument is not set\"\n        audit: ps -ef | grep kube-apiserver | grep -v -- \"--basic-auth-file\"\n        tests:\n          test_items:\n            - flag: \"--basic-auth-file\"\n              set: false\n        remediation: |\n          Follow the documentation and configure alternate mechanisms for authentication. Then,\n          edit the API server pod specification file kube-apiserver\n          on the master node and remove the --basic-auth-file=<filename> parameter.\n        scored: true\n\n      - id: 1.2.3\n        text: \"Ensure that the --token-auth-file parameter is not set\"\n        audit: ps -ef | grep \"/var/vcap/packages/kubernetes/bin/kube-apiserve[r]\" | grep -v tini | grep -v -- \"--token-auth-file=\"\n        type: manual\n        tests:\n          test_items:\n            - flag: \"--token-auth-file\"\n              set: false\n        remediation: |\n          Follow the documentation and configure alternate mechanisms for authentication. Then,\n          edit the API server pod specification file /var/vcap/packages/kubernetes/bin/kube-apiserve[r]\n          on the master node and remove the --token-auth-file=<filename> parameter.\n          Exception\n          Since k8s processes' lifecyle are managed by BOSH, token based authentication is required when processes\n          restart. The file has 0640 permission and root:vcap ownership\n        scored: false\n\n      - id: 1.2.4\n        text: \"Ensure that the --kubelet-https argument is set to true\"\n        audit: ps -ef | grep kube-apiserver | grep -v -- \"--kubelet-https=true\"\n        tests:\n          test_items:\n            - flag: \"--kubelet-https=true\"\n        remediation: |\n          Edit the API server pod specification file kube-apiserver\n          on the master node and remove the --kubelet-https parameter.\n        scored: true\n\n      - id: 1.2.5\n        text: \"Ensure that the --kubelet-client-certificate and --kubelet-client-key arguments are set as appropriate\"\n        audit: |\n          ps -ef | grep kube-apiserver | grep -- \"--kubelet-client-certificate=/var/vcap/jobs/kube-apiserver/config/kubelet-\n          client-cert.pem\" | grep -- \"--kubelet-client-key=/var/vcap/jobs/kube-apiserver/config/kubelet-client-key.pem\"\n        type: manual\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--kubelet-client-certificate\"\n            - flag: \"--kubelet-client-key\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection between the\n          apiserver and kubelets. Then, edit API server pod specification file\n          kube-apiserver on the master node and set the\n          kubelet client certificate and key parameters as below.\n          --kubelet-client-certificate=<path/to/client-certificate-file>\n          --kubelet-client-key=<path/to/client-key-file>\n        scored: false\n\n      - id: 1.2.6\n        text: \"Ensure that the --kubelet-certificate-authority argument is set as appropriate\"\n        audit: ps -ef | grep kube-apiserver | grep -- \"--kubelet-certificate-authority=\"\n        type: manual\n        tests:\n          test_items:\n            - flag: \"--kubelet-certificate-authority\"\n        remediation: |\n          Follow the Kubernetes documentation and setup the TLS connection between\n          the apiserver and kubelets. Then, edit the API server pod specification file\n          kube-apiserver on the master node and set the\n          --kubelet-certificate-authority parameter to the path to the cert file for the certificate authority.\n          --kubelet-certificate-authority=<ca-string>\n          Exception\n          JIRA ticket #PKS-696 created to investigate a fix. PR opened to address the issue https://github.com/cloudfoundry-\n          incubator/kubo-release/pull/179\n        scored: false\n\n      - id: 1.2.7\n        text: \"Ensure API server authorization modes does not include AlwaysAllow\"\n        audit: |\n          ps -ef | grep kube-apiserver | grep -- \"--authorization-mode\" && ps -ef | grep kube-apiserver | grep -v -- \"--\n          authorization-mode=\\(\\w\\+\\|,\\)*AlwaysAllow\\(\\w\\+\\|,\\)*\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: nothave\n                value: \"AlwaysAllow\"\n        remediation: |\n          Edit the API server pod specification file kube-apiserver\n          on the master node and set the --authorization-mode parameter to values other than AlwaysAllow.\n          One such example could be as below.\n          --authorization-mode=RBAC\n        scored: true\n\n      - id: 1.2.8\n        text: \"Ensure that the --authorization-mode argument includes Node\"\n        audit: |\n          ps -ef | grep kube-apiserver | grep -v tini | grep -- \"--authorization-mode=\\(\\w\\+\\|,\\)*Node\\(\\w\\+\\|,\\)* --\"\n        type: manual\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: has\n                value: \"Node\"\n        remediation: |\n          Edit the API server pod specification file kube-apiserver\n          on the master node and set the --authorization-mode parameter to a value that includes Node.\n          --authorization-mode=Node,RBAC\n          Exception\n          This flag can be added using Kubernetes Profiles. Please follow instructions here https://docs.pivotal.io/tkgi/1-\n          8/k8s-profiles.html\n        scored: false\n\n      - id: 1.2.9\n        text: \"Ensure that the --authorization-mode argument includes RBAC\"\n        audit: ps -ef | grep kube-apiserver | grep -v tini | grep -- \"--authorization-mode=\\(\\w\\+\\|,\\)*RBAC\\(\\w\\+\\|,\\)* --\"\n        tests:\n          test_items:\n            - flag: \"--authorization-mode\"\n              compare:\n                op: has\n                value: \"RBAC\"\n        remediation: |\n          Edit the API server pod specification file kube-apiserver\n          on the master node and set the --authorization-mode parameter to a value that includes RBAC,\n          for example:\n          --authorization-mode=Node,RBAC\n        scored: true\n\n      - id: 1.2.10\n        text: \"Ensure that the admission control plugin EventRateLimit is set\"\n        audit: |\n          ps -ef | grep kube-apiserver | grep -v tini | grep -- \"--enable-admission-plugins=\\(\\w\\+\\|,\\)*EventRateLimit\\\n          (\\w\\+\\|,\\)*\"\n        type: manual\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"EventRateLimit\"\n        remediation: |\n          Follow the Kubernetes documentation and set the desired limits in a configuration file.\n          Then, edit the API server pod specification file kube-apiserver\n          and set the below parameters.\n          --enable-admission-plugins=...,EventRateLimit,...\n          --admission-control-config-file=<path/to/configuration/file>\n          Exception\n          \"Note: This is an Alpha feature in the Kubernetes v1.13\"\n          Control provides rate limiting and is site-specific\n        scored: false\n\n      - id: 1.2.11\n        text: \"Ensure that the admission control plugin AlwaysAdmit is not set\"\n        audit: |\n          ps -ef | grep kube-apiserver | grep -v -- \"--enable-admission-plugins=\\(\\w\\+\\|,\\)*AlwaysAdmit\\(\\w\\+\\|,\\)*\"\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: nothave\n                value: AlwaysAdmit\n        remediation: |\n          Edit the API server pod specification file kube-apiserver\n          on the master node and either remove the --enable-admission-plugins parameter, or set it to a\n          value that does not include AlwaysAdmit.\n        scored: true\n\n      - id: 1.2.12\n        text: \"Ensure that the admission control plugin AlwaysPullImages is set\"\n        audit: |\n          ps -ef | grep kube-apiserver | grep -v tini | grep -- \"--enable-admission-plugins=\\(\\w\\+\\|,\\)*AlwaysPullImages\\\n          (\\w\\+\\|,\\)* --\"\n        type: manual\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"AlwaysPullImages\"\n        remediation: |\n          Edit the API server pod specification file kube-apiserver\n          on the master node and set the --enable-admission-plugins parameter to include\n          AlwaysPullImages.\n          --enable-admission-plugins=...,AlwaysPullImages,...\n          Exception\n          \"Credentials would be required to pull the private images every time. Also, in trusted\n          environments, this might increases load on network, registry, and decreases speed.\n          This setting could impact offline or isolated clusters, which have images pre-loaded and do\n          not have access to a registry to pull in-use images. This setting is not appropriate for\n          clusters which use this configuration.\"\n          TKGi is packages with pre-loaded images.\n        scored: false\n\n      - id: 1.2.13\n        text: \"Ensure that the admission control plugin SecurityContextDeny is set\"\n        audit: |\n          ps -ef | grep kube-apiserver | grep -v tini | grep -- \"--enable-admission-plugins=\\(\\w\\+\\|,\\)*SecurityContextDeny\\\n          (\\w\\+\\|,\\)* --\"\n        type: manual\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"SecurityContextDeny\"\n        remediation: |\n          Edit the API server pod specification file kube-apiserver\n          on the master node and set the --enable-admission-plugins parameter to include\n          SecurityContextDeny, unless PodSecurityPolicy is already in place.\n          --enable-admission-plugins=...,SecurityContextDeny,...\n          Exception\n          This setting is site-specific. It can be set in the \"Admission Plugins\" section of the appropriate \"Plan\"\n        scored: false\n\n      - id: 1.2.14\n        text: \"Ensure that the admission control plugin ServiceAccount is set\"\n        audit: |\n          ps -ef | grep kube-apiserver | grep -v tini | grep -v -- \"--disable-admission-plugins=\\(\\w\\+\\|,\\)*ServiceAccount\\\n          (\\w\\+\\|,\\)* --\"\n        tests:\n          test_items:\n            - flag: \"--disable-admission-plugins\"\n              compare:\n                op: nothave\n                value: \"ServiceAccount\"\n        remediation: |\n          Follow the documentation and create ServiceAccount objects as per your environment.\n          Then, edit the API server pod specification file kube-apiserver\n          on the master node and ensure that the --disable-admission-plugins parameter is set to a\n          value that does not include ServiceAccount.\n        scored: true\n\n      - id: 1.2.15\n        text: \"Ensure that the admission control plugin NamespaceLifecycle is set\"\n        audit: |\n          ps -ef | grep kube-apiserver | grep -v tini | grep -v -- \"--disable-admission-plugins=\\\n          (\\w\\+\\|,\\)*NamespaceLifecycle\\(\\w\\+\\|,\\)* --\"\n        tests:\n          test_items:\n            - flag: \"--disable-admission-plugins\"\n              compare:\n                op: nothave\n                value: \"NamespaceLifecycle\"\n        remediation: |\n          Edit the API server pod specification file kube-apiserver\n          on the master node and set the --disable-admission-plugins parameter to\n          ensure it does not include NamespaceLifecycle.\n        scored: true\n\n      - id: 1.2.16\n        text: \"Ensure that the admission control plugin PodSecurityPolicy is set\"\n        audit: |\n          ps -ef | grep kube-apiserver | grep -v tini | grep -- \"--enable-admission-plugins=\\(\\w\\+\\|,\\)*PodSecurityPolicy\\\n          (\\w\\+\\|,\\)* --\"\n        type: manual\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"PodSecurityPolicy\"\n        remediation: |\n          Follow the documentation and create Pod Security Policy objects as per your environment.\n          Then, edit the API server pod specification file kube-apiserver\n          on the master node and set the --enable-admission-plugins parameter to a\n          value that includes PodSecurityPolicy:\n          --enable-admission-plugins=...,PodSecurityPolicy,...\n          Then restart the API Server.\n          Exception\n          This setting is site-specific. It can be set in the \"Admission Plugins\" section of the appropriate \"Plan\"\n        scored: false\n\n      - id: 1.2.17\n        text: \"Ensure that the admission control plugin NodeRestriction is set\"\n        audit: |\n          ps -ef | grep kube-apiserver | grep -v tini | grep -- \"--enable-admission-plugins=\\(\\w\\+\\|,\\)*NodeRestriction\\\n          (\\w\\+\\|,\\)* --\"\n        type: manual\n        tests:\n          test_items:\n            - flag: \"--enable-admission-plugins\"\n              compare:\n                op: has\n                value: \"NodeRestriction\"\n        remediation: |\n          Follow the Kubernetes documentation and configure NodeRestriction plug-in on kubelets.\n          Then, edit the API server pod specification file kube-apiserver\n          on the master node and set the --enable-admission-plugins parameter to a\n          value that includes NodeRestriction.\n          --enable-admission-plugins=...,NodeRestriction,...\n          Exception\n          PR opened to address the issue https://github.com/cloudfoundry-incubator/kubo-release/pull/179\"\n        scored: true\n\n      - id: 1.2.18\n        text: \"Ensure that the --insecure-bind-address argument is not set\"\n        audit: |\n          ps -ef | grep kube-apiserver | grep -v tini | grep -v -- \"--insecure-bind-address\"\n        tests:\n          test_items:\n            - flag: \"--insecure-bind-address\"\n              set: false\n        remediation: |\n          Edit the API server pod specification file kube-apiserver\n          on the master node and remove the --insecure-bind-address parameter.\n        scored: true\n\n      - id: 1.2.19\n        text: \"Ensure that the --insecure-port argument is set to 0\"\n        audit: |\n          ps -ef | grep kube-apiserver | grep -v tini | grep -- \"--insecure-port=0\"\n        type: manual\n        tests:\n          test_items:\n            - flag: \"--insecure-port=0\"\n        remediation: |\n          Edit the API server pod specification file kube-apiserver\n          on the master node and set the below parameter.\n          --insecure-port=0\n          Exception\n          Related to 1.2.1\n          The insecure port is 8080, and is binding only to localhost on the master node, in use by other components on the\n          master that are bypassing authn/z.\n          The components connecting to the APIServer are:\n          kube-controller-manager\n          kube-proxy\n          kube-scheduler\n          Pods are not scheduled on the master node.\n        scored: false\n\n      - id: 1.2.20\n        text: \"Ensure that the --secure-port argument is not set to 0\"\n        audit: |\n          ps -ef | grep kube-apiserver | grep -v tini | grep -v -- \"--secure-port=0\"\n        tests:\n          test_items:\n            - flag: \"--secure-port\"\n              compare:\n                op: noteq\n                value: 0\n        remediation: |\n          Edit the API server pod specification file kube-apiserver\n          on the master node and either remove the --secure-port parameter or\n          set it to a different (non-zero) desired port.\n        scored: true\n\n      - id: 1.2.21\n        text: \"Ensure that the --profiling argument is set to false\"\n        audit: ps -ef | grep kube-apiserver | grep -v tini | grep -- \"--profiling=false\"\n        tests:\n          test_items:\n            - flag: \"--profiling=false\"\n        remediation: |\n          Edit the API server pod specification file kube-apiserver\n          on the master node and set the below parameter.\n          --profiling=false\n        scored: true\n\n      - id: 1.2.22\n        text: \"Ensure that the --audit-log-path argument is set as appropriate\"\n        audit: |\n          ps -ef | grep kube-apiserver | grep -v tini | grep -- \"--audit-log-path=\\/var\\/vcap\\/sys\\/log\\/kube-apiserver\\/audit.log\"\n        type: manual\n        tests:\n          test_items:\n            - flag: \"--audit-log-path\"\n        remediation: |\n          Edit the API server pod specification file kube-apiserver\n          on the master node and set the --audit-log-path parameter to a suitable path and\n          file where you would like audit logs to be written, for example:\n          --audit-log-path=/var/log/apiserver/audit.log\n        scored: false\n\n      - id: 1.2.23\n        text: \"Ensure that the --audit-log-maxage argument is set to 30 or as appropriate\"\n        audit: ps -ef | grep kube-apiserver | grep -v tini | grep -- \"--audit-log-maxage=30\"\n        type: manual\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxage=30\"\n        remediation: |\n          Edit the API server pod specification file kube-apiserver\n          on the master node and set the --audit-log-maxage parameter to 30 or as an appropriate number of days:\n          --audit-log-maxage=30\n          Exception\n          This setting can be set to expected value using Kubernetes Profiles. Please follow instructions here\n          https://docs.pivotal.io/tkgi/1-8/k8s-profiles.html\n        scored: false\n\n      - id: 1.2.24\n        text: \"Ensure that the --audit-log-maxbackup argument is set to 10 or as appropriate\"\n        audit: ps -ef | grep kube-apiserver | grep -v tini | grep -- \"--audit-log-maxbackup=10\"\n        type: manual\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxbackup=10\"\n        remediation: |\n          Edit the API server pod specification file kube-apiserver\n          on the master node and set the --audit-log-maxbackup parameter to 10 or to an appropriate\n          value.\n          --audit-log-maxbackup=10\n          Exception\n          This setting can be set to expected value using Kubernetes Profiles. Please follow instructions here\n          https://docs.pivotal.io/tkgi/1-8/k8s-profiles.html\n        scored: false\n\n      - id: 1.2.25\n        text: \"Ensure that the --audit-log-maxsize argument is set to 100 or as appropriate\"\n        audit: ps -ef | grep kube-apiserver | grep -v tini | grep -- \"--audit-log-maxsize=100\"\n        type: manual\n        tests:\n          test_items:\n            - flag: \"--audit-log-maxsize=100\"\n        remediation: |\n          Edit the API server pod specification file kube-apiserver\n          on the master node and set the --audit-log-maxsize parameter to an appropriate size in MB.\n          For example, to set it as 100 MB:\n          --audit-log-maxsize=100\n          Exception\n          This setting can be set to expected value using Kubernetes Profiles. Please follow instructions here\n          https://docs.pivotal.io/tkgi/1-8/k8s-profiles.html\n        scored: false\n\n      - id: 1.2.26\n        text: \"Ensure that the --request-timeout argument is set as appropriate\"\n        audit: ps -ef | grep kube-apiserver | grep -v tini | grep -v -- \"--request-timeout=\"\n        type: manual\n        tests:\n          test_items:\n            - flag: \"--request-timeout\"\n        remediation: |\n          Edit the API server pod specification file kube-apiserver\n          and set the below parameter as appropriate and if needed.\n          For example,\n          --request-timeout=300s\n        scored: false\n\n      - id: 1.2.27\n        text: \"Ensure that the --service-account-lookup argument is set to true\"\n        audit: ps -ef | grep kube-apiserver | grep -v tini | grep -v -- \"--service-account-lookup\"\n        tests:\n          test_items:\n            - flag: \"--service-account-lookup=true\"\n        remediation: |\n          Edit the API server pod specification file kube-apiserver\n          on the master node and set the below parameter.\n          --service-account-lookup=true\n          Alternatively, you can delete the --service-account-lookup parameter from this file so\n          that the default takes effect.\n        scored: true\n\n      - id: 1.2.28\n        text: \"Ensure that the --service-account-key-file argument is set as appropriate\"\n        audit: |\n          ps -ef | grep kube-apiserver | grep -v tini | grep -- \"--service-account-key-file=/var/vcap/jobs/kube-\n          apiserver/config/service-account-public-key.pem\"\n        type: manual\n        tests:\n          test_items:\n            - flag: \"--service-account-key-file\"\n        remediation: |\n          Edit the API server pod specification file kube-apiserver\n          on the master node and set the --service-account-key-file parameter\n          to the public key file for service accounts:\n          --service-account-key-file=<filename>\n        scored: false\n\n      - id: 1.2.29\n        text: \"Ensure that the --etcd-certfile and --etcd-keyfile arguments are set as appropriate\"\n        audit: |\n          ps -ef | grep kube-apiserver | grep -v tini | grep -- \"--etcd-certfile=/var/vcap/jobs/kube-apiserver/config/etcd-\n          client.crt\" | grep -- \"--etcd-keyfile=/var/vcap/jobs/kube-apiserver/config/etcd-client.key\"\n        type: manual\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--etcd-certfile\"\n            - flag: \"--etcd-keyfile\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection between the apiserver and etcd.\n          Then, edit the API server pod specification file kube-apiserver\n          on the master node and set the etcd certificate and key file parameters.\n          --etcd-certfile=<path/to/client-certificate-file>\n          --etcd-keyfile=<path/to/client-key-file>\n        scored: false\n\n      - id: 1.2.30\n        text: \"Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate\"\n        audit: |\n          ps -ef | grep kube-apiserver | grep -v tini | grep -- \"--tls-cert-file=/var/vcap/jobs/kube-apiserver/config/kubernetes.pem\" | grep -- \"--tls-private-key-file=/var/vcap/jobs/kube-\n          apiserver/config/kubernetes-key.pem\"\n        type: manual\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"--tls-cert-file\"\n            - flag: \"--tls-private-key-file\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection on the apiserver.\n          Then, edit the API server pod specification file kube-apiserver\n          on the master node and set the TLS certificate and private key file parameters.\n          --tls-cert-file=<path/to/tls-certificate-file>\n          --tls-private-key-file=<path/to/tls-key-file>\n        scored: false\n\n      - id: 1.2.31\n        text: \"Ensure that the --client-ca-file argument is set as appropriate\"\n        audit: |\n          ps -ef | grep kube-apiserver | grep -v tini | grep -- \"--client-ca-file=/var/vcap/jobs/kube-apiserver/config/kubernetes-ca.pem\"\n        type: manual\n        tests:\n          test_items:\n            - flag: \"--client-ca-file\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection on the apiserver.\n          Then, edit the API server pod specification file kube-apiserver\n          on the master node and set the client certificate authority file.\n          --client-ca-file=<path/to/client-ca-file>\n        scored: false\n\n      - id: 1.2.32\n        text: \"Ensure that the --etcd-cafile argument is set as appropriate\"\n        audit: |\n          ps -ef | grep kube-apiserver | grep -v tini | grep -- \"--etcd-cafile=/var/vcap/jobs/kube-apiserver/config/etcd-ca.crt\"\n        type: manual\n        tests:\n          test_items:\n            - flag: \"--etcd-cafile\"\n        remediation: |\n          Follow the Kubernetes documentation and set up the TLS connection between the apiserver and etcd.\n          Then, edit the API server pod specification file kube-apiserver\n          on the master node and set the etcd certificate authority file parameter.\n          --etcd-cafile=<path/to/ca-file>\n        scored: false\n\n      - id: 1.2.33\n        text: \"Ensure that the --encryption-provider-config argument is set as appropriate\"\n        audit: |\n          ps -ef | grep kube-apiserver | grep -v tini | grep -- \"--encryption-provider-config=\"\n        type: manual\n        tests:\n          test_items:\n            - flag: \"--encryption-provider-config\"\n        remediation: |\n          Follow the Kubernetes documentation and configure a EncryptionConfig file.\n          Then, edit the API server pod specification file kube-apiserver\n          on the master node and set the --encryption-provider-config parameter to the path of that file: --encryption-provider-config=</path/to/EncryptionConfig/File>\n          Exception\n          Encrypting Secrets in an etcd database can be enabled using Kubernetes Profiles. Please follow instructions here\n          https://docs.pivotal.io/tkgi/1-8/k8s-profiles-encrypt-etcd.html\n        scored: false\n\n      - id: 1.2.34\n        text: \"Ensure that the encryption provider is set to aescbc\"\n        audit: |\n          ENC_CONF=`ps -ef | grep kube-apiserver | grep -v tini | sed $'s/ /\\\\\\\\\\\\n/g' | grep -- '--encryption-provider-\n          config=' | cut -d'=' -f2` grep -- \"- \\(aescbc\\|kms\\|secretbox\\):\" $ENC_CONF\n        type: manual\n        remediation: |\n          Follow the Kubernetes documentation and configure a EncryptionConfig file.\n          In this file, choose aescbc, kms or secretbox as the encryption provider.\n          Exception\n          Encrypting Secrets in an etcd database can be enabled using Kubernetes Profiles. Please follow instructions here\n          https://docs.pivotal.io/tkgi/1-8/k8s-profiles-encrypt-etcd.html\n        scored: false\n\n      - id: 1.2.35\n        text: \"Ensure that the API Server only makes use of Strong Cryptographic Ciphers\"\n        audit: ps -ef | grep kube-apiserver | grep -v tini | grep -- \"--tls-cipher-suites=\"\n        type: manual\n        tests:\n          test_items:\n            - flag: \"--tls-cipher-suites\"\n              compare:\n                op: valid_elements\n                value: \"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\"\n        remediation: |\n          Edit the API server pod specification file /etc/kubernetes/manifests/kube-apiserver.yaml\n          on the master node and set the below parameter.\n          --tls-cipher-suites=TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM\n          _SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM\n          _SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM\n          _SHA384\n        scored: false\n\n  - id: 1.3\n    text: \"Controller Manager\"\n    checks:\n      - id: 1.3.1\n        text: \"Ensure that the --terminated-pod-gc-threshold argument is set as appropriate\"\n        audit: ps -ef | grep kube-controller-manager | grep -- \"--terminated-pod-gc-threshold=100\"\n        type: manual\n        tests:\n          test_items:\n            - flag: \"--terminated-pod-gc-threshold\"\n        remediation: |\n          Edit the Controller Manager pod specification file controller manager conf\n          on the master node and set the --terminated-pod-gc-threshold to an appropriate threshold,\n          for example:\n          --terminated-pod-gc-threshold=10\n        scored: false\n\n      - id: 1.3.2\n        text: \"Ensure controller manager profiling is disabled\"\n        audit: ps -ef | grep kube-controller-manager | grep -- \"--profiling=false\"\n        tests:\n          test_items:\n            - flag: \"--profiling=false\"\n        remediation: |\n          Edit the Controller Manager pod specification file controller manager conf\n          on the master node and set the below parameter.\n          --profiling=false\n        scored: true\n\n      - id: 1.3.3\n        text: \"Ensure that the --use-service-account-credentials argument is set to true\"\n        audit: ps -ef | grep kube-controller-manager | grep -- \"--use\\-service\\-account\\-credentials=true\"\n        tests:\n          test_items:\n            - flag: \"--use-service-account-credentials=true\"\n        remediation: |\n          Edit the Controller Manager pod specification file controller manager conf\n          on the master node to set the below parameter.\n          --use-service-account-credentials=true\n        scored: true\n\n      - id: 1.3.4\n        text: \"Ensure that the --service-account-private-key-file argument is set as appropriate\"\n        audit: |\n          ps -ef | grep kube-controller-manager | grep -- \"--service\\-account\\-private\\-key\\-file=\\/var\\/vcap\\/jobs\\/kube\\-\n          controller\\-manager\\/config\\/service\\-account\\-private\\-key.pem\"\n        type: manual\n        tests:\n          test_items:\n            - flag: \"--service-account-private-key-file\"\n        remediation: |\n          Edit the Controller Manager pod specification file controller manager conf\n          on the master node and set the --service-account-private-key-file parameter\n          to the private key file for service accounts.\n          --service-account-private-key-file=<filename>\n        scored: false\n\n      - id: 1.3.5\n        text: \"Ensure that the --root-ca-file argument is set as appropriate\"\n        audit: |\n          ps -ef | grep kube-controller-manager | grep -- \"--root\\-ca\\-file=\\/var\\/vcap\\/jobs\\/kube\\-controller\\-manager\\/config\\/ca.pem\"\n        type: manual\n        tests:\n          test_items:\n            - flag: \"--root-ca-file\"\n        remediation: |\n          Edit the Controller Manager pod specification file controller manager conf\n          on the master node and set the --root-ca-file parameter to the certificate bundle file`.\n          --root-ca-file=<path/to/file>\n        scored: false\n\n      - id: 1.3.6\n        text: \"Ensure that the RotateKubeletServerCertificate argument is set to true\"\n        audit: |\n          ps -ef | grep kube-controller-manager | grep -- \"--feature-gates=\\\n          (\\w\\+\\|,\\)*RotateKubeletServerCertificate=true\\(\\w\\+\\|,\\)*\"\n        type: manual\n        tests:\n          test_items:\n            - flag: \"--feature-gates=RotateKubeletServerCertificate=true\"\n        remediation: |\n          Edit the Controller Manager pod specification file controller manager conf\n          on the master node and set the --feature-gates parameter to include RotateKubeletServerCertificate=true.\n          --feature-gates=RotateKubeletServerCertificate=true\n          Exception\n          Certificate rotation is handled by Credhub\n        scored: false\n\n      - id: 1.3.7\n        text: \"Ensure that the --bind-address argument is set to 127.0.0.1\"\n        audit: |\n          ps -ef | grep \"/var/vcap/packages/kubernetes/bin/kube-controller-manage[r]\" | grep -v tini | grep -- \"--bind-address=127.0.0.1\"\n        type: manual\n        tests:\n          test_items:\n            - flag: \"--bind-address=127.0.0.1\"\n        remediation: |\n          Edit the Controller Manager pod specification file controller manager conf\n          on the master node and ensure the correct value for the --bind-address parameter\n          Exception\n          This setting can be set to expected value using Kubernetes Profiles. Please follow instructions here\n          https://docs.pivotal.io/tkgi/1-8/k8s-profiles.html\n        scored: false\n\n  - id: 1.4\n    text: \"Scheduler\"\n    checks:\n      - id: 1.4.1\n        text: \"Ensure that the --profiling argument is set to false\"\n        audit: ps -ef | grep kube-scheduler | grep -v tini | grep -- \"--profiling=false\"\n        tests:\n          test_items:\n            - flag: \"--profiling=false\"\n        remediation: |\n          Edit the Scheduler pod specification file scheduler config file\n          on the master node and set the below parameter.\n          --profiling=false\n        scored: true\n\n      - id: 1.4.2\n        text: \"Ensure that the --bind-address argument is set to 127.0.0.1\"\n        audit: ps -ef | grep \"/var/vcap/packages/kubernetes/bin/kube-schedule[r]\" | grep -v tini | grep -- \"--bind-address=127.0.0.1\"\n        type: manual\n        tests:\n          test_items:\n            - flag: \"--bind-address\"\n              compare:\n                op: eq\n                value: \"127.0.0.1\"\n        remediation: |\n          Edit the Scheduler pod specification file scheduler config\n          on the master node and ensure the correct value for the --bind-address parameter\n          Exception\n          This setting can be set to expected value using Kubernetes Profiles. Please follow instructions here\n          https://docs.pivotal.io/tkgi/1-8/k8s-profiles.html\n        scored: false\n"
  },
  {
    "path": "cfg/tkgi-1.2.53/node.yaml",
    "content": "---\ncontrols:\nversion: \"tkgi-1.2.53\"\nid: 4\ntext: \"Worker Node Security Configuration\"\ntype: \"node\"\ngroups:\n  - id: 4.1\n    text: \"Worker Node Configuration Files\"\n    checks:\n      - id: 4.1.1\n        text: \"Ensure that the kubelet service file permissions are set to 644 or more restrictive\"\n        audit: stat -c permissions=%a /var/vcap/jobs/kubelet/monit\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chmod 644 /var/vcap/jobs/kubelet/monit\n        scored: true\n\n      - id: 4.1.2\n        text: \"Ensure that the kubelet service file ownership is set to root:root\"\n        audit: stat -c %U:%G /var/vcap/jobs/kubelet/monit\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chown root:root /var/vcap/jobs/kubelet/monit\n          Exception\n          File is group owned by vcap\n        scored: true\n\n      - id: 4.1.3\n        text: \"Ensure that the proxy kubeconfig file permissions are set to 644 or more restrictive\"\n        audit: stat -c permissions=%a /var/vcap/jobs/kube-proxy/config/kubeconfig\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chmod 644 /var/vcap/jobs/kube-proxy/config/kubeconfig\n        scored: true\n\n      - id: 4.1.4\n        text: \"Ensure that the proxy kubeconfig file ownership is set to root:root\"\n        audit: stat -c %U:%G /var/vcap/jobs/kube-proxy/config/kubeconfig\n        type: manual\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example, chown root:root /var/vcap/jobs/kube-proxy/config/kubeconfig\n          Exception\n          File is group owned by vcap\n        scored: false\n\n      - id: 4.1.5\n        text: \"Ensure that the kubelet.conf file permissions are set to 644 or more restrictive\"\n        audit: stat -c permissions=%a /var/vcap/jobs/kube-proxy/config/kubeconfig\n        type: manual\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chmod 644 /var/vcap/jobs/kube-proxy/config/kubeconfig\n          Exception\n          kubeadm is not used to provision/bootstrap the cluster. kubeadm and associated config files do not exist on worker\n        scored: false\n\n      - id: 4.1.6\n        text: \"Ensure that the kubelet.conf file ownership is set to root:root\"\n        audit: stat -c %U:%G /etc/kubernetes/kubelet.conf\n        type: manual\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the below command (based on the file location on your system) on the each worker node.\n          For example,\n          chown root:root /etc/kubernetes/kubelet.conf\n          Exception\n          file ownership is vcap:vcap\n        scored: false\n\n      - id: 4.1.7\n        text: \"Ensure that the certificate authorities file permissions are set to 644 or more restrictive\"\n        audit: stat -c permissions=%a /var/vcap/jobs/kubelet/config/kubelet-client-ca.pem\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the following command to modify the file permissions of the\n          --client-ca-file chmod 644 <filename>\n        scored: true\n\n      - id: 4.1.8\n        text: \"Ensure that the client certificate authorities file ownership is set to root:root\"\n        audit: stat -c %U:%G /var/vcap/jobs/kubelet/config/kubelet-client-ca.pem\n        type: manual\n        tests:\n          test_items:\n            - flag: root:root\n              compare:\n                op: eq\n                value: root:root\n        remediation: |\n          Run the following command to modify the ownership of the --client-ca-file.\n          chown root:root <filename>\n          Exception\n          File is group owned by vcap\n        scored: false\n\n      - id: 4.1.9\n        text: \"Ensure that the kubelet --config configuration file has permissions set to 644 or more restrictive\"\n        audit: stat -c permissions=%a /var/vcap/jobs/kubelet/config/kubeletconfig.yml\n        tests:\n          test_items:\n            - flag: \"permissions\"\n              compare:\n                op: bitmask\n                value: \"644\"\n        remediation: |\n          Run the following command (using the config file location identified in the Audit step)\n          chmod 644 /var/vcap/jobs/kubelet/config/kubeletconfig.yml\n        scored: true\n\n      - id: 4.1.10\n        text: \"Ensure that the kubelet --config configuration file ownership is set to root:root\"\n        audit: stat -c %U:%G /var/vcap/jobs/kubelet/config/kubeletconfig.yml\n        type: manual\n        tests:\n          test_items:\n            - flag: root:root\n        remediation: |\n          Run the following command (using the config file location identified in the Audit step)\n          chown root:root /var/vcap/jobs/kubelet/config/kubeletconfig.yml\n          Exception\n          File is group owned by vcap\n        scored: false\n\n  - id: 4.2\n    text: \"Kubelet\"\n    checks:\n      - id: 4.2.1\n        text: \"Ensure that the anonymous-auth argument is set to false\"\n        audit: grep \"^authentication:\\n\\s{2}anonymous:\\n\\s{4}enabled:\\sfalse$\" /var/vcap/jobs/kubelet/config/kubeletconfig.yml\n        tests:\n          test_items:\n            - flag: \"enabled: false\"\n        remediation: |\n          If using a Kubelet config file, edit the file to set authentication: anonymous: enabled to\n          false.\n          If using executable arguments, edit the kubelet service file\n          on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --anonymous-auth=false\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.2\n        text: \"Ensure that the --authorization-mode argument is not set to AlwaysAllow\"\n        audit: |\n          grep \"^authorization:\\n\\s{2}mode: AlwaysAllow$\" /var/vcap/jobs/kubelet/config/kubeletconfig.yml\n        tests:\n          test_items:\n            - flag: \"AlwaysAllow\"\n              set: false\n        remediation: |\n          If using a Kubelet config file, edit the file to set authorization: mode to Webhook. If\n          using executable arguments, edit the kubelet service file\n          on each worker node and\n          set the below parameter in KUBELET_AUTHZ_ARGS variable.\n          --authorization-mode=Webhook\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.3\n        text: \"Ensure that the --client-ca-file argument is set as appropriate\"\n        audit: |\n          grep ^authentication:\\n\\s{2}anonymous:\\n\\s{4}enabled:\\sfalse\\n(\\s{2}webhook:\\n\\s{4}cacheTTL:\\s\\d+s\\n\\s{4}enabled:.*\\n)?\n          \\s{2}x509:\\n\\s{4}clientCAFile:\\s\"\\/var\\/vcap\\/jobs\\/kubelet\\/config\\/kubelet-client-ca\\.pem\" /var/vcap/jobs/kubelet/config/kubeletconfig.yml\n        tests:\n          test_items:\n            - flag: \"clientCAFile\"\n        remediation: |\n          If using a Kubelet config file, edit the file to set authentication: x509: clientCAFile to\n          the location of the client CA file.\n          If using command line arguments, edit the kubelet service file\n          on each worker node and\n          set the below parameter in KUBELET_AUTHZ_ARGS variable.\n          --client-ca-file=<path/to/client-ca-file>\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.4\n        text: \"Ensure that the --read-only-port argument is set to 0\"\n        audit: |\n          grep \"readOnlyPort: 0\" /var/vcap/jobs/kubelet/config/kubeletconfig.yml\n        tests:\n          test_items:\n            - flag: \"readOnlyPort: 0\"\n        remediation: |\n          If using a Kubelet config file, edit the file to set readOnlyPort to 0.\n          If using command line arguments, edit the kubelet service file\n          on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --read-only-port=0\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.5\n        text: \"Ensure that the --streaming-connection-idle-timeout argument is not set to 0\"\n        audit: |\n          grep -- \"streamingConnectionIdleTimeout: 0\"  /var/vcap/jobs/kubelet/config/kubeletconfig.yml\n        tests:\n          test_items:\n            - flag: \"streamingConnectionIdleTimeout: 0\"\n              set: false\n        remediation: |\n          If using a Kubelet config file, edit the file to set streamingConnectionIdleTimeout to a\n          value other than 0.\n          If using command line arguments, edit the kubelet service file\n          on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --streaming-connection-idle-timeout=5m\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.6\n        text: \"Ensure that the --protect-kernel-defaults argument is set to true\"\n        audit: |\n          grep -- \"protectKernelDefaults: true\" /var/vcap/jobs/kubelet/config/kubeletconfig.yml\n        tests:\n          test_items:\n            - flag: \"protectKernelDefaults: true\"\n        remediation: |\n          If using a Kubelet config file, edit the file to set protectKernelDefaults: true.\n          If using command line arguments, edit the kubelet service file\n          on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          --protect-kernel-defaults=true\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.7\n        text: \"Ensure that the --make-iptables-util-chains argument is set to true\"\n        audit: |\n          grep -- \"makeIPTablesUtilChains: true\" /var/vcap/jobs/kubelet/config/kubeletconfig.yml\n        tests:\n          test_items:\n            - flag: \"makeIPTablesUtilChains: true\"\n        remediation: |\n          If using a Kubelet config file, edit the file to set makeIPTablesUtilChains: true.\n          If using command line arguments, edit the kubelet service file\n          on each worker node and\n          remove the --make-iptables-util-chains argument from the\n          KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.8\n        text: \"Ensure that the --hostname-override argument is not set\"\n        audit: |\n          ps -ef | grep [k]ubelet | grep -- --[c]onfig=/var/vcap/jobs/kubelet/config/kubeletconfig.yml | grep -v -- --hostname-override\n        type: manual\n        remediation: |\n          Edit the kubelet service file\n          on each worker node and remove the --hostname-override argument from the\n          KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n          Exception\n          On GCE, the hostname needs to be set to the instance name so the gce cloud provider can manage the instance.\n          In other cases its set to the IP address of the VM.\n        scored: false\n\n      - id: 4.2.9\n        text: \"Ensure that the --event-qps argument is set to 0 or a level which ensures appropriate event capture\"\n        audit: grep -- \"--event-qps\" /var/vcap/jobs/kubelet/config/kubeletconfig.yml\n        type: manual\n        tests:\n          test_items:\n            - flag: \"--event-qps\"\n              compare:\n                op: eq\n                value: 0\n        remediation: |\n          If using a Kubelet config file, edit the file to set eventRecordQPS: to an appropriate level.\n          If using command line arguments, edit the kubelet service file\n          on each worker node and\n          set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n\n      - id: 4.2.10\n        text: \"Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate\"\n        audit: |\n          grep  ^tlsCertFile:\\s\\\"\\/var\\/vcap\\/jobs\\/kubelet\\/config\\/kubelet\\.pem\\\"\\ntlsPrivateKeyFile:\\s\\\"\\/var\\/vcap\\/jobs\\/kubelet\\/config\\/kubelet-key\\.pem\\\"$\n          /var/vcap/jobs/kubelet/config/kubeletconfig.yml\n        tests:\n          bin_op: and\n          test_items:\n            - flag: \"tlsCertFile\"\n            - flag: \"tlsPrivateKeyFile\"\n        remediation: |\n          If using a Kubelet config file, edit the file to set tlsCertFile to the location\n          of the certificate file to use to identify this Kubelet, and tlsPrivateKeyFile\n          to the location of the corresponding private key file.\n          If using command line arguments, edit the kubelet service file\n          on each worker node and\n          set the below parameters in KUBELET_CERTIFICATE_ARGS variable.\n          --tls-cert-file=<path/to/tls-certificate-file>\n          --tls-private-key-file=<path/to/tls-key-file>\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: true\n\n      - id: 4.2.11\n        text: \"Ensure that the --rotate-certificates argument is not set to false\"\n        audit: ps -ef | grep kubele[t] | grep -- \"--rotate-certificates=false\"\n        type: manual\n        tests:\n          test_items:\n            - flag: \"--rotate-certificates=false\"\n              set: false\n        remediation: |\n          If using a Kubelet config file, edit the file to add the line rotateCertificates: true or\n          remove it altogether to use the default value.\n          If using command line arguments, edit the kubelet service file\n          on each worker node and\n          remove --rotate-certificates=false argument from the KUBELET_CERTIFICATE_ARGS\n          variable.\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n          Exception\n          Certificate rotation is handled by Credhub\n        scored: false\n\n      - id: 4.2.12\n        text: \"Verify that the RotateKubeletServerCertificate argument is set to true\"\n        audit: ps -ef | grep kubele[t] | grep -- \"--feature-gates=\\(\\w\\+\\|,\\)*RotateKubeletServerCertificate=true\\(\\w\\+\\|,\\)*\"\n        type: manual\n        tests:\n          test_items:\n            - flag: \"RotateKubeletServerCertificate=true\"\n        remediation: |\n          Edit the kubelet service file\n          on each worker node and set the below parameter in KUBELET_CERTIFICATE_ARGS variable.\n          --feature-gates=RotateKubeletServerCertificate=true\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n          Exception\n          Certificate rotation is handled by Credhub\n        scored: false\n\n      - id: 4.2.13\n        text: \"Ensure that the Kubelet only makes use of Strong Cryptographic Ciphers\"\n        audit: ps -ef | grep kubele[t] | grep -- \"--tls-cipher-\n          suites=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384\"\n        type: manual\n        tests:\n          test_items:\n            - flag: --tls-cipher-suites\n              compare:\n                op: regex\n                value: (TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256|TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256|TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305|TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384|TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305|TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384|TLS_RSA_WITH_AES_256_GCM_SHA384|TLS_RSA_WITH_AES_128_GCM_SHA256)\n        remediation: |\n          If using a Kubelet config file, edit the file to set tlsCipherSuites: to\n          TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\n          or to a subset of these values.\n          If using executable arguments, edit the kubelet service file\n          on each worker node and\n          set the --tls-cipher-suites parameter as follows, or to a subset of these values.\n          --tls-cipher-suites=TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\n          Based on your system, restart the kubelet service. For example:\n          systemctl daemon-reload\n          systemctl restart kubelet.service\n        scored: false\n"
  },
  {
    "path": "cfg/tkgi-1.2.53/policies.yaml",
    "content": "---\ncontrols:\nversion: \"tkgi-1.2.53\"\nid: 5\ntext: \"Kubernetes Policies\"\ntype: \"policies\"\ngroups:\n  - id: 5.1\n    text: \"RBAC and Service Accounts\"\n    checks:\n      - id: 5.1.1\n        text: \"Ensure that the cluster-admin role is only used where required\"\n        type: \"manual\"\n        remediation: |\n          Identify all clusterrolebindings to the cluster-admin role. Check if they are used and\n          if they need this role or if they could use a role with fewer privileges.\n          Where possible, first bind users to a lower privileged role and then remove the\n          clusterrolebinding to the cluster-admin role :\n          kubectl delete clusterrolebinding [name]\n          Exception\n          This is site-specific setting.\n        scored: false\n\n      - id: 5.1.2\n        text: \"Minimize access to secrets\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove get, list and watch access to secret objects in the cluster.\n          Exception\n          This is site-specific setting.\n        scored: false\n\n      - id: 5.1.3\n        text: \"Minimize wildcard use in Roles and ClusterRoles\"\n        type: \"manual\"\n        remediation: |\n          Where possible replace any use of wildcards in clusterroles and roles with specific\n          objects or actions.\n          Exception\n          This is site-specific setting.\n        scored: false\n\n      - id: 5.1.4\n        text: \"Minimize access to create pods\"\n        type: \"manual\"\n        remediation: |\n          Where possible, remove create access to pod objects in the cluster.\n          Exception\n          This is site-specific setting.\n        scored: false\n\n      - id: 5.1.5\n        text: \"Ensure that default service accounts are not actively used.\"\n        type: \"manual\"\n        remediation: |\n          Create explicit service accounts wherever a Kubernetes workload requires specific access\n          to the Kubernetes API server.\n          Modify the configuration of each default service account to include this value\n          automountServiceAccountToken: false\n          Exception\n          This is site-specific setting.\n        scored: false\n\n      - id: 5.1.6\n        text: \"Ensure that Service Account Tokens are only mounted where necessary\"\n        type: \"manual\"\n        remediation: |\n          Modify the definition of pods and service accounts which do not need to mount service\n          account tokens to disable it.\n          Exception\n          This is site-specific setting.\n        scored: false\n\n  - id: 5.2\n    text: \"Pod Security Policies\"\n    checks:\n      - id: 5.2.1\n        text: \"Minimize the admission of privileged containers\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that\n          the .spec.privileged field is omitted or set to false.\n          Exception\n          This is site-specific setting.\n        scored: false\n\n      - id: 5.2.2\n        text: \"Minimize the admission of containers wishing to share the host process ID namespace\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that the\n          .spec.hostPID field is omitted or set to false.\n          Exception\n          This is site-specific setting.\n        scored: false\n\n      - id: 5.2.3\n        text: \"Minimize the admission of containers wishing to share the host IPC namespace\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that the\n          .spec.hostIPC field is omitted or set to false.\n          Exception\n          This is site-specific setting.\n        scored: false\n\n      - id: 5.2.4\n        text: \"Minimize the admission of containers wishing to share the host network namespace\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that the\n          .spec.hostNetwork field is omitted or set to false.\n          Exception\n          This is site-specific setting.\n        scored: false\n\n      - id: 5.2.5\n        text: \"Minimize the admission of containers with allowPrivilegeEscalation\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that the\n          .spec.allowPrivilegeEscalation field is omitted or set to false.\n          Exception\n          This is site-specific setting.\n        scored: false\n\n      - id: 5.2.6\n        text: \"Minimize the admission of root containers\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that the\n          .spec.runAsUser.rule is set to either MustRunAsNonRoot or MustRunAs with the range of\n          UIDs not including 0.\n          Exception\n          This is site-specific setting.\n        scored: false\n\n      - id: 5.2.7\n        text: \"Minimize the admission of containers with the NET_RAW capability\"\n        type: \"manual\"\n        remediation: |\n          Create a PSP as described in the Kubernetes documentation, ensuring that the\n          .spec.requiredDropCapabilities is set to include either NET_RAW or ALL.\n          Exception\n          This is site-specific setting.\n        scored: false\n\n      - id: 5.2.8\n        text: \"Minimize the admission of containers with added capabilities\"\n        type: \"manual\"\n        remediation: |\n          Ensure that allowedCapabilities is not present in PSPs for the cluster unless\n          it is set to an empty array.\n          Exception\n          This is site-specific setting.\n        scored: false\n\n      - id: 5.2.9\n        text: \"Minimize the admission of containers with capabilities assigned\"\n        type: \"manual\"\n        remediation: |\n          Review the use of capabilites in applications running on your cluster. Where a namespace\n          contains applications which do not require any Linux capabities to operate consider adding\n          a PSP which forbids the admission of containers which do not drop all capabilities.\n          Exception\n          This is site-specific setting.\n        scored: false\n\n  - id: 5.3\n    text: \"Network Policies and CNI\"\n    checks:\n      - id: 5.3.1\n        text: \"Ensure that the CNI in use supports Network Policies\"\n        type: \"manual\"\n        remediation: |\n          If the CNI plugin in use does not support network policies, consideration should be given to\n          making use of a different plugin, or finding an alternate mechanism for restricting traffic\n          in the Kubernetes cluster.\n          Exception\n          This is site-specific setting.\n        scored: false\n\n      - id: 5.3.2\n        text: \"Ensure that all Namespaces have Network Policies defined\"\n        type: \"manual\"\n        remediation: |\n          Follow the documentation and create NetworkPolicy objects as you need them.\n          Exception\n          This is site-specific setting.\n        scored: false\n\n  - id: 5.4\n    text: \"Secrets Management\"\n    checks:\n      - id: 5.4.1\n        text: \"Prefer using secrets as files over secrets as environment variables\"\n        type: \"manual\"\n        remediation: |\n          if possible, rewrite application code to read secrets from mounted secret files, rather than\n          from environment variables.\n          Exception\n          This is site-specific setting.\n        scored: false\n\n      - id: 5.4.2\n        text: \"Consider external secret storage\"\n        type: \"manual\"\n        remediation: |\n          Refer to the secrets management options offered by your cloud provider or a third-party\n          secrets management solution.\n          Exception\n          This is site-specific setting.\n        scored: false\n\n  - id: 5.5\n    text: \"Extensible Admission Control\"\n    checks:\n      - id: 5.5.1\n        text: \"Configure Image Provenance using ImagePolicyWebhook admission controller\"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and setup image provenance.\n          Exception\n          This is site-specific setting.\n        scored: false\n\n  - id: 5.7\n    text: \"General Policies\"\n    checks:\n      - id: 5.7.1\n        text: \"Create administrative boundaries between resources using namespaces\"\n        type: \"manual\"\n        remediation: |\n          Follow the documentation and create namespaces for objects in your deployment as you need\n          them.\n          Exception\n          This is site-specific setting.\n        scored: false\n\n      - id: 5.7.2\n        text: \"Ensure that the seccomp profile is set to docker/default in your pod definitions\"\n        type: \"manual\"\n        remediation: |\n          Seccomp is an alpha feature currently. By default, all alpha features are disabled. So, you\n          would need to enable alpha features in the apiserver by passing \"--feature-\n          gates=AllAlpha=true\" argument.\n          Edit the /etc/kubernetes/apiserver file on the master node and set the KUBE_API_ARGS\n          parameter to \"--feature-gates=AllAlpha=true\"\n          KUBE_API_ARGS=\"--feature-gates=AllAlpha=true\"\n          Based on your system, restart the kube-apiserver service. For example:\n          systemctl restart kube-apiserver.service\n          Use annotations to enable the docker/default seccomp profile in your pod definitions. An\n          example is as below:\n          apiVersion: v1\n          kind: Pod\n          metadata:\n            name: trustworthy-pod\n            annotations:\n              seccomp.security.alpha.kubernetes.io/pod: docker/default\n          spec:\n            containers:\n              - name: trustworthy-container\n                image: sotrustworthy:latest\n          Exception\n          This is site-specific setting.\n        scored: false\n\n      - id: 5.7.3\n        text: \"Apply Security Context to Your Pods and Containers \"\n        type: \"manual\"\n        remediation: |\n          Follow the Kubernetes documentation and apply security contexts to your pods. For a\n          suggested list of security contexts, you may refer to the CIS Security Benchmark for Docker\n          Containers.\n          Exception\n          This is site-specific setting.\n        scored: false\n\n      - id: 5.7.4\n        text: \"The default namespace should not be used\"\n        type: \"manual\"\n        remediation: |\n          Ensure that namespaces are created to allow for appropriate segregation of Kubernetes\n          resources and that all new resources are created in a specific namespace.\n          Exception\n          This is site-specific setting.\n        scored: false\n"
  },
  {
    "path": "check/check.go",
    "content": "// Copyright © 2017 Aqua Security Software Ltd. <info@aquasec.com>\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage check\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"os/exec\"\n\t\"strings\"\n\n\t\"github.com/golang/glog\"\n)\n\n// NodeType indicates the type of node (master, node).\ntype NodeType string\n\n// State is the state of a control check.\ntype State string\n\nconst (\n\t// PASS check passed.\n\tPASS State = \"PASS\"\n\t// FAIL check failed.\n\tFAIL State = \"FAIL\"\n\t// WARN could not carry out check.\n\tWARN State = \"WARN\"\n\t// INFO informational message\n\tINFO State = \"INFO\"\n\n\t// SKIP for when a check should be skipped.\n\tSKIP = \"skip\"\n\n\t// MASTER a master node\n\tMASTER NodeType = \"master\"\n\t// NODE a node\n\tNODE NodeType = \"node\"\n\t// FEDERATED a federated deployment.\n\tFEDERATED NodeType = \"federated\"\n\n\t// ETCD an etcd node\n\tETCD NodeType = \"etcd\"\n\t// CONTROLPLANE a control plane node\n\tCONTROLPLANE NodeType = \"controlplane\"\n\t// POLICIES a node to run policies from\n\tPOLICIES NodeType = \"policies\"\n\t// MANAGEDSERVICES a node to run managedservices from\n\tMANAGEDSERVICES = \"managedservices\"\n\n\t// MANUAL Check Type\n\tMANUAL string = \"manual\"\n)\n\n// Check contains information about a recommendation in the\n// CIS Kubernetes document.\ntype Check struct {\n\tID                string   `yaml:\"id\" json:\"test_number\"`\n\tText              string   `json:\"test_desc\"`\n\tAudit             string   `json:\"audit\"`\n\tAuditEnv          string   `yaml:\"audit_env\"`\n\tAuditConfig       string   `yaml:\"audit_config\"`\n\tType              string   `json:\"type\"`\n\tTests             *tests   `json:\"-\"`\n\tSet               bool     `json:\"-\"`\n\tRemediation       string   `json:\"remediation\"`\n\tTestInfo          []string `json:\"test_info\"`\n\tState             `json:\"status\"`\n\tActualValue       string `json:\"actual_value\"`\n\tScored            bool   `json:\"scored\"`\n\tIsMultiple        bool   `yaml:\"use_multiple_values\"`\n\tExpectedResult    string `json:\"expected_result\"`\n\tReason            string `json:\"reason,omitempty\"`\n\tAuditOutput       string `json:\"-\"`\n\tAuditEnvOutput    string `json:\"-\"`\n\tAuditConfigOutput string `json:\"-\"`\n\tDisableEnvTesting bool   `json:\"-\"`\n}\n\n// Runner wraps the basic Run method.\ntype Runner interface {\n\t// Run runs a given check and returns the execution state.\n\tRun(c *Check) State\n}\n\n// NewRunner constructs a default Runner.\nfunc NewRunner() Runner {\n\treturn &defaultRunner{}\n}\n\ntype defaultRunner struct{}\n\nfunc (r *defaultRunner) Run(c *Check) State {\n\treturn c.run()\n}\n\n// Run executes the audit commands specified in a check and outputs\n// the results.\nfunc (c *Check) run() State {\n\tglog.V(3).Infof(\"-----   Running check %v   -----\", c.ID)\n\t// Since this is an Scored check\n\t// without tests return a 'WARN' to alert\n\t// the user that this check needs attention\n\tif c.Scored && strings.TrimSpace(c.Type) == \"\" && c.Tests == nil {\n\t\tc.Reason = \"There are no tests\"\n\t\tc.State = WARN\n\t\tglog.V(3).Info(c.Reason)\n\t\treturn c.State\n\t}\n\n\t// If check type is skip, force result to INFO\n\tif c.Type == SKIP {\n\t\tc.Reason = \"Test marked as skip\"\n\t\tc.State = INFO\n\t\tglog.V(3).Info(c.Reason)\n\t\treturn c.State\n\t}\n\n\t// If check type is manual force result to WARN\n\tif c.Type == MANUAL {\n\t\tc.Reason = \"Test marked as a manual test\"\n\t\tc.State = WARN\n\t\tglog.V(3).Info(c.Reason)\n\t\treturn c.State\n\t}\n\n\t// If there aren't any tests defined this is a FAIL or WARN\n\tif c.Tests == nil || len(c.Tests.TestItems) == 0 {\n\t\tc.Reason = \"No tests defined\"\n\t\tif c.Scored {\n\t\t\tc.State = FAIL\n\t\t} else {\n\t\t\tc.State = WARN\n\t\t}\n\t\tglog.V(3).Info(c.Reason)\n\t\treturn c.State\n\t}\n\n\t// Command line parameters override the setting in the config file, so if we get a good result from the Audit command that's all we need to run\n\tvar finalOutput *testOutput\n\tvar lastCommand string\n\n\tlastCommand, err := c.runAuditCommands()\n\tif err == nil {\n\t\tfinalOutput, err = c.execute()\n\t}\n\n\tif finalOutput != nil {\n\t\tif finalOutput.testResult {\n\t\t\tc.State = PASS\n\t\t} else {\n\t\t\tif c.Scored {\n\t\t\t\tc.State = FAIL\n\t\t\t} else {\n\t\t\t\tc.State = WARN\n\t\t\t}\n\t\t}\n\n\t\tc.ActualValue = finalOutput.actualResult\n\t\tc.ExpectedResult = finalOutput.ExpectedResult\n\t}\n\n\tif err != nil {\n\t\tc.Reason = err.Error()\n\t\tif c.Scored {\n\t\t\tc.State = FAIL\n\t\t} else {\n\t\t\tc.State = WARN\n\t\t}\n\t\tglog.V(3).Info(c.Reason)\n\t}\n\n\tif finalOutput != nil {\n\t\tglog.V(3).Infof(\"Command: %q TestResult: %t State: %q \\n\", lastCommand, finalOutput.testResult, c.State)\n\t} else {\n\t\tglog.V(3).Infof(\"Command: %q TestResult: <<EMPTY>> \\n\", lastCommand)\n\t}\n\n\tif c.Reason != \"\" {\n\t\tglog.V(2).Info(c.Reason)\n\t}\n\treturn c.State\n}\n\nfunc (c *Check) runAuditCommands() (lastCommand string, err error) {\n\t// Always run auditEnvOutput if needed\n\tif c.AuditEnv != \"\" {\n\t\tc.AuditEnvOutput, err = runAudit(c.AuditEnv)\n\t\tif err != nil {\n\t\t\treturn c.AuditEnv, err\n\t\t}\n\t}\n\n\t// Run the audit command and auditConfig commands, if present\n\tc.AuditOutput, err = runAudit(c.Audit)\n\tif err != nil {\n\t\treturn c.Audit, err\n\t}\n\n\tc.AuditConfigOutput, err = runAudit(c.AuditConfig)\n\t// when file not found then error comes as exit status 127\n\t// in some env same error comes as exit status 1\n\tif err != nil && (strings.Contains(err.Error(), \"exit status 127\") ||\n\t\tstrings.Contains(err.Error(), \"No such file or directory\")) &&\n\t\t(c.AuditEnvOutput != \"\" || c.AuditOutput != \"\") {\n\t\t// suppress file not found error when there is Audit OR auditEnv output present\n\t\tglog.V(3).Info(err)\n\t\terr = nil\n\t\tc.AuditConfigOutput = \"\"\n\t}\n\treturn c.AuditConfig, err\n}\n\nfunc (c *Check) execute() (finalOutput *testOutput, err error) {\n\tfinalOutput = &testOutput{}\n\n\tts := c.Tests\n\tres := make([]testOutput, len(ts.TestItems))\n\texpectedResultArr := make([]string, len(res))\n\n\tglog.V(3).Infof(\"Running %d test_items\", len(ts.TestItems))\n\tfor i, t := range ts.TestItems {\n\n\t\tt.isMultipleOutput = c.IsMultiple\n\n\t\t// Try with the auditOutput first, and if that's not found, try the auditConfigOutput\n\t\tt.auditUsed = AuditCommand\n\t\tresult := *(t.execute(c.AuditOutput))\n\n\t\t// Check for AuditConfigOutput only if AuditConfig is set and auditConfigOutput is not empty\n\t\tif !result.flagFound && c.AuditConfig != \"\" && c.AuditConfigOutput != \"\" {\n\t\t\t// t.isConfigSetting = true\n\t\t\tt.auditUsed = AuditConfig\n\t\t\tresult = *(t.execute(c.AuditConfigOutput))\n\t\t\tif !result.flagFound && t.Env != \"\" {\n\t\t\t\tt.auditUsed = AuditEnv\n\t\t\t\tresult = *(t.execute(c.AuditEnvOutput))\n\t\t\t}\n\t\t}\n\n\t\tif !result.flagFound && t.Env != \"\" {\n\t\t\tt.auditUsed = AuditEnv\n\t\t\tresult = *(t.execute(c.AuditEnvOutput))\n\t\t}\n\t\tglog.V(2).Infof(\"Used %s\", t.auditUsed)\n\t\tres[i] = result\n\t\texpectedResultArr[i] = res[i].ExpectedResult\n\t}\n\n\tvar result bool\n\t// If no binary operation is specified, default to AND\n\tswitch ts.BinOp {\n\tdefault:\n\t\tglog.V(2).Info(fmt.Sprintf(\"unknown binary operator for tests %s\\n\", ts.BinOp))\n\t\tfinalOutput.actualResult = fmt.Sprintf(\"unknown binary operator for tests %s\\n\", ts.BinOp)\n\t\treturn finalOutput, fmt.Errorf(\"unknown binary operator for tests %s\", ts.BinOp)\n\tcase and, \"\":\n\t\tresult = true\n\t\tfor i := range res {\n\t\t\tresult = result && res[i].testResult\n\t\t}\n\t\t// Generate an AND expected result\n\t\tfinalOutput.ExpectedResult = strings.Join(expectedResultArr, \" AND \")\n\n\tcase or:\n\t\tresult = false\n\t\tfor i := range res {\n\t\t\tresult = result || res[i].testResult\n\t\t}\n\t\t// Generate an OR expected result\n\t\tfinalOutput.ExpectedResult = strings.Join(expectedResultArr, \" OR \")\n\t}\n\n\tfinalOutput.testResult = result\n\tfinalOutput.actualResult = res[0].actualResult\n\n\tglog.V(3).Infof(\"Returning from execute on tests: finalOutput %#v\", finalOutput)\n\treturn finalOutput, nil\n}\n\nfunc runAudit(audit string) (output string, err error) {\n\tvar out bytes.Buffer\n\n\taudit = strings.TrimSpace(audit)\n\tif len(audit) == 0 {\n\t\treturn output, err\n\t}\n\n\tcmd := exec.Command(\"/bin/sh\")\n\tcmd.Stdin = strings.NewReader(audit)\n\tcmd.Stdout = &out\n\tcmd.Stderr = &out\n\terr = cmd.Run()\n\toutput = out.String()\n\n\tif err != nil {\n\t\terr = fmt.Errorf(\"failed to run: %q, output: %q, error: %s\", audit, output, err)\n\t} else {\n\t\tglog.V(3).Infof(\"Command: %q\", audit)\n\t\tglog.V(3).Infof(\"Output:\\n %q\", output)\n\t}\n\treturn output, err\n}\n"
  },
  {
    "path": "check/check_test.go",
    "content": "// Copyright © 2017-2020 Aqua Security Software Ltd. <info@aquasec.com>\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage check\n\nimport (\n\t\"strings\"\n\t\"testing\"\n)\n\nfunc TestCheck_Run(t *testing.T) {\n\ttype TestCase struct {\n\t\tname     string\n\t\tcheck    Check\n\t\tExpected State\n\t}\n\n\ttestCases := []TestCase{\n\t\t{name: \"Manual check should WARN\", check: Check{Type: MANUAL}, Expected: WARN},\n\t\t{name: \"Skip check should INFO\", check: Check{Type: \"skip\"}, Expected: INFO},\n\t\t{name: \"Unscored check (with no type) should WARN on failure\", check: Check{Scored: false}, Expected: WARN},\n\t\t{\n\t\t\tname: \"Unscored check that pass should PASS\",\n\t\t\tcheck: Check{\n\t\t\t\tScored: false,\n\t\t\t\tAudit:  \"echo hello\",\n\t\t\t\tTests: &tests{TestItems: []*testItem{{\n\t\t\t\t\tFlag: \"hello\",\n\t\t\t\t\tSet:  true,\n\t\t\t\t}}},\n\t\t\t},\n\t\t\tExpected: PASS,\n\t\t},\n\n\t\t{name: \"Check with no tests should WARN\", check: Check{Scored: true}, Expected: WARN},\n\t\t{name: \"Scored check with empty tests should FAIL\", check: Check{Scored: true, Tests: &tests{}}, Expected: FAIL},\n\t\t{\n\t\t\tname: \"Scored check that doesn't pass should FAIL\",\n\t\t\tcheck: Check{\n\t\t\t\tScored: true,\n\t\t\t\tAudit:  \"echo hello\",\n\t\t\t\tTests: &tests{TestItems: []*testItem{{\n\t\t\t\t\tFlag: \"hello\",\n\t\t\t\t\tSet:  false,\n\t\t\t\t}}},\n\t\t\t},\n\t\t\tExpected: FAIL,\n\t\t},\n\t\t{\n\t\t\tname: \"Scored checks that pass should PASS\",\n\t\t\tcheck: Check{\n\t\t\t\tScored: true,\n\t\t\t\tAudit:  \"echo hello\",\n\t\t\t\tTests: &tests{TestItems: []*testItem{{\n\t\t\t\t\tFlag: \"hello\",\n\t\t\t\t\tSet:  true,\n\t\t\t\t}}},\n\t\t\t},\n\t\t\tExpected: PASS,\n\t\t},\n\t\t{\n\t\t\tname: \"Scored checks that pass should PASS when config file is not present\",\n\t\t\tcheck: Check{\n\t\t\t\tScored:      true,\n\t\t\t\tAudit:       \"echo hello\",\n\t\t\t\tAuditConfig: \"/test/config.yaml\",\n\t\t\t\tTests: &tests{TestItems: []*testItem{{\n\t\t\t\t\tFlag: \"hello\",\n\t\t\t\t\tSet:  true,\n\t\t\t\t}}},\n\t\t\t},\n\t\t\tExpected: PASS,\n\t\t},\n\t\t{\n\t\t\tname: \"Scored checks that pass should FAIL when config file is not present\",\n\t\t\tcheck: Check{\n\t\t\t\tScored:      true,\n\t\t\t\tAuditConfig: \"/test/config.yaml\",\n\t\t\t\tTests: &tests{TestItems: []*testItem{{\n\t\t\t\t\tFlag: \"hello\",\n\t\t\t\t\tSet:  true,\n\t\t\t\t}}},\n\t\t\t},\n\t\t\tExpected: FAIL,\n\t\t},\n\t}\n\n\tfor _, testCase := range testCases {\n\t\tt.Run(testCase.name, func(t *testing.T) {\n\t\t\ttestCase.check.run()\n\t\t\tif testCase.check.State != testCase.Expected {\n\t\t\t\tt.Errorf(\"expected %s, actual %s\", testCase.Expected, testCase.check.State)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestCheckAuditEnv(t *testing.T) {\n\tpassingCases := []*Check{\n\t\tcontrols.Groups[2].Checks[0],\n\t\tcontrols.Groups[2].Checks[2],\n\t\tcontrols.Groups[2].Checks[3],\n\t\tcontrols.Groups[2].Checks[4],\n\t}\n\n\tfailingCases := []*Check{\n\t\tcontrols.Groups[2].Checks[1],\n\t\tcontrols.Groups[2].Checks[5],\n\t\tcontrols.Groups[2].Checks[6],\n\t}\n\n\tfor _, c := range passingCases {\n\t\tt.Run(c.Text, func(t *testing.T) {\n\t\t\tc.run()\n\t\t\tif c.State != \"PASS\" {\n\t\t\t\tt.Errorf(\"Should PASS, got: %v\", c.State)\n\t\t\t}\n\t\t})\n\t}\n\n\tfor _, c := range failingCases {\n\t\tt.Run(c.Text, func(t *testing.T) {\n\t\t\tc.run()\n\t\t\tif c.State != \"FAIL\" {\n\t\t\t\tt.Errorf(\"Should FAIL, got: %v\", c.State)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestCheckAuditConfig(t *testing.T) {\n\tpassingCases := []*Check{\n\t\tcontrols.Groups[1].Checks[0],\n\t\tcontrols.Groups[1].Checks[3],\n\t\tcontrols.Groups[1].Checks[5],\n\t\tcontrols.Groups[1].Checks[7],\n\t\tcontrols.Groups[1].Checks[9],\n\t\tcontrols.Groups[1].Checks[15],\n\t}\n\n\tfailingCases := []*Check{\n\t\tcontrols.Groups[1].Checks[1],\n\t\tcontrols.Groups[1].Checks[2],\n\t\tcontrols.Groups[1].Checks[4],\n\t\tcontrols.Groups[1].Checks[6],\n\t\tcontrols.Groups[1].Checks[8],\n\t\tcontrols.Groups[1].Checks[10],\n\t\tcontrols.Groups[1].Checks[11],\n\t\tcontrols.Groups[1].Checks[12],\n\t\tcontrols.Groups[1].Checks[13],\n\t\tcontrols.Groups[1].Checks[14],\n\t\tcontrols.Groups[1].Checks[16],\n\t}\n\n\tfor _, c := range passingCases {\n\t\tt.Run(c.Text, func(t *testing.T) {\n\t\t\tc.run()\n\t\t\tif c.State != \"PASS\" {\n\t\t\t\tt.Errorf(\"Should PASS, got: %v\", c.State)\n\t\t\t}\n\t\t})\n\t}\n\n\tfor _, c := range failingCases {\n\t\tt.Run(c.Text, func(t *testing.T) {\n\t\t\tc.run()\n\t\t\tif c.State != \"FAIL\" {\n\t\t\t\tt.Errorf(\"Should FAIL, got: %v\", c.State)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc Test_runAudit(t *testing.T) {\n\ttype args struct {\n\t\taudit  string\n\t\toutput string\n\t}\n\ttests := []struct {\n\t\tname   string\n\t\targs   args\n\t\terrMsg string\n\t\toutput string\n\t}{\n\t\t{\n\t\t\tname: \"run success\",\n\t\t\targs: args{\n\t\t\t\taudit: \"echo 'hello world'\",\n\t\t\t},\n\t\t\terrMsg: \"\",\n\t\t\toutput: \"hello world\\n\",\n\t\t},\n\t\t{\n\t\t\tname: \"run multiple lines script\",\n\t\t\targs: args{\n\t\t\t\taudit: `\nhello() {\n  echo \"hello world\"\n}\n\nhello\n`,\n\t\t\t},\n\t\t\terrMsg: \"\",\n\t\t\toutput: \"hello world\\n\",\n\t\t},\n\t\t{\n\t\t\tname: \"run failed\",\n\t\t\targs: args{\n\t\t\t\taudit: \"unknown_command\",\n\t\t\t},\n\t\t\terrMsg: \"failed to run: \\\"unknown_command\\\", output: \\\"/bin/sh: \",\n\t\t\toutput: \"not found\\n\",\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tvar errMsg string\n\t\t\toutput, err := runAudit(tt.args.audit)\n\t\t\tif err != nil {\n\t\t\t\terrMsg = err.Error()\n\t\t\t}\n\t\t\tif errMsg != \"\" && !strings.Contains(errMsg, tt.errMsg) {\n\t\t\t\tt.Errorf(\"name %s errMsg = %q, want %q\", tt.name, errMsg, tt.errMsg)\n\t\t\t}\n\t\t\tif errMsg == \"\" && output != tt.output {\n\t\t\t\tt.Errorf(\"name %s output = %q, want %q\", tt.name, output, tt.output)\n\t\t\t}\n\t\t\tif errMsg != \"\" && !strings.Contains(output, tt.output) {\n\t\t\t\tt.Errorf(\"name %s output = %q, want %q\", tt.name, output, tt.output)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "check/controls.go",
    "content": "// Copyright © 2017 Aqua Security Software Ltd. <info@aquasec.com>\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage check\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"encoding/xml\"\n\t\"fmt\"\n\t\"time\"\n\n\t\"github.com/aws/aws-sdk-go-v2/aws\"\n\t\"github.com/aws/aws-sdk-go-v2/service/securityhub/types\"\n\t\"github.com/golang/glog\"\n\t\"github.com/onsi/ginkgo/reporters\"\n\t\"github.com/spf13/viper\"\n\t\"gopkg.in/yaml.v2\"\n)\n\nconst (\n\t// UNKNOWN is when the AWS account can't be found\n\tUNKNOWN = \"Unknown\"\n\t// ARN for the AWS Security Hub service\n\tARN = \"arn:aws:securityhub:%s::product/aqua-security/kube-bench\"\n\t// SCHEMA for the AWS Security Hub service\n\tSCHEMA = \"2018-10-08\"\n\t// TYPE is type of Security Hub finding\n\tTYPE = \"Software and Configuration Checks/Industry and Regulatory Standards/CIS Kubernetes Benchmark\"\n)\n\ntype OverallControls struct {\n\tControls []*Controls\n\tTotals   Summary\n}\n\n// Controls holds all controls to check for master nodes.\ntype Controls struct {\n\tID              string   `yaml:\"id\" json:\"id\"`\n\tVersion         string   `json:\"version\"`\n\tDetectedVersion string   `json:\"detected_version,omitempty\"`\n\tText            string   `json:\"text\"`\n\tType            NodeType `json:\"node_type\"`\n\tGroups          []*Group `json:\"tests\"`\n\tSummary\n}\n\n// Group is a collection of similar checks.\ntype Group struct {\n\tID     string   `yaml:\"id\" json:\"section\"`\n\tType   string   `yaml:\"type\" json:\"type\"`\n\tPass   int      `json:\"pass\"`\n\tFail   int      `json:\"fail\"`\n\tWarn   int      `json:\"warn\"`\n\tInfo   int      `json:\"info\"`\n\tText   string   `json:\"desc\"`\n\tChecks []*Check `json:\"results\"`\n}\n\n// Summary is a summary of the results of control checks run.\ntype Summary struct {\n\tPass int `json:\"total_pass\"`\n\tFail int `json:\"total_fail\"`\n\tWarn int `json:\"total_warn\"`\n\tInfo int `json:\"total_info\"`\n}\n\n// Predicate a predicate on the given Group and Check arguments.\ntype Predicate func(group *Group, check *Check) bool\n\n// NewControls instantiates a new master Controls object.\nfunc NewControls(t NodeType, in []byte, detectedVersion string) (*Controls, error) {\n\tc := new(Controls)\n\n\terr := yaml.Unmarshal(in, c)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to unmarshal YAML: %s\", err)\n\t}\n\n\tif t != c.Type {\n\t\treturn nil, fmt.Errorf(\"non-%s controls file specified\", t)\n\t}\n\tc.DetectedVersion = detectedVersion\n\treturn c, nil\n}\n\n// RunChecks runs the checks with the given Runner. Only checks for which the filter Predicate returns `true` will run.\nfunc (controls *Controls) RunChecks(runner Runner, filter Predicate, skipIDMap map[string]bool) Summary {\n\tvar g []*Group\n\tm := make(map[string]*Group)\n\tcontrols.Summary.Pass, controls.Summary.Fail, controls.Summary.Warn, controls.Info = 0, 0, 0, 0\n\n\tfor _, group := range controls.Groups {\n\t\tfor _, check := range group.Checks {\n\n\t\t\tif !filter(group, check) {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t_, groupSkippedViaCmd := skipIDMap[group.ID]\n\t\t\t_, checkSkippedViaCmd := skipIDMap[check.ID]\n\n\t\t\tif group.Type == SKIP || groupSkippedViaCmd || checkSkippedViaCmd {\n\t\t\t\tcheck.Type = SKIP\n\t\t\t}\n\n\t\t\tstate := runner.Run(check)\n\n\t\t\tcheck.TestInfo = append(check.TestInfo, check.Remediation)\n\n\t\t\t// Check if we have already added this checks group.\n\t\t\tif v, ok := m[group.ID]; !ok {\n\t\t\t\t// Create a group with same info\n\t\t\t\tw := &Group{\n\t\t\t\t\tID:     group.ID,\n\t\t\t\t\tText:   group.Text,\n\t\t\t\t\tChecks: []*Check{},\n\t\t\t\t}\n\n\t\t\t\t// Add this check to the new group\n\t\t\t\tw.Checks = append(w.Checks, check)\n\t\t\t\tsummarizeGroup(w, state)\n\n\t\t\t\t// Add to groups we have visited.\n\t\t\t\tm[w.ID] = w\n\t\t\t\tg = append(g, w)\n\t\t\t} else {\n\t\t\t\tv.Checks = append(v.Checks, check)\n\t\t\t\tsummarizeGroup(v, state)\n\t\t\t}\n\n\t\t\tsummarize(controls, state)\n\t\t}\n\t}\n\n\tcontrols.Groups = g\n\treturn controls.Summary\n}\n\n// JSON encodes the results of last run to JSON.\nfunc (controls *Controls) JSON() ([]byte, error) {\n\treturn json.Marshal(controls)\n}\n\n// JUnit encodes the results of last run to JUnit.\nfunc (controls *Controls) JUnit() ([]byte, error) {\n\tsuite := reporters.JUnitTestSuite{\n\t\tName:      controls.Text,\n\t\tTestCases: []reporters.JUnitTestCase{},\n\t\tTests:     controls.Summary.Pass + controls.Summary.Fail + controls.Summary.Info + controls.Summary.Warn,\n\t\tFailures:  controls.Summary.Fail,\n\t}\n\tfor _, g := range controls.Groups {\n\t\tfor _, check := range g.Checks {\n\t\t\tjsonCheck := \"\"\n\t\t\tjsonBytes, err := json.Marshal(check)\n\t\t\tif err != nil {\n\t\t\t\tjsonCheck = fmt.Sprintf(\"Failed to marshal test into JSON: %v. Test as text: %#v\", err, check)\n\t\t\t} else {\n\t\t\t\tjsonCheck = string(jsonBytes)\n\t\t\t}\n\t\t\ttc := reporters.JUnitTestCase{\n\t\t\t\tName:      fmt.Sprintf(\"%v %v\", check.ID, check.Text),\n\t\t\t\tClassName: g.Text,\n\n\t\t\t\t// Store the entire json serialization as system out so we don't lose data in cases where deeper debugging is necessary.\n\t\t\t\tSystemOut: jsonCheck,\n\t\t\t}\n\n\t\t\tswitch check.State {\n\t\t\tcase FAIL:\n\t\t\t\ttc.FailureMessage = &reporters.JUnitFailureMessage{Message: check.Remediation}\n\t\t\tcase WARN, INFO:\n\t\t\t\t// WARN and INFO are two different versions of skipped tests. Either way it would be a false positive/negative to report\n\t\t\t\t// it any other way.\n\t\t\t\ttc.Skipped = &reporters.JUnitSkipped{}\n\t\t\tcase PASS:\n\t\t\tdefault:\n\t\t\t\tglog.Warningf(\"Unrecognized state %s\", check.State)\n\t\t\t}\n\n\t\t\tsuite.TestCases = append(suite.TestCases, tc)\n\t\t}\n\t}\n\n\tvar b bytes.Buffer\n\tencoder := xml.NewEncoder(&b)\n\tencoder.Indent(\"\", \"    \")\n\terr := encoder.Encode(suite)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"Failed to generate JUnit report: %s\", err.Error())\n\t}\n\n\treturn b.Bytes(), nil\n}\n\n// ASFF encodes the results of last run to AWS Security Finding Format(ASFF).\nfunc (controls *Controls) ASFF() ([]types.AwsSecurityFinding, error) {\n\tfs := []types.AwsSecurityFinding{}\n\taccount, err := getConfig(\"AWS_ACCOUNT\")\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tcluster, err := getConfig(\"CLUSTER_ARN\")\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tregion, err := getConfig(\"AWS_REGION\")\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tnodeName, _ := getConfig(\"NODE_NAME\")\n\tarn := fmt.Sprintf(ARN, region)\n\n\tti := time.Now()\n\ttf := ti.Format(time.RFC3339)\n\tfor _, g := range controls.Groups {\n\t\tfor _, check := range g.Checks {\n\t\t\tif check.State == FAIL || check.State == WARN {\n\t\t\t\t// ASFF ProductFields['Actual result'] can't be longer than 1024 characters\n\t\t\t\tactualValue := check.ActualValue\n\t\t\t\tremediation := check.Remediation\n\t\t\t\treason := check.Reason\n\n\t\t\t\tif len(check.ActualValue) > 1024 {\n\t\t\t\t\tactualValue = check.ActualValue[0:1023]\n\t\t\t\t}\n\n\t\t\t\t// Fix issue https://github.com/aquasecurity/kube-bench/issues/903\n\t\t\t\tif len(check.Remediation) > 512 {\n\t\t\t\t\tremediation = check.Remediation[0:511]\n\t\t\t\t}\n\n\t\t\t\tif len(check.Reason) > 1024 {\n\t\t\t\t\treason = check.Reason[0:1023]\n\t\t\t\t}\n\t\t\t\tid := aws.String(fmt.Sprintf(\"%s%sEKSnodeID+%s+%s\", arn, account, check.ID, cluster))\n\t\t\t\tif nodeName != \"\" {\n\t\t\t\t\tid = aws.String(fmt.Sprintf(\"%s%sEKSnodeID+%s+%s+%s\", arn, account, check.ID, cluster, nodeName))\n\t\t\t\t}\n\n\t\t\t\tf := types.AwsSecurityFinding{\n\t\t\t\t\tAwsAccountId:  aws.String(account),\n\t\t\t\t\tConfidence:    aws.Int32(100),\n\t\t\t\t\tGeneratorId:   aws.String(fmt.Sprintf(\"%s/cis-kubernetes-benchmark/%s/%s\", arn, controls.Version, check.ID)),\n\t\t\t\t\tId:            id,\n\t\t\t\t\tCreatedAt:     aws.String(tf),\n\t\t\t\t\tDescription:   aws.String(check.Text),\n\t\t\t\t\tProductArn:    aws.String(arn),\n\t\t\t\t\tSchemaVersion: aws.String(SCHEMA),\n\t\t\t\t\tTitle:         aws.String(fmt.Sprintf(\"%s %s\", check.ID, check.Text)),\n\t\t\t\t\tUpdatedAt:     aws.String(tf),\n\t\t\t\t\tTypes:         []string{*aws.String(TYPE)},\n\t\t\t\t\tSeverity: &types.Severity{\n\t\t\t\t\t\tLabel: types.SeverityLabelHigh,\n\t\t\t\t\t},\n\t\t\t\t\tRemediation: &types.Remediation{\n\t\t\t\t\t\tRecommendation: &types.Recommendation{\n\t\t\t\t\t\t\tText: aws.String(remediation),\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tProductFields: map[string]string{\n\t\t\t\t\t\t\"Reason\":          reason,\n\t\t\t\t\t\t\"Actual result\":   actualValue,\n\t\t\t\t\t\t\"Expected result\": check.ExpectedResult,\n\t\t\t\t\t\t\"Section\":         fmt.Sprintf(\"%s %s\", controls.ID, controls.Text),\n\t\t\t\t\t\t\"Subsection\":      fmt.Sprintf(\"%s %s\", g.ID, g.Text),\n\t\t\t\t\t},\n\t\t\t\t\tResources: []types.Resource{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tId:   aws.String(cluster),\n\t\t\t\t\t\t\tType: aws.String(TYPE),\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t\tfs = append(fs, f)\n\t\t\t}\n\t\t}\n\t}\n\treturn fs, nil\n}\n\nfunc getConfig(name string) (string, error) {\n\tr := viper.GetString(name)\n\tif len(r) == 0 {\n\t\treturn \"\", fmt.Errorf(\"%s not set\", name)\n\t}\n\treturn r, nil\n}\n\nfunc summarize(controls *Controls, state State) {\n\tswitch state {\n\tcase PASS:\n\t\tcontrols.Summary.Pass++\n\tcase FAIL:\n\t\tcontrols.Summary.Fail++\n\tcase WARN:\n\t\tcontrols.Summary.Warn++\n\tcase INFO:\n\t\tcontrols.Summary.Info++\n\tdefault:\n\t\tglog.Warningf(\"Unrecognized state %s\", state)\n\t}\n}\n\nfunc summarizeGroup(group *Group, state State) {\n\tswitch state {\n\tcase PASS:\n\t\tgroup.Pass++\n\tcase FAIL:\n\t\tgroup.Fail++\n\tcase WARN:\n\t\tgroup.Warn++\n\tcase INFO:\n\t\tgroup.Info++\n\tdefault:\n\t\tglog.Warningf(\"Unrecognized state %s\", state)\n\t}\n}\n"
  },
  {
    "path": "check/controls_test.go",
    "content": "// Copyright © 2017-2019 Aqua Security Software Ltd. <info@aquasec.com>\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage check\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"encoding/xml\"\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/aws/aws-sdk-go-v2/aws\"\n\t\"github.com/aws/aws-sdk-go-v2/service/securityhub/types\"\n\t\"github.com/onsi/ginkgo/reporters\"\n\t\"github.com/spf13/viper\"\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/mock\"\n\t\"gopkg.in/yaml.v2\"\n)\n\nconst cfgDir = \"../cfg/\"\n\ntype mockRunner struct {\n\tmock.Mock\n}\n\nfunc (m *mockRunner) Run(c *Check) State {\n\targs := m.Called(c)\n\treturn args.Get(0).(State)\n}\n\n// validate that the files we're shipping are valid YAML\nfunc TestYamlFiles(t *testing.T) {\n\terr := filepath.Walk(cfgDir, func(path string, info os.FileInfo, err error) error {\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"failure accessing path %q: %v\\n\", path, err)\n\t\t}\n\t\tif !info.IsDir() {\n\t\t\tt.Logf(\"reading file: %s\", path)\n\t\t\tin, err := os.ReadFile(path)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatalf(\"error opening file %s: %v\", path, err)\n\t\t\t}\n\n\t\t\tc := new(Controls)\n\t\t\terr = yaml.Unmarshal(in, c)\n\t\t\tif err == nil {\n\t\t\t\tt.Logf(\"YAML file successfully unmarshalled: %s\", path)\n\t\t\t} else {\n\t\t\t\tt.Fatalf(\"failed to load YAML from %s: %v\", path, err)\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"failure walking cfg dir: %v\\n\", err)\n\t}\n}\n\nfunc TestNewControls(t *testing.T) {\n\tt.Run(\"Should return error when node type is not specified\", func(t *testing.T) {\n\t\t// given\n\t\tin := []byte(`\n---\ncontrols:\ntype: # not specified\ngroups:\n`)\n\t\t// when\n\t\t_, err := NewControls(MASTER, in, \"\")\n\t\t// then\n\t\tassert.EqualError(t, err, \"non-master controls file specified\")\n\t})\n\n\tt.Run(\"Should return error when input YAML is invalid\", func(t *testing.T) {\n\t\t// given\n\t\tin := []byte(\"BOOM\")\n\t\t// when\n\t\t_, err := NewControls(MASTER, in, \"\")\n\t\t// then\n\t\tassert.EqualError(t, err, \"failed to unmarshal YAML: yaml: unmarshal errors:\\n  line 1: cannot unmarshal !!str `BOOM` into check.Controls\")\n\t})\n\n}\n\nfunc TestControls_RunChecks_SkippedCmd(t *testing.T) {\n\tt.Run(\"Should skip checks and groups specified by skipMap\", func(t *testing.T) {\n\t\t// given\n\t\tnormalRunner := &defaultRunner{}\n\t\t// and\n\t\tin := []byte(`\n---\ntype: \"master\"\ngroups:\n- id: G1\n  checks:\n  - id: G1/C1\n  - id: G1/C2\n  - id: G1/C3\n- id: G2\n  checks:\n  - id: G2/C1\n  - id: G2/C2\n`)\n\t\tcontrols, err := NewControls(MASTER, in, \"\")\n\t\tassert.NoError(t, err)\n\n\t\tvar allChecks Predicate = func(group *Group, c *Check) bool {\n\t\t\treturn true\n\t\t}\n\n\t\tskipMap := make(map[string]bool, 0)\n\t\tskipMap[\"G1\"] = true\n\t\tskipMap[\"G2/C1\"] = true\n\t\tskipMap[\"G2/C2\"] = true\n\t\tcontrols.RunChecks(normalRunner, allChecks, skipMap)\n\n\t\tG1 := controls.Groups[0]\n\t\tassertEqualGroupSummary(t, 0, 0, 3, 0, G1)\n\n\t\tG2 := controls.Groups[1]\n\t\tassertEqualGroupSummary(t, 0, 0, 2, 0, G2)\n\t})\n}\n\nfunc TestControls_RunChecks_Skipped(t *testing.T) {\n\tt.Run(\"Should skip checks where the parent group is marked as skip\", func(t *testing.T) {\n\t\t// given\n\t\tnormalRunner := &defaultRunner{}\n\t\t// and\n\t\tin := []byte(`\n---\ntype: \"master\"\ngroups:\n- id: G1\n  type: skip\n  checks:\n  - id: G1/C1\n`)\n\t\tcontrols, err := NewControls(MASTER, in, \"\")\n\t\tassert.NoError(t, err)\n\n\t\tvar allChecks Predicate = func(group *Group, c *Check) bool {\n\t\t\treturn true\n\t\t}\n\t\temptySkipList := make(map[string]bool, 0)\n\t\tcontrols.RunChecks(normalRunner, allChecks, emptySkipList)\n\n\t\tG1 := controls.Groups[0]\n\t\tassertEqualGroupSummary(t, 0, 0, 1, 0, G1)\n\t})\n}\n\nfunc TestControls_RunChecks(t *testing.T) {\n\tt.Run(\"Should run checks matching the filter and update summaries\", func(t *testing.T) {\n\t\t// given\n\t\trunner := new(mockRunner)\n\t\t// and\n\t\tin := []byte(`\n---\ntype: \"master\"\ngroups:\n- id: G1\n  checks:\n  - id: G1/C1\n- id: G2\n  checks:\n  - id: G2/C1\n    text: \"Verify that the SomeSampleFlag argument is set to true\"\n    audit: \"grep -B1 SomeSampleFlag=true /this/is/a/file/path\"\n    tests:\n      test_items:\n      - flag: \"SomeSampleFlag=true\"\n        compare:\n          op: has\n          value: \"true\"\n        set: true\n    remediation: |\n      Edit the config file /this/is/a/file/path and set SomeSampleFlag to true.\n    scored: true\n`)\n\t\t// and\n\t\tcontrols, err := NewControls(MASTER, in, \"\")\n\t\tassert.NoError(t, err)\n\t\t// and\n\t\trunner.On(\"Run\", controls.Groups[0].Checks[0]).Return(PASS)\n\t\trunner.On(\"Run\", controls.Groups[1].Checks[0]).Return(FAIL)\n\t\t// and\n\t\tvar runAll Predicate = func(group *Group, c *Check) bool {\n\t\t\treturn true\n\t\t}\n\t\tvar emptySkipList = make(map[string]bool, 0)\n\t\t// when\n\t\tcontrols.RunChecks(runner, runAll, emptySkipList)\n\t\t// then\n\t\tassert.Equal(t, 2, len(controls.Groups))\n\t\t// and\n\t\tG1 := controls.Groups[0]\n\t\tassert.Equal(t, \"G1\", G1.ID)\n\t\tassert.Equal(t, \"G1/C1\", G1.Checks[0].ID)\n\t\tassertEqualGroupSummary(t, 1, 0, 0, 0, G1)\n\t\t// and\n\t\tG2 := controls.Groups[1]\n\t\tassert.Equal(t, \"G2\", G2.ID)\n\t\tassert.Equal(t, \"G2/C1\", G2.Checks[0].ID)\n\t\tassert.Equal(t, \"has\", G2.Checks[0].Tests.TestItems[0].Compare.Op)\n\t\tassert.Equal(t, \"true\", G2.Checks[0].Tests.TestItems[0].Compare.Value)\n\t\tassert.Equal(t, true, G2.Checks[0].Tests.TestItems[0].Set)\n\t\tassert.Equal(t, \"SomeSampleFlag=true\", G2.Checks[0].Tests.TestItems[0].Flag)\n\t\tassert.Equal(t, \"Edit the config file /this/is/a/file/path and set SomeSampleFlag to true.\\n\", G2.Checks[0].Remediation)\n\t\tassert.Equal(t, true, G2.Checks[0].Scored)\n\t\tassertEqualGroupSummary(t, 0, 1, 0, 0, G2)\n\t\t// and\n\t\tassert.Equal(t, 1, controls.Summary.Pass)\n\t\tassert.Equal(t, 1, controls.Summary.Fail)\n\t\tassert.Equal(t, 0, controls.Summary.Info)\n\t\tassert.Equal(t, 0, controls.Summary.Warn)\n\t\t// and\n\t\trunner.AssertExpectations(t)\n\t})\n}\n\nfunc TestControls_JUnitIncludesJSON(t *testing.T) {\n\ttestCases := []struct {\n\t\tdesc   string\n\t\tinput  *Controls\n\t\texpect []byte\n\t}{\n\t\t{\n\t\t\tdesc: \"Serializes to junit\",\n\t\t\tinput: &Controls{\n\t\t\t\tGroups: []*Group{\n\t\t\t\t\t{\n\t\t\t\t\t\tID: \"g1\",\n\t\t\t\t\t\tChecks: []*Check{\n\t\t\t\t\t\t\t{ID: \"check1id\", Text: \"check1text\", State: PASS},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\texpect: []byte(`<testsuite name=\"\" tests=\"0\" failures=\"0\" errors=\"0\" time=\"0\">\n    <testcase name=\"check1id check1text\" classname=\"\" time=\"0\">\n        <system-out>{&#34;test_number&#34;:&#34;check1id&#34;,&#34;test_desc&#34;:&#34;check1text&#34;,&#34;audit&#34;:&#34;&#34;,&#34;AuditEnv&#34;:&#34;&#34;,&#34;AuditConfig&#34;:&#34;&#34;,&#34;type&#34;:&#34;&#34;,&#34;remediation&#34;:&#34;&#34;,&#34;test_info&#34;:null,&#34;status&#34;:&#34;PASS&#34;,&#34;actual_value&#34;:&#34;&#34;,&#34;scored&#34;:false,&#34;IsMultiple&#34;:false,&#34;expected_result&#34;:&#34;&#34;}</system-out>\n    </testcase>\n</testsuite>`),\n\t\t}, {\n\t\t\tdesc: \"Summary values come from summary not checks\",\n\t\t\tinput: &Controls{\n\t\t\t\tSummary: Summary{\n\t\t\t\t\tFail: 99,\n\t\t\t\t\tPass: 100,\n\t\t\t\t\tWarn: 101,\n\t\t\t\t\tInfo: 102,\n\t\t\t\t},\n\t\t\t\tGroups: []*Group{\n\t\t\t\t\t{\n\t\t\t\t\t\tID: \"g1\",\n\t\t\t\t\t\tChecks: []*Check{\n\t\t\t\t\t\t\t{ID: \"check1id\", Text: \"check1text\", State: PASS},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\texpect: []byte(`<testsuite name=\"\" tests=\"402\" failures=\"99\" errors=\"0\" time=\"0\">\n    <testcase name=\"check1id check1text\" classname=\"\" time=\"0\">\n        <system-out>{&#34;test_number&#34;:&#34;check1id&#34;,&#34;test_desc&#34;:&#34;check1text&#34;,&#34;audit&#34;:&#34;&#34;,&#34;AuditEnv&#34;:&#34;&#34;,&#34;AuditConfig&#34;:&#34;&#34;,&#34;type&#34;:&#34;&#34;,&#34;remediation&#34;:&#34;&#34;,&#34;test_info&#34;:null,&#34;status&#34;:&#34;PASS&#34;,&#34;actual_value&#34;:&#34;&#34;,&#34;scored&#34;:false,&#34;IsMultiple&#34;:false,&#34;expected_result&#34;:&#34;&#34;}</system-out>\n    </testcase>\n</testsuite>`),\n\t\t}, {\n\t\t\tdesc: \"Warn and Info are considered skips and failed tests properly reported\",\n\t\t\tinput: &Controls{\n\t\t\t\tGroups: []*Group{\n\t\t\t\t\t{\n\t\t\t\t\t\tID: \"g1\",\n\t\t\t\t\t\tChecks: []*Check{\n\t\t\t\t\t\t\t{ID: \"check1id\", Text: \"check1text\", State: PASS},\n\t\t\t\t\t\t\t{ID: \"check2id\", Text: \"check2text\", State: INFO},\n\t\t\t\t\t\t\t{ID: \"check3id\", Text: \"check3text\", State: WARN},\n\t\t\t\t\t\t\t{ID: \"check4id\", Text: \"check4text\", State: FAIL},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\texpect: []byte(`<testsuite name=\"\" tests=\"0\" failures=\"0\" errors=\"0\" time=\"0\">\n    <testcase name=\"check1id check1text\" classname=\"\" time=\"0\">\n        <system-out>{&#34;test_number&#34;:&#34;check1id&#34;,&#34;test_desc&#34;:&#34;check1text&#34;,&#34;audit&#34;:&#34;&#34;,&#34;AuditEnv&#34;:&#34;&#34;,&#34;AuditConfig&#34;:&#34;&#34;,&#34;type&#34;:&#34;&#34;,&#34;remediation&#34;:&#34;&#34;,&#34;test_info&#34;:null,&#34;status&#34;:&#34;PASS&#34;,&#34;actual_value&#34;:&#34;&#34;,&#34;scored&#34;:false,&#34;IsMultiple&#34;:false,&#34;expected_result&#34;:&#34;&#34;}</system-out>\n    </testcase>\n    <testcase name=\"check2id check2text\" classname=\"\" time=\"0\">\n        <skipped></skipped>\n        <system-out>{&#34;test_number&#34;:&#34;check2id&#34;,&#34;test_desc&#34;:&#34;check2text&#34;,&#34;audit&#34;:&#34;&#34;,&#34;AuditEnv&#34;:&#34;&#34;,&#34;AuditConfig&#34;:&#34;&#34;,&#34;type&#34;:&#34;&#34;,&#34;remediation&#34;:&#34;&#34;,&#34;test_info&#34;:null,&#34;status&#34;:&#34;INFO&#34;,&#34;actual_value&#34;:&#34;&#34;,&#34;scored&#34;:false,&#34;IsMultiple&#34;:false,&#34;expected_result&#34;:&#34;&#34;}</system-out>\n    </testcase>\n    <testcase name=\"check3id check3text\" classname=\"\" time=\"0\">\n        <skipped></skipped>\n        <system-out>{&#34;test_number&#34;:&#34;check3id&#34;,&#34;test_desc&#34;:&#34;check3text&#34;,&#34;audit&#34;:&#34;&#34;,&#34;AuditEnv&#34;:&#34;&#34;,&#34;AuditConfig&#34;:&#34;&#34;,&#34;type&#34;:&#34;&#34;,&#34;remediation&#34;:&#34;&#34;,&#34;test_info&#34;:null,&#34;status&#34;:&#34;WARN&#34;,&#34;actual_value&#34;:&#34;&#34;,&#34;scored&#34;:false,&#34;IsMultiple&#34;:false,&#34;expected_result&#34;:&#34;&#34;}</system-out>\n    </testcase>\n    <testcase name=\"check4id check4text\" classname=\"\" time=\"0\">\n        <failure type=\"\"></failure>\n        <system-out>{&#34;test_number&#34;:&#34;check4id&#34;,&#34;test_desc&#34;:&#34;check4text&#34;,&#34;audit&#34;:&#34;&#34;,&#34;AuditEnv&#34;:&#34;&#34;,&#34;AuditConfig&#34;:&#34;&#34;,&#34;type&#34;:&#34;&#34;,&#34;remediation&#34;:&#34;&#34;,&#34;test_info&#34;:null,&#34;status&#34;:&#34;FAIL&#34;,&#34;actual_value&#34;:&#34;&#34;,&#34;scored&#34;:false,&#34;IsMultiple&#34;:false,&#34;expected_result&#34;:&#34;&#34;}</system-out>\n    </testcase>\n</testsuite>`),\n\t\t},\n\t}\n\tfor _, tc := range testCases {\n\t\tt.Run(tc.desc, func(t *testing.T) {\n\t\t\tjunitBytes, err := tc.input.JUnit()\n\t\t\tif err != nil {\n\t\t\t\tt.Fatalf(\"Failed to serialize to JUnit: %v\", err)\n\t\t\t}\n\n\t\t\tvar out reporters.JUnitTestSuite\n\t\t\tif err := xml.Unmarshal(junitBytes, &out); err != nil {\n\t\t\t\tt.Fatalf(\"Unable to deserialize from resulting JUnit: %v\", err)\n\t\t\t}\n\n\t\t\t// Check that each check was serialized as json and stored as systemOut.\n\t\t\tfor iGroup, group := range tc.input.Groups {\n\t\t\t\tfor iCheck, check := range group.Checks {\n\t\t\t\t\tjsonBytes, err := json.Marshal(check)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tt.Fatalf(\"Failed to serialize to JUnit: %v\", err)\n\t\t\t\t\t}\n\n\t\t\t\t\tif out.TestCases[iGroup*iCheck+iCheck].SystemOut != string(jsonBytes) {\n\t\t\t\t\t\tt.Errorf(\"Expected\\n\\t%v\\n\\tbut got\\n\\t%v\",\n\t\t\t\t\t\t\tout.TestCases[iGroup*iCheck+iCheck].SystemOut,\n\t\t\t\t\t\t\tstring(jsonBytes),\n\t\t\t\t\t\t)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif !bytes.Equal(junitBytes, tc.expect) {\n\t\t\t\tt.Errorf(\"Expected\\n\\t%v\\n\\tbut got\\n\\t%v\",\n\t\t\t\t\tstring(tc.expect),\n\t\t\t\t\tstring(junitBytes),\n\t\t\t\t)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc assertEqualGroupSummary(t *testing.T, pass, fail, info, warn int, actual *Group) {\n\tt.Helper()\n\tassert.Equal(t, pass, actual.Pass)\n\tassert.Equal(t, fail, actual.Fail)\n\tassert.Equal(t, info, actual.Info)\n\tassert.Equal(t, warn, actual.Warn)\n}\n\nfunc TestControls_ASFF(t *testing.T) {\n\ttype fields struct {\n\t\tID      string\n\t\tVersion string\n\t\tText    string\n\t\tGroups  []*Group\n\t\tSummary Summary\n\t}\n\ttests := []struct {\n\t\tname    string\n\t\tfields  fields\n\t\twant    []types.AwsSecurityFinding\n\t\twantErr bool\n\t}{\n\t\t{\n\t\t\tname: \"Test simple conversion\",\n\t\t\tfields: fields{\n\t\t\t\tID:      \"test1\",\n\t\t\t\tVersion: \"1\",\n\t\t\t\tText:    \"test runnner\",\n\t\t\t\tSummary: Summary{\n\t\t\t\t\tFail: 99,\n\t\t\t\t\tPass: 100,\n\t\t\t\t\tWarn: 101,\n\t\t\t\t\tInfo: 102,\n\t\t\t\t},\n\t\t\t\tGroups: []*Group{\n\t\t\t\t\t{\n\t\t\t\t\t\tID:   \"g1\",\n\t\t\t\t\t\tText: \"Group text\",\n\t\t\t\t\t\tChecks: []*Check{\n\t\t\t\t\t\t\t{ID: \"check1id\",\n\t\t\t\t\t\t\t\tText:           \"check1text\",\n\t\t\t\t\t\t\t\tState:          FAIL,\n\t\t\t\t\t\t\t\tRemediation:    \"fix me\",\n\t\t\t\t\t\t\t\tReason:         \"failed\",\n\t\t\t\t\t\t\t\tExpectedResult: \"failed\",\n\t\t\t\t\t\t\t\tActualValue:    \"failed\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t}},\n\t\t\twant: []types.AwsSecurityFinding{\n\t\t\t\t{\n\t\t\t\t\tAwsAccountId:  aws.String(\"foo account\"),\n\t\t\t\t\tConfidence:    aws.Int32(100),\n\t\t\t\t\tGeneratorId:   aws.String(fmt.Sprintf(\"%s/cis-kubernetes-benchmark/%s/%s\", fmt.Sprintf(ARN, \"somewhere\"), \"1\", \"check1id\")),\n\t\t\t\t\tDescription:   aws.String(\"check1text\"),\n\t\t\t\t\tProductArn:    aws.String(fmt.Sprintf(ARN, \"somewhere\")),\n\t\t\t\t\tSchemaVersion: aws.String(SCHEMA),\n\t\t\t\t\tTitle:         aws.String(fmt.Sprintf(\"%s %s\", \"check1id\", \"check1text\")),\n\t\t\t\t\tTypes:         []string{*aws.String(TYPE)},\n\t\t\t\t\tSeverity: &types.Severity{\n\t\t\t\t\t\tLabel: types.SeverityLabelHigh,\n\t\t\t\t\t},\n\t\t\t\t\tRemediation: &types.Remediation{\n\t\t\t\t\t\tRecommendation: &types.Recommendation{\n\t\t\t\t\t\t\tText: aws.String(\"fix me\"),\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tProductFields: map[string]string{\n\t\t\t\t\t\t\"Reason\":          \"failed\",\n\t\t\t\t\t\t\"Actual result\":   \"failed\",\n\t\t\t\t\t\t\"Expected result\": \"failed\",\n\t\t\t\t\t\t\"Section\":         fmt.Sprintf(\"%s %s\", \"test1\", \"test runnner\"),\n\t\t\t\t\t\t\"Subsection\":      fmt.Sprintf(\"%s %s\", \"g1\", \"Group text\"),\n\t\t\t\t\t},\n\t\t\t\t\tResources: []types.Resource{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tId:   aws.String(\"foo Cluster\"),\n\t\t\t\t\t\t\tType: aws.String(TYPE),\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\twantErr: false,\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tviper.Set(\"AWS_ACCOUNT\", \"foo account\")\n\t\t\tviper.Set(\"CLUSTER_ARN\", \"foo Cluster\")\n\t\t\tviper.Set(\"AWS_REGION\", \"somewhere\")\n\t\t\tcontrols := &Controls{\n\t\t\t\tID:      tt.fields.ID,\n\t\t\t\tVersion: tt.fields.Version,\n\t\t\t\tText:    tt.fields.Text,\n\t\t\t\tGroups:  tt.fields.Groups,\n\t\t\t\tSummary: tt.fields.Summary,\n\t\t\t}\n\t\t\tgot, _ := controls.ASFF()\n\t\t\ttt.want[0].CreatedAt = got[0].CreatedAt\n\t\t\ttt.want[0].UpdatedAt = got[0].UpdatedAt\n\t\t\ttt.want[0].Id = got[0].Id\n\t\t\tif !reflect.DeepEqual(got, tt.want) {\n\t\t\t\tt.Errorf(\"Controls.ASFF() = %v, want %v\", got, tt.want)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "check/data",
    "content": "---\ncontrols:\nid: 1\ntext: \"Test Checks\"\ntype: \"master\"\ngroups:\n- id: 1.1\n  text: \"First Group\"\n  checks:\n    - id: 0\n      text: \"flag is set\"\n      audit: \"echo \\\"Non empty command\\\"\"\n      tests:\n        test_items:\n          - flag: \"--allow-privileged\"\n            set: true\n\n    - id: 1\n      text: \"flag is not set\"\n      audit: \"echo \\\"Non empty command\\\"\"\n      tests:\n        test_items:\n          - flag: \"--basic-auth\"\n            set: false\n\n    - id: 2\n      text: \"flag value is set to some value\"\n      audit: \"echo \\\"Non empty command\\\"\"\n      tests:\n        test_items:\n          - flag: \"--insecure-port\"\n            compare:\n              op: eq\n              value: 0\n            set: true\n\n    - id: 3\n      text: \"flag value is greater than or equal some number\"\n      audit: \"echo \\\"Non empty command\\\"\"\n      tests:\n        test_items:\n          - flag: \"--audit-log-maxage\"\n            compare:\n              op: gte\n              value: 30\n            set: true\n\n    - id: 4\n      text: \"flag value is less than some number\"\n      audit: \"echo \\\"Non empty command\\\"\"\n      tests:\n        test_items:\n          - flag: \"--max-backlog\"\n            compare:\n              op: lt\n              value: 30\n            set: true\n\n    - id: 5\n      text: \"flag value does not have some value\"\n      audit: \"echo \\\"Non empty command\\\"\"\n      tests:\n        test_items:\n          - flag: \"--admission-control\"\n            compare:\n              op: nothave\n              value: AlwaysAdmit\n            set: true\n\n    - id: 6\n      text: \"test AND binary operation\"\n      audit: \"echo \\\"Non empty command\\\"\"\n      tests:\n        bin_op: and\n        test_items:\n        - flag: \"--kubelet-client-certificate\"\n          set: true\n        - flag: \"--kubelet-clientkey\"\n          set: true\n\n    - id: 7\n      text: \"test OR binary operation\"\n      audit: \"echo \\\"Non empty command\\\"\"\n      tests:\n        bin_op: or\n        test_items:\n          - flag:  \"--secure-port\"\n            compare:\n              op: eq\n              value: 0\n            set: true\n          -\n            flag: \"--secure-port\"\n            set: false\n\n    - id: 8\n      text: \"test flag with arbitrary text\"\n      audit: \"echo \\\"Non empty command\\\"\"\n      tests:\n        test_items:\n        - flag: \"permissions\"\n          compare:\n            op: eq\n            value: \"SomeValue\"\n          set: true\n\n    - id: 9\n      text: \"test permissions\"\n      audit: \"/bin/sh -c 'if test -e $config; then stat -c permissions=%a $config; fi'\"\n      tests:\n        test_items:\n        - flag: \"permissions\"\n          compare:\n            op: bitmask\n            value: \"644\"\n          set: true\n\n    - id: 10\n      text: \"flag value includes some value in a comma-separated list, value is last in list\"\n      audit: \"echo \\\"Non empty command\\\"\"\n      tests:\n        test_items:\n          - flag: \"--admission-control\"\n            compare:\n              op: has\n              value: RBAC\n            set: true\n\n    - id: 11\n      text: \"flag value includes some value in a comma-separated list, value is first in list\"\n      audit: \"echo \\\"Non empty command\\\"\"\n      tests:\n        test_items:\n          - flag: \"--admission-control\"\n            compare:\n              op: has\n              value: WebHook\n            set: true\n\n    - id: 12\n      text: \"flag value includes some value in a comma-separated list, value middle of list\"\n      audit: \"echo \\\"Non empty command\\\"\"\n      tests:\n        test_items:\n          - flag: \"--admission-control\"\n            compare:\n              op: has\n              value: Something\n            set: true\n\n    - id: 13\n      text: \"flag value includes some value in a comma-separated list, value only one in list\"\n      audit: \"echo \\\"Non empty command\\\"\"\n      tests:\n        test_items:\n          - flag: \"--admission-control\"\n            compare:\n              op: has\n              value: Something\n            set: true\n\n    - id: 14\n      text: \"check that flag some-arg is set to some-val with ':' separator\"\n      audit: \"echo \\\"Non empty command\\\"\"\n      tests:\n        test_items:\n          - flag: \"some-arg\"\n            compare:\n              op: eq\n              value: some-val\n            set: true\n\n    - id: 15\n      text: \"jsonpath correct value on field\"\n      audit: \"echo \\\"Non empty command\\\"\"\n      audit_config: \"echo \\\"Non empty command\\\"\"\n      tests:\n        bin_op: or\n        test_items:\n          - path: \"{.readOnlyPort}\"\n            compare:\n              op: eq\n              value: 15000\n            set: true\n          - path: \"{.readOnlyPort}\"\n            compare:\n              op: gte\n              value: 15000\n            set: true\n          - path: \"{.readOnlyPort}\"\n            compare:\n              op: lte\n              value: 15000\n            set: true\n\n    - id: 16\n      text: \"jsonpath correct case-sensitive value on string field\"\n      audit: \"echo \\\"Non empty command\\\"\"\n      audit_config: \"echo \\\"Non empty command\\\"\"\n      tests:\n        test_items:\n          - path: \"{.stringValue}\"\n            compare:\n              op: noteq\n              value: \"None\"\n            set: true\n          - path: \"{.stringValue}\"\n            compare:\n              op: noteq\n              value: \"webhook,Something,RBAC\"\n            set: true\n          - path: \"{.stringValue}\"\n            compare:\n              op: eq\n              value: \"WebHook,Something,RBAC\"\n            set: true\n\n    - id: 17\n      text: \"jsonpath correct value on boolean field\"\n      audit: \"echo \\\"Non empty command\\\"\"\n      audit_config: \"echo \\\"Non empty command\\\"\"\n      tests:\n        test_items:\n          - path: \"{.trueValue}\"\n            compare:\n              op: noteq\n              value: somethingElse\n            set: true\n          - path: \"{.trueValue}\"\n            compare:\n              op: noteq\n              value: false\n            set: true\n          - path: \"{.trueValue}\"\n            compare:\n              op: eq\n              value: true\n            set: true\n\n    - id: 18\n      text: \"jsonpath field absent\"\n      audit: \"echo \\\"Non empty command\\\"\"\n      audit_config: \"echo \\\"Non empty command\\\"\"\n      tests:\n        test_items:\n          - path: \"{.notARealField}\"\n            set: false\n\n    - id: 19\n      text: \"jsonpath correct value on nested field\"\n      audit: \"echo \\\"Non empty command\\\"\"\n      audit_config: \"echo \\\"Non empty command\\\"\"\n      tests:\n        test_items:\n          - path: \"{.authentication.anonymous.enabled}\"\n            compare:\n              op: eq\n              value: \"false\"\n            set: true\n\n    - id: 20\n      text: \"yamlpath correct value on field\"\n      audit: \"echo \\\"Non empty command\\\"\"\n      audit_config: \"echo \\\"Non empty command\\\"\"\n      tests:\n        test_items:\n          - path: \"{.readOnlyPort}\"\n            compare:\n              op: gt\n              value: 14999\n            set: true\n\n    - id: 21\n      text: \"yamlpath field absent\"\n      audit: \"echo \\\"Non empty command\\\"\"\n      audit_config: \"echo \\\"Non empty command\\\"\"\n      tests:\n        test_items:\n          - path: \"{.fieldThatIsUnset}\"\n            set: false\n\n    - id: 22\n      text: \"yamlpath correct value on nested field\"\n      audit: \"echo \\\"Non empty command\\\"\"\n      audit_config: \"echo \\\"Non empty command\\\"\"\n      tests:\n        test_items:\n          - path: \"{.authentication.anonymous.enabled}\"\n            compare:\n              op: eq\n              value: \"false\"\n            set: true\n\n    - id: 23\n      text: \"path on invalid json\"\n      audit: \"echo \\\"Non empty command\\\"\"\n      audit_config: \"echo \\\"Non empty command\\\"\"\n      tests:\n        test_items:\n          - path: \"{.authentication.anonymous.enabled}\"\n            compare:\n              op: eq\n              value: \"false\"\n            set: true\n\n    - id: 24\n      text: \"path with broken expression\"\n      audit: \"echo \\\"Non empty command\\\"\"\n      audit_config: \"echo \\\"Non empty command\\\"\"\n      tests:\n        test_items:\n          - path: \"{.missingClosingBrace}\"\n            set: true\n\n    - id: 25\n      text: \"yamlpath on invalid yaml\"\n      audit: \"echo \\\"Non empty command\\\"\"\n      tests:\n        test_items:\n          - path: \"{.authentication.anonymous.enabled}\"\n            compare:\n              op: eq\n              value: \"false\"\n            set: true\n\n    - id: 26\n      text: \"check regex op matches\"\n      audit: \"echo \\\"Non empty command\\\"\"\n      audit_config: \"echo \\\"Non empty command\\\"\"\n      tests:\n        test_items:\n          - path: \"{.currentMasterVersion}\"\n            compare:\n              op: regex\n              value: '^1\\.12.*$'\n            set: true\n\n    - id: 27\n      text: \"check boolean flag with no value\"\n      audit: \"echo \\\"Non empty command\\\"\"\n      tests:\n        test_items:\n          - flag: \"--peer-client-cert-auth\"\n            compare:\n              op: eq\n              value: true\n            set: true\n\n    - id: 28\n      text: \"check boolean flag with false value\"\n      audit: \"echo \\\"Non empty command\\\"\"\n      tests:\n        test_items:\n          - flag: \"--peer-client-cert-auth\"\n            compare:\n              op: eq\n              value: false\n            set: true\n    - id: 29\n      text: \"flag is set (via env)\"\n      tests:\n        test_items:\n          - flag: \"--allow-privileged\"\n            env: \"ALLOW_PRIVILEGED\"\n            set: true\n\n    - id: 30\n      text: \"flag is not set (via env)\"\n      tests:\n        test_items:\n          - flag: \"--basic-auth\"\n            env: \"BASIC_AUTH\"\n            set: false\n\n    - id: 31\n      text: \"flag value is set to some value (via env)\"\n      tests:\n        test_items:\n          - flag: \"--insecure-port\"\n            env: \"INSECURE_PORT\"\n            compare:\n              op: eq\n              value: 0\n            set: true\n\n    - id: 32\n      text: \"flag value is greater than or equal some number (via env)\"\n      tests:\n        test_items:\n          - flag: \"--audit-log-maxage\"\n            env: \"AUDIT_LOG_MAXAGE\"\n            compare:\n              op: gte\n              value: 30\n            set: true\n\n    - id: 33\n      text: \"flag value is less than some number (via env)\"\n      tests:\n        test_items:\n          - env: \"MAX_BACKLOG\"\n            compare:\n              op: lt\n              value: 30\n            set: true\n\n- id: 2.1\n  text: \"audit and audit_config commands\"\n  checks:\n    - id: 0\n      text: \"audit finds flag and passes, audit_config doesn't exist -> pass\"\n      audit: \"echo flag=correct\"\n      tests:\n        test_items:\n          - flag: \"flag\"\n            compare:\n              op: eq\n              value: \"correct\"\n            set: true\n      scored: true\n    - id: 1\n      text: \"audit finds flag and fails, audit_config doesn't exist -> fail\"\n      audit: \"echo flag=wrong\"\n      tests:\n        test_items:\n          - flag: \"flag\"\n            compare:\n              op: eq\n              value: \"correct\"\n            set: true\n      scored: true\n    - id: 2\n      text: \"audit doesn't find flag, audit_config doesn't exist -> fail\"\n      audit: \"echo somethingElse=correct\"\n      tests:\n        test_items:\n          - flag: \"flag\"\n            compare:\n              op: eq\n              value: \"correct\"\n            set: true\n      scored: true\n    - id: 3\n      text: \"audit doesn't find flag, audit_config has correct setting -> pass\"\n      audit: \"echo somethingElse=correct\"\n      audit_config: \"echo 'flag: correct'\"\n      tests:\n        test_items:\n          - flag: \"flag\"\n            path: \"{.flag}\"\n            compare:\n              op: eq\n              value: \"correct\"\n            set: true\n      scored: true\n    - id: 4\n      text: \"audit doesn't find flag, audit_config has wrong setting -> fail\"\n      audit: \"echo somethingElse=correct\"\n      audit_config: \"echo 'flag: wrong'\"\n      tests:\n        test_items:\n          - flag: \"flag\"\n            path: \"{.flag}\"\n            compare:\n              op: eq\n              value: \"correct\"\n            set: true\n      scored: true\n    - id: 5\n      text: \"audit finds correct flag, audit_config has wrong setting -> pass\"\n      audit: \"echo flag=correct\"\n      audit_config: \"echo 'flag: wrong'\"\n      tests:\n        test_items:\n          - flag: \"flag\"\n            path: \"{.flag}\"\n            compare:\n              op: eq\n              value: \"correct\"\n            set: true\n      scored: true\n    - id: 6\n      text: \"neither audit nor audit_config has correct setting -> fail\"\n      audit: \"echo flag=wrong\"\n      audit_config: \"echo 'flag: wrong'\"\n      tests:\n        test_items:\n          - flag: \"flag\"\n            path: \"{.flag}\"\n            compare:\n              op: eq\n              value: \"correct\"\n            set: true\n      scored: true\n    - id: 7\n      text: \"audit isn't present, superfluous flag field,audit_config is correct -> pass\"\n      audit_config: \"echo 'flag: correct'\"\n      tests:\n        test_items:\n          - flag: \"flag\"\n            path: \"{.flag}\"\n            compare:\n              op: eq\n              value: \"correct\"\n            set: true\n      scored: true\n    - id: 8\n      text: \"audit isn't present, superfluous flag field,audit_config is wrong -> fail\"\n      audit_config: \"echo 'flag: wrong'\"\n      tests:\n        test_items:\n          - flag: \"flag\"\n            path: \"{.flag}\"\n            compare:\n              op: eq\n              value: \"correct\"\n            set: true\n      scored: true\n    - id: 9\n      text: \"test use_multiple_values is correct -> pass\"\n      audit: \"printf 'permissions=600\\npermissions=600\\npermissions=600'\"\n      use_multiple_values: true\n      tests:\n        test_items:\n          - flag: \"permissions\"\n            compare:\n              op: bitmask\n              value: \"600\"\n            set: true\n      scored: true\n    - id: 10\n      text: \"test use_multiple_values is wrong -> fail\"\n      audit: \"printf 'permissions=600\\npermissions=600\\npermissions=644'\"\n      use_multiple_values: true\n      tests:\n        test_items:\n          - flag: \"permissions\"\n            compare:\n              op: bitmask\n              value: \"600\"\n            set: true\n      scored: true\n    - id: 11\n      text: \"test use_multiple_values include empty value -> fail\"\n      audit: \"printf 'permissions=600\\n\\npermissions=600'\"\n      use_multiple_values: true\n      tests:\n        test_items:\n          - flag: \"permissions\"\n            compare:\n              op: bitmask\n              value: \"600\"\n            set: true\n      scored: true\n    - id: 12\n      text: \"audit is present and wrong, audit_config is right -> fail (command line parameters override config file)\"\n      audit: \"echo flag=wrong\"\n      audit_config: \"echo 'flag: correct'\"\n      tests:\n        test_items:\n          - flag: \"flag\"\n            path: \"{.flag}\"\n            compare:\n              op: eq\n              value: \"correct\"\n            set: true\n      scored: true\n    - id: 13\n      text: \"parameter and config file don't have same default - parameter has failing value\"\n      audit: \"echo '--read-only-port=1'\"\n      audit_config: \"echo 'readOnlyPort: 0'\"\n      tests:\n        bin_op: and\n        test_items:\n          - flag: \"--read-only-port\"\n            path: \"{.readOnlyPort}\"\n            set: true\n            compare:\n              op: eq\n              value: 0\n          - flag: \"--read-only-port\"\n            path: '{.readOnlyPort}'\n            set: false\n      scored: true\n    - id: 14\n      text: \"parameter and config file don't have same default - config file has failing value\"\n      audit: \"echo ''\"\n      audit_config: \"echo 'readOnlyPort: 1'\"\n      tests:\n        bin_op: or\n        test_items:\n          - flag: \"--read-only-port\"\n            path: '{.readOnlyPort}'\n            set: true\n            compare:\n              op: eq\n              value: 0\n          - flag: \"--read-only-port\"\n            path: '{.readOnlyPort}'\n            set: false\n      scored: true\n    - id: 15\n      text: \"parameter and config file don't have same default - passing\"\n      audit: \"echo ''\"\n      audit_config: \"echo ''\"\n      tests:\n        bin_op: or\n        test_items:\n          - flag: \"--read-only-port\"\n            path: '{.readOnlyPort}'\n            set: true\n            compare:\n              op: eq\n              value: 0\n          - flag: \"--read-only-port\"\n            path: '{.readOnlyPort}'\n            set: false\n      scored: true\n    - id: 16\n      text: \"parameter and config file don't have same default - parameter has bad value and config is not present - failing\"\n      audit: \"echo '--read-only-port=1'\"\n      audit_config: \"echo ''\"\n      tests:\n        bin_op: or\n        test_items:\n          - flag: \"--read-only-port\"\n            path: '{.readOnlyPort}'\n            set: true\n            compare:\n              op: eq\n              value: 0\n          - flag: \"--read-only-port\"\n            path: '{.readOnlyPort}'\n            set: false\n      scored: true\n\n- id: 3.1\n  text: \"audit_env commands\"\n  checks:\n    - id: 0\n      text: \"audit fails to find flag, audit_env finds flag -> pass\"\n      audit: \"echo in=incorrect\"\n      audit_env: \"echo flag=correct\"\n      tests:\n        test_items:\n          - flag: \"flag\"\n            env: \"flag\"\n            compare:\n              op: eq\n              value: \"correct\"\n            set: true\n      scored: true\n    - id: 1\n      text: \"audit fails to find flag, audit_env finds flag and fails -> fail\"\n      audit: \"echo in=wrong\"\n      audit_env: \"echo flag=wrong\"\n      tests:\n        test_items:\n          - flag: \"flag\"\n            env: \"flag\"\n            compare:\n              op: eq\n              value: \"correct\"\n            set: true\n      scored: true\n    - id: 2\n      text: \"audit finds correct flag, audit_env is incorrect -> pass\"\n      audit: \"echo flag=correct\"\n      audit_env: \"echo flag=incorrect\"\n      tests:\n        test_items:\n          - flag: \"flag\"\n            env: \"flag\"\n            compare:\n              op: eq\n              value: \"correct\"\n            set: true\n      scored: true\n    - id: 3\n      text: \"audit doesn't flag flag, audit_config finds it and passes, audit_env is not present -> pass\"\n      audit: \"echo in=correct\"\n      audit_config: \"echo 'flag: correct'\"\n      tests:\n        test_items:\n          - flag: \"flag\"\n            path: \"{.flag}\"\n            compare:\n              op: eq\n              value: \"correct\"\n            set: true\n      scored: true\n    - id: 4\n      text: \"audit doesn't flag flag, audit_config doesn't find flag, audit_env finds and passes -> pass\"\n      audit: \"echo in=correct\"\n      audit_config: \"echo 'in: correct'\"\n      audit_env: \"echo flag=correct\"\n      tests:\n        test_items:\n          - flag: \"flag\"\n            path: \"{.flag}\"\n            env: \"flag\"\n            compare:\n              op: eq\n              value: \"correct\"\n            set: true\n      scored: true\n    - id: 5\n      text: \"audit doesn't find flag, audit_config doesn't find flag, audit_env finds and fails -> fails\"\n      audit: \"echo in=correct\"\n      audit_config: \"echo 'in: correct'\"\n      audit_env: \"echo flag=incorrect\"\n      tests:\n        test_items:\n          - flag: \"flag\"\n            path: \"{.flag}\"\n            env: \"flag\"\n            compare:\n              op: eq\n              value: \"correct\"\n            set: true\n      scored: true\n    - id: 6\n      text: \"audit finds flag and fails, audit_config finds flag and fails, audit_env finds and passes -> fails\"\n      audit: \"echo flag=incorrect\"\n      audit_config: \"echo 'flag: incorrect'\"\n      audit_env: \"echo flag=correct\"\n      tests:\n        test_items:\n          - flag: \"flag\"\n            path: \"{.flag}\"\n            env: \"flag\"\n            compare:\n              op: eq\n              value: \"correct\"\n            set: true\n      scored: true\n"
  },
  {
    "path": "check/test.go",
    "content": "// Copyright © 2017 Aqua Security Software Ltd. <info@aquasec.com>\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage check\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"os\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/golang/glog\"\n\t\"gopkg.in/yaml.v2\"\n\t\"k8s.io/client-go/util/jsonpath\"\n)\n\n// test:\n// flag: OPTION\n// set: (true|false)\n// compare:\n//   op: (eq|gt|gte|lt|lte|has)\n//   value: val\n\ntype binOp string\n\nconst (\n\tand                   binOp = \"and\"\n\tor                          = \"or\"\n\tdefaultArraySeparator       = \",\"\n)\n\ntype tests struct {\n\tTestItems []*testItem `yaml:\"test_items\"`\n\tBinOp     binOp       `yaml:\"bin_op\"`\n}\n\ntype AuditUsed string\n\nconst (\n\tAuditCommand AuditUsed = \"auditCommand\"\n\tAuditConfig  AuditUsed = \"auditConfig\"\n\tAuditEnv     AuditUsed = \"auditEnv\"\n)\n\ntype testItem struct {\n\tFlag             string\n\tEnv              string\n\tPath             string\n\tOutput           string\n\tValue            string\n\tSet              bool\n\tCompare          compare\n\tisMultipleOutput bool\n\tauditUsed        AuditUsed\n}\n\ntype (\n\tenvTestItem  testItem\n\tpathTestItem testItem\n\tflagTestItem testItem\n)\n\ntype compare struct {\n\tOp    string\n\tValue string\n}\n\ntype testOutput struct {\n\ttestResult     bool\n\tflagFound      bool\n\tactualResult   string\n\tExpectedResult string\n}\n\nfunc failTestItem(s string) *testOutput {\n\treturn &testOutput{testResult: false, actualResult: s}\n}\n\nfunc (t testItem) value() string {\n\tif t.auditUsed == AuditConfig {\n\t\treturn t.Path\n\t}\n\n\tif t.auditUsed == AuditEnv {\n\t\treturn t.Env\n\t}\n\n\treturn t.Flag\n}\n\nfunc (t testItem) findValue(s string) (match bool, value string, err error) {\n\tif t.auditUsed == AuditEnv {\n\t\tet := envTestItem(t)\n\t\treturn et.findValue(s)\n\t}\n\n\tif t.auditUsed == AuditConfig {\n\t\tpt := pathTestItem(t)\n\t\treturn pt.findValue(s)\n\t}\n\n\tft := flagTestItem(t)\n\treturn ft.findValue(s)\n}\n\nfunc (t flagTestItem) findValue(s string) (match bool, value string, err error) {\n\tif s == \"\" || t.Flag == \"\" {\n\t\treturn\n\t}\n\tmatch = strings.Contains(s, t.Flag)\n\tif match {\n\t\t// Expects flags in the form;\n\t\t// --flag=somevalue\n\t\t// flag: somevalue\n\t\t// --flag\n\t\t// somevalue\n\t\t// DOESN'T COVER - use pathTestItem implementation of findValue() for this\n\t\t// flag:\n\t\t//\t - wehbook\n\t\tpttn := `(` + t.Flag + `)(=|: *)*([^\\s]*) *`\n\t\tflagRe := regexp.MustCompile(pttn)\n\t\tvals := flagRe.FindStringSubmatch(s)\n\n\t\tif len(vals) > 0 {\n\t\t\tif vals[3] != \"\" {\n\t\t\t\tvalue = vals[3]\n\t\t\t} else {\n\t\t\t\t// --bool-flag\n\t\t\t\tif strings.HasPrefix(t.Flag, \"--\") {\n\t\t\t\t\tvalue = \"true\"\n\t\t\t\t} else {\n\t\t\t\t\tvalue = vals[1]\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\terr = fmt.Errorf(\"invalid flag in testItem definition: %s\", s)\n\t\t}\n\t}\n\tglog.V(3).Infof(\"In flagTestItem.findValue %s\", value)\n\n\treturn match, value, err\n}\n\nfunc (t pathTestItem) findValue(s string) (match bool, value string, err error) {\n\tvar jsonInterface interface{}\n\n\terr = unmarshal(s, &jsonInterface)\n\tif err != nil {\n\t\treturn false, \"\", fmt.Errorf(\"failed to load YAML or JSON from input \\\"%s\\\": %v\", s, err)\n\t}\n\n\tvalue, err = executeJSONPath(t.Path, &jsonInterface)\n\tif err != nil {\n\t\treturn false, \"\", fmt.Errorf(\"unable to parse path expression \\\"%s\\\": %v\", t.Path, err)\n\t}\n\n\tglog.V(3).Infof(\"In pathTestItem.findValue %s\", value)\n\tmatch = value != \"\"\n\treturn match, value, err\n}\n\nfunc (t envTestItem) findValue(s string) (match bool, value string, err error) {\n\tif s != \"\" && t.Env != \"\" {\n\t\tr, _ := regexp.Compile(fmt.Sprintf(\"%s=.*(?:$|\\\\n)\", t.Env))\n\t\tout := r.FindString(s)\n\t\tout = strings.Replace(out, \"\\n\", \"\", 1)\n\t\tout = strings.Replace(out, fmt.Sprintf(\"%s=\", t.Env), \"\", 1)\n\n\t\tif len(out) > 0 {\n\t\t\tmatch = true\n\t\t\tvalue = out\n\t\t} else {\n\t\t\tmatch = false\n\t\t\tvalue = \"\"\n\t\t}\n\t}\n\tglog.V(3).Infof(\"In envTestItem.findValue %s\", value)\n\treturn match, value, nil\n}\n\nfunc (t testItem) execute(s string) *testOutput {\n\tresult := &testOutput{}\n\ts = strings.TrimRight(s, \" \\n\")\n\n\t// If the test has output that should be evaluated for each row\n\tvar output []string\n\tif t.isMultipleOutput {\n\t\toutput = strings.Split(s, \"\\n\")\n\t} else {\n\t\toutput = []string{s}\n\t}\n\n\tfor _, op := range output {\n\t\tresult = t.evaluate(op)\n\t\t// If the test failed for the current row, no need to keep testing for this output\n\t\tif !result.testResult {\n\t\t\tbreak\n\t\t}\n\t}\n\n\tresult.actualResult = s\n\treturn result\n}\n\nfunc (t testItem) evaluate(s string) *testOutput {\n\tresult := &testOutput{}\n\n\tmatch, value, err := t.findValue(s)\n\tif err != nil {\n\t\tfmt.Fprint(os.Stderr, err.Error())\n\t\treturn failTestItem(err.Error())\n\t}\n\n\tif t.Set {\n\t\tif match && t.Compare.Op != \"\" {\n\t\t\tresult.ExpectedResult, result.testResult = compareOp(t.Compare.Op, value, t.Compare.Value, t.value())\n\t\t} else {\n\t\t\tresult.ExpectedResult = fmt.Sprintf(\"'%s' is present\", t.value())\n\t\t\tresult.testResult = match\n\t\t}\n\t} else {\n\t\tresult.ExpectedResult = fmt.Sprintf(\"'%s' is not present\", t.value())\n\t\tresult.testResult = !match\n\t}\n\n\tresult.flagFound = match\n\tisExist := \"exists\"\n\tif !result.flagFound {\n\t\tisExist = \"does not exist\"\n\t}\n\tswitch t.auditUsed {\n\tcase AuditCommand:\n\t\tglog.V(3).Infof(\"Flag '%s' %s\", t.Flag, isExist)\n\tcase AuditConfig:\n\t\tglog.V(3).Infof(\"Path '%s' %s\", t.Path, isExist)\n\tcase AuditEnv:\n\t\tglog.V(3).Infof(\"Env '%s' %s\", t.Env, isExist)\n\tdefault:\n\t\tglog.V(3).Infof(\"Error with identify audit used %s\", t.auditUsed)\n\t}\n\n\treturn result\n}\n\nfunc compareOp(tCompareOp string, flagVal string, tCompareValue string, flagName string) (string, bool) {\n\texpectedResultPattern := \"\"\n\ttestResult := false\n\n\tswitch tCompareOp {\n\tcase \"eq\":\n\t\texpectedResultPattern = \"'%s' is equal to '%s'\"\n\t\tvalue := strings.ToLower(flagVal)\n\t\t// Do case insensitive comparaison for booleans ...\n\t\tif value == \"false\" || value == \"true\" {\n\t\t\ttestResult = value == tCompareValue\n\t\t} else {\n\t\t\ttestResult = flagVal == tCompareValue\n\t\t}\n\n\tcase \"noteq\":\n\t\texpectedResultPattern = \"'%s' is not equal to '%s'\"\n\t\tvalue := strings.ToLower(flagVal)\n\t\t// Do case insensitive comparaison for booleans ...\n\t\tif value == \"false\" || value == \"true\" {\n\t\t\ttestResult = !(value == tCompareValue)\n\t\t} else {\n\t\t\ttestResult = !(flagVal == tCompareValue)\n\t\t}\n\n\tcase \"gt\", \"gte\", \"lt\", \"lte\":\n\t\ta, b, err := toNumeric(flagVal, tCompareValue)\n\t\tif err != nil {\n\t\t\texpectedResultPattern = \"Invalid Number(s) used for comparison: '%s' '%s'\"\n\t\t\tglog.V(1).Infof(fmt.Sprintf(\"Not numeric value - flag: %q - compareValue: %q %v\\n\", flagVal, tCompareValue, err))\n\t\t\treturn fmt.Sprintf(expectedResultPattern, flagVal, tCompareValue), false\n\t\t}\n\t\tswitch tCompareOp {\n\t\tcase \"gt\":\n\t\t\texpectedResultPattern = \"'%s' is greater than %s\"\n\t\t\ttestResult = a > b\n\n\t\tcase \"gte\":\n\t\t\texpectedResultPattern = \"'%s' is greater or equal to %s\"\n\t\t\ttestResult = a >= b\n\n\t\tcase \"lt\":\n\t\t\texpectedResultPattern = \"'%s' is lower than %s\"\n\t\t\ttestResult = a < b\n\n\t\tcase \"lte\":\n\t\t\texpectedResultPattern = \"'%s' is lower or equal to %s\"\n\t\t\ttestResult = a <= b\n\t\t}\n\n\tcase \"has\":\n\t\texpectedResultPattern = \"'%s' has '%s'\"\n\t\ttestResult = strings.Contains(flagVal, tCompareValue)\n\n\tcase \"nothave\":\n\t\texpectedResultPattern = \"'%s' does not have '%s'\"\n\t\ttestResult = !strings.Contains(flagVal, tCompareValue)\n\n\tcase \"regex\":\n\t\texpectedResultPattern = \"'%s' matched by regex expression '%s'\"\n\t\topRe := regexp.MustCompile(tCompareValue)\n\t\ttestResult = opRe.MatchString(flagVal)\n\n\tcase \"valid_elements\":\n\t\texpectedResultPattern = \"'%s' contains valid elements from '%s'\"\n\t\ts := splitAndRemoveLastSeparator(flagVal, defaultArraySeparator)\n\t\ttarget := splitAndRemoveLastSeparator(tCompareValue, defaultArraySeparator)\n\t\ttestResult = allElementsValid(s, target)\n\n\tcase \"bitmask\":\n\t\texpectedResultPattern = \"%s has permissions \" + flagVal + \", expected %s or more restrictive\"\n\t\trequested, err := strconv.ParseInt(flagVal, 8, 64)\n\t\tif err != nil {\n\t\t\tglog.V(1).Infof(fmt.Sprintf(\"Not numeric value - flag: %q - compareValue: %q %v\\n\", flagVal, tCompareValue, err))\n\t\t\treturn fmt.Sprintf(\"Not numeric value - flag: %s\", flagVal), false\n\t\t}\n\t\tmax, err := strconv.ParseInt(tCompareValue, 8, 64)\n\t\tif err != nil {\n\t\t\tglog.V(1).Infof(fmt.Sprintf(\"Not numeric value - flag: %q - compareValue: %q %v\\n\", flagVal, tCompareValue, err))\n\t\t\treturn fmt.Sprintf(\"Not numeric value - flag: %s\", tCompareValue), false\n\t\t}\n\t\ttestResult = (max & requested) == requested\n\t}\n\tif expectedResultPattern == \"\" {\n\t\treturn expectedResultPattern, testResult\n\t}\n\n\treturn fmt.Sprintf(expectedResultPattern, flagName, tCompareValue), testResult\n}\n\nfunc unmarshal(s string, jsonInterface *interface{}) error {\n\tdata := []byte(s)\n\terr := json.Unmarshal(data, jsonInterface)\n\tif err != nil {\n\t\terr := yaml.Unmarshal(data, jsonInterface)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc executeJSONPath(path string, jsonInterface interface{}) (string, error) {\n\tj := jsonpath.New(\"jsonpath\")\n\tj.AllowMissingKeys(true)\n\terr := j.Parse(path)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tbuf := new(bytes.Buffer)\n\terr = j.Execute(buf, jsonInterface)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tjsonpathResult := buf.String()\n\treturn jsonpathResult, nil\n}\n\nfunc allElementsValid(s, t []string) bool {\n\tsourceEmpty := len(s) == 0\n\ttargetEmpty := len(t) == 0\n\n\tif sourceEmpty && targetEmpty {\n\t\treturn true\n\t}\n\n\t// XOR comparison -\n\t//     if either value is empty and the other is not empty,\n\t//     not all elements are valid\n\tif (sourceEmpty || targetEmpty) && !(sourceEmpty && targetEmpty) {\n\t\treturn false\n\t}\n\n\tfor _, sv := range s {\n\t\tfound := false\n\t\tfor _, tv := range t {\n\t\t\tif sv == tv {\n\t\t\t\tfound = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif !found {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\nfunc splitAndRemoveLastSeparator(s, sep string) []string {\n\tcleanS := strings.TrimRight(strings.TrimSpace(s), sep)\n\tif len(cleanS) == 0 {\n\t\treturn []string{}\n\t}\n\n\tts := strings.Split(cleanS, sep)\n\tfor i := range ts {\n\t\tts[i] = strings.TrimSpace(ts[i])\n\t}\n\n\treturn ts\n}\n\nfunc toNumeric(a, b string) (c, d int, err error) {\n\tc, err = strconv.Atoi(strings.TrimSpace(a))\n\tif err != nil {\n\t\treturn -1, -1, fmt.Errorf(\"toNumeric - error converting %s: %s\", a, err)\n\t}\n\td, err = strconv.Atoi(strings.TrimSpace(b))\n\tif err != nil {\n\t\treturn -1, -1, fmt.Errorf(\"toNumeric - error converting %s: %s\", b, err)\n\t}\n\n\treturn c, d, nil\n}\n\nfunc (t *testItem) UnmarshalYAML(unmarshal func(interface{}) error) error {\n\ttype buildTest testItem\n\n\t// Make Set parameter to be true by default.\n\tnewTestItem := buildTest{Set: true}\n\terr := unmarshal(&newTestItem)\n\tif err != nil {\n\t\treturn err\n\t}\n\t*t = testItem(newTestItem)\n\treturn nil\n}\n"
  },
  {
    "path": "check/test_test.go",
    "content": "// Copyright © 2017-2020 Aqua Security Software Ltd. <info@aquasec.com>\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage check\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"strings\"\n\t\"testing\"\n)\n\nvar (\n\tin       []byte\n\tcontrols *Controls\n)\n\nfunc init() {\n\tvar err error\n\tin, err = os.ReadFile(\"data\")\n\tif err != nil {\n\t\tpanic(\"Failed reading test data: \" + err.Error())\n\t}\n\n\t// substitute variables in data file\n\tuser := os.Getenv(\"USER\")\n\ts := strings.Replace(string(in), \"$user\", user, -1)\n\n\tcontrols, err = NewControls(MASTER, []byte(s), \"\")\n\t// controls, err = NewControls(MASTER, in)\n\tif err != nil {\n\t\tpanic(\"Failed creating test controls: \" + err.Error())\n\t}\n}\n\nfunc TestTestExecute(t *testing.T) {\n\tcases := []struct {\n\t\tcheck              *Check\n\t\tstr                string\n\t\tstrConfig          string\n\t\texpectedTestResult string\n\t\tstrEnv             string\n\t}{\n\t\t{\n\t\t\tcheck:              controls.Groups[0].Checks[0],\n\t\t\tstr:                \"2:45 ../kubernetes/kube-apiserver --allow-privileged=false --option1=20,30,40\",\n\t\t\tstrConfig:          \"\",\n\t\t\texpectedTestResult: \"'--allow-privileged' is present\",\n\t\t},\n\t\t{\n\t\t\tcheck:              controls.Groups[0].Checks[1],\n\t\t\tstr:                \"2:45 ../kubernetes/kube-apiserver --allow-privileged=false\",\n\t\t\tstrConfig:          \"\",\n\t\t\texpectedTestResult: \"'--basic-auth' is not present\",\n\t\t},\n\t\t{\n\t\t\tcheck:              controls.Groups[0].Checks[2],\n\t\t\tstr:                \"niinai   13617  2635 99 19:26 pts/20   00:03:08 ./kube-apiserver --insecure-port=0 --anonymous-auth\",\n\t\t\tstrConfig:          \"\",\n\t\t\texpectedTestResult: \"'--insecure-port' is equal to '0'\",\n\t\t},\n\t\t{\n\t\t\tcheck:              controls.Groups[0].Checks[3],\n\t\t\tstr:                \"2:45 ../kubernetes/kube-apiserver --secure-port=0 --audit-log-maxage=40 --option\",\n\t\t\tstrConfig:          \"\",\n\t\t\texpectedTestResult: \"'--audit-log-maxage' is greater or equal to 30\",\n\t\t},\n\t\t{\n\t\t\tcheck:              controls.Groups[0].Checks[4],\n\t\t\tstr:                \"2:45 ../kubernetes/kube-apiserver --max-backlog=20 --secure-port=0 --audit-log-maxage=40 --option\",\n\t\t\tstrConfig:          \"\",\n\t\t\texpectedTestResult: \"'--max-backlog' is lower than 30\",\n\t\t},\n\t\t{\n\t\t\tcheck:              controls.Groups[0].Checks[5],\n\t\t\tstr:                \"2:45 ../kubernetes/kube-apiserver --option --admission-control=WebHook,RBAC ---audit-log-maxage=40\",\n\t\t\tstrConfig:          \"\",\n\t\t\texpectedTestResult: \"'--admission-control' does not have 'AlwaysAdmit'\",\n\t\t},\n\t\t{\n\t\t\tcheck:              controls.Groups[0].Checks[6],\n\t\t\tstr:                \"2:45 .. --kubelet-clientkey=foo --kubelet-client-certificate=bar --admission-control=Webhook,RBAC\",\n\t\t\tstrConfig:          \"\",\n\t\t\texpectedTestResult: \"'--kubelet-client-certificate' is present AND '--kubelet-clientkey' is present\",\n\t\t},\n\t\t{\n\t\t\tcheck:              controls.Groups[0].Checks[7],\n\t\t\tstr:                \"2:45 ..  --secure-port=0 --kubelet-client-certificate=bar --admission-control=Webhook,RBAC\",\n\t\t\tstrConfig:          \"\",\n\t\t\texpectedTestResult: \"'--secure-port' is equal to '0' OR '--secure-port' is not present\",\n\t\t},\n\t\t{\n\t\t\tcheck:              controls.Groups[0].Checks[8],\n\t\t\tstr:                \"permissions=SomeValue\",\n\t\t\tstrConfig:          \"\",\n\t\t\texpectedTestResult: \"'permissions' is equal to 'SomeValue'\",\n\t\t},\n\t\t{\n\t\t\tcheck:              controls.Groups[0].Checks[9],\n\t\t\tstr:                \"permissions=640\",\n\t\t\tstrConfig:          \"\",\n\t\t\texpectedTestResult: \"permissions has permissions 640, expected 644 or more restrictive\",\n\t\t},\n\t\t{\n\t\t\tcheck:              controls.Groups[0].Checks[9],\n\t\t\tstr:                \"permissions=600\",\n\t\t\tstrConfig:          \"\",\n\t\t\texpectedTestResult: \"permissions has permissions 600, expected 644 or more restrictive\",\n\t\t},\n\t\t{\n\t\t\tcheck:              controls.Groups[0].Checks[10],\n\t\t\tstr:                \"2:45 ../kubernetes/kube-apiserver --option --admission-control=WebHook,RBAC ---audit-log-maxage=40\",\n\t\t\tstrConfig:          \"\",\n\t\t\texpectedTestResult: \"'--admission-control' has 'RBAC'\",\n\t\t},\n\t\t{\n\t\t\tcheck:              controls.Groups[0].Checks[11],\n\t\t\tstr:                \"2:45 ../kubernetes/kube-apiserver --option --admission-control=WebHook,RBAC ---audit-log-maxage=40\",\n\t\t\tstrConfig:          \"\",\n\t\t\texpectedTestResult: \"'--admission-control' has 'WebHook'\",\n\t\t},\n\t\t{\n\t\t\tcheck:              controls.Groups[0].Checks[12],\n\t\t\tstr:                \"2:45 ../kubernetes/kube-apiserver --option --admission-control=WebHook,Something,RBAC ---audit-log-maxage=40\",\n\t\t\tstrConfig:          \"\",\n\t\t\texpectedTestResult: \"'--admission-control' has 'Something'\",\n\t\t},\n\t\t{\n\t\t\tcheck:              controls.Groups[0].Checks[13],\n\t\t\tstr:                \"2:45 ../kubernetes/kube-apiserver --option --admission-control=Something ---audit-log-maxage=40\",\n\t\t\tstrConfig:          \"\",\n\t\t\texpectedTestResult: \"'--admission-control' has 'Something'\",\n\t\t},\n\t\t{\n\t\t\t// check for ':' as argument-value separator, with space between arg and val\n\t\t\tcheck:              controls.Groups[0].Checks[14],\n\t\t\tstr:                \"2:45 kube-apiserver some-arg: some-val --admission-control=Something ---audit-log-maxage=40\",\n\t\t\tstrConfig:          \"\",\n\t\t\texpectedTestResult: \"'some-arg' is equal to 'some-val'\",\n\t\t},\n\t\t{\n\t\t\t// check for ':' as argument-value separator, with no space between arg and val\n\t\t\tcheck:              controls.Groups[0].Checks[14],\n\t\t\tstr:                \"2:45 kube-apiserver some-arg:some-val --admission-control=Something ---audit-log-maxage=40\",\n\t\t\tstrConfig:          \"\",\n\t\t\texpectedTestResult: \"'some-arg' is equal to 'some-val'\",\n\t\t},\n\t\t{\n\t\t\tcheck:              controls.Groups[0].Checks[15],\n\t\t\tstr:                \"\",\n\t\t\tstrConfig:          \"{\\\"readOnlyPort\\\": 15000}\",\n\t\t\texpectedTestResult: \"'{.readOnlyPort}' is equal to '15000' OR '{.readOnlyPort}' is greater or equal to 15000 OR '{.readOnlyPort}' is lower or equal to 15000\",\n\t\t},\n\t\t{\n\t\t\tcheck:              controls.Groups[0].Checks[16],\n\t\t\tstr:                \"\",\n\t\t\tstrConfig:          \"{\\\"stringValue\\\": \\\"WebHook,Something,RBAC\\\"}\",\n\t\t\texpectedTestResult: \"'{.stringValue}' is not equal to 'None' AND '{.stringValue}' is not equal to 'webhook,Something,RBAC' AND '{.stringValue}' is equal to 'WebHook,Something,RBAC'\",\n\t\t},\n\t\t{\n\t\t\tcheck:              controls.Groups[0].Checks[17],\n\t\t\tstr:                \"\",\n\t\t\tstrConfig:          \"{\\\"trueValue\\\": true}\",\n\t\t\texpectedTestResult: \"'{.trueValue}' is not equal to 'somethingElse' AND '{.trueValue}' is not equal to 'false' AND '{.trueValue}' is equal to 'true'\",\n\t\t},\n\t\t{\n\t\t\tcheck:              controls.Groups[0].Checks[18],\n\t\t\tstr:                \"\",\n\t\t\tstrConfig:          \"{\\\"readOnlyPort\\\": 15000}\",\n\t\t\texpectedTestResult: \"'{.notARealField}' is not present\",\n\t\t},\n\t\t{\n\t\t\tcheck:              controls.Groups[0].Checks[19],\n\t\t\tstr:                \"\",\n\t\t\tstrConfig:          \"{\\\"authentication\\\": { \\\"anonymous\\\": {\\\"enabled\\\": false}}}\",\n\t\t\texpectedTestResult: \"'{.authentication.anonymous.enabled}' is equal to 'false'\",\n\t\t},\n\t\t{\n\t\t\tcheck:              controls.Groups[0].Checks[20],\n\t\t\tstr:                \"\",\n\t\t\tstrConfig:          \"readOnlyPort: 15000\",\n\t\t\texpectedTestResult: \"'{.readOnlyPort}' is greater than 14999\",\n\t\t},\n\t\t{\n\t\t\tcheck:              controls.Groups[0].Checks[21],\n\t\t\tstr:                \"\",\n\t\t\tstrConfig:          \"readOnlyPort: 15000\",\n\t\t\texpectedTestResult: \"'{.fieldThatIsUnset}' is not present\",\n\t\t},\n\t\t{\n\t\t\tcheck:              controls.Groups[0].Checks[22],\n\t\t\tstr:                \"\",\n\t\t\tstrConfig:          \"authentication:\\n  anonymous:\\n    enabled: false\",\n\t\t\texpectedTestResult: \"'{.authentication.anonymous.enabled}' is equal to 'false'\",\n\t\t},\n\t\t{\n\t\t\tcheck:              controls.Groups[0].Checks[26],\n\t\t\tstr:                \"\",\n\t\t\tstrConfig:          \"currentMasterVersion: 1.12.7\",\n\t\t\texpectedTestResult: \"'{.currentMasterVersion}' matched by regex expression '^1\\\\.12.*$'\",\n\t\t},\n\t\t{\n\t\t\tcheck:              controls.Groups[0].Checks[27],\n\t\t\tstr:                \"--peer-client-cert-auth\",\n\t\t\tstrConfig:          \"\",\n\t\t\texpectedTestResult: \"'--peer-client-cert-auth' is equal to 'true'\",\n\t\t},\n\t\t{\n\t\t\tcheck:              controls.Groups[0].Checks[27],\n\t\t\tstr:                \"--abc=true --peer-client-cert-auth --efg=false\",\n\t\t\tstrConfig:          \"\",\n\t\t\texpectedTestResult: \"'--peer-client-cert-auth' is equal to 'true'\",\n\t\t},\n\t\t{\n\t\t\tcheck:              controls.Groups[0].Checks[27],\n\t\t\tstr:                \"--abc --peer-client-cert-auth --efg\",\n\t\t\tstrConfig:          \"\",\n\t\t\texpectedTestResult: \"'--peer-client-cert-auth' is equal to 'true'\",\n\t\t},\n\t\t{\n\t\t\tcheck:              controls.Groups[0].Checks[27],\n\t\t\tstr:                \"--peer-client-cert-auth=true\",\n\t\t\tstrConfig:          \"\",\n\t\t\texpectedTestResult: \"'--peer-client-cert-auth' is equal to 'true'\",\n\t\t},\n\t\t{\n\t\t\tcheck:              controls.Groups[0].Checks[27],\n\t\t\tstr:                \"--abc --peer-client-cert-auth=true --efg\",\n\t\t\tstrConfig:          \"\",\n\t\t\texpectedTestResult: \"'--peer-client-cert-auth' is equal to 'true'\",\n\t\t},\n\t\t{\n\t\t\tcheck:              controls.Groups[0].Checks[28],\n\t\t\tstr:                \"--abc --peer-client-cert-auth=false --efg\",\n\t\t\tstrConfig:          \"\",\n\t\t\texpectedTestResult: \"'--peer-client-cert-auth' is equal to 'false'\",\n\t\t},\n\t\t{\n\t\t\tcheck:              controls.Groups[0].Checks[29],\n\t\t\tstr:                \"2:45 ../kubernetes/kube-apiserver --option1=20,30,40\",\n\t\t\tstrConfig:          \"\",\n\t\t\texpectedTestResult: \"'ALLOW_PRIVILEGED' is present\",\n\t\t\tstrEnv:             \"SOME_OTHER_ENV=true\\nALLOW_PRIVILEGED=false\",\n\t\t},\n\t\t{\n\t\t\tcheck:              controls.Groups[0].Checks[30],\n\t\t\tstr:                \"2:45 ../kubernetes/kube-apiserver --option1=20,30,40\",\n\t\t\tstrConfig:          \"\",\n\t\t\texpectedTestResult: \"'BASIC_AUTH' is not present\",\n\t\t\tstrEnv:             \"\",\n\t\t},\n\t\t{\n\t\t\tcheck:              controls.Groups[0].Checks[31],\n\t\t\tstr:                \"2:45 ../kubernetes/kube-apiserver --option1=20,30,40\",\n\t\t\tstrConfig:          \"\",\n\t\t\texpectedTestResult: \"'INSECURE_PORT' is equal to '0'\",\n\t\t\tstrEnv:             \"INSECURE_PORT=0\",\n\t\t},\n\t\t{\n\t\t\tcheck:              controls.Groups[0].Checks[32],\n\t\t\tstr:                \"2:45 ../kubernetes/kube-apiserver --option1=20,30,40\",\n\t\t\tstrConfig:          \"\",\n\t\t\texpectedTestResult: \"'AUDIT_LOG_MAXAGE' is greater or equal to 30\",\n\t\t\tstrEnv:             \"AUDIT_LOG_MAXAGE=40\",\n\t\t},\n\t\t{\n\t\t\tcheck:              controls.Groups[0].Checks[33],\n\t\t\tstr:                \"2:45 ../kubernetes/kube-apiserver --option1=20,30,40\",\n\t\t\tstrConfig:          \"\",\n\t\t\texpectedTestResult: \"'MAX_BACKLOG' is lower than 30\",\n\t\t\tstrEnv:             \"MAX_BACKLOG=20\",\n\t\t},\n\t}\n\n\tfor _, c := range cases {\n\t\tt.Run(c.check.Text, func(t *testing.T) {\n\t\t\tc.check.AuditOutput = c.str\n\t\t\tc.check.AuditConfigOutput = c.strConfig\n\t\t\tc.check.AuditEnvOutput = c.strEnv\n\t\t\tres, err := c.check.execute()\n\t\t\tif err != nil {\n\t\t\t\tt.Error(err.Error())\n\t\t\t}\n\t\t\tif !res.testResult {\n\t\t\t\tt.Errorf(\"Test ID %v - expected:%v, got:%v\", c.check.ID, true, res)\n\t\t\t}\n\t\t\tif res.ExpectedResult != c.expectedTestResult {\n\t\t\t\tt.Errorf(\"Test ID %v - \\nexpected:%v, \\ngot:     %v\", c.check.ID, c.expectedTestResult, res.ExpectedResult)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestTestExecuteExceptions(t *testing.T) {\n\tcases := []struct {\n\t\t*Check\n\t\tstr string\n\t}{\n\t\t{\n\t\t\tcontrols.Groups[0].Checks[23],\n\t\t\t\"this is not valid json {} at all\",\n\t\t},\n\t\t{\n\t\t\tcontrols.Groups[0].Checks[24],\n\t\t\t\"{\\\"key\\\": \\\"value\\\"}\",\n\t\t},\n\t\t{\n\t\t\tcontrols.Groups[0].Checks[25],\n\t\t\t\"broken } yaml\\nenabled: true\",\n\t\t},\n\t\t{\n\t\t\tcontrols.Groups[0].Checks[26],\n\t\t\t\"currentMasterVersion: 1.11\",\n\t\t},\n\t\t{\n\t\t\tcontrols.Groups[0].Checks[26],\n\t\t\t\"currentMasterVersion: \",\n\t\t},\n\t}\n\n\tfor _, c := range cases {\n\t\tt.Run(c.Text, func(t *testing.T) {\n\t\t\tc.Check.AuditConfigOutput = c.str\n\t\t\tres, err := c.Check.execute()\n\t\t\tif err != nil {\n\t\t\t\tt.Error(err.Error())\n\t\t\t}\n\t\t\tif res.testResult {\n\t\t\t\tt.Errorf(\"expected:%v, got:%v\", false, res)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestTestUnmarshal(t *testing.T) {\n\ttype kubeletConfig struct {\n\t\tKind       string\n\t\tApiVersion string\n\t\tAddress    string\n\t}\n\tcases := []struct {\n\t\tcontent        string\n\t\tjsonInterface  interface{}\n\t\texpectedToFail bool\n\t}{\n\t\t{\n\t\t\t`{\n\t\t\t\"kind\": \"KubeletConfiguration\",\n\t\t\t\"apiVersion\": \"kubelet.config.k8s.io/v1beta1\",\n\t\t\t\"address\": \"0.0.0.0\"\n\t\t\t}\n\t\t\t`,\n\t\t\tkubeletConfig{},\n\t\t\tfalse,\n\t\t},\n\t\t{\n\t\t\t`\nkind: KubeletConfiguration\naddress: 0.0.0.0\napiVersion: kubelet.config.k8s.io/v1beta1\nauthentication:\n  anonymous:\n    enabled: false\n  webhook:\n    cacheTTL: 2m0s\n  enabled: true\n  x509:\n    clientCAFile: /etc/kubernetes/pki/ca.crt\ntlsCipherSuites:\n  - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256\n  - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256\n`,\n\t\t\tkubeletConfig{},\n\t\t\tfalse,\n\t\t},\n\t\t{\n\t\t\t`\nkind: ddress: 0.0.0.0\napiVersion: kubelet.config.k8s.io/v1beta\n`,\n\t\t\tkubeletConfig{},\n\t\t\ttrue,\n\t\t},\n\t}\n\n\tfor id, c := range cases {\n\t\tt.Run(fmt.Sprintf(\"%d\", id), func(t *testing.T) {\n\t\t\terr := unmarshal(c.content, &c.jsonInterface)\n\t\t\tif err != nil {\n\t\t\t\tif !c.expectedToFail {\n\t\t\t\t\tt.Errorf(\"should pass, got error:%v\", err)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif c.expectedToFail {\n\t\t\t\t\tt.Errorf(\"should fail, but passed\")\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestExecuteJSONPath(t *testing.T) {\n\ttype kubeletConfig struct {\n\t\tKind       string\n\t\tApiVersion string\n\t\tAddress    string\n\t}\n\tcases := []struct {\n\t\tname           string\n\t\tjsonPath       string\n\t\tjsonInterface  kubeletConfig\n\t\texpectedResult string\n\t\texpectedToFail bool\n\t}{\n\t\t{\n\t\t\t\"JSONPath parse works, results don't match\",\n\t\t\t\"{.resourcesproviders.aescbc}\",\n\t\t\tkubeletConfig{\n\t\t\t\tKind:       \"KubeletConfiguration\",\n\t\t\t\tApiVersion: \"kubelet.config.k8s.io/v1beta1\",\n\t\t\t\tAddress:    \"127.0.0.0\",\n\t\t\t},\n\t\t\t\"blah\",\n\t\t\ttrue,\n\t\t},\n\t\t{\n\t\t\t\"JSONPath parse works, results match\",\n\t\t\t\"{.Kind}\",\n\t\t\tkubeletConfig{\n\t\t\t\tKind:       \"KubeletConfiguration\",\n\t\t\t\tApiVersion: \"kubelet.config.k8s.io/v1beta1\",\n\t\t\t\tAddress:    \"127.0.0.0\",\n\t\t\t},\n\t\t\t\"KubeletConfiguration\",\n\t\t\tfalse,\n\t\t},\n\t\t{\n\t\t\t\"JSONPath parse fails\",\n\t\t\t\"{.ApiVersion\",\n\t\t\tkubeletConfig{\n\t\t\t\tKind:       \"KubeletConfiguration\",\n\t\t\t\tApiVersion: \"kubelet.config.k8s.io/v1beta1\",\n\t\t\t\tAddress:    \"127.0.0.0\",\n\t\t\t},\n\t\t\t\"\",\n\t\t\ttrue,\n\t\t},\n\t}\n\tfor _, c := range cases {\n\t\tt.Run(c.name, func(t *testing.T) {\n\t\t\tresult, err := executeJSONPath(c.jsonPath, c.jsonInterface)\n\t\t\tif err != nil && !c.expectedToFail {\n\t\t\t\tt.Fatalf(\"jsonPath:%q, expectedResult:%q got:%v\", c.jsonPath, c.expectedResult, err)\n\t\t\t}\n\t\t\tif c.expectedResult != result && !c.expectedToFail {\n\t\t\t\tt.Errorf(\"jsonPath:%q, expectedResult:%q got:%q\", c.jsonPath, c.expectedResult, result)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestAllElementsValid(t *testing.T) {\n\tcases := []struct {\n\t\tsource []string\n\t\ttarget []string\n\t\tvalid  bool\n\t}{\n\t\t{\n\t\t\tsource: []string{},\n\t\t\ttarget: []string{},\n\t\t\tvalid:  true,\n\t\t},\n\t\t{\n\t\t\tsource: []string{\"blah\"},\n\t\t\ttarget: []string{},\n\t\t\tvalid:  false,\n\t\t},\n\t\t{\n\t\t\tsource: []string{},\n\t\t\ttarget: []string{\n\t\t\t\t\"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256\", \"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256\",\n\t\t\t\t\"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305\", \"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384\",\n\t\t\t\t\"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305\", \"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384\",\n\t\t\t\t\"TLS_RSA_WITH_AES_256_GCM_SHA384\", \"TLS_RSA_WITH_AES_128_GCM_SHA256\",\n\t\t\t},\n\t\t\tvalid: false,\n\t\t},\n\t\t{\n\t\t\tsource: []string{\"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256\", \"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256\"},\n\t\t\ttarget: []string{\n\t\t\t\t\"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256\", \"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256\",\n\t\t\t\t\"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305\", \"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384\",\n\t\t\t\t\"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305\", \"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384\",\n\t\t\t\t\"TLS_RSA_WITH_AES_256_GCM_SHA384\", \"TLS_RSA_WITH_AES_128_GCM_SHA256\",\n\t\t\t},\n\t\t\tvalid: true,\n\t\t},\n\t\t{\n\t\t\tsource: []string{\"blah\"},\n\t\t\ttarget: []string{\n\t\t\t\t\"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256\", \"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256\",\n\t\t\t\t\"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305\", \"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384\",\n\t\t\t\t\"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305\", \"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384\",\n\t\t\t\t\"TLS_RSA_WITH_AES_256_GCM_SHA384\", \"TLS_RSA_WITH_AES_128_GCM_SHA256\",\n\t\t\t},\n\t\t\tvalid: false,\n\t\t},\n\t\t{\n\t\t\tsource: []string{\"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256\", \"blah\"},\n\t\t\ttarget: []string{\n\t\t\t\t\"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256\", \"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256\",\n\t\t\t\t\"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305\", \"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384\",\n\t\t\t\t\"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305\", \"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384\",\n\t\t\t\t\"TLS_RSA_WITH_AES_256_GCM_SHA384\", \"TLS_RSA_WITH_AES_128_GCM_SHA256\",\n\t\t\t},\n\t\t\tvalid: false,\n\t\t},\n\t}\n\tfor id, c := range cases {\n\t\tt.Run(fmt.Sprintf(\"%d\", id), func(t *testing.T) {\n\t\t\tif !allElementsValid(c.source, c.target) && c.valid {\n\t\t\t\tt.Errorf(\"Not All Elements in %q are found in %q\", c.source, c.target)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestSplitAndRemoveLastSeparator(t *testing.T) {\n\tcases := []struct {\n\t\tsource     string\n\t\tvalid      bool\n\t\telementCnt int\n\t}{\n\t\t{\n\t\t\tsource:     \"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\",\n\t\t\tvalid:      true,\n\t\t\telementCnt: 8,\n\t\t},\n\t\t{\n\t\t\tsource:     \"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,\",\n\t\t\tvalid:      true,\n\t\t\telementCnt: 2,\n\t\t},\n\t\t{\n\t\t\tsource:     \"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,\",\n\t\t\tvalid:      true,\n\t\t\telementCnt: 2,\n\t\t},\n\t\t{\n\t\t\tsource:     \"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, \",\n\t\t\tvalid:      true,\n\t\t\telementCnt: 2,\n\t\t},\n\t\t{\n\t\t\tsource:     \" TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,\",\n\t\t\tvalid:      true,\n\t\t\telementCnt: 2,\n\t\t},\n\t}\n\n\tfor id, c := range cases {\n\t\tt.Run(fmt.Sprintf(\"%d\", id), func(t *testing.T) {\n\t\t\tas := splitAndRemoveLastSeparator(c.source, defaultArraySeparator)\n\t\t\tif len(as) == 0 && c.valid {\n\t\t\t\tt.Errorf(\"Split did not work with %q\", c.source)\n\t\t\t}\n\n\t\t\tif c.elementCnt != len(as) {\n\t\t\t\tt.Errorf(\"Split did not work with %q expected: %d got: %d\", c.source, c.elementCnt, len(as))\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestCompareOp(t *testing.T) {\n\tcases := []struct {\n\t\tlabel                 string\n\t\top                    string\n\t\tflagVal               string // Test output.\n\t\tcompareValue          string // Flag value to compare with.\n\t\texpectedResultPattern string\n\t\tflagName              string // Compared flag name.\n\t\ttestResult            bool\n\t}{\n\t\t// Test Op not matching\n\t\t{label: \"empty - op\", op: \"\", flagVal: \"\", compareValue: \"\", expectedResultPattern: \"\", testResult: false, flagName: \"\"},\n\t\t{label: \"op=blah\", op: \"blah\", flagVal: \"foo\", compareValue: \"bar\", expectedResultPattern: \"\", testResult: false, flagName: \"\"},\n\n\t\t// Test Op \"eq\"\n\t\t{label: \"op=eq, both empty\", op: \"eq\", flagVal: \"\", compareValue: \"\", expectedResultPattern: \"'' is equal to ''\", testResult: true, flagName: \"\"},\n\n\t\t{\n\t\t\tlabel: \"op=eq, true==true\", op: \"eq\", flagVal: \"true\",\n\t\t\tcompareValue:          \"true\",\n\t\t\texpectedResultPattern: \"'parameterTrue' is equal to 'true'\",\n\t\t\ttestResult:            true,\n\t\t\tflagName:              \"parameterTrue\",\n\t\t},\n\n\t\t{\n\t\t\tlabel: \"op=eq, false==false\", op: \"eq\", flagVal: \"false\",\n\t\t\tcompareValue:          \"false\",\n\t\t\texpectedResultPattern: \"'parameterFalse' is equal to 'false'\",\n\t\t\ttestResult:            true,\n\t\t\tflagName:              \"parameterFalse\",\n\t\t},\n\n\t\t{\n\t\t\tlabel: \"op=eq, false==true\", op: \"eq\", flagVal: \"false\",\n\t\t\tcompareValue:          \"true\",\n\t\t\texpectedResultPattern: \"'parameterFalse' is equal to 'true'\",\n\t\t\ttestResult:            false,\n\t\t\tflagName:              \"parameterFalse\",\n\t\t},\n\n\t\t{\n\t\t\tlabel: \"op=eq, strings match\", op: \"eq\", flagVal: \"KubeletConfiguration\",\n\t\t\tcompareValue:          \"KubeletConfiguration\",\n\t\t\texpectedResultPattern: \"'--FlagNameKubeletConf' is equal to 'KubeletConfiguration'\",\n\t\t\ttestResult:            true,\n\t\t\tflagName:              \"--FlagNameKubeletConf\",\n\t\t},\n\n\t\t{\n\t\t\tlabel: \"op=eq, flagVal=empty\", op: \"eq\", flagVal: \"\",\n\t\t\tcompareValue:          \"KubeletConfiguration\",\n\t\t\texpectedResultPattern: \"'--FlagNameKubeletConf' is equal to 'KubeletConfiguration'\",\n\t\t\ttestResult:            false,\n\t\t\tflagName:              \"--FlagNameKubeletConf\",\n\t\t},\n\n\t\t{\n\t\t\tlabel:                 \"op=eq, compareValue=empty\",\n\t\t\top:                    \"eq\",\n\t\t\tflagVal:               \"KubeletConfiguration\",\n\t\t\tcompareValue:          \"\",\n\t\t\texpectedResultPattern: \"'--FlagNameKubeletConf' is equal to ''\",\n\t\t\ttestResult:            false,\n\t\t\tflagName:              \"--FlagNameKubeletConf\",\n\t\t},\n\n\t\t// Test Op \"noteq\"\n\t\t{\n\t\t\tlabel:                 \"op=noteq, both empty\",\n\t\t\top:                    \"noteq\",\n\t\t\tflagVal:               \"\",\n\t\t\tcompareValue:          \"\",\n\t\t\texpectedResultPattern: \"'parameter' is not equal to ''\",\n\t\t\ttestResult:            false,\n\t\t\tflagName:              \"parameter\",\n\t\t},\n\n\t\t{\n\t\t\tlabel:                 \"op=noteq, true!=true\",\n\t\t\top:                    \"noteq\",\n\t\t\tflagVal:               \"true\",\n\t\t\tcompareValue:          \"true\",\n\t\t\texpectedResultPattern: \"'parameterTrue' is not equal to 'true'\",\n\t\t\ttestResult:            false,\n\t\t\tflagName:              \"parameterTrue\",\n\t\t},\n\n\t\t{\n\t\t\tlabel:                 \"op=noteq, false!=false\",\n\t\t\top:                    \"noteq\",\n\t\t\tflagVal:               \"false\",\n\t\t\tcompareValue:          \"false\",\n\t\t\texpectedResultPattern: \"'parameterFalse' is not equal to 'false'\",\n\t\t\ttestResult:            false,\n\t\t\tflagName:              \"parameterFalse\",\n\t\t},\n\n\t\t{\n\t\t\tlabel:                 \"op=noteq, false!=true\",\n\t\t\top:                    \"noteq\",\n\t\t\tflagVal:               \"false\",\n\t\t\tcompareValue:          \"true\",\n\t\t\texpectedResultPattern: \"'parameterFalse' is not equal to 'true'\",\n\t\t\ttestResult:            true,\n\t\t\tflagName:              \"parameterFalse\",\n\t\t},\n\n\t\t{\n\t\t\tlabel:                 \"op=noteq, strings match\",\n\t\t\top:                    \"noteq\",\n\t\t\tflagVal:               \"KubeletConfiguration\",\n\t\t\tcompareValue:          \"KubeletConfiguration\",\n\t\t\texpectedResultPattern: \"'--FlagNameKubeletConf' is not equal to 'KubeletConfiguration'\",\n\t\t\ttestResult:            false,\n\t\t\tflagName:              \"--FlagNameKubeletConf\",\n\t\t},\n\n\t\t{\n\t\t\tlabel:                 \"op=noteq, flagVal=empty\",\n\t\t\top:                    \"noteq\",\n\t\t\tflagVal:               \"\",\n\t\t\tcompareValue:          \"KubeletConfiguration\",\n\t\t\texpectedResultPattern: \"'--FlagNameKubeletConf' is not equal to 'KubeletConfiguration'\",\n\t\t\ttestResult:            true,\n\t\t\tflagName:              \"--FlagNameKubeletConf\",\n\t\t},\n\n\t\t{\n\t\t\tlabel:                 \"op=noteq, compareValue=empty\",\n\t\t\top:                    \"noteq\",\n\t\t\tflagVal:               \"KubeletConfiguration\",\n\t\t\tcompareValue:          \"\",\n\t\t\texpectedResultPattern: \"'--FlagNameKubeletConf' is not equal to ''\",\n\t\t\ttestResult:            true,\n\t\t\tflagName:              \"--FlagNameKubeletConf\",\n\t\t},\n\n\t\t// Test Op \"gt\"\n\t\t{\n\t\t\tlabel:                 \"op=gt, both empty\",\n\t\t\top:                    \"gt\",\n\t\t\tflagVal:               \"\",\n\t\t\tcompareValue:          \"\",\n\t\t\texpectedResultPattern: \"Invalid Number(s) used for comparison: '' ''\",\n\t\t\ttestResult:            false,\n\t\t\tflagName:              \"flagName\",\n\t\t},\n\t\t{\n\t\t\tlabel:        \"op=gt, 0 > 0\",\n\t\t\top:           \"gt\",\n\t\t\tflagVal:      \"0\",\n\t\t\tcompareValue: \"0\", expectedResultPattern: \"'flagName' is greater than 0\",\n\t\t\ttestResult: false,\n\t\t\tflagName:   \"flagName\",\n\t\t},\n\t\t{\n\t\t\tlabel:                 \"op=gt, 4 > 5\",\n\t\t\top:                    \"gt\",\n\t\t\tflagVal:               \"4\",\n\t\t\tcompareValue:          \"5\",\n\t\t\texpectedResultPattern: \"'flagName' is greater than 5\",\n\t\t\ttestResult:            false,\n\t\t\tflagName:              \"flagName\",\n\t\t},\n\t\t{\n\t\t\tlabel:                 \"op=gt, 5 > 4\",\n\t\t\top:                    \"gt\",\n\t\t\tflagVal:               \"5\",\n\t\t\tcompareValue:          \"4\",\n\t\t\texpectedResultPattern: \"'flagName' is greater than 4\",\n\t\t\ttestResult:            true,\n\t\t\tflagName:              \"flagName\",\n\t\t},\n\t\t{\n\t\t\tlabel:                 \"op=gt, 5 > 5\",\n\t\t\top:                    \"gt\",\n\t\t\tflagVal:               \"5\",\n\t\t\tcompareValue:          \"5\",\n\t\t\texpectedResultPattern: \"'flagName' is greater than 5\",\n\t\t\ttestResult:            false,\n\t\t\tflagName:              \"flagName\",\n\t\t},\n\t\t{\n\t\t\tlabel:                 \"op=gt, Pikachu > 5\",\n\t\t\top:                    \"gt\",\n\t\t\tflagVal:               \"Pikachu\",\n\t\t\tcompareValue:          \"5\",\n\t\t\texpectedResultPattern: \"Invalid Number(s) used for comparison: 'Pikachu' '5'\",\n\t\t\ttestResult:            false,\n\t\t\tflagName:              \"flagName\",\n\t\t},\n\t\t{\n\t\t\tlabel:                 \"op=gt, 5 > Bulbasaur\",\n\t\t\top:                    \"gt\",\n\t\t\tflagVal:               \"5\",\n\t\t\tcompareValue:          \"Bulbasaur\",\n\t\t\texpectedResultPattern: \"Invalid Number(s) used for comparison: '5' 'Bulbasaur'\",\n\t\t\ttestResult:            false,\n\t\t\tflagName:              \"flagName\",\n\t\t},\n\t\t// Test Op \"lt\"\n\t\t{\n\t\t\tlabel:                 \"op=lt, both empty\",\n\t\t\top:                    \"lt\",\n\t\t\tflagVal:               \"\",\n\t\t\tcompareValue:          \"\",\n\t\t\texpectedResultPattern: \"Invalid Number(s) used for comparison: '' ''\",\n\t\t\ttestResult:            false,\n\t\t\tflagName:              \"flagName\",\n\t\t},\n\t\t{\n\t\t\tlabel:                 \"op=lt, 0 < 0\",\n\t\t\top:                    \"lt\",\n\t\t\tflagVal:               \"0\",\n\t\t\tcompareValue:          \"0\",\n\t\t\texpectedResultPattern: \"'flagName' is lower than 0\",\n\t\t\ttestResult:            false,\n\t\t\tflagName:              \"flagName\",\n\t\t},\n\t\t{\n\t\t\tlabel:                 \"op=lt, 4 < 5\",\n\t\t\top:                    \"lt\",\n\t\t\tflagVal:               \"4\",\n\t\t\tcompareValue:          \"5\",\n\t\t\texpectedResultPattern: \"'flagName' is lower than 5\",\n\t\t\ttestResult:            true,\n\t\t\tflagName:              \"flagName\",\n\t\t},\n\t\t{\n\t\t\tlabel:                 \"op=lt, 5 < 4\",\n\t\t\top:                    \"lt\",\n\t\t\tflagVal:               \"5\",\n\t\t\tcompareValue:          \"4\",\n\t\t\texpectedResultPattern: \"'flagName' is lower than 4\",\n\t\t\ttestResult:            false,\n\t\t\tflagName:              \"flagName\",\n\t\t},\n\t\t{\n\t\t\tlabel:                 \"op=lt, 5 < 5\",\n\t\t\top:                    \"lt\",\n\t\t\tflagVal:               \"5\",\n\t\t\tcompareValue:          \"5\",\n\t\t\texpectedResultPattern: \"'flagName' is lower than 5\",\n\t\t\ttestResult:            false,\n\t\t\tflagName:              \"flagName\",\n\t\t},\n\t\t{\n\t\t\tlabel:                 \"op=lt, Charmander < 5\",\n\t\t\top:                    \"lt\",\n\t\t\tflagVal:               \"Charmander\",\n\t\t\tcompareValue:          \"5\",\n\t\t\texpectedResultPattern: \"Invalid Number(s) used for comparison: 'Charmander' '5'\",\n\t\t\ttestResult:            false,\n\t\t\tflagName:              \"flagName\",\n\t\t},\n\t\t{\n\t\t\tlabel:                 \"op=lt, 5 < Charmeleon\",\n\t\t\top:                    \"lt\",\n\t\t\tflagVal:               \"5\",\n\t\t\tcompareValue:          \"Charmeleon\",\n\t\t\texpectedResultPattern: \"Invalid Number(s) used for comparison: '5' 'Charmeleon'\",\n\t\t\ttestResult:            false,\n\t\t\tflagName:              \"flagName\",\n\t\t},\n\t\t// Test Op \"gte\"\n\t\t{\n\t\t\tlabel:                 \"op=gte, both empty\",\n\t\t\top:                    \"gte\",\n\t\t\tflagVal:               \"\",\n\t\t\tcompareValue:          \"\",\n\t\t\texpectedResultPattern: \"Invalid Number(s) used for comparison: '' ''\",\n\t\t\ttestResult:            false,\n\t\t\tflagName:              \"flagName\",\n\t\t},\n\t\t{\n\t\t\tlabel:                 \"op=gte, 0 >= 0\",\n\t\t\top:                    \"gte\",\n\t\t\tflagVal:               \"0\",\n\t\t\tcompareValue:          \"0\",\n\t\t\texpectedResultPattern: \"'flagName' is greater or equal to 0\",\n\t\t\ttestResult:            true,\n\t\t\tflagName:              \"flagName\",\n\t\t},\n\t\t{\n\t\t\tlabel:                 \"op=gte, 4 >= 5\",\n\t\t\top:                    \"gte\",\n\t\t\tflagVal:               \"4\",\n\t\t\tcompareValue:          \"5\",\n\t\t\texpectedResultPattern: \"'flagName' is greater or equal to 5\",\n\t\t\ttestResult:            false,\n\t\t\tflagName:              \"flagName\",\n\t\t},\n\t\t{\n\t\t\tlabel:                 \"op=gte, 5 >= 4\",\n\t\t\top:                    \"gte\",\n\t\t\tflagVal:               \"5\",\n\t\t\tcompareValue:          \"4\",\n\t\t\texpectedResultPattern: \"'flagName' is greater or equal to 4\",\n\t\t\ttestResult:            true,\n\t\t\tflagName:              \"flagName\",\n\t\t},\n\t\t{\n\t\t\tlabel:                 \"op=gte, 5 >= 5\",\n\t\t\top:                    \"gte\",\n\t\t\tflagVal:               \"5\",\n\t\t\tcompareValue:          \"5\",\n\t\t\texpectedResultPattern: \"'flagName' is greater or equal to 5\",\n\t\t\ttestResult:            true,\n\t\t\tflagName:              \"flagName\",\n\t\t},\n\t\t{\n\t\t\tlabel:                 \"op=gte, Ekans >= 5\",\n\t\t\top:                    \"gte\",\n\t\t\tflagVal:               \"Ekans\",\n\t\t\tcompareValue:          \"5\",\n\t\t\texpectedResultPattern: \"Invalid Number(s) used for comparison: 'Ekans' '5'\",\n\t\t\ttestResult:            false,\n\t\t\tflagName:              \"flagName\",\n\t\t},\n\t\t{\n\t\t\tlabel:                 \"op=gte, 4 >= Zubat\",\n\t\t\top:                    \"gte\",\n\t\t\tflagVal:               \"4\",\n\t\t\tcompareValue:          \"Zubat\",\n\t\t\texpectedResultPattern: \"Invalid Number(s) used for comparison: '4' 'Zubat'\",\n\t\t\ttestResult:            false,\n\t\t\tflagName:              \"flagName\",\n\t\t},\n\t\t// Test Op \"lte\"\n\t\t{\n\t\t\tlabel:                 \"op=lte, both empty\",\n\t\t\top:                    \"lte\",\n\t\t\tflagVal:               \"\",\n\t\t\tcompareValue:          \"\",\n\t\t\texpectedResultPattern: \"Invalid Number(s) used for comparison: '' ''\",\n\t\t\ttestResult:            false,\n\t\t\tflagName:              \"flagName\",\n\t\t},\n\t\t{\n\t\t\tlabel:                 \"op=lte, 0 <= 0\",\n\t\t\top:                    \"lte\",\n\t\t\tflagVal:               \"0\",\n\t\t\tcompareValue:          \"0\",\n\t\t\texpectedResultPattern: \"'flagName' is lower or equal to 0\",\n\t\t\ttestResult:            true,\n\t\t\tflagName:              \"flagName\",\n\t\t},\n\t\t{\n\t\t\tlabel:                 \"op=lte, 4 <= 5\",\n\t\t\top:                    \"lte\",\n\t\t\tflagVal:               \"4\",\n\t\t\tcompareValue:          \"5\",\n\t\t\texpectedResultPattern: \"'flagName' is lower or equal to 5\",\n\t\t\ttestResult:            true,\n\t\t\tflagName:              \"flagName\",\n\t\t},\n\t\t{\n\t\t\tlabel:                 \"op=lte, 5 <= 4\",\n\t\t\top:                    \"lte\",\n\t\t\tflagVal:               \"5\",\n\t\t\tcompareValue:          \"4\",\n\t\t\texpectedResultPattern: \"'flagName' is lower or equal to 4\",\n\t\t\ttestResult:            false,\n\t\t\tflagName:              \"flagName\",\n\t\t},\n\t\t{\n\t\t\tlabel:                 \"op=lte, 5 <= 5\",\n\t\t\top:                    \"lte\",\n\t\t\tflagVal:               \"5\",\n\t\t\tcompareValue:          \"5\",\n\t\t\texpectedResultPattern: \"'flagName' is lower or equal to 5\",\n\t\t\ttestResult:            true,\n\t\t\tflagName:              \"flagName\",\n\t\t},\n\t\t{\n\t\t\tlabel:                 \"op=lte, Venomoth <= 4\",\n\t\t\top:                    \"lte\",\n\t\t\tflagVal:               \"Venomoth\",\n\t\t\tcompareValue:          \"4\",\n\t\t\texpectedResultPattern: \"Invalid Number(s) used for comparison: 'Venomoth' '4'\",\n\t\t\ttestResult:            false,\n\t\t\tflagName:              \"flagName\",\n\t\t},\n\t\t{\n\t\t\tlabel:                 \"op=lte, 5 <= Meowth\",\n\t\t\top:                    \"lte\",\n\t\t\tflagVal:               \"5\",\n\t\t\tcompareValue:          \"Meowth\",\n\t\t\texpectedResultPattern: \"Invalid Number(s) used for comparison: '5' 'Meowth'\",\n\t\t\ttestResult:            false,\n\t\t\tflagName:              \"flagName\",\n\t\t},\n\n\t\t// Test Op \"has\"\n\t\t{\n\t\t\tlabel:                 \"op=has, both empty\",\n\t\t\top:                    \"has\",\n\t\t\tflagVal:               \"\",\n\t\t\tcompareValue:          \"\",\n\t\t\texpectedResultPattern: \"'flagName' has ''\",\n\t\t\ttestResult:            true,\n\t\t\tflagName:              \"flagName\",\n\t\t},\n\t\t{\n\t\t\tlabel:                 \"op=has, flagVal=empty\",\n\t\t\top:                    \"has\",\n\t\t\tflagVal:               \"\",\n\t\t\tcompareValue:          \"blah\",\n\t\t\texpectedResultPattern: \"'flagName' has 'blah'\",\n\t\t\ttestResult:            false,\n\t\t\tflagName:              \"flagName\",\n\t\t},\n\t\t{\n\t\t\tlabel:                 \"op=has, compareValue=empty\",\n\t\t\top:                    \"has\",\n\t\t\tflagVal:               \"blah\",\n\t\t\tcompareValue:          \"\",\n\t\t\texpectedResultPattern: \"'flagName-blah' has ''\",\n\t\t\ttestResult:            true,\n\t\t\tflagName:              \"flagName-blah\",\n\t\t},\n\t\t{\n\t\t\tlabel:                 \"op=has, 'blah' has 'la'\",\n\t\t\top:                    \"has\",\n\t\t\tflagVal:               \"blah\",\n\t\t\tcompareValue:          \"la\",\n\t\t\texpectedResultPattern: \"'flagName-blah' has 'la'\",\n\t\t\ttestResult:            true,\n\t\t\tflagName:              \"flagName-blah\",\n\t\t},\n\t\t{\n\t\t\tlabel:                 \"op=has, 'blah' has 'LA'\",\n\t\t\top:                    \"has\",\n\t\t\tflagVal:               \"blah\",\n\t\t\tcompareValue:          \"LA\",\n\t\t\texpectedResultPattern: \"'flagName-blah' has 'LA'\",\n\t\t\ttestResult:            false,\n\t\t\tflagName:              \"flagName-blah\",\n\t\t},\n\t\t{\n\t\t\tlabel:                 \"op=has, 'blah' has 'lo'\",\n\t\t\top:                    \"has\",\n\t\t\tflagVal:               \"blah\",\n\t\t\tcompareValue:          \"lo\",\n\t\t\texpectedResultPattern: \"'flagName-blah' has 'lo'\",\n\t\t\ttestResult:            false,\n\t\t\tflagName:              \"flagName-blah\",\n\t\t},\n\n\t\t// Test Op \"nothave\"\n\t\t{\n\t\t\tlabel:                 \"op=nothave, both empty\",\n\t\t\top:                    \"nothave\",\n\t\t\tflagVal:               \"\",\n\t\t\tcompareValue:          \"\",\n\t\t\texpectedResultPattern: \"'flagName' does not have ''\",\n\t\t\ttestResult:            false,\n\t\t\tflagName:              \"flagName\",\n\t\t},\n\t\t{\n\t\t\tlabel:                 \"op=nothave, flagVal=empty\",\n\t\t\top:                    \"nothave\",\n\t\t\tflagVal:               \"\",\n\t\t\tcompareValue:          \"blah\",\n\t\t\texpectedResultPattern: \"'flagName' does not have 'blah'\",\n\t\t\ttestResult:            true,\n\t\t\tflagName:              \"flagName\",\n\t\t},\n\t\t{\n\t\t\tlabel:                 \"op=nothave, compareValue=empty\",\n\t\t\top:                    \"nothave\",\n\t\t\tflagVal:               \"blah\",\n\t\t\tcompareValue:          \"\",\n\t\t\texpectedResultPattern: \"'flagName-blah' does not have ''\",\n\t\t\ttestResult:            false,\n\t\t\tflagName:              \"flagName-blah\",\n\t\t},\n\t\t{\n\t\t\tlabel:                 \"op=nothave, 'blah' not have 'la'\",\n\t\t\top:                    \"nothave\",\n\t\t\tflagVal:               \"blah\",\n\t\t\tcompareValue:          \"la\",\n\t\t\texpectedResultPattern: \"'flagName-blah' does not have 'la'\",\n\t\t\ttestResult:            false,\n\t\t\tflagName:              \"flagName-blah\",\n\t\t},\n\t\t{\n\t\t\tlabel:                 \"op=nothave, 'blah' not have 'LA'\",\n\t\t\top:                    \"nothave\",\n\t\t\tflagVal:               \"blah\",\n\t\t\tcompareValue:          \"LA\",\n\t\t\texpectedResultPattern: \"'flagName-blah' does not have 'LA'\",\n\t\t\ttestResult:            true,\n\t\t\tflagName:              \"flagName-blah\",\n\t\t},\n\t\t{\n\t\t\tlabel:                 \"op=nothave, 'blah' not have 'lo'\",\n\t\t\top:                    \"nothave\",\n\t\t\tflagVal:               \"blah\",\n\t\t\tcompareValue:          \"lo\",\n\t\t\texpectedResultPattern: \"'flagName-blah' does not have 'lo'\",\n\t\t\ttestResult:            true,\n\t\t\tflagName:              \"flagName-blah\",\n\t\t},\n\n\t\t// Test Op \"regex\"\n\t\t{\n\t\t\tlabel:                 \"op=regex, both empty\",\n\t\t\top:                    \"regex\",\n\t\t\tflagVal:               \"\",\n\t\t\tcompareValue:          \"\",\n\t\t\texpectedResultPattern: \"'flagName' matched by regex expression ''\",\n\t\t\ttestResult:            true,\n\t\t\tflagName:              \"flagName\",\n\t\t},\n\t\t{\n\t\t\tlabel:                 \"op=regex, flagVal=empty\",\n\t\t\top:                    \"regex\",\n\t\t\tflagVal:               \"\",\n\t\t\tcompareValue:          \"blah\",\n\t\t\texpectedResultPattern: \"'flagName' matched by regex expression 'blah'\",\n\t\t\ttestResult:            false,\n\t\t\tflagName:              \"flagName\",\n\t\t},\n\n\t\t// Test Op \"valid_elements\"\n\t\t{\n\t\t\tlabel:                 \"op=valid_elements, valid_elements both empty\",\n\t\t\top:                    \"valid_elements\",\n\t\t\tflagVal:               \"\",\n\t\t\tcompareValue:          \"\",\n\t\t\texpectedResultPattern: \"'flagWithMultipleElements' contains valid elements from ''\",\n\t\t\ttestResult:            true,\n\t\t\tflagName:              \"flagWithMultipleElements\",\n\t\t},\n\n\t\t{\n\t\t\tlabel:                 \"op=valid_elements, valid_elements flagVal empty\",\n\t\t\top:                    \"valid_elements\",\n\t\t\tflagVal:               \"\",\n\t\t\tcompareValue:          \"a,b\",\n\t\t\texpectedResultPattern: \"'flagWithMultipleElements' contains valid elements from 'a,b'\",\n\t\t\ttestResult:            false,\n\t\t\tflagName:              \"flagWithMultipleElements\",\n\t\t},\n\n\t\t{\n\t\t\tlabel:                 \"op=valid_elements, valid_elements compareValue empty\",\n\t\t\top:                    \"valid_elements\",\n\t\t\tflagVal:               \"a,b\",\n\t\t\tcompareValue:          \"\",\n\t\t\texpectedResultPattern: \"'flagWithMultipleElements' contains valid elements from ''\",\n\t\t\ttestResult:            false,\n\t\t\tflagName:              \"flagWithMultipleElements\",\n\t\t},\n\t\t{\n\t\t\tlabel:                 \"op=valid_elements, valid_elements two list equals\",\n\t\t\top:                    \"valid_elements\",\n\t\t\tflagVal:               \"a,b,c\",\n\t\t\tcompareValue:          \"a,b,c\",\n\t\t\texpectedResultPattern: \"'flagWithMultipleElements' contains valid elements from 'a,b,c'\",\n\t\t\ttestResult:            true,\n\t\t\tflagName:              \"flagWithMultipleElements\",\n\t\t},\n\t\t{\n\t\t\tlabel:                 \"op=valid_elements, valid_elements partial flagVal valid\",\n\t\t\top:                    \"valid_elements\",\n\t\t\tflagVal:               \"a,c\",\n\t\t\tcompareValue:          \"a,b,c\",\n\t\t\texpectedResultPattern: \"'flagWithMultipleElements' contains valid elements from 'a,b,c'\",\n\t\t\ttestResult:            true,\n\t\t\tflagName:              \"flagWithMultipleElements\",\n\t\t},\n\t\t{\n\t\t\tlabel:                 \"op=valid_elements, valid_elements partial compareValue valid\",\n\t\t\top:                    \"valid_elements\",\n\t\t\tflagVal:               \"a,b,c\",\n\t\t\tcompareValue:          \"a,c\",\n\t\t\texpectedResultPattern: \"'flagWithMultipleElements' contains valid elements from 'a,c'\",\n\t\t\ttestResult:            false,\n\t\t\tflagName:              \"flagWithMultipleElements\",\n\t\t},\n\n\t\t// Test Op \"bitmask\"\n\t\t{\n\t\t\tlabel:                 \"op=bitmask, 644 AND 640\",\n\t\t\top:                    \"bitmask\",\n\t\t\tflagVal:               \"640\",\n\t\t\tcompareValue:          \"644\",\n\t\t\texpectedResultPattern: \"etc/fileExamplePermission640 has permissions 640, expected 644 or more restrictive\",\n\t\t\ttestResult:            true,\n\t\t\tflagName:              \"etc/fileExamplePermission640\",\n\t\t},\n\t\t{\n\t\t\tlabel:                 \"op=bitmask, 644 AND 777\",\n\t\t\top:                    \"bitmask\",\n\t\t\tflagVal:               \"777\",\n\t\t\tcompareValue:          \"644\",\n\t\t\texpectedResultPattern: \"etc/fileExamplePermission777 has permissions 777, expected 644 or more restrictive\",\n\t\t\ttestResult:            false,\n\t\t\tflagName:              \"etc/fileExamplePermission777\",\n\t\t},\n\t\t{\n\t\t\tlabel:                 \"op=bitmask, 644 AND 444\",\n\t\t\top:                    \"bitmask\",\n\t\t\tflagVal:               \"444\",\n\t\t\tcompareValue:          \"644\",\n\t\t\texpectedResultPattern: \"etc/fileExamplePermission444 has permissions 444, expected 644 or more restrictive\",\n\t\t\ttestResult:            true,\n\t\t\tflagName:              \"etc/fileExamplePermission444\",\n\t\t},\n\t\t{\n\t\t\tlabel:                 \"op=bitmask, 644 AND 211\",\n\t\t\top:                    \"bitmask\",\n\t\t\tflagVal:               \"211\",\n\t\t\tcompareValue:          \"644\",\n\t\t\texpectedResultPattern: \"etc/fileExamplePermission211 has permissions 211, expected 644 or more restrictive\",\n\t\t\ttestResult:            false,\n\t\t\tflagName:              \"etc/fileExamplePermission211\",\n\t\t},\n\t\t{\n\t\t\tlabel:                 \"op=bitmask, Harry AND 211\",\n\t\t\top:                    \"bitmask\",\n\t\t\tflagVal:               \"Harry\",\n\t\t\tcompareValue:          \"644\",\n\t\t\texpectedResultPattern: \"Not numeric value - flag: Harry\",\n\t\t\ttestResult:            false,\n\t\t\tflagName:              \"etc/fileExample\",\n\t\t},\n\t\t{\n\t\t\tlabel:                 \"op=bitmask, 644 AND Potter\",\n\t\t\top:                    \"bitmask\",\n\t\t\tflagVal:               \"211\",\n\t\t\tcompareValue:          \"Potter\",\n\t\t\texpectedResultPattern: \"Not numeric value - flag: Potter\",\n\t\t\ttestResult:            false,\n\t\t\tflagName:              \"etc/fileExample\",\n\t\t},\n\t}\n\n\tfor _, c := range cases {\n\t\tt.Run(c.label, func(t *testing.T) {\n\t\t\texpectedResultPattern, testResult := compareOp(c.op, c.flagVal, c.compareValue, c.flagName)\n\t\t\tif expectedResultPattern != c.expectedResultPattern {\n\t\t\t\tt.Errorf(\"'expectedResultPattern' did not match - op: %q expected:%q  got:%q\", c.op, c.expectedResultPattern, expectedResultPattern)\n\t\t\t}\n\n\t\t\tif testResult != c.testResult {\n\t\t\t\tt.Errorf(\"'testResult' did not match - lop: %q expected:%t  got:%t\", c.op, c.testResult, testResult)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestToNumeric(t *testing.T) {\n\tcases := []struct {\n\t\tfirstValue     string\n\t\tsecondValue    string\n\t\texpectedToFail bool\n\t}{\n\t\t{\n\t\t\tfirstValue:     \"a\",\n\t\t\tsecondValue:    \"b\",\n\t\t\texpectedToFail: true,\n\t\t},\n\t\t{\n\t\t\tfirstValue:     \"5\",\n\t\t\tsecondValue:    \"b\",\n\t\t\texpectedToFail: true,\n\t\t},\n\t\t{\n\t\t\tfirstValue:     \"5\",\n\t\t\tsecondValue:    \"6\",\n\t\t\texpectedToFail: false,\n\t\t},\n\t}\n\n\tfor id, c := range cases {\n\t\tt.Run(fmt.Sprintf(\"%d\", id), func(t *testing.T) {\n\t\t\tf, s, err := toNumeric(c.firstValue, c.secondValue)\n\t\t\tif c.expectedToFail && err == nil {\n\t\t\t\tt.Errorf(\"Expected error while converting %s and %s\", c.firstValue, c.secondValue)\n\t\t\t}\n\n\t\t\tif !c.expectedToFail && (f != 5 || s != 6) {\n\t\t\t\tt.Errorf(\"Expected to return %d,%d - got %d,%d\", 5, 6, f, s)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestExecuteJSONPathOnEncryptionConfig(t *testing.T) {\n\ttype Resources struct {\n\t\tResources []string                 `json:\"resources\"`\n\t\tProviders []map[string]interface{} `json:\"providers\"`\n\t}\n\n\ttype EncryptionConfig struct {\n\t\tKind       string      `json:\"kind\"`\n\t\tApiVersion string      `json:\"apiVersion\"`\n\t\tResources  []Resources `json:\"resources\"`\n\t}\n\n\ttype Key struct {\n\t\tSecret string `json:\"secret\"`\n\t\tName   string `json:\"name\"`\n\t}\n\n\ttype Aescbc struct {\n\t\tKeys []Key `json:\"keys\"`\n\t}\n\n\ttype SecretBox struct {\n\t\tKeys []Key `json:\"keys\"`\n\t}\n\n\ttype Aesgcm struct {\n\t\tKeys []Key `json:\"keys\"`\n\t}\n\n\t// identity disable encryption when set as the first parameter\n\ttype Identity struct{}\n\n\tcases := []struct {\n\t\tname           string\n\t\tjsonPath       string\n\t\tjsonInterface  EncryptionConfig\n\t\texpectedResult string\n\t\texpectedToFail bool\n\t}{\n\t\t{\n\t\t\t\"JSONPath parse works, results match\",\n\t\t\t\"{.resources[*].providers[*].aescbc.keys[*].secret}\",\n\t\t\tEncryptionConfig{\n\t\t\t\tKind:       \"EncryptionConfig\",\n\t\t\t\tApiVersion: \"v1\",\n\t\t\t\tResources: []Resources{{Resources: []string{\"secrets\"}, Providers: []map[string]interface{}{\n\t\t\t\t\t{\"aescbc\": Aescbc{Keys: []Key{{Secret: \"secret1\", Name: \"name1\"}}}},\n\t\t\t\t}}},\n\t\t\t},\n\t\t\t\"secret1\",\n\t\t\tfalse,\n\t\t},\n\t\t{\n\t\t\t\"JSONPath parse works, results match\",\n\t\t\t\"{.resources[*].providers[*].aescbc.keys[*].name}\",\n\t\t\tEncryptionConfig{\n\t\t\t\tKind:       \"EncryptionConfig\",\n\t\t\t\tApiVersion: \"v1\",\n\t\t\t\tResources: []Resources{{Resources: []string{\"secrets\"}, Providers: []map[string]interface{}{\n\t\t\t\t\t{\"aescbc\": Aescbc{Keys: []Key{{Secret: \"secret1\", Name: \"name1\"}}}},\n\t\t\t\t}}},\n\t\t\t},\n\t\t\t\"name1\",\n\t\t\tfalse,\n\t\t},\n\t\t{\n\t\t\t\"JSONPath parse works, results don't match\",\n\t\t\t\"{.resources[*].providers[*].aescbc.keys[*].secret}\",\n\t\t\tEncryptionConfig{\n\t\t\t\tKind:       \"EncryptionConfig\",\n\t\t\t\tApiVersion: \"v1\",\n\t\t\t\tResources: []Resources{{Resources: []string{\"secrets\"}, Providers: []map[string]interface{}{\n\t\t\t\t\t{\"aesgcm\": Aesgcm{Keys: []Key{{Secret: \"secret1\", Name: \"name1\"}}}},\n\t\t\t\t}}},\n\t\t\t},\n\t\t\t\"secret1\",\n\t\t\ttrue,\n\t\t},\n\t\t{\n\t\t\t\"JSONPath parse works, results match\",\n\t\t\t\"{.resources[*].providers[*].aesgcm.keys[*].secret}\",\n\t\t\tEncryptionConfig{\n\t\t\t\tKind:       \"EncryptionConfig\",\n\t\t\t\tApiVersion: \"v1\",\n\t\t\t\tResources: []Resources{{Resources: []string{\"secrets\"}, Providers: []map[string]interface{}{\n\t\t\t\t\t{\"aesgcm\": Aesgcm{Keys: []Key{{Secret: \"secret1\", Name: \"name1\"}}}},\n\t\t\t\t}}},\n\t\t\t},\n\t\t\t\"secret1\",\n\t\t\tfalse,\n\t\t},\n\t\t{\n\t\t\t\"JSONPath parse works, results match\",\n\t\t\t\"{.resources[*].providers[*].secretbox.keys[*].secret}\",\n\t\t\tEncryptionConfig{\n\t\t\t\tKind:       \"EncryptionConfig\",\n\t\t\t\tApiVersion: \"v1\",\n\t\t\t\tResources: []Resources{{Resources: []string{\"secrets\"}, Providers: []map[string]interface{}{\n\t\t\t\t\t{\"secretbox\": SecretBox{Keys: []Key{{Secret: \"secret1\", Name: \"name1\"}}}},\n\t\t\t\t}}},\n\t\t\t},\n\t\t\t\"secret1\",\n\t\t\tfalse,\n\t\t},\n\t\t{\n\t\t\t\"JSONPath parse works, results match\",\n\t\t\t\"{.resources[*].providers[*].aescbc.keys[*].secret}\",\n\t\t\tEncryptionConfig{\n\t\t\t\tKind:       \"EncryptionConfig\",\n\t\t\t\tApiVersion: \"v1\",\n\t\t\t\tResources: []Resources{{Resources: []string{\"secrets\"}, Providers: []map[string]interface{}{\n\t\t\t\t\t{\"aescbc\": Aescbc{Keys: []Key{{Secret: \"secret1\", Name: \"name1\"}, {Secret: \"secret2\", Name: \"name2\"}}}},\n\t\t\t\t}}},\n\t\t\t},\n\t\t\t\"secret1 secret2\",\n\t\t\tfalse,\n\t\t},\n\t}\n\tfor _, c := range cases {\n\t\tt.Run(c.name, func(t *testing.T) {\n\t\t\tresult, err := executeJSONPath(c.jsonPath, c.jsonInterface)\n\t\t\tif err != nil && !c.expectedToFail {\n\t\t\t\tt.Fatalf(\"jsonPath:%q, expectedResult:%q got:%v\", c.jsonPath, c.expectedResult, err)\n\t\t\t}\n\t\t\tif c.expectedResult != result && !c.expectedToFail {\n\t\t\t\tt.Errorf(\"jsonPath:%q, expectedResult:%q got:%q\", c.jsonPath, c.expectedResult, result)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "cmd/common.go",
    "content": "// Copyright © 2017 Aqua Security Software Ltd. <info@aquasec.com>\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage cmd\n\nimport (\n\t\"bufio\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"sort\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/aquasecurity/kube-bench/check\"\n\t\"github.com/golang/glog\"\n\t\"github.com/spf13/viper\"\n)\n\n// NewRunFilter constructs a Predicate based on FilterOpts which determines whether tested Checks should be run or not.\nfunc NewRunFilter(opts FilterOpts) (check.Predicate, error) {\n\tif opts.CheckList != \"\" && opts.GroupList != \"\" {\n\t\treturn nil, fmt.Errorf(\"group option and check option can't be used together\")\n\t}\n\n\tvar groupIDs map[string]bool\n\tif opts.GroupList != \"\" {\n\t\tgroupIDs = cleanIDs(opts.GroupList)\n\t}\n\n\tvar checkIDs map[string]bool\n\tif opts.CheckList != \"\" {\n\t\tcheckIDs = cleanIDs(opts.CheckList)\n\t}\n\n\treturn func(g *check.Group, c *check.Check) bool {\n\t\ttest := true\n\t\tif len(groupIDs) > 0 {\n\t\t\t_, ok := groupIDs[g.ID]\n\t\t\ttest = test && ok\n\t\t}\n\n\t\tif len(checkIDs) > 0 {\n\t\t\t_, ok := checkIDs[c.ID]\n\t\t\ttest = test && ok\n\t\t}\n\n\t\ttest = test && (opts.Scored && c.Scored || opts.Unscored && !c.Scored)\n\n\t\treturn test\n\t}, nil\n}\n\nfunc runChecks(nodetype check.NodeType, testYamlFile, detectedVersion string) {\n\t// Verify config file was loaded into Viper during Cobra sub-command initialization.\n\tif configFileError != nil {\n\t\tcolorPrint(check.FAIL, fmt.Sprintf(\"Failed to read config file: %v\\n\", configFileError))\n\t\tos.Exit(1)\n\t}\n\n\tin, err := os.ReadFile(testYamlFile)\n\tif err != nil {\n\t\texitWithError(fmt.Errorf(\"error opening %s test file: %v\", testYamlFile, err))\n\t}\n\n\tglog.V(1).Info(fmt.Sprintf(\"Using test file: %s\\n\", testYamlFile))\n\n\t// Get the viper config for this section of tests\n\ttypeConf := viper.Sub(string(nodetype))\n\tif typeConf == nil {\n\t\tcolorPrint(check.FAIL, fmt.Sprintf(\"No config settings for %s\\n\", string(nodetype)))\n\t\tos.Exit(1)\n\t}\n\n\t// Get the set of executables we need for this section of the tests\n\tbinmap, err := getBinaries(typeConf, nodetype)\n\t// Checks that the executables we need for the section are running.\n\tif err != nil {\n\t\tglog.V(1).Info(fmt.Sprintf(\"failed to get a set of executables needed for tests: %v\", err))\n\t}\n\n\tconfmap := getFiles(typeConf, \"config\")\n\tsvcmap := getFiles(typeConf, \"service\")\n\tkubeconfmap := getFiles(typeConf, \"kubeconfig\")\n\tcafilemap := getFiles(typeConf, \"ca\")\n\tdatadirmap := getFiles(typeConf, \"datadir\")\n\n\t// Variable substitutions. Replace all occurrences of variables in controls files.\n\ts := string(in)\n\ts, binSubs := makeSubstitutions(s, \"bin\", binmap)\n\ts, _ = makeSubstitutions(s, \"conf\", confmap)\n\ts, _ = makeSubstitutions(s, \"svc\", svcmap)\n\ts, _ = makeSubstitutions(s, \"kubeconfig\", kubeconfmap)\n\ts, _ = makeSubstitutions(s, \"cafile\", cafilemap)\n\ts, _ = makeSubstitutions(s, \"datadir\", datadirmap)\n\n\tcontrols, err := check.NewControls(nodetype, []byte(s), detectedVersion)\n\tif err != nil {\n\t\texitWithError(fmt.Errorf(\"error setting up %s controls: %v\", nodetype, err))\n\t}\n\n\trunner := check.NewRunner()\n\tfilter, err := NewRunFilter(filterOpts)\n\tif err != nil {\n\t\texitWithError(fmt.Errorf(\"error setting up run filter: %v\", err))\n\t}\n\n\tgenerateDefaultEnvAudit(controls, binSubs)\n\n\tcontrols.RunChecks(runner, filter, parseSkipIds(skipIds))\n\tcontrolsCollection = append(controlsCollection, controls)\n}\n\nfunc generateDefaultEnvAudit(controls *check.Controls, binSubs []string) {\n\tfor _, group := range controls.Groups {\n\t\tfor _, checkItem := range group.Checks {\n\t\t\tif checkItem.Tests != nil && !checkItem.DisableEnvTesting {\n\t\t\t\tfor _, test := range checkItem.Tests.TestItems {\n\t\t\t\t\tif test.Env != \"\" && checkItem.AuditEnv == \"\" {\n\t\t\t\t\t\tbinPath := \"\"\n\n\t\t\t\t\t\tif len(binSubs) == 1 {\n\t\t\t\t\t\t\tbinPath = binSubs[0]\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tglog.V(1).Infof(\"AuditEnv not explicit for check (%s), where bin path cannot be determined\", checkItem.ID)\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif test.Env != \"\" && checkItem.AuditEnv == \"\" {\n\t\t\t\t\t\t\tcheckItem.AuditEnv = fmt.Sprintf(\"cat \\\"/proc/$(/bin/ps -C %s -o pid= | tr -d ' ')/environ\\\" | tr '\\\\0' '\\\\n'\", binPath)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc parseSkipIds(skipIds string) map[string]bool {\n\tskipIdMap := make(map[string]bool, 0)\n\tif skipIds != \"\" {\n\t\tfor _, id := range strings.Split(skipIds, \",\") {\n\t\t\tskipIdMap[strings.Trim(id, \" \")] = true\n\t\t}\n\t}\n\treturn skipIdMap\n}\n\n// colorPrint outputs the state in a specific colour, along with a message string\nfunc colorPrint(state check.State, s string) {\n\tcolors[state].Printf(\"[%s] \", state)\n\tfmt.Printf(\"%s\", s)\n}\n\n// prettyPrint outputs the results to stdout in human-readable format\nfunc prettyPrint(r *check.Controls, summary check.Summary) {\n\t// Print check results.\n\tif !noResults {\n\t\tcolorPrint(check.INFO, fmt.Sprintf(\"%s %s\\n\", r.ID, r.Text))\n\t\tfor _, g := range r.Groups {\n\t\t\tcolorPrint(check.INFO, fmt.Sprintf(\"%s %s\\n\", g.ID, g.Text))\n\t\t\tfor _, c := range g.Checks {\n\t\t\t\tcolorPrint(c.State, fmt.Sprintf(\"%s %s\\n\", c.ID, c.Text))\n\n\t\t\t\tif includeTestOutput && c.State == check.FAIL && len(c.ActualValue) > 0 {\n\t\t\t\t\tprintRawOutput(c.ActualValue)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfmt.Println()\n\t}\n\n\t// Print remediations.\n\tif !noRemediations {\n\t\tif summary.Fail > 0 || summary.Warn > 0 {\n\t\t\tcolors[check.WARN].Printf(\"== Remediations %s ==\\n\", r.Type)\n\t\t\tfor _, g := range r.Groups {\n\t\t\t\tfor _, c := range g.Checks {\n\t\t\t\t\tif c.State == check.FAIL {\n\t\t\t\t\t\tfmt.Printf(\"%s %s\\n\", c.ID, c.Remediation)\n\t\t\t\t\t}\n\t\t\t\t\tif c.State == check.WARN {\n\t\t\t\t\t\t// Print the error if test failed due to problem with the audit command\n\t\t\t\t\t\tif c.Reason != \"\" && c.Type != \"manual\" {\n\t\t\t\t\t\t\tfmt.Printf(\"%s audit test did not run: %s\\n\", c.ID, c.Reason)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tfmt.Printf(\"%s %s\\n\", c.ID, c.Remediation)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tfmt.Println()\n\t\t}\n\t}\n\n\t// Print summary setting output color to highest severity.\n\tif !noSummary {\n\t\tprintSummary(summary, string(r.Type))\n\t}\n}\n\nfunc printSummary(summary check.Summary, sectionName string) {\n\tvar res check.State\n\tif summary.Fail > 0 {\n\t\tres = check.FAIL\n\t} else if summary.Warn > 0 {\n\t\tres = check.WARN\n\t} else {\n\t\tres = check.PASS\n\t}\n\n\tcolors[res].Printf(\"== Summary %s ==\\n\", sectionName)\n\tfmt.Printf(\"%d checks PASS\\n%d checks FAIL\\n%d checks WARN\\n%d checks INFO\\n\\n\",\n\t\tsummary.Pass, summary.Fail, summary.Warn, summary.Info,\n\t)\n}\n\n// loadConfig finds the correct config dir based on the kubernetes version,\n// merges any specific config.yaml file found with the main config\n// and returns the benchmark file to use.\nfunc loadConfig(nodetype check.NodeType, benchmarkVersion string) string {\n\tvar file string\n\tvar err error\n\n\tswitch nodetype {\n\tcase check.MASTER:\n\t\tfile = masterFile\n\tcase check.NODE:\n\t\tfile = nodeFile\n\tcase check.CONTROLPLANE:\n\t\tfile = controlplaneFile\n\tcase check.ETCD:\n\t\tfile = etcdFile\n\tcase check.POLICIES:\n\t\tfile = policiesFile\n\tcase check.MANAGEDSERVICES:\n\t\tfile = managedservicesFile\n\t}\n\n\tpath, err := getConfigFilePath(benchmarkVersion, file)\n\tif err != nil {\n\t\texitWithError(fmt.Errorf(\"can't find %s controls file in %s: %v\", nodetype, cfgDir, err))\n\t}\n\n\t// Merge version-specific config if any.\n\tmergeConfig(path)\n\n\treturn filepath.Join(path, file)\n}\n\nfunc mergeConfig(path string) error {\n\tviper.SetConfigFile(path + \"/config.yaml\")\n\terr := viper.MergeInConfig()\n\tif err != nil {\n\t\tif os.IsNotExist(err) {\n\t\t\tglog.V(2).Info(fmt.Sprintf(\"No version-specific config.yaml file in %s\", path))\n\t\t} else {\n\t\t\treturn fmt.Errorf(\"couldn't read config file %s: %v\", path+\"/config.yaml\", err)\n\t\t}\n\t}\n\n\tglog.V(1).Info(fmt.Sprintf(\"Using config file: %s\\n\", viper.ConfigFileUsed()))\n\n\treturn nil\n}\n\nfunc mapToBenchmarkVersion(kubeToBenchmarkMap map[string]string, kv string) (string, error) {\n\tkvOriginal := kv\n\tcisVersion, found := kubeToBenchmarkMap[kv]\n\tglog.V(2).Info(fmt.Sprintf(\"mapToBenchmarkVersion for k8sVersion: %q cisVersion: %q found: %t\\n\", kv, cisVersion, found))\n\tfor !found && (kv != defaultKubeVersion && !isEmpty(kv)) {\n\t\tkv = decrementVersion(kv)\n\t\tcisVersion, found = kubeToBenchmarkMap[kv]\n\t\tglog.V(2).Info(fmt.Sprintf(\"mapToBenchmarkVersion for k8sVersion: %q cisVersion: %q found: %t\\n\", kv, cisVersion, found))\n\t}\n\n\tif !found {\n\t\tglog.V(1).Info(fmt.Sprintf(\"mapToBenchmarkVersion unable to find a match for: %q\", kvOriginal))\n\t\tglog.V(3).Info(fmt.Sprintf(\"mapToBenchmarkVersion kubeToBenchmarkMap: %#v\", kubeToBenchmarkMap))\n\t\treturn \"\", fmt.Errorf(\"unable to find a matching Benchmark Version match for kubernetes version: %s\", kvOriginal)\n\t}\n\n\treturn cisVersion, nil\n}\n\nfunc loadVersionMapping(v *viper.Viper) (map[string]string, error) {\n\tkubeToBenchmarkMap := v.GetStringMapString(\"version_mapping\")\n\tif kubeToBenchmarkMap == nil || (len(kubeToBenchmarkMap) == 0) {\n\t\treturn nil, fmt.Errorf(\"config file is missing 'version_mapping' section\")\n\t}\n\n\treturn kubeToBenchmarkMap, nil\n}\n\nfunc loadTargetMapping(v *viper.Viper) (map[string][]string, error) {\n\tbenchmarkVersionToTargetsMap := v.GetStringMapStringSlice(\"target_mapping\")\n\tif len(benchmarkVersionToTargetsMap) == 0 {\n\t\treturn nil, fmt.Errorf(\"config file is missing 'target_mapping' section\")\n\t}\n\n\treturn benchmarkVersionToTargetsMap, nil\n}\n\nfunc getBenchmarkVersion(kubeVersion, benchmarkVersion string, platform Platform, v *viper.Viper) (bv string, err error) {\n\tdetecetedKubeVersion = \"none\"\n\tif !isEmpty(kubeVersion) && !isEmpty(benchmarkVersion) {\n\t\treturn \"\", fmt.Errorf(\"It is an error to specify both --version and --benchmark flags\")\n\t}\n\tif isEmpty(benchmarkVersion) && isEmpty(kubeVersion) && !isEmpty(platform.Name) {\n\t\tbenchmarkVersion = getPlatformBenchmarkVersion(platform)\n\t\tif !isEmpty(benchmarkVersion) {\n\t\t\tdetecetedKubeVersion = benchmarkVersion\n\t\t}\n\t}\n\n\tif isEmpty(benchmarkVersion) {\n\t\tif isEmpty(kubeVersion) {\n\t\t\tkv, err := getKubeVersion()\n\t\t\tif err != nil {\n\t\t\t\treturn \"\", fmt.Errorf(\"Version check failed: %s\\nAlternatively, you can specify the version with --version\", err)\n\t\t\t}\n\t\t\tkubeVersion = kv.BaseVersion()\n\t\t\tdetecetedKubeVersion = kubeVersion\n\t\t}\n\n\t\tkubeToBenchmarkMap, err := loadVersionMapping(v)\n\t\tif err != nil {\n\t\t\treturn \"\", err\n\t\t}\n\n\t\tbenchmarkVersion, err = mapToBenchmarkVersion(kubeToBenchmarkMap, kubeVersion)\n\t\tif err != nil {\n\t\t\treturn \"\", err\n\t\t}\n\n\t\tglog.V(2).Info(fmt.Sprintf(\"Mapped Kubernetes version: %s to Benchmark version: %s\", kubeVersion, benchmarkVersion))\n\t}\n\n\tglog.V(1).Info(fmt.Sprintf(\"Kubernetes version: %q to Benchmark version: %q\", kubeVersion, benchmarkVersion))\n\treturn benchmarkVersion, nil\n}\n\n// isMaster verify if master components are running on the node.\nfunc isMaster() bool {\n\treturn isThisNodeRunning(check.MASTER)\n}\n\n// isEtcd verify if etcd components are running on the node.\nfunc isEtcd() bool {\n\treturn isThisNodeRunning(check.ETCD)\n}\n\nfunc isThisNodeRunning(nodeType check.NodeType) bool {\n\tglog.V(3).Infof(\"Checking if the current node is running %s components\", nodeType)\n\tnodeTypeConf := viper.Sub(string(nodeType))\n\tif nodeTypeConf == nil {\n\t\tglog.V(2).Infof(\"No config for %s components found\", nodeType)\n\t\treturn false\n\t}\n\n\tcomponents, err := getBinariesFunc(nodeTypeConf, nodeType)\n\tif err != nil {\n\t\tglog.V(2).Infof(\"Failed to find %s binaries: %v\", nodeType, err)\n\t\treturn false\n\t}\n\tif len(components) == 0 {\n\t\tglog.V(2).Infof(\"No %s binaries specified\", nodeType)\n\t\treturn false\n\t}\n\n\tglog.V(2).Infof(\"Node is running %s components\", nodeType)\n\treturn true\n}\n\nfunc exitCodeSelection(controlsCollection []*check.Controls) int {\n\tfor _, control := range controlsCollection {\n\t\tif control.Fail > 0 {\n\t\t\treturn exitCode\n\t\t}\n\t}\n\n\treturn 0\n}\n\nfunc writeOutput(controlsCollection []*check.Controls) {\n\tsort.Slice(controlsCollection, func(i, j int) bool {\n\t\tiid, _ := strconv.Atoi(controlsCollection[i].ID)\n\t\tjid, _ := strconv.Atoi(controlsCollection[j].ID)\n\t\treturn iid < jid\n\t})\n\tif junitFmt {\n\t\twriteJunitOutput(controlsCollection)\n\t\treturn\n\t}\n\tif jsonFmt {\n\t\twriteJSONOutput(controlsCollection)\n\t\treturn\n\t}\n\tif pgSQL {\n\t\twritePgsqlOutput(controlsCollection)\n\t\treturn\n\t}\n\tif aSFF {\n\t\twriteASFFOutput(controlsCollection)\n\t\treturn\n\t}\n\twriteStdoutOutput(controlsCollection)\n}\n\nfunc writeJSONOutput(controlsCollection []*check.Controls) {\n\tvar out []byte\n\tvar err error\n\tif !noTotals {\n\t\tvar totals check.OverallControls\n\t\ttotals.Controls = controlsCollection\n\t\ttotals.Totals = getSummaryTotals(controlsCollection)\n\t\tout, err = json.Marshal(totals)\n\t} else {\n\t\tout, err = json.Marshal(controlsCollection)\n\t}\n\tif err != nil {\n\t\texitWithError(fmt.Errorf(\"failed to output in JSON format: %v\", err))\n\t}\n\tprintOutput(string(out), outputFile)\n}\n\nfunc writeJunitOutput(controlsCollection []*check.Controls) {\n\t// QuickFix for issue https://github.com/aquasecurity/kube-bench/issues/883\n\t// Should consider to deprecate of switch to using Junit template\n\tprefix := \"<testsuites>\\n\"\n\tsuffix := \"\\n</testsuites>\"\n\tvar outputAllControls []byte\n\tfor _, controls := range controlsCollection {\n\t\ttempOut, err := controls.JUnit()\n\t\toutputAllControls = append(outputAllControls[:], tempOut[:]...)\n\t\tif err != nil {\n\t\t\texitWithError(fmt.Errorf(\"failed to output in JUnit format: %v\", err))\n\t\t}\n\t}\n\tprintOutput(prefix+string(outputAllControls)+suffix, outputFile)\n}\n\nfunc writePgsqlOutput(controlsCollection []*check.Controls) {\n\tfor _, controls := range controlsCollection {\n\t\tout, err := controls.JSON()\n\t\tif err != nil {\n\t\t\texitWithError(fmt.Errorf(\"failed to output in Postgresql format: %v\", err))\n\t\t}\n\t\tsavePgsql(string(out))\n\t}\n}\n\nfunc writeASFFOutput(controlsCollection []*check.Controls) {\n\tfor _, controls := range controlsCollection {\n\t\tout, err := controls.ASFF()\n\t\tif err != nil {\n\t\t\texitWithError(fmt.Errorf(\"failed to format findings as ASFF: %v\", err))\n\t\t}\n\t\tif err := writeFinding(out); err != nil {\n\t\t\texitWithError(fmt.Errorf(\"failed to output to ASFF: %v\", err))\n\t\t}\n\t}\n}\n\nfunc writeStdoutOutput(controlsCollection []*check.Controls) {\n\tfor _, controls := range controlsCollection {\n\t\tsummary := controls.Summary\n\t\tprettyPrint(controls, summary)\n\t}\n\tif !noTotals {\n\t\tprintSummary(getSummaryTotals(controlsCollection), \"total\")\n\t}\n}\n\nfunc getSummaryTotals(controlsCollection []*check.Controls) check.Summary {\n\tvar totalSummary check.Summary\n\tfor _, controls := range controlsCollection {\n\t\tsummary := controls.Summary\n\t\ttotalSummary.Fail = totalSummary.Fail + summary.Fail\n\t\ttotalSummary.Warn = totalSummary.Warn + summary.Warn\n\t\ttotalSummary.Pass = totalSummary.Pass + summary.Pass\n\t\ttotalSummary.Info = totalSummary.Info + summary.Info\n\t}\n\treturn totalSummary\n}\n\nfunc printRawOutput(output string) {\n\tfor _, row := range strings.Split(output, \"\\n\") {\n\t\tfmt.Println(fmt.Sprintf(\"\\t %s\", row))\n\t}\n}\n\nfunc writeOutputToFile(output string, outputFile string) error {\n\tfile, err := os.Create(outputFile)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer file.Close()\n\n\tw := bufio.NewWriter(file)\n\tfmt.Fprintln(w, output)\n\treturn w.Flush()\n}\n\nfunc printOutput(output string, outputFile string) {\n\tif outputFile == \"\" {\n\t\tfmt.Println(output)\n\t} else {\n\t\terr := writeOutputToFile(output, outputFile)\n\t\tif err != nil {\n\t\t\texitWithError(fmt.Errorf(\"Failed to write to output file %s: %v\", outputFile, err))\n\t\t}\n\t}\n}\n\n// validTargets helps determine if the targets\n// are legitimate for the benchmarkVersion.\nfunc validTargets(benchmarkVersion string, targets []string, v *viper.Viper) (bool, error) {\n\tbenchmarkVersionToTargetsMap, err := loadTargetMapping(v)\n\tif err != nil {\n\t\treturn false, err\n\t}\n\tprovidedTargets, found := benchmarkVersionToTargetsMap[benchmarkVersion]\n\tif !found {\n\t\treturn false, fmt.Errorf(\"No targets configured for %s\", benchmarkVersion)\n\t}\n\n\tfor _, pt := range targets {\n\t\tf := false\n\t\tfor _, t := range providedTargets {\n\t\t\tif pt == strings.ToLower(t) {\n\t\t\t\tf = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\tif !f {\n\t\t\treturn false, nil\n\t\t}\n\t}\n\n\treturn true, nil\n}\n"
  },
  {
    "path": "cmd/common_test.go",
    "content": "// Copyright © 2017-2019 Aqua Security Software Ltd. <info@aquasec.com>\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage cmd\n\nimport (\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"path\"\n\t\"path/filepath\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/aquasecurity/kube-bench/check\"\n\t\"github.com/spf13/viper\"\n\t\"github.com/stretchr/testify/assert\"\n)\n\ntype JsonOutputFormat struct {\n\tControls     []*check.Controls `json:\"Controls\"`\n\tTotalSummary map[string]int    `json:\"Totals\"`\n}\n\ntype JsonOutputFormatNoTotals struct {\n\tControls []*check.Controls `json:\"Controls\"`\n}\n\nfunc TestParseSkipIds(t *testing.T) {\n\tskipMap := parseSkipIds(\"4.12,4.13,5\")\n\t_, fourTwelveExists := skipMap[\"4.12\"]\n\t_, fourThirteenExists := skipMap[\"4.13\"]\n\t_, fiveExists := skipMap[\"5\"]\n\t_, other := skipMap[\"G1\"]\n\tassert.True(t, fourThirteenExists)\n\tassert.True(t, fourTwelveExists)\n\tassert.True(t, fiveExists)\n\tassert.False(t, other)\n}\n\nfunc TestNewRunFilter(t *testing.T) {\n\ttype TestCase struct {\n\t\tName       string\n\t\tFilterOpts FilterOpts\n\t\tGroup      *check.Group\n\t\tCheck      *check.Check\n\n\t\tExpected bool\n\t}\n\n\ttestCases := []TestCase{\n\t\t{\n\t\t\tName:       \"Should return true when scored flag is enabled and check is scored\",\n\t\t\tFilterOpts: FilterOpts{Scored: true, Unscored: false},\n\t\t\tGroup:      &check.Group{},\n\t\t\tCheck:      &check.Check{Scored: true},\n\t\t\tExpected:   true,\n\t\t},\n\t\t{\n\t\t\tName:       \"Should return false when scored flag is enabled and check is not scored\",\n\t\t\tFilterOpts: FilterOpts{Scored: true, Unscored: false},\n\t\t\tGroup:      &check.Group{},\n\t\t\tCheck:      &check.Check{Scored: false},\n\t\t\tExpected:   false,\n\t\t},\n\n\t\t{\n\t\t\tName:       \"Should return true when unscored flag is enabled and check is not scored\",\n\t\t\tFilterOpts: FilterOpts{Scored: false, Unscored: true},\n\t\t\tGroup:      &check.Group{},\n\t\t\tCheck:      &check.Check{Scored: false},\n\t\t\tExpected:   true,\n\t\t},\n\t\t{\n\t\t\tName:       \"Should return false when unscored flag is enabled and check is scored\",\n\t\t\tFilterOpts: FilterOpts{Scored: false, Unscored: true},\n\t\t\tGroup:      &check.Group{},\n\t\t\tCheck:      &check.Check{Scored: true},\n\t\t\tExpected:   false,\n\t\t},\n\n\t\t{\n\t\t\tName:       \"Should return true when group flag contains group's ID\",\n\t\t\tFilterOpts: FilterOpts{Scored: true, Unscored: true, GroupList: \"G1,G2,G3\"},\n\t\t\tGroup:      &check.Group{ID: \"G2\"},\n\t\t\tCheck:      &check.Check{},\n\t\t\tExpected:   true,\n\t\t},\n\t\t{\n\t\t\tName:       \"Should return false when group flag doesn't contain group's ID\",\n\t\t\tFilterOpts: FilterOpts{GroupList: \"G1,G3\"},\n\t\t\tGroup:      &check.Group{ID: \"G2\"},\n\t\t\tCheck:      &check.Check{},\n\t\t\tExpected:   false,\n\t\t},\n\n\t\t{\n\t\t\tName:       \"Should return true when check flag contains check's ID\",\n\t\t\tFilterOpts: FilterOpts{Scored: true, Unscored: true, CheckList: \"C1,C2,C3\"},\n\t\t\tGroup:      &check.Group{},\n\t\t\tCheck:      &check.Check{ID: \"C2\"},\n\t\t\tExpected:   true,\n\t\t},\n\t\t{\n\t\t\tName:       \"Should return false when check flag doesn't contain check's ID\",\n\t\t\tFilterOpts: FilterOpts{CheckList: \"C1,C3\"},\n\t\t\tGroup:      &check.Group{},\n\t\t\tCheck:      &check.Check{ID: \"C2\"},\n\t\t\tExpected:   false,\n\t\t},\n\t}\n\n\tfor _, testCase := range testCases {\n\t\tt.Run(testCase.Name, func(t *testing.T) {\n\t\t\tfilter, _ := NewRunFilter(testCase.FilterOpts)\n\t\t\tassert.Equal(t, testCase.Expected, filter(testCase.Group, testCase.Check))\n\t\t})\n\t}\n\n\tt.Run(\"Should return error when both group and check flags are used\", func(t *testing.T) {\n\t\t// given\n\t\topts := FilterOpts{GroupList: \"G1\", CheckList: \"C1\"}\n\t\t// when\n\t\t_, err := NewRunFilter(opts)\n\t\t// then\n\t\tassert.EqualError(t, err, \"group option and check option can't be used together\")\n\t})\n}\n\nfunc TestIsMaster(t *testing.T) {\n\ttestCases := []struct {\n\t\tname            string\n\t\tcfgFile         string\n\t\tgetBinariesFunc func(*viper.Viper, check.NodeType) (map[string]string, error)\n\t\tisMaster        bool\n\t}{\n\t\t{\n\t\t\tname:    \"valid config, is master and all components are running\",\n\t\t\tcfgFile: \"../cfg/config.yaml\",\n\t\t\tgetBinariesFunc: func(viper *viper.Viper, nt check.NodeType) (strings map[string]string, i error) {\n\t\t\t\treturn map[string]string{\"apiserver\": \"kube-apiserver\"}, nil\n\t\t\t},\n\t\t\tisMaster: true,\n\t\t},\n\t\t{\n\t\t\tname:    \"valid config, is master and but not all components are running\",\n\t\t\tcfgFile: \"../cfg/config.yaml\",\n\t\t\tgetBinariesFunc: func(viper *viper.Viper, nt check.NodeType) (strings map[string]string, i error) {\n\t\t\t\treturn map[string]string{}, nil\n\t\t\t},\n\t\t\tisMaster: false,\n\t\t},\n\t\t{\n\t\t\tname:    \"valid config, is master, not all components are running and fails to find all binaries\",\n\t\t\tcfgFile: \"../cfg/config.yaml\",\n\t\t\tgetBinariesFunc: func(viper *viper.Viper, nt check.NodeType) (strings map[string]string, i error) {\n\t\t\t\treturn map[string]string{}, errors.New(\"failed to find binaries\")\n\t\t\t},\n\t\t\tisMaster: false,\n\t\t},\n\t\t{\n\t\t\tname:     \"valid config, does not include master\",\n\t\t\tcfgFile:  \"../hack/node_only.yaml\",\n\t\t\tisMaster: false,\n\t\t},\n\t}\n\tcfgDirOld := cfgDir\n\tcfgDir = \"../cfg\"\n\tdefer func() {\n\t\tcfgDir = cfgDirOld\n\t}()\n\n\texecCode := `#!/bin/sh\n\techo \"Server Version: v1.13.10\"\n\t`\n\trestore, err := fakeExecutableInPath(\"kubectl\", execCode)\n\tif err != nil {\n\t\tt.Fatal(\"Failed when calling fakeExecutableInPath \", err)\n\t}\n\tdefer restore()\n\n\tfor _, tc := range testCases {\n\t\tfunc() {\n\t\t\tcfgFile = tc.cfgFile\n\t\t\tinitConfig()\n\n\t\t\toldGetBinariesFunc := getBinariesFunc\n\t\t\tgetBinariesFunc = tc.getBinariesFunc\n\t\t\tdefer func() {\n\t\t\t\tgetBinariesFunc = oldGetBinariesFunc\n\t\t\t\tcfgFile = \"\"\n\t\t\t}()\n\n\t\t\tassert.Equal(t, tc.isMaster, isMaster(), tc.name)\n\t\t}()\n\t}\n}\n\nfunc TestMapToCISVersion(t *testing.T) {\n\tviperWithData, err := loadConfigForTest()\n\tif err != nil {\n\t\tt.Fatalf(\"Unable to load config file %v\", err)\n\t}\n\tkubeToBenchmarkMap, err := loadVersionMapping(viperWithData)\n\tif err != nil {\n\t\tt.Fatalf(\"Unable to load config file %v\", err)\n\t}\n\n\tcases := []struct {\n\t\tkubeVersion string\n\t\tsucceed     bool\n\t\texp         string\n\t\texpErr      string\n\t}{\n\t\t{kubeVersion: \"1.9\", succeed: false, exp: \"\", expErr: \"unable to find a matching Benchmark Version match for kubernetes version: 1.9\"},\n\t\t{kubeVersion: \"1.11\", succeed: false, exp: \"\", expErr: \"unable to find a matching Benchmark Version match for kubernetes version: 1.11\"},\n\t\t{kubeVersion: \"1.12\", succeed: false, exp: \"\", expErr: \"unable to find a matching Benchmark Version match for kubernetes version: 1.12\"},\n\t\t{kubeVersion: \"1.13\", succeed: false, exp: \"\", expErr: \"unable to find a matching Benchmark Version match for kubernetes version: 1.13\"},\n\t\t{kubeVersion: \"1.14\", succeed: false, exp: \"\", expErr: \"unable to find a matching Benchmark Version match for kubernetes version: 1.14\"},\n\t\t{kubeVersion: \"1.15\", succeed: true, exp: \"cis-1.5\"},\n\t\t{kubeVersion: \"1.16\", succeed: true, exp: \"cis-1.6\"},\n\t\t{kubeVersion: \"1.17\", succeed: true, exp: \"cis-1.6\"},\n\t\t{kubeVersion: \"1.18\", succeed: true, exp: \"cis-1.6\"},\n\t\t{kubeVersion: \"1.19\", succeed: true, exp: \"cis-1.20\"},\n\t\t{kubeVersion: \"1.20\", succeed: true, exp: \"cis-1.20\"},\n\t\t{kubeVersion: \"1.21\", succeed: true, exp: \"cis-1.20\"},\n\t\t{kubeVersion: \"1.22\", succeed: true, exp: \"cis-1.23\"},\n\t\t{kubeVersion: \"1.23\", succeed: true, exp: \"cis-1.23\"},\n\t\t{kubeVersion: \"1.24\", succeed: true, exp: \"cis-1.24\"},\n\t\t{kubeVersion: \"1.25\", succeed: true, exp: \"cis-1.7\"},\n\t\t{kubeVersion: \"1.26\", succeed: true, exp: \"cis-1.8\"},\n\t\t{kubeVersion: \"1.27\", succeed: true, exp: \"cis-1.9\"},\n\t\t{kubeVersion: \"1.28\", succeed: true, exp: \"cis-1.10\"},\n\t\t{kubeVersion: \"1.29\", succeed: true, exp: \"cis-1.11\"},\n\t\t{kubeVersion: \"1.30\", succeed: true, exp: \"cis-1.11\"},\n\t\t{kubeVersion: \"1.31\", succeed: true, exp: \"cis-1.11\"},\n\t\t{kubeVersion: \"1.32\", succeed: true, exp: \"cis-1.12\"},\n\t\t{kubeVersion: \"1.33\", succeed: true, exp: \"cis-1.12\"},\n\t\t{kubeVersion: \"1.34\", succeed: true, exp: \"cis-1.12\"},\n\t\t{kubeVersion: \"gke-1.2.0\", succeed: true, exp: \"gke-1.2.0\"},\n\t\t{kubeVersion: \"ocp-3.10\", succeed: true, exp: \"rh-0.7\"},\n\t\t{kubeVersion: \"ocp-3.11\", succeed: true, exp: \"rh-0.7\"},\n\t\t{kubeVersion: \"unknown\", succeed: false, exp: \"\", expErr: \"unable to find a matching Benchmark Version match for kubernetes version: unknown\"},\n\t}\n\tfor _, c := range cases {\n\t\trv, err := mapToBenchmarkVersion(kubeToBenchmarkMap, c.kubeVersion)\n\t\tif c.succeed {\n\t\t\tif err != nil {\n\t\t\t\tt.Errorf(\"[%q]-Unexpected error: %v\", c.kubeVersion, err)\n\t\t\t}\n\n\t\t\tif len(rv) == 0 {\n\t\t\t\tt.Errorf(\"[%q]-missing return value\", c.kubeVersion)\n\t\t\t}\n\n\t\t\tif c.exp != rv {\n\t\t\t\tt.Errorf(\"[%q]- expected %q but Got %q\", c.kubeVersion, c.exp, rv)\n\t\t\t}\n\n\t\t} else {\n\t\t\tif c.exp != rv {\n\t\t\t\tt.Errorf(\"[%q]-mapToBenchmarkVersion kubeversion: %q Got %q expected %s\", c.kubeVersion, c.kubeVersion, rv, c.exp)\n\t\t\t}\n\n\t\t\tif c.expErr != err.Error() {\n\t\t\t\tt.Errorf(\"[%q]-mapToBenchmarkVersion expected Error: %q instead Got %q\", c.kubeVersion, c.expErr, err.Error())\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc TestLoadVersionMapping(t *testing.T) {\n\tsetDefault := func(v *viper.Viper, key string, value interface{}) *viper.Viper {\n\t\tv.SetDefault(key, value)\n\t\treturn v\n\t}\n\n\tviperWithData, err := loadConfigForTest()\n\tif err != nil {\n\t\tt.Fatalf(\"Unable to load config file %v\", err)\n\t}\n\n\tcases := []struct {\n\t\tn       string\n\t\tv       *viper.Viper\n\t\tsucceed bool\n\t}{\n\t\t{n: \"empty\", v: viper.New(), succeed: false},\n\t\t{\n\t\t\tn:       \"novals\",\n\t\t\tv:       setDefault(viper.New(), \"version_mapping\", \"novals\"),\n\t\t\tsucceed: false,\n\t\t},\n\t\t{\n\t\t\tn:       \"good\",\n\t\t\tv:       viperWithData,\n\t\t\tsucceed: true,\n\t\t},\n\t}\n\tfor _, c := range cases {\n\t\trv, err := loadVersionMapping(c.v)\n\t\tif c.succeed {\n\t\t\tif err != nil {\n\t\t\t\tt.Errorf(\"[%q]-Unexpected error: %v\", c.n, err)\n\t\t\t}\n\n\t\t\tif len(rv) == 0 {\n\t\t\t\tt.Errorf(\"[%q]-missing mapping value\", c.n)\n\t\t\t}\n\t\t} else {\n\t\t\tif err == nil {\n\t\t\t\tt.Errorf(\"[%q]-Expected error but got none\", c.n)\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc TestGetBenchmarkVersion(t *testing.T) {\n\tviperWithData, err := loadConfigForTest()\n\tif err != nil {\n\t\tt.Fatalf(\"Unable to load config file %v\", err)\n\t}\n\n\ttype getBenchmarkVersionFnToTest func(kubeVersion, benchmarkVersion string, platform Platform, v *viper.Viper) (string, error)\n\n\twithFakeKubectl := func(kubeVersion, benchmarkVersion string, platform Platform, v *viper.Viper, fn getBenchmarkVersionFnToTest) (string, error) {\n\t\texecCode := `#!/bin/sh\n\t\techo '{\"serverVersion\": {\"major\": \"1\", \"minor\": \"18\", \"gitVersion\": \"v1.18.10\"}}'\n\t\t`\n\t\trestore, err := fakeExecutableInPath(\"kubectl\", execCode)\n\t\tif err != nil {\n\t\t\tt.Fatal(\"Failed when calling fakeExecutableInPath \", err)\n\t\t}\n\t\tdefer restore()\n\n\t\treturn fn(kubeVersion, benchmarkVersion, platform, v)\n\t}\n\n\twithNoPath := func(kubeVersion, benchmarkVersion string, platform Platform, v *viper.Viper, fn getBenchmarkVersionFnToTest) (string, error) {\n\t\trestore, err := prunePath()\n\t\tif err != nil {\n\t\t\tt.Fatal(\"Failed when calling prunePath \", err)\n\t\t}\n\t\tdefer restore()\n\n\t\treturn fn(kubeVersion, benchmarkVersion, platform, v)\n\t}\n\n\ttype getBenchmarkVersionFn func(string, string, Platform, *viper.Viper, getBenchmarkVersionFnToTest) (string, error)\n\tcases := []struct {\n\t\tn                string\n\t\tkubeVersion      string\n\t\tbenchmarkVersion string\n\t\tplatform         Platform\n\t\tv                *viper.Viper\n\t\tcallFn           getBenchmarkVersionFn\n\t\texp              string\n\t\tsucceed          bool\n\t}{\n\t\t{n: \"both versions\", kubeVersion: \"1.11\", benchmarkVersion: \"cis-1.3\", platform: Platform{}, exp: \"cis-1.3\", callFn: withNoPath, v: viper.New(), succeed: false},\n\t\t{n: \"no version-missing-kubectl\", kubeVersion: \"\", benchmarkVersion: \"\", platform: Platform{}, v: viperWithData, exp: \"cis-1.6\", callFn: withNoPath, succeed: true},\n\t\t{n: \"no version-fakeKubectl\", kubeVersion: \"\", benchmarkVersion: \"\", platform: Platform{}, v: viperWithData, exp: \"cis-1.6\", callFn: withFakeKubectl, succeed: true},\n\t\t{n: \"kubeVersion\", kubeVersion: \"1.15\", benchmarkVersion: \"\", platform: Platform{}, v: viperWithData, exp: \"cis-1.5\", callFn: withNoPath, succeed: true},\n\t\t{n: \"ocpVersion310\", kubeVersion: \"ocp-3.10\", benchmarkVersion: \"\", platform: Platform{}, v: viperWithData, exp: \"rh-0.7\", callFn: withNoPath, succeed: true},\n\t\t{n: \"ocpVersion311\", kubeVersion: \"ocp-3.11\", benchmarkVersion: \"\", platform: Platform{}, v: viperWithData, exp: \"rh-0.7\", callFn: withNoPath, succeed: true},\n\t\t{n: \"gke12\", kubeVersion: \"gke-1.2.0\", benchmarkVersion: \"\", platform: Platform{}, v: viperWithData, exp: \"gke-1.2.0\", callFn: withNoPath, succeed: true},\n\t}\n\tfor _, c := range cases {\n\t\trv, err := c.callFn(c.kubeVersion, c.benchmarkVersion, c.platform, c.v, getBenchmarkVersion)\n\t\tif c.succeed {\n\t\t\tif err != nil {\n\t\t\t\tt.Errorf(\"[%q]-Unexpected error: %v\", c.n, err)\n\t\t\t}\n\n\t\t\tif len(rv) == 0 {\n\t\t\t\tt.Errorf(\"[%q]-missing return value\", c.n)\n\t\t\t}\n\n\t\t\tif c.exp != rv {\n\t\t\t\tt.Errorf(\"[%q]- expected %q but Got %q\", c.n, c.exp, rv)\n\t\t\t}\n\t\t} else {\n\t\t\tif err == nil {\n\t\t\t\tt.Errorf(\"[%q]-Expected error but got none\", c.n)\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc TestValidTargets(t *testing.T) {\n\tviperWithData, err := loadConfigForTest()\n\tif err != nil {\n\t\tt.Fatalf(\"Unable to load config file %v\", err)\n\t}\n\tcases := []struct {\n\t\tname      string\n\t\tbenchmark string\n\t\ttargets   []string\n\t\texpected  bool\n\t}{\n\t\t{\n\t\t\tname:      \"cis-1.5 no dummy\",\n\t\t\tbenchmark: \"cis-1.5\",\n\t\t\ttargets:   []string{\"master\", \"node\", \"controlplane\", \"etcd\", \"dummy\"},\n\t\t\texpected:  false,\n\t\t},\n\t\t{\n\t\t\tname:      \"cis-1.5 valid\",\n\t\t\tbenchmark: \"cis-1.5\",\n\t\t\ttargets:   []string{\"master\", \"node\", \"controlplane\", \"etcd\", \"policies\"},\n\t\t\texpected:  true,\n\t\t},\n\t\t{\n\t\t\tname:      \"cis-1.6 no Pikachu\",\n\t\t\tbenchmark: \"cis-1.6\",\n\t\t\ttargets:   []string{\"master\", \"node\", \"controlplane\", \"etcd\", \"Pikachu\"},\n\t\t\texpected:  false,\n\t\t},\n\t\t{\n\t\t\tname:      \"cis-1.6 valid\",\n\t\t\tbenchmark: \"cis-1.6\",\n\t\t\ttargets:   []string{\"master\", \"node\", \"controlplane\", \"etcd\", \"policies\"},\n\t\t\texpected:  true,\n\t\t},\n\t\t{\n\t\t\tname:      \"gke-1.2.0 valid\",\n\t\t\tbenchmark: \"gke-1.2.0\",\n\t\t\ttargets:   []string{\"master\", \"node\", \"controlplane\", \"policies\", \"managedservices\"},\n\t\t\texpected:  true,\n\t\t},\n\t\t{\n\t\t\tname:      \"aks-1.0 valid\",\n\t\t\tbenchmark: \"aks-1.0\",\n\t\t\ttargets:   []string{\"node\", \"policies\", \"controlplane\", \"managedservices\"},\n\t\t\texpected:  true,\n\t\t},\n\t\t{\n\t\t\tname:      \"aks-1.7 valid\",\n\t\t\tbenchmark: \"aks-1.7\",\n\t\t\ttargets:   []string{\"node\", \"policies\", \"controlplane\", \"managedservices\"},\n\t\t\texpected:  true,\n\t\t},\n\t\t{\n\t\t\tname:      \"eks-1.0.1 valid\",\n\t\t\tbenchmark: \"eks-1.0.1\",\n\t\t\ttargets:   []string{\"node\", \"policies\", \"controlplane\", \"managedservices\"},\n\t\t\texpected:  true,\n\t\t},\n\t\t{\n\t\t\tname:      \"eks-1.1.0 valid\",\n\t\t\tbenchmark: \"eks-1.1.0\",\n\t\t\ttargets:   []string{\"node\", \"policies\", \"controlplane\", \"managedservices\"},\n\t\t\texpected:  true,\n\t\t},\n\t\t{\n\t\t\tname:      \"eks-1.2.0 valid\",\n\t\t\tbenchmark: \"eks-1.2.0\",\n\t\t\ttargets:   []string{\"node\", \"policies\", \"controlplane\", \"managedservices\"},\n\t\t\texpected:  true,\n\t\t},\n\t\t{\n\t\t\tname:      \"eks-1.5.0 valid\",\n\t\t\tbenchmark: \"eks-1.5.0\",\n\t\t\ttargets:   []string{\"node\", \"policies\", \"controlplane\", \"managedservices\"},\n\t\t\texpected:  true,\n\t\t},\n\t\t{\n\t\t\tname:      \"eks-1.7.0 valid\",\n\t\t\tbenchmark: \"eks-1.7.0\",\n\t\t\ttargets:   []string{\"node\", \"policies\", \"controlplane\", \"managedservices\"},\n\t\t\texpected:  true,\n\t\t},\n\t}\n\n\tfor _, c := range cases {\n\t\tt.Run(c.name, func(t *testing.T) {\n\t\t\tret, err := validTargets(c.benchmark, c.targets, viperWithData)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatalf(\"Expected nil error, got: %v\", err)\n\t\t\t}\n\t\t\tif ret != c.expected {\n\t\t\t\tt.Fatalf(\"Expected %t, got %t\", c.expected, ret)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestIsEtcd(t *testing.T) {\n\ttestCases := []struct {\n\t\tname            string\n\t\tcfgFile         string\n\t\tgetBinariesFunc func(*viper.Viper, check.NodeType) (map[string]string, error)\n\t\tisEtcd          bool\n\t}{\n\t\t{\n\t\t\tname:    \"valid config, is etcd and all components are running\",\n\t\t\tcfgFile: \"../cfg/config.yaml\",\n\t\t\tgetBinariesFunc: func(viper *viper.Viper, nt check.NodeType) (strings map[string]string, i error) {\n\t\t\t\treturn map[string]string{\"etcd\": \"etcd\"}, nil\n\t\t\t},\n\t\t\tisEtcd: true,\n\t\t},\n\t\t{\n\t\t\tname:    \"valid config, is etcd and but not all components are running\",\n\t\t\tcfgFile: \"../cfg/config.yaml\",\n\t\t\tgetBinariesFunc: func(viper *viper.Viper, nt check.NodeType) (strings map[string]string, i error) {\n\t\t\t\treturn map[string]string{}, nil\n\t\t\t},\n\t\t\tisEtcd: false,\n\t\t},\n\t\t{\n\t\t\tname:    \"valid config, is etcd, not all components are running and fails to find all binaries\",\n\t\t\tcfgFile: \"../cfg/config.yaml\",\n\t\t\tgetBinariesFunc: func(viper *viper.Viper, nt check.NodeType) (strings map[string]string, i error) {\n\t\t\t\treturn map[string]string{}, errors.New(\"failed to find binaries\")\n\t\t\t},\n\t\t\tisEtcd: false,\n\t\t},\n\t\t{\n\t\t\tname:    \"valid config, does not include etcd\",\n\t\t\tcfgFile: \"../hack/node_only.yaml\",\n\t\t\tisEtcd:  false,\n\t\t},\n\t}\n\tcfgDirOld := cfgDir\n\tcfgDir = \"../cfg\"\n\tdefer func() {\n\t\tcfgDir = cfgDirOld\n\t}()\n\n\texecCode := `#!/bin/sh\n\techo \"Server Version: v1.15.03\"\n\t`\n\trestore, err := fakeExecutableInPath(\"kubectl\", execCode)\n\tif err != nil {\n\t\tt.Fatal(\"Failed when calling fakeExecutableInPath \", err)\n\t}\n\tdefer restore()\n\n\tfor _, tc := range testCases {\n\t\tfunc() {\n\t\t\tcfgFile = tc.cfgFile\n\t\t\tinitConfig()\n\n\t\t\toldGetBinariesFunc := getBinariesFunc\n\t\t\tgetBinariesFunc = tc.getBinariesFunc\n\t\t\tdefer func() {\n\t\t\t\tgetBinariesFunc = oldGetBinariesFunc\n\t\t\t\tcfgFile = \"\"\n\t\t\t}()\n\n\t\t\tassert.Equal(t, tc.isEtcd, isEtcd(), tc.name)\n\t\t}()\n\t}\n}\n\nfunc TestWriteResultToJsonFile(t *testing.T) {\n\tdefer func() {\n\t\tcontrolsCollection = []*check.Controls{}\n\t\tjsonFmt = false\n\t\toutputFile = \"\"\n\t}()\n\tvar err error\n\tjsonFmt = true\n\toutputFile = path.Join(os.TempDir(), fmt.Sprintf(\"%d\", time.Now().UnixNano()))\n\n\tcontrolsCollection, err = parseControlsJsonFile(\"./testdata/controlsCollection.json\")\n\tif err != nil {\n\t\tt.Error(err)\n\t}\n\twriteOutput(controlsCollection)\n\n\tvar expect JsonOutputFormat\n\tvar result JsonOutputFormat\n\tresult, err = parseResultJsonFile(outputFile)\n\tif err != nil {\n\t\tt.Error(err)\n\t}\n\texpect, err = parseResultJsonFile(\"./testdata/result.json\")\n\tif err != nil {\n\t\tt.Error(err)\n\t}\n\n\tassert.Equal(t, expect, result)\n}\n\nfunc TestWriteResultNoTotalsToJsonFile(t *testing.T) {\n\tdefer func() {\n\t\tcontrolsCollection = []*check.Controls{}\n\t\tjsonFmt = false\n\t\toutputFile = \"\"\n\t}()\n\tvar err error\n\tjsonFmt = true\n\toutputFile = path.Join(os.TempDir(), fmt.Sprintf(\"%d\", time.Now().UnixNano()))\n\n\tnoTotals = true\n\n\tcontrolsCollection, err = parseControlsJsonFile(\"./testdata/controlsCollection.json\")\n\tif err != nil {\n\t\tt.Error(err)\n\t}\n\twriteOutput(controlsCollection)\n\n\tvar expect []*check.Controls\n\tvar result []*check.Controls\n\tresult, err = parseResultNoTotalsJsonFile(outputFile)\n\tif err != nil {\n\t\tt.Error(err)\n\t}\n\texpect, err = parseResultNoTotalsJsonFile(\"./testdata/result_no_totals.json\")\n\tif err != nil {\n\t\tt.Error(err)\n\t}\n\n\tassert.Equal(t, expect, result)\n}\n\nfunc TestExitCodeSelection(t *testing.T) {\n\texitCode = 10\n\tcontrolsCollectionAllPassed, errPassed := parseControlsJsonFile(\"./testdata/passedControlsCollection.json\")\n\tif errPassed != nil {\n\t\tt.Error(errPassed)\n\t}\n\tcontrolsCollectionWithFailures, errFailure := parseControlsJsonFile(\"./testdata/controlsCollection.json\")\n\tif errFailure != nil {\n\t\tt.Error(errFailure)\n\t}\n\n\texitCodePassed := exitCodeSelection(controlsCollectionAllPassed)\n\tassert.Equal(t, 0, exitCodePassed)\n\n\texitCodeFailure := exitCodeSelection(controlsCollectionWithFailures)\n\tassert.Equal(t, 10, exitCodeFailure)\n}\n\nfunc TestGenerationDefaultEnvAudit(t *testing.T) {\n\tinput := []byte(`\n---\ntype: \"master\"\ngroups:\n- id: G1\n  checks:\n  - id: G1/C1\n- id: G2\n  checks:\n  - id: G2/C1\n    text: \"Verify that the SomeSampleFlag argument is set to true\"\n    audit: \"grep -B1 SomeSampleFlag=true /this/is/a/file/path\"\n    tests:\n      test_items:\n      - flag: \"SomeSampleFlag=true\"\n        env: \"SOME_SAMPLE_FLAG\"\n        compare:\n          op: has\n          value: \"true\"\n        set: true\n    remediation: |\n      Edit the config file /this/is/a/file/path and set SomeSampleFlag to true.\n    scored: true\n`)\n\tcontrols, err := check.NewControls(check.MASTER, input, \"\")\n\tassert.NoError(t, err)\n\n\tbinSubs := []string{\"TestBinPath\"}\n\tgenerateDefaultEnvAudit(controls, binSubs)\n\n\texpectedAuditEnv := fmt.Sprintf(\"cat \\\"/proc/$(/bin/ps -C %s -o pid= | tr -d ' ')/environ\\\" | tr '\\\\0' '\\\\n'\", binSubs[0])\n\tassert.Equal(t, expectedAuditEnv, controls.Groups[1].Checks[0].AuditEnv)\n}\n\nfunc TestGetSummaryTotals(t *testing.T) {\n\tcontrolsCollection, err := parseControlsJsonFile(\"./testdata/controlsCollection.json\")\n\tif err != nil {\n\t\tt.Error(err)\n\t}\n\n\tresultTotals := getSummaryTotals(controlsCollection)\n\tassert.Equal(t, 12, resultTotals.Fail)\n\tassert.Equal(t, 14, resultTotals.Warn)\n\tassert.Equal(t, 0, resultTotals.Info)\n\tassert.Equal(t, 49, resultTotals.Pass)\n}\n\nfunc TestPrintSummary(t *testing.T) {\n\tcontrolsCollection, err := parseControlsJsonFile(\"./testdata/controlsCollection.json\")\n\tif err != nil {\n\t\tt.Error(err)\n\t}\n\n\tresultTotals := getSummaryTotals(controlsCollection)\n\trescueStdout := os.Stdout\n\tr, w, _ := os.Pipe()\n\tos.Stdout = w\n\tprintSummary(resultTotals, \"totals\")\n\tw.Close()\n\tout, _ := io.ReadAll(r)\n\tos.Stdout = rescueStdout\n\n\tassert.Contains(t, string(out), \"49 checks PASS\\n12 checks FAIL\\n14 checks WARN\\n0 checks INFO\\n\\n\")\n}\n\nfunc TestPrettyPrintNoSummary(t *testing.T) {\n\tcontrolsCollection, err := parseControlsJsonFile(\"./testdata/controlsCollection.json\")\n\tif err != nil {\n\t\tt.Error(err)\n\t}\n\n\tresultTotals := getSummaryTotals(controlsCollection)\n\trescueStdout := os.Stdout\n\tr, w, _ := os.Pipe()\n\tos.Stdout = w\n\tnoSummary = true\n\tprettyPrint(controlsCollection[0], resultTotals)\n\tw.Close()\n\tout, _ := io.ReadAll(r)\n\tos.Stdout = rescueStdout\n\n\tassert.NotContains(t, string(out), \"49 checks PASS\")\n}\n\nfunc TestPrettyPrintSummary(t *testing.T) {\n\tcontrolsCollection, err := parseControlsJsonFile(\"./testdata/controlsCollection.json\")\n\tif err != nil {\n\t\tt.Error(err)\n\t}\n\n\tresultTotals := getSummaryTotals(controlsCollection)\n\trescueStdout := os.Stdout\n\tr, w, _ := os.Pipe()\n\tos.Stdout = w\n\tnoSummary = false\n\tprettyPrint(controlsCollection[0], resultTotals)\n\tw.Close()\n\tout, _ := io.ReadAll(r)\n\tos.Stdout = rescueStdout\n\n\tassert.Contains(t, string(out), \"49 checks PASS\")\n}\n\nfunc TestWriteStdoutOutputNoTotal(t *testing.T) {\n\tcontrolsCollection, err := parseControlsJsonFile(\"./testdata/controlsCollection.json\")\n\tif err != nil {\n\t\tt.Error(err)\n\t}\n\n\trescueStdout := os.Stdout\n\tr, w, _ := os.Pipe()\n\tos.Stdout = w\n\tnoTotals = true\n\twriteStdoutOutput(controlsCollection)\n\tw.Close()\n\tout, _ := io.ReadAll(r)\n\tos.Stdout = rescueStdout\n\n\tassert.NotContains(t, string(out), \"49 checks PASS\")\n}\n\nfunc TestWriteStdoutOutputTotal(t *testing.T) {\n\tcontrolsCollection, err := parseControlsJsonFile(\"./testdata/controlsCollection.json\")\n\tif err != nil {\n\t\tt.Error(err)\n\t}\n\n\trescueStdout := os.Stdout\n\n\tr, w, _ := os.Pipe()\n\n\tos.Stdout = w\n\tnoTotals = false\n\twriteStdoutOutput(controlsCollection)\n\tw.Close()\n\tout, _ := io.ReadAll(r)\n\n\tos.Stdout = rescueStdout\n\n\tassert.Contains(t, string(out), \"49 checks PASS\")\n}\n\nfunc parseControlsJsonFile(filepath string) ([]*check.Controls, error) {\n\tvar result []*check.Controls\n\n\td, err := os.ReadFile(filepath)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\terr = json.Unmarshal(d, &result)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn result, nil\n}\n\nfunc parseResultJsonFile(filepath string) (JsonOutputFormat, error) {\n\tvar result JsonOutputFormat\n\n\td, err := os.ReadFile(filepath)\n\tif err != nil {\n\t\treturn result, err\n\t}\n\terr = json.Unmarshal(d, &result)\n\tif err != nil {\n\t\treturn result, err\n\t}\n\n\treturn result, nil\n}\n\nfunc parseResultNoTotalsJsonFile(filepath string) ([]*check.Controls, error) {\n\tvar result []*check.Controls\n\n\td, err := os.ReadFile(filepath)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\terr = json.Unmarshal(d, &result)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn result, nil\n}\n\nfunc loadConfigForTest() (*viper.Viper, error) {\n\tviperWithData := viper.New()\n\tviperWithData.SetConfigFile(\"../cfg/config.yaml\")\n\tif err := viperWithData.ReadInConfig(); err != nil {\n\t\treturn nil, err\n\t}\n\treturn viperWithData, nil\n}\n\ntype restoreFn func()\n\nfunc fakeExecutableInPath(execFile, execCode string) (restoreFn, error) {\n\tpathenv := os.Getenv(\"PATH\")\n\ttmp, err := os.MkdirTemp(\"\", \"TestfakeExecutableInPath\")\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\twd, err := os.Getwd()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif len(execCode) > 0 {\n\t\tos.WriteFile(filepath.Join(tmp, execFile), []byte(execCode), 0700)\n\t} else {\n\t\tf, err := os.OpenFile(execFile, os.O_CREATE|os.O_EXCL, 0700)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\terr = f.Close()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\terr = os.Setenv(\"PATH\", fmt.Sprintf(\"%s:%s\", tmp, pathenv))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\trestorePath := func() {\n\t\tos.RemoveAll(tmp)\n\t\tos.Chdir(wd)\n\t\tos.Setenv(\"PATH\", pathenv)\n\t}\n\n\treturn restorePath, nil\n}\n\nfunc prunePath() (restoreFn, error) {\n\tpathenv := os.Getenv(\"PATH\")\n\terr := os.Setenv(\"PATH\", \"\")\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\trestorePath := func() {\n\t\tos.Setenv(\"PATH\", pathenv)\n\t}\n\treturn restorePath, nil\n}\n"
  },
  {
    "path": "cmd/database.go",
    "content": "package cmd\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"time\"\n\n\t\"github.com/golang/glog\"\n\t\"github.com/spf13/viper\"\n\t\"gorm.io/driver/postgres\"\n\t\"gorm.io/gorm\"\n)\n\ntype PsqlConnInfo struct {\n\tHost     string\n\tUser     string\n\tDbName   string\n\tSslMode  string\n\tPassword string\n}\n\nfunc getPsqlConnInfo() (PsqlConnInfo, error) {\n\tvar host string\n\tif value := viper.GetString(\"PGSQL_HOST\"); value != \"\" {\n\t\thost = value\n\t} else {\n\t\treturn PsqlConnInfo{}, fmt.Errorf(\"%s_PGSQL_HOST env var is required\", envVarsPrefix)\n\t}\n\n\tvar user string\n\tif value := viper.GetString(\"PGSQL_USER\"); value != \"\" {\n\t\tuser = value\n\t} else {\n\t\treturn PsqlConnInfo{}, fmt.Errorf(\"%s_PGSQL_USER env var is required\", envVarsPrefix)\n\t}\n\n\tvar dbName string\n\tif value := viper.GetString(\"PGSQL_DBNAME\"); value != \"\" {\n\t\tdbName = value\n\t} else {\n\t\treturn PsqlConnInfo{}, fmt.Errorf(\"%s_PGSQL_DBNAME env var is required\", envVarsPrefix)\n\t}\n\n\tvar sslMode string\n\tif value := viper.GetString(\"PGSQL_SSLMODE\"); value != \"\" {\n\t\tsslMode = value\n\t} else {\n\t\treturn PsqlConnInfo{}, fmt.Errorf(\"%s_PGSQL_SSLMODE env var is required\", envVarsPrefix)\n\t}\n\n\tvar password string\n\tif value := viper.GetString(\"PGSQL_PASSWORD\"); value != \"\" {\n\t\tpassword = value\n\t} else {\n\t\treturn PsqlConnInfo{}, fmt.Errorf(\"%s_PGSQL_PASSWORD env var is required\", envVarsPrefix)\n\t}\n\n\treturn PsqlConnInfo{\n\t\tHost:     host,\n\t\tUser:     user,\n\t\tDbName:   dbName,\n\t\tSslMode:  sslMode,\n\t\tPassword: password,\n\t}, nil\n}\n\nfunc (c *PsqlConnInfo) toString() string {\n\treturn fmt.Sprintf(\"host=%s user=%s dbname=%s sslmode=%s password=%s\",\n\t\tc.Host,\n\t\tc.User,\n\t\tc.DbName,\n\t\tc.SslMode,\n\t\tc.Password,\n\t)\n}\n\nfunc savePgsql(jsonInfo string) {\n\tvar hostname string\n\tif value := viper.GetString(\"K8S_HOST\"); value != \"\" {\n\t\t// Adhere to the ScanHost column definition below\n\t\tif len(value) > 63 {\n\t\t\texitWithError(fmt.Errorf(\"%s_K8S_HOST value's length must be less than 63 chars\", envVarsPrefix))\n\t\t}\n\n\t\thostname = value\n\t} else {\n\t\thost, err := os.Hostname()\n\t\tif err != nil {\n\t\t\texitWithError(fmt.Errorf(\"received error looking up hostname: %s\", err))\n\t\t}\n\n\t\thostname = host\n\t}\n\n\tPsqlConnInfo, err := getPsqlConnInfo()\n\tif err != nil {\n\t\texitWithError(err)\n\t}\n\n\tdb, err := gorm.Open(postgres.Open(PsqlConnInfo.toString()), &gorm.Config{})\n\tif err != nil {\n\t\texitWithError(fmt.Errorf(\"received error connecting to database: %s\", err))\n\t}\n\n\ttimestamp := time.Now()\n\ttype ScanResult struct {\n\t\tgorm.Model\n\t\tScanHost string    `gorm:\"type:varchar(63) not null\"` // https://www.ietf.org/rfc/rfc1035.txt\n\t\tScanTime time.Time `gorm:\"not null\"`\n\t\tScanInfo string    `gorm:\"type:jsonb not null\"`\n\t}\n\n\tdb.Debug().AutoMigrate(&ScanResult{})\n\tdb.Save(&ScanResult{ScanHost: hostname, ScanTime: timestamp, ScanInfo: jsonInfo})\n\tglog.V(2).Info(fmt.Sprintf(\"successfully stored result to: %s\", PsqlConnInfo.Host))\n}\n"
  },
  {
    "path": "cmd/kubernetes_version.go",
    "content": "package cmd\n\nimport (\n\t\"crypto/tls\"\n\t\"encoding/json\"\n\t\"encoding/pem\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/golang/glog\"\n)\n\ntype KubeVersion struct {\n\tMajor       string\n\tMinor       string\n\tbaseVersion string\n\tGitVersion  string\n}\n\nfunc (k *KubeVersion) BaseVersion() string {\n\tif k.baseVersion != \"\" {\n\t\treturn k.baseVersion\n\t}\n\t// Some provides return the minor version like \"15+\"\n\tminor := strings.Replace(k.Minor, \"+\", \"\", -1)\n\tver := fmt.Sprintf(\"%s.%s\", k.Major, minor)\n\tk.baseVersion = ver\n\treturn ver\n}\n\nfunc getKubeVersionFromRESTAPI() (*KubeVersion, error) {\n\tglog.V(2).Info(\"Try to get version from Rest API\")\n\tk8sVersionURL := getKubernetesURL()\n\tserviceaccount := \"/var/run/secrets/kubernetes.io/serviceaccount\"\n\tcacertfile := fmt.Sprintf(\"%s/ca.crt\", serviceaccount)\n\ttokenfile := fmt.Sprintf(\"%s/token\", serviceaccount)\n\n\ttlsCert, err := loadCertificate(cacertfile)\n\tif err != nil {\n\t\tglog.V(2).Infof(\"Failed loading certificate Error: %s\", err)\n\t\treturn nil, err\n\t}\n\n\ttb, err := os.ReadFile(tokenfile)\n\tif err != nil {\n\t\tglog.V(2).Infof(\"Failed reading token file Error: %s\", err)\n\t\treturn nil, err\n\t}\n\ttoken := strings.TrimSpace(string(tb))\n\n\tdata, err := getWebDataWithRetry(k8sVersionURL, token, tlsCert)\n\tif err != nil {\n\t\tglog.V(2).Infof(\"Failed to get data Error: %s\", err)\n\t\treturn nil, err\n\t}\n\n\tk8sVersion, err := extractVersion(data)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn k8sVersion, nil\n}\n\n// The idea of this function is so if Kubernetes DNS is not completely seetup and the\n// Container where kube-bench is running needs time for DNS configure.\n// Basically try 10 times, waiting 1 second until either it is successful or it fails.\nfunc getWebDataWithRetry(k8sVersionURL, token string, cacert *tls.Certificate) (data []byte, err error) {\n\ttries := 0\n\t// We retry a few times in case the DNS service has not had time to come up\n\tfor tries < 10 {\n\t\tdata, err = getWebData(k8sVersionURL, token, cacert)\n\t\tif err == nil {\n\t\t\treturn\n\t\t}\n\t\ttries++\n\t\ttime.Sleep(1 * time.Second)\n\t}\n\n\treturn\n}\n\ntype VersionResponse struct {\n\tMajor        string\n\tMinor        string\n\tGitVersion   string\n\tGitCommit    string\n\tGitTreeState string\n\tBuildDate    string\n\tGoVersion    string\n\tCompiler     string\n\tPlatform     string\n}\n\nfunc extractVersion(data []byte) (*KubeVersion, error) {\n\tvrObj := &VersionResponse{}\n\tglog.V(2).Info(fmt.Sprintf(\"vd: %s\\n\", string(data)))\n\terr := json.Unmarshal(data, vrObj)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tglog.V(2).Info(fmt.Sprintf(\"vrObj: %#v\\n\", vrObj))\n\n\treturn &KubeVersion{\n\t\tMajor:      vrObj.Major,\n\t\tMinor:      vrObj.Minor,\n\t\tGitVersion: vrObj.GitVersion,\n\t}, nil\n}\n\nfunc getWebData(srvURL, token string, cacert *tls.Certificate) ([]byte, error) {\n\tglog.V(2).Info(fmt.Sprintf(\"getWebData srvURL: %s\\n\", srvURL))\n\n\ttlsConf := &tls.Config{\n\t\tCertificates:       []tls.Certificate{*cacert},\n\t\tInsecureSkipVerify: true,\n\t}\n\ttr := &http.Transport{\n\t\tTLSClientConfig: tlsConf,\n\t}\n\tclient := &http.Client{Transport: tr}\n\treq, err := http.NewRequest(http.MethodGet, srvURL, nil)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tauthToken := fmt.Sprintf(\"Bearer %s\", token)\n\treq.Header.Set(\"Authorization\", authToken)\n\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\tglog.V(2).Info(fmt.Sprintf(\"HTTP ERROR: %v\\n\", err))\n\t\treturn nil, err\n\t}\n\tdefer resp.Body.Close()\n\n\tif resp.StatusCode != http.StatusOK {\n\t\tglog.V(2).Info(fmt.Sprintf(\"URL:[%s], StatusCode:[%d] \\n Headers: %#v\\n\", srvURL, resp.StatusCode, resp.Header))\n\t\terr = fmt.Errorf(\"URL:[%s], StatusCode:[%d]\", srvURL, resp.StatusCode)\n\t\treturn nil, err\n\t}\n\n\treturn io.ReadAll(resp.Body)\n}\n\nfunc loadCertificate(certFile string) (*tls.Certificate, error) {\n\tcacert, err := os.ReadFile(certFile)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar tlsCert tls.Certificate\n\tblock, _ := pem.Decode(cacert)\n\tif block == nil {\n\t\treturn nil, fmt.Errorf(\"unable to Decode certificate\")\n\t}\n\n\tglog.V(2).Info(\"Loading CA certificate\")\n\ttlsCert.Certificate = append(tlsCert.Certificate, block.Bytes)\n\treturn &tlsCert, nil\n}\n\nfunc getKubernetesURL() string {\n\tk8sVersionURL := \"https://kubernetes.default.svc/version\"\n\n\t// The following provides flexibility to use\n\t// K8S provided variables is situations where\n\t// hostNetwork: true\n\tif !isEmpty(os.Getenv(\"KUBE_BENCH_K8S_ENV\")) {\n\t\tk8sHost := os.Getenv(\"KUBERNETES_SERVICE_HOST\")\n\t\tk8sPort := os.Getenv(\"KUBERNETES_SERVICE_PORT_HTTPS\")\n\t\tif !isEmpty(k8sHost) && !isEmpty(k8sPort) {\n\t\t\treturn fmt.Sprintf(\"https://%s:%s/version\", k8sHost, k8sPort)\n\t\t}\n\n\t\tglog.V(2).Info(\"KUBE_BENCH_K8S_ENV is set, but environment variables KUBERNETES_SERVICE_HOST or KUBERNETES_SERVICE_PORT_HTTPS are not set\")\n\t}\n\n\treturn k8sVersionURL\n}\n"
  },
  {
    "path": "cmd/kubernetes_version_test.go",
    "content": "package cmd\n\nimport (\n\t\"crypto/tls\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"os\"\n\t\"strconv\"\n\t\"testing\"\n)\n\nfunc TestLoadCertificate(t *testing.T) {\n\ttmp, err := os.MkdirTemp(\"\", \"TestFakeLoadCertificate\")\n\tif err != nil {\n\t\tt.Fatalf(\"unable to create temp directory: %v\", err)\n\t}\n\tdefer os.RemoveAll(tmp)\n\n\tgoodCertFile, _ := os.CreateTemp(tmp, \"good-cert-*\")\n\t_, _ = goodCertFile.Write([]byte(`-----BEGIN CERTIFICATE-----\nMIICyDCCAbCgAwIBAgIBADANBgkqhkiG9w0BAQsFADAVMRMwEQYDVQQDEwprdWJl\ncm5ldGVzMB4XDTE5MTEwODAxNDAwMFoXDTI5MTEwNTAxNDAwMFowFTETMBEGA1UE\nAxMKa3ViZXJuZXRlczCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMn6\nwjvhMc9e0MDwpQNhp8SPxmv1DsYJ4Btp1GeScIgKKDwppuoOmVizLiMNdV5+70yI\nMgNfm/gwFRNDOtN3R7msfZDD5Dd1vI6qRTP21DFOGVdysFdwqJTs0nGcmfvZEOtw\n9cjcsXrBi2Mg54v+X/pq2w51xajCGBt2+bpxJJ3WBiWqKYv0RQdNL0WZGm+V9BuP\npHRWPBeLxuCzt5K3Gx+1QDy8o6Y4sSRPssWC4RhD9Hs5/9eeGRyZslLs+AuqdDLQ\naziiSjHVtgCfRXE9nYVxaDIwTFuh+Q1IvtB36NRLyX47oya+BbX3PoCtSjA36RBb\ntcJfulr3oNHnb2ZlfcUCAwEAAaMjMCEwDgYDVR0PAQH/BAQDAgKkMA8GA1UdEwEB\n/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAAeQDkbM6DilLkIVQDyxauETgJDV\n2AaVzYaAgDApQGAoYV6WIY7Exk4TlmLeKQjWt2s/GtthQWuzUDKTcEvWcG6gNdXk\ngzuCRRDMGu25NtG3m67w4e2RzW8Z/lzvbfyJZGoV2c6dN+yP9/Pw2MXlrnMWugd1\njLv3UYZRHMpuNS8BJU74BuVzVPHd55RAl+bV8yemdZJ7pPzMvGbZ7zRXWODTDlge\nCQb9lY+jYErisH8Sq7uABFPvi7RaTh8SS7V7OxqHZvmttNTdZs4TIkk45JK7Y+Xq\nFAjB57z2NcIgJuVpQnGRYtr/JcH2Qdsq8bLtXaojUIWOOqoTDRLYozdMOOQ=\n-----END CERTIFICATE-----`))\n\tbadCertFile, _ := os.CreateTemp(tmp, \"bad-cert-*\")\n\n\tcases := []struct {\n\t\tfile string\n\t\tfail bool\n\t}{\n\t\t{\n\t\t\tfile: \"missing cert file\",\n\t\t\tfail: true,\n\t\t},\n\t\t{\n\t\t\tfile: badCertFile.Name(),\n\t\t\tfail: true,\n\t\t},\n\t\t{\n\t\t\tfile: goodCertFile.Name(),\n\t\t\tfail: false,\n\t\t},\n\t}\n\n\tfor id, c := range cases {\n\t\tt.Run(strconv.Itoa(id), func(t *testing.T) {\n\t\t\ttlsCert, err := loadCertificate(c.file)\n\t\t\tif !c.fail {\n\t\t\t\tif err != nil {\n\t\t\t\t\tt.Errorf(\"unexpected error: %v\", err)\n\t\t\t\t}\n\n\t\t\t\tif tlsCert == nil {\n\t\t\t\t\tt.Errorf(\"missing returned TLS Certificate\")\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif err == nil {\n\t\t\t\t\tt.Errorf(\"Expected error\")\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestGetWebData(t *testing.T) {\n\tokfn := func(w http.ResponseWriter, r *http.Request) {\n\t\t_, _ = fmt.Fprintln(w, `{\n\t\t\t\"major\": \"1\",\n\t\t\t\"minor\": \"15\"}`)\n\t}\n\terrfn := func(w http.ResponseWriter, r *http.Request) {\n\t\thttp.Error(w, http.StatusText(http.StatusInternalServerError),\n\t\t\thttp.StatusInternalServerError)\n\t}\n\ttoken := \"dummyToken\"\n\tvar tlsCert tls.Certificate\n\n\tcases := []struct {\n\t\tfn   http.HandlerFunc\n\t\tfail bool\n\t}{\n\t\t{\n\t\t\tfn:   okfn,\n\t\t\tfail: false,\n\t\t},\n\t\t{\n\t\t\tfn:   errfn,\n\t\t\tfail: true,\n\t\t},\n\t}\n\n\tfor id, c := range cases {\n\t\tt.Run(strconv.Itoa(id), func(t *testing.T) {\n\t\t\tts := httptest.NewServer(c.fn)\n\t\t\tdefer ts.Close()\n\t\t\tdata, err := getWebData(ts.URL, token, &tlsCert)\n\t\t\tif !c.fail {\n\t\t\t\tif err != nil {\n\t\t\t\t\tt.Errorf(\"unexpected error: %v\", err)\n\t\t\t\t}\n\n\t\t\t\tif len(data) == 0 {\n\t\t\t\t\tt.Errorf(\"missing data\")\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif err == nil {\n\t\t\t\t\tt.Errorf(\"Expected error\")\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestGetWebDataWithRetry(t *testing.T) {\n\tokfn := func(w http.ResponseWriter, r *http.Request) {\n\t\t_, _ = fmt.Fprintln(w, `{\n\t\t\t\"major\": \"1\",\n\t\t\t\"minor\": \"15\"}`)\n\t}\n\terrfn := func(w http.ResponseWriter, r *http.Request) {\n\t\thttp.Error(w, http.StatusText(http.StatusInternalServerError),\n\t\t\thttp.StatusInternalServerError)\n\t}\n\ttoken := \"dummyToken\"\n\tvar tlsCert tls.Certificate\n\n\tcases := []struct {\n\t\tfn   http.HandlerFunc\n\t\tfail bool\n\t}{\n\t\t{\n\t\t\tfn:   okfn,\n\t\t\tfail: false,\n\t\t},\n\t\t{\n\t\t\tfn:   errfn,\n\t\t\tfail: true,\n\t\t},\n\t}\n\n\tfor id, c := range cases {\n\t\tt.Run(strconv.Itoa(id), func(t *testing.T) {\n\t\t\tts := httptest.NewServer(c.fn)\n\t\t\tdefer ts.Close()\n\t\t\tdata, err := getWebDataWithRetry(ts.URL, token, &tlsCert)\n\t\t\tif !c.fail {\n\t\t\t\tif err != nil {\n\t\t\t\t\tt.Errorf(\"unexpected error: %v\", err)\n\t\t\t\t}\n\n\t\t\t\tif len(data) == 0 {\n\t\t\t\t\tt.Errorf(\"missing data\")\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif err == nil {\n\t\t\t\t\tt.Errorf(\"Expected error\")\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestExtractVersion(t *testing.T) {\n\tokJSON := []byte(`{\n\t\"major\": \"1\",\n\t\"minor\": \"15\",\n\t\"gitVersion\": \"v1.15.3\",\n\t\"gitCommit\": \"2d3c76f9091b6bec110a5e63777c332469e0cba2\",\n\t\"gitTreeState\": \"clean\",\n\t\"buildDate\": \"2019-08-20T18:57:36Z\",\n\t\"goVersion\": \"go1.12.9\",\n\t\"compiler\": \"gc\",\n\t\"platform\": \"linux/amd64\"\n    }`)\n\n\tinvalidJSON := []byte(`{\n\t\"major\": \"1\",\n\t\"minor\": \"15\",\n\t\"gitVersion\": \"v1.15.3\",\n\t\"gitCommit\": \"2d3c76f9091b6bec110a5e63777c332469e0cba2\",\n\t\"gitTreeState\": \"clean\",`)\n\n\tcases := []struct {\n\t\tdata        []byte\n\t\tfail        bool\n\t\texpectedVer string\n\t}{\n\t\t{\n\t\t\tdata:        okJSON,\n\t\t\tfail:        false,\n\t\t\texpectedVer: \"1.15\",\n\t\t},\n\t\t{\n\t\t\tdata: invalidJSON,\n\t\t\tfail: true,\n\t\t},\n\t}\n\n\tfor id, c := range cases {\n\t\tt.Run(strconv.Itoa(id), func(t *testing.T) {\n\t\t\tver, err := extractVersion(c.data)\n\t\t\tif !c.fail {\n\t\t\t\tif err != nil {\n\t\t\t\t\tt.Errorf(\"unexpected error: %v\", err)\n\t\t\t\t}\n\t\t\t\tif c.expectedVer != ver.BaseVersion() {\n\t\t\t\t\tt.Errorf(\"Expected %q but Got %q\", c.expectedVer, ver)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif err == nil {\n\t\t\t\t\tt.Errorf(\"Expected error\")\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestGetKubernetesURL(t *testing.T) {\n\tresetEnvs := func() {\n\t\tos.Unsetenv(\"KUBE_BENCH_K8S_ENV\")\n\t\tos.Unsetenv(\"KUBERNETES_SERVICE_HOST\")\n\t\tos.Unsetenv(\"KUBERNETES_SERVICE_PORT_HTTPS\")\n\t}\n\n\tsetEnvs := func() {\n\t\tos.Setenv(\"KUBE_BENCH_K8S_ENV\", \"1\")\n\t\tos.Setenv(\"KUBERNETES_SERVICE_HOST\", \"testHostServer\")\n\t\tos.Setenv(\"KUBERNETES_SERVICE_PORT_HTTPS\", \"443\")\n\t}\n\n\tcases := []struct {\n\t\tuseDefault bool\n\t\texpected   string\n\t}{\n\t\t{\n\t\t\tuseDefault: true,\n\t\t\texpected:   \"https://kubernetes.default.svc/version\",\n\t\t},\n\t\t{\n\t\t\tuseDefault: false,\n\t\t\texpected:   \"https://testHostServer:443/version\",\n\t\t},\n\t}\n\tfor id, c := range cases {\n\t\tt.Run(strconv.Itoa(id), func(t *testing.T) {\n\t\t\tresetEnvs()\n\t\t\tdefer resetEnvs()\n\t\t\tif !c.useDefault {\n\t\t\t\tsetEnvs()\n\t\t\t}\n\t\t\tk8sURL := getKubernetesURL()\n\n\t\t\tif k8sURL != c.expected {\n\t\t\t\tt.Errorf(\"Expected %q but Got %q\", k8sURL, c.expected)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "cmd/root.go",
    "content": "// Copyright © 2017 Aqua Security Software Ltd. <info@aquasec.com>\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage cmd\n\nimport (\n\tgoflag \"flag\"\n\t\"fmt\"\n\t\"os\"\n\n\t\"github.com/aquasecurity/kube-bench/check\"\n\t\"github.com/golang/glog\"\n\t\"github.com/spf13/cobra\"\n\t\"github.com/spf13/viper\"\n)\n\ntype FilterOpts struct {\n\tCheckList string\n\tGroupList string\n\tScored    bool\n\tUnscored  bool\n}\n\nvar (\n\tenvVarsPrefix        = \"KUBE_BENCH\"\n\tdefaultKubeVersion   = \"1.18\"\n\tkubeVersion          string\n\tdetecetedKubeVersion string\n\tbenchmarkVersion     string\n\tcfgFile              string\n\tcfgDir               = \"./cfg/\"\n\tjsonFmt              bool\n\tjunitFmt             bool\n\tpgSQL                bool\n\taSFF                 bool\n\tmasterFile           = \"master.yaml\"\n\tnodeFile             = \"node.yaml\"\n\tetcdFile             = \"etcd.yaml\"\n\tcontrolplaneFile     = \"controlplane.yaml\"\n\tpoliciesFile         = \"policies.yaml\"\n\tmanagedservicesFile  = \"managedservices.yaml\"\n\texitCode             int\n\tnoResults            bool\n\tnoSummary            bool\n\tnoRemediations       bool\n\tskipIds              string\n\tnoTotals             bool\n\tfilterOpts           FilterOpts\n\tincludeTestOutput    bool\n\toutputFile           string\n\tconfigFileError      error\n\tcontrolsCollection   []*check.Controls\n)\n\n// RootCmd represents the base command when called without any subcommands\nvar RootCmd = &cobra.Command{\n\tUse:   os.Args[0],\n\tShort: \"Run CIS Benchmarks checks against a Kubernetes deployment\",\n\tLong:  `This tool runs the CIS Kubernetes Benchmark (https://www.cisecurity.org/benchmark/kubernetes/)`,\n\tRun: func(cmd *cobra.Command, args []string) {\n\t\tbv, err := getBenchmarkVersion(kubeVersion, benchmarkVersion, getPlatformInfo(), viper.GetViper())\n\t\tif err != nil {\n\t\t\texitWithError(fmt.Errorf(\"unable to determine benchmark version: %v\", err))\n\t\t}\n\t\tglog.V(1).Infof(\"Running checks for benchmark %v\", bv)\n\n\t\tif isMaster() {\n\t\t\tglog.V(1).Info(\"== Running master checks ==\")\n\t\t\trunChecks(check.MASTER, loadConfig(check.MASTER, bv), detecetedKubeVersion)\n\n\t\t\t// Control Plane is only valid for CIS 1.5 and later,\n\t\t\t// this a gatekeeper for previous versions\n\t\t\tvalid, err := validTargets(bv, []string{string(check.CONTROLPLANE)}, viper.GetViper())\n\t\t\tif err != nil {\n\t\t\t\texitWithError(fmt.Errorf(\"error validating targets: %v\", err))\n\t\t\t}\n\t\t\tif valid {\n\t\t\t\tglog.V(1).Info(\"== Running control plane checks ==\")\n\t\t\t\trunChecks(check.CONTROLPLANE, loadConfig(check.CONTROLPLANE, bv), detecetedKubeVersion)\n\t\t\t}\n\t\t} else {\n\t\t\tglog.V(1).Info(\"== Skipping master checks ==\")\n\t\t}\n\n\t\t// Etcd is only valid for CIS 1.5 and later,\n\t\t// this a gatekeeper for previous versions.\n\t\tvalid, err := validTargets(bv, []string{string(check.ETCD)}, viper.GetViper())\n\t\tif err != nil {\n\t\t\texitWithError(fmt.Errorf(\"error validating targets: %v\", err))\n\t\t}\n\t\tif valid && isEtcd() {\n\t\t\tglog.V(1).Info(\"== Running etcd checks ==\")\n\t\t\trunChecks(check.ETCD, loadConfig(check.ETCD, bv), detecetedKubeVersion)\n\t\t} else {\n\t\t\tglog.V(1).Info(\"== Skipping etcd checks ==\")\n\t\t}\n\n\t\tglog.V(1).Info(\"== Running node checks ==\")\n\t\trunChecks(check.NODE, loadConfig(check.NODE, bv), detecetedKubeVersion)\n\n\t\t// Policies is only valid for CIS 1.5 and later,\n\t\t// this a gatekeeper for previous versions.\n\t\tvalid, err = validTargets(bv, []string{string(check.POLICIES)}, viper.GetViper())\n\t\tif err != nil {\n\t\t\texitWithError(fmt.Errorf(\"error validating targets: %v\", err))\n\t\t}\n\t\tif valid {\n\t\t\tglog.V(1).Info(\"== Running policies checks ==\")\n\t\t\trunChecks(check.POLICIES, loadConfig(check.POLICIES, bv), detecetedKubeVersion)\n\t\t} else {\n\t\t\tglog.V(1).Info(\"== Skipping policies checks ==\")\n\t\t}\n\n\t\t// Managedservices is only valid for GKE 1.0 and later,\n\t\t// this a gatekeeper for previous versions.\n\t\tvalid, err = validTargets(bv, []string{string(check.MANAGEDSERVICES)}, viper.GetViper())\n\t\tif err != nil {\n\t\t\texitWithError(fmt.Errorf(\"error validating targets: %v\", err))\n\t\t}\n\t\tif valid {\n\t\t\tglog.V(1).Info(\"== Running managed services checks ==\")\n\t\t\trunChecks(check.MANAGEDSERVICES, loadConfig(check.MANAGEDSERVICES, bv), detecetedKubeVersion)\n\t\t} else {\n\t\t\tglog.V(1).Info(\"== Skipping managed services checks ==\")\n\t\t}\n\n\t\twriteOutput(controlsCollection)\n\t\tos.Exit(exitCodeSelection(controlsCollection))\n\t},\n}\n\n// Execute adds all child commands to the root command sets flags appropriately.\n// This is called by main.main(). It only needs to happen once to the rootCmd.\nfunc Execute() {\n\tgoflag.CommandLine.Parse([]string{})\n\n\tif err := RootCmd.Execute(); err != nil {\n\t\tfmt.Println(err)\n\t\t// flush before exit non-zero\n\t\tglog.Flush()\n\t\tos.Exit(-1)\n\t}\n\t// flush before exit\n\tglog.Flush()\n}\n\nfunc init() {\n\tcobra.OnInitialize(initConfig)\n\n\t// Output control\n\tRootCmd.PersistentFlags().IntVar(&exitCode, \"exit-code\", 0, \"Specify the exit code for when checks fail\")\n\tRootCmd.PersistentFlags().BoolVar(&noResults, \"noresults\", false, \"Disable printing of results section\")\n\tRootCmd.PersistentFlags().BoolVar(&noSummary, \"nosummary\", false, \"Disable printing of summary section\")\n\tRootCmd.PersistentFlags().BoolVar(&noRemediations, \"noremediations\", false, \"Disable printing of remediations section\")\n\tRootCmd.PersistentFlags().BoolVar(&noTotals, \"nototals\", false, \"Disable printing of totals for failed, passed, ... checks across all sections\")\n\tRootCmd.PersistentFlags().BoolVar(&jsonFmt, \"json\", false, \"Prints the results as JSON\")\n\tRootCmd.PersistentFlags().BoolVar(&junitFmt, \"junit\", false, \"Prints the results as JUnit\")\n\tRootCmd.PersistentFlags().BoolVar(&pgSQL, \"pgsql\", false, \"Save the results to PostgreSQL\")\n\tRootCmd.PersistentFlags().BoolVar(&aSFF, \"asff\", false, \"Send the results to AWS Security Hub\")\n\tRootCmd.PersistentFlags().BoolVar(&filterOpts.Scored, \"scored\", true, \"Run the scored CIS checks\")\n\tRootCmd.PersistentFlags().BoolVar(&filterOpts.Unscored, \"unscored\", true, \"Run the unscored CIS checks\")\n\tRootCmd.PersistentFlags().StringVar(&skipIds, \"skip\", \"\", \"List of comma separated values of checks to be skipped\")\n\tRootCmd.PersistentFlags().BoolVar(&includeTestOutput, \"include-test-output\", false, \"Prints the actual result when test fails\")\n\tRootCmd.PersistentFlags().StringVar(&outputFile, \"outputfile\", \"\", \"Writes the results to output file when run with --json or --junit\")\n\n\tRootCmd.PersistentFlags().StringVarP(\n\t\t&filterOpts.CheckList,\n\t\t\"check\",\n\t\t\"c\",\n\t\t\"\",\n\t\t`A comma-delimited list of checks to run as specified in CIS document. Example --check=\"1.1.1,1.1.2\"`,\n\t)\n\tRootCmd.PersistentFlags().StringVarP(\n\t\t&filterOpts.GroupList,\n\t\t\"group\",\n\t\t\"g\",\n\t\t\"\",\n\t\t`Run all the checks under this comma-delimited list of groups. Example --group=\"1.1\"`,\n\t)\n\tRootCmd.PersistentFlags().StringVar(&cfgFile, \"config\", \"\", \"config file (default is ./cfg/config.yaml)\")\n\tRootCmd.PersistentFlags().StringVarP(&cfgDir, \"config-dir\", \"D\", cfgDir, \"config directory\")\n\tRootCmd.PersistentFlags().StringVar(&kubeVersion, \"version\", \"\", \"Manually specify Kubernetes version, automatically detected if unset\")\n\tRootCmd.PersistentFlags().StringVar(&benchmarkVersion, \"benchmark\", \"\", \"Manually specify CIS benchmark version. It would be an error to specify both --version and --benchmark flags\")\n\n\tif err := goflag.Set(\"logtostderr\", \"true\"); err != nil {\n\t\tfmt.Printf(\"unable to set logtostderr: %+v\\n\", err)\n\t\tos.Exit(-1)\n\t}\n\tgoflag.CommandLine.VisitAll(func(goflag *goflag.Flag) {\n\t\tRootCmd.PersistentFlags().AddGoFlag(goflag)\n\t})\n}\n\n// initConfig reads in config file and ENV variables if set.\nfunc initConfig() {\n\tif cfgFile != \"\" { // enable ability to specify config file via flag\n\t\tviper.SetConfigFile(cfgFile)\n\t} else {\n\t\tviper.SetConfigName(\"config\") // name of config file (without extension)\n\t\tviper.AddConfigPath(cfgDir)   // adding ./cfg as first search path\n\t}\n\n\t// Read flag values from environment variables.\n\t// Precedence: Command line flags take precedence over environment variables.\n\tviper.SetEnvPrefix(envVarsPrefix)\n\tviper.AutomaticEnv()\n\n\tif kubeVersion == \"\" {\n\t\tif env := viper.Get(\"version\"); env != nil {\n\t\t\tkubeVersion = env.(string)\n\t\t}\n\t}\n\n\t// If a config file is found, read it in.\n\tif err := viper.ReadInConfig(); err != nil {\n\t\tif _, ok := err.(viper.ConfigFileNotFoundError); ok {\n\t\t\t// Config file not found; ignore error for now to prevent commands\n\t\t\t// which don't need the config file exiting.\n\t\t\tconfigFileError = err\n\t\t} else {\n\t\t\t// Config file was found but another error was produced\n\t\t\tcolorPrint(check.FAIL, fmt.Sprintf(\"Failed to read config file: %v\\n\", err))\n\t\t\tos.Exit(1)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "cmd/run.go",
    "content": "package cmd\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\n\t\"github.com/aquasecurity/kube-bench/check\"\n\t\"github.com/golang/glog\"\n\t\"github.com/spf13/cobra\"\n\t\"github.com/spf13/viper\"\n)\n\nfunc init() {\n\tRootCmd.AddCommand(runCmd)\n\trunCmd.Flags().StringSliceP(\"targets\", \"s\", []string{},\n\t\t`Specify targets of the benchmark to run. These names need to match the filenames in the cfg/<version> directory.\n\tFor example, to run the tests specified in master.yaml and etcd.yaml, specify --targets=master,etcd\n\tIf no targets are specified, run tests from all files in the cfg/<version> directory.\n\t`)\n}\n\n// runCmd represents the run command\nvar runCmd = &cobra.Command{\n\tUse:   \"run\",\n\tShort: \"Run tests\",\n\tLong:  `Run tests. If no arguments are specified, runs tests from all files`,\n\tRun: func(cmd *cobra.Command, args []string) {\n\t\ttargets, err := cmd.Flags().GetStringSlice(\"targets\")\n\t\tif err != nil {\n\t\t\texitWithError(fmt.Errorf(\"unable to get `targets` from command line :%v\", err))\n\t\t}\n\n\t\tbv, err := getBenchmarkVersion(kubeVersion, benchmarkVersion, getPlatformInfo(), viper.GetViper())\n\t\tif err != nil {\n\t\t\texitWithError(fmt.Errorf(\"unable to get benchmark version. error: %v\", err))\n\t\t}\n\n\t\tglog.V(2).Infof(\"Checking targets %v for %v\", targets, bv)\n\t\tbenchmarkVersionToTargetsMap, err := loadTargetMapping(viper.GetViper())\n\t\tif err != nil {\n\t\t\texitWithError(fmt.Errorf(\"error loading targets: %v\", err))\n\t\t}\n\t\tvalid, err := validTargets(bv, targets, viper.GetViper())\n\t\tif err != nil {\n\t\t\texitWithError(fmt.Errorf(\"error validating targets: %v\", err))\n\t\t}\n\t\tif len(targets) > 0 && !valid {\n\t\t\texitWithError(fmt.Errorf(`The specified --targets \"%s\" are not configured for the CIS Benchmark %s\\n Valid targets %v`, strings.Join(targets, \",\"), bv, benchmarkVersionToTargetsMap[bv]))\n\t\t}\n\n\t\t// Merge version-specific config if any.\n\t\tpath := filepath.Join(cfgDir, bv)\n\t\terr = mergeConfig(path)\n\t\tif err != nil {\n\t\t\texitWithError(fmt.Errorf(\"Error in mergeConfig: %v\\n\", err))\n\t\t}\n\n\t\terr = run(targets, bv)\n\t\tif err != nil {\n\t\t\texitWithError(fmt.Errorf(\"Error in run: %v\\n\", err))\n\t\t}\n\n\t\tos.Exit(exitCodeSelection(controlsCollection))\n\t},\n}\n\nfunc run(targets []string, benchmarkVersion string) (err error) {\n\tyamlFiles, err := getTestYamlFiles(targets, benchmarkVersion)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tglog.V(3).Infof(\"Running tests from files %v\\n\", yamlFiles)\n\n\tfor _, yamlFile := range yamlFiles {\n\t\t_, name := filepath.Split(yamlFile)\n\t\ttestType := check.NodeType(strings.Split(name, \".\")[0])\n\t\trunChecks(testType, yamlFile, detecetedKubeVersion)\n\t}\n\n\twriteOutput(controlsCollection)\n\treturn nil\n}\n\nfunc getTestYamlFiles(targets []string, benchmarkVersion string) (yamlFiles []string, err error) {\n\t// Check that the specified targets have corresponding YAML files in the config directory\n\tconfigFileDirectory := filepath.Join(cfgDir, benchmarkVersion)\n\tfor _, target := range targets {\n\t\tfilename := translate(target) + \".yaml\"\n\t\tfile := filepath.Join(configFileDirectory, filename)\n\t\tif _, err := os.Stat(file); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"file %s not found for version %s\", filename, benchmarkVersion)\n\t\t}\n\t\tyamlFiles = append(yamlFiles, file)\n\t}\n\n\t// If no targets were specified, we will run tests from all the files in the directory\n\tif len(yamlFiles) == 0 {\n\t\tyamlFiles, err = getYamlFilesFromDir(configFileDirectory)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\treturn yamlFiles, err\n}\n\nfunc translate(target string) string {\n\treturn strings.Replace(strings.ToLower(target), \"worker\", \"node\", -1)\n}\n"
  },
  {
    "path": "cmd/run_test.go",
    "content": "package cmd\n\nimport (\n\t\"os\"\n\t\"path/filepath\"\n\t\"testing\"\n)\n\nfunc TestGetTestYamlFiles(t *testing.T) {\n\tcases := []struct {\n\t\tname      string\n\t\ttargets   []string\n\t\tbenchmark string\n\t\tsucceed   bool\n\t\texpCount  int\n\t}{\n\t\t{\n\t\t\tname:      \"Specify two targets\",\n\t\t\ttargets:   []string{\"one\", \"two\"},\n\t\t\tbenchmark: \"benchmark\",\n\t\t\tsucceed:   true,\n\t\t\texpCount:  2,\n\t\t},\n\t\t{\n\t\t\tname:      \"Specify a target that doesn't exist\",\n\t\t\ttargets:   []string{\"one\", \"missing\"},\n\t\t\tbenchmark: \"benchmark\",\n\t\t\tsucceed:   false,\n\t\t},\n\t\t{\n\t\t\tname:      \"No targets specified - should return everything except config.yaml\",\n\t\t\ttargets:   []string{},\n\t\t\tbenchmark: \"benchmark\",\n\t\t\tsucceed:   true,\n\t\t\texpCount:  3,\n\t\t},\n\t\t{\n\t\t\tname:      \"Specify benchmark that doesn't exist\",\n\t\t\ttargets:   []string{\"one\"},\n\t\t\tbenchmark: \"missing\",\n\t\t\tsucceed:   false,\n\t\t},\n\t}\n\n\t// Set up temp config directory\n\tvar err error\n\tcfgDir, err = os.MkdirTemp(\"\", \"kube-bench-test\")\n\tif err != nil {\n\t\tt.Fatalf(\"Failed to create temp directory\")\n\t}\n\tdefer os.RemoveAll(cfgDir)\n\n\td := filepath.Join(cfgDir, \"benchmark\")\n\terr = os.Mkdir(d, 0766)\n\tif err != nil {\n\t\tt.Fatalf(\"Failed to create temp dir\")\n\t}\n\n\t// We never expect config.yaml to be returned\n\tfor _, filename := range []string{\"one.yaml\", \"two.yaml\", \"three.yaml\", \"config.yaml\"} {\n\t\terr = os.WriteFile(filepath.Join(d, filename), []byte(\"hello world\"), 0666)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"error writing temp file %s: %v\", filename, err)\n\t\t}\n\t}\n\n\tfor _, c := range cases {\n\t\tt.Run(c.name, func(t *testing.T) {\n\t\t\tyamlFiles, err := getTestYamlFiles(c.targets, c.benchmark)\n\t\t\tif err != nil && c.succeed {\n\t\t\t\tt.Fatalf(\"Error %v\", err)\n\t\t\t}\n\n\t\t\tif err == nil && !c.succeed {\n\t\t\t\tt.Fatalf(\"Expected failure\")\n\t\t\t}\n\n\t\t\tif len(yamlFiles) != c.expCount {\n\t\t\t\tt.Fatalf(\"Expected %d, got %d\", c.expCount, len(yamlFiles))\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestTranslate(t *testing.T) {\n\tcases := []struct {\n\t\tname     string\n\t\toriginal string\n\t\texpected string\n\t}{\n\t\t{\n\t\t\tname:     \"keep\",\n\t\t\toriginal: \"controlplane\",\n\t\t\texpected: \"controlplane\",\n\t\t},\n\t\t{\n\t\t\tname:     \"translate\",\n\t\t\toriginal: \"worker\",\n\t\t\texpected: \"node\",\n\t\t},\n\t\t{\n\t\t\tname:     \"translateLower\",\n\t\t\toriginal: \"Worker\",\n\t\t\texpected: \"node\",\n\t\t},\n\t\t{\n\t\t\tname:     \"Lower\",\n\t\t\toriginal: \"ETCD\",\n\t\t\texpected: \"etcd\",\n\t\t},\n\t}\n\n\tfor _, c := range cases {\n\t\tt.Run(c.name, func(t *testing.T) {\n\t\t\tret := translate(c.original)\n\t\t\tif ret != c.expected {\n\t\t\t\tt.Fatalf(\"Expected %q, got %q\", c.expected, ret)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "cmd/securityHub.go",
    "content": "package cmd\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\n\t\"github.com/aquasecurity/kube-bench/internal/findings\"\n\t\"github.com/aws/aws-sdk-go-v2/config\"\n\t\"github.com/aws/aws-sdk-go-v2/service/securityhub\"\n\t\"github.com/aws/aws-sdk-go-v2/service/securityhub/types\"\n\t\"github.com/spf13/viper\"\n)\n\n// REGION ...\nconst REGION = \"AWS_REGION\"\n\nfunc writeFinding(in []types.AwsSecurityFinding) error {\n\tr := viper.GetString(REGION)\n\tif len(r) == 0 {\n\t\treturn fmt.Errorf(\"%s not set\", REGION)\n\t}\n\tcfg, err := config.LoadDefaultConfig(context.Background(), config.WithRegion(r))\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tsvc := securityhub.NewFromConfig(cfg)\n\tp := findings.New(*svc)\n\tout, perr := p.PublishFinding(in)\n\tprint(out)\n\treturn perr\n}\n\nfunc print(out *findings.PublisherOutput) {\n\tif out.SuccessCount > 0 {\n\t\tlog.Printf(\"Number of findings that were successfully imported:%v\\n\", out.SuccessCount)\n\t}\n\tif out.FailedCount > 0 {\n\t\tlog.Printf(\"Number of findings that failed to import:%v\\n\", out.FailedCount)\n\t\tfor _, f := range out.FailedFindings {\n\t\t\tlog.Printf(\"ID:%s\", *f.Id)\n\t\t\tlog.Printf(\"Message:%s\", *f.ErrorMessage)\n\t\t\tlog.Printf(\"Error Code:%s\", *f.ErrorCode)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "cmd/testdata/controlsCollection.json",
    "content": "[\n  {\n    \"id\": \"2\",\n    \"version\": \"1.15\",\n    \"text\": \"Etcd Node Configuration\",\n    \"node_type\": \"etcd\",\n    \"tests\": [\n      {\n        \"section\": \"2\",\n        \"pass\": 7,\n        \"fail\": 0,\n        \"warn\": 0,\n        \"info\": 0,\n        \"desc\": \"Etcd Node Configuration Files\",\n        \"results\": [\n          {\n            \"test_number\": \"2.1\",\n            \"test_desc\": \"Ensure that the --cert-file and --key-file arguments are set as appropriate (Scored)\",\n            \"audit\": \"/bin/ps -ef | /bin/grep etcd | /bin/grep -v grep\",\n            \"AuditConfig\": \"\",\n            \"type\": \"\",\n            \"remediation\": \"Follow the etcd service documentation and configure TLS encryption.\\nThen, edit the etcd pod specification file /etc/kubernetes/manifests/etcd.yaml\\non the master node and set the below parameters.\\n--cert-file=</path/to/ca-file>\\n--key-file=</path/to/key-file>\\n\",\n            \"test_info\": [\n              \"Follow the etcd service documentation and configure TLS encryption.\\nThen, edit the etcd pod specification file /etc/kubernetes/manifests/etcd.yaml\\non the master node and set the below parameters.\\n--cert-file=</path/to/ca-file>\\n--key-file=</path/to/key-file>\\n\"\n            ],\n            \"status\": \"PASS\",\n            \"actual_value\": \"root      3277  3218  3 Apr19 ?        03:57:52 etcd --advertise-client-urls=https://192.168.64.4:2379 --cert-file=/var/lib/minikube/certs/etcd/server.crt --client-cert-auth=true --data-dir=/var/lib/minikube/etcd --initial-advertise-peer-urls=https://192.168.64.4:2380 --initial-cluster=minikube=https://192.168.64.4:2380 --key-file=/var/lib/minikube/certs/etcd/server.key --listen-client-urls=https://127.0.0.1:2379,https://192.168.64.4:2379 --listen-metrics-urls=http://127.0.0.1:2381 --listen-peer-urls=https://192.168.64.4:2380 --name=minikube --peer-cert-file=/var/lib/minikube/certs/etcd/peer.crt --peer-client-cert-auth=true --peer-key-file=/var/lib/minikube/certs/etcd/peer.key --peer-trusted-ca-file=/var/lib/minikube/certs/etcd/ca.crt --snapshot-count=10000 --trusted-ca-file=/var/lib/minikube/certs/etcd/ca.crt\\nroot      4624  4605  8 Apr21 ?        04:55:10 kube-apiserver --advertise-address=192.168.64.4 --allow-privileged=true --authorization-mode=Node,RBAC --client-ca-file=/var/lib/minikube/certs/ca.crt --enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota,PodSecurityPolicy --enable-bootstrap-token-auth=true --etcd-cafile=/var/lib/minikube/certs/etcd/ca.crt --etcd-certfile=/var/lib/minikube/certs/apiserver-etcd-client.crt --etcd-keyfile=/var/lib/minikube/certs/apiserver-etcd-client.key --etcd-servers=https://127.0.0.1:2379 --insecure-port=0 --kubelet-client-certificate=/var/lib/minikube/certs/apiserver-kubelet-client.crt --kubelet-client-key=/var/lib/minikube/certs/apiserver-kubelet-client.key --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname --proxy-client-cert-file=/var/lib/minikube/certs/front-proxy-client.crt --proxy-client-key-file=/var/lib/minikube/certs/front-proxy-client.key --requestheader-allowed-names=front-proxy-client --requestheader-client-ca-file=/var/lib/minikube/certs/front-proxy-ca.crt --requestheader-extra-headers-prefix=X-Remote-Extra- --requestheader-group-headers=X-Remote-Group --requestheader-username-headers=X-Remote-User --secure-port=8443 --service-account-key-file=/var/lib/minikube/certs/sa.pub --service-cluster-ip-range=10.96.0.0/12 --tls-cert-file=/var/lib/minikube/certs/apiserver.crt --tls-private-key-file=/var/lib/minikube/certs/apiserver.key\\n\",\n            \"scored\": true,\n            \"expected_result\": \"'--cert-file' is present AND '--key-file' is present\"\n          }\n        ]\n      }\n    ],\n    \"total_pass\": 7,\n    \"total_fail\": 0,\n    \"total_warn\": 0,\n    \"total_info\": 0\n  },\n  {\n    \"id\": \"3\",\n    \"version\": \"1.5\",\n    \"text\": \"Control Plane Configuration\",\n    \"node_type\": \"controlplane\",\n    \"tests\": [\n      {\n        \"section\": \"3.1\",\n        \"pass\": 0,\n        \"fail\": 0,\n        \"warn\": 1,\n        \"info\": 0,\n        \"desc\": \"Authentication and Authorization\",\n        \"results\": [\n          {\n            \"test_number\": \"3.1.1\",\n            \"test_desc\": \"Client certificate authentication should not be used for users (Not Scored)\",\n            \"audit\": \"\",\n            \"AuditConfig\": \"\",\n            \"type\": \"manual\",\n            \"remediation\": \"Alternative mechanisms provided by Kubernetes such as the use of OIDC should be\\nimplemented in place of client certificates.\\n\",\n            \"test_info\": [\n              \"Alternative mechanisms provided by Kubernetes such as the use of OIDC should be\\nimplemented in place of client certificates.\\n\"\n            ],\n            \"status\": \"WARN\",\n            \"actual_value\": \"\",\n            \"scored\": false,\n            \"expected_result\": \"\",\n            \"reason\": \"Test marked as a manual test\"\n          }\n        ]\n      }\n    ],\n    \"total_pass\": 0,\n    \"total_fail\": 0,\n    \"total_warn\": 3,\n    \"total_info\": 0\n  },\n  {\n    \"id\": \"1\",\n    \"version\": \"1.5\",\n    \"text\": \"Master Node Security Configuration\",\n    \"node_type\": \"master\",\n    \"tests\": [\n      {\n        \"section\": \"1.1\",\n        \"pass\": 15,\n        \"fail\": 1,\n        \"warn\": 5,\n        \"info\": 0,\n        \"desc\": \"Master Node Configuration Files\",\n        \"results\": [\n          {\n            \"test_number\": \"1.1.1\",\n            \"test_desc\": \"Ensure that the API server pod specification file permissions are set to 644 or more restrictive (Scored)\",\n            \"audit\": \"/bin/sh -c 'if test -e /etc/kubernetes/manifests/kube-apiserver.yaml; then stat -c permissions=%a /etc/kubernetes/manifests/kube-apiserver.yaml; fi'\",\n            \"AuditConfig\": \"\",\n            \"type\": \"\",\n            \"remediation\": \"Run the below command (based on the file location on your system) on the\\nmaster node.\\nFor example, chmod 644 /etc/kubernetes/manifests/kube-apiserver.yaml\\n\",\n            \"test_info\": [\n              \"Run the below command (based on the file location on your system) on the\\nmaster node.\\nFor example, chmod 644 /etc/kubernetes/manifests/kube-apiserver.yaml\\n\"\n            ],\n            \"status\": \"PASS\",\n            \"actual_value\": \"permissions=600\\n\",\n            \"scored\": true,\n            \"expected_result\": \"bitmask '600' AND '644'\"\n          }\n        ]\n      }\n    ],\n    \"total_pass\": 42,\n    \"total_fail\": 12,\n    \"total_warn\": 11,\n    \"total_info\": 0\n  }\n]"
  },
  {
    "path": "cmd/testdata/passedControlsCollection.json",
    "content": "[\n  {\n    \"id\": \"2\",\n    \"version\": \"1.15\",\n    \"text\": \"Etcd Node Configuration\",\n    \"node_type\": \"etcd\",\n    \"tests\": [\n      {\n        \"section\": \"2\",\n        \"pass\": 7,\n        \"fail\": 0,\n        \"warn\": 0,\n        \"info\": 0,\n        \"desc\": \"Etcd Node Configuration Files\",\n        \"results\": [\n          {\n            \"test_number\": \"2.1\",\n            \"test_desc\": \"Ensure that the --cert-file and --key-file arguments are set as appropriate (Scored)\",\n            \"audit\": \"/bin/ps -ef | /bin/grep etcd | /bin/grep -v grep\",\n            \"AuditConfig\": \"\",\n            \"type\": \"\",\n            \"remediation\": \"Follow the etcd service documentation and configure TLS encryption.\\nThen, edit the etcd pod specification file /etc/kubernetes/manifests/etcd.yaml\\non the master node and set the below parameters.\\n--cert-file=</path/to/ca-file>\\n--key-file=</path/to/key-file>\\n\",\n            \"test_info\": [\n              \"Follow the etcd service documentation and configure TLS encryption.\\nThen, edit the etcd pod specification file /etc/kubernetes/manifests/etcd.yaml\\non the master node and set the below parameters.\\n--cert-file=</path/to/ca-file>\\n--key-file=</path/to/key-file>\\n\"\n            ],\n            \"status\": \"PASS\",\n            \"actual_value\": \"root      3277  3218  3 Apr19 ?        03:57:52 etcd --advertise-client-urls=https://192.168.64.4:2379 --cert-file=/var/lib/minikube/certs/etcd/server.crt --client-cert-auth=true --data-dir=/var/lib/minikube/etcd --initial-advertise-peer-urls=https://192.168.64.4:2380 --initial-cluster=minikube=https://192.168.64.4:2380 --key-file=/var/lib/minikube/certs/etcd/server.key --listen-client-urls=https://127.0.0.1:2379,https://192.168.64.4:2379 --listen-metrics-urls=http://127.0.0.1:2381 --listen-peer-urls=https://192.168.64.4:2380 --name=minikube --peer-cert-file=/var/lib/minikube/certs/etcd/peer.crt --peer-client-cert-auth=true --peer-key-file=/var/lib/minikube/certs/etcd/peer.key --peer-trusted-ca-file=/var/lib/minikube/certs/etcd/ca.crt --snapshot-count=10000 --trusted-ca-file=/var/lib/minikube/certs/etcd/ca.crt\\nroot      4624  4605  8 Apr21 ?        04:55:10 kube-apiserver --advertise-address=192.168.64.4 --allow-privileged=true --authorization-mode=Node,RBAC --client-ca-file=/var/lib/minikube/certs/ca.crt --enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota,PodSecurityPolicy --enable-bootstrap-token-auth=true --etcd-cafile=/var/lib/minikube/certs/etcd/ca.crt --etcd-certfile=/var/lib/minikube/certs/apiserver-etcd-client.crt --etcd-keyfile=/var/lib/minikube/certs/apiserver-etcd-client.key --etcd-servers=https://127.0.0.1:2379 --insecure-port=0 --kubelet-client-certificate=/var/lib/minikube/certs/apiserver-kubelet-client.crt --kubelet-client-key=/var/lib/minikube/certs/apiserver-kubelet-client.key --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname --proxy-client-cert-file=/var/lib/minikube/certs/front-proxy-client.crt --proxy-client-key-file=/var/lib/minikube/certs/front-proxy-client.key --requestheader-allowed-names=front-proxy-client --requestheader-client-ca-file=/var/lib/minikube/certs/front-proxy-ca.crt --requestheader-extra-headers-prefix=X-Remote-Extra- --requestheader-group-headers=X-Remote-Group --requestheader-username-headers=X-Remote-User --secure-port=8443 --service-account-key-file=/var/lib/minikube/certs/sa.pub --service-cluster-ip-range=10.96.0.0/12 --tls-cert-file=/var/lib/minikube/certs/apiserver.crt --tls-private-key-file=/var/lib/minikube/certs/apiserver.key\\n\",\n            \"scored\": true,\n            \"expected_result\": \"'--cert-file' is present AND '--key-file' is present\"\n          }\n        ]\n      }\n    ],\n    \"total_pass\": 7,\n    \"total_fail\": 0,\n    \"total_warn\": 0,\n    \"total_info\": 0\n  },\n  {\n    \"id\": \"3\",\n    \"version\": \"1.5\",\n    \"text\": \"Control Plane Configuration\",\n    \"node_type\": \"controlplane\",\n    \"tests\": [\n      {\n        \"section\": \"3.1\",\n        \"pass\": 0,\n        \"fail\": 0,\n        \"warn\": 1,\n        \"info\": 0,\n        \"desc\": \"Authentication and Authorization\",\n        \"results\": [\n          {\n            \"test_number\": \"3.1.1\",\n            \"test_desc\": \"Client certificate authentication should not be used for users (Not Scored)\",\n            \"audit\": \"\",\n            \"AuditConfig\": \"\",\n            \"type\": \"manual\",\n            \"remediation\": \"Alternative mechanisms provided by Kubernetes such as the use of OIDC should be\\nimplemented in place of client certificates.\\n\",\n            \"test_info\": [\n              \"Alternative mechanisms provided by Kubernetes such as the use of OIDC should be\\nimplemented in place of client certificates.\\n\"\n            ],\n            \"status\": \"WARN\",\n            \"actual_value\": \"\",\n            \"scored\": false,\n            \"expected_result\": \"\",\n            \"reason\": \"Test marked as a manual test\"\n          }\n        ]\n      }\n    ],\n    \"total_pass\": 0,\n    \"total_fail\": 0,\n    \"total_warn\": 3,\n    \"total_info\": 0\n  }\n]\n"
  },
  {
    "path": "cmd/testdata/result.json",
    "content": "{\n  \"Controls\": [\n    {\n      \"id\": \"1\",\n      \"version\": \"1.5\",\n      \"text\": \"Master Node Security Configuration\",\n      \"node_type\": \"master\",\n      \"tests\": [\n        {\n          \"section\": \"1.1\",\n          \"pass\": 15,\n          \"fail\": 1,\n          \"warn\": 5,\n          \"info\": 0,\n          \"desc\": \"Master Node Configuration Files\",\n          \"results\": [\n            {\n              \"test_number\": \"1.1.1\",\n              \"test_desc\": \"Ensure that the API server pod specification file permissions are set to 644 or more restrictive (Scored)\",\n              \"audit\": \"/bin/sh -c 'if test -e /etc/kubernetes/manifests/kube-apiserver.yaml; then stat -c permissions=%a /etc/kubernetes/manifests/kube-apiserver.yaml; fi'\",\n              \"AuditConfig\": \"\",\n              \"type\": \"\",\n              \"remediation\": \"Run the below command (based on the file location on your system) on the\\nmaster node.\\nFor example, chmod 644 /etc/kubernetes/manifests/kube-apiserver.yaml\\n\",\n              \"test_info\": [\n                \"Run the below command (based on the file location on your system) on the\\nmaster node.\\nFor example, chmod 644 /etc/kubernetes/manifests/kube-apiserver.yaml\\n\"\n              ],\n              \"status\": \"PASS\",\n              \"actual_value\": \"permissions=600\\n\",\n              \"scored\": true,\n              \"expected_result\": \"bitmask '600' AND '644'\"\n            }\n          ]\n        }\n      ],\n      \"total_pass\": 42,\n      \"total_fail\": 12,\n      \"total_warn\": 11,\n      \"total_info\": 0\n    },\n    {\n      \"id\": \"2\",\n      \"version\": \"1.15\",\n      \"text\": \"Etcd Node Configuration\",\n      \"node_type\": \"etcd\",\n      \"tests\": [\n        {\n          \"section\": \"2\",\n          \"pass\": 7,\n          \"fail\": 0,\n          \"warn\": 0,\n          \"info\": 0,\n          \"desc\": \"Etcd Node Configuration Files\",\n          \"results\": [\n            {\n              \"test_number\": \"2.1\",\n              \"test_desc\": \"Ensure that the --cert-file and --key-file arguments are set as appropriate (Scored)\",\n              \"audit\": \"/bin/ps -ef | /bin/grep etcd | /bin/grep -v grep\",\n              \"AuditConfig\": \"\",\n              \"type\": \"\",\n              \"remediation\": \"Follow the etcd service documentation and configure TLS encryption.\\nThen, edit the etcd pod specification file /etc/kubernetes/manifests/etcd.yaml\\non the master node and set the below parameters.\\n--cert-file=</path/to/ca-file>\\n--key-file=</path/to/key-file>\\n\",\n              \"test_info\": [\n                \"Follow the etcd service documentation and configure TLS encryption.\\nThen, edit the etcd pod specification file /etc/kubernetes/manifests/etcd.yaml\\non the master node and set the below parameters.\\n--cert-file=</path/to/ca-file>\\n--key-file=</path/to/key-file>\\n\"\n              ],\n              \"status\": \"PASS\",\n              \"actual_value\": \"root      3277  3218  3 Apr19 ?        03:57:52 etcd --advertise-client-urls=https://192.168.64.4:2379 --cert-file=/var/lib/minikube/certs/etcd/server.crt --client-cert-auth=true --data-dir=/var/lib/minikube/etcd --initial-advertise-peer-urls=https://192.168.64.4:2380 --initial-cluster=minikube=https://192.168.64.4:2380 --key-file=/var/lib/minikube/certs/etcd/server.key --listen-client-urls=https://127.0.0.1:2379,https://192.168.64.4:2379 --listen-metrics-urls=http://127.0.0.1:2381 --listen-peer-urls=https://192.168.64.4:2380 --name=minikube --peer-cert-file=/var/lib/minikube/certs/etcd/peer.crt --peer-client-cert-auth=true --peer-key-file=/var/lib/minikube/certs/etcd/peer.key --peer-trusted-ca-file=/var/lib/minikube/certs/etcd/ca.crt --snapshot-count=10000 --trusted-ca-file=/var/lib/minikube/certs/etcd/ca.crt\\nroot      4624  4605  8 Apr21 ?        04:55:10 kube-apiserver --advertise-address=192.168.64.4 --allow-privileged=true --authorization-mode=Node,RBAC --client-ca-file=/var/lib/minikube/certs/ca.crt --enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota,PodSecurityPolicy --enable-bootstrap-token-auth=true --etcd-cafile=/var/lib/minikube/certs/etcd/ca.crt --etcd-certfile=/var/lib/minikube/certs/apiserver-etcd-client.crt --etcd-keyfile=/var/lib/minikube/certs/apiserver-etcd-client.key --etcd-servers=https://127.0.0.1:2379 --insecure-port=0 --kubelet-client-certificate=/var/lib/minikube/certs/apiserver-kubelet-client.crt --kubelet-client-key=/var/lib/minikube/certs/apiserver-kubelet-client.key --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname --proxy-client-cert-file=/var/lib/minikube/certs/front-proxy-client.crt --proxy-client-key-file=/var/lib/minikube/certs/front-proxy-client.key --requestheader-allowed-names=front-proxy-client --requestheader-client-ca-file=/var/lib/minikube/certs/front-proxy-ca.crt --requestheader-extra-headers-prefix=X-Remote-Extra- --requestheader-group-headers=X-Remote-Group --requestheader-username-headers=X-Remote-User --secure-port=8443 --service-account-key-file=/var/lib/minikube/certs/sa.pub --service-cluster-ip-range=10.96.0.0/12 --tls-cert-file=/var/lib/minikube/certs/apiserver.crt --tls-private-key-file=/var/lib/minikube/certs/apiserver.key\\n\",\n              \"scored\": true,\n              \"expected_result\": \"'--cert-file' is present AND '--key-file' is present\"\n            }\n          ]\n        }\n      ],\n      \"total_pass\": 7,\n      \"total_fail\": 0,\n      \"total_warn\": 0,\n      \"total_info\": 0\n    },\n    {\n      \"id\": \"3\",\n      \"version\": \"1.5\",\n      \"text\": \"Control Plane Configuration\",\n      \"node_type\": \"controlplane\",\n      \"tests\": [\n        {\n          \"section\": \"3.1\",\n          \"pass\": 0,\n          \"fail\": 0,\n          \"warn\": 1,\n          \"info\": 0,\n          \"desc\": \"Authentication and Authorization\",\n          \"results\": [\n            {\n              \"test_number\": \"3.1.1\",\n              \"test_desc\": \"Client certificate authentication should not be used for users (Not Scored)\",\n              \"audit\": \"\",\n              \"AuditConfig\": \"\",\n              \"type\": \"manual\",\n              \"remediation\": \"Alternative mechanisms provided by Kubernetes such as the use of OIDC should be\\nimplemented in place of client certificates.\\n\",\n              \"test_info\": [\n                \"Alternative mechanisms provided by Kubernetes such as the use of OIDC should be\\nimplemented in place of client certificates.\\n\"\n              ],\n              \"status\": \"WARN\",\n              \"actual_value\": \"\",\n              \"scored\": false,\n              \"expected_result\": \"\",\n              \"reason\": \"Test marked as a manual test\"\n            }\n          ]\n        }\n      ],\n      \"total_pass\": 0,\n      \"total_fail\": 0,\n      \"total_warn\": 3,\n      \"total_info\": 0\n    }\n  ],\n  \"Totals\": {\n    \"total_pass\": 49,\n    \"total_fail\": 12,\n    \"total_warn\": 14,\n    \"total_info\": 0\n  }\n}\n"
  },
  {
    "path": "cmd/testdata/result_no_totals.json",
    "content": "[\n  {\n    \"id\": \"1\",\n    \"version\": \"1.5\",\n    \"text\": \"Master Node Security Configuration\",\n    \"node_type\": \"master\",\n    \"tests\": [\n      {\n        \"section\": \"1.1\",\n        \"pass\": 15,\n        \"fail\": 1,\n        \"warn\": 5,\n        \"info\": 0,\n        \"desc\": \"Master Node Configuration Files\",\n        \"results\": [\n          {\n            \"test_number\": \"1.1.1\",\n            \"test_desc\": \"Ensure that the API server pod specification file permissions are set to 644 or more restrictive (Scored)\",\n            \"audit\": \"/bin/sh -c 'if test -e /etc/kubernetes/manifests/kube-apiserver.yaml; then stat -c permissions=%a /etc/kubernetes/manifests/kube-apiserver.yaml; fi'\",\n            \"AuditConfig\": \"\",\n            \"type\": \"\",\n            \"remediation\": \"Run the below command (based on the file location on your system) on the\\nmaster node.\\nFor example, chmod 644 /etc/kubernetes/manifests/kube-apiserver.yaml\\n\",\n            \"test_info\": [\n              \"Run the below command (based on the file location on your system) on the\\nmaster node.\\nFor example, chmod 644 /etc/kubernetes/manifests/kube-apiserver.yaml\\n\"\n            ],\n            \"status\": \"PASS\",\n            \"actual_value\": \"permissions=600\\n\",\n            \"scored\": true,\n            \"expected_result\": \"bitmask '600' AND '644'\"\n          }\n        ]\n      }\n    ],\n    \"total_pass\": 42,\n    \"total_fail\": 12,\n    \"total_warn\": 11,\n    \"total_info\": 0\n  },\n  {\n    \"id\": \"2\",\n    \"version\": \"1.15\",\n    \"text\": \"Etcd Node Configuration\",\n    \"node_type\": \"etcd\",\n    \"tests\": [\n      {\n        \"section\": \"2\",\n        \"pass\": 7,\n        \"fail\": 0,\n        \"warn\": 0,\n        \"info\": 0,\n        \"desc\": \"Etcd Node Configuration Files\",\n        \"results\": [\n          {\n            \"test_number\": \"2.1\",\n            \"test_desc\": \"Ensure that the --cert-file and --key-file arguments are set as appropriate (Scored)\",\n            \"audit\": \"/bin/ps -ef | /bin/grep etcd | /bin/grep -v grep\",\n            \"AuditConfig\": \"\",\n            \"type\": \"\",\n            \"remediation\": \"Follow the etcd service documentation and configure TLS encryption.\\nThen, edit the etcd pod specification file /etc/kubernetes/manifests/etcd.yaml\\non the master node and set the below parameters.\\n--cert-file=</path/to/ca-file>\\n--key-file=</path/to/key-file>\\n\",\n            \"test_info\": [\n              \"Follow the etcd service documentation and configure TLS encryption.\\nThen, edit the etcd pod specification file /etc/kubernetes/manifests/etcd.yaml\\non the master node and set the below parameters.\\n--cert-file=</path/to/ca-file>\\n--key-file=</path/to/key-file>\\n\"\n            ],\n            \"status\": \"PASS\",\n            \"actual_value\": \"root      3277  3218  3 Apr19 ?        03:57:52 etcd --advertise-client-urls=https://192.168.64.4:2379 --cert-file=/var/lib/minikube/certs/etcd/server.crt --client-cert-auth=true --data-dir=/var/lib/minikube/etcd --initial-advertise-peer-urls=https://192.168.64.4:2380 --initial-cluster=minikube=https://192.168.64.4:2380 --key-file=/var/lib/minikube/certs/etcd/server.key --listen-client-urls=https://127.0.0.1:2379,https://192.168.64.4:2379 --listen-metrics-urls=http://127.0.0.1:2381 --listen-peer-urls=https://192.168.64.4:2380 --name=minikube --peer-cert-file=/var/lib/minikube/certs/etcd/peer.crt --peer-client-cert-auth=true --peer-key-file=/var/lib/minikube/certs/etcd/peer.key --peer-trusted-ca-file=/var/lib/minikube/certs/etcd/ca.crt --snapshot-count=10000 --trusted-ca-file=/var/lib/minikube/certs/etcd/ca.crt\\nroot      4624  4605  8 Apr21 ?        04:55:10 kube-apiserver --advertise-address=192.168.64.4 --allow-privileged=true --authorization-mode=Node,RBAC --client-ca-file=/var/lib/minikube/certs/ca.crt --enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota,PodSecurityPolicy --enable-bootstrap-token-auth=true --etcd-cafile=/var/lib/minikube/certs/etcd/ca.crt --etcd-certfile=/var/lib/minikube/certs/apiserver-etcd-client.crt --etcd-keyfile=/var/lib/minikube/certs/apiserver-etcd-client.key --etcd-servers=https://127.0.0.1:2379 --insecure-port=0 --kubelet-client-certificate=/var/lib/minikube/certs/apiserver-kubelet-client.crt --kubelet-client-key=/var/lib/minikube/certs/apiserver-kubelet-client.key --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname --proxy-client-cert-file=/var/lib/minikube/certs/front-proxy-client.crt --proxy-client-key-file=/var/lib/minikube/certs/front-proxy-client.key --requestheader-allowed-names=front-proxy-client --requestheader-client-ca-file=/var/lib/minikube/certs/front-proxy-ca.crt --requestheader-extra-headers-prefix=X-Remote-Extra- --requestheader-group-headers=X-Remote-Group --requestheader-username-headers=X-Remote-User --secure-port=8443 --service-account-key-file=/var/lib/minikube/certs/sa.pub --service-cluster-ip-range=10.96.0.0/12 --tls-cert-file=/var/lib/minikube/certs/apiserver.crt --tls-private-key-file=/var/lib/minikube/certs/apiserver.key\\n\",\n            \"scored\": true,\n            \"expected_result\": \"'--cert-file' is present AND '--key-file' is present\"\n          }\n        ]\n      }\n    ],\n    \"total_pass\": 7,\n    \"total_fail\": 0,\n    \"total_warn\": 0,\n    \"total_info\": 0\n  },\n  {\n    \"id\": \"3\",\n    \"version\": \"1.5\",\n    \"text\": \"Control Plane Configuration\",\n    \"node_type\": \"controlplane\",\n    \"tests\": [\n      {\n        \"section\": \"3.1\",\n        \"pass\": 0,\n        \"fail\": 0,\n        \"warn\": 1,\n        \"info\": 0,\n        \"desc\": \"Authentication and Authorization\",\n        \"results\": [\n          {\n            \"test_number\": \"3.1.1\",\n            \"test_desc\": \"Client certificate authentication should not be used for users (Not Scored)\",\n            \"audit\": \"\",\n            \"AuditConfig\": \"\",\n            \"type\": \"manual\",\n            \"remediation\": \"Alternative mechanisms provided by Kubernetes such as the use of OIDC should be\\nimplemented in place of client certificates.\\n\",\n            \"test_info\": [\n              \"Alternative mechanisms provided by Kubernetes such as the use of OIDC should be\\nimplemented in place of client certificates.\\n\"\n            ],\n            \"status\": \"WARN\",\n            \"actual_value\": \"\",\n            \"scored\": false,\n            \"expected_result\": \"\",\n            \"reason\": \"Test marked as a manual test\"\n          }\n        ]\n      }\n    ],\n    \"total_pass\": 0,\n    \"total_fail\": 0,\n    \"total_warn\": 3,\n    \"total_info\": 0\n  }\n]"
  },
  {
    "path": "cmd/util.go",
    "content": "package cmd\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"os\"\n\t\"os/exec\"\n\t\"path/filepath\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/aquasecurity/kube-bench/check\"\n\t\"github.com/fatih/color\"\n\t\"github.com/golang/glog\"\n\t\"github.com/spf13/viper\"\n\t\"golang.org/x/exp/slices\"\n\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"k8s.io/client-go/kubernetes\"\n\t\"k8s.io/client-go/rest\"\n)\n\n// Print colors\nvar colors = map[check.State]*color.Color{\n\tcheck.PASS: color.New(color.FgGreen),\n\tcheck.FAIL: color.New(color.FgRed),\n\tcheck.WARN: color.New(color.FgYellow),\n\tcheck.INFO: color.New(color.FgBlue),\n}\n\nvar (\n\tpsFunc          func(string) string\n\tstatFunc        func(string) (os.FileInfo, error)\n\tgetBinariesFunc func(*viper.Viper, check.NodeType) (map[string]string, error)\n\tTypeMap         = map[string][]string{\n\t\t\"ca\":         {\"cafile\", \"defaultcafile\"},\n\t\t\"kubeconfig\": {\"kubeconfig\", \"defaultkubeconfig\"},\n\t\t\"service\":    {\"svc\", \"defaultsvc\"},\n\t\t\"config\":     {\"confs\", \"defaultconf\"},\n\t\t\"datadir\":    {\"datadirs\", \"defaultdatadir\"},\n\t}\n)\n\nfunc init() {\n\tpsFunc = ps\n\tstatFunc = os.Stat\n\tgetBinariesFunc = getBinaries\n}\n\ntype Platform struct {\n\tName    string\n\tVersion string\n}\n\nfunc (p Platform) String() string {\n\treturn fmt.Sprintf(\"Platform{ Name: %s Version: %s }\", p.Name, p.Version)\n}\n\nfunc exitWithError(err error) {\n\tfmt.Fprintf(os.Stderr, \"\\n%v\\n\", err)\n\t// flush before exit non-zero\n\tglog.Flush()\n\tos.Exit(1)\n}\n\nfunc cleanIDs(list string) map[string]bool {\n\tlist = strings.Trim(list, \",\")\n\tids := strings.Split(list, \",\")\n\n\tset := make(map[string]bool)\n\n\tfor _, id := range ids {\n\t\tid = strings.Trim(id, \" \")\n\t\tset[id] = true\n\t}\n\n\treturn set\n}\n\n// ps execs out to the ps command; it's separated into a function so we can write tests\nfunc ps(proc string) string {\n\t// TODO: truncate proc to 15 chars\n\t// See https://github.com/aquasecurity/kube-bench/issues/328#issuecomment-506813344\n\tglog.V(2).Info(fmt.Sprintf(\"ps - proc: %q\", proc))\n\tcmd := exec.Command(\"/bin/ps\", \"-C\", proc, \"-o\", \"cmd\", \"--no-headers\")\n\tout, err := cmd.Output()\n\tif err != nil {\n\t\tglog.V(2).Info(fmt.Errorf(\"%s: %s\", cmd.Args, err))\n\t}\n\n\tglog.V(2).Info(fmt.Sprintf(\"ps - returning: %q\", string(out)))\n\treturn string(out)\n}\n\n// getBinaries finds which of the set of candidate executables are running.\n// It returns an error if one mandatory executable is not running.\nfunc getBinaries(v *viper.Viper, nodetype check.NodeType) (map[string]string, error) {\n\tbinmap := make(map[string]string)\n\n\tfor _, component := range v.GetStringSlice(\"components\") {\n\t\ts := v.Sub(component)\n\t\tif s == nil {\n\t\t\tcontinue\n\t\t}\n\n\t\toptional := s.GetBool(\"optional\")\n\t\tbins := s.GetStringSlice(\"bins\")\n\t\tif len(bins) > 0 {\n\t\t\tbin, err := findExecutable(bins)\n\t\t\tif err != nil && !optional {\n\t\t\t\tglog.V(1).Info(buildComponentMissingErrorMessage(nodetype, component, bins))\n\t\t\t\treturn nil, fmt.Errorf(\"unable to detect running programs for component %q\", component)\n\t\t\t}\n\n\t\t\t// Default the executable name that we'll substitute to the name of the component\n\t\t\tif bin == \"\" {\n\t\t\t\tbin = component\n\t\t\t\tglog.V(2).Info(fmt.Sprintf(\"Component %s not running\", component))\n\t\t\t} else {\n\t\t\t\tglog.V(2).Info(fmt.Sprintf(\"Component %s uses running binary %s\", component, bin))\n\t\t\t}\n\t\t\tbinmap[component] = bin\n\t\t}\n\t}\n\n\treturn binmap, nil\n}\n\n// getConfigFilePath locates the config files we should be using for CIS version\nfunc getConfigFilePath(benchmarkVersion string, filename string) (path string, err error) {\n\tglog.V(2).Info(fmt.Sprintf(\"Looking for config specific CIS version %q\", benchmarkVersion))\n\n\tpath = filepath.Join(cfgDir, benchmarkVersion)\n\tfile := filepath.Join(path, filename)\n\tglog.V(2).Info(fmt.Sprintf(\"Looking for file: %s\", file))\n\n\tif _, err := os.Stat(file); err != nil {\n\t\tglog.V(2).Infof(\"error accessing config file: %q error: %v\\n\", file, err)\n\t\treturn \"\", fmt.Errorf(\"no test files found <= benchmark version: %s\", benchmarkVersion)\n\t}\n\n\treturn path, nil\n}\n\n// getYamlFilesFromDir returns a list of yaml files in the specified directory, ignoring config.yaml\nfunc getYamlFilesFromDir(path string) (names []string, err error) {\n\terr = filepath.Walk(path, func(path string, info os.FileInfo, err error) error {\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t_, name := filepath.Split(path)\n\t\tif name != \"\" && name != \"config.yaml\" && filepath.Ext(name) == \".yaml\" {\n\t\t\tnames = append(names, path)\n\t\t}\n\n\t\treturn nil\n\t})\n\treturn names, err\n}\n\n// decrementVersion decrements the version number\n// We want to decrement individually even through versions where we don't supply test files\n// just in case someone wants to specify their own test files for that version\nfunc decrementVersion(version string) string {\n\tsplit := strings.Split(version, \".\")\n\tif len(split) < 2 {\n\t\treturn \"\"\n\t}\n\tminor, err := strconv.Atoi(split[1])\n\tif err != nil {\n\t\treturn \"\"\n\t}\n\tif minor <= 1 {\n\t\treturn \"\"\n\t}\n\tsplit[1] = strconv.Itoa(minor - 1)\n\treturn strings.Join(split, \".\")\n}\n\n// getFiles finds which of the set of candidate files exist\nfunc getFiles(v *viper.Viper, fileType string) map[string]string {\n\tfilemap := make(map[string]string)\n\tmainOpt := TypeMap[fileType][0]\n\tdefaultOpt := TypeMap[fileType][1]\n\n\tfor _, component := range v.GetStringSlice(\"components\") {\n\t\ts := v.Sub(component)\n\t\tif s == nil {\n\t\t\tcontinue\n\t\t}\n\n\t\t// See if any of the candidate files exist\n\t\tfile := findConfigFile(s.GetStringSlice(mainOpt))\n\t\tif file == \"\" {\n\t\t\tif s.IsSet(defaultOpt) {\n\t\t\t\tfile = s.GetString(defaultOpt)\n\t\t\t\tglog.V(2).Info(fmt.Sprintf(\"Using default %s file name '%s' for component %s\", fileType, file, component))\n\t\t\t} else {\n\t\t\t\t// Default the file name that we'll substitute to the name of the component\n\t\t\t\tglog.V(2).Info(fmt.Sprintf(\"Missing %s file for %s\", fileType, component))\n\t\t\t\tfile = component\n\t\t\t}\n\t\t} else {\n\t\t\tglog.V(2).Info(fmt.Sprintf(\"Component %s uses %s file '%s'\", component, fileType, file))\n\t\t}\n\n\t\tfilemap[component] = file\n\t}\n\n\treturn filemap\n}\n\n// verifyBin checks that the binary specified is running\nfunc verifyBin(bin string) bool {\n\t// Strip any quotes\n\tbin = strings.Trim(bin, \"'\\\"\")\n\n\t// bin could consist of more than one word\n\t// We'll search for running processes with the first word, and then check the whole\n\t// proc as supplied is included in the results\n\tproc := strings.Fields(bin)[0]\n\tout := psFunc(proc)\n\n\t// There could be multiple lines in the ps output\n\t// The binary needs to be the first word in the ps output, except that it could be preceded by a path\n\t// e.g. /usr/bin/kubelet is a match for kubelet\n\t// but apiserver is not a match for kube-apiserver\n\treFirstWord := regexp.MustCompile(`^(\\S*\\/)*` + bin)\n\tlines := strings.Split(out, \"\\n\")\n\tfor _, l := range lines {\n\t\tglog.V(3).Info(fmt.Sprintf(\"reFirstWord.Match(%s)\", l))\n\t\tif reFirstWord.Match([]byte(l)) {\n\t\t\treturn true\n\t\t}\n\t}\n\n\treturn false\n}\n\n// fundConfigFile looks through a list of possible config files and finds the first one that exists\nfunc findConfigFile(candidates []string) string {\n\tfor _, c := range candidates {\n\t\t_, err := statFunc(c)\n\t\tif err == nil {\n\t\t\treturn c\n\t\t}\n\t\tif !os.IsNotExist(err) && !strings.HasSuffix(err.Error(), \"not a directory\") {\n\t\t\texitWithError(fmt.Errorf(\"error looking for file %s: %v\", c, err))\n\t\t}\n\t}\n\n\treturn \"\"\n}\n\n// findExecutable looks through a list of possible executable names and finds the first one that's running\nfunc findExecutable(candidates []string) (string, error) {\n\tfor _, c := range candidates {\n\t\tif verifyBin(c) {\n\t\t\treturn c, nil\n\t\t}\n\t\tglog.V(1).Info(fmt.Sprintf(\"executable '%s' not running\", c))\n\t}\n\n\treturn \"\", fmt.Errorf(\"no candidates running\")\n}\n\nfunc multiWordReplace(s string, subname string, sub string) string {\n\tf := strings.Fields(sub)\n\tif len(f) > 1 {\n\t\tsub = \"'\" + sub + \"'\"\n\t}\n\n\treturn strings.Replace(s, subname, sub, -1)\n}\n\nconst missingKubectlKubeletMessage = `\nUnable to find the programs kubectl or kubelet in the PATH.\nThese programs are used to determine which version of Kubernetes is running.\nMake sure the /usr/local/mount-from-host/bin directory is mapped to the container,\neither in the job.yaml file, or Docker command.\n\nFor job.yaml:\n...\n- name: usr-bin\n  mountPath: /usr/local/mount-from-host/bin\n...\n\nFor docker command:\n   docker -v $(which kubectl):/usr/local/mount-from-host/bin/kubectl ....\n\nAlternatively, you can specify the version with --version\n   kube-bench --version <VERSION> ...\n`\n\nfunc getKubeVersion() (*KubeVersion, error) {\n\tkubeConfig, err := rest.InClusterConfig()\n\tif err != nil {\n\t\tglog.V(3).Infof(\"Error fetching cluster config: %s\", err)\n\t}\n\tisRKE := false\n\tisAKS := false\n\tif err == nil && kubeConfig != nil {\n\t\tk8sClient, err := kubernetes.NewForConfig(kubeConfig)\n\t\tif err != nil {\n\t\t\tglog.V(3).Infof(\"Failed to fetch k8sClient object from kube config : %s\", err)\n\t\t}\n\n\t\tif err == nil {\n\t\t\tisRKE, err = IsRKE(context.Background(), k8sClient)\n\t\t\tif err != nil {\n\t\t\t\tglog.V(3).Infof(\"Error detecting RKE cluster: %s\", err)\n\t\t\t}\n\t\t\tisAKS, err = IsAKS(context.Background(), k8sClient)\n\t\t\tif err != nil {\n\t\t\t\tglog.V(3).Infof(\"Error detecting AKS cluster: %s\", err)\n\t\t\t}\n\t\t}\n\n\t}\n\n\tif k8sVer, err := getKubeVersionFromRESTAPI(); err == nil {\n\t\tglog.V(2).Info(fmt.Sprintf(\"Kubernetes REST API Reported version: %s\", k8sVer))\n\t\tif isRKE {\n\t\t\tk8sVer.GitVersion = k8sVer.GitVersion + \"-rancher1\"\n\t\t}\n\t\tif isAKS {\n\t\t\tk8sVer.GitVersion = k8sVer.GitVersion + \"-aks1\"\n\t\t}\n\t\treturn k8sVer, nil\n\t}\n\n\t// These executables might not be on the user's path.\n\t_, err = exec.LookPath(\"kubectl\")\n\tif err != nil {\n\t\tglog.V(3).Infof(\"Error locating kubectl: %s\", err)\n\t\t_, err = exec.LookPath(\"kubelet\")\n\t\tif err != nil {\n\t\t\tglog.V(3).Infof(\"Error locating kubelet: %s\", err)\n\t\t\t// Search for the kubelet binary all over the filesystem and run the first match to get the kubernetes version\n\t\t\tcmd := exec.Command(\"/bin/sh\", \"-c\", \"`find / -type f -executable -name kubelet 2>/dev/null | grep -m1 .` --version\")\n\t\t\tout, err := cmd.CombinedOutput()\n\t\t\tif err == nil {\n\t\t\t\tglog.V(3).Infof(\"Found kubelet and query kubernetes version is: %s\", string(out))\n\t\t\t\treturn getVersionFromKubeletOutput(string(out)), nil\n\t\t\t}\n\n\t\t\tglog.Warning(missingKubectlKubeletMessage)\n\t\t\tglog.V(1).Info(\"unable to find the programs kubectl or kubelet in the PATH\")\n\t\t\tglog.V(1).Infof(\"Cant detect version, assuming default %s\", defaultKubeVersion)\n\t\t\treturn &KubeVersion{baseVersion: defaultKubeVersion}, nil\n\t\t}\n\t\treturn getKubeVersionFromKubelet(), nil\n\t}\n\n\treturn getKubeVersionFromKubectl(), nil\n}\n\nfunc getKubeVersionFromKubectl() *KubeVersion {\n\tcmd := exec.Command(\"kubectl\", \"version\", \"-o\", \"json\")\n\tout, err := cmd.CombinedOutput()\n\tif err != nil {\n\t\tglog.V(2).Infof(\"Failed to query kubectl: %s\", err)\n\t\tglog.V(2).Info(err)\n\t}\n\n\treturn getVersionFromKubectlOutput(string(out))\n}\n\nfunc getKubeVersionFromKubelet() *KubeVersion {\n\tcmd := exec.Command(\"kubelet\", \"--version\")\n\tout, err := cmd.CombinedOutput()\n\tif err != nil {\n\t\tglog.V(2).Infof(\"Failed to query kubelet: %s\", err)\n\t\tglog.V(2).Info(err)\n\t}\n\n\treturn getVersionFromKubeletOutput(string(out))\n}\n\nfunc getVersionFromKubectlOutput(s string) *KubeVersion {\n\tglog.V(2).Infof(\"Kubectl output: %s\", s)\n\ttype versionResult struct {\n\t\tServerVersion VersionResponse\n\t}\n\tvrObj := &versionResult{}\n\tif err := json.Unmarshal([]byte(s), vrObj); err != nil {\n\t\tglog.V(2).Info(err)\n\t\tif strings.Contains(s, \"The connection to the server\") {\n\t\t\tmsg := fmt.Sprintf(`Warning: Kubernetes version was not auto-detected because kubectl could not connect to the Kubernetes server. This may be because the kubeconfig information is missing or has credentials that do not match the server. Assuming default version %s`, defaultKubeVersion)\n\t\t\tfmt.Fprintln(os.Stderr, msg)\n\t\t}\n\t\tglog.V(1).Info(fmt.Sprintf(\"Unable to get Kubernetes version from kubectl, using default version: %s\", defaultKubeVersion))\n\t\treturn &KubeVersion{baseVersion: defaultKubeVersion}\n\t}\n\tsv := vrObj.ServerVersion\n\treturn &KubeVersion{\n\t\tMajor:      sv.Major,\n\t\tMinor:      sv.Minor,\n\t\tGitVersion: sv.GitVersion,\n\t}\n}\n\nfunc getVersionFromKubeletOutput(s string) *KubeVersion {\n\tglog.V(2).Infof(\"Kubelet output: %s\", s)\n\tserverVersionRe := regexp.MustCompile(`Kubernetes v(\\d+.\\d+)`)\n\tsubs := serverVersionRe.FindStringSubmatch(s)\n\tif len(subs) < 2 {\n\t\tglog.V(1).Info(fmt.Sprintf(\"Unable to get Kubernetes version from kubelet, using default version: %s\", defaultKubeVersion))\n\t\treturn &KubeVersion{baseVersion: defaultKubeVersion}\n\t}\n\treturn &KubeVersion{baseVersion: subs[1]}\n}\n\nfunc makeSubstitutions(s string, ext string, m map[string]string) (string, []string) {\n\tsubstitutions := make([]string, 0)\n\tfor k, v := range m {\n\t\tsubst := \"$\" + k + ext\n\t\tif v == \"\" {\n\t\t\tglog.V(2).Info(fmt.Sprintf(\"No substitution for '%s'\\n\", subst))\n\t\t\tcontinue\n\t\t}\n\t\tglog.V(2).Info(fmt.Sprintf(\"Substituting %s with '%s'\\n\", subst, v))\n\t\tbeforeS := s\n\t\ts = multiWordReplace(s, subst, v)\n\t\tif beforeS != s {\n\t\t\tsubstitutions = append(substitutions, v)\n\t\t}\n\t}\n\n\treturn s, substitutions\n}\n\nfunc isEmpty(str string) bool {\n\treturn strings.TrimSpace(str) == \"\"\n}\n\nfunc buildComponentMissingErrorMessage(nodetype check.NodeType, component string, bins []string) string {\n\terrMessageTemplate := `\nUnable to detect running programs for component %q\nThe following %q programs have been searched, but none of them have been found:\n%s\n\nThese program names are provided in the config.yaml, section '%s.%s.bins'\n`\n\n\tvar componentRoleName, componentType string\n\tswitch nodetype {\n\n\tcase check.NODE:\n\t\tcomponentRoleName = \"worker node\"\n\t\tcomponentType = \"node\"\n\tcase check.ETCD:\n\t\tcomponentRoleName = \"etcd node\"\n\t\tcomponentType = \"etcd\"\n\tdefault:\n\t\tcomponentRoleName = \"master node\"\n\t\tcomponentType = \"master\"\n\t}\n\n\tbinList := \"\"\n\tfor _, bin := range bins {\n\t\tbinList = fmt.Sprintf(\"%s\\t- %s\\n\", binList, bin)\n\t}\n\n\treturn fmt.Sprintf(errMessageTemplate, component, componentRoleName, binList, componentType, component)\n}\n\nfunc getPlatformInfo() Platform {\n\n\topenShiftInfo := getOpenShiftInfo()\n\tif openShiftInfo.Name != \"\" && openShiftInfo.Version != \"\" {\n\t\treturn openShiftInfo\n\t}\n\n\tkv, err := getKubeVersion()\n\tif err != nil {\n\t\tglog.V(2).Info(err)\n\t\treturn Platform{}\n\t}\n\treturn getPlatformInfoFromVersion(kv.GitVersion)\n}\n\nfunc getPlatformInfoFromVersion(s string) Platform {\n\tversionRe := regexp.MustCompile(`v(\\d+\\.\\d+)\\.\\d+[-+](\\w+)(?:[.\\-+]*)\\w+`)\n\tsubs := versionRe.FindStringSubmatch(s)\n\tif len(subs) < 3 {\n\t\treturn Platform{}\n\t}\n\treturn Platform{\n\t\tName:    subs[2],\n\t\tVersion: subs[1],\n\t}\n}\n\nfunc IsAKS(ctx context.Context, k8sClient kubernetes.Interface) (bool, error) {\n\tnodes, err := k8sClient.CoreV1().Nodes().List(ctx, metav1.ListOptions{Limit: 1})\n\tif err != nil {\n\t\treturn false, err\n\t}\n\n\tif len(nodes.Items) == 0 {\n\t\treturn false, nil\n\t}\n\n\tnode := nodes.Items[0]\n\tlabels := node.Labels\n\tif _, exists := labels[\"kubernetes.azure.com/cluster\"]; exists {\n\t\treturn true, nil\n\t}\n\n\tif strings.HasPrefix(node.Spec.ProviderID, \"azure://\") {\n\t\treturn true, nil\n\t}\n\n\treturn false, nil\n}\n\nfunc getPlatformBenchmarkVersion(platform Platform) string {\n\tglog.V(3).Infof(\"getPlatformBenchmarkVersion platform: %s\", platform)\n\n\tswitch platform.Name {\n\tcase \"eks\":\n\t\treturn eksBenchmark(platform.Version)\n\tcase \"aks\":\n\t\treturn aksBenchmark(platform.Version)\n\tcase \"gke\":\n\t\treturn gkeBenchmark(platform.Version)\n\tcase \"ocp\":\n\t\treturn ocpBenchmark(platform.Version)\n\tcase \"k3s\":\n\t\treturn k3sBenchmark(platform.Version)\n\tcase \"rancher\":\n\t\treturn rkeBenchmark(platform.Version)\n\tcase \"rke2r\":\n\t\treturn rke2Benchmark(platform.Version)\n\tcase \"aliyun\":\n\t\treturn \"ack-1.0\"\n\tcase \"vmware\":\n\t\treturn \"tkgi-1.2.53\"\n\tdefault:\n\t\treturn \"\"\n\t}\n}\n\nfunc eksBenchmark(version string) string {\n\tswitch version {\n\tcase \"1.15\", \"1.16\", \"1.17\", \"1.18\", \"1.19\":\n\t\treturn \"eks-1.0.1\"\n\tcase \"1.29\", \"1.30\", \"1.31\":\n\t\treturn \"eks-1.7.0\"\n\tcase \"1.32\", \"1.33\", \"1.34\":\n\t\treturn \"eks-1.8.0\"\n\tdefault:\n\t\treturn \"eks-1.5.0\"\n\t}\n}\n\nfunc aksBenchmark(version string) string {\n\tswitch version {\n\tcase \"1.19\", \"1.20\", \"1.21\", \"1.22\", \"1.23\", \"1.24\":\n\t\treturn \"aks-1.0\"\n\tcase \"1.29\", \"1.30\", \"1.31\":\n\t\treturn \"aks-1.7\"\n\tdefault:\n\t\treturn \"aks-1.8\"\n\t}\n}\n\nfunc gkeBenchmark(version string) string {\n\tswitch version {\n\tcase \"1.15\", \"1.16\", \"1.17\", \"1.18\", \"1.19\":\n\t\treturn \"gke-1.0\"\n\tcase \"1.28\", \"1.29\", \"1.30\":\n\t\treturn \"gke-1.6.0\"\n\tcase \"1.31\", \"1.32\", \"1.33\", \"1.34\":\n\t\treturn \"gke-1.8.0\"\n\tdefault:\n\t\treturn \"gke-1.2.0\"\n\t}\n}\n\nfunc ocpBenchmark(version string) string {\n\tswitch version {\n\tcase \"3.10\":\n\t\treturn \"rh-0.7\"\n\tcase \"4.1\":\n\t\treturn \"rh-1.0\"\n\tcase \"4.11\":\n\t\treturn \"rh-1.4\"\n\tcase \"4.13\":\n\t\treturn \"rh-1.8\"\n\tdefault:\n\t\treturn \"\"\n\t}\n}\n\nfunc k3sBenchmark(version string) string {\n\tswitch version {\n\tcase \"1.23\":\n\t\treturn \"k3s-cis-1.23\"\n\tcase \"1.24\":\n\t\treturn \"k3s-cis-1.24\"\n\tcase \"1.25\", \"1.26\", \"1.27\":\n\t\treturn \"k3s-cis-1.7\"\n\tdefault:\n\t\treturn \"\"\n\t}\n}\n\nfunc rkeBenchmark(version string) string {\n\tswitch version {\n\tcase \"1.23\":\n\t\treturn \"rke-cis-1.23\"\n\tcase \"1.24\":\n\t\treturn \"rke-cis-1.24\"\n\tcase \"1.25\", \"1.26\", \"1.27\":\n\t\treturn \"rke-cis-1.7\"\n\tdefault:\n\t\treturn \"rke-cis-1.7\"\n\t}\n}\n\nfunc rke2Benchmark(version string) string {\n\tswitch version {\n\tcase \"1.23\":\n\t\treturn \"rke2-cis-1.23\"\n\tcase \"1.24\":\n\t\treturn \"rke2-cis-1.24\"\n\tcase \"1.25\":\n\t\treturn \"rke2-cis-1.7\"\n\tcase \"1.26\", \"1.27\":\n\t\treturn \"rke2-cis-1.8\"\n\tdefault:\n\t\treturn \"rke2-cis-1.8\"\n\t}\n}\n\nfunc getOpenShiftInfo() Platform {\n\tglog.V(1).Info(\"Checking for oc\")\n\t_, err := exec.LookPath(\"oc\")\n\n\tif err == nil {\n\t\tcmd := exec.Command(\"oc\", \"version\")\n\t\tout, err := cmd.CombinedOutput()\n\n\t\tif err == nil {\n\t\t\tversionRe := regexp.MustCompile(`oc v(\\d+\\.\\d+)`)\n\t\t\tsubs := versionRe.FindStringSubmatch(string(out))\n\t\t\tif len(subs) < 1 {\n\t\t\t\tversionRe = regexp.MustCompile(`Client Version:\\s*(\\d+\\.\\d+)`)\n\t\t\t\tsubs = versionRe.FindStringSubmatch(string(out))\n\t\t\t}\n\t\t\tif len(subs) > 1 {\n\t\t\t\tglog.V(2).Infof(\"OCP output '%s' \\nplatform is %s \\nocp %v\", string(out), getPlatformInfoFromVersion(string(out)), subs[1])\n\t\t\t\tocpBenchmarkVersion, err := getOcpValidVersion(subs[1])\n\t\t\t\tif err == nil {\n\t\t\t\t\treturn Platform{Name: \"ocp\", Version: ocpBenchmarkVersion}\n\t\t\t\t} else {\n\t\t\t\t\tglog.V(1).Infof(\"Can't get getOcpValidVersion: %v\", err)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tglog.V(1).Infof(\"Can't parse version output: %v\", subs)\n\t\t\t}\n\t\t} else {\n\t\t\tglog.V(1).Infof(\"Can't use oc command: %v\", err)\n\t\t}\n\t} else {\n\t\tglog.V(1).Infof(\"Can't find oc command: %v\", err)\n\t}\n\treturn Platform{}\n}\n\nfunc getOcpValidVersion(ocpVer string) (string, error) {\n\tocpOriginal := ocpVer\n\tvalid := []string{\"3.10\", \"4.1\", \"4.11\", \"4.13\"}\n\tfor !isEmpty(ocpVer) {\n\t\tglog.V(3).Info(fmt.Sprintf(\"getOcpBenchmarkVersion check for ocp: %q \\n\", ocpVer))\n\t\tif slices.Contains(valid, ocpVer) {\n\t\t\tglog.V(1).Info(fmt.Sprintf(\"getOcpBenchmarkVersion found valid version for ocp: %q \\n\", ocpVer))\n\t\t\treturn ocpVer, nil\n\t\t}\n\t\tocpVer = decrementVersion(ocpVer)\n\t}\n\n\tglog.V(1).Info(fmt.Sprintf(\"getOcpBenchmarkVersion unable to find a match for: %q\", ocpOriginal))\n\treturn \"\", fmt.Errorf(\"unable to find a matching Benchmark Version match for ocp version: %s\", ocpOriginal)\n}\n\n// IsRKE Identifies if the cluster belongs to Rancher Distribution RKE\nfunc IsRKE(ctx context.Context, k8sClient kubernetes.Interface) (bool, error) {\n\t// if there are windows nodes then this should not be counted as rke.linux\n\twindowsNodes, err := k8sClient.CoreV1().Nodes().List(ctx, metav1.ListOptions{\n\t\tLimit:         1,\n\t\tLabelSelector: \"kubernetes.io/os=windows\",\n\t})\n\tif err != nil {\n\t\treturn false, err\n\t}\n\tif len(windowsNodes.Items) != 0 {\n\t\treturn false, nil\n\t}\n\n\t// Any node created by RKE should have the annotation, so just grab 1\n\tnodes, err := k8sClient.CoreV1().Nodes().List(ctx, metav1.ListOptions{Limit: 1})\n\tif err != nil {\n\t\treturn false, err\n\t}\n\n\tif len(nodes.Items) == 0 {\n\t\treturn false, nil\n\t}\n\n\tannos := nodes.Items[0].Annotations\n\tif _, ok := annos[\"rke.cattle.io/external-ip\"]; ok {\n\t\treturn true, nil\n\t}\n\tif _, ok := annos[\"rke.cattle.io/internal-ip\"]; ok {\n\t\treturn true, nil\n\t}\n\treturn false, nil\n}\n"
  },
  {
    "path": "cmd/util_test.go",
    "content": "// Copyright © 2017 Aqua Security Software Ltd. <info@aquasec.com>\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage cmd\n\nimport (\n\t\"errors\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"reflect\"\n\t\"sort\"\n\t\"strconv\"\n\t\"testing\"\n\n\t\"github.com/magiconair/properties/assert\"\n\n\t\"github.com/aquasecurity/kube-bench/check\"\n\t\"github.com/spf13/viper\"\n)\n\nvar (\n\tg      string\n\te      []error\n\teIndex int\n)\n\nfunc fakeps(proc string) string {\n\treturn g\n}\n\nfunc fakestat(file string) (os.FileInfo, error) {\n\terr := e[eIndex]\n\teIndex++\n\treturn nil, err\n}\n\nfunc TestVerifyBin(t *testing.T) {\n\tcases := []struct {\n\t\tproc  string\n\t\tpsOut string\n\t\texp   bool\n\t}{\n\t\t{proc: \"single\", psOut: \"single\", exp: true},\n\t\t{proc: \"single\", psOut: \"\", exp: false},\n\t\t{proc: \"two words\", psOut: \"two words\", exp: true},\n\t\t{proc: \"two words\", psOut: \"\", exp: false},\n\t\t{proc: \"cmd\", psOut: \"cmd param1 param2\", exp: true},\n\t\t{proc: \"cmd param\", psOut: \"cmd param1 param2\", exp: true},\n\t\t{proc: \"cmd param\", psOut: \"cmd\", exp: false},\n\t\t{proc: \"cmd\", psOut: \"cmd x \\ncmd y\", exp: true},\n\t\t{proc: \"cmd y\", psOut: \"cmd x \\ncmd y\", exp: true},\n\t\t{proc: \"cmd\", psOut: \"/usr/bin/cmd\", exp: true},\n\t\t{proc: \"cmd\", psOut: \"kube-cmd\", exp: false},\n\t\t{proc: \"cmd\", psOut: \"/usr/bin/kube-cmd\", exp: false},\n\t}\n\n\tpsFunc = fakeps\n\tfor id, c := range cases {\n\t\tt.Run(strconv.Itoa(id), func(t *testing.T) {\n\t\t\tg = c.psOut\n\t\t\tv := verifyBin(c.proc)\n\t\t\tif v != c.exp {\n\t\t\t\tt.Fatalf(\"Expected %v got %v\", c.exp, v)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestFindExecutable(t *testing.T) {\n\tcases := []struct {\n\t\tcandidates []string // list of executables we'd consider\n\t\tpsOut      string   // fake output from ps\n\t\texp        string   // the one we expect to find in the (fake) ps output\n\t\texpErr     bool\n\t}{\n\t\t{candidates: []string{\"one\", \"two\", \"three\"}, psOut: \"two\", exp: \"two\"},\n\t\t{candidates: []string{\"one\", \"two\", \"three\"}, psOut: \"two three\", exp: \"two\"},\n\t\t{candidates: []string{\"one double\", \"two double\", \"three double\"}, psOut: \"two double is running\", exp: \"two double\"},\n\t\t{candidates: []string{\"one\", \"two\", \"three\"}, psOut: \"blah\", expErr: true},\n\t\t{candidates: []string{\"one double\", \"two double\", \"three double\"}, psOut: \"two\", expErr: true},\n\t\t{candidates: []string{\"apiserver\", \"kube-apiserver\"}, psOut: \"kube-apiserver\", exp: \"kube-apiserver\"},\n\t\t{candidates: []string{\"apiserver\", \"kube-apiserver\", \"hyperkube-apiserver\"}, psOut: \"kube-apiserver\", exp: \"kube-apiserver\"},\n\t}\n\n\tpsFunc = fakeps\n\tfor id, c := range cases {\n\t\tt.Run(strconv.Itoa(id), func(t *testing.T) {\n\t\t\tg = c.psOut\n\t\t\te, err := findExecutable(c.candidates)\n\t\t\tif e != c.exp {\n\t\t\t\tt.Fatalf(\"Expected %v got %v\", c.exp, e)\n\t\t\t}\n\n\t\t\tif err == nil && c.expErr {\n\t\t\t\tt.Fatalf(\"Expected error\")\n\t\t\t}\n\n\t\t\tif err != nil && !c.expErr {\n\t\t\t\tt.Fatalf(\"Didn't expect error: %v\", err)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestGetBinaries(t *testing.T) {\n\tcases := []struct {\n\t\tconfig    map[string]interface{}\n\t\tpsOut     string\n\t\texp       map[string]string\n\t\texpectErr bool\n\t}{\n\t\t{\n\t\t\tconfig:    map[string]interface{}{\"components\": []string{\"apiserver\"}, \"apiserver\": map[string]interface{}{\"bins\": []string{\"apiserver\", \"kube-apiserver\"}}},\n\t\t\tpsOut:     \"kube-apiserver\",\n\t\t\texp:       map[string]string{\"apiserver\": \"kube-apiserver\"},\n\t\t\texpectErr: false,\n\t\t},\n\t\t{\n\t\t\t// \"thing\" is not in the list of components\n\t\t\tconfig:    map[string]interface{}{\"components\": []string{\"apiserver\"}, \"apiserver\": map[string]interface{}{\"bins\": []string{\"apiserver\", \"kube-apiserver\"}}, \"thing\": map[string]interface{}{\"bins\": []string{\"something else\", \"thing\"}}},\n\t\t\tpsOut:     \"kube-apiserver thing\",\n\t\t\texp:       map[string]string{\"apiserver\": \"kube-apiserver\"},\n\t\t\texpectErr: false,\n\t\t},\n\t\t{\n\t\t\t// \"anotherthing\" in list of components but doesn't have a definition\n\t\t\tconfig:    map[string]interface{}{\"components\": []string{\"apiserver\", \"anotherthing\"}, \"apiserver\": map[string]interface{}{\"bins\": []string{\"apiserver\", \"kube-apiserver\"}}, \"thing\": map[string]interface{}{\"bins\": []string{\"something else\", \"thing\"}}},\n\t\t\tpsOut:     \"kube-apiserver thing\",\n\t\t\texp:       map[string]string{\"apiserver\": \"kube-apiserver\"},\n\t\t\texpectErr: false,\n\t\t},\n\t\t{\n\t\t\t// more than one component\n\t\t\tconfig:    map[string]interface{}{\"components\": []string{\"apiserver\", \"thing\"}, \"apiserver\": map[string]interface{}{\"bins\": []string{\"apiserver\", \"kube-apiserver\"}}, \"thing\": map[string]interface{}{\"bins\": []string{\"something else\", \"thing\"}}},\n\t\t\tpsOut:     \"kube-apiserver \\nthing\",\n\t\t\texp:       map[string]string{\"apiserver\": \"kube-apiserver\", \"thing\": \"thing\"},\n\t\t\texpectErr: false,\n\t\t},\n\t\t{\n\t\t\t// default binary to component name\n\t\t\tconfig:    map[string]interface{}{\"components\": []string{\"apiserver\", \"thing\"}, \"apiserver\": map[string]interface{}{\"bins\": []string{\"apiserver\", \"kube-apiserver\"}}, \"thing\": map[string]interface{}{\"bins\": []string{\"something else\", \"thing\"}, \"optional\": true}},\n\t\t\tpsOut:     \"kube-apiserver \\notherthing some params\",\n\t\t\texp:       map[string]string{\"apiserver\": \"kube-apiserver\", \"thing\": \"thing\"},\n\t\t\texpectErr: false,\n\t\t},\n\t\t{\n\t\t\t// missing mandatory component\n\t\t\tconfig:    map[string]interface{}{\"components\": []string{\"apiserver\", \"thing\"}, \"apiserver\": map[string]interface{}{\"bins\": []string{\"apiserver\", \"kube-apiserver\"}}, \"thing\": map[string]interface{}{\"bins\": []string{\"something else\", \"thing\"}, \"optional\": true}},\n\t\t\tpsOut:     \"otherthing some params\",\n\t\t\texp:       map[string]string{\"apiserver\": \"kube-apiserver\", \"thing\": \"thing\"},\n\t\t\texpectErr: true,\n\t\t},\n\t}\n\n\tv := viper.New()\n\tpsFunc = fakeps\n\n\tfor id, c := range cases {\n\t\tt.Run(strconv.Itoa(id), func(t *testing.T) {\n\t\t\tg = c.psOut\n\t\t\tfor k, val := range c.config {\n\t\t\t\tv.Set(k, val)\n\t\t\t}\n\t\t\tm, err := getBinaries(v, check.MASTER)\n\t\t\tif c.expectErr {\n\t\t\t\tif err == nil {\n\t\t\t\t\tt.Fatal(\"Got nil Expected error\")\n\t\t\t\t}\n\t\t\t} else if !reflect.DeepEqual(m, c.exp) {\n\t\t\t\tt.Fatalf(\"Got %v\\nExpected %v\", m, c.exp)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestMultiWordReplace(t *testing.T) {\n\tcases := []struct {\n\t\tinput   string\n\t\tsub     string\n\t\tsubname string\n\t\toutput  string\n\t}{\n\t\t{input: \"Here's a file with no substitutions\", sub: \"blah\", subname: \"blah\", output: \"Here's a file with no substitutions\"},\n\t\t{input: \"Here's a file with a substitution\", sub: \"blah\", subname: \"substitution\", output: \"Here's a file with a blah\"},\n\t\t{input: \"Here's a file with multi-word substitutions\", sub: \"multi word\", subname: \"multi-word\", output: \"Here's a file with 'multi word' substitutions\"},\n\t\t{input: \"Here's a file with several several substitutions several\", sub: \"blah\", subname: \"several\", output: \"Here's a file with blah blah substitutions blah\"},\n\t}\n\tfor id, c := range cases {\n\t\tt.Run(strconv.Itoa(id), func(t *testing.T) {\n\t\t\ts := multiWordReplace(c.input, c.subname, c.sub)\n\t\t\tif s != c.output {\n\t\t\t\tt.Fatalf(\"Expected %s got %s\", c.output, s)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc Test_getVersionFromKubectlOutput(t *testing.T) {\n\tver := getVersionFromKubectlOutput(`{\n  \"serverVersion\": {\n    \"major\": \"1\",\n    \"minor\": \"8\",\n    \"gitVersion\": \"v1.8.0\"\n  }\n}`)\n\tif ver.BaseVersion() != \"1.8\" {\n\t\tt.Fatalf(\"Expected 1.8 got %s\", ver.BaseVersion())\n\t}\n\n\tver = getVersionFromKubectlOutput(\"Something completely different\")\n\tif ver.BaseVersion() != defaultKubeVersion {\n\t\tt.Fatalf(\"Expected %s got %s\", defaultKubeVersion, ver.BaseVersion())\n\t}\n}\n\nfunc TestFindConfigFile(t *testing.T) {\n\tcases := []struct {\n\t\tinput       []string\n\t\tstatResults []error\n\t\texp         string\n\t}{\n\t\t{input: []string{\"myfile\"}, statResults: []error{nil}, exp: \"myfile\"},\n\t\t{input: []string{\"thisfile\", \"thatfile\"}, statResults: []error{os.ErrNotExist, nil}, exp: \"thatfile\"},\n\t\t{input: []string{\"thisfile\", \"thatfile\"}, statResults: []error{os.ErrNotExist, os.ErrNotExist}, exp: \"\"},\n\t\t{input: []string{\"thisfile\", \"/etc/dummy/thatfile\"}, statResults: []error{os.ErrNotExist, errors.New(\"stat /etc/dummy/thatfile: not a directory\")}, exp: \"\"},\n\t}\n\n\tstatFunc = fakestat\n\tfor id, c := range cases {\n\t\tt.Run(strconv.Itoa(id), func(t *testing.T) {\n\t\t\te = c.statResults\n\t\t\teIndex = 0\n\t\t\tconf := findConfigFile(c.input)\n\t\t\tif conf != c.exp {\n\t\t\t\tt.Fatalf(\"Got %s expected %s\", conf, c.exp)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestGetConfigFiles(t *testing.T) {\n\tcases := []struct {\n\t\tconfig      map[string]interface{}\n\t\texp         map[string]string\n\t\tstatResults []error\n\t}{\n\t\t{\n\t\t\tconfig:      map[string]interface{}{\"components\": []string{\"apiserver\"}, \"apiserver\": map[string]interface{}{\"confs\": []string{\"apiserver\", \"kube-apiserver\"}}},\n\t\t\tstatResults: []error{os.ErrNotExist, nil},\n\t\t\texp:         map[string]string{\"apiserver\": \"kube-apiserver\"},\n\t\t},\n\t\t{\n\t\t\t// Component \"thing\" isn't included in the list of components\n\t\t\tconfig: map[string]interface{}{\n\t\t\t\t\"components\": []string{\"apiserver\"},\n\t\t\t\t\"apiserver\":  map[string]interface{}{\"confs\": []string{\"apiserver\", \"kube-apiserver\"}},\n\t\t\t\t\"thing\":      map[string]interface{}{\"confs\": []string{\"/my/file/thing\"}},\n\t\t\t},\n\t\t\tstatResults: []error{os.ErrNotExist, nil},\n\t\t\texp:         map[string]string{\"apiserver\": \"kube-apiserver\"},\n\t\t},\n\t\t{\n\t\t\t// More than one component\n\t\t\tconfig: map[string]interface{}{\n\t\t\t\t\"components\": []string{\"apiserver\", \"thing\"},\n\t\t\t\t\"apiserver\":  map[string]interface{}{\"confs\": []string{\"apiserver\", \"kube-apiserver\"}},\n\t\t\t\t\"thing\":      map[string]interface{}{\"confs\": []string{\"/my/file/thing\"}},\n\t\t\t},\n\t\t\tstatResults: []error{os.ErrNotExist, nil, nil},\n\t\t\texp:         map[string]string{\"apiserver\": \"kube-apiserver\", \"thing\": \"/my/file/thing\"},\n\t\t},\n\t\t{\n\t\t\t// Default thing to specified default config\n\t\t\tconfig: map[string]interface{}{\n\t\t\t\t\"components\": []string{\"apiserver\", \"thing\"},\n\t\t\t\t\"apiserver\":  map[string]interface{}{\"confs\": []string{\"apiserver\", \"kube-apiserver\"}},\n\t\t\t\t\"thing\":      map[string]interface{}{\"confs\": []string{\"/my/file/thing\"}, \"defaultconf\": \"another/thing\"},\n\t\t\t},\n\t\t\tstatResults: []error{os.ErrNotExist, nil, os.ErrNotExist},\n\t\t\texp:         map[string]string{\"apiserver\": \"kube-apiserver\", \"thing\": \"another/thing\"},\n\t\t},\n\t\t{\n\t\t\t// Default thing to component name\n\t\t\tconfig: map[string]interface{}{\n\t\t\t\t\"components\": []string{\"apiserver\", \"thing\"},\n\t\t\t\t\"apiserver\":  map[string]interface{}{\"confs\": []string{\"apiserver\", \"kube-apiserver\"}},\n\t\t\t\t\"thing\":      map[string]interface{}{\"confs\": []string{\"/my/file/thing\"}},\n\t\t\t},\n\t\t\tstatResults: []error{os.ErrNotExist, nil, os.ErrNotExist},\n\t\t\texp:         map[string]string{\"apiserver\": \"kube-apiserver\", \"thing\": \"thing\"},\n\t\t},\n\t}\n\n\tv := viper.New()\n\tstatFunc = fakestat\n\n\tfor id, c := range cases {\n\t\tt.Run(strconv.Itoa(id), func(t *testing.T) {\n\t\t\tfor k, val := range c.config {\n\t\t\t\tv.Set(k, val)\n\t\t\t}\n\t\t\te = c.statResults\n\t\t\teIndex = 0\n\n\t\t\tm := getFiles(v, \"config\")\n\t\t\tif !reflect.DeepEqual(m, c.exp) {\n\t\t\t\tt.Fatalf(\"Got %v\\nExpected %v\", m, c.exp)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestGetServiceFiles(t *testing.T) {\n\tcases := []struct {\n\t\tconfig      map[string]interface{}\n\t\texp         map[string]string\n\t\tstatResults []error\n\t}{\n\t\t{\n\t\t\tconfig: map[string]interface{}{\n\t\t\t\t\"components\": []string{\"kubelet\"},\n\t\t\t\t\"kubelet\":    map[string]interface{}{\"svc\": []string{\"kubelet\", \"10-kubeadm.conf\"}},\n\t\t\t},\n\t\t\tstatResults: []error{os.ErrNotExist, nil},\n\t\t\texp:         map[string]string{\"kubelet\": \"10-kubeadm.conf\"},\n\t\t},\n\t\t{\n\t\t\t// Component \"thing\" isn't included in the list of components\n\t\t\tconfig: map[string]interface{}{\n\t\t\t\t\"components\": []string{\"kubelet\"},\n\t\t\t\t\"kubelet\":    map[string]interface{}{\"svc\": []string{\"kubelet\", \"10-kubeadm.conf\"}},\n\t\t\t\t\"thing\":      map[string]interface{}{\"svc\": []string{\"/my/file/thing\"}},\n\t\t\t},\n\t\t\tstatResults: []error{os.ErrNotExist, nil},\n\t\t\texp:         map[string]string{\"kubelet\": \"10-kubeadm.conf\"},\n\t\t},\n\t\t{\n\t\t\t// More than one component\n\t\t\tconfig: map[string]interface{}{\n\t\t\t\t\"components\": []string{\"kubelet\", \"thing\"},\n\t\t\t\t\"kubelet\":    map[string]interface{}{\"svc\": []string{\"kubelet\", \"10-kubeadm.conf\"}},\n\t\t\t\t\"thing\":      map[string]interface{}{\"svc\": []string{\"/my/file/thing\"}},\n\t\t\t},\n\t\t\tstatResults: []error{os.ErrNotExist, nil, nil},\n\t\t\texp:         map[string]string{\"kubelet\": \"10-kubeadm.conf\", \"thing\": \"/my/file/thing\"},\n\t\t},\n\t\t{\n\t\t\t// Default thing to specified default service\n\t\t\tconfig: map[string]interface{}{\n\t\t\t\t\"components\": []string{\"kubelet\", \"thing\"},\n\t\t\t\t\"kubelet\":    map[string]interface{}{\"svc\": []string{\"kubelet\", \"10-kubeadm.conf\"}},\n\t\t\t\t\"thing\":      map[string]interface{}{\"svc\": []string{\"/my/file/thing\"}, \"defaultsvc\": \"another/thing\"},\n\t\t\t},\n\t\t\tstatResults: []error{os.ErrNotExist, nil, os.ErrNotExist},\n\t\t\texp:         map[string]string{\"kubelet\": \"10-kubeadm.conf\", \"thing\": \"another/thing\"},\n\t\t},\n\t\t{\n\t\t\t// Default thing to component name\n\t\t\tconfig: map[string]interface{}{\n\t\t\t\t\"components\": []string{\"kubelet\", \"thing\"},\n\t\t\t\t\"kubelet\":    map[string]interface{}{\"svc\": []string{\"kubelet\", \"10-kubeadm.conf\"}},\n\t\t\t\t\"thing\":      map[string]interface{}{\"svc\": []string{\"/my/file/thing\"}},\n\t\t\t},\n\t\t\tstatResults: []error{os.ErrNotExist, nil, os.ErrNotExist},\n\t\t\texp:         map[string]string{\"kubelet\": \"10-kubeadm.conf\", \"thing\": \"thing\"},\n\t\t},\n\t}\n\n\tv := viper.New()\n\tstatFunc = fakestat\n\n\tfor id, c := range cases {\n\t\tt.Run(strconv.Itoa(id), func(t *testing.T) {\n\t\t\tfor k, val := range c.config {\n\t\t\t\tv.Set(k, val)\n\t\t\t}\n\t\t\te = c.statResults\n\t\t\teIndex = 0\n\n\t\t\tm := getFiles(v, \"service\")\n\t\t\tif !reflect.DeepEqual(m, c.exp) {\n\t\t\t\tt.Fatalf(\"Got %v\\nExpected %v\", m, c.exp)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestGetDatadirFiles(t *testing.T) {\n\tvar err error\n\tdatadir, err := os.MkdirTemp(\"\", \"kube-bench-test-etcd-data-dir\")\n\tif err != nil {\n\t\tt.Fatalf(\"Failed to create temp directory\")\n\t}\n\tdefer os.RemoveAll(datadir)\n\n\tcases := []struct {\n\t\tconfig      map[string]interface{}\n\t\texp         map[string]string\n\t\tstatResults []error\n\t}{\n\t\t{\n\t\t\tconfig: map[string]interface{}{\n\t\t\t\t\"components\": []string{\"etcd\"},\n\t\t\t\t\"etcd\": map[string]interface{}{\"datadirs\": []string{datadir},\n\t\t\t\t\t\"defaultdatadir\": \"/var/lib/etcd/default.etcd\"},\n\t\t\t},\n\t\t\tstatResults: []error{nil},\n\t\t\texp:         map[string]string{\"etcd\": datadir},\n\t\t},\n\t\t// fallback to defaultdatadir\n\t\t{\n\t\t\tconfig: map[string]interface{}{\n\t\t\t\t\"components\": []string{\"etcd\"},\n\t\t\t\t\"etcd\": map[string]interface{}{\"datadirs\": []string{\"/path/to/etcd/data.etcd\"},\n\t\t\t\t\t\"defaultdatadir\": \"/var/lib/etcd/default.etcd\"},\n\t\t\t},\n\t\t\tstatResults: []error{os.ErrNotExist},\n\t\t\texp:         map[string]string{\"etcd\": \"/var/lib/etcd/default.etcd\"},\n\t\t},\n\t}\n\n\tv := viper.New()\n\tstatFunc = fakestat\n\n\tfor id, c := range cases {\n\t\tt.Run(strconv.Itoa(id), func(t *testing.T) {\n\t\t\tfor k, val := range c.config {\n\t\t\t\tv.Set(k, val)\n\t\t\t}\n\t\t\te = c.statResults\n\t\t\teIndex = 0\n\t\t\tm := getFiles(v, \"datadir\")\n\t\t\tif !reflect.DeepEqual(m, c.exp) {\n\t\t\t\tt.Fatalf(\"Got %v\\nExpected %v\", m, c.exp)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestMakeSubsitutions(t *testing.T) {\n\tcases := []struct {\n\t\tinput        string\n\t\tsubst        map[string]string\n\t\texp          string\n\t\texpectedSubs []string\n\t}{\n\t\t{input: \"Replace $thisbin\", subst: map[string]string{\"this\": \"that\"}, exp: \"Replace that\", expectedSubs: []string{\"that\"}},\n\t\t{input: \"Replace $thisbin\", subst: map[string]string{\"this\": \"that\", \"here\": \"there\"}, exp: \"Replace that\", expectedSubs: []string{\"that\"}},\n\t\t{input: \"Replace $thisbin and $herebin\", subst: map[string]string{\"this\": \"that\", \"here\": \"there\"}, exp: \"Replace that and there\", expectedSubs: []string{\"that\", \"there\"}},\n\t}\n\tfor _, c := range cases {\n\t\tt.Run(c.input, func(t *testing.T) {\n\t\t\ts, subs := makeSubstitutions(c.input, \"bin\", c.subst)\n\t\t\tif s != c.exp {\n\t\t\t\tt.Fatalf(\"Got %s expected %s\", s, c.exp)\n\t\t\t}\n\t\t\tsort.Strings(subs)\n\t\t\tassert.Equal(t, c.expectedSubs, subs)\n\t\t})\n\t}\n}\n\nfunc TestGetConfigFilePath(t *testing.T) {\n\tvar err error\n\tcfgDir, err = os.MkdirTemp(\"\", \"kube-bench-test\")\n\tif err != nil {\n\t\tt.Fatalf(\"Failed to create temp directory\")\n\t}\n\tdefer os.RemoveAll(cfgDir)\n\td := filepath.Join(cfgDir, \"cis-1.4\")\n\terr = os.Mkdir(d, 0766)\n\tif err != nil {\n\t\tt.Fatalf(\"Failed to create temp dir\")\n\t}\n\terr = os.WriteFile(filepath.Join(d, \"master.yaml\"), []byte(\"hello world\"), 0666)\n\tif err != nil {\n\t\tt.Logf(\"Failed to create temp file\")\n\t}\n\n\tcases := []struct {\n\t\tbenchmarkVersion string\n\t\tsucceed          bool\n\t\texp              string\n\t}{\n\t\t{benchmarkVersion: \"cis-1.4\", succeed: true, exp: d},\n\t\t{benchmarkVersion: \"cis-1.5\", succeed: false, exp: \"\"},\n\t\t{benchmarkVersion: \"1.1\", succeed: false, exp: \"\"},\n\t}\n\n\tfor _, c := range cases {\n\t\tt.Run(c.benchmarkVersion, func(t *testing.T) {\n\t\t\tpath, err := getConfigFilePath(c.benchmarkVersion, \"/master.yaml\")\n\t\t\tif c.succeed {\n\t\t\t\tif err != nil {\n\t\t\t\t\tt.Fatalf(\"Error %v\", err)\n\t\t\t\t}\n\t\t\t\tif path != c.exp {\n\t\t\t\t\tt.Fatalf(\"Got %s expected %s\", path, c.exp)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif err == nil {\n\t\t\t\t\tt.Fatalf(\"Expected Error, but none\")\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestDecrementVersion(t *testing.T) {\n\tcases := []struct {\n\t\tkubeVersion string\n\t\tsucceed     bool\n\t\texp         string\n\t}{\n\t\t{kubeVersion: \"1.13\", succeed: true, exp: \"1.12\"},\n\t\t{kubeVersion: \"1.15\", succeed: true, exp: \"1.14\"},\n\t\t{kubeVersion: \"1.11\", succeed: true, exp: \"1.10\"},\n\t\t{kubeVersion: \"1.1\", succeed: true, exp: \"\"},\n\t\t{kubeVersion: \"invalid\", succeed: false, exp: \"\"},\n\t}\n\tfor _, c := range cases {\n\t\trv := decrementVersion(c.kubeVersion)\n\t\tif c.succeed {\n\t\t\tif c.exp != rv {\n\t\t\t\tt.Fatalf(\"decrementVersion(%q) - Got %q expected %s\", c.kubeVersion, rv, c.exp)\n\t\t\t}\n\t\t} else {\n\t\t\tif len(rv) > 0 {\n\t\t\t\tt.Fatalf(\"decrementVersion(%q) - Expected empty string but Got %s\", c.kubeVersion, rv)\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc TestGetYamlFilesFromDir(t *testing.T) {\n\tcfgDir, err := os.MkdirTemp(\"\", \"kube-bench-test\")\n\tif err != nil {\n\t\tt.Fatalf(\"Failed to create temp directory\")\n\t}\n\tdefer os.RemoveAll(cfgDir)\n\n\td := filepath.Join(cfgDir, \"cis-1.4\")\n\terr = os.Mkdir(d, 0766)\n\tif err != nil {\n\t\tt.Fatalf(\"Failed to create temp dir\")\n\t}\n\n\terr = os.WriteFile(filepath.Join(d, \"something.yaml\"), []byte(\"hello world\"), 0666)\n\tif err != nil {\n\t\tt.Fatalf(\"error writing file %v\", err)\n\t}\n\terr = os.WriteFile(filepath.Join(d, \"config.yaml\"), []byte(\"hello world\"), 0666)\n\tif err != nil {\n\t\tt.Fatalf(\"error writing file %v\", err)\n\t}\n\n\tfiles, err := getYamlFilesFromDir(d)\n\tif err != nil {\n\t\tt.Fatalf(\"Unexpected error: %v\", err)\n\t}\n\tif len(files) != 1 {\n\t\tt.Fatalf(\"Expected to find one file, found %d\", len(files))\n\t}\n\n\tif files[0] != filepath.Join(d, \"something.yaml\") {\n\t\tt.Fatalf(\"Expected to find something.yaml, found %s\", files[0])\n\t}\n}\n\nfunc Test_getPlatformNameFromKubectlOutput(t *testing.T) {\n\ttype args struct {\n\t\ts string\n\t}\n\ttests := []struct {\n\t\tname string\n\t\targs args\n\t\twant Platform\n\t}{\n\t\t{\n\t\t\tname: \"eks\",\n\t\t\targs: args{s: \"v1.17.9-eks-4c6976\"},\n\t\t\twant: Platform{Name: \"eks\", Version: \"1.17\"},\n\t\t},\n\t\t{\n\t\t\tname: \"gke\",\n\t\t\targs: args{s: \"v1.17.6-gke.1\"},\n\t\t\twant: Platform{Name: \"gke\", Version: \"1.17\"},\n\t\t},\n\t\t{\n\t\t\tname: \"ack\",\n\t\t\targs: args{s: \"v1.18.8-aliyun.1\"},\n\t\t\twant: Platform{Name: \"aliyun\", Version: \"1.18\"},\n\t\t},\n\t\t{\n\t\t\tname: \"unknown\",\n\t\t\targs: args{s: \"v1.17.6\"},\n\t\t\twant: Platform{},\n\t\t},\n\t\t{\n\t\t\tname: \"empty string\",\n\t\t\targs: args{s: \"\"},\n\t\t\twant: Platform{},\n\t\t},\n\t\t{\n\t\t\tname: \"k3s\",\n\t\t\targs: args{s: \"v1.27.6+k3s1\"},\n\t\t\twant: Platform{Name: \"k3s\", Version: \"1.27\"},\n\t\t},\n\t\t{\n\t\t\tname: \"rancher1\",\n\t\t\targs: args{s: \"v1.25.13-rancher1-1\"},\n\t\t\twant: Platform{Name: \"rancher1\", Version: \"1.25\"},\n\t\t},\n\t\t{\n\t\t\tname: \"rke2\",\n\t\t\targs: args{s: \"v1.27.6+rke2r1\"},\n\t\t\twant: Platform{Name: \"rke2r\", Version: \"1.27\"},\n\t\t},\n\t\t{\n\t\t\tname: \"aks\",\n\t\t\targs: args{s: \"v1.27.6+aks1\"},\n\t\t\twant: Platform{Name: \"aks\", Version: \"1.27\"},\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tgot := getPlatformInfoFromVersion(tt.args.s)\n\t\t\tassert.Equal(t, tt.want, got)\n\t\t})\n\t}\n}\n\nfunc Test_getPlatformBenchmarkVersion(t *testing.T) {\n\ttype args struct {\n\t\tplatform Platform\n\t}\n\ttests := []struct {\n\t\tname string\n\t\targs args\n\t\twant string\n\t}{\n\t\t{\n\t\t\tname: \"eks 1.31\",\n\t\t\targs: args{\n\t\t\t\tplatform: Platform{Name: \"eks\", Version: \"1.31\"},\n\t\t\t},\n\t\t\twant: \"eks-1.7.0\",\n\t\t},\n\t\t{\n\t\t\tname: \"eks 1.29\",\n\t\t\targs: args{\n\t\t\t\tplatform: Platform{Name: \"eks\", Version: \"1.29\"},\n\t\t\t},\n\t\t\twant: \"eks-1.7.0\",\n\t\t},\n\t\t{\n\t\t\tname: \"eks 1.30\",\n\t\t\targs: args{\n\t\t\t\tplatform: Platform{Name: \"eks\", Version: \"1.30\"},\n\t\t\t},\n\t\t\twant: \"eks-1.7.0\",\n\t\t},\n\t\t{\n\t\t\tname: \"eks 1.32\",\n\t\t\targs: args{\n\t\t\t\tplatform: Platform{Name: \"eks\", Version: \"1.32\"},\n\t\t\t},\n\t\t\twant: \"eks-1.8.0\",\n\t\t},\n\t\t{\n\t\t\tname: \"eks 1.24\",\n\t\t\targs: args{\n\t\t\t\tplatform: Platform{Name: \"eks\", Version: \"1.24\"},\n\t\t\t},\n\t\t\twant: \"eks-1.5.0\",\n\t\t},\n\t\t{\n\t\t\tname: \"gke 1.19\",\n\t\t\targs: args{\n\t\t\t\tplatform: Platform{Name: \"gke\", Version: \"1.19\"},\n\t\t\t},\n\t\t\twant: \"gke-1.0\",\n\t\t},\n\t\t{\n\t\t\tname: \"gke 1.20\",\n\t\t\targs: args{\n\t\t\t\tplatform: Platform{Name: \"gke\", Version: \"1.20\"},\n\t\t\t},\n\t\t\twant: \"gke-1.2.0\",\n\t\t},\n\t\t{\n\t\t\tname: \"gke 1.22\",\n\t\t\targs: args{\n\t\t\t\tplatform: Platform{Name: \"gke\", Version: \"1.22\"},\n\t\t\t},\n\t\t\twant: \"gke-1.2.0\",\n\t\t},\n\t\t{\n\t\t\tname: \"gke 1.28\",\n\t\t\targs: args{\n\t\t\t\tplatform: Platform{Name: \"gke\", Version: \"1.28\"},\n\t\t\t},\n\t\t\twant: \"gke-1.6.0\",\n\t\t},\n\t\t{\n\t\t\tname: \"gke 1.31\",\n\t\t\targs: args{\n\t\t\t\tplatform: Platform{Name: \"gke\", Version: \"1.31\"},\n\t\t\t},\n\t\t\twant: \"gke-1.8.0\",\n\t\t},\n\t\t{\n\t\t\tname: \"aliyun\",\n\t\t\targs: args{\n\t\t\t\tplatform: Platform{Name: \"aliyun\"},\n\t\t\t},\n\t\t\twant: \"ack-1.0\",\n\t\t},\n\t\t{\n\t\t\tname: \"unknown\",\n\t\t\targs: args{\n\t\t\t\tplatform: Platform{Name: \"rh\"},\n\t\t\t},\n\t\t\twant: \"\",\n\t\t},\n\t\t{\n\t\t\tname: \"empty\",\n\t\t\targs: args{\n\t\t\t\tplatform: Platform{},\n\t\t\t},\n\t\t\twant: \"\",\n\t\t},\n\t\t{\n\t\t\tname: \"openshift3\",\n\t\t\targs: args{\n\t\t\t\tplatform: Platform{Name: \"ocp\", Version: \"3.10\"},\n\t\t\t},\n\t\t\twant: \"rh-0.7\",\n\t\t},\n\t\t{\n\t\t\tname: \"openshift4\",\n\t\t\targs: args{\n\t\t\t\tplatform: Platform{Name: \"ocp\", Version: \"4.11\"},\n\t\t\t},\n\t\t\twant: \"rh-1.4\",\n\t\t},\n\t\t{\n\t\t\tname: \"openshift4\",\n\t\t\targs: args{\n\t\t\t\tplatform: Platform{Name: \"ocp\", Version: \"4.13\"},\n\t\t\t},\n\t\t\twant: \"rh-1.8\",\n\t\t},\n\t\t{\n\t\t\tname: \"openshift4\",\n\t\t\targs: args{\n\t\t\t\tplatform: Platform{Name: \"ocp\", Version: \"4.1\"},\n\t\t\t},\n\t\t\twant: \"rh-1.0\",\n\t\t},\n\t\t{\n\t\t\tname: \"k3s\",\n\t\t\targs: args{\n\t\t\t\tplatform: Platform{Name: \"k3s\", Version: \"1.27\"},\n\t\t\t},\n\t\t\twant: \"k3s-cis-1.7\",\n\t\t},\n\t\t{\n\t\t\tname: \"rancher1\",\n\t\t\targs: args{\n\t\t\t\tplatform: Platform{Name: \"rancher\", Version: \"1.27\"},\n\t\t\t},\n\t\t\twant: \"rke-cis-1.7\",\n\t\t},\n\t\t{\n\t\t\tname: \"rke2\",\n\t\t\targs: args{\n\t\t\t\tplatform: Platform{Name: \"rke2r\", Version: \"1.25\"},\n\t\t\t},\n\t\t\twant: \"rke2-cis-1.7\",\n\t\t},\n\t\t{\n\t\t\tname: \"rke2\",\n\t\t\targs: args{\n\t\t\t\tplatform: Platform{Name: \"rke2r\", Version: \"1.26\"},\n\t\t\t},\n\t\t\twant: \"rke2-cis-1.8\",\n\t\t},\n\t\t{\n\t\t\tname: \"aks\",\n\t\t\targs: args{\n\t\t\t\tplatform: Platform{Name: \"aks\", Version: \"1.29\"},\n\t\t\t},\n\t\t\twant: \"aks-1.7\",\n\t\t},\n\t\t{\n\t\t\tname: \"aks\",\n\t\t\targs: args{\n\t\t\t\tplatform: Platform{Name: \"aks\", Version: \"1.32\"},\n\t\t\t},\n\t\t\twant: \"aks-1.8\",\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tif got := getPlatformBenchmarkVersion(tt.args.platform); got != tt.want {\n\t\t\t\tt.Errorf(\"getPlatformBenchmarkVersion() = %v, want %v\", got, tt.want)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc Test_getOcpValidVersion(t *testing.T) {\n\tcases := []struct {\n\t\topenShiftVersion string\n\t\tsucceed          bool\n\t\texp              string\n\t}{\n\t\t{openShiftVersion: \"3.11\", succeed: true, exp: \"3.10\"},\n\t\t{openShiftVersion: \"3.10\", succeed: true, exp: \"3.10\"},\n\t\t{openShiftVersion: \"2.9\", succeed: false, exp: \"\"},\n\t\t{openShiftVersion: \"4.1\", succeed: true, exp: \"4.1\"},\n\t\t{openShiftVersion: \"4.5\", succeed: true, exp: \"4.1\"},\n\t\t{openShiftVersion: \"4.6\", succeed: true, exp: \"4.1\"},\n\t\t{openShiftVersion: \"invalid\", succeed: false, exp: \"\"},\n\t}\n\tfor _, c := range cases {\n\t\tocpVer, _ := getOcpValidVersion(c.openShiftVersion)\n\t\tif c.succeed {\n\t\t\tif c.exp != ocpVer {\n\t\t\t\tt.Errorf(\"getOcpValidVersion(%q) - Got %q expected %s\", c.openShiftVersion, ocpVer, c.exp)\n\t\t\t}\n\t\t} else {\n\t\t\tif len(ocpVer) > 0 {\n\t\t\t\tt.Errorf(\"getOcpValidVersion(%q) - Expected empty string but Got %s\", c.openShiftVersion, ocpVer)\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "cmd/version.go",
    "content": "package cmd\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/spf13/cobra\"\n)\n\nvar KubeBenchVersion string\n\n// versionCmd represents the version command\nvar versionCmd = &cobra.Command{\n\tUse:   \"version\",\n\tShort: \"Shows the version of kube-bench.\",\n\tLong:  `Shows the version of kube-bench.`,\n\tRun: func(cmd *cobra.Command, args []string) {\n\t\tfmt.Println(KubeBenchVersion)\n\t},\n}\n\nfunc init() {\n\tRootCmd.AddCommand(versionCmd)\n}\n"
  },
  {
    "path": "codecov.yml",
    "content": "---\ncoverage:\n  status:\n    project:\n      default:\n        target: auto  # auto compares coverage to the previous base commit\n        threshold: 1%\n"
  },
  {
    "path": "docs/architecture.md",
    "content": "## Test config YAML representation\n\nThe tests (or \"controls\") are maintained in YAML documents. There are different versions of these test YAML files reflecting different [versions and platforms of the CIS Kubernetes Benchmark](./platforms.md). You will find more information about the test file YAML definitions in our [controls documentation](./controls.md).\n\n## Kube-bench benchmarks\n\nThe test files for the various versions of Benchmarks can be found in directories\nwith same name as the Benchmark versions under the `cfg` directory next to the kube-bench executable,\nfor example `./cfg/cis-1.5` will contain all test files for [CIS Kubernetes Benchmark v1.5.1](https://workbench.cisecurity.org/benchmarks/4892) which are:\nmaster.yaml, controlplane.yaml, node.yaml, etcd.yaml, policies.yaml and config.yaml\n\nCheck the contents of the benchmark directory under `cfg` to see which targets are available for that benchmark. Each file except `config.yaml` represents a target (also known as a `control` in other parts of this documentation).\n\nThe following table shows the valid targets based on the CIS Benchmark version.\n\n| CIS Benchmark        | Targets |\n|----------------------|---------|\n| cis-1.5              | master, controlplane, node, etcd, policies |\n| cis-1.6              | master, controlplane, node, etcd, policies |\n| cis-1.20             | master, controlplane, node, etcd, policies |\n| cis-1.23             | master, controlplane, node, etcd, policies |\n| cis-1.24             | master, controlplane, node, etcd, policies |\n| cis-1.7              | master, controlplane, node, etcd, policies |\n| cis-1.8              | master, controlplane, node, etcd, policies |\n| cis-1.9              | master, controlplane, node, etcd, policies |\n| cis-1.10              | master, controlplane, node, etcd, policies |\n| cis-1.11              | master, controlplane, node, etcd, policies |\n| cis-1.12              | master, controlplane, node, etcd, policies |\n| gke-1.0              | master, controlplane, node, etcd, policies, managedservices |\n| gke-1.2.0            | controlplane, node, policies, managedservices |\n| gke-1.6.0            | controlplane, node, policies, managedservices |\n| eks-1.0.1            | controlplane, node, policies, managedservices |\n| eks-1.1.0            | controlplane, node, policies, managedservices |\n| eks-1.2.0            | controlplane, node, policies, managedservices |\n| eks-1.5.0            | controlplane, node, policies, managedservices |\n| ack-1.0              | master, controlplane, node, etcd, policies, managedservices |\n| aks-1.0              | controlplane, node, policies, managedservices |\n| aks-1.7              | controlplane, node, policies, managedservices |\n| rh-0.7               | master,node|\n| rh-1.0               | master, controlplane, node, etcd, policies |\n| cis-1.6-k3s          | master, controlplane, node, etcd, policies |\n| cis-1.24-microk8s    | master, controlplane, node, etcd, policies |\n\nThe following table shows the valid DISA STIG versions\n\n| STIG                       | Targets |\n|----------------------------|---------|\n| eks-stig-kubernetes-v1r6   | master, controlplane, node, policies, managedservices |\n\n\n"
  },
  {
    "path": "docs/asff.md",
    "content": "# Integrating kube-bench with AWS Security Hub\n\nYou can configure kube-bench with the `--asff` to send findings to AWS Security Hub. There are some additional steps required so that kube-bench has information and permissions to send these findings.\n\n## Enable the AWS Security Hub integration\n\n* You will need AWS Security Hub to be enabled in your account\n* In the Security Hub console, under Integrations, search for kube-bench\n\n<p align=\"center\">\n  <img src=\"./images/kube-bench-security-hub.png\">\n</p>\n\n* Click on `Accept findings`. This gives information about the IAM permissions required to send findings to your Security Hub account. kube-bench runs within a pod on your EKS cluster, and will need to be associated with a Role that has these permissions.\n\n## Configure permissions in an IAM Role\n\n* Grant these permissions to the IAM Role that the kube-bench pod will be associated with. There are two options:\n  * You can run the kube-bench pod under a specific [service account associated with an IAM role](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html) that has these permissions to write Security Hub findings.\n  * Alternatively the pod can be granted permissions specified by the Role that your [EKS node group uses](https://docs.aws.amazon.com/eks/latest/userguide/managed-node-groups.html).\n  \nHere is an example IAM Policy that you can attach to your EKS node group's IAM Role: \n\n```json\n{\n    \"Version\": \"2012-10-17\",\n    \"Statement\": [\n        {\n            \"Effect\": \"Allow\",\n            \"Action\": \"securityhub:BatchImportFindings\",\n            \"Resource\": [\n                \"arn:aws:securityhub:us-east-1::product/aqua-security/kube-bench\"\n            ]\n        }\n    ]\n}\n```\n\n### Modify the job configuration\n\n* Modify the kube-bench Configmap in `job-eks-asff.yaml` to specify the AWS account, AWS region, and the EKS Cluster ARN.\n* In the same file, modify the image specifed in the Job to use the kube-bench image pushed to your ECR\n* [Optional] - If you have created a dedicated IAM role to be used with kube-bench as described above in [Configure permissions in an IAM Role](#configure-permissions-in-an-iam-role), you will need to add the IAM role arn to the kube-bench ServiceAccount in `job-eks-asff.yaml`.\n* Make sure that `job-eks-asff.yaml` specifies the container image you just pushed to your ECR registry.\n\nYou can now run kube-bench as a pod in your cluster: `kubectl apply -f job-eks-asff.yaml`\n\nFindings will be generated for any kube-bench test that generates a `[FAIL]` or `[WARN]` output. If all tests pass, no findings will be generated. However, it's recommended that you consult the pod log output to check whether any findings were generated but could not be written to Security Hub.\n\n<p align=\"center\">\n  <img src=\"./images/asff-example-finding.png\">\n</p>\n\n[eks-instructions]: ../README.md#running-in-an-EKS-cluster\n"
  },
  {
    "path": "docs/controls.md",
    "content": "# Test and config files\n\n`kube-bench` runs checks specified in `controls` files that are a YAML \nrepresentation of the CIS Kubernetes Benchmark checks (or other distribution-specific hardening guides). \n\n## Controls\n\n`controls` is a YAML document that contains checks that must be run against a \nspecific Kubernetes node type, master or node and version.\n\n`controls` is the fundamental input to `kube-bench`. The following is an example \nof a basic `controls`:\n\n```yml\n---\ncontrols:\nid: 1\ntext: \"Master Node Security Configuration\"\ntype: \"master\"\ngroups:\n- id: 1.1\n  text: API Server\n  checks:\n    - id: 1.1.1\n      text: \"Ensure that the --allow-privileged argument is set (Scored)\"\n      audit: \"ps -ef | grep kube-apiserver | grep -v grep\"\n      tests:\n      bin_op: or\n      test_items:\n      - flag: \"--allow-privileged\"\n        set: true\n      - flag: \"--some-other-flag\"\n        set: false\n      remediation: \"Edit the /etc/kubernetes/config file on the master node and\n        set the KUBE_ALLOW_PRIV parameter to '--allow-privileged=false'\"\n      scored: true\n- id: 1.2\n  text: Scheduler\n  checks:\n    - id: 1.2.1\n      text: \"Ensure that the --profiling argument is set to false (Scored)\"\n      audit: \"ps -ef | grep kube-scheduler | grep -v grep\"\n      tests:\n        bin_op: and\n        test_items:\n          - flag: \"--profiling\"\n            set: true\n          - flag: \"--some-other-flag\"\n            set: false\n      remediation: \"Edit the /etc/kubernetes/config file on the master node and\n        set the KUBE_ALLOW_PRIV parameter to '--allow-privileged=false'\"\n      scored: true\n```\n\n`controls` is composed of a hierarchy of groups, sub-groups and checks. Each of\nthe `controls` components have an id and a text description which are displayed \nin the `kube-bench` output.\n\n`type` specifies what kubernetes node type a `controls` is for. Possible values\nfor `type` are `master` and `node`.\n\n## Groups\n\n`groups` is a list of subgroups that test the various Kubernetes components\nthat run on the node type specified in the `controls`. \n\nFor example, one subgroup checks parameters passed to the API server binary, while \nanother subgroup checks parameters passed to the controller-manager binary.\n\n```yml\ngroups:\n- id: 1.1\n  text: API Server\n  # ...\n- id: 1.2\n  text: Scheduler\n  # ...\n```\n\nThese subgroups have `id`, `text` fields which serve the same purposes described\nin the previous paragraphs. The most important part of the subgroup is the\n`checks` field which is the collection of actual `check`s that form the subgroup.\n\nThis is an example of a subgroup and checks in the subgroup.\n\n```yml\nid: 1.1\ntext: API Server\nchecks:\n  - id: 1.1.1\n    text: \"Ensure that the --allow-privileged argument is set (Scored)\"\n    audit: \"ps -ef | grep kube-apiserver | grep -v grep\"\n    tests:\n    # ...\n  - id: 1.1.2\n    text: \"Ensure that the --anonymous-auth argument is set to false (Not Scored)\"\n    audit: \"ps -ef | grep kube-apiserver | grep -v grep\"\n    tests:\n    # ...\n``` \n\n`kube-bench` supports running a subgroup by specifying the subgroup `id` on the\ncommand line, with the flag `--group` or `-g`.\n\n## Check\n\nThe CIS Kubernetes Benchmark recommends configurations to harden Kubernetes components. These recommendations are usually configuration options and can be \nspecified by flags to Kubernetes binaries, or in configuration files.\n\nThe Benchmark also provides commands to audit a Kubernetes installation, identify\nplaces where the cluster security can be improved, and steps to remediate these\nidentified problems.\n\nIn `kube-bench`, `check` objects embody these recommendations.  This an example\n`check` object:\n\n```yml\nid: 1.1.1\ntext: \"Ensure that the --anonymous-auth argument is set to false (Not Scored)\"\naudit: \"ps -ef | grep kube-apiserver | grep -v grep\"\ntests:\n  test_items:\n  - flag: \"--anonymous-auth\"\n    compare:\n      op: eq\n      value: false\n    set: true\nremediation: |\n  Edit the API server pod specification file kube-apiserver\n  on the master node and set the below parameter.\n  --anonymous-auth=false\nscored: false\n```\n\nA `check` object has an `id`, a `text`, an `audit`, a `tests`, `remediation`\nand `scored` fields.\n\n`kube-bench` supports running individual checks by specifying the check's `id`\nas a comma-delimited list on the command line with the `--check` flag.\n\nThe `audit` field specifies the command to run for a check. The output of this\ncommand is then evaluated for conformance with the CIS Kubernetes Benchmark\nrecommendation.\n\nThe audit is evaluated against criteria specified by the `tests`\nobject. `tests` contain `bin_op` and `test_items`.\n\n`test_items` specify the criteria(s) the `audit` command's output should meet to\npass a check. This criteria is made up of keywords extracted from the output of\nthe `audit` command and operations that compare these keywords against\nvalues expected by the CIS Kubernetes Benchmark. \n\nThere are three ways to run and extract keywords from the output of the command used, \n| Command | Output var |\n|---|---|\n| `audit` | `flag` |\n| `audit_config` | `path` | \n| `audit_env` | `env` |\n\n`flag` is used when the keyword is a command-line flag. The associated `audit` command could \nbe any binaries available on the system like `ps` command and a `grep` for the binary whose flag we are\nchecking:\n\n```sh\nps -ef | grep somebinary | grep -v grep\n``` \n\nHere is an example usage of the `flag` option:\n\n```yml\n# ...\naudit: \"ps -ef | grep kube-apiserver | grep -v grep\"\ntests:\n  test_items:\n  - flag: \"--anonymous-auth\"\n  # ...\n```\n\n`path` is used when the keyword is an option set in a JSON or YAML config file.\nThe associated `audit_command` command is usually `cat /path/to/config-yaml-or-json`.\nFor example:\n\n```yml\n# ...\ntext: \"Ensure that the --anonymous-auth argument is set to false (Not Scored)\"\naudit: \"cat /path/to/some/config\"\ntests:\n  test_items:\n  - path: \"{.someoption.value}\"\n    # ...\n```\n\n`env` is used to check if the value is present within a specified environment variable. The presence of `env` is treated as an OR operation, if both `flag` and `env` are supplied it will use either to attempt pass the check.\nThe command used for checking the environment variables of a process **is generated by default**.\n\nIf the command being generated is causing errors, you can override the command used by setting `audit_env` on the check.\nSimilarly, if you don't want the environment checking command to be generated or run at all, specify `disableEnvTesting` as true on the check.\n\nThe example below will check if the flag `--auto-tls` is equal to false *OR* `ETCD_AUTO_TLS` is equal to false\n\n```yml\n  test_items:\n  - flag: \"--auto-tls\"\n    env: \"ETCD_AUTO_TLS\"\n    compare:\n      op: eq\n      value: false\n```\n**Note:** flag, path and env will act as OR if more then one present. \n\n`test_item` compares the output of the audit command and keywords using the\n`set` and `compare` fields.\n\n```yml\n  test_items:\n  - flag: \"--anonymous-auth\"\n    compare:\n      op: eq\n      value: false\n    set: true\n```\n\n`set` checks if a keyword is present in the output of the audit command or a config file. The possible values for `set` are true and false.\n\nIf `set` is true, the check passes only if the keyword is present in the output\nof the audit command, or config file. If `set` is false, the check passes only\nif the keyword is not present in the output of the audit command, or config file.\n`set` is true by default.\n\n`compare` has two fields `op` and `value` to compare keywords with expected\nvalue. `op` specifies which operation is used for the comparison, and `value`\nspecifies the value to compare against.\n\n> To use `compare`, `set` must true. The comparison will be ignored if `set` is\n> false\n\nThe `op` (operations) currently supported in `kube-bench` are:\n- `eq`: tests if the keyword is equal to the compared value.\n- `noteq`: tests if the keyword is unequal to the compared value.\n- `gt`: tests if the keyword is greater than the compared value.\n- `gte`: tests if the keyword is greater than or equal to the compared value.\n- `lt`: tests if the keyword is less than the compared value.\n- `lte`: tests if the keyword is less than or equal to the compared value.\n- `has`: tests if the keyword contains the compared value.\n- `nothave`: tests if the keyword does not contain the compared value.\n- `regex`: tests if the flag value matches the compared value regular expression.\n   When defining regular expressions in YAML it is generally easier to wrap them in\n   single quotes, for example `'^[abc]$'`, to avoid issues with string escaping.\n- `bitmask` : tests if keyward is bitmasked with the compared value, common usege is for \n   comparing file permissions in linux.\n\n## Omitting checks\n\nIf you decide that a recommendation is not appropriate for your environment, you can choose to omit it by editing the test YAML file to give it the check type `skip` as in this example:\n\n```yaml\n  checks:\n  - id: 2.1.1\n    text: \"Ensure that the --allow-privileged argument is set to false (Scored)\"\n    type: \"skip\"\n    scored: true\n```\n\nNo tests will be run for this check and the output will be marked [INFO].\n\n## Configuration and Variables\n\nKubernetes component configuration and binary file locations and names \nvary based on cluster deployment methods and Kubernetes distribution used.\nFor this reason, the locations of these binaries and config files are configurable\nby editing the `cfg/config.yaml` file and these binaries and files can be\nreferenced in a `controls` file via variables.\n\nThe `cfg/config.yaml` file is a global configuration file. Configuration files\ncan be created for specific Kubernetes versions (distributions). Values in the\nversion-specific config overwrite similar values in `cfg/config.yaml`.\n\nFor example, the kube-apiserver in Red Hat OCP distribution is run as \n`hypershift openshift-kube-apiserver` instead of the default `kube-apiserver`.\nThis difference can be specified by editing the `master.apiserver.defaultbin`\nentry `cfg/rh-0.7/config.yaml`.\n\nBelow is the structure of `cfg/config.yaml`:\n\n```\nnodetype\n  |-- components\n    |-- component1\n  |-- component1\n    |-- bins\n    |-- defaultbin (optional)\n    |-- confs\n    |-- defaultconf (optional)\n    |-- svcs\n    |-- defaultsvc (optional)\n    |-- kubeconfig\n    |-- defaultkubeconfig (optional)\n```\n\nEvery node type has a subsection that specifies the main configuration items.\n\n- `components`: A list of components for the node type. For example master \n  will have an entry for **apiserver**, **scheduler** and **controllermanager**.\n  \n  Each component has the following entries:\n\n- `bins`: A list of candidate binaries for a component. `kube-bench` checks this\n   list and selects the **first** binary that is running on the node.\n\n   If none of the binaries in `bins` list is running, `kube-bench` checks if the\n   binary specified by `defaultbin` is running and terminates if none of the \n   binaries in both `bins` and `defaultbin` is running.\n   \n   The selected binary for a component can be referenced in `controls` using a \n   variable in the form `$<component>bin`. In the example below, we reference \n   the selected API server binary with the variable `$apiserverbin` in an `audit`\n   command.\n   \n   ```yml\n   id: 1.1.1\n    text: \"Ensure that the --anonymous-auth argument is set to false (Scored)\"\n    audit: \"ps -ef | grep $apiserverbin | grep -v grep\"\n    # ...\n   ```\n   \n- `confs`: A list of candidate configuration files for a component. `kube-bench`\n  checks this list and selects the **first** config file that is found on the node.\n  If none of the config files exists, `kube-bench` defaults conf to the value\n  of `defaultconf`.\n  \n  The selected config for a component can be referenced in `controls` using a\n  variable in the form `$<component>conf`. In the example below, we reference the \n  selected API server config file with the variable `$apiserverconf` in an `audit`\n  command.\n  \n  ```yml\n  id: 1.4.1\n    text: \"Ensure that the API server pod specification file permissions are\n    set to 644 or more restrictive (Scored)\"\n    audit: \"/bin/sh -c 'if test -e $apiserverconf; then stat -c %a $apiserverconf; fi'\"\n  ```\n  \n- `svcs`:  A list of candidate unitfiles for a component. `kube-bench` checks this \n  list and selects the **first** unitfile that is found on the node. If none of the\n  unitfiles exists, `kube-bench` defaults unitfile to the value of `defaultsvc`.\n  \n  The selected unitfile for a component can be referenced in `controls` via a\n  variable in the form `$<component>svc`. In the example below, the selected \n  kubelet unitfile is referenced with `$kubeletsvc` in the `remediation` of the \n  `check`.\n  \n  ```yml\n  id: 2.1.1\n    # ...\n    remediation: |\n      Edit the kubelet service file $kubeletsvc\n      on each worker node and set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n      --allow-privileged=false\n      Based on your system, restart the kubelet service. For example:\n      systemctl daemon-reload\n      systemctl restart kubelet.service\n    # ...\n  ```\n  \n  - `kubeconfig`: A list of candidate kubeconfig files for a component. `kube-bench`\n    checks this list and selects the **first** file that is found on the node. If none\n    of the files exists, `kube-bench` defaults kubeconfig to the value of \n    `defaultkubeconfig`.\n    \n    The selected kubeconfig for a component can be referenced in `controls` with a variable in the form `$<component>kubeconfig`. In the example below, the\n    selected kubelet kubeconfig is referenced with `$kubeletkubeconfig` in the\n    `audit` command.\n    \n    ```yml\n    id: 2.2.1\n      text: \"Ensure that the kubelet.conf file permissions are set to 644 or\n      more restrictive (Scored)\"\n      audit: \"/bin/sh -c 'if test -e $kubeletkubeconfig; then stat -c %a $kubeletkubeconfig; fi'\"\n      # ...\n    ```\n"
  },
  {
    "path": "docs/flags-and-commands.md",
    "content": "## Commands \nCommand | Description\n--- | ---\nhelp | Prints help about any command\nrun | List of components to run \nversion | Print kube-bench version\n\n## Flags\nFlag | Description\n--- | ---\n--alsologtostderr | log to standard error as well as files\n--asff | Send findings to AWS Security Hub for any benchmark tests that fail or that generate a warning. See [this page][kube-bench-aws-security-hub] for more information on how to enable the kube-bench integration with AWS Security Hub.\n--benchmark | Manually specify CIS benchmark version \n-c, --check | A comma-delimited list of checks to run as specified in Benchmark document.\n--config | config file (default is ./cfg/config.yaml)\n--exit-code | Specify the exit code for when checks fail\n--group | Run all the checks under this comma-delimited list of groups.\n--include-test-output | Prints the actual result when test fails.\n--json | Prints the results as JSON\n--junit | Prints the results as JUnit\n--log_backtrace_at traceLocation | when logging hits line file:N, emit a stack trace (default :0)\n--logtostderr | log to standard error instead of files\n--noremediations | Disable printing of remediations section to stdout.\n--noresults | Disable printing of results section to stdout.\n--nototals | Disable calculating and printing of totals for failed, passed, ... checks across all sections \n--outputfile | Writes the results to output file when run with --json or --junit\n--pgsql | Save the results to PostgreSQL\n--scored | Run the scored CIS checks (default true)\n--skip string | List of comma separated values of checks to be skipped\n--stderrthreshold severity | logs at or above this threshold go to stderr (default 2)\n-v, --v Level | log level for V logs (default 0)\n--unscored | Run the unscored CIS checks (default true)\n--version string | Manually specify Kubernetes version, automatically detected if unset\n--vmodule moduleSpec | comma-separated list of pattern=N settings for file-filtered logging\n\n### Examples \n\n#### Report kube-bench findings to AWS Security Hub\n\nYou can configure kube-bench with the `--asff` option to send findings to AWS Security Hub for any benchmark tests that fail or that generate a warning. See [this page](asff.md) for more information on how to enable the kube-bench integration with AWS Security Hub.\n\n#### Specifying the benchmark or Kubernetes version\n\n`kube-bench` uses the Kubernetes API, or access to the `kubectl` or `kubelet` executables to try to determine the Kubernetes version, and hence which benchmark to run. If you wish to override this, or if none of these methods are available, you can specify either the Kubernetes version or CIS Benchmark as a command line parameter.  \n\nYou can specify a particular version of Kubernetes by setting the `--version` flag or with the `KUBE_BENCH_VERSION` environment variable. The value of `--version` takes precedence over the value of `KUBE_BENCH_VERSION`.\n\nFor example, run kube-bench using the tests for Kubernetes version 1.13:\n\n```\nkube-bench --version 1.13\n```\n\n\nYou can specify `--benchmark` to run a specific CIS Benchmark version:\n\n```\nkube-bench --benchmark cis-1.5\n```\n\n**Note:**  It is an error to specify both `--version` and `--benchmark` flags together\n\n#### Specifying Benchmark sections\n\nIf you want to run specific CIS Benchmark sections (i.e master, node, etcd, etc...)\nyou can use the `run --targets` subcommand.\n\n```\nkube-bench run --targets master,node\n```\n\nor\n\n```\nkube-bench run --targets master,node,etcd,policies\n```\n\n\nIf no targets are specified, `kube-bench` will determine the appropriate targets based on the CIS Benchmark version and the components detected on the node. The detection is done by verifying which components are running, as defined in the config files (see [Configuration](controls.md#configuration-and-variables).\n\n#### Run specific check or group\n\n`kube-bench` supports running individual checks by specifying the check's `id`\nas a comma-delimited list on the command line with the `--check` | `-c` flag.\n`kube-bench --check=\"1.1.1,1.1.2,1.2.1,1.3.3\"`\n\n`kube-bench` supports running all checks under group by specifying the group's `id`\nas a comma-delimited list on the command line with the `--group` | `-g` flag.\n`kube-bench --check=\"1.1,2.2\"`\nWill run all checks 1.1.X and 2.2.X. \n\n#### Skip specific check or group\n\n`kube-bench` supports skipping checks or groups by specifying the `id`\nas a comma-delimited list on the command line with the `--skip` flag.\n`kube-bench --skip=\"1.1,1.2.1,1.3.3\"`\nWill skip 1.1.X group and individual checks 1.2.1, 1.3.3.\nSkipped checks returns [INFO] output. \n\n#### Exit code\n\n`kube-bench` supports using uniqe exit code when failing a check or more. \n`kube-bench --exit-code 42` \nWill return 42 if one check or more failed, and 0 incase none failed. \n**Note:** [WARN] is not [FAIL].\n\n#### Output manipulation flags\n\nThere are four output states:\n- [PASS] indicates that the test was run successfully, and passed.\n- [FAIL] indicates that the test was run successfully, and failed. The remediation output describes how to correct the configuration, or includes an error message describing why the test could not be run.\n- [WARN] means this test needs further attention, for example it is a test that needs to be run manually. Check the remediation output for further information.\n- [INFO] is informational output that needs no further action.\n\nNote:\n- Some tests with `Automated` in their description must still be run manually\n- If the user has to run a test manually, this always generates WARN\n- If the test is Scored, and kube-bench was unable to run the test, this generates FAIL (because the test has not been passed, and as a Scored test, if it doesn't pass then it must be considered a failure).\n- If the test is Not Scored, and kube-bench was unable to run the test, this generates WARN.\n- If the test is Scored, type is empty, and there are no `test_items` present, it generates a WARN. This is to highlight tests that appear to be incompletely defined.\n\n`kube-bench` supports multiple output manipulation flags. \n`kube-bench --include-test-output` will print failing checks output in the results section\n```\n[INFO] 1 Master Node Security Configuration\n[INFO] 1.1 Master Node Configuration Files\n[FAIL] 1.1.1 Ensure that the API server pod specification file permissions are set to 644 or more restrictive (Automated)\n         **permissions=777**\n```\n\n**Note:** `--noresults` `--noremediations` and `--include-test-output` **will not** effect the json output but only stdout. \nOnly `--nototals` will effect the json output and thats because it will not call the function to calculate totals. \n\n\n#### Troubleshooting\n\nRunning `kube-bench` with the `-v 3` parameter will generate debug logs that can be very helpful for debugging problems.\n\nIf you are using one of the example `job*.yaml` files, you will need to edit the `command` field, for example `[\"kube-bench\", \"-v\", \"3\"]`. Once the job has run, the logs can be retrieved using `kubectl logs` on the job's pod.\n"
  },
  {
    "path": "docs/index.md",
    "content": "[download]: https://img.shields.io/github/downloads/aquasecurity/kube-bench/total?logo=github\n[release-img]: https://img.shields.io/github/release/aquasecurity/kube-bench.svg?logo=github\n[release]: https://github.com/aquasecurity/kube-bench/releases\n[docker-pull]: https://img.shields.io/docker/pulls/aquasec/kube-bench?logo=docker&label=docker%20pulls%20%2F%20kube-bench\n[docker]: https://hub.docker.com/r/aquasec/kube-bench\n[cov-img]: https://codecov.io/github/aquasecurity/kube-bench/branch/main/graph/badge.svg\n[cov]: https://codecov.io/github/aquasecurity/kube-bench\n[report-card-img]: https://goreportcard.com/badge/github.com/aquasecurity/kube-bench\n[report-card]: https://goreportcard.com/report/github.com/aquasecurity/kube-bench\n\n![Kube-bench Logo](images/kube-bench.jpg)\n[![GitHub Release][release-img]][release]\n[![Downloads][download]][release]\n[![Docker Pulls][docker-pull]][docker]\n[![Go Report Card][report-card-img]][report-card]\n[![Build Status](https://github.com/aquasecurity/kube-bench/workflows/Build/badge.svg?branch=main)](https://github.com/aquasecurity/kube-bench/actions)\n[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://github.com/aquasecurity/kube-bench/blob/main/LICENSE)\n[![Coverage Status][cov-img]][cov]\n\n\n# Kube-bench \n\nkube-bench is a Go application that checks whether Kubernetes is deployed securely by running the checks documented in the [CIS Kubernetes Benchmark](https://www.cisecurity.org/benchmark/kubernetes/).\n\nTests are configured with YAML files, making this tool easy to update as test specifications evolve.\n\n\n1. kube-bench implements the [CIS Kubernetes Benchmark](https://www.cisecurity.org/benchmark/kubernetes/) as closely as possible. Please raise issues here if kube-bench is not correctly implementing the test as described in the Benchmark. To report issues in the Benchmark itself (for example, tests that you believe are inappropriate), please join the [CIS community](https://cisecurity.org).\n\n1. There is not a one-to-one mapping between releases of Kubernetes and releases of the CIS benchmark. See [CIS Kubernetes Benchmark support](#cis-kubernetes-benchmark-support) to see which releases of Kubernetes are covered by different releases of the benchmark.\n\n1. It is impossible to inspect the master nodes of managed clusters, e.g. GKE, EKS, AKS and ACK, using kube-bench as one does not have access to such nodes, although it is still possible to use kube-bench to check worker node configuration in these environments.\n\nFor help and more information go to our [github discussions q&a](https://github.com/aquasecurity/kube-bench/discussions/categories/q-a)\n"
  },
  {
    "path": "docs/installation.md",
    "content": "## Installation\n\nYou can choose to\n* Run kube-bench from inside a container (sharing PID namespace with the host). See [Running inside a container](./running.md#running-inside-a-container) for additional details.\n* Run a container that installs kube-bench on the host, and then run kube-bench directly on the host. See [Installing from a container](#installing-from-a-container) for additional details.\n* install the latest binaries from the [Releases page](https://github.com/aquasecurity/kube-bench/releases), though please note that you also need to download the config and test files from the `cfg` directory. See [Download and Install binaries](#download-and-install-binaries) for details.\n* Compile it from source. See [Installing from sources](#installing-from-sources) for details.\n\n\n### Download and Install binaries\n\nIt is possible to manually install and run kube-bench release binaries. In order to do that, you must have access to your Kubernetes cluster nodes. Note that if you're using one of the managed Kubernetes services (e.g. EKS, AKS, GKE, ACK, OCP), you will not have access to the master nodes of your cluster and you can’t perform any tests on the master nodes.\n\nFirst, log into one of the nodes using SSH.\n\nInstall kube-bench binary for your platform using the commands below. Note that there may be newer releases available. See [releases page](https://github.com/aquasecurity/kube-bench/releases).\n\nUbuntu/Debian:\n\n```\nKUBE_BENCH_VERSION=0.10.1\n\ncurl -L https://github.com/aquasecurity/kube-bench/releases/download/v${KUBE_BENCH_VERSION}/kube-bench_${KUBE_BENCH_VERSION}_linux_amd64.deb -o kube-bench_${KUBE_BENCH_VERSION}_linux_amd64.deb\n\nsudo apt install ./kube-bench_${KUBE_BENCH_VERSION}_linux_amd64.deb -f\n```\n\nRHEL:\n\n```\nKUBE_BENCH_VERSION=0.10.1\n\ncurl -L https://github.com/aquasecurity/kube-bench/releases/download/v${KUBE_BENCH_VERSION}/kube-bench_${KUBE_BENCH_VERSION}_linux_amd64.rpm -o kube-bench_${KUBE_BENCH_VERSION}_linux_amd64.rpm\n\nsudo yum install kube-bench_${KUBE_BENCH_VERSION}_linux_amd64.rpm -y\n```\n\nAlternatively, you can manually download and extract the kube-bench binary:\n\n```\nKUBE_BENCH_VERSION=0.10.1\n\ncurl -L https://github.com/aquasecurity/kube-bench/releases/download/v${KUBE_BENCH_VERSION}/kube-bench_${KUBE_BENCH_VERSION}_linux_amd64.tar.gz -o kube-bench_${KUBE_BENCH_VERSION}_linux_amd64.tar.gz\n\ntar -xvf kube-bench_${KUBE_BENCH_VERSION}_linux_amd64.tar.gz\n```\n\nYou can then run kube-bench directly:\n```\nkube-bench\n```\n\nIf you manually downloaded the kube-bench binary (using curl command above), you have to specify the location of configuration directory and file. For example:\n```\n./kube-bench --config-dir `pwd`/cfg --config `pwd`/cfg/config.yaml \n```\n\nSee previous section on [Running kube-bench](./running.md#running-kube-bench) for further details on using the kube-bench binary.\n\n### Installing from sources\n\nIf Go is installed on the target machines, you can simply clone this repository and run as follows (assuming your [`GOPATH` is set](https://github.com/golang/go/wiki/GOPATH)) as per this example:\n\n```shell\n# Create a target directory for the clone, inside the $GOPATH\nmkdir -p $GOPATH/src/github.com/aquasecurity/kube-bench\n\n# Clone this repository, using SSH\ngit clone git@github.com:aquasecurity/kube-bench.git $GOPATH/src/github.com/aquasecurity/kube-bench\n\n# Install the pre-requisites\ngo get github.com/aquasecurity/kube-bench\n\n# Change to the kube-bench directory\ncd $GOPATH/src/github.com/aquasecurity/kube-bench\n\n# Build the kube-bench binary\ngo build -o kube-bench .\n\n# See all supported options\n./kube-bench --help\n\n# Run all checks\n./kube-bench\n```\n\n\n### Installing from a container\n\nThis command copies the kube-bench binary and configuration files to your host from the Docker container:\n**binaries compiled for linux-x86-64 only (so they won't run on macOS or Windows)**\n```\ndocker run --rm -v `pwd`:/host docker.io/aquasec/kube-bench:latest install\n```\n\nYou can then run `./kube-bench`.\n"
  },
  {
    "path": "docs/platforms.md",
    "content": "\n## CIS Kubernetes Benchmark support\n\nkube-bench runs industry standard benchmark tests for Kubernetes.\nMost of our supported benchmarks are defined in either of the following:\n* [CIS Kubernetes Benchmarks](https://www.cisecurity.org/benchmark/kubernetes/)\n* [STIG Document Library](https://public.cyber.mil/stigs/downloads)\n\nOther benchmarks are defined by hardening guides.\n\n| Source | Kubernetes Benchmark                                                                                                                                                                              | kube-bench config        | Kubernetes versions |\n|:------:|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-------------------------|:--------------------|\n| CIS    | [1.5.1](https://workbench.cisecurity.org/benchmarks/4892)                                                                                                                                         | cis-1.5                  | 1.15                |\n| CIS    | [1.6.0](https://workbench.cisecurity.org/benchmarks/4834)                                                                                                                                         | cis-1.6                  | 1.16-1.18           |\n| CIS    | [1.20](https://workbench.cisecurity.org/benchmarks/6246)                                                                                                                                          | cis-1.20                 | 1.19-1.21           |\n| CIS    | [1.23](https://workbench.cisecurity.org/benchmarks/7532)                                                                                                                                          | cis-1.23                 | 1.22-1.23           |\n| CIS    | [1.24](https://workbench.cisecurity.org/benchmarks/10873)                                                                                                                                         | cis-1.24                 | 1.24                |\n| CIS    | [1.7](https://workbench.cisecurity.org/benchmarks/11107)                                                                                                                                          | cis-1.7                  | 1.25                |\n| CIS    | [1.8](https://workbench.cisecurity.org/benchmarks/12958)                                                                                                                                          | cis-1.8                  | 1.26                |\n| CIS    | [1.9](https://workbench.cisecurity.org/benchmarks/16828)                                                                                                                                          | cis-1.9                  | 1.27                |\n| CIS    | [1.10](https://workbench.cisecurity.org/benchmarks/17568)                                                                                                                                         | cis-1.10                  | 1.28               |\n| CIS    | [1.11](https://workbench.cisecurity.org/benchmarks/21709)                                                                                                                                         | cis-1.11                  | 1.29-1.31          |\n| CIS    | [1.12](https://workbench.cisecurity.org/benchmarks/22107)                                                                                                                                         | cis-1.12                  | 1.32-1.34          |\n| CIS    | [GKE 1.0.0](https://workbench.cisecurity.org/benchmarks/4536)                                                                                                                                     | gke-1.0                  | GKE                 |\n| CIS    | [GKE 1.2.0](https://workbench.cisecurity.org/benchmarks/7534)                                                                                                                                     | gke-1.2.0                | GKE                 |\n| CIS    | [GKE 1.6.0](https://workbench.cisecurity.org/benchmarks/16093)                                                                                                                                    | gke-1.6.0                | GKE                 |\n| CIS    | [EKS 1.0.1](https://workbench.cisecurity.org/benchmarks/6041)                                                                                                                                     | eks-1.0.1                | EKS                 |\n| CIS    | [EKS 1.1.0](https://workbench.cisecurity.org/benchmarks/6248)                                                                                                                                     | eks-1.1.0                | EKS                 |\n| CIS    | [EKS 1.2.0](https://workbench.cisecurity.org/benchmarks/9681)                                                                                                                                     | eks-1.2.0                | EKS                 |\n| CIS    | [EKS 1.5.0](https://workbench.cisecurity.org/benchmarks/17733)                                                                                                                                    | eks-1.5.0                | EKS                 |\n| CIS    | [ACK 1.0.0](https://workbench.cisecurity.org/benchmarks/6467)                                                                                                                                     | ack-1.0                  | ACK                 |\n| CIS    | [AKS 1.0.0](https://workbench.cisecurity.org/benchmarks/6347)                                                                                                                                     | aks-1.0                  | AKS                 |\n| CIS    | [AKS 1.7.0](https://workbench.cisecurity.org/benchmarks/20359)                                                                                                                                    | aks-1.7                  | AKS                 |\n| RHEL   | Red Hat OpenShift hardening guide                                                                                                                                                                 | rh-0.7                   | OCP 3.10-3.11       |\n| CIS    | [OCP4 1.1.0](https://workbench.cisecurity.org/benchmarks/6778)                                                                                                                                    | rh-1.0                   | OCP 4.1-            |\n| CIS    | [1.6.0-k3s](https://docs.rancher.cn/docs/k3s/security/self-assessment/_index)                                                                                                                     | cis-1.6-k3s              | k3s v1.16-v1.24     |\n| DISA   | [Kubernetes Ver 1, Rel 6](https://dl.dod.cyber.mil/wp-content/uploads/stigs/zip/U_Kubernetes_V1R6_STIG.zip)                                                                                       | eks-stig-kubernetes-v1r6 | EKS                 |\n| CIS    | [TKGI 1.2.53](https://network.pivotal.io/products/p-compliance-scanner#/releases/1248397)                                                                                                         | tkgi-1.2.53              | vmware              |\n| CIS    | [1.7.0-rke](https://ranchermanager.docs.rancher.com/v2.7/reference-guides/rancher-security/hardening-guides/rke1-hardening-guide/rke1-self-assessment-guide-with-cis-v1.7-k8s-v1.25-v1.26-v1.27)  | rke-cis-1.7              | rke v1.25-v1.27     |\n| CIS    | [1.7.0-rke2](https://ranchermanager.docs.rancher.com/v2.7/reference-guides/rancher-security/hardening-guides/rke2-hardening-guide/rke2-self-assessment-guide-with-cis-v1.7-k8s-v1.25-v1.26-v1.27) | rke2-cis-1.6             | rke2 v1.25-v1.27    |\n| CIS    | [1.7.0-k3s](https://ranchermanager.docs.rancher.com/v2.7/reference-guides/rancher-security/hardening-guides/k3s-hardening-guide/k3s-self-assessment-guide-with-cis-v1.7-k8s-v1.25-v1.26-v1.27)    | k3s-cis-1.7              | k3s v1.25-v1.27     |\n"
  },
  {
    "path": "docs/running.md",
    "content": "\n## Running kube-bench\n\nIf you run kube-bench directly from the command line you may need to be root / sudo to have access to all the config files.\n\nBy default kube-bench attempts to auto-detect the running version of Kubernetes, and map this to the corresponding CIS Benchmark version. For example, Kubernetes version 1.15 is mapped to CIS Benchmark version `cis-1.15` which is the benchmark version valid for Kubernetes 1.15.\n\nkube-bench also attempts to identify the components running on the node, and uses this to determine which tests to run (for example, only running the master node tests if the node is running an API server). \n\n**Please note**\nIt is impossible to inspect the master nodes of managed clusters, e.g. GKE, EKS, AKS and ACK, using kube-bench as one does not have access to such nodes, although it is still possible to use kube-bench to check worker node configuration in these environments.\n\n### Running inside a container\n\nYou can avoid installing kube-bench on the host by running it inside a container using the host PID namespace and mounting the `/etc` and `/var` directories where the configuration and other files are located on the host so that kube-bench can check their existence and permissions.\n\n```\ndocker run --pid=host -v /etc:/etc:ro -v /var:/var:ro -t docker.io/aquasec/kube-bench:latest --version 1.18\n```\n\n> Note: the tests require either the kubelet or kubectl binary in the path in order to auto-detect the Kubernetes version. You can pass `-v $(which kubectl):/usr/local/mount-from-host/bin/kubectl` to resolve this. You will also need to pass in kubeconfig credentials. For example:\n\n```\ndocker run --pid=host -v /etc:/etc:ro -v /var:/var:ro -v $(which kubectl):/usr/local/mount-from-host/bin/kubectl -v ~/.kube:/.kube -e KUBECONFIG=/.kube/config -t docker.io/aquasec/kube-bench:latest \n```\n\nYou can use your own configs by mounting them over the default ones in `/opt/kube-bench/cfg/`\n\n```\ndocker run --pid=host -v /etc:/etc:ro -v /var:/var:ro -t -v path/to/my-config.yaml:/opt/kube-bench/cfg/config.yaml -v $(which kubectl):/usr/local/mount-from-host/bin/kubectl -v ~/.kube:/.kube -e KUBECONFIG=/.kube/config docker.io/aquasec/kube-bench:latest\n```\n\n### Running in a Kubernetes cluster\n\nYou can run kube-bench inside a pod, but it will need access to the host's PID namespace in order to check the running processes, as well as access to some directories on the host where config files and other files are stored.\n\nThe `job.yaml` file (available in the root directory of the repository) can be applied to run the tests as a Kubernetes `Job`. For example:\n\n```bash\n$ kubectl apply -f job.yaml\njob.batch/kube-bench created\n\n$ kubectl get pods\nNAME                      READY   STATUS              RESTARTS   AGE\nkube-bench-j76s9   0/1     ContainerCreating   0          3s\n\n# Wait for a few seconds for the job to complete\n$ kubectl get pods\nNAME                      READY   STATUS      RESTARTS   AGE\nkube-bench-j76s9   0/1     Completed   0          11s\n\n# The results are held in the pod's logs\nkubectl logs kube-bench-j76s9\n[INFO] 1 Master Node Security Configuration\n[INFO] 1.1 API Server\n...\n```\n\nTo run tests on the master node, the pod needs to be scheduled on that node. This involves setting a nodeSelector and tolerations in the pod spec.\n\nThe default labels applied to master nodes has changed since Kubernetes 1.11, so if you are using an older version you may need to modify the nodeSelector and tolerations to run the job on the master node.\n### Running in an AKS cluster\n\n1. Create an AKS cluster(e.g. 1.13.7) with RBAC enabled, otherwise there would be 4 failures\n\n1. Use the [kubectl-enter plugin](https://github.com/kvaps/kubectl-enter) to shell into a node\n`\nkubectl-enter {node-name}\n`\nor ssh to one agent node\ncould open nsg 22 port and assign a public ip for one agent node (only for testing purpose)\n\n1. Run CIS benchmark to view results:\n```\ndocker run --rm -v `pwd`:/host docker.io/aquasec/kube-bench:latest install\n./kube-bench \n```\nkube-bench cannot be run on AKS master nodes\n\n### Running CIS benchmark in an EKS cluster\n\nThere is a `job-eks.yaml` file for running the kube-bench node checks on an EKS cluster. The significant difference on EKS is that it's not possible to schedule jobs onto the master node, so master checks can't be performed\n\n1. To create an EKS Cluster refer to [Getting Started with Amazon EKS](https://docs.aws.amazon.com/eks/latest/userguide/getting-started.html) in the *Amazon EKS User Guide*\n  - Information on configuring `eksctl`, `kubectl` and the AWS CLI is within\n2. Create an [Amazon Elastic Container Registry (ECR)](https://docs.aws.amazon.com/AmazonECR/latest/userguide/what-is-ecr.html) repository to host the kube-bench container image\n```\naws ecr create-repository --repository-name k8s/kube-bench --image-tag-mutability MUTABLE\n```\n3. Download, build and push the kube-bench container image to your ECR repo\n```\ngit clone https://github.com/aquasecurity/kube-bench.git\ncd kube-bench\naws ecr get-login-password --region <AWS_REGION> | docker login --username AWS --password-stdin <AWS_ACCT_NUMBER>.dkr.ecr.<AWS_REGION>.amazonaws.com\nmake build-docker IMAGE_NAME=k8s/kube-bench\ndocker tag k8s/kube-bench:latest <AWS_ACCT_NUMBER>.dkr.ecr.<AWS_REGION>.amazonaws.com/k8s/kube-bench:latest\ndocker push <AWS_ACCT_NUMBER>.dkr.ecr.<AWS_REGION>.amazonaws.com/k8s/kube-bench:latest\n```\n4. Copy the URI of your pushed image, the URI format is like this: `<AWS_ACCT_NUMBER>.dkr.ecr.<AWS_REGION>.amazonaws.com/k8s/kube-bench:latest`\n5. Replace the `image` value in `job-eks.yaml` with the URI from Step 4\n6. Run the kube-bench job on a Pod in your Cluster: `kubectl apply -f job-eks.yaml`\n7. Find the Pod that was created, it *should* be in the `default` namespace: `kubectl get pods --all-namespaces`\n8. Retrieve the value of this Pod and output the report, note the Pod name will vary: `kubectl logs kube-bench-<value>`\n  - You can save the report for later reference: `kubectl logs kube-bench-<value> > kube-bench-report.txt`\n\n### Running DISA STIG in an EKS cluster\n\nThere is a `job-eks-stig.yaml` file for running the kube-bench node checks on an EKS cluster. The significant difference on EKS is that it's not possible to schedule jobs onto the master node, so master checks can't be performed\n\n1. To create an EKS Cluster refer to [Getting Started with Amazon EKS](https://docs.aws.amazon.com/eks/latest/userguide/getting-started.html) in the *Amazon EKS User Guide*\n  - Information on configuring `eksctl`, `kubectl` and the AWS CLI is within\n2. Create an [Amazon Elastic Container Registry (ECR)](https://docs.aws.amazon.com/AmazonECR/latest/userguide/what-is-ecr.html) repository to host the kube-bench container image\n```\naws ecr create-repository --repository-name k8s/kube-bench --image-tag-mutability MUTABLE\n```\n3. Download, build and push the kube-bench container image to your ECR repo\n```\ngit clone https://github.com/aquasecurity/kube-bench.git\ncd kube-bench\naws ecr get-login-password --region <AWS_REGION> | docker login --username AWS --password-stdin <AWS_ACCT_NUMBER>.dkr.ecr.<AWS_REGION>.amazonaws.com\ndocker build -t k8s/kube-bench .\ndocker tag k8s/kube-bench:latest <AWS_ACCT_NUMBER>.dkr.ecr.<AWS_REGION>.amazonaws.com/k8s/kube-bench:latest\ndocker push <AWS_ACCT_NUMBER>.dkr.ecr.<AWS_REGION>.amazonaws.com/k8s/kube-bench:latest\n```\n4. Copy the URI of your pushed image, the URI format is like this: `<AWS_ACCT_NUMBER>.dkr.ecr.<AWS_REGION>.amazonaws.com/k8s/kube-bench:latest`\n5. Replace the `image` value in `job-eks-stig.yaml` with the URI from Step 4\n6. Run the kube-bench job on a Pod in your Cluster: `kubectl apply -f job-eks-stig.yaml`\n7. Find the Pod that was created, it *should* be in the `default` namespace: `kubectl get pods --all-namespaces`\n8. Retrieve the value of this Pod and output the report, note the Pod name will vary: `kubectl logs kube-bench-<value>`\n  - You can save the report for later reference: `kubectl logs kube-bench-<value> > kube-bench-report.txt`\n\n### Running on OpenShift\n\n| OpenShift Hardening Guide | kube-bench config |\n| ------------------------- | ----------------- |\n| ocp-3.10 +                | rh-0.7            |\n| ocp-4.1 +                 | rh-1.0            |\n\nkube-bench includes a set of test files for Red Hat's OpenShift hardening guide for OCP 3.10 and 4.1. To run this you will need to specify `--benchmark rh-07`, or `--version ocp-3.10` or,`--version ocp-4.5` or `--benchmark rh-1.0` \n\n`kube-bench` supports auto-detection, when you run the `kube-bench` command it will autodetect if running in openshift environment.\n\nSince running `kube-bench` requires elevated privileges, the `privileged` SecurityContextConstraint needs to be applied to the ServiceAccount used for the `Job`:\n\n```\noc create namespace kube-bench\noc adm policy add-scc-to-user privileged --serviceaccount default\noc apply -f job.yaml\n```\n\n### Running in a GKE cluster\n\n| CIS Benchmark | Targets                                                     |\n| ------------- | ----------------------------------------------------------- |\n| gke-1.0       | master, controlplane, node, etcd, policies, managedservices |\n| gke-1.2.0     | master, controlplane, node, policies, managedservices       |\n| gke-1.6.0     | master, controlplane, node, policies, managedservices       |\n\nkube-bench includes benchmarks for GKE. To run this you will need to specify `--benchmark gke-1.0`, `--benchmark gke-1.2.0` or `--benchmark gke-1.6.0` when you run the `kube-bench` command.\n\nTo run the benchmark as a job in your GKE cluster apply the included `job-gke.yaml`.\n\n```\nkubectl apply -f job-gke.yaml\n```\n\n### Running in a ACK cluster\n\n| CIS Benchmark | Targets                                                     |\n| ------------- | ----------------------------------------------------------- |\n| ack-1.0       | master, controlplane, node, etcd, policies, managedservices |\n\nkube-bench includes benchmarks for Alibaba Cloud Container Service For Kubernetes (ACK).\nTo run this you will need to specify `--benchmark ack-1.0` when you run the `kube-bench` command.\n\nTo run the benchmark as a job in your ACK cluster apply the included `job-ack.yaml`.\n\n```\nkubectl apply -f job-ack.yaml\n```\n\n### Running in a VMware TKGI cluster\n\n| CIS Benchmark | Targets                                    |\n|---------------|--------------------------------------------|\n| tkgi-1.2.53   | master, etcd, controlplane, node, policies |\n\nkube-bench includes benchmarks for VMware tkgi platform.\nTo run this you will need to specify `--benchmark tkgi-1.2.53` when you run the `kube-bench` command.\n\nTo run the benchmark as a job in your VMware tkgi cluster apply the included `job-tkgi.yaml`.\n\n```\nkubectl apply -f job-tkgi.yaml\n```\n\n### Running in a Rancher RKE cluster\n\n| CIS Benchmark | Targets                                    |\n|---------------|--------------------------------------------|\n| rke-cis-1.7   | master, etcd, controlplane, node, policies |\n\nkube-bench includes benchmarks for Rancher RKE platform.\nTo run this you will need to specify `--benchmark rke-cis-1.7` when you run the `kube-bench` command.\n\n### Running in a Rancher RKE2 cluster\n\n| CIS Benchmark | Targets                                    |\n|---------------|--------------------------------------------|\n| rke2-cis-1.7  | master, etcd, controlplane, node, policies |\n\nkube-bench includes benchmarks for Rancher RKE2 platform.\nTo run this you will need to specify `--benchmark rke2-cis-1.7` when you run the `kube-bench` command.\n\n### Running in a Rancher K3s cluster\n\n| CIS Benchmark | Targets                                    |\n|---------------|--------------------------------------------|\n| k3s-cis-1.7   | master, etcd, controlplane, node, policies |\n\nkube-bench includes benchmarks for Rancher K3S platform.\nTo run this you will need to specify `--benchmark k3s-cis-1.7` when you run the `kube-bench` command.\n"
  },
  {
    "path": "entrypoint.sh",
    "content": "#!/bin/sh -e\nif [ \"$1\" == \"install\" ]; then\n  if [ -d /host ]; then\n    mkdir -p /host/cfg/\n    yes | cp -rf cfg/* /host/cfg/\n    yes | cp -rf /usr/local/bin/kube-bench /host/\n    echo \"===============================================\"\n    echo \"kube-bench is now installed on your host       \"\n    echo \"Run ./kube-bench to perform a security check   \"\n    echo \"===============================================\"\n  else\n    echo \"Usage:\"\n    echo \"  install: docker run --rm -v \\`pwd\\`:/host aquasec/kube-bench install\"\n    echo \"  run:     docker run --rm --pid=host aquasec/kube-bench [command]\"\n    exit\n  fi\nelse\n  exec kube-bench \"$@\"\nfi\n"
  },
  {
    "path": "fipsonly.go",
    "content": "//go:build fipsonly\n\npackage main\n\nimport (\n\t_ \"crypto/tls/fipsonly\"\n)\n"
  },
  {
    "path": "go.mod",
    "content": "module github.com/aquasecurity/kube-bench\n\ngo 1.25.0\n\nrequire (\n\tgithub.com/aws/aws-sdk-go-v2 v1.41.4\n\tgithub.com/aws/aws-sdk-go-v2/config v1.32.12\n\tgithub.com/aws/aws-sdk-go-v2/service/securityhub v1.68.2\n\tgithub.com/fatih/color v1.18.0\n\tgithub.com/golang/glog v1.2.5\n\tgithub.com/magiconair/properties v1.8.10\n\tgithub.com/onsi/ginkgo v1.16.5\n\tgithub.com/pkg/errors v0.9.1\n\tgithub.com/spf13/cobra v1.10.2\n\tgithub.com/spf13/viper v1.21.0\n\tgithub.com/stretchr/testify v1.11.1\n\tgolang.org/x/exp v0.0.0-20250718183923-645b1fa84792\n\tgopkg.in/yaml.v2 v2.4.0\n\tgorm.io/driver/postgres v1.6.0\n\tgorm.io/gorm v1.31.1\n\tk8s.io/apimachinery v0.35.2\n\tk8s.io/client-go v0.35.2\n)\n\nrequire (\n\tgithub.com/aws/aws-sdk-go-v2/credentials v1.19.12 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.20 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/internal/configsources v1.4.20 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.20 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/internal/ini v1.8.6 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.7 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.20 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/service/signin v1.0.8 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/service/sso v1.30.13 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.17 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/service/sts v1.41.9 // indirect\n\tgithub.com/aws/smithy-go v1.24.2 // indirect\n\tgithub.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect\n\tgithub.com/emicklei/go-restful/v3 v3.12.2 // indirect\n\tgithub.com/fsnotify/fsnotify v1.9.0 // indirect\n\tgithub.com/fxamacker/cbor/v2 v2.9.0 // indirect\n\tgithub.com/go-logr/logr v1.4.3 // indirect\n\tgithub.com/go-openapi/jsonpointer v0.21.0 // indirect\n\tgithub.com/go-openapi/jsonreference v0.20.2 // indirect\n\tgithub.com/go-openapi/swag v0.23.0 // indirect\n\tgithub.com/go-viper/mapstructure/v2 v2.4.0 // indirect\n\tgithub.com/google/gnostic-models v0.7.0 // indirect\n\tgithub.com/google/uuid v1.6.0 // indirect\n\tgithub.com/inconshreveable/mousetrap v1.1.0 // indirect\n\tgithub.com/jackc/pgpassfile v1.0.0 // indirect\n\tgithub.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect\n\tgithub.com/jackc/pgx/v5 v5.6.0 // indirect\n\tgithub.com/jackc/puddle/v2 v2.2.2 // indirect\n\tgithub.com/jinzhu/inflection v1.0.0 // indirect\n\tgithub.com/jinzhu/now v1.1.5 // indirect\n\tgithub.com/josharian/intern v1.0.0 // indirect\n\tgithub.com/json-iterator/go v1.1.12 // indirect\n\tgithub.com/mailru/easyjson v0.7.7 // indirect\n\tgithub.com/mattn/go-colorable v0.1.13 // indirect\n\tgithub.com/mattn/go-isatty v0.0.20 // indirect\n\tgithub.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect\n\tgithub.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect\n\tgithub.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect\n\tgithub.com/pelletier/go-toml/v2 v2.2.4 // indirect\n\tgithub.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect\n\tgithub.com/sagikazarmark/locafero v0.11.0 // indirect\n\tgithub.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect\n\tgithub.com/spf13/afero v1.15.0 // indirect\n\tgithub.com/spf13/cast v1.10.0 // indirect\n\tgithub.com/spf13/pflag v1.0.10 // indirect\n\tgithub.com/stretchr/objx v0.5.2 // indirect\n\tgithub.com/subosito/gotenv v1.6.0 // indirect\n\tgithub.com/x448/float16 v0.8.4 // indirect\n\tgo.yaml.in/yaml/v2 v2.4.3 // indirect\n\tgo.yaml.in/yaml/v3 v3.0.4 // indirect\n\tgolang.org/x/crypto v0.45.0 // indirect\n\tgolang.org/x/net v0.47.0 // indirect\n\tgolang.org/x/oauth2 v0.30.0 // indirect\n\tgolang.org/x/sync v0.18.0 // indirect\n\tgolang.org/x/sys v0.38.0 // indirect\n\tgolang.org/x/term v0.37.0 // indirect\n\tgolang.org/x/text v0.31.0 // indirect\n\tgolang.org/x/time v0.9.0 // indirect\n\tgoogle.golang.org/protobuf v1.36.8 // indirect\n\tgopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect\n\tgopkg.in/inf.v0 v0.9.1 // indirect\n\tgopkg.in/yaml.v3 v3.0.1 // indirect\n\tk8s.io/api v0.35.2 // indirect\n\tk8s.io/klog/v2 v2.130.1 // indirect\n\tk8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 // indirect\n\tk8s.io/utils v0.0.0-20251002143259-bc988d571ff4 // indirect\n\tsigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect\n\tsigs.k8s.io/randfill v1.0.0 // indirect\n\tsigs.k8s.io/structured-merge-diff/v6 v6.3.0 // indirect\n\tsigs.k8s.io/yaml v1.6.0 // indirect\n)\n"
  },
  {
    "path": "go.sum",
    "content": "github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0=\ngithub.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=\ngithub.com/aws/aws-sdk-go-v2 v1.41.4 h1:10f50G7WyU02T56ox1wWXq+zTX9I1zxG46HYuG1hH/k=\ngithub.com/aws/aws-sdk-go-v2 v1.41.4/go.mod h1:mwsPRE8ceUUpiTgF7QmQIJ7lgsKUPQOUl3o72QBrE1o=\ngithub.com/aws/aws-sdk-go-v2/config v1.32.12 h1:O3csC7HUGn2895eNrLytOJQdoL2xyJy0iYXhoZ1OmP0=\ngithub.com/aws/aws-sdk-go-v2/config v1.32.12/go.mod h1:96zTvoOFR4FURjI+/5wY1vc1ABceROO4lWgWJuxgy0g=\ngithub.com/aws/aws-sdk-go-v2/credentials v1.19.12 h1:oqtA6v+y5fZg//tcTWahyN9PEn5eDU/Wpvc2+kJ4aY8=\ngithub.com/aws/aws-sdk-go-v2/credentials v1.19.12/go.mod h1:U3R1RtSHx6NB0DvEQFGyf/0sbrpJrluENHdPy1j/3TE=\ngithub.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.20 h1:zOgq3uezl5nznfoK3ODuqbhVg1JzAGDUhXOsU0IDCAo=\ngithub.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.20/go.mod h1:z/MVwUARehy6GAg/yQ1GO2IMl0k++cu1ohP9zo887wE=\ngithub.com/aws/aws-sdk-go-v2/internal/configsources v1.4.20 h1:CNXO7mvgThFGqOFgbNAP2nol2qAWBOGfqR/7tQlvLmc=\ngithub.com/aws/aws-sdk-go-v2/internal/configsources v1.4.20/go.mod h1:oydPDJKcfMhgfcgBUZaG+toBbwy8yPWubJXBVERtI4o=\ngithub.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.20 h1:tN6W/hg+pkM+tf9XDkWUbDEjGLb+raoBMFsTodcoYKw=\ngithub.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.20/go.mod h1:YJ898MhD067hSHA6xYCx5ts/jEd8BSOLtQDL3iZsvbc=\ngithub.com/aws/aws-sdk-go-v2/internal/ini v1.8.6 h1:qYQ4pzQ2Oz6WpQ8T3HvGHnZydA72MnLuFK9tJwmrbHw=\ngithub.com/aws/aws-sdk-go-v2/internal/ini v1.8.6/go.mod h1:O3h0IK87yXci+kg6flUKzJnWeziQUKciKrLjcatSNcY=\ngithub.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.7 h1:5EniKhLZe4xzL7a+fU3C2tfUN4nWIqlLesfrjkuPFTY=\ngithub.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.7/go.mod h1:x0nZssQ3qZSnIcePWLvcoFisRXJzcTVvYpAAdYX8+GI=\ngithub.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.20 h1:2HvVAIq+YqgGotK6EkMf+KIEqTISmTYh5zLpYyeTo1Y=\ngithub.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.20/go.mod h1:V4X406Y666khGa8ghKmphma/7C0DAtEQYhkq9z4vpbk=\ngithub.com/aws/aws-sdk-go-v2/service/securityhub v1.68.2 h1:FqGvGaRzvB6JLJvzNoBpyHkqe0pDzsan5FXLYvdfRi8=\ngithub.com/aws/aws-sdk-go-v2/service/securityhub v1.68.2/go.mod h1:gPgOaKWvECFTmnY8oC/cvFHud/KCa/TOBEwO5dNrL7k=\ngithub.com/aws/aws-sdk-go-v2/service/signin v1.0.8 h1:0GFOLzEbOyZABS3PhYfBIx2rNBACYcKty+XGkTgw1ow=\ngithub.com/aws/aws-sdk-go-v2/service/signin v1.0.8/go.mod h1:LXypKvk85AROkKhOG6/YEcHFPoX+prKTowKnVdcaIxE=\ngithub.com/aws/aws-sdk-go-v2/service/sso v1.30.13 h1:kiIDLZ005EcKomYYITtfsjn7dtOwHDOFy7IbPXKek2o=\ngithub.com/aws/aws-sdk-go-v2/service/sso v1.30.13/go.mod h1:2h/xGEowcW/g38g06g3KpRWDlT+OTfxxI0o1KqayAB8=\ngithub.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.17 h1:jzKAXIlhZhJbnYwHbvUQZEB8KfgAEuG0dc08Bkda7NU=\ngithub.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.17/go.mod h1:Al9fFsXjv4KfbzQHGe6V4NZSZQXecFcvaIF4e70FoRA=\ngithub.com/aws/aws-sdk-go-v2/service/sts v1.41.9 h1:Cng+OOwCHmFljXIxpEVXAGMnBia8MSU6Ch5i9PgBkcU=\ngithub.com/aws/aws-sdk-go-v2/service/sts v1.41.9/go.mod h1:LrlIndBDdjA/EeXeyNBle+gyCwTlizzW5ycgWnvIxkk=\ngithub.com/aws/smithy-go v1.24.2 h1:FzA3bu/nt/vDvmnkg+R8Xl46gmzEDam6mZ1hzmwXFng=\ngithub.com/aws/smithy-go v1.24.2/go.mod h1:YE2RhdIuDbA5E5bTdciG9KrW3+TiEONeUWCqxX9i1Fc=\ngithub.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=\ngithub.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=\ngithub.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=\ngithub.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/emicklei/go-restful/v3 v3.12.2 h1:DhwDP0vY3k8ZzE0RunuJy8GhNpPL6zqLkDf9B/a0/xU=\ngithub.com/emicklei/go-restful/v3 v3.12.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=\ngithub.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=\ngithub.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=\ngithub.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=\ngithub.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=\ngithub.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=\ngithub.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=\ngithub.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=\ngithub.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=\ngithub.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM=\ngithub.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=\ngithub.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=\ngithub.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=\ngithub.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=\ngithub.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ=\ngithub.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY=\ngithub.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE=\ngithub.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k=\ngithub.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=\ngithub.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE=\ngithub.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ=\ngithub.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I=\ngithub.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=\ngithub.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=\ngithub.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=\ngithub.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs=\ngithub.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=\ngithub.com/golang/glog v1.2.5 h1:DrW6hGnjIhtvhOIiAKT6Psh/Kd/ldepEa81DKeiRJ5I=\ngithub.com/golang/glog v1.2.5/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w=\ngithub.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=\ngithub.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=\ngithub.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=\ngithub.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=\ngithub.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=\ngithub.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=\ngithub.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo=\ngithub.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ=\ngithub.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=\ngithub.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=\ngithub.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=\ngithub.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=\ngithub.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=\ngithub.com/google/pprof v0.0.0-20250403155104-27863c87afa6 h1:BHT72Gu3keYf3ZEu2J0b1vyeLSOYI8bm5wbJM/8yDe8=\ngithub.com/google/pprof v0.0.0-20250403155104-27863c87afa6/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA=\ngithub.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=\ngithub.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=\ngithub.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=\ngithub.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=\ngithub.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=\ngithub.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=\ngithub.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=\ngithub.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=\ngithub.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=\ngithub.com/jackc/pgx/v5 v5.6.0 h1:SWJzexBzPL5jb0GEsrPMLIsi/3jOo7RHlzTjcAeDrPY=\ngithub.com/jackc/pgx/v5 v5.6.0/go.mod h1:DNZ/vlrUnhWCoFGxHAG8U2ljioxukquj7utPDgtQdTw=\ngithub.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo=\ngithub.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=\ngithub.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=\ngithub.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=\ngithub.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=\ngithub.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=\ngithub.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=\ngithub.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=\ngithub.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=\ngithub.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=\ngithub.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=\ngithub.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=\ngithub.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=\ngithub.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=\ngithub.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=\ngithub.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=\ngithub.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=\ngithub.com/magiconair/properties v1.8.10 h1:s31yESBquKXCV9a/ScB3ESkOjUYYv+X0rg8SYxI99mE=\ngithub.com/magiconair/properties v1.8.10/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=\ngithub.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=\ngithub.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=\ngithub.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=\ngithub.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=\ngithub.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=\ngithub.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=\ngithub.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=\ngithub.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=\ngithub.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=\ngithub.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=\ngithub.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=\ngithub.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8=\ngithub.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=\ngithub.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=\ngithub.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=\ngithub.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=\ngithub.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=\ngithub.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=\ngithub.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=\ngithub.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=\ngithub.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=\ngithub.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=\ngithub.com/onsi/ginkgo/v2 v2.27.2 h1:LzwLj0b89qtIy6SSASkzlNvX6WktqurSHwkk2ipF/Ns=\ngithub.com/onsi/ginkgo/v2 v2.27.2/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo=\ngithub.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=\ngithub.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=\ngithub.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A=\ngithub.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k=\ngithub.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=\ngithub.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=\ngithub.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=\ngithub.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=\ngithub.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=\ngithub.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=\ngithub.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=\ngithub.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=\ngithub.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=\ngithub.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=\ngithub.com/sagikazarmark/locafero v0.11.0 h1:1iurJgmM9G3PA/I+wWYIOw/5SyBtxapeHDcg+AAIFXc=\ngithub.com/sagikazarmark/locafero v0.11.0/go.mod h1:nVIGvgyzw595SUSUE6tvCp3YYTeHs15MvlmU87WwIik=\ngithub.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 h1:+jumHNA0Wrelhe64i8F6HNlS8pkoyMv5sreGx2Ry5Rw=\ngithub.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8/go.mod h1:3n1Cwaq1E1/1lhQhtRK2ts/ZwZEhjcQeJQ1RuC6Q/8U=\ngithub.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I=\ngithub.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8lxMg=\ngithub.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY=\ngithub.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo=\ngithub.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU=\ngithub.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4=\ngithub.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=\ngithub.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=\ngithub.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=\ngithub.com/spf13/viper v1.21.0 h1:x5S+0EU27Lbphp4UKm1C+1oQO+rKx36vfCoaVebLFSU=\ngithub.com/spf13/viper v1.21.0/go.mod h1:P0lhsswPGWD/1lZJ9ny3fYnVqxiegrlNrEmgLjbTCAY=\ngithub.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=\ngithub.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=\ngithub.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=\ngithub.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=\ngithub.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=\ngithub.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=\ngithub.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=\ngithub.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=\ngithub.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=\ngithub.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=\ngithub.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=\ngithub.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=\ngithub.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=\ngithub.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=\ngithub.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=\ngithub.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=\ngithub.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=\ngithub.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngo.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0=\ngo.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8=\ngo.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=\ngo.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=\ngolang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=\ngolang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=\ngolang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=\ngolang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=\ngolang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=\ngolang.org/x/exp v0.0.0-20250718183923-645b1fa84792 h1:R9PFI6EUdfVKgwKjZef7QIwGcBKu86OEFpJ9nUEP2l4=\ngolang.org/x/exp v0.0.0-20250718183923-645b1fa84792/go.mod h1:A+z0yzpGtvnG90cToK5n2tu8UJVP2XUATh+r+sfOOOc=\ngolang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/mod v0.29.0 h1:HV8lRxZC4l2cr3Zq1LvtOsi/ThTgWnUk/y64QSs8GwA=\ngolang.org/x/mod v0.29.0/go.mod h1:NyhrlYXJ2H4eJiRy/WDBO6HMqZQ6q9nk4JzS3NuCK+w=\ngolang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=\ngolang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=\ngolang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=\ngolang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI=\ngolang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU=\ngolang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I=\ngolang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=\ngolang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=\ngolang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=\ngolang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU=\ngolang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254=\ngolang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=\ngolang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=\ngolang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY=\ngolang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=\ngolang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ=\ngolang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs=\ngolang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngoogle.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=\ngoogle.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=\ngoogle.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=\ngoogle.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=\ngoogle.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=\ngoogle.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=\ngoogle.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc=\ngoogle.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU=\ngopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=\ngopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=\ngopkg.in/evanphx/json-patch.v4 v4.13.0 h1:czT3CmqEaQ1aanPc5SdlgQrrEIb8w/wwCvWWnfEbYzo=\ngopkg.in/evanphx/json-patch.v4 v4.13.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M=\ngopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=\ngopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=\ngopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=\ngopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=\ngopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=\ngopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=\ngopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=\ngopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\ngopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=\ngopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\ngorm.io/driver/postgres v1.6.0 h1:2dxzU8xJ+ivvqTRph34QX+WrRaJlmfyPqXmoGVjMBa4=\ngorm.io/driver/postgres v1.6.0/go.mod h1:vUw0mrGgrTK+uPHEhAdV4sfFELrByKVGnaVRkXDhtWo=\ngorm.io/gorm v1.31.1 h1:7CA8FTFz/gRfgqgpeKIBcervUn3xSyPUmr6B2WXJ7kg=\ngorm.io/gorm v1.31.1/go.mod h1:XyQVbO2k6YkOis7C2437jSit3SsDK72s7n7rsSHd+Gs=\nk8s.io/api v0.35.2 h1:tW7mWc2RpxW7HS4CoRXhtYHSzme1PN1UjGHJ1bdrtdw=\nk8s.io/api v0.35.2/go.mod h1:7AJfqGoAZcwSFhOjcGM7WV05QxMMgUaChNfLTXDRE60=\nk8s.io/apimachinery v0.35.2 h1:NqsM/mmZA7sHW02JZ9RTtk3wInRgbVxL8MPfzSANAK8=\nk8s.io/apimachinery v0.35.2/go.mod h1:jQCgFZFR1F4Ik7hvr2g84RTJSZegBc8yHgFWKn//hns=\nk8s.io/client-go v0.35.2 h1:YUfPefdGJA4aljDdayAXkc98DnPkIetMl4PrKX97W9o=\nk8s.io/client-go v0.35.2/go.mod h1:4QqEwh4oQpeK8AaefZ0jwTFJw/9kIjdQi0jpKeYvz7g=\nk8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=\nk8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=\nk8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 h1:Y3gxNAuB0OBLImH611+UDZcmKS3g6CthxToOb37KgwE=\nk8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ=\nk8s.io/utils v0.0.0-20251002143259-bc988d571ff4 h1:SjGebBtkBqHFOli+05xYbK8YF1Dzkbzn+gDM4X9T4Ck=\nk8s.io/utils v0.0.0-20251002143259-bc988d571ff4/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=\nsigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg=\nsigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg=\nsigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU=\nsigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=\nsigs.k8s.io/structured-merge-diff/v6 v6.3.0 h1:jTijUJbW353oVOd9oTlifJqOGEkUw2jB/fXCbTiQEco=\nsigs.k8s.io/structured-merge-diff/v6 v6.3.0/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE=\nsigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs=\nsigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4=\n"
  },
  {
    "path": "hack/debug.yaml",
    "content": "---\n# use this pod with: kubectl run ubuntu -it --pid=host  -- /bin/bash\n# this allows you to debug what is running on the host.\napiVersion: v1\nkind: Pod\nmetadata:\n  name: ubuntu\nspec:\n  hostPID: true\n  containers:\n    - name: ubuntu\n      image: ubuntu\n      command: [\"/bin/bash\", \"-c\", \"--\"]\n      args: [\"while true; do sleep 30; done;\"]\n      env:\n        - name: PATH\n          value: \"/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/mount-from-host/bin\"\n      volumeMounts:\n        - name: var-lib-kubelet\n          mountPath: /var/lib/kubelet\n        - name: etc-systemd\n          mountPath: /etc/systemd\n        - name: etc-kubernetes\n          mountPath: /etc/kubernetes\n          # /usr/local/mount-from-host/bin is mounted to access kubectl / kubelet, for auto-detecting the Kubernetes version.\n          # You can omit this mount if you specify --version as part of the command.\n        - name: usr-bin\n          mountPath: /usr/local/mount-from-host/bin\n        - name: kind-bin\n          mountPath: /kind/bin\n      resources:\n        limits:\n          memory: \"128Mi\"\n          cpu: \"500m\"\n  volumes:\n    - name: var-lib-kubelet\n      hostPath:\n        path: \"/var/lib/kubelet\"\n    - name: etc-systemd\n      hostPath:\n        path: \"/etc/systemd\"\n    - name: etc-kubernetes\n      hostPath:\n        path: \"/etc/kubernetes\"\n    - name: usr-bin\n      hostPath:\n        path: \"/usr/bin\"\n    - name: kind-bin\n      hostPath:\n        path: \"/kind/bin\"\n"
  },
  {
    "path": "hack/kind-stig.test.yaml",
    "content": "---\napiVersion: batch/v1\nkind: Job\nmetadata:\n  name: kube-bench\nspec:\n  template:\n    metadata:\n      labels:\n        app: kube-bench\n    spec:\n      hostPID: true\n      containers:\n        - name: kube-bench\n          image: docker.io/aquasec/kube-bench:latest\n          command: [\n            \"kube-bench\",\n            \"run\",\n            \"--benchmark\",\n            \"eks-stig-kubernetes-v1r6\",\n          ]\n          volumeMounts:\n            - name: var-lib-etcd\n              mountPath: /var/lib/etcd\n            - name: var-lib-kubelet\n              mountPath: /var/lib/kubelet\n            - name: etc-systemd\n              mountPath: /etc/systemd\n            - name: etc-kubernetes\n              mountPath: /etc/kubernetes\n              # /usr/local/mount-from-host/bin is mounted to access kubectl / kubelet, for auto-detecting the Kubernetes version.\n              # You can omit this mount if you specify --version as part of the command.\n            - name: usr-bin\n              mountPath: /usr/local/mount-from-host/bin\n            - name: kind-bin\n              mountPath: /kind/bin\n      restartPolicy: Never\n      volumes:\n        - name: var-lib-etcd\n          hostPath:\n            path: \"/var/lib/etcd\"\n        - name: var-lib-kubelet\n          hostPath:\n            path: \"/var/lib/kubelet\"\n        - name: etc-systemd\n          hostPath:\n            path: \"/etc/systemd\"\n        - name: etc-kubernetes\n          hostPath:\n            path: \"/etc/kubernetes\"\n        - name: usr-bin\n          hostPath:\n            path: \"/usr/bin\"\n        - name: kind-bin\n          hostPath:\n            path: \"/kind/bin\"\n"
  },
  {
    "path": "hack/kind-stig.yaml",
    "content": "---\napiVersion: batch/v1\nkind: Job\nmetadata:\n  name: kube-bench\nspec:\n  template:\n    metadata:\n      labels:\n        app: kube-bench\n    spec:\n      hostPID: true\n      containers:\n        - name: kube-bench\n          image: docker.io/aquasec/kube-bench:${VERSION}\n          command: [\n            \"kube-bench\",\n            \"run\",\n            \"--benchmark\",\n            \"eks-stig-kubernetes-v1r6\",\n          ]\n          volumeMounts:\n            - name: var-lib-etcd\n              mountPath: /var/lib/etcd\n            - name: var-lib-kubelet\n              mountPath: /var/lib/kubelet\n            - name: etc-systemd\n              mountPath: /etc/systemd\n            - name: etc-kubernetes\n              mountPath: /etc/kubernetes\n              # /usr/local/mount-from-host/bin is mounted to access kubectl / kubelet, for auto-detecting the Kubernetes version.\n              # You can omit this mount if you specify --version as part of the command.\n            - name: usr-bin\n              mountPath: /usr/local/mount-from-host/bin\n            - name: kind-bin\n              mountPath: /kind/bin\n      restartPolicy: Never\n      volumes:\n        - name: var-lib-etcd\n          hostPath:\n            path: \"/var/lib/etcd\"\n        - name: var-lib-kubelet\n          hostPath:\n            path: \"/var/lib/kubelet\"\n        - name: etc-systemd\n          hostPath:\n            path: \"/etc/systemd\"\n        - name: etc-kubernetes\n          hostPath:\n            path: \"/etc/kubernetes\"\n        - name: usr-bin\n          hostPath:\n            path: \"/usr/bin\"\n        - name: kind-bin\n          hostPath:\n            path: \"/kind/bin\"\n"
  },
  {
    "path": "hack/kind.yaml",
    "content": "---\napiVersion: batch/v1\nkind: Job\nmetadata:\n  name: kube-bench\nspec:\n  template:\n    metadata:\n      labels:\n        app: kube-bench\n    spec:\n      hostPID: true\n      containers:\n        - name: kube-bench\n          image: docker.io/aquasec/kube-bench:${VERSION}\n          command: [\"kube-bench\"]\n          volumeMounts:\n            - name: var-lib-etcd\n              mountPath: /var/lib/etcd\n            - name: var-lib-kubelet\n              mountPath: /var/lib/kubelet\n            - name: etc-systemd\n              mountPath: /etc/systemd\n            - name: etc-kubernetes\n              mountPath: /etc/kubernetes\n              # /usr/local/mount-from-host/bin is mounted to access kubectl / kubelet, for auto-detecting the Kubernetes version.\n              # You can omit this mount if you specify --version as part of the command.\n            - name: usr-bin\n              mountPath: /usr/local/mount-from-host/bin\n            - name: kind-bin\n              mountPath: /kind/bin\n      restartPolicy: Never\n      volumes:\n        - name: var-lib-etcd\n          hostPath:\n            path: \"/var/lib/etcd\"\n        - name: var-lib-kubelet\n          hostPath:\n            path: \"/var/lib/kubelet\"\n        - name: etc-systemd\n          hostPath:\n            path: \"/etc/systemd\"\n        - name: etc-kubernetes\n          hostPath:\n            path: \"/etc/kubernetes\"\n        - name: usr-bin\n          hostPath:\n            path: \"/usr/bin\"\n        - name: kind-bin\n          hostPath:\n            path: \"/kind/bin\"\n"
  },
  {
    "path": "hack/node_only.yaml",
    "content": "---\nnode:\n  components:\n    - kubelet\n    - proxy\n    # kubernetes is a component to cover the config file /etc/kubernetes/config that is referred to in the benchmark\n    - kubernetes\n\n  kubernetes:\n    defaultconf: \"/etc/kubernetes/config\"\n\n  kubelet:\n    cafile:\n      - \"/etc/kubernetes/pki/ca.crt\"\n      - \"/etc/kubernetes/certs/ca.crt\"\n      - \"/etc/kubernetes/cert/ca.pem\"\n    svc:\n      # These paths must also be included\n      #  in the 'confs' property below\n      - \"/etc/systemd/system/kubelet.service.d/10-kubeadm.conf\"\n      - \"/etc/systemd/system/kubelet.service\"\n      - \"/lib/systemd/system/kubelet.service\"\n    bins:\n      - \"hyperkube kubelet\"\n      - \"kubelet\"\n    kubeconfig:\n      - \"/etc/kubernetes/kubelet.conf\"\n      - \"/var/lib/kubelet/kubeconfig\"\n      - \"/etc/kubernetes/kubelet-kubeconfig\"\n    confs:\n      - \"/var/lib/kubelet/config.yaml\"\n      - \"/var/lib/kubelet/config.yml\"\n      - \"/etc/kubernetes/kubelet/kubelet-config.json\"\n      - \"/home/kubernetes/kubelet-config.yaml\"\n      - \"/home/kubernetes/kubelet-config.yml\"\n      - \"/etc/default/kubelet\"\n      ## Due to the fact that the kubelet might be configured\n      ## without a kubelet-config file, we use a work-around\n      ## of pointing to the systemd service file (which can also\n      ## hold kubelet configuration).\n      ## Note: The following paths must match the one under 'svc'\n      - \"/etc/systemd/system/kubelet.service.d/10-kubeadm.conf\"\n      - \"/etc/systemd/system/kubelet.service\"\n      - \"/lib/systemd/system/kubelet.service\"\n    defaultconf: \"/var/lib/kubelet/config.yaml\"\n    defaultsvc: \"/etc/systemd/system/kubelet.service.d/10-kubeadm.conf\"\n    defaultkubeconfig: \"/etc/kubernetes/kubelet.conf\"\n    defaultcafile: \"/etc/kubernetes/pki/ca.crt\"\n\n  proxy:\n    bins:\n      - \"kube-proxy\"\n      - \"hyperkube proxy\"\n      - \"hyperkube kube-proxy\"\n      - \"proxy\"\n    confs:\n      - /etc/kubernetes/proxy\n      - /etc/kubernetes/addons/kube-proxy-daemonset.yaml\n    kubeconfig:\n      - /etc/kubernetes/kubelet-kubeconfig\n    svc:\n      - \"/lib/systemd/system/kube-proxy.service\"\n    defaultconf: /etc/kubernetes/addons/kube-proxy-daemonset.yaml\n    defaultkubeconfig: \"/etc/kubernetes/proxy.conf\"\n\nversion_mapping:\n  \"1.15\": \"cis-1.5\"\n  \"1.16\": \"cis-1.6\"\n  \"1.17\": \"cis-1.6\"\n  \"1.18\": \"cis-1.6\"\n  \"1.19\": \"cis-1.6\"\n  \"ocp-3.10\": \"rh-0.7\"\n  \"ocp-3.11\": \"rh-0.7\"\n"
  },
  {
    "path": "helper_scripts/check_files_owner_in_dir.sh",
    "content": "#!/usr/bin/env bash\n\n# This script is used to ensure the owner is set to root:root for\n# the given directory and all the files in it\n#\n# inputs:\n#   $1 = /full/path/to/directory\n#\n# outputs:\n#   true/false\n\nINPUT_DIR=$1\n\nif [[ \"${INPUT_DIR}\" == \"\" ]]; then\n    echo \"false\"\n    exit\nfi\n\nif [[ $(stat -c %U:%G ${INPUT_DIR}) != \"root:root\" ]]; then\n    echo \"false\"\n    exit\nfi\n\nstatInfoLines=$(stat -c \"%n %U:%G\" ${INPUT_DIR}/*)\nwhile read -r statInfoLine; do\n  f=$(echo ${statInfoLine} | cut -d' ' -f1)\n  p=$(echo ${statInfoLine} | cut -d' ' -f2)\n\n  if [[ $(basename \"$f\" .pem) == \"kube-etcd-\"* ]]; then\n    if [[ \"$p\" != \"root:root\" && \"$p\" != \"etcd:etcd\" ]]; then\n      echo \"false\"\n      exit\n    fi\n  else\n    if [[ \"$p\" != \"root:root\" ]]; then\n      echo \"false\"\n      exit\n    fi\n  fi\ndone <<< \"${statInfoLines}\"\n\n\necho \"true\"\nexit\n"
  },
  {
    "path": "hooks/build",
    "content": "#!/bin/bash\n\n# $IMAGE_NAME var is injected into the build so the tag is correct. \ndocker build --build-arg BUILD_DATE=`date -u +\"%Y-%m-%dT%H:%M:%SZ\"` \\\n             --build-arg VCS_REF=`git rev-parse --short HEAD` \\\n             --build-arg KUBEBENCH_VERSION=`git describe --tags --abbrev=0` \\\n             -t $IMAGE_NAME .\n"
  },
  {
    "path": "integration/testdata/Expected_output.data",
    "content": "[INFO] 1 Master Node Security Configuration\n[INFO] 1.1 Master Node Configuration Files\n[PASS] 1.1.1 Ensure that the API server pod specification file permissions are set to 644 or more restrictive (Automated)\n[PASS] 1.1.2 Ensure that the API server pod specification file ownership is set to root:root (Automated)\n[PASS] 1.1.3 Ensure that the controller manager pod specification file permissions are set to 644 or more restrictive (Automated)\n[PASS] 1.1.4 Ensure that the controller manager pod specification file ownership is set to root:root (Automated)\n[PASS] 1.1.5 Ensure that the scheduler pod specification file permissions are set to 644 or more restrictive (Automated)\n[PASS] 1.1.6 Ensure that the scheduler pod specification file ownership is set to root:root (Automated)\n[PASS] 1.1.7 Ensure that the etcd pod specification file permissions are set to 644 or more restrictive (Automated)\n[PASS] 1.1.8 Ensure that the etcd pod specification file ownership is set to root:root (Automated)\n[WARN] 1.1.9 Ensure that the Container Network Interface file permissions are set to 644 or more restrictive (Manual)\n[WARN] 1.1.10 Ensure that the Container Network Interface file ownership is set to root:root (Manual)\n[PASS] 1.1.11 Ensure that the etcd data directory permissions are set to 700 or more restrictive (Automated)\n[FAIL] 1.1.12 Ensure that the etcd data directory ownership is set to etcd:etcd (Automated)\n[PASS] 1.1.13 Ensure that the admin.conf file permissions are set to 644 or more restrictive (Automated)\n[PASS] 1.1.14 Ensure that the admin.conf file ownership is set to root:root (Automated)\n[PASS] 1.1.15 Ensure that the scheduler.conf file permissions are set to 644 or more restrictive (Automated)\n[PASS] 1.1.16 Ensure that the scheduler.conf file ownership is set to root:root (Automated)\n[PASS] 1.1.17 Ensure that the controller-manager.conf file permissions are set to 644 or more restrictive (Automated)\n[PASS] 1.1.18 Ensure that the controller-manager.conf file ownership is set to root:root (Automated)\n[PASS] 1.1.19 Ensure that the Kubernetes PKI directory and file ownership is set to root:root (Automated)\n[PASS] 1.1.20 Ensure that the Kubernetes PKI certificate file permissions are set to 644 or more restrictive (Manual)\n[PASS] 1.1.21 Ensure that the Kubernetes PKI key file permissions are set to 600 (Manual)\n[INFO] 1.2 API Server\n[WARN] 1.2.1 Ensure that the --anonymous-auth argument is set to false (Manual)\n[PASS] 1.2.2 Ensure that the --token-auth-file parameter is not set (Automated)\n[PASS] 1.2.3 Ensure that the --kubelet-https argument is set to true (Automated)\n[PASS] 1.2.4 Ensure that the --kubelet-client-certificate and --kubelet-client-key arguments are set as appropriate (Automated)\n[FAIL] 1.2.5 Ensure that the --kubelet-certificate-authority argument is set as appropriate (Automated)\n[PASS] 1.2.6 Ensure that the --authorization-mode argument is not set to AlwaysAllow (Automated)\n[PASS] 1.2.7 Ensure that the --authorization-mode argument includes Node (Automated)\n[PASS] 1.2.8 Ensure that the --authorization-mode argument includes RBAC (Automated)\n[WARN] 1.2.9 Ensure that the admission control plugin EventRateLimit is set (Manual)\n[PASS] 1.2.10 Ensure that the admission control plugin AlwaysAdmit is not set (Automated)\n[WARN] 1.2.11 Ensure that the admission control plugin AlwaysPullImages is set (Manual)\n[WARN] 1.2.12 Ensure that the admission control plugin SecurityContextDeny is set if PodSecurityPolicy is not used (Manual)\n[PASS] 1.2.13 Ensure that the admission control plugin ServiceAccount is set (Automated)\n[PASS] 1.2.14 Ensure that the admission control plugin NamespaceLifecycle is set (Automated)\n[FAIL] 1.2.15 Ensure that the admission control plugin PodSecurityPolicy is set (Automated)\n[PASS] 1.2.16 Ensure that the admission control plugin NodeRestriction is set (Automated)\n[PASS] 1.2.17 Ensure that the --insecure-bind-address argument is not set (Automated)\n[PASS] 1.2.18 Ensure that the --insecure-port argument is set to 0 (Automated)\n[PASS] 1.2.19 Ensure that the --secure-port argument is not set to 0 (Automated)\n[FAIL] 1.2.20 Ensure that the --profiling argument is set to false (Automated)\n[FAIL] 1.2.21 Ensure that the --audit-log-path argument is set (Automated)\n[FAIL] 1.2.22 Ensure that the --audit-log-maxage argument is set to 30 or as appropriate (Automated)\n[FAIL] 1.2.23 Ensure that the --audit-log-maxbackup argument is set to 10 or as appropriate (Automated)\n[FAIL] 1.2.24 Ensure that the --audit-log-maxsize argument is set to 100 or as appropriate (Automated)\n[WARN] 1.2.25 Ensure that the --request-timeout argument is set as appropriate (Manual)\n[PASS] 1.2.26 Ensure that the --service-account-lookup argument is set to true (Automated)\n[PASS] 1.2.27 Ensure that the --service-account-key-file argument is set as appropriate (Automated)\n[PASS] 1.2.28 Ensure that the --etcd-certfile and --etcd-keyfile arguments are set as appropriate (Automated)\n[PASS] 1.2.29 Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Automated)\n[PASS] 1.2.30 Ensure that the --client-ca-file argument is set as appropriate (Automated)\n[PASS] 1.2.31 Ensure that the --etcd-cafile argument is set as appropriate (Automated)\n[WARN] 1.2.32 Ensure that the --encryption-provider-config argument is set as appropriate (Manual)\n[WARN] 1.2.33 Ensure that encryption providers are appropriately configured (Manual)\n[WARN] 1.2.34 Ensure that the API Server only makes use of Strong Cryptographic Ciphers (Manual)\n[INFO] 1.3 Controller Manager\n[WARN] 1.3.1 Ensure that the --terminated-pod-gc-threshold argument is set as appropriate (Manual)\n[FAIL] 1.3.2 Ensure that the --profiling argument is set to false (Automated)\n[PASS] 1.3.3 Ensure that the --use-service-account-credentials argument is set to true (Automated)\n[PASS] 1.3.4 Ensure that the --service-account-private-key-file argument is set as appropriate (Automated)\n[PASS] 1.3.5 Ensure that the --root-ca-file argument is set as appropriate (Automated)\n[PASS] 1.3.6 Ensure that the RotateKubeletServerCertificate argument is set to true (Automated)\n[PASS] 1.3.7 Ensure that the --bind-address argument is set to 127.0.0.1 (Automated)\n[INFO] 1.4 Scheduler\n[FAIL] 1.4.1 Ensure that the --profiling argument is set to false (Automated)\n[PASS] 1.4.2 Ensure that the --bind-address argument is set to 127.0.0.1 (Automated)\n\n== Remediations master ==\n1.1.9 Run the below command (based on the file location on your system) on the master node.\nFor example,\nchmod 644 <path/to/cni/files>\n\n1.1.10 Run the below command (based on the file location on your system) on the master node.\nFor example,\nchown root:root <path/to/cni/files>\n\n1.1.12 On the etcd server node, get the etcd data directory, passed as an argument --data-dir,\nfrom the below command:\nps -ef | grep etcd\nRun the below command (based on the etcd data directory found above).\nFor example, chown etcd:etcd /var/lib/etcd\n\n1.2.1 Edit the API server pod specification file /etc/kubernetes/manifests/kube-apiserver.yaml\non the master node and set the below parameter.\n--anonymous-auth=false\n\n1.2.5 Follow the Kubernetes documentation and setup the TLS connection between\nthe apiserver and kubelets. Then, edit the API server pod specification file\n/etc/kubernetes/manifests/kube-apiserver.yaml on the master node and set the\n--kubelet-certificate-authority parameter to the path to the cert file for the certificate authority.\n--kubelet-certificate-authority=<ca-string>\n\n1.2.9 Follow the Kubernetes documentation and set the desired limits in a configuration file.\nThen, edit the API server pod specification file /etc/kubernetes/manifests/kube-apiserver.yaml\nand set the below parameters.\n--enable-admission-plugins=...,EventRateLimit,...\n--admission-control-config-file=<path/to/configuration/file>\n\n1.2.11 Edit the API server pod specification file /etc/kubernetes/manifests/kube-apiserver.yaml\non the master node and set the --enable-admission-plugins parameter to include\nAlwaysPullImages.\n--enable-admission-plugins=...,AlwaysPullImages,...\n\n1.2.12 Edit the API server pod specification file /etc/kubernetes/manifests/kube-apiserver.yaml\non the master node and set the --enable-admission-plugins parameter to include\nSecurityContextDeny, unless PodSecurityPolicy is already in place.\n--enable-admission-plugins=...,SecurityContextDeny,...\n\n1.2.15 Follow the documentation and create Pod Security Policy objects as per your environment.\nThen, edit the API server pod specification file /etc/kubernetes/manifests/kube-apiserver.yaml\non the master node and set the --enable-admission-plugins parameter to a\nvalue that includes PodSecurityPolicy:\n--enable-admission-plugins=...,PodSecurityPolicy,...\nThen restart the API Server.\n\n1.2.20 Edit the API server pod specification file /etc/kubernetes/manifests/kube-apiserver.yaml\non the master node and set the below parameter.\n--profiling=false\n\n1.2.21 Edit the API server pod specification file /etc/kubernetes/manifests/kube-apiserver.yaml\non the master node and set the --audit-log-path parameter to a suitable path and\nfile where you would like audit logs to be written, for example:\n--audit-log-path=/var/log/apiserver/audit.log\n\n1.2.22 Edit the API server pod specification file /etc/kubernetes/manifests/kube-apiserver.yaml\non the master node and set the --audit-log-maxage parameter to 30 or as an appropriate number of days:\n--audit-log-maxage=30\n\n1.2.23 Edit the API server pod specification file /etc/kubernetes/manifests/kube-apiserver.yaml\non the master node and set the --audit-log-maxbackup parameter to 10 or to an appropriate\nvalue.\n--audit-log-maxbackup=10\n\n1.2.24 Edit the API server pod specification file /etc/kubernetes/manifests/kube-apiserver.yaml\non the master node and set the --audit-log-maxsize parameter to an appropriate size in MB.\nFor example, to set it as 100 MB:\n--audit-log-maxsize=100\n\n1.2.25 Edit the API server pod specification file /etc/kubernetes/manifests/kube-apiserver.yaml\nand set the below parameter as appropriate and if needed.\nFor example,\n--request-timeout=300s\n\n1.2.32 Follow the Kubernetes documentation and configure a EncryptionConfig file.\nThen, edit the API server pod specification file /etc/kubernetes/manifests/kube-apiserver.yaml\non the master node and set the --encryption-provider-config parameter to the path of that file: --encryption-provider-config=</path/to/EncryptionConfig/File>\n\n1.2.33 Follow the Kubernetes documentation and configure a EncryptionConfig file.\nIn this file, choose aescbc, kms or secretbox as the encryption provider.\n\n1.2.34 Edit the API server pod specification file /etc/kubernetes/manifests/kube-apiserver.yaml\non the master node and set the below parameter.\n--tls-cipher-suites=TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM\n_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM\n_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM\n_SHA384\n\n1.3.1 Edit the Controller Manager pod specification file /etc/kubernetes/manifests/kube-controller-manager.yaml\non the master node and set the --terminated-pod-gc-threshold to an appropriate threshold,\nfor example:\n--terminated-pod-gc-threshold=10\n\n1.3.2 Edit the Controller Manager pod specification file /etc/kubernetes/manifests/kube-controller-manager.yaml\non the master node and set the below parameter.\n--profiling=false\n\n1.4.1 Edit the Scheduler pod specification file /etc/kubernetes/manifests/kube-scheduler.yaml file\non the master node and set the below parameter.\n--profiling=false\n\n\n== Summary master ==\n43 checks PASS\n10 checks FAIL\n11 checks WARN\n0 checks INFO\n\n[INFO] 2 Etcd Node Configuration\n[INFO] 2 Etcd Node Configuration Files\n[PASS] 2.1 Ensure that the --cert-file and --key-file arguments are set as appropriate (Automated)\n[PASS] 2.2 Ensure that the --client-cert-auth argument is set to true (Automated)\n[PASS] 2.3 Ensure that the --auto-tls argument is not set to true (Automated)\n[PASS] 2.4 Ensure that the --peer-cert-file and --peer-key-file arguments are set as appropriate (Automated)\n[PASS] 2.5 Ensure that the --peer-client-cert-auth argument is set to true (Automated)\n[PASS] 2.6 Ensure that the --peer-auto-tls argument is not set to true (Automated)\n[PASS] 2.7 Ensure that a unique Certificate Authority is used for etcd (Manual)\n\n== Summary etcd ==\n7 checks PASS\n0 checks FAIL\n0 checks WARN\n0 checks INFO\n\n[INFO] 3 Control Plane Configuration\n[INFO] 3.1 Authentication and Authorization\n[WARN] 3.1.1 Client certificate authentication should not be used for users (Manual)\n[INFO] 3.2 Logging\n[WARN] 3.2.1 Ensure that a minimal audit policy is created (Manual)\n[WARN] 3.2.2 Ensure that the audit policy covers key security concerns (Manual)\n\n== Remediations controlplane ==\n3.1.1 Alternative mechanisms provided by Kubernetes such as the use of OIDC should be\nimplemented in place of client certificates.\n\n3.2.1 Create an audit policy file for your cluster.\n\n3.2.2 Consider modification of the audit policy in use on the cluster to include these items, at a\nminimum.\n\n\n== Summary controlplane ==\n0 checks PASS\n0 checks FAIL\n3 checks WARN\n0 checks INFO\n\n[INFO] 4 Worker Node Security Configuration\n[INFO] 4.1 Worker Node Configuration Files\n[PASS] 4.1.1 Ensure that the kubelet service file permissions are set to 644 or more restrictive (Automated)\n[PASS] 4.1.2 Ensure that the kubelet service file ownership is set to root:root (Automated)\n[WARN] 4.1.3 If proxy kubeconfig file exists ensure permissions are set to 644 or more restrictive (Manual)\n[WARN] 4.1.4 If proxy kubeconfig file exists ensure ownership is set to root:root (Manual)\n[PASS] 4.1.5 Ensure that the --kubeconfig kubelet.conf file permissions are set to 644 or more restrictive (Automated)\n[PASS] 4.1.6 Ensure that the --kubeconfig kubelet.conf file ownership is set to root:root (Automated)\n[PASS] 4.1.7 Ensure that the certificate authorities file permissions are set to 644 or more restrictive (Manual)\n[PASS] 4.1.8 Ensure that the client certificate authorities file ownership is set to root:root (Manual)\n[PASS] 4.1.9 Ensure that the kubelet --config configuration file has permissions set to 644 or more restrictive (Automated)\n[PASS] 4.1.10 Ensure that the kubelet --config configuration file ownership is set to root:root (Automated)\n[INFO] 4.2 Kubelet\n[PASS] 4.2.1 Ensure that the anonymous-auth argument is set to false (Automated)\n[PASS] 4.2.2 Ensure that the --authorization-mode argument is not set to AlwaysAllow (Automated)\n[PASS] 4.2.3 Ensure that the --client-ca-file argument is set as appropriate (Automated)\n[PASS] 4.2.4 Ensure that the --read-only-port argument is set to 0 (Manual)\n[PASS] 4.2.5 Ensure that the --streaming-connection-idle-timeout argument is not set to 0 (Manual)\n[FAIL] 4.2.6 Ensure that the --protect-kernel-defaults argument is set to true (Automated)\n[PASS] 4.2.7 Ensure that the --make-iptables-util-chains argument is set to true (Automated)\n[PASS] 4.2.8 Ensure that the --hostname-override argument is not set (Manual)\n[WARN] 4.2.9 Ensure that the --event-qps argument is set to 0 or a level which ensures appropriate event capture (Manual)\n[WARN] 4.2.10 Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Manual)\n[PASS] 4.2.11 Ensure that the --rotate-certificates argument is not set to false (Automated)\n[PASS] 4.2.12 Verify that the RotateKubeletServerCertificate argument is set to true (Manual)\n[WARN] 4.2.13 Ensure that the Kubelet only makes use of Strong Cryptographic Ciphers (Manual)\n\n== Remediations node ==\n4.1.3 Run the below command (based on the file location on your system) on the each worker node.\nFor example,\nchmod 644 /etc/kubernetes/proxy.conf\n\n4.1.4 Run the below command (based on the file location on your system) on the each worker node.\nFor example, chown root:root /etc/kubernetes/proxy.conf\n\n4.2.6 If using a Kubelet config file, edit the file to set protectKernelDefaults: true.\nIf using command line arguments, edit the kubelet service file\n/etc/systemd/system/kubelet.service.d/10-kubeadm.conf on each worker node and\nset the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n--protect-kernel-defaults=true\nBased on your system, restart the kubelet service. For example:\nsystemctl daemon-reload\nsystemctl restart kubelet.service\n\n4.2.9 If using a Kubelet config file, edit the file to set eventRecordQPS: to an appropriate level.\nIf using command line arguments, edit the kubelet service file\n/etc/systemd/system/kubelet.service.d/10-kubeadm.conf on each worker node and\nset the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\nBased on your system, restart the kubelet service. For example:\nsystemctl daemon-reload\nsystemctl restart kubelet.service\n\n4.2.10 If using a Kubelet config file, edit the file to set tlsCertFile to the location\nof the certificate file to use to identify this Kubelet, and tlsPrivateKeyFile\nto the location of the corresponding private key file.\nIf using command line arguments, edit the kubelet service file\n/etc/systemd/system/kubelet.service.d/10-kubeadm.conf on each worker node and\nset the below parameters in KUBELET_CERTIFICATE_ARGS variable.\n--tls-cert-file=<path/to/tls-certificate-file>\n--tls-private-key-file=<path/to/tls-key-file>\nBased on your system, restart the kubelet service. For example:\nsystemctl daemon-reload\nsystemctl restart kubelet.service\n\n4.2.13 If using a Kubelet config file, edit the file to set tlsCipherSuites: to\nTLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\nor to a subset of these values.\nIf using executable arguments, edit the kubelet service file\n/etc/systemd/system/kubelet.service.d/10-kubeadm.conf on each worker node and\nset the --tls-cipher-suites parameter as follows, or to a subset of these values.\n--tls-cipher-suites=TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256\nBased on your system, restart the kubelet service. For example:\nsystemctl daemon-reload\nsystemctl restart kubelet.service\n\n\n== Summary node ==\n17 checks PASS\n1 checks FAIL\n5 checks WARN\n0 checks INFO\n\n[INFO] 5 Kubernetes Policies\n[INFO] 5.1 RBAC and Service Accounts\n[WARN] 5.1.1 Ensure that the cluster-admin role is only used where required (Manual)\n[WARN] 5.1.2 Minimize access to secrets (Manual)\n[WARN] 5.1.3 Minimize wildcard use in Roles and ClusterRoles (Manual)\n[WARN] 5.1.4 Minimize access to create pods (Manual)\n[WARN] 5.1.5 Ensure that default service accounts are not actively used. (Manual)\n[WARN] 5.1.6 Ensure that Service Account Tokens are only mounted where necessary (Manual)\n[WARN] 5.1.7 Avoid use of system:masters group (Manual)\n[WARN] 5.1.8 Limit use of the Bind, Impersonate and Escalate permissions in the Kubernetes cluster (Manual)\n[INFO] 5.2 Pod Security Policies\n[WARN] 5.2.1 Minimize the admission of privileged containers (Automated)\n[WARN] 5.2.2 Minimize the admission of containers wishing to share the host process ID namespace (Automated)\n[WARN] 5.2.3 Minimize the admission of containers wishing to share the host IPC namespace (Automated)\n[WARN] 5.2.4 Minimize the admission of containers wishing to share the host network namespace (Automated)\n[WARN] 5.2.5 Minimize the admission of containers with allowPrivilegeEscalation (Automated)\n[WARN] 5.2.6 Minimize the admission of root containers (Automated)\n[WARN] 5.2.7 Minimize the admission of containers with the NET_RAW capability (Automated)\n[WARN] 5.2.8 Minimize the admission of containers with added capabilities (Automated)\n[WARN] 5.2.9 Minimize the admission of containers with capabilities assigned (Manual)\n[INFO] 5.3 Network Policies and CNI\n[WARN] 5.3.1 Ensure that the CNI in use supports Network Policies (Manual)\n[WARN] 5.3.2 Ensure that all Namespaces have Network Policies defined (Manual)\n[INFO] 5.4 Secrets Management\n[WARN] 5.4.1 Prefer using secrets as files over secrets as environment variables (Manual)\n[WARN] 5.4.2 Consider external secret storage (Manual)\n[INFO] 5.5 Extensible Admission Control\n[WARN] 5.5.1 Configure Image Provenance using ImagePolicyWebhook admission controller (Manual)\n[INFO] 5.7 General Policies\n[WARN] 5.7.1 Create administrative boundaries between resources using namespaces (Manual)\n[WARN] 5.7.2 Ensure that the seccomp profile is set to docker/default in your pod definitions (Manual)\n[WARN] 5.7.3 Apply Security Context to Your Pods and Containers (Manual)\n[WARN] 5.7.4 The default namespace should not be used (Manual)\n\n== Remediations policies ==\n5.1.1 Identify all clusterrolebindings to the cluster-admin role. Check if they are used and\nif they need this role or if they could use a role with fewer privileges.\nWhere possible, first bind users to a lower privileged role and then remove the\nclusterrolebinding to the cluster-admin role :\nkubectl delete clusterrolebinding [name]\n\n5.1.2 Where possible, remove get, list and watch access to secret objects in the cluster.\n\n5.1.3 Where possible replace any use of wildcards in clusterroles and roles with specific\nobjects or actions.\n\n5.1.4 Where possible, remove create access to pod objects in the cluster.\n\n5.1.5 Create explicit service accounts wherever a Kubernetes workload requires specific access\nto the Kubernetes API server.\nModify the configuration of each default service account to include this value\nautomountServiceAccountToken: false\n\n5.1.6 Modify the definition of pods and service accounts which do not need to mount service\naccount tokens to disable it.\n\n5.1.7 Remove the system:masters group from all users in the cluster.\n\n5.1.8 Where possible, remove the impersonate, bind and escalate rights from subjects.\n\n5.2.1 Create a PSP as described in the Kubernetes documentation, ensuring that\nthe .spec.privileged field is omitted or set to false.\n\n5.2.2 Create a PSP as described in the Kubernetes documentation, ensuring that the\n.spec.hostPID field is omitted or set to false.\n\n5.2.3 Create a PSP as described in the Kubernetes documentation, ensuring that the\n.spec.hostIPC field is omitted or set to false.\n\n5.2.4 Create a PSP as described in the Kubernetes documentation, ensuring that the\n.spec.hostNetwork field is omitted or set to false.\n\n5.2.5 Create a PSP as described in the Kubernetes documentation, ensuring that the\n.spec.allowPrivilegeEscalation field is omitted or set to false.\n\n5.2.6 Create a PSP as described in the Kubernetes documentation, ensuring that the\n.spec.runAsUser.rule is set to either MustRunAsNonRoot or MustRunAs with the range of\nUIDs not including 0.\n\n5.2.7 Create a PSP as described in the Kubernetes documentation, ensuring that the\n.spec.requiredDropCapabilities is set to include either NET_RAW or ALL.\n\n5.2.8 Ensure that allowedCapabilities is not present in PSPs for the cluster unless\nit is set to an empty array.\n\n5.2.9 Review the use of capabilites in applications running on your cluster. Where a namespace\ncontains applications which do not require any Linux capabities to operate consider adding\na PSP which forbids the admission of containers which do not drop all capabilities.\n\n5.3.1 If the CNI plugin in use does not support network policies, consideration should be given to\nmaking use of a different plugin, or finding an alternate mechanism for restricting traffic\nin the Kubernetes cluster.\n\n5.3.2 Follow the documentation and create NetworkPolicy objects as you need them.\n\n5.4.1 if possible, rewrite application code to read secrets from mounted secret files, rather than\nfrom environment variables.\n\n5.4.2 Refer to the secrets management options offered by your cloud provider or a third-party\nsecrets management solution.\n\n5.5.1 Follow the Kubernetes documentation and setup image provenance.\n\n5.7.1 Follow the documentation and create namespaces for objects in your deployment as you need\nthem.\n\n5.7.2 Use security context to enable the docker/default seccomp profile in your pod definitions.\nAn example is as below:\n  securityContext:\n    seccompProfile:\n      type: RuntimeDefault\n\n5.7.3 Follow the Kubernetes documentation and apply security contexts to your pods. For a\nsuggested list of security contexts, you may refer to the CIS Security Benchmark for Docker\nContainers.\n\n5.7.4 Ensure that namespaces are created to allow for appropriate segregation of Kubernetes\nresources and that all new resources are created in a specific namespace.\n\n\n== Summary policies ==\n0 checks PASS\n0 checks FAIL\n26 checks WARN\n0 checks INFO\n\n== Summary total ==\n67 checks PASS\n11 checks FAIL\n45 checks WARN\n0 checks INFO\n\n"
  },
  {
    "path": "integration/testdata/Expected_output_stig.data",
    "content": "[INFO] 1 Control Plane Components\n\n== Summary master ==\n0 checks PASS\n0 checks FAIL\n0 checks WARN\n0 checks INFO\n\n[INFO] 2 Control Plane Configuration\n[INFO] 2.1 DISA Category Code I\n[FAIL] V-242390 The Kubernetes API server must have anonymous authentication disabled (Automated)\n[FAIL] V-242400 The Kubernetes API server must have Alpha APIs disabled (Automated)\n[INFO] 2.2 DISA Category Code II\n[WARN] V-242381 The Kubernetes Controller Manager must create unique service accounts for each work payload. (Manual)\n[WARN] V-242402 The Kubernetes API Server must have an audit log path set (Manual)\n[WARN] V-242403 Kubernetes API Server must generate audit records (Manual)\n[WARN] V-242461 Kubernetes API Server audit logs must be enabled. (Manual)\n[WARN] V-242462 The Kubernetes API Server must be set to audit log max size. (Manual)\n[WARN] V-242463 The Kubernetes API Server must be set to audit log maximum backup. (Manual)\n[WARN] V-242464 The Kubernetes API Server audit log retention must be set. (Manual)\n[WARN] V-242465 The Kubernetes API Server audit log path must be set. (Manual)\n[WARN] V-242443  Kubernetes must contain the latest updates as authorized by IAVMs, CTOs, DTMs, and STIGs. (Manual)\n\n== Remediations controlplane ==\nV-242390 If using a Kubelet config file, edit $kubeletconf to set authentication: anonymous: enabled to\nfalse.\nIf using executable arguments, edit the kubelet service file\n$kubeletsvc on each worker node and\nset the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n--anonymous-auth=false\nBased on your system, restart the kubelet service. For example:\nsystemctl daemon-reload\nsystemctl restart kubelet.service\n\nV-242400 Edit any manifest files or $kubeletconf that contain the feature-gates\nsetting with AllAlpha set to \"true\".\nSet the flag to \"false\" or remove the \"AllAlpha\" setting\ncompletely. Restart the kubelet service if the kubelet config file\nif the kubelet config file is changed.\n\nV-242381 Create explicit service accounts wherever a Kubernetes workload requires specific access\nto the Kubernetes API server.\nModify the configuration of each default service account to include this value\nautomountServiceAccountToken: false\n\nV-242402 Enable control plane logging for API Server, Audit, Authenticator, Controller Manager, and Scheduler.\nRef: https://docs.aws.amazon.com/eks/latest/userguide/control-plane-logs.html\n\nV-242403 Enable control plane logging for API Server, Audit, Authenticator, Controller Manager, and Scheduler.\nRef: https://docs.aws.amazon.com/eks/latest/userguide/control-plane-logs.html\n\nV-242461 Enable control plane logging for API Server, Audit, Authenticator, Controller Manager, and Scheduler.\nRef: https://docs.aws.amazon.com/eks/latest/userguide/control-plane-logs.html\n\nV-242462 Enable control plane logging for API Server, Audit, Authenticator, Controller Manager, and Scheduler.\nRef: https://docs.aws.amazon.com/eks/latest/userguide/control-plane-logs.html\n\nV-242463 Enable control plane logging for API Server, Audit, Authenticator, Controller Manager, and Scheduler.\nRef: https://docs.aws.amazon.com/eks/latest/userguide/control-plane-logs.html\n\nV-242464 Enable control plane logging for API Server, Audit, Authenticator, Controller Manager, and Scheduler.\nRef: https://docs.aws.amazon.com/eks/latest/userguide/control-plane-logs.html\n\nV-242465 Enable control plane logging for API Server, Audit, Authenticator, Controller Manager, and Scheduler.\nRef: https://docs.aws.amazon.com/eks/latest/userguide/control-plane-logs.html\n\nV-242443 Upgrade Kubernetes to a supported version.\nRef: https://docs.aws.amazon.com/eks/latest/userguide/update-cluster.html\n\n\n== Summary controlplane ==\n0 checks PASS\n2 checks FAIL\n9 checks WARN\n0 checks INFO\n\n[INFO] 3 Worker Node Security Configuration\n[INFO] 3.1 DISA Category Code I\n[WARN] V-242387 The Kubernetes Kubelet must have the read-only port flag disabled (Manual)\n[PASS] V-242391 The Kubernetes Kubelet must have anonymous authentication disabled (Automated)\n[PASS] V-242392 The Kubernetes kubelet must enable explicit authorization (Automated)\n[FAIL] V-242397 The Kubernetes kubelet static PodPath must not enable static pods (Automated)\n[WARN] V-242415 Secrets in Kubernetes must not be stored as environment variables.(Manual)\n[FAIL] V-242434 Kubernetes Kubelet must enable kernel protection (Automated)\n[PASS] V-242435 Kubernetes must prevent non-privileged users from executing privileged functions (Automated)\n[FAIL] V-242393 Kubernetes Worker Nodes must not have sshd service running. (Automated)\n[FAIL] V-242394 Kubernetes Worker Nodes must not have the sshd service enabled. (Automated)\n[WARN] V-242395 Kubernetes dashboard must not be enabled. (Manual)\n[PASS] V-242398 Kubernetes DynamicAuditing must not be enabled. (Automated)\n[PASS] V-242399 Kubernetes DynamicKubeletConfig must not be enabled. (Automated)\n[PASS] V-242404 Kubernetes Kubelet must deny hostname override (Automated)\n[PASS] V-242406 The Kubernetes kubelet configuration file must be owned by root (Automated)\n[PASS] V-242407 The Kubernetes kubelet configuration files must have file permissions set to 644 or more restrictive (Automated)\n[WARN] V-242414 The Kubernetes cluster must use non-privileged host ports for user pods. (Manual)\n[WARN] V-242442 Kubernetes must remove old components after updated versions have been installed. (Manual)\n[WARN] V-242396 Kubernetes Kubectl cp command must give expected access and results. (Manual)\n\n== Remediations node ==\nV-242387 If using a Kubelet config file, edit /var/lib/kubelet/config.yaml to set readOnlyPort to 0.\nIf using command line arguments, edit the kubelet service file\n/etc/systemd/system/kubelet.service.d/10-kubeadm.conf on each worker node and\nset the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n--read-only-port=0\nBased on your system, restart the kubelet service. For example:\nsystemctl daemon-reload\nsystemctl restart kubelet.service\n\nV-242397 Edit /var/lib/kubelet/config.yaml on each node to to remove the staticPodPath\nBased on your system, restart the kubelet service. For example,\nsystemctl daemon-reload\nsystemctl restart kubelet.service\n\nV-242415 Run the following command:\nkubectl get all -o jsonpath='{range .items[?(@..secretKeyRef)]} {.kind} {.metadata.name} {\"\\n\"}{end}' -A\nIf any of the values returned reference environment variables\nrewrite application code to read secrets from mounted secret files, rather than\nfrom environment variables.\n\nV-242434 If using a Kubelet config file, edit /var/lib/kubelet/config.yaml to set protectKernelDefaults: true.\nIf using command line arguments, edit the kubelet service file\n/etc/systemd/system/kubelet.service.d/10-kubeadm.conf on each worker node and\nset the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.\n--protect-kernel-defaults=true\nBased on your system, restart the kubelet service. For example:\nsystemctl daemon-reload\nsystemctl restart kubelet.service\n\nV-242393 To stop the sshd service, run the command: systemctl stop sshd\n\nV-242394 To disable the sshd service, run the command:\n  chkconfig sshd off\n\nV-242395 Run the command: kubectl get pods --all-namespaces -l k8s-app=kubernetes-dashboard\nIf any resources are returned, this is a finding.\nFix Text: Delete the Kubernetes dashboard deployment with the following command:\n  kubectl delete deployment kubernetes-dashboard --namespace=kube-system\n\nV-242414 For any of the pods that are using ports below 1024,\nreconfigure the pod to use a service to map a host non-privileged\nport to the pod port or reconfigure the image to use non-privileged ports.\n\nV-242442 To view all pods and the images used to create the pods, from the Master node, run the following command:\n kubectl get pods --all-namespaces -o jsonpath=\"{..image}\" | \\\n tr -s '[[:space:]]' '\\n' | \\\n sort | \\\n uniq -c\n Review the images used for pods running within Kubernetes.\n Remove any old pods that are using older images.\n\nV-242396 If any Worker nodes are not using kubectl version 1.12.9 or newer, this is a finding.\nUpgrade the Master and Worker nodes to the latest version of kubectl.\n\n\n== Summary node ==\n8 checks PASS\n4 checks FAIL\n6 checks WARN\n0 checks INFO\n\n[INFO] 4 Policies\n[INFO] 4.1 Policies - DISA Category Code I\n[WARN] V-242381 The Kubernetes Controller Manager must create unique service accounts for each work payload. (Manual)\n[WARN] V-242383 User-managed resources must be created in dedicated namespaces. (Manual)\n[WARN] V-242417 Kubernetes must separate user functionality. (Manual)\n\n== Remediations policies ==\nV-242381 Create explicit service accounts wherever a Kubernetes workload requires specific access\nto the Kubernetes API server.\nModify the configuration of each default service account to include this value\nautomountServiceAccountToken: false\n\nV-242383 Move any user-managed resources from the default, kube-public and kube-node-lease namespaces, to user namespaces.\n\nV-242417 Move any user pods that are present in the Kubernetes system namespaces to user specific namespaces.\n\n\n== Summary policies ==\n0 checks PASS\n0 checks FAIL\n3 checks WARN\n0 checks INFO\n\n[INFO] 5 Managed Services\n[INFO] 5.1 DISA Category Code I\n[INFO] V-242386 The Kubernetes API server must have the insecure port flag disabled | Component of EKS Control Plane\n[INFO] V-242388 The Kubernetes API server must have the insecure bind address not set | Component of EKS Control Plane\n[WARN] V-242436 The Kubernetes API server must have the ValidatingAdmissionWebhook enabled (manual)\n[INFO] V-245542 Kubernetes API Server must disable basic authentication to protect information in transit | Component of EKS Control Plane\n[INFO] 5.2 DISA Category Code II\n[INFO] V-242376 The Kubernetes Controller Manager must use TLS 1.2, at a minimum | Component of EKS Control Plane\n[INFO] V-242377 The Kubernetes Scheduler must use TLS 1.2, at a minimum | Component of EKS Control Plane\n[INFO] V-242378 The Kubernetes API Server must use TLS 1.2, at a minimum | Component of EKS Control Plane\n[INFO] V-242379 The Kubernetes etcd must use TLS to protect the confidentiality of sensitive data during electronic dissemination | Component of EKS Control Plane\n[INFO] V-242380 The Kubernetes etcd must use TLS to protect the confidentiality of sensitive data during electronic dissemination | Component of EKS Control Plane\n[INFO] V-242382 The Kubernetes API Server must enable Node,RBAC as the authorization mode | Component of EKS Control Plane\n[INFO] V-242384 The Kubernetes Scheduler must have secure binding | Component of EKS Control Plane\n[INFO] V-242385 The Kubernetes Controller Manager must have secure binding | Component of EKS Control Plane\n[INFO] V-242389 The Kubernetes API server must have the secure port set | Component of EKS Control Plane\n[INFO] V-242401 The Kubernetes API Server must have an audit policy set | Component of EKS Control Plane\n[INFO] V-242402 The Kubernetes API Server must have an audit log path set | Component of EKS Control Plane\n[INFO] V-242403 Kubernetes API Server must generate audit records | Component of EKS Control Plane\n[INFO] V-242405 The Kubernetes manifests must be owned by root | Component of EKS Control Plane\n[INFO] V-242408 The Kubernetes manifests must have least privileges | Component of EKS Control Plane\n[INFO] V-242409 Kubernetes Controller Manager must disable profiling | Component of EKS Control Plane\n[INFO] V-242410 The Kubernetes API Server must enforce PPS that adhere to PPSM CAL | Component of EKS Control Plane\n[INFO] V-242411 The Kubernetes Scheduler must enforce PPS that adhere to PPSM CAL | Component of EKS Control Plane\n[INFO] V-242412 The Kubernetes Controllers must enforce PPS that adhere to PPSM CAL | Component of EKS Control Plane\n[INFO] V-242413 The Kubernetes etcd must enforce PPS that adhere to PPSM CAL | Component of EKS Control Plane\n[INFO] V-242418 The Kubernetes API server must use approved cipher suites | Component of EKS Control Plane\n[INFO] V-242419 Kubernetes API Server must have the SSL Certificate Authority set | Component of EKS Control Plane\n[INFO] V-242420 Kubernetes Kubelet must have the SSL Certificate Authority set | Component of EKS Control Plane\n[INFO] V-242421 Kubernetes Controller Manager must have the SSL Certificate Authority set | Component of EKS Control Plane\n[INFO] V-242422 Kubernetes API Server must have a certificate for communication | Component of EKS Control Plane\n[INFO] V-242423 Kubernetes etcd must enable client authentication to secure service | Component of EKS Control Plane\n[INFO] V-242424 Kubernetes etcd must enable client authentication to secure service | Component of EKS Control Plane\n[INFO] V-242425 Kubernetes Kubelet must enable tls-cert-file for client authentication to secure service | Component of EKS Control Plane\n[INFO] V-242426 Kubernetes etcd must enable client authentication to secure service | Component of EKS Control Plane\n[INFO] V-242427 Kubernetes etcd must have a key file for secure communication | Component of EKS Control Plane\n[INFO] V-242428 Kubernetes etcd must have a certificate for communication | Component of EKS Control Plane\n[INFO] V-242429 Kubernetes etcd must have the SSL Certificate Authority set | Component of EKS Control Plane\n[INFO] V-242430 Kubernetes etcd must have a certificate for communication | Component of EKS Control Plane\n[INFO] V-242431 Kubernetes etcd must have a key file for secure communication | Component of EKS Control Plane\n[INFO] V-242432 Kubernetes etcd must have peer-cert-file set for secure communication | Component of EKS Control Plane\n[INFO] V-242433 Kubernetes etcd must have a peer-key-file set for secure communication | Component of EKS Control Plane\n[INFO] V-242438 Kubernetes API Server must configure timeouts to limit attack surface | Component of EKS Control Plane\n[INFO] V-242444 The Kubernetes component manifests must be owned by root | Component of EKS Control Plane\n[INFO] V-242445 The Kubernetes component etcd must be owned by etcd | Component of EKS Control Plane\n[INFO] V-242446 The Kubernetes conf files must be owned by root | Component of EKS Control Plane\n[INFO] V-242447 The Kubernetes Kube Proxy must have file permissions set to 644 or more restrictive | Component of EKS Control Plane\n[INFO] V-242448 The Kubernetes Kube Proxy must be owned by root | Component of EKS Control Plane\n[INFO] V-242449 The Kubernetes Kubelet certificate authority file must have file permissions set to 644 or more restrictive | Component of EKS Control Plane\n[INFO] V-242450 The Kubernetes Kubelet certificate authority must be owned by root | Component of EKS Control Plane\n[INFO] V-242451 The Kubernetes component PKI must be owned by root | Component of EKS Control Plane\n[INFO] V-242452 The Kubernetes kubelet config must have file permissions set to 644 or more restrictive | Component of EKS Control Plane\n[INFO] V-242453 The Kubernetes kubelet config must be owned by root | Component of EKS Control Plane\n[INFO] V-242454 The Kubernetes kubeadm.conf must be owned by root | Component of EKS Control Plane\n[INFO] V-242455 The Kubernetes kubeadm.conf must have file permissions set to 644 or more restrictive | Component of EKS Control Plane\n[INFO] V-242456 The Kubernetes kubelet config must have file permissions set to 644 or more restrictive | Component of EKS Control Plane\n[INFO] V-242457 The Kubernetes kubelet config must be owned by root | Component of EKS Control Plane\n[INFO] V-242458 The Kubernetes API Server must have file permissions set to 644 or more restrictive | Component of EKS Control Plane\n[INFO] V-242459 The Kubernetes etcd must have file permissions set to 644 or more restrictive | Component of EKS Control Plane\n[INFO] V-242460 The Kubernetes admin.conf must have file permissions set to 644 or more restrictive | Component of EKS Control Plane\n[INFO] V-242466 The Kubernetes PKI CRT must have file permissions set to 644 or more restrictive | Component of EKS Control Plane\n[INFO] V-242467 The Kubernetes PKI keys must have file permissions set to 600 or more restrictive | Component of EKS Control Plane\n[INFO] V-242468 The Kubernetes API Server must prohibit communication using TLS version 1.0 and 1.1, and SSL 2.0 and 3.0 | Component of EKS Control Plane\n[INFO] V-245541 Kubernetes Kubelet must not disable timeouts | Component of EKS Control Plane\n[INFO] V-245543 Kubernetes API Server must disable token authentication to protect information in transit | Component of EKS Control Plane\n[INFO] V-245544 Kubernetes endpoints must use approved organizational certificate and key pair to protect information in transit | Component of EKS Control Plane\n\n== Remediations managedservices ==\nV-242436 Amazon EKS version 1.18 and later automatically enable ValidatingAdmissionWebhook\nRef: https://docs.aws.amazon.com/eks/latest/userguide/platform-versions.html\n\n\n== Summary managedservices ==\n0 checks PASS\n0 checks FAIL\n1 checks WARN\n62 checks INFO\n\n== Summary total ==\n8 checks PASS\n6 checks FAIL\n19 checks WARN\n62 checks INFO\n\n"
  },
  {
    "path": "internal/findings/doc.go",
    "content": "/*\nPackage findings handles sending findings to Security Hub.\n*/\npackage findings\n"
  },
  {
    "path": "internal/findings/publisher.go",
    "content": "package findings\n\nimport (\n\t\"context\"\n\n\t\"github.com/aws/aws-sdk-go-v2/service/securityhub\"\n\t\"github.com/aws/aws-sdk-go-v2/service/securityhub/types\"\n\t\"github.com/pkg/errors\"\n)\n\n// A Publisher represents an object that publishes finds to AWS Security Hub.\ntype Publisher struct {\n\tclient securityhub.Client // AWS Security Hub Service Client\n}\n\n// A PublisherOutput represents an object that contains information about the service call.\ntype PublisherOutput struct {\n\t// The number of findings that failed to import.\n\t//\n\t// FailedCount is a required field\n\tFailedCount int32\n\n\t// The list of findings that failed to import.\n\tFailedFindings []types.ImportFindingsError\n\n\t// The number of findings that were successfully imported.\n\t//\n\t// SuccessCount is a required field\n\tSuccessCount int32\n}\n\n// New creates a new Publisher.\nfunc New(client securityhub.Client) *Publisher {\n\treturn &Publisher{\n\t\tclient: client,\n\t}\n}\n\n// PublishFinding publishes findings to AWS Security Hub Service\nfunc (p *Publisher) PublishFinding(finding []types.AwsSecurityFinding) (*PublisherOutput, error) {\n\to := PublisherOutput{}\n\ti := securityhub.BatchImportFindingsInput{}\n\ti.Findings = finding\n\tvar errs error\n\n\t// Split the slice into batches of 100 finding.\n\tbatch := 100\n\n\tfor i := 0; i < len(finding); i += batch {\n\t\ti := securityhub.BatchImportFindingsInput{}\n\t\ti.Findings = finding\n\t\tr, err := p.client.BatchImportFindings(context.Background(), &i) // Process the batch.\n\t\tif err != nil {\n\t\t\terrs = errors.Wrap(err, \"finding publish failed\")\n\t\t}\n\t\tif r != nil {\n\t\t\tif *r.FailedCount != 0 {\n\t\t\t\to.FailedCount += *r.FailedCount\n\t\t\t}\n\t\t\tif *r.SuccessCount != 0 {\n\t\t\t\to.SuccessCount += *r.SuccessCount\n\t\t\t}\n\t\t\to.FailedFindings = append(o.FailedFindings, r.FailedFindings...)\n\t\t}\n\t}\n\treturn &o, errs\n}\n"
  },
  {
    "path": "job-ack.yaml",
    "content": "---\napiVersion: batch/v1\nkind: Job\nmetadata:\n  name: kube-bench\nspec:\n  template:\n    spec:\n      hostPID: true\n      containers:\n        - name: kube-bench\n          image: docker.io/aquasec/kube-bench:latest\n          command:\n            [\n              \"kube-bench\",\n              \"run\",\n              \"--targets\",\n              \"node,policies,managedservices\",\n              \"--benchmark\",\n              \"ack-1.0\",\n            ]\n          volumeMounts:\n            - name: var-lib-kubelet\n              mountPath: /var/lib/kubelet\n              readOnly: true\n            - name: etc-systemd\n              mountPath: /etc/systemd\n              readOnly: true\n            - name: etc-kubernetes\n              mountPath: /etc/kubernetes\n              readOnly: true\n      restartPolicy: Never\n      volumes:\n        - name: var-lib-kubelet\n          hostPath:\n            path: \"/var/lib/kubelet\"\n        - name: etc-systemd\n          hostPath:\n            path: \"/etc/systemd\"\n        - name: etc-kubernetes\n          hostPath:\n            path: \"/etc/kubernetes\"\n"
  },
  {
    "path": "job-aks.yaml",
    "content": "---\napiVersion: batch/v1\nkind: Job\nmetadata:\n  name: kube-bench\nspec:\n  template:\n    spec:\n      hostPID: true\n      containers:\n        - name: kube-bench\n          image: docker.io/aquasec/kube-bench:latest\n          command:\n            [\"kube-bench\", \"run\", \"--targets\", \"node\", \"--benchmark\", \"aks-1.7\"]\n          volumeMounts:\n            - name: var-lib-kubelet\n              mountPath: /var/lib/kubelet\n              readOnly: true\n            - name: etc-systemd\n              mountPath: /etc/systemd\n              readOnly: true\n            - name: etc-default\n              mountPath: /etc/default\n              readOnly: true\n            - name: etc-kubernetes\n              mountPath: /etc/kubernetes\n              readOnly: true\n      restartPolicy: Never\n      volumes:\n        - name: var-lib-kubelet\n          hostPath:\n            path: \"/var/lib/kubelet\"\n        - name: etc-systemd\n          hostPath:\n            path: \"/etc/systemd\"\n        - name: etc-default\n          hostPath:\n            path: \"/etc/default\"\n        - name: etc-kubernetes\n          hostPath:\n            path: \"/etc/kubernetes\"\n"
  },
  {
    "path": "job-eks-asff.yaml",
    "content": "---\napiVersion: v1\nkind: ServiceAccount\nmetadata:\n  name: kube-bench\n  # If using a dedicated IAM role for kube-bench, uncomment the annotations\n  # block below and replace the ROLE_ARN\n  # annotations:\n  #   eks.amazonaws.com/role-arn: \"<ROLE_ARN>\"\n\n---\napiVersion: v1\nkind: ConfigMap\nmetadata:\n  name: kube-bench-eks-config\ndata:\n  config.yaml: |\n    AWS_ACCOUNT: \"<AWS_ACCT_NUMBER>\"\n    AWS_REGION: \"<AWS_REGION>\"\n    CLUSTER_ARN: \"<AWS_CLUSTER_ARN>\"\n\n---\napiVersion: batch/v1\nkind: Job\nmetadata:\n  name: kube-bench\nspec:\n  template:\n    spec:\n      hostPID: true\n      containers:\n        - name: kube-bench\n          # Push the image to your ECR and then refer to it here\n          # image: <ID.dkr.ecr.region.amazonaws.com/aquasec/kube-bench:ref>\n          image: docker.io/aquasec/kube-bench:latest\n          command:\n            [\n              \"kube-bench\",\n              \"run\",\n              \"--targets\",\n              \"node\",\n              \"--benchmark\",\n              \"eks-1.2.0\",\n              \"--asff\",\n            ]\n          env:\n            - name: NODE_NAME\n              valueFrom:\n                fieldRef:\n                  fieldPath: spec.nodeName\n          volumeMounts:\n            - name: var-lib-kubelet\n              mountPath: /var/lib/kubelet\n              readOnly: true\n            - name: etc-systemd\n              mountPath: /etc/systemd\n              readOnly: true\n            - name: etc-kubernetes\n              mountPath: /etc/kubernetes\n              readOnly: true\n            - name: kube-bench-eks-config\n              mountPath: \"/opt/kube-bench/cfg/eks-1.2.0/config.yaml\"\n              subPath: config.yaml\n              readOnly: true\n      restartPolicy: Never\n      serviceAccountName: kube-bench\n      volumes:\n        - name: var-lib-kubelet\n          hostPath:\n            path: \"/var/lib/kubelet\"\n        - name: etc-systemd\n          hostPath:\n            path: \"/etc/systemd\"\n        - name: etc-kubernetes\n          hostPath:\n            path: \"/etc/kubernetes\"\n        - name: kube-bench-eks-config\n          configMap:\n            name: kube-bench-eks-config\n            items:\n              - key: config.yaml\n                path: config.yaml\n"
  },
  {
    "path": "job-eks-stig.yaml",
    "content": "---\napiVersion: batch/v1\nkind: Job\nmetadata:\n  name: kube-bench\nspec:\n  template:\n    spec:\n      hostPID: true\n      containers:\n        - name: kube-bench\n          # Push the image to your ECR and then refer to it here\n          # image: <ID.dkr.ecr.region.amazonaws.com/aquasec/kube-bench:ref>\n          image: docker.io/aquasec/kube-bench:latest\n          # To send findings to AWS Security Hub, refer to `job-eks-asff.yaml` instead\n          command:\n            [\n              \"kube-bench\",\n              \"run\",\n              \"--benchmark\",\n              \"eks-stig-kubernetes-v1r6\",\n            ]\n          volumeMounts:\n            - name: var-lib-kubelet\n              mountPath: /var/lib/kubelet\n              readOnly: true\n            - name: etc-systemd\n              mountPath: /etc/systemd\n              readOnly: true\n            - name: etc-kubernetes\n              mountPath: /etc/kubernetes\n              readOnly: true\n      restartPolicy: Never\n      volumes:\n        - name: var-lib-kubelet\n          hostPath:\n            path: \"/var/lib/kubelet\"\n        - name: etc-systemd\n          hostPath:\n            path: \"/etc/systemd\"\n        - name: etc-kubernetes\n          hostPath:\n            path: \"/etc/kubernetes\"\n"
  },
  {
    "path": "job-eks.yaml",
    "content": "---\napiVersion: batch/v1\nkind: Job\nmetadata:\n  name: kube-bench\nspec:\n  template:\n    spec:\n      hostPID: true\n      containers:\n        - name: kube-bench\n          # Push the image to your ECR and then refer to it here\n          # image: <ID.dkr.ecr.region.amazonaws.com/aquasec/kube-bench:ref>\n          image: docker.io/aquasec/kube-bench:latest\n          # To send findings to AWS Security Hub, refer to `job-eks-asff.yaml` instead\n          command:\n            [\n              \"kube-bench\",\n              \"run\",\n              \"--targets\",\n              \"node,policies,managedservices,controlplane\",\n              \"--benchmark\",\n              \"eks-1.5.0\",\n            ]\n          volumeMounts:\n            - name: var-lib-kubelet\n              mountPath: /var/lib/kubelet\n              readOnly: true\n            - name: etc-systemd\n              mountPath: /etc/systemd\n              readOnly: true\n            - name: etc-kubernetes\n              mountPath: /etc/kubernetes\n              readOnly: true\n      restartPolicy: Never\n      volumes:\n        - name: var-lib-kubelet\n          hostPath:\n            path: \"/var/lib/kubelet\"\n        - name: etc-systemd\n          hostPath:\n            path: \"/etc/systemd\"\n        - name: etc-kubernetes\n          hostPath:\n            path: \"/etc/kubernetes\"\n"
  },
  {
    "path": "job-gke.yaml",
    "content": "---\napiVersion: batch/v1\nkind: Job\nmetadata:\n  name: kube-bench\nspec:\n  template:\n    spec:\n      hostPID: true\n      containers:\n        - name: kube-bench\n          image: docker.io/aquasec/kube-bench:latest\n          command:\n            [\n              \"kube-bench\",\n              \"run\",\n              \"--targets\",\n              \"node,policies,managedservices\",\n              \"--benchmark\",\n              \"gke-1.2.0\",\n            ]\n          volumeMounts:\n            - name: var-lib-kubelet\n              mountPath: /var/lib/kubelet\n              readOnly: true\n            - name: etc-systemd\n              mountPath: /etc/systemd\n              readOnly: true\n            - name: etc-kubernetes\n              mountPath: /etc/kubernetes\n              readOnly: true\n            - name: home-kubernetes\n              mountPath: /home/kubernetes\n              readOnly: true\n      restartPolicy: Never\n      volumes:\n        - name: var-lib-kubelet\n          hostPath:\n            path: \"/var/lib/kubelet\"\n        - name: etc-systemd\n          hostPath:\n            path: \"/etc/systemd\"\n        - name: etc-kubernetes\n          hostPath:\n            path: \"/etc/kubernetes\"\n        - name: home-kubernetes\n          hostPath:\n            path: \"/home/kubernetes\"\n"
  },
  {
    "path": "job-iks.yaml",
    "content": "---\napiVersion: batch/v1\nkind: Job\nmetadata:\n  name: kube-bench\nspec:\n  template:\n    spec:\n      hostPID: true\n      containers:\n        - name: kube-bench\n          image: docker.io/aquasec/kube-bench:latest\n          command:\n            [\"kube-bench\", \"run\", \"--targets\", \"node\", \"--version\", \"1.20\"]\n          volumeMounts:\n            - name: var-lib-kubelet\n              mountPath: /var/lib/kubelet\n              readOnly: true\n            - name: etc-systemd\n              mountPath: /etc/systemd\n              readOnly: true\n            - name: etc-kubernetes\n              mountPath: /etc/kubernetes\n              readOnly: true\n      restartPolicy: Never\n      volumes:\n        - name: var-lib-kubelet\n          hostPath:\n            path: \"/var/lib/kubelet\"\n        - name: etc-systemd\n          hostPath:\n            path: \"/lib/systemd\"\n        - name: etc-kubernetes\n          hostPath:\n            path: \"/etc/kubernetes\"\n        - name: usr-bin\n          hostPath:\n            path: \"/usr/bin\"\n"
  },
  {
    "path": "job-master.yaml",
    "content": "---\napiVersion: batch/v1\nkind: Job\nmetadata:\n  name: kube-bench-master\nspec:\n  template:\n    spec:\n      hostPID: true\n      affinity:\n        nodeAffinity:\n          requiredDuringSchedulingIgnoredDuringExecution:\n            nodeSelectorTerms:\n              - matchExpressions:\n                  - key: node-role.kubernetes.io/control-plane\n                    operator: Exists\n              - matchExpressions:\n                  - key: node-role.kubernetes.io/master\n                    operator: Exists\n      tolerations:\n        - key: node-role.kubernetes.io/master\n          operator: Exists\n          effect: NoSchedule\n        - key: node-role.kubernetes.io/control-plane\n          operator: Exists\n          effect: NoSchedule\n      containers:\n        - name: kube-bench\n          image: docker.io/aquasec/kube-bench:latest\n          command: [\"kube-bench\", \"run\", \"--targets\", \"master\"]\n          volumeMounts:\n            - name: var-lib-cni\n              mountPath: /var/lib/cni\n              readOnly: true\n            - name: var-lib-etcd\n              mountPath: /var/lib/etcd\n              readOnly: true\n            - name: var-lib-kubelet\n              mountPath: /var/lib/kubelet\n              readOnly: true\n            - name: var-lib-kube-scheduler\n              mountPath: /var/lib/kube-scheduler\n              readOnly: true\n            - name: var-lib-kube-controller-manager\n              mountPath: /var/lib/kube-controller-manager\n              readOnly: true\n            - name: etc-systemd\n              mountPath: /etc/systemd\n              readOnly: true\n            - name: lib-systemd\n              mountPath: /lib/systemd/\n              readOnly: true\n            - name: srv-kubernetes\n              mountPath: /srv/kubernetes/\n              readOnly: true\n            - name: etc-kubernetes\n              mountPath: /etc/kubernetes\n              readOnly: true\n              # /usr/local/mount-from-host/bin is mounted to access kubectl / kubelet, for auto-detecting the Kubernetes version.\n              # You can omit this mount if you specify --version as part of the command.\n            - name: usr-bin\n              mountPath: /usr/local/mount-from-host/bin\n              readOnly: true\n            - name: etc-cni-netd\n              mountPath: /etc/cni/net.d/\n              readOnly: true\n            - name: opt-cni-bin\n              mountPath: /opt/cni/bin/\n              readOnly: true\n            - name: etc-passwd\n              mountPath: /etc/passwd\n              readOnly: true\n            - name: etc-group\n              mountPath: /etc/group\n              readOnly: true\n      restartPolicy: Never\n      volumes:\n        - name: var-lib-cni\n          hostPath:\n            path: \"/var/lib/cni\"\n        - name: var-lib-etcd\n          hostPath:\n            path: \"/var/lib/etcd\"\n        - name: var-lib-kubelet\n          hostPath:\n            path: \"/var/lib/kubelet\"\n        - name: var-lib-kube-scheduler\n          hostPath:\n            path: \"/var/lib/kube-scheduler\"\n        - name: var-lib-kube-controller-manager\n          hostPath:\n            path: \"/var/lib/kube-controller-manager\"\n        - name: etc-systemd\n          hostPath:\n            path: \"/etc/systemd\"\n        - name: lib-systemd\n          hostPath:\n            path: \"/lib/systemd\"\n        - name: srv-kubernetes\n          hostPath:\n            path: \"/srv/kubernetes\"\n        - name: etc-kubernetes\n          hostPath:\n            path: \"/etc/kubernetes\"\n        - name: usr-bin\n          hostPath:\n            path: \"/usr/bin\"\n        - name: etc-cni-netd\n          hostPath:\n            path: \"/etc/cni/net.d/\"\n        - name: opt-cni-bin\n          hostPath:\n            path: \"/opt/cni/bin/\"\n        - name: etc-passwd\n          hostPath:\n            path: \"/etc/passwd\"\n        - name: etc-group\n          hostPath:\n            path: \"/etc/group\"\n"
  },
  {
    "path": "job-node.yaml",
    "content": "---\napiVersion: batch/v1\nkind: Job\nmetadata:\n  name: kube-bench-node\nspec:\n  template:\n    spec:\n      hostPID: true\n      containers:\n        - name: kube-bench\n          image: docker.io/aquasec/kube-bench:latest\n          command: [\"kube-bench\", \"run\", \"--targets\", \"node\"]\n          volumeMounts:\n            - name: var-lib-cni\n              mountPath: /var/lib/cni\n              readOnly: true\n            - name: var-lib-etcd\n              mountPath: /var/lib/etcd\n              readOnly: true\n            - name: var-lib-kubelet\n              mountPath: /var/lib/kubelet\n              readOnly: true\n            - name: var-lib-kube-scheduler\n              mountPath: /var/lib/kube-scheduler\n              readOnly: true\n            - name: var-lib-kube-controller-manager\n              mountPath: /var/lib/kube-controller-manager\n              readOnly: true\n            - name: etc-systemd\n              mountPath: /etc/systemd\n              readOnly: true\n            - name: lib-systemd\n              mountPath: /lib/systemd/\n              readOnly: true\n            - name: srv-kubernetes\n              mountPath: /srv/kubernetes/\n              readOnly: true\n            - name: etc-kubernetes\n              mountPath: /etc/kubernetes\n              readOnly: true\n              # /usr/local/mount-from-host/bin is mounted to access kubectl / kubelet, for auto-detecting the Kubernetes version.\n              # You can omit this mount if you specify --version as part of the command.\n            - name: usr-bin\n              mountPath: /usr/local/mount-from-host/bin\n              readOnly: true\n            - name: etc-cni-netd\n              mountPath: /etc/cni/net.d/\n              readOnly: true\n            - name: opt-cni-bin\n              mountPath: /opt/cni/bin/\n              readOnly: true\n      restartPolicy: Never\n      volumes:\n        - name: var-lib-cni\n          hostPath:\n            path: \"/var/lib/cni\"\n        - name: var-lib-etcd\n          hostPath:\n            path: \"/var/lib/etcd\"\n        - name: var-lib-kubelet\n          hostPath:\n            path: \"/var/lib/kubelet\"\n        - name: var-lib-kube-scheduler\n          hostPath:\n            path: \"/var/lib/kube-scheduler\"\n        - name: var-lib-kube-controller-manager\n          hostPath:\n            path: \"/var/lib/kube-controller-manager\"\n        - name: etc-systemd\n          hostPath:\n            path: \"/etc/systemd\"\n        - name: lib-systemd\n          hostPath:\n            path: \"/lib/systemd\"\n        - name: srv-kubernetes\n          hostPath:\n            path: \"/srv/kubernetes\"\n        - name: etc-kubernetes\n          hostPath:\n            path: \"/etc/kubernetes\"\n        - name: usr-bin\n          hostPath:\n            path: \"/usr/bin\"\n        - name: etc-cni-netd\n          hostPath:\n            path: \"/etc/cni/net.d/\"\n        - name: opt-cni-bin\n          hostPath:\n            path: \"/opt/cni/bin/\"\n"
  },
  {
    "path": "job-tkgi.yaml",
    "content": "---\napiVersion: batch/v1\nkind: Job\nmetadata:\n  name: kube-bench\nspec:\n  template:\n    spec:\n      hostPID: true\n      containers:\n        - name: kube-bench\n          image: docker.io/aquasec/kube-bench:latest\n          command:\n            [\n              \"kube-bench\",\n              \"run\",\n              \"--targets\",\n              \"node,policies\",\n              \"--benchmark\",\n              \"tkgi-1.2.53\",\n            ]\n          volumeMounts:\n            - name: var-vcap-jobs\n              mountPath: /var/vcap/jobs\n              readOnly: true\n            - name: var-vcap-data-jobs\n              mountPath: /var/vcap/data/jobs\n              readOnly: true\n            - name: var-vcap-packages\n              mountPath: /var/vcap/packages\n              readOnly: true\n            - name: var-vcap-store-etcd\n              mountPath: /var/vcap/store/etcd\n              readOnly: true\n            - name: var-vcap-sys\n              mountPath: /var/vcap/sys\n              readOnly: true\n            - name: var-vcap-data-sys\n              mountPath: /var/vcap/data/sys\n              readOnly: true\n            - name: etc-kubernetes\n              mountPath: /etc/kubernetes\n              readOnly: true\n      restartPolicy: Never\n      volumes:\n        - name: var-vcap-jobs\n          hostPath:\n            path: \"/var/vcap/jobs\"\n        - name: var-vcap-data-jobs\n          hostPath:\n            path: \"/var/vcap/data/jobs\"\n        - name: var-vcap-packages\n          hostPath:\n            path: \"/var/vcap/packages\"\n        - name: var-vcap-store-etcd\n          hostPath:\n            path: \"/var/vcap/store/etcd\"\n        - name: var-vcap-sys\n          hostPath:\n            path: \"/var/vcap/sys\"\n        - name: var-vcap-data-sys\n          hostPath:\n            path: \"/var/vcap/data/sys\"\n        - name: etc-kubernetes\n          hostPath:\n            path: \"/etc/kubernetes\"\n"
  },
  {
    "path": "job.yaml",
    "content": "---\napiVersion: batch/v1\nkind: Job\nmetadata:\n  name: kube-bench\nspec:\n  template:\n    metadata:\n      labels:\n        app: kube-bench\n    spec:\n      containers:\n        - command: [\"kube-bench\"]\n          image: docker.io/aquasec/kube-bench:v0.15.0\n          name: kube-bench\n          volumeMounts:\n            - name: var-lib-cni\n              mountPath: /var/lib/cni\n              readOnly: true\n            - mountPath: /var/lib/etcd\n              name: var-lib-etcd\n              readOnly: true\n            - mountPath: /var/lib/kubelet\n              name: var-lib-kubelet\n              readOnly: true\n            - mountPath: /var/lib/kube-scheduler\n              name: var-lib-kube-scheduler\n              readOnly: true\n            - mountPath: /var/lib/kube-controller-manager\n              name: var-lib-kube-controller-manager\n              readOnly: true\n            - mountPath: /etc/systemd\n              name: etc-systemd\n              readOnly: true\n            - mountPath: /lib/systemd/\n              name: lib-systemd\n              readOnly: true\n            - mountPath: /srv/kubernetes/\n              name: srv-kubernetes\n              readOnly: true\n            - mountPath: /etc/kubernetes\n              name: etc-kubernetes\n              readOnly: true\n            - mountPath: /usr/local/mount-from-host/bin\n              name: usr-bin\n              readOnly: true\n            - mountPath: /etc/cni/net.d/\n              name: etc-cni-netd\n              readOnly: true\n            - mountPath: /opt/cni/bin/\n              name: opt-cni-bin\n              readOnly: true\n      hostPID: true\n      restartPolicy: Never\n      volumes:\n        - name: var-lib-cni\n          hostPath:\n            path: /var/lib/cni\n        - hostPath:\n            path: /var/lib/etcd\n          name: var-lib-etcd\n        - hostPath:\n            path: /var/lib/kubelet\n          name: var-lib-kubelet\n        - hostPath:\n            path: /var/lib/kube-scheduler\n          name: var-lib-kube-scheduler\n        - hostPath:\n            path: /var/lib/kube-controller-manager\n          name: var-lib-kube-controller-manager\n        - hostPath:\n            path: /etc/systemd\n          name: etc-systemd\n        - hostPath:\n            path: /lib/systemd\n          name: lib-systemd\n        - hostPath:\n            path: /srv/kubernetes\n          name: srv-kubernetes\n        - hostPath:\n            path: /etc/kubernetes\n          name: etc-kubernetes\n        - hostPath:\n            path: /usr/bin\n          name: usr-bin\n        - hostPath:\n            path: /etc/cni/net.d/\n          name: etc-cni-netd\n        - hostPath:\n            path: /opt/cni/bin/\n          name: opt-cni-bin\n"
  },
  {
    "path": "main.go",
    "content": "// Copyright © 2017 Aqua Security Software Ltd. <info@aquasec.com>\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage main\n\nimport (\n\t\"github.com/aquasecurity/kube-bench/cmd\"\n)\n\nfunc main() {\n\tcmd.Execute()\n}\n"
  },
  {
    "path": "makefile",
    "content": "SOURCES := $(shell find . -name '*.go')\nBINARY := kube-bench\nDOCKER_ORG ?= aquasec\nVERSION ?= $(shell git rev-parse --short=7 HEAD)\nKUBEBENCH_VERSION ?= $(shell git describe --tags --abbrev=0)\nIMAGE_NAME ?= $(DOCKER_ORG)/$(BINARY):$(VERSION)\nIMAGE_NAME_UBI ?= $(DOCKER_ORG)/$(BINARY):$(VERSION)-ubi\nGOOS ?= linux\nBUILD_OS := linux\nuname := $(shell uname -s)\nBUILDX_PLATFORM ?= linux/amd64,linux/arm64,linux/arm,linux/ppc64le,linux/s390x\nDOCKER_ORGS ?= aquasec public.ecr.aws/aquasecurity\nGOARCH ?= $@\nKUBECTL_VERSION ?= 1.36.0-alpha.1\nARCH ?= $(shell go env GOARCH)\n\nifneq ($(findstring Microsoft,$(shell uname -r)),)\n\tBUILD_OS := windows\nelse ifeq ($(uname),Linux)\n\tBUILD_OS := linux\nelse ifeq ($(uname),Darwin)\n\tBUILD_OS := darwin\nendif\n\n# kind cluster name to use\nKIND_PROFILE ?= kube-bench\nKIND_CONTAINER_NAME=$(KIND_PROFILE)-control-plane\nKIND_IMAGE ?= kindest/node:v1.21.1@sha256:69860bda5563ac81e3c0057d654b5253219618a22ec3a346306239bba8cfa1a6\n\n# build a multi-arch image and push to Docker hub\n.PHONY: docker\ndocker:\n\tset -xe; \\\n\tfor org in $(DOCKER_ORGS); do \\\n\t\tdocker buildx build --tag $${org}/kube-bench:${VERSION} \\\n\t\t--platform $(BUILDX_PLATFORM) --push . ; \\\n\tdone\n\nbuild: $(BINARY)\n\n$(BINARY): $(SOURCES)\n\tGOOS=$(GOOS) CGO_ENABLED=0 go build -ldflags \"-X github.com/aquasecurity/kube-bench/cmd.KubeBenchVersion=$(KUBEBENCH_VERSION)\" -o $(BINARY) .\n\nbuild-fips:\n\tGOOS=$(GOOS) CGO_ENABLED=0 GOEXPERIMENT=boringcrypto go build -tags fipsonly -ldflags \"-X github.com/aquasecurity/kube-bench/cmd.KubeBenchVersion=$(KUBEBENCH_VERSION)\" -o $(BINARY) .\n\n# builds the current dev docker version\nbuild-docker:\n\tdocker build --build-arg BUILD_DATE=$(shell date -u +\"%Y-%m-%dT%H:%M:%SZ\") \\\n                     \t--build-arg VCS_REF=$(VERSION) \\\n\t\t     \t--build-arg KUBEBENCH_VERSION=$(KUBEBENCH_VERSION) \\\n\t             \t--build-arg KUBECTL_VERSION=$(KUBECTL_VERSION) \\\n\t\t\t--build-arg TARGETARCH=$(ARCH) \\\n                       \t-t $(IMAGE_NAME) .\n\nbuild-docker-ubi:\n\tdocker build -f Dockerfile.ubi --build-arg BUILD_DATE=$(shell date -u +\"%Y-%m-%dT%H:%M:%SZ\") \\\n            \t\t--build-arg VCS_REF=$(VERSION) \\\n\t\t\t--build-arg KUBEBENCH_VERSION=$(KUBEBENCH_VERSION) \\\n\t\t\t--build-arg KUBECTL_VERSION=$(KUBECTL_VERSION) \\\n\t\t\t--build-arg TARGETARCH=$(ARCH) \\\n            \t\t-t $(IMAGE_NAME_UBI) .\n\n# unit tests\ntests:\n\tGO111MODULE=on go test -vet all -short -race -timeout 30s -coverprofile=coverage.txt -covermode=atomic ./...\n\nintegration-test: kind-test-cluster kind-run\n\n# creates a kind cluster to be used for development.\nHAS_KIND := $(shell command -v kind;)\nkind-test-cluster:\nifndef HAS_KIND\n\tgo get -u sigs.k8s.io/kind\nendif\n\t@if [ -z $$(kind get clusters | grep $(KIND_PROFILE)) ]; then\\\n\t\techo \"Could not find $(KIND_PROFILE) cluster. Creating...\";\\\n\t\tkind create cluster --name $(KIND_PROFILE) --image $(KIND_IMAGE) --wait 5m;\\\n\tfi\n\n# pushes the current dev version to the kind cluster.\nkind-push: build-docker\n\tkind load docker-image $(IMAGE_NAME) --name $(KIND_PROFILE)\n\n# runs the current version on kind using a job and follow logs\nkind-run: KUBECONFIG = \"./kubeconfig.kube-bench\"\nkind-run: kind-push\n\tsed \"s/\\$${VERSION}/$(VERSION)/\" ./hack/kind.yaml > ./hack/kind.test.yaml\n\tkind get kubeconfig --name=\"$(KIND_PROFILE)\" > $(KUBECONFIG)\n\t-KUBECONFIG=$(KUBECONFIG) \\\n\t\tkubectl delete job kube-bench\n\tKUBECONFIG=$(KUBECONFIG) \\\n\t\tkubectl apply -f ./hack/kind.test.yaml && \\\n\t\tkubectl wait --for=condition=complete job.batch/kube-bench --timeout=60s && \\\n\t\tkubectl logs job/kube-bench > ./test.data && \\\n\t\tdiff ./test.data integration/testdata/Expected_output.data\n\nkind-run-stig: KUBECONFIG = \"./kubeconfig.kube-bench\"\nkind-run-stig: kind-push\n\tsed \"s/\\$${VERSION}/$(VERSION)/\" ./hack/kind-stig.yaml > ./hack/kind-stig.test.yaml\n\tkind get kubeconfig --name=\"$(KIND_PROFILE)\" > $(KUBECONFIG)\n\t-KUBECONFIG=$(KUBECONFIG) \\\n\t\tkubectl delete job kube-bench\n\tKUBECONFIG=$(KUBECONFIG) \\\n\t\tkubectl apply -f ./hack/kind-stig.test.yaml && \\\n\t\tkubectl wait --for=condition=complete job.batch/kube-bench --timeout=60s && \\\n\t\tkubectl logs job/kube-bench > ./test.data && \\\n\t\tdiff ./test.data integration/testdata/Expected_output_stig.data\n"
  },
  {
    "path": "mkdocs.yml",
    "content": "---\nsite_name: Kube-bench\nsite_url: https://aquasecurity.github.io/kube-bench/\nsite_description: Checks whether Kubernetes is deployed according to security best practices as defined in the CIS Kubernetes Benchmark\ndocs_dir: docs/\nrepo_name: GitHub\nrepo_url: https://github.com/aquasecurity/kube-bench/\nedit_uri: \"\"\n\nnav:\n  - Overview: index.md\n  - Getting Started:\n      - Installation: installation.md\n      - Platforms: platforms.md\n      - How to run: running.md\n      - ASFF: asff.md\n  - Flags: flags-and-commands.md\n  - Configuration Options:\n      - Understanding the yamls: controls.md\n      - Architecture: architecture.md\n  - Contributing: CONTRIBUTING.md\n\nmarkdown_extensions:\n  - pymdownx.highlight\n  - pymdownx.superfences\n  - admonition\n\nextra:\n  generator: false\n  version:\n    method: mike\n    provider: mike\n\ntheme:\n  name: material\n  language: 'en'\n  logo: images/kube-bench-logo-only.png\n\nplugins:\n  - search\n  - macros\n"
  }
]