-
Notifications
You must be signed in to change notification settings - Fork 0
[codex] Add nightly security sweep #195
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,250 @@ | ||
| name: Nightly Security | ||
|
|
||
| on: | ||
| schedule: | ||
| - cron: "41 2 * * *" | ||
| workflow_dispatch: | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| env: | ||
| CARGO_FUZZ_VERSION: "0.13.2" | ||
| CARGO_TERM_COLOR: always | ||
|
|
||
| jobs: | ||
| changes: | ||
| name: Changed security surfaces | ||
| runs-on: ubuntu-24.04 | ||
| outputs: | ||
| run: ${{ steps.classify.outputs.run }} | ||
| head_sha: ${{ steps.classify.outputs.head_sha }} | ||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 | ||
| with: | ||
| fetch-depth: 0 | ||
| persist-credentials: false | ||
| submodules: false | ||
|
|
||
| - name: Restore last successful nightly state | ||
| uses: actions/cache/restore@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4 | ||
| with: | ||
| path: .nightly-security-state | ||
| key: nightly-security-state-${{ github.run_id }}-${{ github.run_attempt }} | ||
| restore-keys: | | ||
| nightly-security-state- | ||
|
|
||
| - name: Classify changed paths | ||
| id: classify | ||
| shell: bash | ||
| run: | | ||
| set -euo pipefail | ||
|
|
||
| head_sha="$(git rev-parse HEAD)" | ||
| run=false | ||
|
|
||
| changed_files="${RUNNER_TEMP}/registry-stack-nightly-security-files" | ||
| : > "${changed_files}" | ||
|
|
||
| is_relevant_path() { | ||
| local path="$1" | ||
| case "${path}" in | ||
| .github/workflows/*|.github/dependabot.yml) | ||
| return 0 | ||
| ;; | ||
| Cargo.toml|Cargo.lock|deny.toml|rust-toolchain*) | ||
| return 0 | ||
| ;; | ||
| crates/registry-relay/*|crates/registry-notary*/*) | ||
| return 0 | ||
| ;; | ||
| crates/registry-platform-authcommon/*|crates/registry-platform-crypto/*) | ||
| return 0 | ||
| ;; | ||
| crates/registry-platform-oid4vci/*|crates/registry-platform-sdjwt/*) | ||
| return 0 | ||
| ;; | ||
| products/notary/*|products/platform/*|release/docker/*) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When the only relevant change is under Useful? React with 👍 / 👎. |
||
| return 0 | ||
| ;; | ||
| *) | ||
| return 1 | ||
| ;; | ||
| esac | ||
| } | ||
|
|
||
| if [[ "${GITHUB_EVENT_NAME}" == "workflow_dispatch" ]]; then | ||
| run=true | ||
| elif [[ ! -f .nightly-security-state/last-success-sha ]]; then | ||
| run=true | ||
| else | ||
| base_sha="$(tr -d '[:space:]' < .nightly-security-state/last-success-sha)" | ||
| if [[ -z "${base_sha}" ]] || | ||
| ! git cat-file -e "${base_sha}^{commit}" 2>/dev/null; then | ||
| run=true | ||
| elif [[ "${base_sha}" != "${head_sha}" ]]; then | ||
| git diff --name-only -z "${base_sha}" "${head_sha}" > "${changed_files}" | ||
| while IFS= read -r -d '' path; do | ||
| if is_relevant_path "${path}"; then | ||
| run=true | ||
| break | ||
| fi | ||
| done < "${changed_files}" | ||
| fi | ||
| fi | ||
|
|
||
| { | ||
| echo "run=${run}" | ||
| echo "head_sha=${head_sha}" | ||
| } >> "${GITHUB_OUTPUT}" | ||
|
|
||
| assurance: | ||
| name: Security assurance manifests | ||
| needs: changes | ||
| if: needs.changes.outputs.run == 'true' | ||
| runs-on: ubuntu-24.04 | ||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 | ||
| with: | ||
| persist-credentials: false | ||
| submodules: false | ||
|
|
||
| - name: Test assurance ratchets | ||
| run: | | ||
| python3 -m unittest \ | ||
| crates/registry-relay/tests/security_assurance_check_test.py \ | ||
| crates/registry-relay/tests/advisory_baseline_check_test.py \ | ||
| products/notary/tests/security_assurance_check_test.py \ | ||
| products/notary/tests/advisory_baseline_check_test.py | ||
|
|
||
| - name: Relay exposure and container checks | ||
| working-directory: crates/registry-relay | ||
| run: | | ||
| python3 scripts/check_security_assurance.py manifest | ||
| python3 scripts/check_security_assurance.py dockerfile-secrets | ||
|
|
||
| - name: Notary container and OpenAPI checks | ||
| working-directory: products/notary | ||
| run: | | ||
| python3 scripts/check_security_assurance.py dockerfile-secrets | ||
| python3 scripts/check_security_assurance.py openapi-baseline | ||
|
|
||
| notary-fuzz: | ||
| name: Notary fuzz smoke | ||
| needs: changes | ||
| if: needs.changes.outputs.run == 'true' | ||
| runs-on: ubuntu-24.04 | ||
| timeout-minutes: 45 | ||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 | ||
| with: | ||
| persist-credentials: false | ||
| submodules: false | ||
|
|
||
| - name: Install Rust nightly | ||
| uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # nightly | ||
| with: | ||
| toolchain: nightly | ||
|
|
||
| - name: Cache Cargo registry and build artifacts | ||
| uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2 | ||
|
|
||
| - name: Install cargo-fuzz | ||
| uses: taiki-e/install-action@25435dc8dd3baed7417e0c96d3fe89013a5b2e09 # v2.81.3 | ||
| with: | ||
| tool: cargo-fuzz@${{ env.CARGO_FUZZ_VERSION }} | ||
|
|
||
| - name: Run request parser fuzz smoke | ||
| working-directory: products/notary | ||
| run: | | ||
| set -euo pipefail | ||
| mkdir -p fuzz/artifacts/core_request_bodies | ||
| cargo +nightly fuzz run --fuzz-dir fuzz --target x86_64-unknown-linux-gnu core_request_bodies -- \ | ||
| -max_total_time=120 \ | ||
| -rss_limit_mb=1024 \ | ||
| -artifact_prefix=fuzz/artifacts/core_request_bodies/ \ | ||
| -print_final_stats=1 | ||
|
|
||
| - name: Upload notary fuzz artifacts | ||
| if: failure() | ||
| uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 | ||
| with: | ||
| name: nightly-notary-fuzz-artifacts | ||
| path: products/notary/fuzz/artifacts | ||
| if-no-files-found: ignore | ||
|
|
||
| platform-fuzz: | ||
| name: Platform fuzz smoke | ||
| needs: changes | ||
| if: needs.changes.outputs.run == 'true' | ||
| runs-on: ubuntu-24.04 | ||
| timeout-minutes: 60 | ||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 | ||
| with: | ||
| persist-credentials: false | ||
| submodules: false | ||
|
|
||
| - name: Install Rust nightly | ||
| uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # nightly | ||
| with: | ||
| toolchain: nightly | ||
|
|
||
| - name: Cache Cargo registry and build artifacts | ||
| uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2 | ||
|
|
||
| - name: Install cargo-fuzz | ||
| uses: taiki-e/install-action@25435dc8dd3baed7417e0c96d3fe89013a5b2e09 # v2.81.3 | ||
| with: | ||
| tool: cargo-fuzz@${{ env.CARGO_FUZZ_VERSION }} | ||
|
|
||
| - name: Run parser and credential fuzz smoke | ||
| working-directory: products/platform | ||
| run: | | ||
| set -euo pipefail | ||
| for target in \ | ||
| authcommon_parsers \ | ||
| oid4vci_request_and_proof \ | ||
| sdjwt_holder_proof \ | ||
| sdjwt_issuance | ||
| do | ||
| mkdir -p "fuzz/artifacts/${target}" | ||
| cargo +nightly fuzz run --fuzz-dir fuzz --target x86_64-unknown-linux-gnu "${target}" -- \ | ||
| -max_total_time=60 \ | ||
| -rss_limit_mb=1024 \ | ||
| -artifact_prefix="fuzz/artifacts/${target}/" \ | ||
| -print_final_stats=1 | ||
| done | ||
|
|
||
| - name: Upload platform fuzz artifacts | ||
| if: failure() | ||
| uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 | ||
| with: | ||
| name: nightly-platform-fuzz-artifacts | ||
| path: products/platform/fuzz/artifacts | ||
| if-no-files-found: ignore | ||
|
|
||
| save-state: | ||
| name: Save successful nightly state | ||
| needs: | ||
| - changes | ||
| - assurance | ||
| - notary-fuzz | ||
| - platform-fuzz | ||
| if: needs.changes.outputs.run == 'true' | ||
| runs-on: ubuntu-24.04 | ||
| steps: | ||
| - name: Write successful head | ||
| run: | | ||
| mkdir -p .nightly-security-state | ||
| printf '%s\n' "${{ needs.changes.outputs.head_sha }}" > .nightly-security-state/last-success-sha | ||
|
|
||
| - name: Save last successful nightly state | ||
| uses: actions/cache/save@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4 | ||
| with: | ||
| path: .nightly-security-state | ||
| key: nightly-security-state-${{ github.run_id }}-${{ github.run_attempt }} | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When a commit only touches
crates/registry-platform-replay/..., this classifier falls through and the nightly sweep is skipped, even thoughregistry-platform-oid4vcidepends on that crate for replay handling (crates/registry-platform-oid4vci/Cargo.toml:16) and both fuzz lockfiles pull it in (products/platform/fuzz/Cargo.lock:1018,products/notary/fuzz/Cargo.lock:1548). In that context replay-protection changes bypass the nightly OID4VCI/Notary fuzz smoke entirely, so addcrates/registry-platform-replay/*to the relevant path set.Useful? React with 👍 / 👎.