|
| 1 | +name: Security |
| 2 | + |
| 3 | +# Socket Basics SAST / secret scanning for PUBLIC repositories. |
| 4 | +# |
| 5 | +# This file lives in the public Unstructured-IO/github-workflows-public repo so |
| 6 | +# that public repositories can consume it (public repos cannot reference |
| 7 | +# reusable/required workflows that live in a private or internal repo). It is |
| 8 | +# intended to be enforced org-wide on public repos via a repository ruleset |
| 9 | +# scoped to `visibility: public`. |
| 10 | +# |
| 11 | +# Posture: informational to start (continue-on-error), so it never blocks a PR. |
| 12 | +# Gating for real findings is governed by the Socket dashboard policy + the |
| 13 | +# native Socket GitHub App, not by this workflow. |
| 14 | + |
| 15 | +on: pull_request |
| 16 | + |
| 17 | +# Default-deny at the top level so any job added to this file in the future |
| 18 | +# must explicitly opt into the token scopes it needs. The scan job below |
| 19 | +# grants itself only `contents: read`. |
| 20 | +permissions: {} |
| 21 | + |
| 22 | +jobs: |
| 23 | + socket_basics: |
| 24 | + name: Socket Basics |
| 25 | + runs-on: ubuntu-latest |
| 26 | + permissions: |
| 27 | + contents: read |
| 28 | + steps: |
| 29 | + - name: checkout code |
| 30 | + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 |
| 31 | + |
| 32 | + - name: Run Socket Basics |
| 33 | + id: socket |
| 34 | + # Skip on fork PRs: forked pull requests do not receive repository or |
| 35 | + # organization secrets (GitHub withholds them to prevent exfiltration), |
| 36 | + # so PUBLIC_SOCKET_SECURITY_API_KEY would be empty and the scan could |
| 37 | + # not authenticate. Fork PRs are covered by the native Socket GitHub |
| 38 | + # App instead (server-side auth, no key in the Actions context). This |
| 39 | + # keeps the API key on trusted, same-repo events only. |
| 40 | + if: github.event.pull_request.head.repo.full_name == github.repository |
| 41 | + uses: SocketDev/socket-basics@6b71cdf3f792e1ba15b0c42133d8a6f29fb1fc4f # v3.0.0 |
| 42 | + continue-on-error: true |
| 43 | + env: |
| 44 | + GITHUB_PR_NUMBER: ${{ github.event.pull_request.number || github.event.issue.number }} |
| 45 | + with: |
| 46 | + github_token: ${{ secrets.GITHUB_TOKEN }} |
| 47 | + socket_security_api_key: ${{ secrets.PUBLIC_SOCKET_SECURITY_API_KEY }} |
| 48 | + |
| 49 | + - name: Log Socket Basics failure for audit |
| 50 | + if: steps.socket.outcome == 'failure' |
| 51 | + env: |
| 52 | + REPO: ${{ github.repository }} |
| 53 | + PR_NUMBER: ${{ github.event.pull_request.number }} |
| 54 | + PR_URL: ${{ github.event.pull_request.html_url }} |
| 55 | + ACTOR: ${{ github.actor }} |
| 56 | + HEAD_REF: ${{ github.head_ref }} |
| 57 | + HEAD_SHA: ${{ github.event.pull_request.head.sha }} |
| 58 | + RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}/attempts/${{ github.run_attempt }} |
| 59 | + run: | |
| 60 | + # Emits a workflow annotation + structured log line so the failure is |
| 61 | + # visible in the run summary and ingestible by enterprise audit log |
| 62 | + # consumers that scrape job logs. Untrusted fields (HEAD_REF, |
| 63 | + # PR_NUMBER, etc.) are bound via env: and printed with printf %s, so |
| 64 | + # they are never interpreted by the shell. Job stays green via |
| 65 | + # continue-on-error on the Socket step above. |
| 66 | + SHORT_SHA="${HEAD_SHA:0:12}" |
| 67 | + printf '::warning title=Socket Basics failed::repo=%s pr=%s actor=%s head_ref=%s sha=%s run=%s\n' \ |
| 68 | + "$REPO" "$PR_NUMBER" "$ACTOR" "$HEAD_REF" "$SHORT_SHA" "$RUN_URL" |
| 69 | + printf 'audit_event=socket_basics_failed repo=%s pr=%s pr_url=%s actor=%s head_ref=%s sha=%s run=%s\n' \ |
| 70 | + "$REPO" "$PR_NUMBER" "$PR_URL" "$ACTOR" "$HEAD_REF" "$SHORT_SHA" "$RUN_URL" |
0 commit comments