diff --git a/.github/workflows/build-and-push-fleetctl-docker.yml b/.github/workflows/build-and-push-fleetctl-docker.yml index a42eb0ddd3..8ae3c7069e 100644 --- a/.github/workflows/build-and-push-fleetctl-docker.yml +++ b/.github/workflows/build-and-push-fleetctl-docker.yml @@ -29,6 +29,11 @@ jobs: permissions: contents: write steps: + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit + - name: Checkout uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 diff --git a/.github/workflows/build-binaries.yaml b/.github/workflows/build-binaries.yaml index 29faa1eacf..ed18437c74 100644 --- a/.github/workflows/build-binaries.yaml +++ b/.github/workflows/build-binaries.yaml @@ -24,6 +24,11 @@ jobs: build-binaries: runs-on: ubuntu-latest steps: + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit + - name: Install Go uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0 with: diff --git a/.github/workflows/build-orbit.yaml b/.github/workflows/build-orbit.yaml index 40e3c84909..09f296aece 100644 --- a/.github/workflows/build-orbit.yaml +++ b/.github/workflows/build-orbit.yaml @@ -33,6 +33,11 @@ jobs: build: runs-on: macos-latest steps: + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit + - name: Checkout uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 diff --git a/.github/workflows/check-tuf-timestamps.yml b/.github/workflows/check-tuf-timestamps.yml index 4a67a3d5b0..f5c01ec136 100644 --- a/.github/workflows/check-tuf-timestamps.yml +++ b/.github/workflows/check-tuf-timestamps.yml @@ -29,6 +29,11 @@ jobs: runs-on: ${{ matrix.os }} steps: + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit + - name: Check remote timestamp.json file run: | expires=$(curl -s http://tuf.fleetctl.com/timestamp.json | jq -r '.signed.expires' | cut -c 1-10) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 37e1fd9850..246c6418a1 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -45,6 +45,11 @@ jobs: # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed steps: + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit + - name: Checkout repository uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml new file mode 100644 index 0000000000..3f3456223b --- /dev/null +++ b/.github/workflows/dependency-review.yml @@ -0,0 +1,27 @@ +# Dependency Review Action +# +# This Action will scan dependency manifest files that change as part of a Pull Request, +# surfacing known-vulnerable versions of the packages declared or updated in the PR. +# Once installed, if the workflow run is marked as required, +# PRs introducing known-vulnerable packages will be blocked from merging. +# +# Source repository: https://github.com/actions/dependency-review-action +name: 'Dependency Review' +on: [pull_request] + +permissions: + contents: read + +jobs: + dependency-review: + runs-on: ubuntu-latest + steps: + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit + + - name: 'Checkout Repository' + uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 + - name: 'Dependency Review' + uses: actions/dependency-review-action@0efb1d1d84fc9633afcdaad14c485cbbc90ef46c # v2.5.1 diff --git a/.github/workflows/deploy-fleet-website.yml b/.github/workflows/deploy-fleet-website.yml index 538291617b..9fc044e13b 100644 --- a/.github/workflows/deploy-fleet-website.yml +++ b/.github/workflows/deploy-fleet-website.yml @@ -34,6 +34,11 @@ jobs: node-version: [16.x] steps: + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit + - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 # Configure our access credentials for the Heroku CLI diff --git a/.github/workflows/deploy-vulnerability-dashboard.yml b/.github/workflows/deploy-vulnerability-dashboard.yml index 7f453b8367..5030c2eb1c 100644 --- a/.github/workflows/deploy-vulnerability-dashboard.yml +++ b/.github/workflows/deploy-vulnerability-dashboard.yml @@ -6,8 +6,13 @@ on: paths: - 'ee/vulnerability-dashboard/**' +permissions: + contents: read + jobs: build: + permissions: + contents: write # for Git to git push if: ${{ github.repository == 'fleetdm/fleet' }} runs-on: ubuntu-latest @@ -17,14 +22,19 @@ jobs: node-version: [14.x] steps: + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit + - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 # Configure our access credentials for the Heroku CLI - uses: akhileshns/heroku-deploy@79ef2ae4ff9b897010907016b268fd0f88561820 # v3.6.8 with: - heroku_api_key: ${{secrets.HEROKU_API_TOKEN_FOR_DEPLOYMENT}} + heroku_api_key: ${{secrets.HEROKU_API_TOKEN_FOR_BOT_USER}} heroku_app_name: "" # this has to be blank or it doesn't work - heroku_email: ${{secrets.HEROKU_EMAIL_FOR_DEPLOYMENT}} + heroku_email: ${{secrets.HEROKU_EMAIL_FOR_BOT_USER}} justlogin: true - run: heroku auth:whoami diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 8b0b3a22fe..ec0df78a4d 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -28,6 +28,11 @@ jobs: contents: read # to read files to check dead links runs-on: ubuntu-latest steps: + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit + - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - uses: gaurav-nelson/github-action-markdown-link-check@d53a906aa6b22b8979d33bc86170567e619495ec # v1.0.15 with: diff --git a/.github/workflows/dogfood-deploy.yml b/.github/workflows/dogfood-deploy.yml index 393102abd0..d13d2f4761 100644 --- a/.github/workflows/dogfood-deploy.yml +++ b/.github/workflows/dogfood-deploy.yml @@ -41,6 +41,11 @@ jobs: name: Deploy Fleet Dogfood Environment runs-on: ubuntu-latest steps: + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit + - uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b - id: fail-on-main run: "false" diff --git a/.github/workflows/dogfood-gitops.yml b/.github/workflows/dogfood-gitops.yml index e50cbc7a33..43761a5fbb 100644 --- a/.github/workflows/dogfood-gitops.yml +++ b/.github/workflows/dogfood-gitops.yml @@ -22,11 +22,16 @@ jobs: timeout-minutes: 10 runs-on: ubuntu-latest steps: + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit + - name: Checkout our repository - uses: actions/checkout@v4 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Checkout GitOps repository - uses: actions/checkout@v4 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 with: repository: fleetdm/fleet-gitops ref: main diff --git a/.github/workflows/fleet-and-orbit.yml b/.github/workflows/fleet-and-orbit.yml index 29d4d82c7a..2849c0f561 100644 --- a/.github/workflows/fleet-and-orbit.yml +++ b/.github/workflows/fleet-and-orbit.yml @@ -44,6 +44,11 @@ jobs: address: ${{ steps.gen.outputs.address }} enroll_secret: ${{ steps.gen.outputs.enroll_secret }} steps: + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit + - id: gen run: | UUID=$(uuidgen) @@ -62,6 +67,11 @@ jobs: runs-on: ubuntu-latest needs: gen steps: + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit + - name: Install Go uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0 with: @@ -171,6 +181,11 @@ jobs: runs-on: ubuntu-latest needs: gen steps: + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit + - name: Install Go uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0 with: @@ -214,6 +229,11 @@ jobs: # or if we revise our minimum supported macOS version. runs-on: macos-12 steps: + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit + - name: Install Go uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0 with: @@ -255,6 +275,11 @@ jobs: runs-on: ubuntu-latest needs: [gen, build-macos-targets] steps: + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit + - name: Install Go uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0 with: @@ -317,6 +342,11 @@ jobs: runs-on: macos-latest needs: [gen, run-tuf-and-gen-pkgs] steps: + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit + - name: Checkout Code uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 @@ -366,6 +396,11 @@ jobs: runs-on: ubuntu-latest needs: [gen, run-tuf-and-gen-pkgs] steps: + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit + - name: Download deb id: download uses: actions/download-artifact@fb598a63ae348fa914e94cd0ff38f362e927b741 # v2 @@ -412,6 +447,11 @@ jobs: needs: [gen, run-tuf-and-gen-pkgs] runs-on: windows-latest steps: + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit + - name: Download msi id: download uses: actions/download-artifact@fb598a63ae348fa914e94cd0ff38f362e927b741 # v2 diff --git a/.github/workflows/fleetctl-preview-latest.yml b/.github/workflows/fleetctl-preview-latest.yml index 839072ed83..dda4e0f73c 100644 --- a/.github/workflows/fleetctl-preview-latest.yml +++ b/.github/workflows/fleetctl-preview-latest.yml @@ -57,6 +57,11 @@ jobs: runs-on: ${{ matrix.os }} steps: + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit + - name: Install Go uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0 with: diff --git a/.github/workflows/fleetctl-preview.yml b/.github/workflows/fleetctl-preview.yml index 9bcfdb7376..ab9a69c2b2 100644 --- a/.github/workflows/fleetctl-preview.yml +++ b/.github/workflows/fleetctl-preview.yml @@ -27,6 +27,11 @@ jobs: runs-on: ${{ matrix.os }} steps: + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit + - name: Test fleetctl preview run: | npm install -g fleetctl diff --git a/.github/workflows/fleetd-tuf.yml b/.github/workflows/fleetd-tuf.yml index 26faf617c5..c1617cb860 100644 --- a/.github/workflows/fleetd-tuf.yml +++ b/.github/workflows/fleetd-tuf.yml @@ -25,6 +25,11 @@ jobs: pull-requests: write # for peter-evans/create-pull-request to create a PR runs-on: ubuntu-latest steps: + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit + - name: Install Go uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0 with: diff --git a/.github/workflows/generate-desktop-targets.yml b/.github/workflows/generate-desktop-targets.yml index b2557c1a06..fef2d6075b 100644 --- a/.github/workflows/generate-desktop-targets.yml +++ b/.github/workflows/generate-desktop-targets.yml @@ -40,6 +40,11 @@ jobs: runs-on: macos-12 steps: + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit + - name: Install Go uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0 with: @@ -88,6 +93,11 @@ jobs: runs-on: ubuntu-latest steps: + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit + - name: Install Go uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0 with: @@ -111,6 +121,11 @@ jobs: runs-on: ubuntu-latest steps: + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit + - name: Install Go uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0 with: diff --git a/.github/workflows/generate-nudge-targets.yml b/.github/workflows/generate-nudge-targets.yml index b1771f6703..4b7f025f4e 100644 --- a/.github/workflows/generate-nudge-targets.yml +++ b/.github/workflows/generate-nudge-targets.yml @@ -33,6 +33,11 @@ jobs: generate-macos: runs-on: macos-latest steps: + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit + - name: Checkout uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 diff --git a/.github/workflows/generate-osqueryd-targets.yml b/.github/workflows/generate-osqueryd-targets.yml index e2d4933e61..0af9f64bea 100644 --- a/.github/workflows/generate-osqueryd-targets.yml +++ b/.github/workflows/generate-osqueryd-targets.yml @@ -33,6 +33,11 @@ jobs: generate-macos: runs-on: macos-latest steps: + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit + - name: Checkout uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 @@ -49,6 +54,11 @@ jobs: generate-linux: runs-on: ubuntu-latest steps: + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit + - name: Checkout uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 @@ -69,6 +79,11 @@ jobs: generate-windows: runs-on: windows-latest steps: + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit + - name: Checkout uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml index 6de7068ccf..1d00e3c0d9 100644 --- a/.github/workflows/golangci-lint.yml +++ b/.github/workflows/golangci-lint.yml @@ -41,6 +41,11 @@ jobs: go-version: ['${{ vars.GO_VERSION }}'] runs-on: ${{ matrix.os }} steps: + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit + - name: Checkout code uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 diff --git a/.github/workflows/goreleaser-fleet.yaml b/.github/workflows/goreleaser-fleet.yaml index 8f8f2cd67d..f192a624ff 100644 --- a/.github/workflows/goreleaser-fleet.yaml +++ b/.github/workflows/goreleaser-fleet.yaml @@ -25,6 +25,11 @@ jobs: permissions: contents: write steps: + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit + - name: Checkout uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 with: diff --git a/.github/workflows/goreleaser-orbit.yaml b/.github/workflows/goreleaser-orbit.yaml index 1efd3faec1..2f1eb3905b 100644 --- a/.github/workflows/goreleaser-orbit.yaml +++ b/.github/workflows/goreleaser-orbit.yaml @@ -24,6 +24,11 @@ jobs: permissions: contents: read steps: + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit + - name: Checkout uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 @@ -73,6 +78,11 @@ jobs: permissions: contents: read steps: + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit + - name: Checkout uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 @@ -101,6 +111,11 @@ jobs: permissions: contents: read steps: + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit + - name: Checkout uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 diff --git a/.github/workflows/goreleaser-snapshot-fleet.yaml b/.github/workflows/goreleaser-snapshot-fleet.yaml index c6fb9c1419..65ac166c1b 100644 --- a/.github/workflows/goreleaser-snapshot-fleet.yaml +++ b/.github/workflows/goreleaser-snapshot-fleet.yaml @@ -40,6 +40,11 @@ jobs: runs-on: ubuntu-20.04 environment: Docker Hub steps: + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit + - name: Checkout uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index 04f61e743b..a6200e9849 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -31,6 +31,11 @@ jobs: subdomain: ${{ steps.gen.outputs.subdomain }} address: ${{ steps.gen.outputs.address }} steps: + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit + - id: gen run: | UUID=$(uuidgen) @@ -41,6 +46,11 @@ jobs: runs-on: ubuntu-latest needs: gen steps: + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit + - name: Start tunnel env: CERT_PEM: ${{ secrets.CLOUDFLARE_TUNNEL_FLEETUEM_CERT_B64 }} @@ -136,6 +146,11 @@ jobs: token: ${{ steps.login.outputs.token }} steps: # Download fleet and fleetctl binaries from last successful build on main + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit + - name: Download binaries uses: dawidd6/action-download-artifact@5e780fc7bbd0cac69fc73271ed86edf5dcb72d67 with: @@ -178,6 +193,11 @@ jobs: runs-on: macos-latest needs: [gen, login] steps: + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit + - name: Checkout Code uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 @@ -234,6 +254,11 @@ jobs: runs-on: ubuntu-latest needs: [gen, login] steps: + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit + - name: Install dependencies run: | npm install -g fleetctl @@ -299,6 +324,11 @@ jobs: runs-on: ubuntu-latest needs: [gen, login] steps: + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit + - name: Install dependencies run: | docker pull fleetdm/wix:latest & @@ -335,6 +365,11 @@ jobs: needs: [gen, login, orbit-windows-build] runs-on: windows-latest steps: + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit + - name: Install dependencies shell: bash run: | diff --git a/.github/workflows/pr-helm.yaml b/.github/workflows/pr-helm.yaml index c81c21f7b4..4f119e04a6 100644 --- a/.github/workflows/pr-helm.yaml +++ b/.github/workflows/pr-helm.yaml @@ -28,6 +28,11 @@ jobs: kube-version: [1.16.0, 1.17.0, 1.18.0] # kubeval is currently lagging behind the active schema versions, so these are the ones we can test against. see https://github.com/instrumenta/kubernetes-json-schema/issues/26 runs-on: ubuntu-20.04 steps: + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit + - name: checkout uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - name: create temp dir diff --git a/.github/workflows/push-osquery-perf-to-ecr.yml b/.github/workflows/push-osquery-perf-to-ecr.yml index c905c92e08..0760d03900 100644 --- a/.github/workflows/push-osquery-perf-to-ecr.yml +++ b/.github/workflows/push-osquery-perf-to-ecr.yml @@ -35,6 +35,11 @@ jobs: build-docker: runs-on: ubuntu-latest steps: + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit + - name: Checkout Code uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 diff --git a/.github/workflows/release-fleetd-chrome-beta.yml b/.github/workflows/release-fleetd-chrome-beta.yml index 7c81d9be4f..8f50b02d60 100644 --- a/.github/workflows/release-fleetd-chrome-beta.yml +++ b/.github/workflows/release-fleetd-chrome-beta.yml @@ -24,6 +24,11 @@ jobs: permissions: contents: read steps: + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit + - name: Checkout uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 diff --git a/.github/workflows/release-fleetd-chrome.yml b/.github/workflows/release-fleetd-chrome.yml index dc168426d5..6751d7705e 100644 --- a/.github/workflows/release-fleetd-chrome.yml +++ b/.github/workflows/release-fleetd-chrome.yml @@ -25,6 +25,11 @@ jobs: permissions: contents: read steps: + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit + - name: Checkout uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 diff --git a/.github/workflows/release-helm.yaml b/.github/workflows/release-helm.yaml index 91ef4e34c1..d6d738c362 100644 --- a/.github/workflows/release-helm.yaml +++ b/.github/workflows/release-helm.yaml @@ -24,6 +24,11 @@ jobs: contents: write # to push helm charts runs-on: ubuntu-20.04 steps: + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit + - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - uses: stefanprodan/helm-gh-pages@0ad2bb377311d61ac04ad9eb6f252fb68e207260 with: diff --git a/.github/workflows/scorecards-analysis.yml b/.github/workflows/scorecards-analysis.yml index af1990e9c5..59dfd8a7ff 100644 --- a/.github/workflows/scorecards-analysis.yml +++ b/.github/workflows/scorecards-analysis.yml @@ -24,6 +24,11 @@ jobs: id-token: write steps: + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit + - name: "Checkout code" uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # v3.1.0 with: diff --git a/.github/workflows/test-db-changes.yml b/.github/workflows/test-db-changes.yml index 46aafcc9d4..301645008e 100644 --- a/.github/workflows/test-db-changes.yml +++ b/.github/workflows/test-db-changes.yml @@ -30,6 +30,11 @@ jobs: test-db-changes: runs-on: ubuntu-latest steps: + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit + - name: Install Go uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0 with: diff --git a/.github/workflows/test-fleetd-chrome.yml b/.github/workflows/test-fleetd-chrome.yml index d9772cf225..82fa08fc82 100644 --- a/.github/workflows/test-fleetd-chrome.yml +++ b/.github/workflows/test-fleetd-chrome.yml @@ -31,6 +31,11 @@ jobs: runs-on: ${{ matrix.os }} steps: + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit + - name: Checkout Code uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 diff --git a/.github/workflows/test-go.yaml b/.github/workflows/test-go.yaml index 0a924f3876..69c9b3be6c 100644 --- a/.github/workflows/test-go.yaml +++ b/.github/workflows/test-go.yaml @@ -52,6 +52,11 @@ jobs: GO_TEST_TIMEOUT: 15m steps: + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit + - name: Install Go uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0 with: diff --git a/.github/workflows/test.yml b/.github/workflows/test-js.yml similarity index 88% rename from .github/workflows/test.yml rename to .github/workflows/test-js.yml index cf9c08157f..9d63523737 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test-js.yml @@ -1,4 +1,4 @@ -name: Run Tests +name: JavaScript Tests on: push: @@ -37,6 +37,11 @@ jobs: steps: # Set the Node.js version + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit + - name: Set up Node.js ${{ vars.NODE_VERSION }} uses: actions/setup-node@5e21ff4d9bc1a8cf6de233a3057d20ec6b3fb69d # v3.8.1 with: @@ -76,6 +81,11 @@ jobs: steps: # Set the Node.js version + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit + - name: Set up Node.js ${{ vars.NODE_VERSION }} uses: actions/setup-node@5e21ff4d9bc1a8cf6de233a3057d20ec6b3fb69d # v3.8.1 with: diff --git a/.github/workflows/test-native-tooling-packaging.yml b/.github/workflows/test-native-tooling-packaging.yml index a109100ffb..db242cee0c 100644 --- a/.github/workflows/test-native-tooling-packaging.yml +++ b/.github/workflows/test-native-tooling-packaging.yml @@ -45,6 +45,11 @@ jobs: runs-on: ${{ matrix.os }} steps: + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit + - name: Install Go uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0 with: diff --git a/.github/workflows/test-packaging.yml b/.github/workflows/test-packaging.yml index bdf5940aab..113f3c33ce 100644 --- a/.github/workflows/test-packaging.yml +++ b/.github/workflows/test-packaging.yml @@ -51,6 +51,11 @@ jobs: # Docker needs to be installed manually on macOS. # From https://github.com/docker/for-mac/issues/2359#issuecomment-943131345 # FIXME: lock Docker version to 4.10.0 as newer versions fail to initialize + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit + - name: Install Docker timeout-minutes: 20 if: matrix.os == 'macos-latest' diff --git a/.github/workflows/test-puppet.yml b/.github/workflows/test-puppet.yml index 82531fc272..f537913a52 100644 --- a/.github/workflows/test-puppet.yml +++ b/.github/workflows/test-puppet.yml @@ -28,6 +28,11 @@ jobs: test-puppet: runs-on: macos-latest steps: + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit + - name: Install Puppet Development Kit run: brew install --cask puppetlabs/puppet/pdk diff --git a/.github/workflows/test-vulnerability-dashboard-changes.yml b/.github/workflows/test-vulnerability-dashboard-changes.yml index abc11f57ae..d2c5cb45fc 100644 --- a/.github/workflows/test-vulnerability-dashboard-changes.yml +++ b/.github/workflows/test-vulnerability-dashboard-changes.yml @@ -9,6 +9,9 @@ concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.run_id}} cancel-in-progress: true +permissions: + contents: read + jobs: build: permissions: @@ -20,6 +23,11 @@ jobs: node-version: [16.x] steps: + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit + - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 # Set the Node.js version diff --git a/.github/workflows/test-website.yml b/.github/workflows/test-website.yml index a9fd54ef31..3045c9d4a7 100644 --- a/.github/workflows/test-website.yml +++ b/.github/workflows/test-website.yml @@ -32,6 +32,11 @@ jobs: node-version: [16.x] steps: + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit + - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 # Set the Node.js version diff --git a/.github/workflows/test-yml-specs.yml b/.github/workflows/test-yml-specs.yml index d4e0ed7db0..75e46d6af0 100644 --- a/.github/workflows/test-yml-specs.yml +++ b/.github/workflows/test-yml-specs.yml @@ -37,6 +37,11 @@ jobs: runs-on: ${{ matrix.os }} steps: + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit + - name: Install Go uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0 with: diff --git a/.github/workflows/tfvalidate.yml b/.github/workflows/tfvalidate.yml index 05da7c6e6e..6513377a08 100644 --- a/.github/workflows/tfvalidate.yml +++ b/.github/workflows/tfvalidate.yml @@ -30,6 +30,11 @@ jobs: runs-on: ubuntu-latest steps: + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit + - name: Clone repo uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 diff --git a/.github/workflows/trivy-scan.yml b/.github/workflows/trivy-scan.yml index 0d362fe9b4..9e0686c46b 100644 --- a/.github/workflows/trivy-scan.yml +++ b/.github/workflows/trivy-scan.yml @@ -34,6 +34,11 @@ jobs: runs-on: ubuntu-latest steps: + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit + - name: Checkout code uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 diff --git a/.github/workflows/update-certs.yml b/.github/workflows/update-certs.yml index 1aa054f68a..c5227657f3 100644 --- a/.github/workflows/update-certs.yml +++ b/.github/workflows/update-certs.yml @@ -25,6 +25,11 @@ jobs: pull-requests: write # for peter-evans/create-pull-request to create a PR runs-on: ubuntu-latest steps: + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit + - name: Checkout code uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # v.24.0 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000000..aee9602607 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,35 @@ +repos: +- repo: https://github.com/digitalpulp/pre-commit-php + rev: 1.4.0 + hooks: + - id: php-lint-all +- repo: https://github.com/gitleaks/gitleaks + rev: v8.16.3 + hooks: + - id: gitleaks +- repo: https://github.com/golangci/golangci-lint + rev: v1.52.2 + hooks: + - id: golangci-lint +- repo: https://github.com/jumanjihouse/pre-commit-hooks + rev: 3.0.0 + hooks: + - id: RuboCop + - id: shellcheck +- repo: https://github.com/pocc/pre-commit-hooks + rev: v1.3.5 + hooks: + - id: cpplint +- repo: https://github.com/pre-commit/mirrors-eslint + rev: v8.38.0 + hooks: + - id: eslint +- repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.4.0 + hooks: + - id: end-of-file-fixer + - id: trailing-whitespace +- repo: https://github.com/pylint-dev/pylint + rev: v2.17.2 + hooks: + - id: pylint diff --git a/CODEOWNERS b/CODEOWNERS index 45f22c8841..6813739818 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -68,7 +68,7 @@ go.mod @fleetdm/go /docs/Using-Fleet/REST-API.md @rachaelshaw # « REST API reference documentation /docs/Contributing/API-for-contributors.md @rachaelshaw # « Advanced / contributors-only API reference documentation /schema @eashaw # « Data tables (osquery/fleetd schema) documentation -/docs/Deploy/kubernetes/ @dherder # « Kubernetes best practice +/docs/Deploy/_kubernetes/ @dherder # « Kubernetes best practice ############################################################################################## # 🫧 Pricing and features # @@ -106,5 +106,56 @@ go.mod @fleetdm/go ############################################################################################## /.github/ISSUE_TEMPLATE @mikermcneil @sampfluger88 @lukeheath # See https://github.com/fleetdm/fleet/pull/16203 +############################################################################################## +# 🌐 GitHub workflows +############################################################################################## +/.github/workflows/markdown-link-check-config.json @eashaw +/.github/workflows/deploy-vulnerability-dashboard.yml @eashaw +/.github/workflows/test-website.yml @eashaw +/.github/workflows/test-vulnerability-dashboard-changes.yml @eashaw +/.github/workflows/docs.yml @eashaw +/.github/workflows/deploy-fleet-website.yml @eashaw + +############################################################################################## +# 🚀 GitHub workflows +############################################################################################## +/.github/workflows/README.md @lukeheath @georgekarrv @sharon-fdm +/.github/workflows/goreleaser-fleet.yaml @lukeheath @georgekarrv @sharon-fdm +/.github/workflows/update-certs.yml @lukeheath @georgekarrv @sharon-fdm +/.github/workflows/codeql-analysis.yml @lukeheath @georgekarrv @sharon-fdm +/.github/workflows/codeql.yml @lukeheath @georgekarrv @sharon-fdm +/.github/workflows/scorecards-analysis.yml @lukeheath @georgekarrv @sharon-fdm +/.github/workflows/integration.yml @lukeheath @georgekarrv @sharon-fdm +/.github/workflows/fleetctl-preview.yml @lukeheath @georgekarrv @sharon-fdm +/.github/workflows/fleetctl-preview-latest.yml @lukeheath @georgekarrv @sharon-fdm +/.github/workflows/goreleaser-orbit.yaml @lukeheath @georgekarrv @sharon-fdm +/.github/workflows/trivy-scan.yml @lukeheath @georgekarrv @sharon-fdm +/.github/workflows/goreleaser-snapshot-fleet.yaml @lukeheath @georgekarrv @sharon-fdm +/.github/workflows/build-and-push-fleetctl-docker.yml @lukeheath @georgekarrv @sharon-fdm +/.github/workflows/fleetd-tuf.yml @lucasmrod @lukeheath @georgekarrv @sharon-fdm +/.github/workflows/generate-desktop-targets.yml @lucasmrod @lukeheath @georgekarrv @sharon-fdm +/.github/workflows/test-yml-specs.yml @lucasmrod @lukeheath @georgekarrv @sharon-fdm +/.github/workflows/build-binaries.yaml @lucasmrod @lukeheath @georgekarrv @sharon-fdm +/.github/workflows/fleet-and-orbit.yml @lucasmrod @lukeheath @georgekarrv @sharon-fdm +/.github/workflows/build-orbit.yaml @lucasmrod @lukeheath @georgekarrv @sharon-fdm +/.github/workflows/generate-osqueryd-targets.yml @lucasmrod @lukeheath @georgekarrv @sharon-fdm +/.github/workflows/test-packaging.yml @lucasmrod @lukeheath @georgekarrv @sharon-fdm +/.github/workflows/release-helm.yaml @rfairburn @lukeheath @georgekarrv @sharon-fdm +/.github/workflows/pr-helm.yaml @rfairburn @lukeheath @georgekarrv @sharon-fdm +/.github/workflows/tfvalidate.yml @rfairburn @lukeheath @georgekarrv @sharon-fdm +/.github/workflows/dogfood-deploy.yml @rfairburn @lukeheath @georgekarrv @sharon-fdm +/.github/workflows/test-db-changes.yml @roperzh @lukeheath @georgekarrv @sharon-fdm +/.github/workflows/test-go.yaml @roperzh @lukeheath @georgekarrv @sharon-fdm +/.github/workflows/golangci-lint.yml @roperzh @lukeheath @georgekarrv @sharon-fdm +/.github/workflows/test-native-tooling-packaging.yml @roperzh @lukeheath @georgekarrv @sharon-fdm +/.github/workflows/check-tuf-timestamps.yml @roperzh @lukeheath @georgekarrv @sharon-fdm +/.github/workflows/test-puppet.yml @roperzh @lukeheath @georgekarrv @sharon-fdm +/.github/workflows/generate-nudge-targets.yml @roperzh @lukeheath @georgekarrv @sharon-fdm +/.github/workflows/test-js.yml @ghernandez345 @lukeheath @georgekarrv @sharon-fdm +/.github/workflows/dogfood-gitops.yml @getvictor @lukeheath @georgekarrv @sharon-fdm +/.github/workflows/test-fleetd-chrome.yml @getvictor @lukeheath @georgekarrv @sharon-fdm +/.github/workflows/release-fleetd-chrome.yml @getvictor @lukeheath @georgekarrv @sharon-fdm +/.github/workflows/release-fleetd-chrome-beta.yml @getvictor @lukeheath @georgekarrv @sharon-fdm + # ℹ️ But wait, there's more! # See the comments up top to learn where else DRIs and maintainers are configured. diff --git a/changes/15565-windows-automatic-enrollment b/changes/15565-windows-automatic-enrollment new file mode 100644 index 0000000000..a89e709468 --- /dev/null +++ b/changes/15565-windows-automatic-enrollment @@ -0,0 +1 @@ +- Fix a bug where all Windows MDM enrollments were detected as automatic diff --git a/changes/17208-hover-states b/changes/17208-hover-states new file mode 100644 index 0000000000..5ae0c7f17a --- /dev/null +++ b/changes/17208-hover-states @@ -0,0 +1 @@ +Fleet UI: Add hover states to clickable elements diff --git a/changes/17662-render-standard-query-platforms-correctly b/changes/17662-render-standard-query-platforms-correctly new file mode 100644 index 0000000000..c625264580 --- /dev/null +++ b/changes/17662-render-standard-query-platforms-correctly @@ -0,0 +1 @@ +- Fixes UI bug to render the query platform correctly for queries imported from the standard query library diff --git a/cmd/osquery-perf/agent.go b/cmd/osquery-perf/agent.go index 719b59b23c..756f6f0cd5 100644 --- a/cmd/osquery-perf/agent.go +++ b/cmd/osquery-perf/agent.go @@ -1514,12 +1514,12 @@ func (a *agent) mdmWindows() []map[string]string { if !a.mdmEnrolled() { return []map[string]string{ // empty service url means not enrolled - {"is_federated": "0", "discovery_service_url": "", "provider_id": "", "installation_type": "Client"}, + {"aad_resource_id": "", "discovery_service_url": "", "provider_id": "", "installation_type": "Client"}, } } return []map[string]string{ { - "is_federated": "0", + "aad_resource_id": "", "discovery_service_url": a.serverAddress, "provider_id": fleet.WellKnownMDMFleet, "installation_type": "Client", diff --git a/docs/01-Using-Fleet/standard-query-library/standard-query-library.yml b/docs/01-Using-Fleet/standard-query-library/standard-query-library.yml index f5fb4ee816..4e451247b6 100644 --- a/docs/01-Using-Fleet/standard-query-library/standard-query-library.yml +++ b/docs/01-Using-Fleet/standard-query-library/standard-query-library.yml @@ -880,7 +880,7 @@ apiVersion: v1 kind: policy spec: name: No 1Password emergency kit stored on desktop or in downloads (macOS) - query: SELECT 1 FROM file WHERE filename LIKE '%Emergency Kit%.pdf' AND (path LIKE '/Users/%%/Desktop/%%' OR path LIKE '/Users/%%/Documents/%%' OR path LIKE '/Users/%%/Downloads/%%' OR path LIKE '/Users/Shared'); + query: SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM file WHERE filename LIKE '%Emergency Kit%.pdf' AND (path LIKE '/Users/%%/Desktop/%%' OR path LIKE '/Users/%%/Documents/%%' OR path LIKE '/Users/%%/Downloads/%%' OR path LIKE '/Users/Shared')); description: "Looks for PDF files with file names typically used by 1Password for emergency recovery kits." resolution: "Delete 1Password emergency kits from your computer, and empty the trash. 1Password emergency kits should only be printed and stored in a physically secure location." platform: darwin diff --git a/docs/Contributing/windows-mdm-glossary-and-protocol.md b/docs/Contributing/windows-mdm-glossary-and-protocol.md index 03d5283a48..94dc6095db 100644 --- a/docs/Contributing/windows-mdm-glossary-and-protocol.md +++ b/docs/Contributing/windows-mdm-glossary-and-protocol.md @@ -57,6 +57,88 @@ The certificate created through the WSTEP process is used to authenticate mTLS b https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-mdm/33769a92-ac31-47ef-ae7b-dc8501f7104f +## MDM Device Registration Summary + +https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-dvrd/296ebf70-bd4b-489e-a531-460d8ef7519b + +# Registry + +- `HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Enrollments\` + Each enrollment gets its own subdirectory with a UUID as a key, + inside each directory is a set of keys associated with that enrollment + - `CurCryptoProvider` + Often `Microsoft Software Key Storage Provider` + Cryptographic Key storage provider + - `CurKeyContainer` + Key within key provider + - `DiscoveryServiceFullURL` + MDM Discovery service URL + - `DMPCertThumbPrint` + According to [this blog post](https://call4cloud.nl/2022/10/fullmetal-certificate-the-revenge-of-renewal/), this is the thumbprint of your MDM device certificate + - `EnrollmentFlags` + See [this link](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-xcep/cd22d3a0-f469-4a44-95ed-d10ce4dc2063) for details + + | Integer value | Meaning | + |---------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| + | 0x00000001 | Instructs the client and CA to include an S/MIME extension, as specified in [RFC4262]. | + | 0x00000008 | Instructs the CA to append the issued certificate to the userCertificate attribute, on the user object in Active Directory. | + | 0x00000010 | Instructs the CA to check the user's userCertificate attribute in Active Directory, as specified in [RFC4523], for valid certificates that match the template enrolled for. | + | 0x00000040 | This flag instructs clients to sign the renewal request using the private key of the existing certificate. For more information, see [MS-WCCE] section 3.2.2.6.2.1.4.5.6. This flag also instructs the CA to process the renewal requests as specified in [MS-WCCE] section 3.2.2.6.2.1.4.5.6. | + | 0x00000100 | Instructs the client to get a user's consent before attempting to enroll for a certificate based on the specified template. | + | 0x00000400 | Instructs the client to delete any expired, revoked, or renewed certificate from the user's certificate stores. | + | 0x00002000 | This flag instructs the client to reuse the private key for a smart card–based certificate renewal if it is unable to create a new private key on the card. | + - `EnrollmentState` + The best documentation we can find is [here](https://learn.microsoft.com/en-us/graph/api/resources/intune-shared-enrollmentstate?view=graph-rest-beta) + + | Member | Value | Description | + |--------------|-------|--------------------------------------------------------------------------------------------------------------------| + | unknown | 0 | Device enrollment state is unknown | + | enrolled | 1 | Device is Enrolled. | + | pendingReset | 2 | Enrolled but it's enrolled via enrollment profile and the enrolled profile is different from the assigned profile. | + | failed | 3 | Not enrolled and there is enrollment failure record. | + | notContacted | 4 | Device is imported but not enrolled. | + | blocked | 5 | Device is enrolled as userless, but is blocked from moving to user enrollment because the app failed to install. | + + - `EnrollmentType` + According to [this PDF](https://winprotocoldoc.blob.core.windows.net/productionwindowsarchives/MS-MDE2/%5BMS-MDE2%5D.pdf) it can have three different values. + + Device, Full, and AppManaged + + From what I've seen, value 6 on AAD, 1 on manual + - `isFederated` + According to [this web page](https://learn.microsoft.com/en-us/windows/client-management/federated-authentication-device-enrollment), being federated means that the MDM + endpoints and details were fetched from a Discovery endpoint, + instead of being manually installed. The page does not make mention + of the specific registry key, but we are making an assumption that + it means the same thing. + - `ProviderID` + Set during enrollment. In our case it's the word "Fleet". + - `RenewalPeriod` + Set during enrollment. Period to renew WSTEP certificate. + - `RenewErrorCode` + Presumably set if there is an error renewing WSTEP certificate. + - `RenewROBOSupport` + According to [this post](https://call4cloud.nl/2022/10/fullmetal-certificate-the-revenge-of-renewal/) this means "Request On Behalf Of". + It seems to have to do with automatic certificate renewal + - `RenewStatus` + Status of the renewal + - `RenewTimestamp` + Presumably the timestamp of the last renewal + - `RootCertThumbPrint` + The thumbprint of the WSTEP root certificate + - `SID` + Security Identifier + - `UPN` + User Principal Name of the user that enrolled the device + - `AADResourceID` + Appears to be the domain of the server managing the enrollment, + always appears to be present on machines enrolled through Microsoft + Entra (Azure Active Directory) + - `AADTenantID` + Also related to Azure Active Directory, and also appears to be + present at the same time as AADResourceID. +- `HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Provisioning\Diagnostics\AutoPilot` + Autopilot provisioning diagnostic data - \ No newline at end of file + diff --git a/docs/Deploy/Deploy-Fleet-on-Kubernetes.md b/docs/Deploy/Deploy-Fleet-on-Kubernetes.md index c8a6204ec0..c5318ccb22 100644 --- a/docs/Deploy/Deploy-Fleet-on-Kubernetes.md +++ b/docs/Deploy/Deploy-Fleet-on-Kubernetes.md @@ -8,7 +8,7 @@ There are 2 primary ways to deploy the Fleet server to a Kubernetes cluster. The We will assume you have `kubectl` and MySQL and Redis are all set up and running. Optionally you have minikube to test your deployment locally on your machine. -To deploy the Fleet server and connect to its dependencies (MySQL and Redis), we will use [Fleet's best practice `fleet-deployment.yml` file](https://github.com/fleetdm/fleet/blob/main/docs/Deploy/kubernetes/fleet-deployment.yml). +To deploy the Fleet server and connect to its dependencies (MySQL and Redis), we will use [Fleet's best practice `fleet-deployment.yml` file](https://github.com/fleetdm/fleet/blob/main/docs/Deploy/_kubernetes/fleet-deployment.yml). Let's tell Kubernetes to create the cluster by running the below command. @@ -57,14 +57,14 @@ Helm v2 ```sh helm install \ --name fleet-database \ - --set mysqlUser=fleet,mysqlDatabase=fleet \ + --set auth.username=fleet,auth.database=fleet \ oci://registry-1.docker.io/bitnamicharts/mysql ``` Helm v3 ```sh helm install fleet-database \ - --set mysqlUser=fleet,mysqlDatabase=fleet \ + --set auth.username=fleet,auth.database=fleet \ oci://registry-1.docker.io/bitnamicharts/mysql ``` @@ -83,14 +83,14 @@ Note: this step is not neccessary when using the Fleet Helm Chart as it handles The last step is to run the Fleet database migrations on your new MySQL server. To do this, run the following: ```sh -kubectl create -f ./docs/Deploy/kubernetes/fleet-migrations.yml +kubectl create -f ./docs/Deploy/_kubernetes/fleet-migrations.yml ``` In Kubernetes, you can only run a job once. If you'd like to run it again (i.e.: you'd like to run the migrations again using the same file), you must delete the job before re-creating it. To delete the job and re-run it, you can run the following commands: ```sh -kubectl delete -f ./docs/Deploy/kubernetes/fleet-migrations.yml -kubectl create -f ./docs/Deploy/kubernetes/fleet-migrations.yml +kubectl delete -f ./docs/Deploy/_kubernetes/fleet-migrations.yml +kubectl create -f ./docs/Deploy/_kubernetes/fleet-migrations.yml ``` #### Redis @@ -158,7 +158,7 @@ kubectl create secret tls fleet-tls --key=./tls.key --cert=./tls.crt First we must deploy the instances of the Fleet webserver. The Fleet webserver is described using a Kubernetes deployment object. To create this deployment, run the following: ```sh -kubectl apply -f ./docs/Deploy/fleet-deployment.yml +kubectl apply -f ./docs/Deploy/_kubernetes/fleet-deployment.yml ``` You should be able to get an instance of the webserver running via `kubectl get pods` and you should see the following logs: @@ -174,7 +174,7 @@ ts=2017-11-16T02:48:38.441148166Z transport=https address=0.0.0.0:443 msg=listen Now that the Fleet server is running on our cluster, we have to expose the Fleet webservers to the internet via a load balancer. To create a Kubernetes `Service` of type `LoadBalancer`, run the following: ```sh -kubectl apply -f ./docs/Deploy/fleet-service.yml +kubectl apply -f ./docs/Deploy/_kubernetes/fleet-service.yml ``` #### Configure DNS diff --git a/docs/Deploy/kubernetes/README.md b/docs/Deploy/_kubernetes/README.md similarity index 100% rename from docs/Deploy/kubernetes/README.md rename to docs/Deploy/_kubernetes/README.md diff --git a/docs/Deploy/kubernetes/fleet-deployment.yml b/docs/Deploy/_kubernetes/fleet-deployment.yml similarity index 100% rename from docs/Deploy/kubernetes/fleet-deployment.yml rename to docs/Deploy/_kubernetes/fleet-deployment.yml diff --git a/docs/Deploy/kubernetes/fleet-migrations.yml b/docs/Deploy/_kubernetes/fleet-migrations.yml similarity index 100% rename from docs/Deploy/kubernetes/fleet-migrations.yml rename to docs/Deploy/_kubernetes/fleet-migrations.yml diff --git a/docs/Deploy/kubernetes/fleet-service.yml b/docs/Deploy/_kubernetes/fleet-service.yml similarity index 100% rename from docs/Deploy/kubernetes/fleet-service.yml rename to docs/Deploy/_kubernetes/fleet-service.yml diff --git a/docs/REST API/rest-api.md b/docs/REST API/rest-api.md index 95d055eef7..671831ccb5 100644 --- a/docs/REST API/rest-api.md +++ b/docs/REST API/rest-api.md @@ -2030,9 +2030,10 @@ If `after` is being used with `created_at` or `updated_at`, the table must be sp }, "mdm": { "encryption_key_available": false, - "enrollment_status": null, - "name": "", - "server_url": null + "enrollment_status": "Pending", + "dep_profile_error": true, + "name": "Fleet", + "server_url": "https://example.fleetdm.com/mdm/apple/mdm" }, "software": [ { @@ -3717,13 +3718,10 @@ created_at,updated_at,id,detail_updated_at,label_updated_at,policy_updated_at,la ### Get host's disk encryption key -For macOS, requires the [macadmins osquery extension](https://github.com/macadmins/osquery-extension) which comes bundled -in [Fleet's osquery installers](https://fleetdm.com/docs/using-fleet/adding-hosts#osquery-installer). - -Requires Fleet's MDM properly [enabled and configured](https://fleetdm.com/docs/using-fleet/mdm-macos-setup). - Retrieves the disk encryption key for a host. +Requires that disk encryption is enforced and the host has MDM turned on. + `GET /api/v1/fleet/mdm/hosts/:id/encryption_key` #### Parameters @@ -3877,19 +3875,19 @@ To wipe a macOS or Windows host, the host must have MDM turned on. To lock a Lin ### Get host's past activity -`GET /api/v1/fleet/hosts/:id/activites/past` +`GET /api/v1/fleet/hosts/:id/activities` #### Parameters | Name | Type | In | Description | | ---- | ------- | ---- | ---------------------------- | -| id | integer | path | **Required**. The host's id. | +| id | integer | path | **Required**. The host's ID. | | page | integer | query | Page number of the results to fetch.| | per_page | integer | query | Results per page.| #### Example -`GET /api/v1/fleet/hosts/12/activities/past` +`GET /api/v1/fleet/hosts/12/activities` ##### Default response @@ -7461,8 +7459,11 @@ Run a live script and get results back (5 minute timeout). Live scripts only run | Name | Type | In | Description | | ---- | ------- | ---- | -------------------------------------------- | | host_id | integer | body | **Required**. The host id to run the script on. | -| script_id | integer | body | The ID of the existing saved script to run. Only one of either `script_id` or `script_contents` can be included in the request; omit this parameter if using `script_contents`. | -| script_contents | string | body | The contents of the script to run. Only one of either `script_id` or `script_contents` can be included in the request; omit this parameter if using `script_id`. | +| script_id | integer | body | The ID of the existing saved script to run. Only one of either `script_id`, `script_name` or `script_contents` can be included in the request; omit this parameter if using `script_contents` or `script_name`. | +| script_contents | string | body | The contents of the script to run. Only one of either `script_contents`, `script_id` or `script_name` can be included in the request; omit this parameter if using `script_id` or `script_name`. | +| script_name | string | body | The name of the existing saved script to run. Only one of either `script_name`, `script_id` or `script_contents` can be included in the request; omit this parameter if using `script_contents` or `script_id`. | +| team_id | integer | body | ID of the team the saved script referenced by `script_name` belongs to. Default: `0` (hosts assigned to "No team") | + > Note that if both `script_id` and `script_contents` are included in the request, this endpoint will respond with an error. diff --git a/docs/Using Fleet/CIS-Benchmarks.md b/docs/Using Fleet/CIS-Benchmarks.md index bf12e3ba44..1bcbb2e1fc 100644 --- a/docs/Using Fleet/CIS-Benchmarks.md +++ b/docs/Using Fleet/CIS-Benchmarks.md @@ -1,19 +1,21 @@ # CIS Benchmarks -> Available in Fleet Premium +_Available in Fleet Premium_. ## Overview + CIS Benchmarks represent the consensus-based effort of cybersecurity experts globally to help you protect your systems against threats more confidently. For more information about CIS Benchmarks check out [Center for Internet Security](https://www.cisecurity.org/cis-benchmarks)'s website. Fleet has implemented native support for CIS Benchmarks for the following platforms: -- macOS 13.0 Ventura (96 checks) -- Windows 10 Enterprise (496 checks) -- Windows 11 Enterprise (521 checks) +- macOS 13.0 Ventura +- macOS 14.0 Sonoma +- Windows 10 Enterprise +- Windows 11 Enterprise [Where possible](#limitations), each CIS Benchmark is implemented with a [policy query](./REST-API.md#policies) in Fleet. -These benchmarks are intended to gauge your organization's security posture, rather than the current state of a given host. A host may fail a CIS Benchmark policy despite having the correct settings enabled if there is not a specific policy in place to enforce that setting. For example, this is the query for **CIS - Ensure FileVault Is Enabled (MDM Required)**: +These benchmarks are intended to gauge your organization's security posture, rather than the current state of a given host. A host may fail a CIS Benchmark policy despite having the correct settings enabled if there is no configuration profile or Group Policy Object (GPO) in place to enforce the setting. For example, this is the query for **CIS - Ensure FileVault Is Enabled (MDM Required)**: ```sql SELECT 1 WHERE @@ -88,14 +90,13 @@ fleetctl apply --policies-team "Workstations" -f cis-policy-queries.yml ``` ## Limitations -Fleet's current set of benchmarks only implements benchmark *auditing* steps that can be *automated*. -In practice, Fleet is able to cover a large majority of benchmarks: -* macOS 13 Ventura - 96 of 104 -* Windows 10 Enterprise - All CIS items (496) -* Windows 11 Enterprise - All CIS items (521) +Certain benchmarks require human action to audit, and cannot be automated by a policy in Fleet. For a list of specific benchmarks which are not covered, please visit the README for each benchmark: -For a list of specific checks which are not covered by Fleet, please visit the section devoted to each benchmark. +- [macOS 13.0 Ventura](https://github.com/fleetdm/fleet/blob/main/ee/cis/macos-13/README.md) +- [macOS 14.0 Sonoma](https://github.com/fleetdm/fleet/blob/main/ee/cis/macos-14/README.md) +- [Windows 10 Enterprise](https://github.com/fleetdm/fleet/blob/main/ee/cis/win-10/README.md) +- [Windows 11 Enterprise](https://github.com/fleetdm/fleet/blob/main/ee/cis/win-11/README.md) ### Audit vs. remediation Each benchmark has two elements: @@ -106,18 +107,6 @@ Since Fleetd is currently read-only without the ability to execute actions on th To implement automated remediation, you can install a separate agent such as Munki, Chef, Puppet, etc. which has write functionality. -### Manual vs. automated - -For both the audit and remediation elements of a CIS Benchmark, there are two types: -1. Automated - the element can be audited or remediated without human intervention -2. Manual - the element requires human intervention to be audited or remediated - -Fleet only implements automated audit checks. Manual checks require administrators to implement other processes to conduct the check. - -* macOS 13 Ventura - 96 of 104 are automated -* Windows 10 Enterprise - All CIS items (496) are automated -* Windows 11 Enterprise - All CIS items (521) are automated - ## Levels 1 and 2 CIS designates various benchmarks as Level 1 or Level 2 to describe the level of thoroughness and burden that each benchmark represents. @@ -137,50 +126,6 @@ This profile extends the "Level 1" profile. Items in this profile exhibit one or - are intended for environments or use cases where security is paramount or acts as defense in depth measure - may negatively inhibit the utility or performance of the technology. -## macOS 13.0 Ventura benchmark - -Fleet's policies have been written against v1.0 of the benchmark. Please refer to the "CIS Apple macOS 13.0 Ventura Benchmark v1.0.0 - 11-14-2022" PDF from the CIS website for full details. - -### Checks that require customer decision - -CIS has left the parameters of the following checks up to the benchmark implementer. CIS recommends that an organization make a conscious decision for these benchmarks, but does not make a specific recommendation. - -Fleet has provided both an "enabled" and "disabled" version of these benchmarks. When both policies are added, at least one will fail. Once your organization has made a decision, you can delete one or the other policy query. -The policy will be appended with a `-enabled` or `-disabled` label, such as `2.1.1.1-enabled`. - -- 2.1.1.1 Audit iCloud Keychain -- 2.1.1.2 Audit iCloud Drive -- 2.5.1 Audit Siri -- 2.8.1 Audit Universal Control - -Furthermore, CIS has decided to not require the following password complexity settings: -- 5.2.3 Ensure Complex Password Must Contain Alphabetic Characters Is Configured -- 5.2.4 Ensure Complex Password Must Contain Numeric Character Is Configured -- 5.2.5 Ensure Complex Password Must Contain Special Character Is Configured -- 5.2.6 Ensure Complex Password Must Contain Uppercase and Lowercase Characters Is Configured - -However, Fleet has provided these as policies. If your organization declines to implement these, simply delete the corresponding policy. - -### macOS 13.0 Ventura manual checks - -The following CIS benchmark checks cannot be automated and must be addressed manually: -- 2.1.2 Audit App Store Password Settings -- 2.3.3.12 Ensure Computer Name Does Not Contain PII or Protected Organizational Information -- 2.6.6 Audit Lockdown Mode -- 2.11.2 Audit Touch ID and Wallet & Apple Pay Settings -- 2.13.1 Audit Passwords System Preference Setting -- 2.14.1 Audit Notification & Focus Settings -- 3.7 Audit Software Inventory -- 6.2.1 Ensure Protect Mail Activity in Mail Is Enabled - -## Windows 10 & 11 Enterprise benchmarks - -Fleet's policies have been written against v2.0.0 of the benchmarks. You can refer to the [CIS website](https://www.cisecurity.org/cis-benchmarks) for full details about this version. - -### Checks that require a Group Policy template - -Several items require Group Policy templates in place in order to audit them. -These items are tagged with the label `CIS_group_policy_template_required` in the YAML file, and details about the required Group Policy templates can be found in each item's `resolution`. ## Performance testing In August 2023, we completed scale testing on 10k Windows hosts and 70k macOS hosts. Ultimately, we validated both server and host performance at that scale. diff --git a/docs/Using Fleet/Scripts.md b/docs/Using Fleet/Scripts.md index 5ed888688b..64b9957fff 100644 --- a/docs/Using Fleet/Scripts.md +++ b/docs/Using Fleet/Scripts.md @@ -30,7 +30,11 @@ Fleet UI: 2. Head to the **Hosts** page and select the host you want to run the script on. -3. On your target host's host details page, select the **Scripts** tab and select **Actions** to run the script. +3. On your target host's host details page, select the **Actions** dropdown and select **Run Script** to view the **Run Script** menu. + +4. In the **Run Script** menu, select the **Actions** dropdown for the script you'd like to execute and choose the **Run** option. + +Scripts run from the Fleet UI will run the next time your host checks in with Fleet. You can view the status of the script execution as well as the output in the target host's activity feed. Fleet API: API documentation is [here](https://fleetdm.com/docs/rest-api/rest-api#run-script) diff --git a/docs/Using Fleet/Understanding-host-vitals.md b/docs/Using Fleet/Understanding-host-vitals.md index 10cc3f8548..47dca9f92c 100644 --- a/docs/Using Fleet/Understanding-host-vitals.md +++ b/docs/Using Fleet/Understanding-host-vitals.md @@ -176,10 +176,10 @@ WITH registry_keys AS ( enrollment_info AS ( SELECT MAX(CASE WHEN name = 'UPN' THEN data END) AS upn, - MAX(CASE WHEN name = 'IsFederated' THEN data END) AS is_federated, MAX(CASE WHEN name = 'DiscoveryServiceFullURL' THEN data END) AS discovery_service_url, MAX(CASE WHEN name = 'ProviderID' THEN data END) AS provider_id, - MAX(CASE WHEN name = 'EnrollmentState' THEN data END) AS state + MAX(CASE WHEN name = 'EnrollmentState' THEN data END) AS state, + MAX(CASE WHEN name = 'AADResourceID' THEN data END) AS aad_resource_id FROM registry_keys GROUP BY key ), @@ -190,7 +190,7 @@ WITH registry_keys AS ( LIMIT 1 ) SELECT - e.is_federated, + e.aad_resource_id, e.discovery_service_url, e.provider_id, i.installation_type @@ -374,7 +374,7 @@ SELECT * FROM os_version LIMIT 1 - Query: ```sql SELECT os.name, r.data as display_version, k.version - FROM + FROM registry r, os_version os, kernel_info k diff --git a/docs/Using Fleet/manage-access.md b/docs/Using Fleet/manage-access.md index c073b1a6f9..802c7c36f5 100644 --- a/docs/Using Fleet/manage-access.md +++ b/docs/Using Fleet/manage-access.md @@ -37,6 +37,7 @@ GitOps is an API-only and write-only role that can be used on CI/CD pipelines. | ------------------------------------------------------------------------------------------------------------------------------------------ | -------- | ---------- | ---------- | ----- | ------- | | View all [activity](https://fleetdm.com/docs/using-fleet/rest-api#activities) | ✅ | ✅ | ✅ | ✅ | | | View all hosts | ✅ | ✅ | ✅ | ✅ | | +| View a host by identifier | ✅ | ✅ | ✅ | ✅ | ✅ | | Filter hosts using [labels](https://fleetdm.com/docs/using-fleet/rest-api#labels) | ✅ | ✅ | ✅ | ✅ | | | Target hosts using labels | ✅ | ✅ | ✅ | ✅ | | | Add and delete hosts | | | ✅ | ✅ | | @@ -83,6 +84,7 @@ GitOps is an API-only and write-only role that can be used on CI/CD pipelines. | View results of MDM commands executed on macOS and Windows hosts\** | ✅ | ✅ | ✅ | ✅ | | | Edit [MDM settings](https://fleetdm.com/docs/using-fleet/mdm-macos-settings) | | | | ✅ | ✅ | | Edit [MDM settings for teams](https://fleetdm.com/docs/using-fleet/mdm-macos-settings) | | | | ✅ | ✅ | +| View all [MDM settings](https://fleetdm.com/docs/using-fleet/mdm-macos-settings) | | | | ✅ | ✅ | | Upload an EULA file for MDM automatic enrollment\* | | | | ✅ | | | View/download MDM macOS setup assistant\* | | | ✅ | ✅ | | | Edit/upload MDM macOS setup assistant\* | | | ✅ | ✅ | ✅ | @@ -119,6 +121,7 @@ Users with access to multiple teams can be assigned different roles for each tea | **Action** | Team observer | Team observer+ | Team maintainer | Team admin | Team GitOps | | -------------------------------------------------------------------------------------------------------------------------------- | ------------- | -------------- | --------------- | ---------- | ----------- | | View hosts | ✅ | ✅ | ✅ | ✅ | | +| View a host by identifier | ✅ | ✅ | ✅ | ✅ | ✅ | | Filter hosts using [labels](https://fleetdm.com/docs/using-fleet/rest-api#labels) | ✅ | ✅ | ✅ | ✅ | | | Target hosts using labels | ✅ | ✅ | ✅ | ✅ | | | Add and delete hosts | | | ✅ | ✅ | | diff --git a/ee/cis/macos-13/README.md b/ee/cis/macos-13/README.md new file mode 100644 index 0000000000..e49628ac6e --- /dev/null +++ b/ee/cis/macos-13/README.md @@ -0,0 +1,37 @@ +# macOS 13.0 Ventura benchmark + +Fleet's policies have been written against v1.0 of the benchmark. You can refer to the [CIS website](https://www.cisecurity.org/cis-benchmarks) for full details about this version. + +For requirements and usage details, see the [CIS Benchmarks](https://fleetdm.com/docs/using-fleet/cis-benchmarks) documentation. + +### Limitations + +The following CIS benchmarks cannot be checked with a policy in Fleet: +1. 2.1.2 Audit App Store Password Settings +2. 2.3.3.12 Ensure Computer Name Does Not Contain PII or Protected Organizational Information +3. 2.6.6 Audit Lockdown Mode +4. 2.11.2 Audit Touch ID and Wallet & Apple Pay Settings +5. 2.13.1 Audit Passwords System Preference Setting +6. 2.14.1 Audit Notification & Focus Settings +7. 3.7 Audit Software Inventory +8. 6.2.1 Ensure Protect Mail Activity in Mail Is Enabled + +### Checks that require decision + +CIS has left the parameters of the following checks up to the benchmark implementer. CIS recommends that an organization make a conscious decision for these benchmarks, but does not make a specific recommendation. + +Fleet has provided both an "enabled" and "disabled" version of these benchmarks. When both policies are added, at least one will fail. Once your organization has made a decision, you can delete one or the other policy query. +The policy will be appended with a `-enabled` or `-disabled` label, such as `2.1.1.1-enabled`. + +- 2.1.1.1 Audit iCloud Keychain +- 2.1.1.2 Audit iCloud Drive +- 2.5.1 Audit Siri +- 2.8.1 Audit Universal Control + +Furthermore, CIS has decided to not require the following password complexity settings: +- 5.2.3 Ensure Complex Password Must Contain Alphabetic Characters Is Configured +- 5.2.4 Ensure Complex Password Must Contain Numeric Character Is Configured +- 5.2.5 Ensure Complex Password Must Contain Special Character Is Configured +- 5.2.6 Ensure Complex Password Must Contain Uppercase and Lowercase Characters Is Configured + +However, Fleet has provided these as policies. If your organization declines to implement these, simply delete the corresponding policies. \ No newline at end of file diff --git a/ee/cis/macos-14/README.md b/ee/cis/macos-14/README.md new file mode 100644 index 0000000000..a83cd38d4a --- /dev/null +++ b/ee/cis/macos-14/README.md @@ -0,0 +1,37 @@ +# macOS 14.0 Sonoma benchmark + +Fleet's policies have been written against v1.0 of the benchmark. You can refer to the [CIS website](https://www.cisecurity.org/cis-benchmarks) for full details about this version. + +For requirements and usage details, see the [CIS Benchmarks](https://fleetdm.com/docs/using-fleet/cis-benchmarks) documentation. + +### Limitations + +The following CIS benchmarks cannot be checked with a policy in Fleet: +1. 2.1.2 Audit App Store Password Settings +2. 2.3.3.12 Ensure Computer Name Does Not Contain PII or Protected Organizational Information +3. 2.6.6 Audit Lockdown Mode +4. 2.11.2 Audit Touch ID and Wallet & Apple Pay Settings +5. 2.13.1 Audit Passwords System Preference Setting +6. 2.14.1 Audit Notification & Focus Settings +7. 3.7 Audit Software Inventory +8. 6.2.1 Ensure Protect Mail Activity in Mail Is Enabled + +### Checks that require decision + +CIS has left the parameters of the following checks up to the benchmark implementer. CIS recommends that an organization make a conscious decision for these benchmarks, but does not make a specific recommendation. + +Fleet has provided both an "enabled" and "disabled" version of these benchmarks. When both policies are added, at least one will fail. Once your organization has made a decision, you can delete one or the other policy query. +The policy will be appended with a `-enabled` or `-disabled` label, such as `2.1.1.1-enabled`. + +- 2.1.1.1 Audit iCloud Keychain +- 2.1.1.2 Audit iCloud Drive +- 2.5.1 Audit Siri +- 2.8.1 Audit Universal Control + +Furthermore, CIS has decided to not require the following password complexity settings: +- 5.2.3 Ensure Complex Password Must Contain Alphabetic Characters Is Configured +- 5.2.4 Ensure Complex Password Must Contain Numeric Character Is Configured +- 5.2.5 Ensure Complex Password Must Contain Special Character Is Configured +- 5.2.6 Ensure Complex Password Must Contain Uppercase and Lowercase Characters Is Configured + +However, Fleet has provided these as policies. If your organization declines to implement these, simply delete the corresponding policies. \ No newline at end of file diff --git a/ee/cis/win-10/README.md b/ee/cis/win-10/README.md new file mode 100644 index 0000000000..880dd1445b --- /dev/null +++ b/ee/cis/win-10/README.md @@ -0,0 +1,15 @@ +# Windows 10 Enterprise benchmarks + +Fleet's policies have been written against v2.0.0 of the benchmark. You can refer to the [CIS website](https://www.cisecurity.org/cis-benchmarks) for full details about this version. + +For requirements and usage details, see the [CIS Benchmarks](https://fleetdm.com/docs/using-fleet/cis-benchmarks) documentation. + +### Limitations + +> None. All items in this version of the benchmark are able to be automated. + + +### Checks that require a Group Policy template + +Several items require Group Policy templates in place in order to audit them. +These items are tagged with the label `CIS_group_policy_template_required` in the YAML file, and details about the required Group Policy templates can be found in each item's `resolution`. \ No newline at end of file diff --git a/ee/cis/win-11/README.md b/ee/cis/win-11/README.md new file mode 100644 index 0000000000..428a365217 --- /dev/null +++ b/ee/cis/win-11/README.md @@ -0,0 +1,15 @@ +# Windows 11 Enterprise benchmarks + +Fleet's policies have been written against v2.0.0 of the benchmark. You can refer to the [CIS website](https://www.cisecurity.org/cis-benchmarks) for full details about this version. + +For requirements and usage details, see the [CIS Benchmarks](https://fleetdm.com/docs/using-fleet/cis-benchmarks) documentation. + +### Limitations + +> None. All items in this version of the benchmark are able to be automated. + + +### Checks that require a Group Policy template + +Several items require Group Policy templates in place in order to audit them. +These items are tagged with the label `CIS_group_policy_template_required` in the YAML file, and details about the required Group Policy templates can be found in each item's `resolution`. \ No newline at end of file diff --git a/ee/vulnerability-dashboard/.dockerignore b/ee/vulnerability-dashboard/.dockerignore new file mode 100644 index 0000000000..9303c347ee --- /dev/null +++ b/ee/vulnerability-dashboard/.dockerignore @@ -0,0 +1,2 @@ +node_modules/ +npm-debug.log \ No newline at end of file diff --git a/ee/vulnerability-dashboard/Dockerfile b/ee/vulnerability-dashboard/Dockerfile new file mode 100644 index 0000000000..0d96a8a8ff --- /dev/null +++ b/ee/vulnerability-dashboard/Dockerfile @@ -0,0 +1,35 @@ +# Use the official Node.js 14 image as a base +FROM node:20@sha256:e06aae17c40c7a6b5296ca6f942a02e6737ae61bbbf3e2158624bb0f887991b5 + +# Set the working directory in the container +WORKDIR /usr/src/app + +# Copy the package.json +COPY package.json ./ + +# Install vulnerability dashboard dependencies +RUN npm install + +# Copy the vulnerability dashboard into the container +COPY . . + +# Install cron on the Docker image +RUN apt-get update && apt-get install -y cron + +# Add the crontab file for the update reports script to the cron directory +ADD crontab /etc/cron.d/update-reports-cron + +# Give execution rights on the cron job and apply it +RUN chmod 0644 /etc/cron.d/update-reports-cron && crontab /etc/cron.d/update-reports-cron + +# Copy the entrypoint script into the container +COPY entrypoint.sh /usr/src/app/entrypoint.sh + +# Make sure the entrypoint script is executable +RUN chmod +x /usr/src/app/entrypoint.sh + +# Expose the port the vulnerability dashboard runs on +EXPOSE 1337 + +# Set the entrypoint script as the entry point +ENTRYPOINT ["/usr/src/app/entrypoint.sh"] diff --git a/ee/vulnerability-dashboard/README.md b/ee/vulnerability-dashboard/README.md index 82c068793e..e6e6988188 100644 --- a/ee/vulnerability-dashboard/README.md +++ b/ee/vulnerability-dashboard/README.md @@ -26,6 +26,32 @@ f.k.a. "scooper" Original raw notes and context: (private google doc since it contains competitor information: https://docs.google.com/document/d/1ByNWY6n_C-rvL75lI6jca2OniHt5FqA5_nYMf61S0pM/edit#) +## Running the vulnerability dashboard with Docker. + +To run a local vulnerability dashboard with docker, you can follow these instructions. + +1. Clone this repo +2. Update the following ENV variables `ee/vulnerability-dashboard/docker-compose.yml` file: + + 1. `sails_custom__fleetBaseUrl`: The full URL of your Fleet instance. (e.g., https://fleet.example.com) + + 2. `sails_custom__fleetApiToken`: AN API token for an API-only user on your Fleet instance. + + >You can read about how to create an API-only user and get it's token [here](https://fleetdm.com/docs/using-fleet/fleetctl-cli#create-api-only-user) + +3. Open the `ee/vulnerability-dashboard/` folder in your terminal +4. Run `docker compose up --build` to build the vulnerability dashboard's Docker image. + + > The first time the vulnerability dashboard starts it will Initalize the database and run the `update-reports` script before the server starts. + +5. Once the container is done building, the vulnerability dashboard will be available at http://localhost:1337 + + > You can login with the default admin login: + > + >- Email address: `admin@example.com` + > + >- Password: `abc123` + ## How it's made This is a [Sails v1](https://sailsjs.com) application: @@ -35,4 +61,3 @@ This is a [Sails v1](https://sailsjs.com) application: + [Community support options](https://sailsjs.com/support) + **Version info**: This app was originally generated on Sat Dec 10 2022 15:56:06 GMT-0600 (Central Standard Time) using Sails v1.5.3. + This project's boilerplate is based on an expanded seed app provided by the [Sails core team](https://sailsjs.com/about) to make it easier for you to build on top of ready-made features like authentication, enrollment, email verification, and billing. - diff --git a/ee/vulnerability-dashboard/api/hooks/OktaSSO/index.js b/ee/vulnerability-dashboard/api/hooks/okta-sso/index.js similarity index 96% rename from ee/vulnerability-dashboard/api/hooks/OktaSSO/index.js rename to ee/vulnerability-dashboard/api/hooks/okta-sso/index.js index d66c67db1e..d50c580c98 100644 --- a/ee/vulnerability-dashboard/api/hooks/OktaSSO/index.js +++ b/ee/vulnerability-dashboard/api/hooks/okta-sso/index.js @@ -35,6 +35,7 @@ module.exports = function (sails){ } // Clone the existing routes + // NOTE: Changing sails.config after the app lifts goes against Sails.js conventions and this code should not be reproduced. let appRoutes = Object.assign({}, sails.config.routes); // Remove the routes for the built-in login page.. delete appRoutes['GET /login']; @@ -45,9 +46,9 @@ module.exports = function (sails){ 'bodyParser', 'compress', 'poweredBy', + 'www',// Note: This changes the conventions of Sails.js. Don't ever replicate this or use Passport.js. 'oktaSSO', 'router', - 'www', 'favicon', ]; // Specify a custom http middleware order, placing the Okta middleware before the router. This is so the routes generated by Okta will take precedence over the sails router. diff --git a/ee/vulnerability-dashboard/crontab b/ee/vulnerability-dashboard/crontab new file mode 100644 index 0000000000..31f359cb44 --- /dev/null +++ b/ee/vulnerability-dashboard/crontab @@ -0,0 +1 @@ +0 * * * * cd /usr/src/app && /usr/local/bin/node ./node_modules/.bin/sails run update-reports >> /usr/src/app/cron.log 2>&1 diff --git a/ee/vulnerability-dashboard/docker-compose.yml b/ee/vulnerability-dashboard/docker-compose.yml new file mode 100644 index 0000000000..a1c92cdaed --- /dev/null +++ b/ee/vulnerability-dashboard/docker-compose.yml @@ -0,0 +1,31 @@ +version: '3' +services: + vuln-dash: + build: . + ports: + - "1337:1337" + depends_on: + - redis + - postgres + environment: + sails_datastores__default__url: postgres://user:password@postgres:5432/dbname + sails_datastores__default__adapter: sails-postgresql + sails_sockets__url: redis://redis:6379 + sails_session__url: redis://redis:6379 + sails_custom__fleetBaseUrl: '' #Add the base url of your Fleet instance: ex: https://fleet.example.com + sails_custom__fleetApiToken: '' # Add the API token of an API-only user [?] Here's how you get one: https://fleetdm.com/docs/using-fleet/fleetctl-cli#get-the-api-token-of-an-api-only-user + + redis: + image: "redis:alpine" + + postgres: + image: "postgres:alpine" + environment: + POSTGRES_USER: user + POSTGRES_PASSWORD: password + POSTGRES_DB: dbname + volumes: + - pgdata:/var/lib/postgresql/data + +volumes: + pgdata: diff --git a/ee/vulnerability-dashboard/entrypoint.sh b/ee/vulnerability-dashboard/entrypoint.sh new file mode 100644 index 0000000000..8d5566eb15 --- /dev/null +++ b/ee/vulnerability-dashboard/entrypoint.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +if [ -z "$sails_custom__fleetBaseUrl" ] && [ -z "$sails_custom__fleetApiToken" ]; then + echo 'ERROR: Missing environment variables. Please set "sails_custom__fleetApiToken" and "sails_custom__fleetBaseUrl" and and try starting this container again' + exit 1 +elif [ -z "$sails_custom__fleetBaseUrl" ]; then + echo 'ERROR: Missing environment variables. Please set "sails_custom__fleetBaseUrl" and try starting this container again' + exit 1 +elif [ -z "$sails_custom__fleetApiToken" ]; then + echo 'ERROR: Missing environment variables. Please set "sails_custom__fleetApiToken" and and try starting this container again' + exit 1 +fi + +# Check if the vulnerability dashboard has been initialized before +if [ ! -f "/usr/src/app/.initialized" ]; then + # if it hasn't, lift the app with in console mode with the --drop flag to create our databsae tables. + echo '.exit' | node ./node_modules/sails/bin/sails console --drop + + touch /usr/src/app/.initialized + # run the `update-reports` script + node ./node_modules/sails/bin/sails run update-reports +fi + +# Expose the container's ENV variables to cron +printenv >> /etc/environment + +# Start cron +cron + +# Start the vulnerability dashboard +exec node app.js diff --git a/ee/vulnerability-dashboard/package.json b/ee/vulnerability-dashboard/package.json index a72ab3d351..f54c10bde6 100644 --- a/ee/vulnerability-dashboard/package.json +++ b/ee/vulnerability-dashboard/package.json @@ -5,7 +5,7 @@ "description": "Report and track progress on fixing and prioritizing thousands of installed CVEs.", "keywords": [], "dependencies": { - "@okta/oidc-middleware": "4.0.1", + "@okta/oidc-middleware": "5.0.0", "@okta/okta-sdk-nodejs": "3.2.0", "@sailshq/connect-redis": "^3.2.1", "@sailshq/lodash": "^3.10.3", @@ -21,7 +21,7 @@ }, "devDependencies": { "eslint": "5.16.0", - "grunt": "1.0.4", + "grunt": "1.5.3", "htmlhint": "0.11.0", "lesshint": "6.3.6", "sails-hook-grunt": "^5.0.0", diff --git a/frontend/components/forms/fields/Checkbox/_styles.scss b/frontend/components/forms/fields/Checkbox/_styles.scss index 1bd81b1e2a..3aa8725df1 100644 --- a/frontend/components/forms/fields/Checkbox/_styles.scss +++ b/frontend/components/forms/fields/Checkbox/_styles.scss @@ -22,6 +22,13 @@ border: solid 2px $core-vibrant-blue; } + &:hover { + &::after { + background-color: $core-vibrant-blue-over; + border: solid 2px $core-vibrant-blue-over; + } + } + &::before { @include position(absolute, 50% null null 50%); transform: rotate(45deg); @@ -42,6 +49,7 @@ @include size(20px); @include position(absolute, 0 null null 0); display: inline-block; + cursor: pointer; &::after { @include size(20px); @@ -54,11 +62,17 @@ background-color: $core-white; visibility: visible; } + &:hover { + &::after { + border: solid 2px $core-vibrant-blue-over; + } + } &--disabled { &::after { background-color: $ui-fleet-black-25; } + cursor: default; } &--indeterminate { @@ -67,6 +81,15 @@ border: solid 1px $core-vibrant-blue; } + &:hover { + &::after { + &::after { + background-color: $core-vibrant-blue-over; + border: solid 1px $core-vibrant-blue-over; + } + } + } + &::before { @include position(absolute, 50% null null 50%); box-sizing: border-box; diff --git a/frontend/components/forms/fields/Dropdown/_styles.scss b/frontend/components/forms/fields/Dropdown/_styles.scss index d955d357f2..5523158b09 100644 --- a/frontend/components/forms/fields/Dropdown/_styles.scss +++ b/frontend/components/forms/fields/Dropdown/_styles.scss @@ -75,6 +75,8 @@ background-color: $ui-light-grey; border: 0; border-radius: $border-radius; + cursor: pointer; + .Select-value { font-size: $small; background-color: $ui-light-grey; diff --git a/frontend/pages/DashboardPage/cards/MDM/MDM.tsx b/frontend/pages/DashboardPage/cards/MDM/MDM.tsx index e102869a4d..2e79bd8749 100644 --- a/frontend/pages/DashboardPage/cards/MDM/MDM.tsx +++ b/frontend/pages/DashboardPage/cards/MDM/MDM.tsx @@ -166,6 +166,7 @@ const Mdm = ({ isAllPagesSelected={false} disableCount disablePagination + disableMultiRowSelect onClickRow={handleSolutionRowClick} /> )} diff --git a/frontend/pages/hosts/ManageHostsPage/components/LabelFilterSelect/_styles.scss b/frontend/pages/hosts/ManageHostsPage/components/LabelFilterSelect/_styles.scss index 0c1ed6fac5..72ab4f59e9 100644 --- a/frontend/pages/hosts/ManageHostsPage/components/LabelFilterSelect/_styles.scss +++ b/frontend/pages/hosts/ManageHostsPage/components/LabelFilterSelect/_styles.scss @@ -26,6 +26,10 @@ border-radius: $border-radius; height: 40px; + :hover { + cursor: pointer; + } + &--is-focused, &--menu-is-open, &:hover { diff --git a/frontend/pages/queries/edit/components/EditQueryForm/EditQueryForm.tsx b/frontend/pages/queries/edit/components/EditQueryForm/EditQueryForm.tsx index e6ac26e7c2..c5b70d70a9 100644 --- a/frontend/pages/queries/edit/components/EditQueryForm/EditQueryForm.tsx +++ b/frontend/pages/queries/edit/components/EditQueryForm/EditQueryForm.tsx @@ -724,7 +724,7 @@ const EditQueryForm = ({ placeholder="Select" label="Platform" onChange={onChangeSelectPlatformOptions} - value={lastEditedQueryPlatforms} + value={lastEditedQueryPlatforms.replace(/\s/g, "")} // NOTE: FE requires no whitespace to render UI multi wrapperClassName={`${baseClass}__form-field form-field--platform`} helpText="By default, your query collects data on all compatible platforms." diff --git a/go.mod b/go.mod index e4e78b47d7..2b89ecb1ce 100644 --- a/go.mod +++ b/go.mod @@ -25,7 +25,7 @@ require ( github.com/davecgh/go-spew v1.1.1 github.com/dgraph-io/badger/v2 v2.2007.2 github.com/digitalocean/go-smbios v0.0.0-20180907143718-390a4f403a8e - github.com/docker/docker v24.0.7+incompatible + github.com/docker/docker v24.0.9+incompatible github.com/docker/go-units v0.4.0 github.com/doug-martin/goqu/v9 v9.18.0 github.com/e-dard/netbug v0.0.0-20151029172837-e64d308a0b20 @@ -312,7 +312,7 @@ require ( google.golang.org/genproto v0.0.0-20231002182017-d307bd883b97 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20231012201019-e917dd12ba7a // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20231012201019-e917dd12ba7a // indirect - google.golang.org/protobuf v1.31.0 // indirect + google.golang.org/protobuf v1.33.0 // indirect gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect gopkg.in/mail.v2 v2.3.1 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect diff --git a/go.sum b/go.sum index 866a29d973..616092fefd 100644 --- a/go.sum +++ b/go.sum @@ -394,8 +394,8 @@ github.com/dimchansky/utfbom v1.1.1 h1:vV6w1AhK4VMnhBno/TPVCoK9U/LP0PkLCS9tbxHdi github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE= github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v24.0.7+incompatible h1:Wo6l37AuwP3JaMnZa226lzVXGA3F9Ig1seQen0cKYlM= -github.com/docker/docker v24.0.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v24.0.9+incompatible h1:HPGzNmwfLZWdxHqK9/II92pyi1EpYKsAqcl4G0Of9v0= +github.com/docker/docker v24.0.9+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= @@ -1855,8 +1855,8 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= -google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= +google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk= gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk= diff --git a/handbook/business-operations/README.md b/handbook/business-operations/README.md index 6bea61ddf0..4c8f16f444 100644 --- a/handbook/business-operations/README.md +++ b/handbook/business-operations/README.md @@ -265,6 +265,13 @@ Within 60 days of the end of the year, follow these steps: - Afterward, post in #random letting folks know that the quarterly tool reconciliation and seat clearing is complete, and that any members who lost access to anything they still need can submit a ZenHub issue to BizOps to have their access restored. - The goal is to build deep, integrated knowledge of tool usage across Fleet and cut costs whenever possible. It will also force conversations on redundancies and decisions that aren't helping the business that otherwise might not be looked at a second time. +### Process a new vendor invoice +- After making sure that an invoice received from a new vendor is valid, add the new vendor to the recurring expenses section of ["The numbers"](https://docs.google.com/spreadsheets/d/1X-brkmUK7_Rgp7aq42drNcUg8ZipzEiS153uKZSabWc/edit#gid=2112277278) before paying the invoice. + +### Process a request to cancel a vendor +- Make the cancellation notification in accordance with the contract terms between Fleet and the vendor, typically these notifications are made via email and may have a specific address that notice must be sent to. If the vendor has an autorenew contract with Fleet there will often be a window of time in which Fleet can cancel, if notification is made after this time period Fleet may be obligated to pay for the subsequent year even if we don't use the vendor during the next contract term. +- Once cancelled, update the recurring expenses section of [The Numbers](https://docs.google.com/spreadsheets/d/1X-brkmUK7_Rgp7aq42drNcUg8ZipzEiS153uKZSabWc/edit#gid=2112277278) to reflect the cancellation by changing the projected monthly burn in column G to $0 and adding "CANCELLED" in front of the vendor's name in column C. + ### Update weekly KPIs - Create the weekly update issue from the template in ZenHub every Friday and update the [KPIs for BizOps](https://docs.google.com/spreadsheets/d/1Hso0LxqwrRVINCyW_n436bNHmoqhoLhC8bcbvLPOs9A/edit#gid=0) by 5pm US central time. - Check the KPI sheet at 5pm US central time to ensure all departments have updated their KPIs on time. If any departments are delinquent, notify the department head and let the [Apprentice to the CEO](https://fleetdm.com/handbook/ceo#team) know so they can put it on the agenda for their next one-on-one with the CEO. diff --git a/handbook/business-operations/security-policies.md b/handbook/business-operations/security-policies.md index c4f3842cfc..cde44d2837 100644 --- a/handbook/business-operations/security-policies.md +++ b/handbook/business-operations/security-policies.md @@ -25,7 +25,7 @@ All Fleet employees and long-term collaborators are expected to read and electro | Policy owner | Effective date | | -------------- | -------------- | -| @zwass | 2023-06-01 | +| @Jostableford | 2024-03-14 | Fleet requires all team members to comply with the following acceptable use requirements and procedures: @@ -60,7 +60,7 @@ When in doubt, **ASK!** (in [#g-security](https://fleetdm.slack.com/archives/C03 | Policy owner | Effective date | | -------------- | -------------- | -| @zwass | 2022-06-01 | +| @Jostableford | 2024-03-14 | Fleet requires all workforce members to comply with the following acceptable use requirements and procedures, such that: @@ -117,7 +117,7 @@ Fleet policy requires that: | Policy owner | Effective date | | -------------- | -------------- | -| @zwass | 2022-06-01 | +| @Jostableford | 2024-03-14 | You can't protect what you can't see. Therefore, Fleet must maintain an accurate and up-to-date inventory of its physical and digital assets. @@ -134,7 +134,7 @@ Fleet policy requires that: | Policy owner | Effective date | | -------------- | -------------- | -| @zwass | 2022-06-01 | +| @Jostableford | 2024-03-14 | The Fleet business continuity and disaster recovery plan establishes procedures to recover Fleet following a disruption resulting from a disaster. @@ -341,7 +341,7 @@ This process is followed when offboarding a customer and deleting all of the pro | Policy owner | Effective date | | -------------- | -------------- | -| @zwass | 2022-06-01 | +| @Jostableford | 2024-03-14 | Fleet requires all workforce members to comply with the encryption policy, such that: @@ -708,7 +708,7 @@ incident response plan annually. | Policy owner | Effective date | | -------------- | -------------- | -| @zwass | 2022-06-01 | +| @Jostableford | 2024-03-14 | Fleet Device Management is committed to conducting business in compliance with all applicable laws, regulations, and company policies. Fleet has adopted this policy to outline the security measures required to protect electronic information systems and related equipment from unauthorized use. @@ -728,7 +728,7 @@ CTO | Oversight over information sec | Policy owner | Effective date | | -------------- | -------------- | -| @zwass | 2022-06-01 | +| @Jostableford | 2024-03-14 | Fleet policy requires @@ -749,7 +749,7 @@ Fleet policy requires | Policy owner | Effective date | | -------------- | -------------- | -| @zwass | 2022-06-01 | +| @Jostableford | 2024-03-14 | Fleet policy requires: @@ -811,7 +811,7 @@ Fleet policy requires that: | Policy owner | Effective date | | -------------- | -------------- | -| @zwass | 2022-06-01 | +| @Jostableford | 2024-03-14 | Fleet policy requires that: diff --git a/handbook/company/communications.md b/handbook/company/communications.md index c0f6a7afcd..bc96271f7f 100644 --- a/handbook/company/communications.md +++ b/handbook/company/communications.md @@ -296,6 +296,8 @@ Our handbook and docs pages are written in Markdown and are editable from our we 6. GitHub will run a series of automated checks and notify the reviewer. At this point, you are done and can safely close the browser page at any time. 8. Check the “Files changed” section on the Open a pull request page to double-check your proposed changes. +> Note: Pages in the `./docs/Contributing/` folder and folders with a underscore prefix (e.g., `./docs/Deploy/_kubernetes/`) are not included in the documentation on the Fleet website. + ### Merging changes When merging a PR to the master branch of the [Fleet repo](https://github.com/fleetdm/fleet), remember that whatever you merge gets deployed live immediately. Ensure that the appropriate quality checks have been completed before merging. [Learn about the website QA process](#quality). @@ -712,7 +714,9 @@ Learn how to communicate as Fleet with guidelines for tone of voice, our approac - Infuse the core [values](https://fleetdm.com/handbook/company#values) into everything you write. - Read and reread, then rewrite to make it shorter. Use links rather than explanations, short sentences. - Get to where you feel like it’s really good, short, simple, and clear, hack away at any word that’s too confusing. - - Don’t sound formal, sound welcoming so that anyone can understand. Translate "[puffery](https://www.linkedin.com/pulse/puffery-adam-frankl%3FtrackingId=SBVWxzqXTBm9qlO7Rw3ddw%253D%253D/?trackingId=SBVWxzqXTBm9qlO7Rw3ddw%3D%3D)" into "ease of use" or "readability". + - Don’t sound formal, sound welcoming so that anyone can understand. Translate "[puffery](https://www.linkedin.com/pulse/puffery-adam-frankl%3FtrackingId=SBVWxzqXTBm9qlO7Rw3ddw%253D%253D/?trackingId=SBVWxzqXTBm9qlO7Rw3ddw%3D%3D)" into "ease of use" or "readability". + - Disarm puffery for engineers by replacing puffery with real data. + - Disarm puffery for the business by replacing puffery with ROI/RTO (how much time and/or money is it going save the business? Forget the details. When will it pay itself back?) - Apply the advice about writing linked from the company values (the [Paul Graham](http://www.paulgraham.com/simply.html) essays). - Create headings that make good permalinks, use links and add missing links. Indicate links by highlighting words that describe the content (Better SEO than lighting up “click here”). - Don’t duplicate content, link to other places like the [values](https://fleetdm.com/handbook/company#values) or [“why this way”](https://fleetdm.com/handbook/company/why-this-way#why-this-way), but don’t make it awkward. diff --git a/handbook/digital-experience/README.md b/handbook/digital-experience/README.md index de58d211fd..e8d0626b78 100644 --- a/handbook/digital-experience/README.md +++ b/handbook/digital-experience/README.md @@ -185,6 +185,18 @@ Fleet's public relations firm is directly responsible for the accuracy of event 2. Update the workbook with the latest location, dates, and CFP deadlines from the website. +### Archive a document +Follow these steps to archive any document: +1. Create a copy of the document prefixed with the date using the format "`YYYY-MM-DD` Backup of `DOCUMENT_NAME`" (e.g. "2024-03-22 Backup of 🪂🗞️ Customer voice"). +2. Be sure to "Share it with the same people", "Copy comments and suggestions", and "Include resolved comments and suggestions" as shown below. + +Screenshot 2024-03-23 at 12 14 00 PM + +3. Save this backup copy to the same location in Google Drive where the original is found. +4. Link to the backup copy at the top of the original document. Be sure to use the full URL, no abbreviated pill links (e.g. "Notes from last time: URL_OF_MOST_RECENT_BACKUP_DOCUMENT"). +5. Delete all non-structural content from the original document, including past meeting notes and current answers to "evergreen" questions. + + ### Schedule CEO interview From time to time, you will need to schedule an interview between a candidate and the CEO: 1. [Make a copy of the "¶¶ CEO interview template"](https://docs.google.com/document/d/1yARlH6iZY-cP9cQbmL3z6TbMy-Ii7lO64RbuolpWQzI/copy) (private Google doc) @@ -382,34 +394,16 @@ You can also grab a copy of the [original slides](https://fleetdm.com/handbook/c ### Process and backup Sid agenda Every two weeks, our CEO Mike has a meeting with Sid Sijbrandij. The CEO uses dedicated (blocked, recurring) time to prepare for this meeting earlier in the week. - -30 minutes After each meeting (to allow all parties to collect action items), the Apprentice makes a copy of the "💻 Sid : Mike(Fleet)" doc and renames it "YYYY-MM-DD Backup of 💻 Sid : Mike(Fleet)". Then moves the backup version into the [(¶¶) Sid archive](https://drive.google.com/drive/folders/1izVfIBt2nr4APlkm36E6DJg1k1PDjmae) - -Then process the backup Sid agenda by: -- Leaving google doc comments assigning all Fleet TODOs to correct Fleeties. -- In the ¶¶¶¶🦿🌪️CEO Roundup doc, update the URL in `Sam: FYI: Agenda from last time:` [LINK](link). - -**Being sure to preserve agenda format**, process the 💻 Sid : Mike(Fleet) master doc by: -- (Unless otherwise prefixed) Delete all agenda items, **being sure to leave 3 empty bullets in every section**. +1. 30 minutes After each meeting [archive the "💻 Sid : Mike(Fleet)" agenda](https://fleetdm.com/handbook/digital-experience#archive-a-document), moving it to the [(¶¶) Sid archive](https://drive.google.com/drive/folders/1izVfIBt2nr4APlkm36E6DJg1k1PDjmae) folder in Google Drive. +2. **In the backup copy**, leave Google Doc comments assigning all Fleet TODOs to the correct DRI. +3. In the ¶¶¶¶🦿🌪️CEO Roundup doc, update the URL in `Sam: FYI: Agenda from last time:` [LINK](link). ### Process and backup E-group agenda -Immediately after every e-group the Apprentice makes a copy of the E-group agenda doc and renames it "YYYY-MM-DD backup of E-group agenda". Then saves it to the [(¶¶) E-group archive](https://drive.google.com/drive/u/0/folders/1IsSGMgbt4pDcP8gSnLj8Z8NGY7_6UTt6). - -Then process the backup E-group agenda by: -- Leaving google doc comments assigning all TODOs to correct individuals. -- In the E-group master doc, update the URL in `Sam: FYI: Agenda from last time:` [LINK](link). - -**Being sure to preserve agenda format**, process the E-group master doc by: -- Clearing all bullets from the "Mike: Hear from each department" section. - - Delete the "Blockers" and "Last week" bullets from each department's section. - - Move contents from "This week" to "Last week". -- (Unless otherwise prefixed) Delete all agenda items from the "Mike: This weeks focus" section. -- (Unless otherwise prefixed) Delete all agenda items from the "Today's other topics" section. - -If it's the day of an All hands: - - Remove any spotlights that aren't a permanent staple (e.g. Mike: Every time: Pick a value, present on it.). - +Follow these steps to process and backup the E-group agenda: +1. [Archive the E-group agenda](https://fleetdm.com/handbook/digital-experience#archive-a-document) after each meeting, moving it to the ["¶¶ E-group archive"](https://drive.google.com/drive/u/0/folders/1IsSGMgbt4pDcP8gSnLj8Z8NGY7_6UTt6) folder in Google Drive. +2. **In the backup copy**, leave Google Doc comments assigning all TODOs to the correct DRI. +3. If the "All hands" meeting has happened today ### Check LinkedIn for unread messages Once a day the Apprentice will confirm check LinkedIn for unread messages. diff --git a/handbook/product-design/README.md b/handbook/product-design/README.md index 21e61fe871..835982d970 100644 --- a/handbook/product-design/README.md +++ b/handbook/product-design/README.md @@ -170,7 +170,7 @@ Every week, a member of the product team looks up whether there is: 4. a release of CIS Benchmarks for [macOS 14 Sonoma](https://workbench.cisecurity.org/community/20/benchmarks?q=sonoma&status=&sortBy=version&type=desc) 5. a new major or minor version of [ChromeOS](https://chromereleases.googleblog.com/search/label/Chrome%20OS) -The DRI should record the latest versions in the [maintenance tracker](https://docs.google.com/spreadsheets/d/1IWfQtSkOQgm_JIQZ0i2y3A8aaK5vQW1ayWRk6-4FOp0/edit#gid=0) and then notify the [#help-product-design Slack channel](https://fleetdm.slack.com/archives/C02A8BRABB5) with an update, noting the current versions and highlighting any changes. +The DRI should record the latest versions in the [maintenance tracker](https://docs.google.com/spreadsheets/d/1IWfQtSkOQgm_JIQZ0i2y3A8aaK5vQW1ayWRk6-4FOp0/edit#gid=0). If there are any changes, the DRI sends an update in the [#help-product-design Slack channel](https://fleetdm.slack.com/archives/C02A8BRABB5). ### View Fleet usage statistics In order to understand the usage of the Fleet product, we [collect statistics](https://fleetdm.com/docs/using-fleet/usage-statistics) from installations where this functionality is enabled. diff --git a/infrastructure/kubequery/Dockerfile b/infrastructure/kubequery/Dockerfile index a3088c1a3e..5480212ad9 100644 --- a/infrastructure/kubequery/Dockerfile +++ b/infrastructure/kubequery/Dockerfile @@ -5,7 +5,7 @@ # # SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only) -FROM ubuntu:20.04 AS builder +FROM ubuntu:20.04@sha256:80ef4a44043dec4490506e6cc4289eeda2d106a70148b74b5ae91ee670e9c35d AS builder ARG BASEQUERY_VERSION=5.0.2 @@ -15,7 +15,7 @@ RUN dpkg -i /tmp/basequery.deb # ===== -FROM uptycs/busybox:v1.33.0 +FROM uptycs/busybox:v1.33.0@sha256:6a312f5959d374420eedce83f42d2ad19a027bd4e448ed734372bc1a07ad8b10 ARG BASEQUERY_VERSION ARG KUBEQUERY_VERSION diff --git a/it-and-security/default.yml b/it-and-security/default.yml index 5a5a170fef..a30c72224b 100644 --- a/it-and-security/default.yml +++ b/it-and-security/default.yml @@ -30,7 +30,6 @@ org_settings: transparency_url: https://fleetdm.com/transparency host_expiry_settings: host_expiry_enabled: false - host_expiry_window: 7 integrations: jira: [ ] zendesk: [ ] diff --git a/it-and-security/lib/macos-device-health.policies.yml b/it-and-security/lib/macos-device-health.policies.yml index 401c086fa0..ea00f2baa6 100644 --- a/it-and-security/lib/macos-device-health.policies.yml +++ b/it-and-security/lib/macos-device-health.policies.yml @@ -11,13 +11,25 @@ resolution: An an IT admin, deploy a macOS, Firewall profile with the EnableFirewall option set to true. platform: darwin - name: macOS - Disable guest account - query: SELECT 1 FROM managed_policies WHERE domain='com.apple.loginwindow' AND username = '' AND name='DisableGuestAccount' AND CAST(value AS INT) = 1; + query: SELECT 1 FROM plist WHERE path='/Library/Preferences/com.apple.loginwindow.plist' AND key='GuestEnabled' AND value = 0; critical: false description: This policy checks if the guest account is disabled. resolution: An an IT admin, deploy a macOS, login window profile with the DisableGuestAccount option set to true. platform: darwin - name: macOS - Require 10 character password - query: SELECT 1 FROM plist WHERE path='/Library/Preferences/com.apple.loginwindow.plist' AND key='GuestEnabled' AND value = 0; + query: SELECT 1 WHERE + EXISTS ( + SELECT 1 FROM managed_policies WHERE + domain='com.apple.screensaver' AND + name='askForPassword' AND + CAST(value AS INT) + ) + AND EXISTS ( + SELECT 1 FROM managed_policies WHERE + domain='com.apple.screensaver' AND + name='minLength' AND + CAST(value AS INT) <= 10 + ); critical: false description: This policy checks if the end user is required to enter a password, with at least 10 characters, to unlock the host. resolution: An an IT admin, deploy a macOS, screensaver profile with the askForPassword option set to true and minLength option set to 10. @@ -40,4 +52,10 @@ critical: false description: This policy checks if maximum amount of time (in minutes) the device is allowed to sit idle before the screen is locked. End users can select any value less than the specified maximum. resolution: An an IT admin, deploy a macOS, screen saver profile with the maxInactivity option set to 20 minutes. - platform: darwin \ No newline at end of file + platform: darwin +- name: macOS - No 1Password emergency kit stored on desktop or in downloads + query: SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM file WHERE filename LIKE '%Emergency Kit%.pdf' AND (path LIKE '/Users/%%/Desktop/%%' OR path LIKE '/Users/%%/Documents/%%' OR path LIKE '/Users/%%/Downloads/%%' OR path LIKE '/Users/Shared')); + critical: false + description: "Looks for PDF files with file names typically used by 1Password for emergency recovery kits." + resolution: "Delete 1Password emergency kits from your computer, and empty the trash. 1Password emergency kits should only be printed and stored in a physically secure location." + platform: darwin diff --git a/server/mdm/scep/Dockerfile b/server/mdm/scep/Dockerfile index c34882b76b..89e0abca6d 100644 --- a/server/mdm/scep/Dockerfile +++ b/server/mdm/scep/Dockerfile @@ -1,4 +1,4 @@ -FROM alpine:3 +FROM alpine:3@sha256:c5b1261d6d3e43071626931fc004f70149baeba2c8ec672bd4f27761f8e1ad6b COPY ./scepclient-linux-amd64 /usr/bin/scepclient COPY ./scepserver-linux-amd64 /usr/bin/scepserver diff --git a/server/service/osquery_utils/queries.go b/server/service/osquery_utils/queries.go index 27ec3932db..030294f5ed 100644 --- a/server/service/osquery_utils/queries.go +++ b/server/service/osquery_utils/queries.go @@ -473,10 +473,10 @@ var extraDetailQueries = map[string]DetailQuery{ enrollment_info AS ( SELECT MAX(CASE WHEN name = 'UPN' THEN data END) AS upn, - MAX(CASE WHEN name = 'IsFederated' THEN data END) AS is_federated, MAX(CASE WHEN name = 'DiscoveryServiceFullURL' THEN data END) AS discovery_service_url, MAX(CASE WHEN name = 'ProviderID' THEN data END) AS provider_id, - MAX(CASE WHEN name = 'EnrollmentState' THEN data END) AS state + MAX(CASE WHEN name = 'EnrollmentState' THEN data END) AS state, + MAX(CASE WHEN name = 'AADResourceID' THEN data END) AS aad_resource_id FROM registry_keys GROUP BY key ), @@ -487,7 +487,7 @@ var extraDetailQueries = map[string]DetailQuery{ LIMIT 1 ) SELECT - e.is_federated, + e.aad_resource_id, e.discovery_service_url, e.provider_id, i.installation_type @@ -1612,7 +1612,7 @@ func directIngestMDMWindows(ctx context.Context, logger log.Logger, host *fleet. serverURL := data["discovery_service_url"] if serverURL != "" { enrolled = true - if isFederated := data["is_federated"]; isFederated == "1" { + if data["aad_resource_id"] != "" { // NOTE: We intentionally nest this condition to eliminate `enrolled == false && automatic == true` // as a possible status for Windows hosts (which would be otherwise be categorized as // "Pending"). Currently, the "Pending" status is supported only for macOS hosts. diff --git a/server/service/osquery_utils/queries_test.go b/server/service/osquery_utils/queries_test.go index 022c00aa7d..4a6da7a2ad 100644 --- a/server/service/osquery_utils/queries_test.go +++ b/server/service/osquery_utils/queries_test.go @@ -692,7 +692,7 @@ func TestDirectIngestMDMWindows(t *testing.T) { data: []map[string]string{ { "discovery_service_url": "", - "is_federated": "1", + "aad_resource_id": "https://example.com", "provider_id": "Some_ID", "installation_type": "Client", }, @@ -703,7 +703,7 @@ func TestDirectIngestMDMWindows(t *testing.T) { wantServerURL: "", }, { - name: "off missing is_federated and server url", + name: "off missing aad_resource_id and server url", data: []map[string]string{ { "provider_id": "Some_ID", @@ -728,7 +728,7 @@ func TestDirectIngestMDMWindows(t *testing.T) { data: []map[string]string{ { "discovery_service_url": "https://example.com", - "is_federated": "1", + "aad_resource_id": "https://example.com", "provider_id": "Some_ID", "installation_type": "Client", }, @@ -743,7 +743,7 @@ func TestDirectIngestMDMWindows(t *testing.T) { data: []map[string]string{ { "discovery_service_url": "https://example.com", - "is_federated": "0", + "aad_resource_id": "", "provider_id": "Local_Management", "installation_type": "Client", }, @@ -754,7 +754,7 @@ func TestDirectIngestMDMWindows(t *testing.T) { wantServerURL: "https://example.com", }, { - name: "on manual missing is_federated", + name: "on manual missing aad_resource_id", data: []map[string]string{ { "discovery_service_url": "https://example.com", @@ -772,7 +772,7 @@ func TestDirectIngestMDMWindows(t *testing.T) { data: []map[string]string{ { "discovery_service_url": "https://example.com", - "is_federated": "1", + "aad_resource_id": "https://example.com", "provider_id": "Some_ID", "installation_type": "Windows SeRvEr 99.9", }, @@ -790,7 +790,7 @@ func TestDirectIngestMDMWindows(t *testing.T) { data: []map[string]string{ { "discovery_service_url": "https://jumpcloud.com", - "is_federated": "0", + "aad_resource_id": "", "provider_id": "Local_Management", "installation_type": "Client", }, @@ -806,7 +806,7 @@ func TestDirectIngestMDMWindows(t *testing.T) { data: []map[string]string{ { "discovery_service_url": "https://airwatch.com", - "is_federated": "0", + "aad_resource_id": "", "provider_id": "Local_Management", "installation_type": "Client", }, @@ -822,7 +822,7 @@ func TestDirectIngestMDMWindows(t *testing.T) { data: []map[string]string{ { "discovery_service_url": "https://awmdm.com", - "is_federated": "0", + "aad_resource_id": "", "provider_id": "Local_Management", "installation_type": "Client", }, @@ -838,7 +838,7 @@ func TestDirectIngestMDMWindows(t *testing.T) { data: []map[string]string{ { "discovery_service_url": "https://microsoft.com", - "is_federated": "0", + "aad_resource_id": "", "provider_id": "Local_Management", "installation_type": "Client", }, @@ -854,7 +854,7 @@ func TestDirectIngestMDMWindows(t *testing.T) { data: []map[string]string{ { "discovery_service_url": "https://fleetdm.com", - "is_federated": "0", + "aad_resource_id": "", "provider_id": "Local_Management", "installation_type": "Client", }, @@ -871,7 +871,7 @@ func TestDirectIngestMDMWindows(t *testing.T) { data: []map[string]string{ { "discovery_service_url": "https://myinstall.local", - "is_federated": "0", + "aad_resource_id": "", "provider_id": "Fleet", "installation_type": "Client", }, diff --git a/tools/fleetctl-npm/yarn.lock b/tools/fleetctl-npm/yarn.lock index 3076f03fae..fabb81d6c0 100644 --- a/tools/fleetctl-npm/yarn.lock +++ b/tools/fleetctl-npm/yarn.lock @@ -52,9 +52,9 @@ delayed-stream@~1.0.0: integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== follow-redirects@^1.15.0: - version "1.15.5" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.5.tgz#54d4d6d062c0fa7d9d17feb008461550e3ba8020" - integrity sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw== + version "1.15.6" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.6.tgz#7f815c0cda4249c74ff09e95ef97c23b5fd0399b" + integrity sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA== form-data@^4.0.0: version "4.0.0" diff --git a/tools/release/patch_release.sh b/tools/release/patch_release.sh new file mode 100755 index 0000000000..30e61662b8 --- /dev/null +++ b/tools/release/patch_release.sh @@ -0,0 +1,659 @@ +#!/usr/bin/env bash + +# +# ,::;;, +# ,:;;;:,,;: +# ,::;;+: ,:;;: +# ,;;;:,,++;;:, +# :;;;::++:, +# ++:, ,;: +# ,, ,;: ::+;::: ,,, +# ,:;::;: ::: ,:,;:,*;;;;+,,,,::,,, +# ;: :+: ,;:, ,:++;;:;**;++::::::;;;;:, +# ,; ,::,:;:, :,: :,;;+*+;, :: :;:;;:, +# ,;:;, :;:, ,;:*: ,::?*: :: ,,,, ,:::::;++;;:::::,, +# :; :;:, ,;+; ,:;;; ,::;;;::::::;;:,,,,:+,,,,,:::;;::, +# ;, ,;:, :+, ,:;;, ;::;:,,,:: :: :; ,;?+ +# ,;, ,;:, ,;: ,:;:, ,+;, ::, ::,,:;: ,,,::;;;+; +# ,; ,+;, :::,:;++, :;;;;;;;;;;;;;;+;;;::;;;;;::,,:;:, +# :: ,;:,;;, ,;;;:,:+, ,,: ,,:::;;;;;;**;,,,, ,:;:, +# :: ,;:, ,;;, ,;;:, :;;:, ,,::::,,:;:,, ;+*+ ,:;;;, +# ;, ,::, ,:;;;:, ::;,:,,::::, ,:;: ,++:,::;;:, +# ,;, :;, ,:;++, ::+:;:,, :;:, ,:;;;:, +# ,;,;: ,:;++:, ,:;++;, ,;+:, ,:;;;:, +# :; ,,:;+;:, ,:::,,,,,,, :;;+; ,:;;::, +# ;: :;+;:, ,:::, ,;+;;;:::;;,:;;::, +# ;;,;*+:,,:, ,:::, ,;, ,;: :,++:,, +# :;:*;: :;, ,::, ,:, ::, ::; +# ,:+:, :: ,:: ,:, ;: ,;; +# ,;, ,,,: ;;,,,;; ,;; ,:, ,;:,:+;, ,,,,, +# ;::;;;::*;:;;;:::;;++, ,:, ,+;;::;+;;;:::;+, +# +;, :?;;:::, ,+, ,:, :;,,,:;;:, :; +# ,+, :+,,,,,;,,,;; ,:, ;+;;;:;; ,;; +# :; :; ,::;+, ,:,,;:,,, :: ,,:;;, +# ;: :; ;; ,: ++;+;; ,;+;;;::, +# ,;, :: :;: ,: ::,,,::+?*+;: +# :; :: ;::, ,: ,;:,:;;:,;;:*+; +# ,;: :: ,: : ,: :;,;:, :+;+, +# ,;, ;: ;,,: ,:,;+ ,: ,;+: +# ;;;;: ,: :, ,;:*++;;;+++**+: +# ;:,, ;, ;:;+::,, ,:;+:::+; +# ,:,;;:, ,,:;;::::;;: +# +;:,,,:;;;;;;;;::, +# ;?+;;;:,:;;::, +# ,,,+;,,:; +# :;::, +# +# +# /$$$$$$$$ /$$ /$$$$$$$$ /$$$$$$$$ /$$$$$$$$ /$$$$$$$ /$$$$$$ /$$$$$$$$ /$$$$$$ /$$ /$$ +# | $$_____/| $$ | $$_____/| $$_____/|__ $$__/ | $$__ $$ /$$__ $$|__ $$__//$$__ $$| $$ | $$ +# | $$ | $$ | $$ | $$ | $$ | $$ \ $$| $$ \ $$ | $$ | $$ \__/| $$ | $$ +# | $$$$$ | $$ | $$$$$ | $$$$$ | $$ | $$$$$$$/| $$$$$$$$ | $$ | $$ | $$$$$$$$ +# | $$__/ | $$ | $$__/ | $$__/ | $$ | $$____/ | $$__ $$ | $$ | $$ | $$__ $$ +# | $$ | $$ | $$ | $$ | $$ | $$ | $$ | $$ | $$ | $$ $$| $$ | $$ +# | $$ | $$$$$$$$| $$$$$$$$| $$$$$$$$ | $$ | $$ | $$ | $$ | $$ | $$$$$$/| $$ | $$ +# |__/ |________/|________/|________/ |__/ |__/ |__/ |__/ |__/ \______/ |__/ |__/ +# +# /$$$$$$$ /$$$$$$$$ /$$ /$$$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$$$ /$$$$$$$ +# | $$__ $$| $$_____/| $$ | $$_____/ /$$__ $$ /$$__ $$| $$_____/| $$__ $$ +# | $$ \ $$| $$ | $$ | $$ | $$ \ $$| $$ \__/| $$ | $$ \ $$ +# | $$$$$$$/| $$$$$ | $$ | $$$$$ | $$$$$$$$| $$$$$$ | $$$$$ | $$$$$$$/ +# | $$__ $$| $$__/ | $$ | $$__/ | $$__ $$ \____ $$| $$__/ | $$__ $$ +# | $$ \ $$| $$ | $$ | $$ | $$ | $$ /$$ \ $$| $$ | $$ \ $$ +# | $$ | $$| $$$$$$$$| $$$$$$$$| $$$$$$$$| $$ | $$| $$$$$$/| $$$$$$$$| $$ | $$ +# |__/ |__/|________/|________/|________/|__/ |__/ \______/ |________/|__/ |__/ +# + +usage() { + echo "Usage: $0 [options] (optional|start_version)" + echo "" + echo "Options:" + echo " -c, --cherry_pick_resolved The script has been run, had merge conflicts, and those have been resolved and all cherry picks completed manually." + echo " -d, --dry_run Perform a trial run with no changes made" + echo " -f, --force Skip all confirmations" + echo " -h, --help Display this help message and exit" + echo " -m, --minor Increment to a minor version instead of patch (Required if including non-bugs" + echo " -o, --open_api_key Set the Open API key for calling out to ChatGPT" + echo " -p, --print If the release is already drafted then print out the helpful info" + echo " -r, --release_notes Update the release notes in the named release on github and exit (requires changelog output from running the script previously)." + echo " -s, --start_version Set the target starting version (can also be the first positional arg) for the release, defaults to latest release on github" + echo " -t, --target_date Set the target date for the release, defaults to today if not provided" + echo " -v, --target_version Set the target version for the release" + echo "" + echo "Environment Variables:" + echo " OPEN_API_KEY Open API key used for fallback if not provided via -o or --open-api-key option" + echo "" + echo "Examples:" + echo " $0 -d Dry run the script" + echo " $0 -m -v 4.45.1 Set a minor release targeting version 4.45.1" + echo " $0 --target_version 4.45.1 --open_api_key examplekey" + echo "" +} + +# Usage example: Run a command and show spinner for n seconds +# Replace `sleep 5` with your command +# sleep 5 & show_spinner 5 +show_spinner() { + local pid=$! + local delay=0.1 + local spinstr='/-\|' + local elapsedTime=0 + local maxTime=$1 + + printf "Processing " + while [ $elapsedTime -lt $maxTime ]; do + local temp=${spinstr#?} + printf "%c" "$spinstr" + local spinstr=$temp${spinstr%"$temp"} + sleep $delay + printf "\b" + elapsedTime=$((elapsedTime+1)) + done + + printf "\nDone.\n" +} + +check_grep() { + # Check if `grep` supports the `-P` option by using it in a no-op search. + # Redirecting stderr to /dev/null to suppress error messages in case `-P` is not supported. + if echo "" | grep -P "" >/dev/null 2>&1; then + return + else + # Now check if `ggrep` is available. + if command -v ggrep >/dev/null 2>&1; then + return + else + echo "Please install latest grep with `brew install grep`" + exit 1 + fi + fi +} + +check_required_binaries() { + local missing_counter=0 + # List of required binaries used in the script + local required_binaries=("jq" "gh" "git" "curl" "awk" "sed" "make" "ack") + + for bin in "${required_binaries[@]}"; do + if ! command -v "$bin" &> /dev/null; then + echo "Error: Required binary '$bin' is not installed." >&2 + missing_counter=$((missing_counter + 1)) + fi + done + + if [ $missing_counter -ne 0 ]; then + echo "Error: $missing_counter required binary(ies) are missing. Install them before running this script." >&2 + exit 1 + fi + check_grep +} + +validate_and_format_date() { + local input_date="$1" + local formatted_date + local correct_format="%b %d, %Y" # e.g., Jan 01, 2024 + + # Try to convert input_date to the correct format + formatted_date=$(date -d "$input_date" +"$correct_format" 2>/dev/null) + + if [ $? -ne 0 ]; then + # date conversion failed + echo "Error: Incorrect date format. Expected format example: $correct_format (e.g., Jan 01, 2024)" >&2 + exit 1 + else + # Check if the formatted date matches the expected date format + if ! date -d "$formatted_date" +"$correct_format" &>/dev/null; then + # This means the formatted date does not match our correct format + echo "Error: Incorrect date format after conversion. Expected format example: $correct_format (e.g., Jan 01, 2024)" >&2 + exit 1 + fi + fi + + # If we reached here, the date is valid and correctly formatted + target_date="$formatted_date" # Update the target_date with the formatted date + echo "Validated and formatted date: $target_date" +} + +print_announce_info() { + echo + echo "For announcing in #help-engineering" + echo "====================================================" + echo "Release $target_milestone QA ticket and docker publish" + echo "QA ticket for Release $target_milestone " `gh issue list --search "Release QA: $target_milestone in:title" --json url | jq -r .[0].url` + echo "Docker Deploy status " `gh run list --workflow goreleaser-snapshot-fleet.yaml --json event,url,headBranch --limit 100 | jq -r "[.[]|select(.headBranch==\"$target_patch_branch\")][0].url"` + echo "List of tickets pulled into release https://github.com/fleetdm/fleet/milestone/$target_milestone_number" + echo +} + +update_release_notes() { + if [ ! -f temp_changelog ]; then + echo "cannot find changelog to populate release notes" + exit 1 + fi + cat temp_changelog | tail -n +3 > release_notes + echo "" >> release_notes + echo "### Upgrading" >> release_notes + echo "" >> release_notes + echo "Please visit our [update guide](https://fleetdm.com/docs/deploying/upgrading-fleet) for upgrade instructions." >> release_notes + echo "" >> release_notes + echo "### Documentation" >> release_notes + echo "" >> release_notes + echo "Documentation for Fleet is available at [fleetdm.com/docs](https://fleetdm.com/docs)." >> release_notes + echo "" >> release_notes + echo "### Binary Checksum" >> release_notes + echo "" >> release_notes + echo "**SHA256**" >> release_notes + echo "" >> release_notes + echo '```' >> release_notes + gh release download $next_tag -p checksums.txt --clobber + cat checksums.txt >> release_notes + echo '```' >> release_notes + + echo + echo "============== Release Notes ========================" + cat release_notes + echo "============== Release Notes ========================" + + if [ "$dry_run" = "false" ]; then + gh release edit --draft -F release_notes $next_tag + fi +} + +# Validate we have all commands required to perform this script +check_required_binaries + +# Initialize variables for the options +cherry_pick_resolved=false +dry_run=false +force=false +minor=false +open_api_key="" +start_version="" +target_date="" +target_version="" +print_info=false +release_notes=false + +# Parse long options manually +for arg in "$@"; do + shift + case "$arg" in + "--cherry_pick_resolved") set -- "$@" "-c" ;; + "--dry-run") set -- "$@" "-d" ;; + "--force") set -- "$@" "-f" ;; + "--help") set -- "$@" "-h" ;; + "--minor") set -- "$@" "-m" ;; + "--open_api_key") set -- "$@" "-o" ;; + "--print") set -- "$@" "-p" ;; + "--release_notes") set -- "$@" "-r" ;; + "--start_version") set -- "$@" "-s" ;; + "--target_date") set -- "$@" "-t" ;; + "--target_version") set -- "$@" "-v" ;; + *) set -- "$@" "$arg" + esac +done + +# Extract options and their arguments using getopts +while getopts "cdfhmo:prs:t:v:" opt; do + case "$opt" in + c) cherry_pick_resolved=true ;; + d) dry_run=true ;; + f) force=true ;; + h) usage; exit 0 ;; + m) minor=true ;; + o) open_api_key=$OPTARG ;; + p) print_info=true ;; + r) release_notes=true ;; + s) start_version=$OPTARG ;; + t) target_date=$OPTARG ;; + v) target_version=$OPTARG ;; + ?) usage; exit 1 ;; + esac +done + +# Shift off the options and optional -- +shift $((OPTIND -1)) + +# Function to determine the best grep variant to use +determine_grep_command() { + # Check if `ggrep` is available + if command -v ggrep >/dev/null 2>&1; then + echo "ggrep" # Use GNU grep if available + elif echo "" | grep -P "" >/dev/null 2>&1; then + echo "grep" # Use grep if it supports the -P option + else + echo "grep" # Default to grep if ggrep is not available and -P is not supported + # Note: You might want to handle the lack of -P support differently here + fi +} + +# Assign the best grep variant to a variable +GREP_CMD=$(determine_grep_command) + +# Now you can use the $dry_run variable to see if the option was set +if $dry_run; then + echo "Dry run mode enabled." +fi + +# Check for OPEN_API_KEY environment variable if no key was provided through command-line options +if [ -z "$open_api_key" ]; then + if [ -n "$OPEN_API_KEY" ]; then + open_api_key=$OPEN_API_KEY + else + echo "Error: No open API key provided. Set the key via -o/--open-api-key option or OPEN_API_KEY environment variable." >&2 + exit 1 + fi +fi + +if [[ "$target_date" != "" ]]; then + validate_and_format_date $target_date +fi + +# ex v4.43.0 +if [ -z "$start_version" ]; then + if [[ "$1" == "" ]]; then + # grab latest draft excluding test version 9.99.9 + draft=`gh release list | $GREP_CMD Draft | $GREP_CMD -v 9.99.9` + if [[ "$draft" != "" ]]; then + target_version=`echo $draft | awk '{print $1}' | cut -d '-' -f2` + start_version=`gh release list | $GREP_CMD Draft -A1 | tail -n1 | awk '{print $1}' | cut -d '-' -f2` + else + start_version=`gh release list | $GREP_CMD Latest | awk '{print $1}' | cut -d '-' -f2` + fi + else + start_version="$1" + fi +fi + +if [[ $start_version != v* ]]; then + start_version=`echo "v$start_version"` +fi + +if [[ "$target_version" != "" ]]; then + if [[ $target_version != v* ]]; then + target_version=`echo "v$target_version"` + fi + next_ver=$target_version +else + if [[ "$minor" == "true" ]]; then + next_ver=$(echo $start_version | awk -F. '{print $1"."($2+1)".0"}') + else + next_ver=$(echo $start_version | awk -F. '{print $1"."$2"."($3+1)}') + fi +fi + +start_ver_tag=fleet-$start_version + +echo "Patch release from $start_version to $next_ver" +if [ "$force" = "false" ]; then + read -r -p "If this is correct confirm yes to continue? [y/N] " response + case "$response" in + [yY][eE][sS]|[yY]) + echo + ;; + *) + exit 1 + ;; + esac +fi +start_milestone="${start_version:1}" +target_milestone="${next_ver:1}" +target_milestone_number=`gh api repos/:owner/:repo/milestones | jq -r ".[] | select(.title==\"$target_milestone\") | .number"` +target_patch_branch="patch-fleet-$next_ver" +next_tag="fleet-$next_ver" + +if [ "$print_info" = "true" ]; then + print_announce_info + exit 0 +fi + +if [ "$release_notes" = "true" ]; then + update_release_notes + exit 0 +fi + +if [[ "$target_milestone_number" == "" ]]; then + echo "Missing milestone $target_milestone, Please create one and tie tickets to the milestone to continue" + exit 1 +fi +echo "Found milestone $target_milestone with number $target_milestone_number" + +failed=false + +if [ "$cherry_pick_resolved" = "false" ]; then + if [ "$dry_run" = "false" ]; then + git fetch + fi + + # TODO Fail if not found + if [ "$dry_run" = "false" ]; then + git checkout $start_ver_tag + else + echo "DRYRUN: Would have checked out starting tag $start_ver_tag" + fi + + + local_exists=`git branch | $GREP_CMD $target_patch_branch` + + if [ "$dry_run" = "false" ]; then + if [[ $local_exists != "" ]]; then + # Clear previous + git branch -D $target_patch_branch + fi + git checkout -b $target_patch_branch + else + echo "DRYRUN: Would have cleared / checked out new branch $target_patch_branch" + fi + + + total_prs=() + + issue_list=`gh issue list --search 'milestone:"'"$target_milestone"'"' --json number | jq -r '.[] | .number'` + if [[ "$issue_list" == "" ]]; then + echo "Milestone $target_milestone has no target issues, please tie tickets to the milestone to continue" + exit 1 + fi + echo "Issue list for new patch $next_ver" + echo $issue_list + for issue in $issue_list; do + prs_for_issue=`gh api repos/fleetdm/fleet/issues/$issue/timeline --paginate | jq -r '.[]' | $GREP_CMD "fleetdm/fleet/" | $GREP_CMD -oP "pulls\/\K(?:\d+)"` + echo -n "https://github.com/fleetdm/fleet/issues/$issue" + if [[ "$prs_for_issue" == "" ]]; then + echo -n "NO PR's found, please verify they are not missing in the issue, if no PR's were required for this ticket please reconsider adding it to this release." + fi + for val in $prs_for_issue; do + echo -n " $val" + total_prs+=("$val") + done + echo + done + + + if [ "$force" = "false" ]; then + read -r -p "Check any issues that have no pull requests, no to cancel and yes to continue? [y/N] " response + case "$response" in + [yY][eE][sS]|[yY]) + echo "Continuing to cherry-pick" + echo + ;; + *) + exit 1 + ;; + esac + fi + + commits="" + + for pr in ${total_prs[*]}; + do + output=`gh pr view $pr --json state,mergeCommit,baseRefName` + state=`echo $output | jq -r .state` + commit=`echo $output | jq -r .mergeCommit.oid` + target_branch=`echo $output | jq -r .baseRefName` + echo -n "$pr $state $commit $target_branch:" + if [[ "$state" != "MERGED" || "$target_branch" != "main" ]]; then + echo " WARNING - Skipping pr https://github.com/fleetdm/fleet/pull/$pr" + else + if [[ "$commit" != "" && "$commit" != "null" ]]; then + echo " Commit looks valid - $commit, adding to cherry-pick" + commits+="$commit " + else + echo " WARNING - invalid commit for pr https://github.com/fleetdm/fleet/pull/$pr - $commit" + fi + fi + #echo "=======================================" + done + + for commit in $commits; + do + # echo $commit + timestamp=`git log -n 1 --pretty=format:%at $commit` + if [ $? -ne 0 ]; then + echo "Failed to identify $commit, exiting" + exit 1 + fi + # echo $timestamp + time_map[$timestamp]=$commit + done + + timestamps="" + for key in "${!time_map[@]}"; do + timestamps+="$key\n" + done + for ts in `echo -e $timestamps | sort`; do + commit_hash="${time_map[$ts]}" + # echo "# $ts $commit_hash" + if git branch --contains "$commit_hash" | $GREP_CMD -q "$(git rev-parse --abbrev-ref HEAD)"; then + echo "# Commit $commit_hash is on the current branch." + is_on_current_branch=true + else + # echo "# Commit $commit_hash is not on the current branch." + if [[ "$failed" == "false" ]]; then + + if [ "$dry_run" = "false" ]; then + git cherry-pick $commit_hash + if [ $? -ne 0 ]; then + echo "Cherry pick of $commit_hash failed. Please resolve then continue the cherry-picks manually" + failed=true + fi + else + echo "DRYRUN: Would have cherry picked $commit_hash" + fi + else + echo "git cherry-pick $commit_hash" + fi + is_on_current_branch=false + fi + done +fi + +if [[ "$failed" == "false" ]]; then + + if [ "$dry_run" = "false" ]; then + make changelog + git diff CHANGELOG.md | $GREP_CMD '^+' | sed 's/^+//g' | $GREP_CMD -v CHANGELOG.md > new_changelog + prompt=$'I am creating a changelog for an open source project from a list of commit messages. Please format it for me using the following rules:\n1. Correct spelling and punctuation.\n2. Sentence casing.\n3. Past tense.\n4. Each list item is designated with an asterisk.\n5. Output in markdown format.' + content=$(cat new_changelog | sed -E ':a;N;$!ba;s/\r{0,1}\n/\\n/g') + question="${prompt}\n\n${content}" + + # API endpoint for ChatGPT + api_endpoint="https://api.openai.com/v1/chat/completions" + output="null" + + while [[ "$output" == "null" ]]; do + data_payload=$(jq -n \ + --arg prompt "$question" \ + --arg model "gpt-3.5-turbo" \ + '{model: $model, messages: [{"role": "user", "content": $prompt}]}') + + response=$(curl -s -X POST $api_endpoint \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer $open_api_key" \ + --data "$data_payload") + + output=`echo $response | jq -r .choices[0].message.content` + echo "${output}" + done + else + echo "DRYRUN: Would have run make changelog and sent to ChatGPT to format" + fi + + if [ "$dry_run" = "false" ]; then + git checkout CHANGELOG.md + if [[ "$target_date" == "" ]]; then + tartget_date=`date +"%b %d, %Y"` + fi + echo "## Fleet $target_milestone ($tartget_date)" > temp_changelog + echo "" >> temp_changelog + echo "### Bug fixes" >> temp_changelog + echo "" >> temp_changelog + echo -e "${output}" >> temp_changelog + echo "" >> temp_changelog + cp CHANGELOG.md old_changelog + cat temp_changelog > CHANGELOG.md + cat old_changelog >> CHANGELOG.md + rm -f old_changelog + update_changelog_patch_branch="update-changelog-pb-$target_milestone" + local_exists=`git branch | $GREP_CMD $update_changelog_patch_branch` + if [[ $local_exists != "" ]]; then + # Clear previous + git branch -D $update_changelog_patch_branch + fi + git checkout -b $update_changelog_patch_branch + git add CHANGELOG.md + git commit -m "Adding changes for patch $target_milestone" + git push origin $update_changelog_patch_branch -f + gh pr create -f -B $target_patch_branch + + cp CHANGELOG.md /tmp + git checkout main + git pull origin main + update_changelog_branch="update-changelog-$target_milestone" + local_exists=`git branch | $GREP_CMD $update_changelog_branch` + if [[ $local_exists != "" ]]; then + # Clear previous + git branch -D $update_changelog_branch + fi + git checkout -b $update_changelog_branch + cp /tmp/CHANGELOG.md . + git add CHANGELOG.md + escaped_start_version=$(echo "$start_milestone" | sed 's/\./\\./g') + version_files=`ack -l --ignore-file=is:CHANGELOG.md "$escaped_start_version"` + unameOut="$(uname -s)" + case "${unameOut}" in + Linux*) echo "$version_files" | xargs sed -i "s/$escaped_start_version/$target_milestone/g";; + Darwin*) echo "$version_files" | xargs sed -i '' "s/$escaped_start_version/$target_milestone/g";; + *) echo "unknown distro to parse version" + esac + git add terraform charts infrastructure tools + git commit -m "Updating changelog for $target_milestone" + git push origin $update_changelog_branch -f + gh pr create -f + + git checkout $target_patch_branch + else + echo "DRYRUN: Would have formatted changelog and created PR on main" + fi + + # Check for QA issue + if [ "$dry_run" = "false" ]; then + found=$(gh issue list --search "Release QA: $target_milestone in:title" --json number | jq length) + if [[ "$found" == "0" ]]; then + cat .github/ISSUE_TEMPLATE/release-qa.md | awk 'BEGIN {count=0} /^---$/ {count++} count==2 && /^---$/ {getline; count++} count > 2 {print}' > temp_qa_issue_file + gh issue create --title "Release QA: $target_milestone" -F temp_qa_issue_file \ + --assignee "sabrinabuckets" --assignee "xpkoala" --label ":release" --label "#g-mdm" --label "#g-endpoint-ops" + rm -f temp_qa_issue_file + fi + else + echo "DRYRUN: Would have searched for and created if not found QA release ticket" + fi + + if [ "$dry_run" = "false" ]; then + echo "Waiting for github actions to propogate..." + show_spinner 200 + # For announce in #help-engineering + print_announce_info + else + echo "DRYRUN: Would have printed announce in #help-engineering text w/ qa ticket, deploy to docker link, and milestone issue list link" + fi + + if [ "$dry_run" = "false" ]; then + echo "waiting for Changelog PR to merge..." + echo `gh pr view $update_changelog_patch_branch --json url | jq -r .url` + echo + waiting=true + while waiting; do + pr_state=`gh pr view $update_changelog_patch_branch --json state | jq -r .state` + if [[ "$pr_state" == "MERGED" ]]; then + waiting=false + else + show_spinner 50 + fi + done + git pull origin $target_patch_branch + + git tag $next_tag + git push origin $next_tag + + show_spinner 200 + else + echo "DRYRUN: Would have tagged and pushed $next_tag" + fi + + if [ "$dry_run" = "false" ]; then + releaser_out=`gh run list --workflow goreleaser-fleet.yaml --json databaseID,event,headBranch,url | jq "[.[]|select(.headBranch==\"$next_tag\")[0]` + echo "Releaser running " `echo $releaser_out | jq -r ".url"` + + gh run watch `echo $releaser_out | jq -r ".databaseID"` + else + echo "DRYRUN: Would found goreleaser action and waited for it to complete" + fi + + + update_release_notes +else + # TODO echo what to do + echo "Placeholder, Cherry pick failed....figure out what to do..." + exit 1 +fi + diff --git a/tools/tuf/test/Dockerfile b/tools/tuf/test/Dockerfile index eef0bfc90f..d83db1c41a 100644 --- a/tools/tuf/test/Dockerfile +++ b/tools/tuf/test/Dockerfile @@ -1,4 +1,4 @@ -FROM debian:bookworm-slim +FROM debian:bookworm-slim@sha256:ccb33c3ac5b02588fc1d9e4fc09b952e433d0c54d8618d0ee1afadf1f3cf2455 WORKDIR /usr/src/app diff --git a/website/api/controllers/deliver-premium-upgrade-form.js b/website/api/controllers/deliver-premium-upgrade-form.js deleted file mode 100644 index 783191f13e..0000000000 --- a/website/api/controllers/deliver-premium-upgrade-form.js +++ /dev/null @@ -1,72 +0,0 @@ -module.exports = { - - - friendlyName: 'Deliver premium upgrade form', - - - description: 'Delivers a Fleet Premium upgrade form submission to a Zapier webhook', - - - inputs: { - organization: { - type: 'string', - required: true, - }, - - monthsUsingFleetFree: { - type: 'string', - required: true, - example: '1 - 3 months' - }, - - emailAddress: { - type: 'string', - isEmail: true, - required: true, - }, - - numberOfHosts: { - type: 'number', - required: true, - isInteger: true, - } - }, - - - exits: { - success: { - description: 'The Fleet Premium upgrade form submission was sent to Zapier successfully.' - } - }, - - - fn: async function ({organization, monthsUsingFleetFree, emailAddress, numberOfHosts}) { - - if(!sails.config.custom.zapierSandboxWebhookSecret) { - throw new Error('Message not delivered: zapierSandboxWebhookSecret needs to be configured in sails.config.custom.'); - } - - // Send a POST request to Zapier - await sails.helpers.http.post( - 'https://hooks.zapier.com/hooks/catch/3627242/bvxxkjf/', - { - 'emailAddress': emailAddress, - 'organization': organization, - 'numberOfHosts': numberOfHosts, - 'monthsUsingFleetFree': monthsUsingFleetFree, - 'webhookSecret': sails.config.custom.zapierSandboxWebhookSecret - } - ) - .timeout(5000) - .tolerate(['non200Response', 'requestFailed', {name: 'TimeoutError'}], (err)=>{ - // Note that Zapier responds with a 2xx status code even if something goes wrong, so just because this message is not logged doesn't mean everything is hunky dory. More info: https://github.com/fleetdm/fleet/pull/6380#issuecomment-1204395762 - sails.log.warn(`When a user submitted the Fleet Premium upgrade form, an error occurred while sending a request to Zapier. Raw error: ${require('util').inspect(err)}`); - return; - });//∞ - - // All done. - return; - } - - -}; diff --git a/website/api/controllers/view-upgrade.js b/website/api/controllers/view-upgrade.js deleted file mode 100644 index e946b02700..0000000000 --- a/website/api/controllers/view-upgrade.js +++ /dev/null @@ -1,27 +0,0 @@ -module.exports = { - - - friendlyName: 'View upgrade', - - - description: 'Display "Upgrade" page.', - - - exits: { - - success: { - viewTemplatePath: 'pages/upgrade' - } - - }, - - - fn: async function () { - - // Respond with view. - return {}; - - } - - -}; diff --git a/website/assets/images/premium-landing-feature-1.svg b/website/assets/images/premium-landing-feature-1.svg deleted file mode 100644 index 39945d4cfd..0000000000 --- a/website/assets/images/premium-landing-feature-1.svg +++ /dev/null @@ -1,72 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/website/assets/images/premium-landing-feature-2.svg b/website/assets/images/premium-landing-feature-2.svg deleted file mode 100644 index 61e48c60d3..0000000000 --- a/website/assets/images/premium-landing-feature-2.svg +++ /dev/null @@ -1,148 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/website/assets/images/premium-landing-feature-3.svg b/website/assets/images/premium-landing-feature-3.svg deleted file mode 100644 index 28a0ffeaea..0000000000 --- a/website/assets/images/premium-landing-feature-3.svg +++ /dev/null @@ -1,231 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/website/assets/images/premium-landing-feature-4.svg b/website/assets/images/premium-landing-feature-4.svg deleted file mode 100644 index 239a1cc75c..0000000000 --- a/website/assets/images/premium-landing-feature-4.svg +++ /dev/null @@ -1,123 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/website/assets/images/premium-landing-feature-5.svg b/website/assets/images/premium-landing-feature-5.svg deleted file mode 100644 index 50ddd2e529..0000000000 --- a/website/assets/images/premium-landing-feature-5.svg +++ /dev/null @@ -1,74 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/website/assets/js/pages/upgrade.page.js b/website/assets/js/pages/upgrade.page.js deleted file mode 100644 index 9281c1a9b7..0000000000 --- a/website/assets/js/pages/upgrade.page.js +++ /dev/null @@ -1,64 +0,0 @@ -parasails.registerPage('upgrade', { - // ╦╔╗╔╦╔╦╗╦╔═╗╦ ╔═╗╔╦╗╔═╗╔╦╗╔═╗ - // ║║║║║ ║ ║╠═╣║ ╚═╗ ║ ╠═╣ ║ ║╣ - // ╩╝╚╝╩ ╩ ╩╩ ╩╩═╝ ╚═╝ ╩ ╩ ╩ ╩ ╚═╝ - data: { - formData: { - monthsUsingFleetFree: 'Please select one', - }, - - // For tracking client-side validation errors in our form. - // > Has property set to `true` for each invalid property in `formData`. - formErrors: { /* … */ }, - - // Form rules - formRules: { - organization: {required: true }, - monthsUsingFleetFree: { - required: true, - isIn:[ - '1 - 3 months', - '3 - 6 months', - '6 - 12 months', - '12+ months', - ] - }, - emailAddress: {required: true, isEmail: true}, - numberOfHosts: {required: true }, - }, - cloudError: '', - // Syncing / loading state - syncing: false, - cloudSuccess: false, - }, - - // ╦ ╦╔═╗╔═╗╔═╗╦ ╦╔═╗╦ ╔═╗ - // ║ ║╠╣ ║╣ ║ ╚╦╝║ ║ ║╣ - // ╩═╝╩╚ ╚═╝╚═╝ ╩ ╚═╝╩═╝╚═╝ - beforeMount: function() { - //… - }, - mounted: async function() { - //… - }, - - // ╦╔╗╔╔╦╗╔═╗╦═╗╔═╗╔═╗╔╦╗╦╔═╗╔╗╔╔═╗ - // ║║║║ ║ ║╣ ╠╦╝╠═╣║ ║ ║║ ║║║║╚═╗ - // ╩╝╚╝ ╩ ╚═╝╩╚═╩ ╩╚═╝ ╩ ╩╚═╝╝╚╝╚═╝ - methods: { - typeClearOneFormError: async function(field) { - if(this.formErrors[field]){ - this.formErrors = _.omit(this.formErrors, field); - } - }, - submittedForm: function() { - this.cloudSuccess = true; - }, - _resetForms: async function() { - this.cloudError = ''; - this.formData = {}; - this.formErrors = {}; - await this.forceRender(); - }, - } -}); diff --git a/website/assets/styles/importer.less b/website/assets/styles/importer.less index 7d4131d5cf..0d2f94d678 100644 --- a/website/assets/styles/importer.less +++ b/website/assets/styles/importer.less @@ -65,7 +65,6 @@ @import 'pages/vanta-authorization.less'; @import 'pages/admin/generate-license.less'; @import 'pages/device-management.less'; -@import 'pages/upgrade.less'; @import 'pages/endpoint-ops.less'; @import 'pages/transparency.less'; @import 'pages/press-kit.less'; diff --git a/website/assets/styles/layout.less b/website/assets/styles/layout.less index de314d96ae..42b4574d6b 100644 --- a/website/assets/styles/layout.less +++ b/website/assets/styles/layout.less @@ -417,7 +417,7 @@ html, body { } } [purpose='page-wrap'].reduced-footer-links { - padding-bottom: 67px; + padding-bottom: 70px; } // Landing page footer styles @@ -425,7 +425,7 @@ html, body { position: absolute; bottom: 0px; width: 100%; - height: 67px; + height: 70px; padding: 24px 32px; color: @core-fleet-black-75; a { @@ -451,9 +451,9 @@ body.detected-mobile { [purpose='page-footer'] { padding: 64px 40px; height: 460px; - } - [purpose='footer-socials'] { - margin-bottom: 32px; + [purpose='footer-socials'] { + margin-bottom: 32px; + } } } @@ -479,15 +479,22 @@ body.detected-mobile { padding: 64px 32px; height: 701px; } + [purpose='page-wrap'].reduced-footer-links { + padding-bottom: 121px; + } + [purpose='reduced-nav-footer'] { + height: 121px; + [purpose='footer-socials'] { + margin-bottom: 32px; + } + } + } @media (max-width: 575px) { [purpose='page-wrap'] { padding-bottom: 925px; } - [purpose='page-wrap'].reduced-footer-links { - padding-bottom: 97px; - } [purpose='page-header'] { padding: 19px 24px; [purpose='mobile-nav'] { @@ -499,8 +506,12 @@ body.detected-mobile { } } } + [purpose='page-wrap'].reduced-footer-links { + padding-bottom: 173px; + } [purpose='reduced-nav-footer'] { - height: 97px; + height: 173px; + padding: 24px; } [purpose='page-footer'] { height: 925px; diff --git a/website/assets/styles/pages/homepage.less b/website/assets/styles/pages/homepage.less index 79445817c7..80fbb8029d 100644 --- a/website/assets/styles/pages/homepage.less +++ b/website/assets/styles/pages/homepage.less @@ -82,7 +82,8 @@ position: relative; width: 100%; overflow: hidden; - div { + + [purpose='logo-row'] { white-space: nowrap; animation: scroll-horizontal 80s linear infinite; } @@ -110,7 +111,14 @@ background: linear-gradient(90deg, rgba(255, 255, 255, 0.00) 0%, #FFF 100%); } } - + @keyframes scroll-horizontal { + 0% { + transform: translateX(-25%); + } + 100% { + transform: translateX(-125%); + } + } [purpose='homepage-content'] { max-width: 1200px; @@ -1428,13 +1436,6 @@ } - @keyframes scroll-horizontal { - 0% { - transform: translateX(50%); - } - 100% { - transform: translateX(-50%); - } - } + } diff --git a/website/assets/styles/pages/upgrade.less b/website/assets/styles/pages/upgrade.less deleted file mode 100644 index e883a27e38..0000000000 --- a/website/assets/styles/pages/upgrade.less +++ /dev/null @@ -1,199 +0,0 @@ -#upgrade { - background: linear-gradient(180deg, rgba(232, 241, 246, 0.5) 4.75%, rgba(255, 255, 255, 0) 37.29%); - [purpose='page-container'] { - padding-top: 100px; - padding-bottom: 120px; - max-width: 1200px; - margin-left: auto; - margin-right: auto; - padding-left: 40px; - padding-right: 40px; - } - h1 { - font-weight: 800; - font-size: 40px; - line-height: 48px; - text-align: left; - margin-bottom: 80px; - } - h2 { - font-weight: 800; - font-size: 28px; - line-height: 38px; - } - h3 { - font-weight: 700; - font-size: 20px; - line-height: 24px; - margin-bottom: 16px; - } - a { - font-size: 14px; - color: @core-vibrant-blue; - text-decoration: underline; - } - - [purpose='feature'] { - img { - margin-left: auto; - margin-right: auto; - } - [purpose='feature-image'] { - min-width: 160px; - margin-right: 40px; - } - margin-bottom: 80px; - } - [purpose='upgrade-form'] { - margin-left: 80px; - padding: 40px; - background: #F9FAFC; - box-shadow: 0px 0px 0px 1px #E2E4EA; - border-radius: 8px; - width: 480px; - input { - border: 1px solid #C5C7D1; - border-radius: 6px; - height: 48px; - font-size: 16px; - color: @core-fleet-black; - -webkit-appearance: none; - } - select { - // for hiding the +

Includes computers, servers, containers, and other hosts.

Please enter a number of devices
diff --git a/website/views/pages/homepage.ejs b/website/views/pages/homepage.ejs index 20b048c4f9..91db1122b6 100644 --- a/website/views/pages/homepage.ejs +++ b/website/views/pages/homepage.ejs @@ -22,7 +22,7 @@
-
+
Notion logo Pinterest logo Gusto logo @@ -41,7 +41,26 @@ Reddit logo
-
+
+ Notion logo + Pinterest logo + Gusto logo + Epic Games logo + Rivian logo + Deloitte logo + Flywire logo + Snowflake logo + Uber logo + Atlassian logo + Toast logo + + Fastly logo + Hashicorp logo + Dropbox logo + + Reddit logo +
+
Notion logo Pinterest logo Gusto logo diff --git a/website/views/pages/upgrade.ejs b/website/views/pages/upgrade.ejs deleted file mode 100644 index 950e582fa4..0000000000 --- a/website/views/pages/upgrade.ejs +++ /dev/null @@ -1,109 +0,0 @@ -
-
-

Get even more control with Fleet Premium

-
-
- <%// First row with two bullet points %> -
-
-
- Expertise on-demand -
-
-

Expertise on-demand

-

Get your own private Slack channel with Fleet experts.

-
-
-
-
- Custom solutions -
-
-

Custom solutions

-

Customize your Fleet deployment with queries and policies tailored to your needs, training specific to the roles of your users, and dashboards relevant to your executives.

-
-
-
- <%// Second row with two bullet points %> -
-
-
- Target and configure specific device groups -
-
-

Target and configure specific device groups

-

Improve your security posture with unique configurations for specific groups of endpoints. Give appropriate access to every employee with RBAC.

-
-
-
-
- Open source CIS compliance policies -
-
-

Open source CIS compliance policies

-

Strengthen your IT risk management strategy with our out-of-the-box CIS compliance policies that protect your systems and data from cyber threats.

-
-
-
- <%// Third row with one bullet point %> -
-
-
- See vulnerability scores and probability of exploit -
-
-

See vulnerability scores and probability of exploit

-

Fleet Premium provides richer software vulnerability data, including real-time EPSS and CVSS scores, as well as CISA-known exploited vulnerabilities.

-
-
-
-
-
- <%// Form %> -
-

Upgrade to Fleet Premium

-

Complete the form below and a member of our team will be in touch within one business day.

- -
- - -
Please enter the name of your company.
-
-
- - -
Please select an option
-
-
- - -
This doesn’t appear to be a valid email address
-
-
- - -
Please enter a number of devices.
-
- -
- Submit -
-
-

We will never spam you.

-
- <%// Form success state %> -
-

We’ll be in touch soon!

-

A member of our team will be in touch within one business day.

-
-
-
-
-
-<%- /* Expose server-rendered data as window.SAILS_LOCALS :: */ exposeLocalsToBrowser() %> diff --git a/yarn.lock b/yarn.lock index 3cd3f36bde..eca3a26a55 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9598,9 +9598,9 @@ flow-parser@0.*: integrity sha512-ZJ6VuLe/BoqeI4GsF+ZuzlpfGi3FCnBrb4xDYhgEJxRt7SAj3ibRuRSsuJSRcY+lQhPZRPNbNWiQqFMxramUzw== follow-redirects@^1.14.0, follow-redirects@^1.15.0: - version "1.15.4" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.4.tgz#cdc7d308bf6493126b17ea2191ea0ccf3e535adf" - integrity sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw== + version "1.15.6" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.6.tgz#7f815c0cda4249c74ff09e95ef97c23b5fd0399b" + integrity sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA== for-each@^0.3.3: version "0.3.3" @@ -17840,9 +17840,9 @@ webpack-cli@5.0.1: webpack-merge "^5.7.3" webpack-dev-middleware@^6.1.1: - version "6.1.1" - resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-6.1.1.tgz#6bbc257ec83ae15522de7a62f995630efde7cc3d" - integrity sha512-y51HrHaFeeWir0YO4f0g+9GwZawuigzcAdRNon6jErXy/SqV/+O6eaVAzDqE6t3e3NpGeR5CS+cCDaTC+V3yEQ== + version "6.1.2" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-6.1.2.tgz#0463232e59b7d7330fa154121528d484d36eb973" + integrity sha512-Wu+EHmX326YPYUpQLKmKbTyZZJIB8/n6R09pTmB03kJmnMsVPTo9COzHZFr01txwaCAuZvfBJE4ZCHRcKs5JaQ== dependencies: colorette "^2.0.10" memfs "^3.4.12"