Flatcar Security Triage #31
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Flatcar Security Triage | |
| # Daily discovery + cleanup analysis using Microsoft Foundry through GitHub | |
| # OIDC. This workflow never mutates advisory issues directly: it only | |
| # produces diagnostic reports and creates human-gated review issue part(s). | |
| # Actual advisory mutations happen later, only when a maintainer closes a | |
| # review issue with reason "Completed" (see security-triage-apply.yml). | |
| # | |
| # Battle testing: SECURITY_TRIAGE_ADVISORY_REPO and SECURITY_TRIAGE_REVIEW_REPO | |
| # are both pinned to `${{ github.repository }}` (this repository). Moving this | |
| # workflow to the production repository later requires only configuration | |
| # changes, never business-logic changes -- see docs/github-actions-foundry-oidc.md. | |
| on: | |
| schedule: | |
| - cron: '0 6 * * 1-5' | |
| workflow_dispatch: | |
| concurrency: | |
| # Serialize daily runs so a new schedule tick can never race an | |
| # in-progress review-issue creation sequence; never cancel an in-flight | |
| # run partway through issue creation. | |
| group: security-triage-daily-analysis | |
| cancel-in-progress: false | |
| permissions: | |
| contents: read | |
| issues: write | |
| id-token: write | |
| env: | |
| # Pinned to this repository for battle testing. A future move to the | |
| # production repository changes only these two values. | |
| SECURITY_TRIAGE_ADVISORY_REPO: ${{ github.repository }} | |
| SECURITY_TRIAGE_REVIEW_REPO: ${{ github.repository }} | |
| jobs: | |
| daily-analysis: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.12' | |
| - name: Install | |
| run: python -m pip install -e '.[yaml]' | |
| - name: Restore prompt cache | |
| id: prompt-cache-restore | |
| uses: actions/cache/restore@v4 | |
| with: | |
| path: .prompt-cache | |
| key: flatcar-prompt-cache-${{ github.run_id }} | |
| restore-keys: | | |
| flatcar-prompt-cache- | |
| # Branch-bound OIDC federated login: no client secret is created or | |
| # stored. See docs/github-actions-foundry-oidc.md for one-time setup. | |
| - name: Azure login (OIDC) | |
| uses: azure/login@v2 | |
| with: | |
| client-id: ${{ vars.AZURE_CLIENT_ID }} | |
| tenant-id: ${{ vars.AZURE_TENANT_ID }} | |
| subscription-id: ${{ vars.AZURE_SUBSCRIPTION_ID }} | |
| # The runtime Foundry client never shells out to Azure CLI; this | |
| # workflow step is the only place that bridges the OIDC-authenticated | |
| # `az` session to a short-lived Cognitive Services bearer token. | |
| - name: Obtain Microsoft Foundry access token | |
| id: foundry-token | |
| run: | | |
| set -euo pipefail | |
| TOKEN=$(az account get-access-token --resource https://cognitiveservices.azure.com/ --query accessToken -o tsv) | |
| echo "::add-mask::$TOKEN" | |
| echo "token=$TOKEN" >> "$GITHUB_OUTPUT" | |
| # Read-only: discovery never writes advisory issues directly. | |
| # Output is consumed by `review create` for human-gated apply. | |
| - name: Discovery | |
| env: | |
| GITHUB_TOKEN: ${{ github.token }} | |
| FOUNDRY_BEARER_TOKEN: ${{ steps.foundry-token.outputs.token }} | |
| FOUNDRY_ENDPOINT: ${{ vars.FOUNDRY_ENDPOINT }} | |
| FOUNDRY_DEPLOYMENT: ${{ vars.FOUNDRY_DEPLOYMENT }} | |
| FOUNDRY_EXTRACTION_DEPLOYMENT: ${{ vars.FOUNDRY_EXTRACTION_DEPLOYMENT }} | |
| FOUNDRY_API_VERSION: ${{ vars.FOUNDRY_API_VERSION }} | |
| FLATCAR_PROMPT_CACHE_DIR: .prompt-cache | |
| run: | | |
| security-triage discovery \ | |
| --model foundry \ | |
| --advisory-repo "$SECURITY_TRIAGE_ADVISORY_REPO" \ | |
| --output reports/discovery.json \ | |
| --markdown-output reports/discovery.md \ | |
| --debug-log reports/discovery-debug.jsonl | |
| # Read-only: cleanup never writes advisory issues directly. | |
| # Output is consumed by `review create` for human-gated apply. | |
| - name: Cleanup | |
| env: | |
| GITHUB_TOKEN: ${{ github.token }} | |
| FOUNDRY_BEARER_TOKEN: ${{ steps.foundry-token.outputs.token }} | |
| FOUNDRY_ENDPOINT: ${{ vars.FOUNDRY_ENDPOINT }} | |
| FOUNDRY_DEPLOYMENT: ${{ vars.FOUNDRY_DEPLOYMENT }} | |
| FOUNDRY_EXTRACTION_DEPLOYMENT: ${{ vars.FOUNDRY_EXTRACTION_DEPLOYMENT }} | |
| FOUNDRY_API_VERSION: ${{ vars.FOUNDRY_API_VERSION }} | |
| FLATCAR_PROMPT_CACHE_DIR: .prompt-cache | |
| run: | | |
| security-triage cleanup \ | |
| --model foundry \ | |
| --advisory-repo "$SECURITY_TRIAGE_ADVISORY_REPO" \ | |
| --output reports/cleanup.json \ | |
| --markdown-output reports/cleanup.md \ | |
| --debug-log reports/cleanup-debug.jsonl | |
| - name: Save prompt cache | |
| if: always() | |
| uses: actions/cache/save@v4 | |
| with: | |
| path: .prompt-cache | |
| key: flatcar-prompt-cache-${{ github.run_id }} | |
| - name: Upload reports | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: security-triage-reports-${{ github.run_id }} | |
| path: reports/ | |
| # The only mutating step in this workflow: it creates (or, on a rerun | |
| # of the same run, idempotently finds) the human-gated review issue | |
| # part(s). It never mutates an advisory issue. | |
| - name: Create review issue(s) | |
| env: | |
| GITHUB_TOKEN: ${{ github.token }} | |
| run: | | |
| security-triage review create \ | |
| --discovery-json reports/discovery.json \ | |
| --cleanup-json reports/cleanup.json \ | |
| --advisory-repo "$SECURITY_TRIAGE_ADVISORY_REPO" \ | |
| --review-repo "$SECURITY_TRIAGE_REVIEW_REPO" \ | |
| --run-id "${{ github.run_id }}" \ | |
| --run-url "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" \ | |
| --commit-sha "${{ github.sha }}" \ | |
| --discovery-report-url "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" \ | |
| --output reports/review-create.json | |
| - name: Upload review creation summary | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: security-triage-review-create-${{ github.run_id }} | |
| path: reports/review-create.json |