From 0738a2909c828540f6955ce0d746c57b658abbe1 Mon Sep 17 00:00:00 2001 From: linus-sun Date: Fri, 15 Nov 2024 19:33:12 +0000 Subject: [PATCH] add readme and workflow Signed-off-by: linus-sun --- .github/workflows/ct_reusable_monitoring.yml | 83 ++++++++++++++++++++ README.md | 48 +++++++++++ cmd/ct_monitor/main.go | 11 ++- pkg/ct/monitor.go | 6 +- 4 files changed, 144 insertions(+), 4 deletions(-) create mode 100644 .github/workflows/ct_reusable_monitoring.yml diff --git a/.github/workflows/ct_reusable_monitoring.yml b/.github/workflows/ct_reusable_monitoring.yml new file mode 100644 index 00000000..8a243f8f --- /dev/null +++ b/.github/workflows/ct_reusable_monitoring.yml @@ -0,0 +1,83 @@ +# Copyright 2024 The Sigstore Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +name: Certificate Transparency Monitoring Template + +on: + workflow_call: + inputs: + once: + description: 'whether to run the identity monitor once or periodically' + default: true + required: false + type: boolean + config: + description: 'multiline yaml of configuration settings for identity monitor run' + required: true + type: string + +permissions: + contents: read + +env: + UPLOADED_LOG_NAME: checkpoint + LOG_FILE: checkpoint_log.txt + +jobs: + detect-workflow: + runs-on: ubuntu-latest + permissions: + id-token: write # Needed to detect the current reusable repository and ref. + outputs: + repository: ${{ steps.detect.outputs.repository }} + ref: ${{ steps.detect.outputs.ref }} + steps: + - name: Detect the repository and ref + id: detect + uses: slsa-framework/slsa-github-generator/.github/actions/detect-workflow-js@5a775b367a56d5bd118a224a811bba288150a563 # v2.0.0 + # NOTE: This GHA should not be run concurrently. + concurrency: + group: certificate-transparency-monitor + cancel-in-progress: true + + monitor: + runs-on: ubuntu-latest + needs: [detect-workflow] + steps: + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + repository: ${{ needs.detect-workflow.outputs.repository }} + ref: "${{ needs.detect-workflow.outputs.ref }}" + - uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 + with: + go-version: '1.23' + - name: Download artifact + uses: dawidd6/action-download-artifact@bf251b5aa9c2f7eeb574a96ee720e24f801b7c11 # v6 + with: + name: ${{ env.UPLOADED_LOG_NAME }} + # Skip on first run since there will be no checkpoint + continue-on-error: true + - name: Log current checkpoints + run: cat ${{ env.LOG_FILE }} + # Skip on first run + continue-on-error: true + - run: go run ./cmd/ct_monitor --config ${{ inputs.config }} --file ${{ env.LOG_FILE }} --once=${{ inputs.once }}" + - name: Upload checkpoint + uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + with: + name: ${{ env.UPLOADED_LOG_NAME }} + path: ${{ env.LOG_FILE }} + retention-days: ${{ inputs.artifact_retention_days }} + - name: Log new checkpoints + run: cat ${{ env.LOG_FILE }} \ No newline at end of file diff --git a/README.md b/README.md index a7e36bb2..464ad48b 100644 --- a/README.md +++ b/README.md @@ -120,6 +120,54 @@ Upcoming features: * Support for other identities * CI identity values in Fulcio certificates +## Certificate transparency log monitoring + +Certificate transparency log instances can also be monitored. To run, create a GitHub Actions workflow that uses the +[reusable certificate transparency log monitoring workflow](https://github.com/sigstore/rekor-monitor/blob/main/.github/workflows/ct_reusable_monitoring.yml). +It is recommended to run the log monitor every hour for optimal performance. + +Example workflow below: + +``` +name: Fulcio log and identity monitor +on: + schedule: + - cron: '0 * * * *' # every hour + +permissions: read-all + +jobs: + run_consistency_proof: + permissions: + contents: read # Needed to checkout repositories + issues: write # Needed if you set "file_issue: true" + id-token: write # Needed to detect the current reusable repository and ref + uses: sigstore/rekor-monitor/.github/workflows/reusable_monitoring.yaml@main + with: + file_issue: true # Strongly recommended: Files an issue on monitoring failure + artifact_retention_days: 14 # Optional, default is 14: Must be longer than the cron job frequency + identities: | + certIdentities: + - certSubject: user@domain\.com + - certSubject: otheruser@domain\.com + issuers: + - https://accounts\.google\.com + - https://github\.com/login + - certSubject: https://github\.com/actions/starter-workflows/blob/main/\.github/workflows/lint\.yaml@.* + issuers: + - https://token\.actions\.githubusercontent\.com + subjects: + - subject@domain\.com + fingerprints: + - A0B1C2D3E4F5 + fulcioExtensions: + build-config-uri: + - https://example.com/owner/repository/build-config.yml + customExtensions: + - objectIdentifier: 1.3.6.1.4.1.57264.1.9 + extensionValues: https://github.com/slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v1.4.0 +``` + ## Security Please report any vulnerabilities following Sigstore's [security process](https://github.com/sigstore/.github/blob/main/SECURITY.md). diff --git a/cmd/ct_monitor/main.go b/cmd/ct_monitor/main.go index c42f8e02..2f0afffd 100644 --- a/cmd/ct_monitor/main.go +++ b/cmd/ct_monitor/main.go @@ -138,11 +138,19 @@ func main() { } if identity.MonitoredValuesExist(monitoredValues) { - _, err = ct.IdentitySearch(fulcioClient, *config.StartIndex, *config.EndIndex, monitoredValues) + foundEntries, err := ct.IdentitySearch(fulcioClient, *config.StartIndex, *config.EndIndex, monitoredValues) if err != nil { fmt.Fprintf(os.Stderr, "failed to successfully complete identity search: %v", err) return } + + notificationPool := notifications.CreateNotificationPool(config) + + err = notifications.TriggerNotifications(notificationPool, foundEntries) + if err != nil { + // continue running consistency check if notifications fail to trigger + fmt.Fprintf(os.Stderr, "failed to trigger notifications: %v", err) + } } if *once || inputEndIndex != nil { @@ -152,5 +160,4 @@ func main() { config.StartIndex = config.EndIndex config.EndIndex = nil } - } diff --git a/pkg/ct/monitor.go b/pkg/ct/monitor.go index 71b6ccf4..0d359ffb 100644 --- a/pkg/ct/monitor.go +++ b/pkg/ct/monitor.go @@ -87,7 +87,7 @@ func MatchedIndices(logEntries []ct.LogEntry, mvs identity.MonitoredValues) ([]i return matchedEntries, nil } -func IdentitySearch(client *ctclient.LogClient, startIndex int, endIndex int, mvs identity.MonitoredValues) ([]identity.LogEntry, error) { +func IdentitySearch(client *ctclient.LogClient, startIndex int, endIndex int, mvs identity.MonitoredValues) ([]identity.MonitoredIdentity, error) { retrievedEntries, err := GetCTLogEntries(client, startIndex, endIndex) if err != nil { return nil, err @@ -96,5 +96,7 @@ func IdentitySearch(client *ctclient.LogClient, startIndex int, endIndex int, mv if err != nil { return nil, err } - return matchedEntries, nil + identities := identity.CreateIdentitiesList(mvs) + monitoredIdentities := identity.CreateMonitoredIdentities(matchedEntries, identities) + return monitoredIdentities, nil }