Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
195 changes: 195 additions & 0 deletions .github/workflows/bearer-diff.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
name: Bearer-CLI differential scan

on:
workflow_call:
inputs:
minimum_severity:
description: >-
Lowest severity to report.
required: false
type: string
default: high
enforce:
description: Fail this job when the scan reports new findings.
required: false
type: boolean
default: false
toolkit_repository:
description: Trusted repository containing the shared reporting script.
required: true
type: string
toolkit_ref:
description: Trusted ref containing the shared reporting script.
required: true
type: string

permissions:
contents: read

env:
BEARER_VERSION: "2.1.1"
BEARER_LINUX_AMD64_SHA256: "6b79d315577fea8305dfe08577bea6ad53852a929cd24de9211d39750a194bbb"

jobs:
scan:
name: Scan
runs-on: ubuntu-24.04
timeout-minutes: 30

steps:
- name: Validate trigger
shell: bash
run: |
set -euo pipefail

if [[ "${GITHUB_EVENT_NAME}" != "pull_request" ]]; then
echo "::error::This workflow must be called from a pull_request workflow."
exit 2
fi

- name: Resolve severity threshold
id: policy
shell: bash
env:
MINIMUM_SEVERITY: ${{ inputs.minimum_severity }}
run: |
set -euo pipefail

case "${MINIMUM_SEVERITY}" in
critical) severities="critical" ;;
high) severities="critical,high" ;;
medium) severities="critical,high,medium" ;;
low) severities="critical,high,medium,low" ;;
all) severities="critical,high,medium,low,warning" ;;
*)
echo "::error::minimum_severity must be critical, high, medium, low, or all."
exit 2
;;
esac

echo "severities=${severities}" >> "${GITHUB_OUTPUT}"

- name: Check out pull request head
uses: actions/checkout@v7.0.1
with:
fetch-depth: 0
persist-credentials: false
ref: ${{ github.event.pull_request.head.sha }}

- name: Flag Bearer-CLI configuration changes
shell: bash
env:
BASE_REF: ${{ github.base_ref }}
run: |
set -euo pipefail

range="origin/${BASE_REF}...HEAD"

if git diff --quiet "${range}" -- .bearer; then
echo "This pull request does not change the Bearer-CLI configuration."
exit 0
fi

{
echo "## Configuration changed"
echo
echo "**This pull request changes Bearer-CLI's own configuration.**"
echo
echo "These files control what gets scanned and ignored. Confirm the change is intended before approving."
echo
git diff --no-color "${range}" -- .bearer | sed 's/^/ /'
} >> "${GITHUB_STEP_SUMMARY}"

while IFS= read -r -d '' path; do
path="${path//%/%25}"
path="${path//$'\r'/%0D}"
path="${path//$'\n'/%0A}"
path="${path//:/%3A}"
path="${path//,/%2C}"

echo "::warning file=${path},line=1,title=Configuration changed::This file controls what Bearer-CLI scans and ignores. Confirm the change is intended before approving."
done < <(git diff --name-only -z "${range}" -- .bearer)

- name: Install Bearer-CLI
shell: bash
run: |
set -euo pipefail

bin_dir="${RUNNER_TEMP}/bearer-bin"
archive="${RUNNER_TEMP}/bearer.tar.gz"
mkdir -p "${bin_dir}"

curl --fail --silent --show-error --location --retry 3 --retry-all-errors \
"https://github.com/Bearer/bearer/releases/download/v${BEARER_VERSION}/bearer_${BEARER_VERSION}_linux_amd64.tar.gz" \
--output "${archive}"
printf '%s %s\n' "${BEARER_LINUX_AMD64_SHA256}" "${archive}" | sha256sum --check --strict -
tar -xzf "${archive}" -C "${bin_dir}" bearer

"${bin_dir}/bearer" version
echo "${bin_dir}" >> "${GITHUB_PATH}"

- name: Run Bearer-CLI
shell: bash
env:
BEARER_DIFF_BASE_BRANCH: ${{ github.base_ref }}
SEVERITIES: ${{ steps.policy.outputs.severities }}
run: |
set -euo pipefail

bearer scan . \
--diff \
--config-file=.bearer/bearer.yml \
--ignore-file=.bearer/bearer.ignore \
Comment thread
dockscp marked this conversation as resolved.
--scanner=sast,secrets \
--severity="${SEVERITIES}" \
--format=json \
--output="${RUNNER_TEMP}/bearer-results.json" \
--no-extract \
--hide-progress-bar \
--no-color \
--disable-domain-resolution \
--disable-version-check \
--exit-code=0

test -s "${RUNNER_TEMP}/bearer-results.json"

- name: Check out shared scripts
uses: actions/checkout@v7.0.1
with:
repository: ${{ inputs.toolkit_repository }}
ref: ${{ inputs.toolkit_ref }}
sparse-checkout: bearer/scripts
path: .bearer-toolkit
persist-credentials: false

- name: Publish pull request report
shell: bash
env:
ANNOTATION_LEVEL: ${{ inputs.enforce && 'error' || 'warning' }}
ENFORCE: ${{ inputs.enforce }}
MINIMUM_SEVERITY: ${{ inputs.minimum_severity }}
REPORT_FILE: ${{ runner.temp }}/bearer-results.json
SUMMARY_FILE: ${{ runner.temp }}/bearer-summary.md
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
run: |
set -euo pipefail

echo "::group::Bearer-CLI findings"
node "${GITHUB_WORKSPACE}/.bearer-toolkit/bearer/scripts/bearer-summary.mjs" \
"${REPORT_FILE}" \
"${SUMMARY_FILE}" \
"${MINIMUM_SEVERITY}" \
"${GITHUB_REPOSITORY}" \
"${HEAD_SHA}" \
"Bearer-CLI differential scan: findings introduced by this pull request"
echo "::endgroup::"

cat "${SUMMARY_FILE}" >> "${GITHUB_STEP_SUMMARY}"

finding_count="$(jq '[.critical, .high, .medium, .low, .warning] | map(length) | add' "${REPORT_FILE}")"
echo "Bearer-CLI reported ${finding_count} new findings at or above ${MINIMUM_SEVERITY}."

if [[ "${ENFORCE}" == "true" ]] && (( finding_count > 0 )); then
echo "::error::Bearer-CLI reported ${finding_count} new findings at or above ${MINIMUM_SEVERITY}. See the job summary, then fix or suppress them."
exit 1
fi
130 changes: 130 additions & 0 deletions .github/workflows/bearer-full.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
name: Bearer-CLI Full Scan

on:
workflow_call:
inputs:
minimum_severity:
description: Lowest severity to include in the scan.
required: false
type: string
default: high
toolkit_repository:
description: Trusted repository containing the shared reporting script.
required: true
type: string
toolkit_ref:
description: Trusted ref containing the shared reporting script.
required: true
type: string

permissions:
contents: read

env:
BEARER_VERSION: "2.1.1"
BEARER_LINUX_AMD64_SHA256: "6b79d315577fea8305dfe08577bea6ad53852a929cd24de9211d39750a194bbb"

jobs:
scan:
name: Full scan
runs-on: ubuntu-24.04
timeout-minutes: 30

steps:
- name: Resolve severity threshold
id: policy
shell: bash
env:
MINIMUM_SEVERITY: ${{ inputs.minimum_severity }}
run: |
set -euo pipefail

case "${MINIMUM_SEVERITY}" in
critical) severities="critical" ;;
high) severities="critical,high" ;;
medium) severities="critical,high,medium" ;;
low) severities="critical,high,medium,low" ;;
all) severities="critical,high,medium,low,warning" ;;
*)
echo "::error::minimum_severity must be critical, high, medium, low, or all."
exit 2
;;
esac

echo "severities=${severities}" >> "${GITHUB_OUTPUT}"

- name: Check out selected branch
uses: actions/checkout@v7.0.1
with:
fetch-depth: 1
persist-credentials: false

- name: Install Bearer-CLI
shell: bash
run: |
set -euo pipefail

bin_dir="${RUNNER_TEMP}/bearer-bin"
archive="${RUNNER_TEMP}/bearer.tar.gz"
mkdir -p "${bin_dir}"

curl --fail --silent --show-error --location --retry 3 --retry-all-errors \
"https://github.com/Bearer/bearer/releases/download/v${BEARER_VERSION}/bearer_${BEARER_VERSION}_linux_amd64.tar.gz" \
--output "${archive}"
printf '%s %s\n' "${BEARER_LINUX_AMD64_SHA256}" "${archive}" | sha256sum --check --strict -
tar -xzf "${archive}" -C "${bin_dir}" bearer

"${bin_dir}/bearer" version
echo "${bin_dir}" >> "${GITHUB_PATH}"

- name: Run Bearer-CLI
shell: bash
env:
SEVERITIES: ${{ steps.policy.outputs.severities }}
run: |
set -euo pipefail

bearer scan . \
--config-file=.bearer/bearer.yml \
--ignore-file=.bearer/bearer.ignore \
--scanner=sast,secrets \
--severity="${SEVERITIES}" \
--format=json \
--output="${RUNNER_TEMP}/bearer-results.json" \
--no-extract \
--hide-progress-bar \
--no-color \
--disable-domain-resolution \
--disable-version-check \
--exit-code=0

test -s "${RUNNER_TEMP}/bearer-results.json"

- name: Check out shared scripts
uses: actions/checkout@v7.0.1
with:
repository: ${{ inputs.toolkit_repository }}
ref: ${{ inputs.toolkit_ref }}
sparse-checkout: bearer/scripts
path: .bearer-toolkit
persist-credentials: false

- name: Write full scan report
shell: bash
env:
MINIMUM_SEVERITY: ${{ inputs.minimum_severity }}
REPORT_FILE: ${{ runner.temp }}/bearer-results.json
SUMMARY_FILE: ${{ runner.temp }}/bearer-summary.md
run: |
set -euo pipefail

echo "::group::Bearer-CLI findings"
node "${GITHUB_WORKSPACE}/.bearer-toolkit/bearer/scripts/bearer-summary.mjs" \
"${REPORT_FILE}" \
"${SUMMARY_FILE}" \
"${MINIMUM_SEVERITY}" \
"${GITHUB_REPOSITORY}" \
"${GITHUB_REF_NAME}"
echo "::endgroup::"

cat "${SUMMARY_FILE}" >> "${GITHUB_STEP_SUMMARY}"
10 changes: 8 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,8 @@
# engineering-toolkit
Shared development tooling, configurations, reusable GitHub workflows, and other engineering artifacts for repositories across the organization.
# Dock Engineering Toolkit

WIP.

## Guides

- [Bearer-CLI workflows](bearer/README.md)
- [Managing Semgrep findings](SEMGREP.md)
35 changes: 35 additions & 0 deletions SEMGREP.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Managing Semgrep findings

Handle Semgrep findings in the pull request where they appear.

## Choose the right outcome

- **Fix it** when the finding is valid.
- **False positive** only when Semgrep has misunderstood the code.
- **Acceptable risk** when the finding is valid but the risk is deliberately accepted.

For GitHub PR comments, reply to the Semgrep bot with:

```text
/fp <why Semgrep is wrong here>
/ar <why the risk is accepted; include a tracking issue>
/open
```

Avoid `/other` as it leaves little useful audit context.

Alternatively, in the Semgrep platform, filter **Findings** to your PR or branch, select the
finding, and use **Triage** to set the same status and explanation.

## Guardrails

- Always give a specific and sensible reason. For instance, a generic "Not exploitable" is not
enough without saying what prevents exploitation.
- Do not disable rules, add broad path exclusions, or change policies to resolve
one false positive.
- Try to avoid the use of `nosemgrep` for code-local suppression.

## References

- [Semgrep Platform Org Link](https://semgrep.dev/orgs/dock_labs)
- [Semgrep's finding triage documentation](https://semgrep.dev/docs/for-developers/resolve-findings-through-app)
Loading