☝️ Context
Docker image security is an ever increasing trend. But more than a trend, not achieving a proper pipeline around images security can lead to disasters.
To achieve that we adopted the following strategy :
- Rely on highly securely maintained images
- Paying attention to dependency management
Dependency management is managed thanks to DependaBot, and it'as available almost "Out of the Box".
For docker imaged there is some more work.
👉 In this short post you'll see how we implemented a repo-centric and CI driven efficient approach.
📝 Implementation
For docker image scan, we rely on the Container Scan (GitHub Action) maintained by Anchore.
Then we wrapped some CI around it so we can monitor security as part of our daily activities.
⏰ Schedule scans
First, we have scheduled scans. Below our code to scan the latest
tag :
name: 🛡️ Scan Docker image latest 🐳
on:
schedule: ## Schedule the job to run at a particular time.
- cron: '0 1 * * 1' ## every monday at 1:00AM
💥 Use severity-cutoff
Next, we need our scheduled task to fail if a critical vulnerability has been discovered.
Find below severity-cutoff
implementation :
jobs:
scan:
name: 🛡️ Scan image latest
runs-on: ubuntu-latest
steps:
- uses: anchore/scan-action@v3
id: scan
with:
image: optnc/domaine-nc-api:latest
fail-build: true
severity-cutoff: critical
🎫 Create (or update) issue
Next we want to create an issue in case of Scan Action failure (meaning that a critical
security issue has been found).
What we want is to get properly tagged issues so we can manage them as part of our daily tasks and produce reporting.
Therefore we :
- Setup some labels (so it makes filtering easier), eg :
security
,docker-scan'
- Get the ref to the latest opened issue that matches these specific label so issues are updated instead of getting tons of issues targetting the same issue everyday
- Get the scan report and put it in the issue so all elements are available at a single place
Find the code below :
- name: Create/Update an issue of vulnerabilities 🛡️ that have been detected
if: ${{ failure() }}
uses: actions/github-script@v6
with:
debug: true
script: |
const { owner, repo } = context.repo;
const labels = ['security', 'docker-scan', 'Alert : Docker image scan'];
// récupération de l'id de la dernière issue (si existante)
const existingIssue = (await github.paginate(github.rest.issues.listForRepo.endpoint.merge({
owner, repo, state: 'open',labels
}))).filter(i => i.title.indexOf('Docker image security scan') !== -1)[0];
// création ou modification de l'issue
const body = `Workflow failed for commit ${{github.sha}}.
Following vulnerabilities have been detected :
\`\`\`
${{ steps.scan_report.outputs.report }}
\`\`\`
`;
if (existingIssue) {
github.rest.issues.update({ owner, repo, issue_number: existingIssue.number, body });
} else {
github.rest.issues.create({
owner, repo,
title : '🛡️ Docker image security scan failed 🛡️',
body,
labels
});
}
👮 Enjoy a clean issue
Then you are setup to get very useful issue from your CI :
🎀 Bonus
Pay good attention to the fact that issue is related to commit which is really useful to follow how the security flaw may have been introduced too :