GitHub Advanced Security now supports the ability to analyze your code for vulnerabilities from third-party CI pipelines, while previously, instead, this capability was available exclusively with GitHub Actions.
In this post (and video) I will show you how to use Code Scanning to scan a GitHub Repository from an Azure DevOps pipeline using the YAML editor.
Alright, as I've mentioned before, rather than leveraging the native GitHub Actions workflow with the standard “Set Up Workflow” experience, today we are going to use an Azure DevOps Pipeline to scan the Code we have in our GitHub repo.
Let's take a look at the steps we would need to perform to integrate GitHub Advanced Security for Code Scanning with Azure DevOps:
Since the Azure Pipelines Agent I am using is ephemeral, because I'm using the Hosted Agents, I'll have to install the CodeQL package on each pipeline execution. If you are using a self-hosted agent instead consider pre-installing the package to save time and compute resources.
As usual, if you are a visual learner, or simply prefer to watch and listen instead of reading, here you have the video with the whole explanation and demo, which to be fair is much more complete than this post.
If you rather prefer reading, well... let's just continue :)
First thing we have to do, as we have seen in the list of steps, is to Download the latest CodeQL dependencies on my agent.
- script: | wget https://github.com/github/codeql-action/releases/latest/download/codeql-runner-linux chmod +x codeql-runner-linux displayName: 'Get latest CodeQL package. Install on Agent.'
Since this Pipeline runs on Linux, using wget and targeting the latest Linux release I can download all necessary files to my directory. I also change permissions for the downloaded file before I run it.
Next, we need to give that pipeline full access to our repo. To do so, we need to create a GitHub Personal Access Token. (see how).
For private repositories the token must have the whole
reposcope. For public repos, instead, the token needs only the
Then we need to save the PAT as a variable in the Pipeline. Remember to set it as a secret. For security sake, I'd recommend you using Azure KeyVault, save the PAT there and reference it into Azure Pipelines.
Now that we have the GitHub Personal Access Token saved in Azure Pipelines, we can initialize CodeQL.
Let's initialize the CodeQL Executable and create a CodeQL database for the language detected.
Once again we need to add a script step to our workflow:
- script: | ./codeql-runner-linux init \ --repository YOUR_REPO_NAME \ --github-url https://github.com \ --github-auth $GITHUB_PAT \ --config-file .github/codeql/codeql-config.yml displayName: 'Initialize CodeQL Executable and create a CodeQL database'
YOUR_REPO_NAME placeholder with the whole name of the repo you want to scan, for example "n3wt0n/myrepo"
$GITHUB_PAT is the name of the variable where I've saved the PAT.
If you want to analyze a compiled language like .Net, Java and so on, remember to execute the build AFTER the CodeQL Init step but BEFORE the Analyze step.
In fact the init step will create a script for you that you have to execute before building your code in order for CodeQL to be able to monitor the build as well.
Finally, I want to populate the CodeQL runner databases, analyze them, and upload the results to GitHub.
Let's add the final script
- script: | ./codeql-runner-linux analyze \ --repository YOUR_REPO_NAME \ --github-url https://github.com \ --github-auth $GITHUB_PAT \ --commit $(Build.SourceVersion) \ --ref $(Build.SourceBranch) displayName: 'Populate the CodeQL runner databases, analyze them, and upload the results to GitHub.'
Once again, replace the
YOUR_REPO_NAME placeholder with the whole name of the repo you want to scan.
Here we also have 2 more parameters:
- --commit: this is the SHA of the commit you want to scan
- --ref: this is the fully qualified ref name of the branch you want to scan (i.e. refs/heads/master)
In my case I retrieve both parameters from variables, which is an approach I would recommend.
And that is basically it.
You can now run the Pipelines and, if successful, you should be able to navigate back to your GitHub repository security tab under code scanning to view the results of your scan.
Let me know in the comment section below what you think about this experience. For me, it would of course be even better if we could have native Azure Pipelines tasks instead of having to write shell scripts, but for the time being this work pretty well as well.