As you deploy Endor Labs in your environment, it’s important for your team to understand key scanning strategies.
Set a default branch
The findings, metrics, and data shown on the dashboard and the project listing page are based on scanning the default branch, which is also known as the main context.
Important recommendation
If you are scanning multiple branches, it is essential to select and set one as the default branch. When performing the endorctl scan, use the flag--as-default-branch
to designate a project branch as the default branch and view its findings.
endorctl scan --as-default-branch
If you do not set the flag as-default-branch
, the first branch you scan is automatically considered as the default branch.
After a scan, if you switch the default branch to another using --as-default-branch
, scans from the previous branches are erased, and their findings will no longer be available.
You do not need to set a default branch if you are using the Endor Labs GitHub App or not scanning multiple branches.
Testing and monitoring different versions of your code
Across the software engineering lifecycle its important that continuous testing is separated from what is monitored and reported on regularly. Often, engineering organizations want to test each and every change that enters a code base, but if security teams reported on each test they would quickly find themselves overwhelmed with noise. Endor Labs enables teams to separate what should be reported on relative to what should be tested but not reported on. Endor Labs allows teams to select reporting strategies for their software applications when integrated into CI/CD pipelines.
Here are the primary scanning and reporting strategies:
- Reporting on the default branch - All pull request commits are tested and all pushes or merges to the default branch are reported on and monitored by security and management teams.
- Reporting on the latest release - All reporting and monitoring is performed against tagged release versions. This requires each team have a mature release tagging strategy.
How to deploy a strategy for reporting
The endorctl scan
command by default will continuously monitor a version of your code for new findings such as unmaintained, outdated or vulnerable dependencies in the bill of materials for a package. To test a version of your code without monitoring and reporting on it, use the flag --pr
or environment variable ENDOR_SCAN_PR
as part of your scan.
When adopting a strategy such as reporting on the default branch, you will want to run any push or merge event to the default branch without the --pr
flag and run any pull_request or merged_request event with the --pr
flag. This allows you to test changes before they have been approved and report what has been merged to the default branch as your closest proxy to what is in production.
Lets use the following GitHub actions workflow as an example! In this workflow any push event will be scanned without the --pr
flag but any pull_request event is scanned as a point in time test of that specific version of your code.
name: Endor Labs Scan
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
scan:
permissions:
security-events: write # Used to upload sarif artifact to GitHub
contents: read # Used to check out a private repository but actions/checkout.
actions: read # Required for private repositories to upload sarif files. GitHub Advanced Security licenses are required.
id-token: write # Used for keyless authentication to Endor Labs
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v3
- name: Setup Java
uses: actions/setup-java@v3
with:
distribution: 'microsoft'
java-version: '17'
- name: Build Package
run: mvn clean install
- name: Endor Labs Scan Pull Request
if: github.event_name == 'pull_request'
uses: endorlabs/github-action@v1.1.1
with:
namespace: 'example'
pr: true
sarif_file: 'findings.sarif'
pr_baseline: $GITHUB_BASE_REF
- name: Endor Labs Reporting Scan
if: github.event_name == 'push'
uses: endorlabs/github-action@v1.1.1
with:
namespace: 'example'
pr: false
sarif_file: 'findings.sarif'
- name: Endor Labs Testing Scan
if: github.event_name == 'pull_request'
uses: endorlabs/github-action@v1.1.1
with:
namespace: 'example'
pr: true
sarif_file: 'findings.sarif'
- name: Upload findings to github
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: 'findings.sarif'
Scanning detached refs
In some CI/CD based environments, each time code is pushed to the default branch the exact commit SHA is checked out as a detached Git Reference. This is notably the case with Jenkins, CircleCI and GitLab Pipelines.
In these scenarios, on push or merge events Endor Labs must be told that the reference should be monitored as the default branch. You can do this with the --detached-ref-name
flag or ENDOR_SCAN_DETACHED_REF_NAME
environment variable. You should also couple this flag with the --as-default-branch
flag or ENDOR_SCAN_AS_DEFAULT_BRANCH
environment variable. This allows you to set this version of code as a version that should be monitored as well as define the name associated with the branch.
This strategy may be used for both a strategy reporting on the default branch on push events and a strategy reporting on tag creation event for that version of code.
You can see in the below GitLab Pipelines example defining the logic to manage a detached reference on GitLab.
- if [ "$CI_COMMIT_REF_NAME" == "$CI_DEFAULT_BRANCH" ]; then
export ENDOR_SCAN_AS_DEFAULT_BRANCH=true;
export ENDOR_SCAN_DETACHED_REF_NAME="$CI_COMMIT_REF_NAME";
else
export ENDOR_SCAN_PR=true;
fi
You can find the full GitLab pipelines reference below:
Endor Labs Dependency Scan:
stage: Scan
image: node # Modify this image to align with the build tools nessesary to build your software packages
dependencies: []
variables:
ENDOR_ENABLED: "true"
ENDOR_ALLOW_FAILURE: "true"
ENDOR_NAMESPACE: "demo"
ENDOR_PROJECT_DIR: "."
ENDOR_ARGS: |
--path=${ENDOR_PROJECT_DIR}
--show-progress=false
--detached-ref-name=$CI_COMMIT_REF_NAME
--output-type=summary
--exit-on-policy-warning
--dependencies --secrets --git-logs
before_script:
- npm install yarn
script:
- curl https://api.endorlabs.com/download/latest/endorctl_linux_amd64 -o endorctl;
- echo "$(curl -s https://api.endorlabs.com/sha/latest/endorctl_linux_amd64) endorctl" | sha256sum -c;
if [ $? -ne 0 ]; then
echo "Integrity check failed";
exit 1;
fi
- chmod +x ./endorctl
- if [ "$DEBUG" == "true" ]; then
export ENDOR_LOG_VERBOSE=true;
export ENDOR_LOG_LEVEL=debug;
fi
- if [ "$CI_COMMIT_REF_NAME" == "$CI_DEFAULT_BRANCH" ]; then
export ENDOR_SCAN_AS_DEFAULT_BRANCH=true;
export ENDOR_SCAN_DETACHED_REF_NAME="$CI_COMMIT_REF_NAME";
else
export ENDOR_SCAN_PR=true;
fi
- ./endorctl scan ${ENDOR_ARGS}
rules:
- if: $ENDOR_ENABLED != "true"
when: never
- if: $CI_COMMIT_TAG
when: never
- if: $CI_COMMIT_REF_NAME != $CI_DEFAULT_BRANCH && $ENDOR_FEATURE_BRANCH_ENABLED != "true"
when: never
- if: $ENDOR_ALLOW_FAILURE == "true"
allow_failure: true
- if: $ENDOR_ALLOW_FAILURE != "true"
allow_failure: false
Implementing baseline scans
One of the common concerns software development teams have when adopting preventative controls is ownership of issues. Often, software has accrued significant technical debt, or new vulnerabilities arise that don’t directly impact their changes. Security teams want to have all known issues addressed while the development teams are focused on fixing issues or delivering core business value. They can’t be hindered each time a new issue impacts their entire code base.
To prevent new issues from entering the environment, security teams sometimes set policies that may break the build or return a non-zero exit code that can fail automated tests. This creates friction as there is no context around what changes a developer is responsible for versus what technical debt exists in a codebase on that day.
Establishing a baseline of what issues already exist in a software project and what issues may occur because of new updates is crucial to enabling preventative control adoption.
Accelerating preventative control adoption with CI baselines
The high-level steps to establish and measure policies against a baseline scan are as follows:
- Establish a baseline scan of your default branch or any other branch that undergoes regular testing
- Integrate baseline scans into your automated workflows
- Evaluate policy violations within the context of the branches to which you routinely merge
Implementing baseline scan into your program
Development teams often have different delivery strategies. Some merge changes to a default branch. Others merge to a release branch that is then released to their environment. While these strategies differ across organizations, a baseline scan must exist to measure against attribute ownership.
To establish a baseline scan, your team must perform regular scans on the branch to which you merge. This often means that you scan each push of your default branch to monitor your environment and you test each pull request using the --pr
and --pr-baseline
flags.
The --pr
flag is a user’s declaration that they are testing their code as they would in a CI pipeline. The --pr-baseline
flag tells Endor Labs which Git reference to measure any changes.
For this example, we will use the default branch as a merging strategy. In this strategy, you’ll want to scan the default branch on each push event to re-establish your baseline. You’ll also want to establish your CI baseline as the default branch.
The following GitHub workflow illustrates this strategy:
- See the GitHub Actions documentation for GitHub default variables.
- See the GitLab CI/CD documentation for the GitLab default variables.
name: Endor Labs Scan
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
scan:
permissions:
security-events: write # Used to upload sarif artifact to GitHub
contents: read # Used to check out a private repository but actions/checkout.
actions: read # Required for private repositories to upload sarif files. GitHub Advanced Security licenses are required.
id-token: write # Used for keyless authentication to Endor Labs
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v3
- name: Setup Java
uses: actions/setup-java@v3
with:
distribution: 'microsoft'
java-version: '17'
- name: Build Package
run: mvn clean install
- name: Endor Labs Scan Pull Request
if: github.event_name == 'pull_request'
uses: endorlabs/github-action@v1.1.1
with:
namespace: 'example'
pr: true
sarif_file: 'findings.sarif'
pr_baseline: $GITHUB_BASE_REF
- name: Endor Labs Reporting Scan
if: github.event_name == 'push'
uses: endorlabs/github-action@v1.1.1
with:
namespace: 'example'
pr: false
sarif_file: 'findings.sarif'
- name: Endor Labs Testing Scan
if: github.event_name == 'pull_request'
uses: endorlabs/github-action@v1.1.1
with:
namespace: 'example'
pr: true
sarif_file: 'findings.sarif'
- name: Upload findings to github
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: 'findings.sarif'