Anchore is a Container Image scanning tool that is used to validate the security of containers deployed for applications. I recently undertook an effort to build a custom Azure DevOps task to enable integration with this tool; nothing previously existed.
To get a feel for how this process works, this is a high level diagram of the underlying steps:
Under the covers we contact the given Anchore Engine server after adding out built image to an accessible registry. This contact exists as a polling operation which waits for the status to change.
For my approach, I elected to standup an Ubuntu VM in the Azure cloud and opt to run the server using docker-compose. The steps to this are here: https://docs.anchore.com/current/docs/engine/engine_installation/docker_compose. Despite being listed in the Enterprise documentation (the pay for version of Anchore, it does work for the OSS version).
Setup can take a few minutes once started since the engine needs to download information necessary to carry out scanning related functions. This actually makes it a bit faster since the information will be cached ahead of your scan requests.
Once that is complete you need to add a user. This is done as part of an account. When you perform commands against the API and give this username and password, the information is stored relative to that account. Meaning two accounts do not share things like images or registered registries.
Next, we need to register our registry, though I am not certain if you need to this if using a public repository on Docker Hub – for my purpose I am using Azure Container Registry (ACR). When the ACR is created you will need to enable admin mode to have ACR generate a username and password that can be used to access.
Once you have established these values, you simply need to register the registry using the registry add command:
anchore-cli –u someUser –p somePass –url someUrl registry add SomeAcrLoginServer SomeAcrUsername SomeAcrPassword
With this, our Anchore Engine is set to go.
I have noticed that if the engine is kept idle for a period of time, it will stop analyzing incoming images. You need only stop and start using docker-compose. Not entirely sure why this is happening
Using the Anchore Task
The task is available, publicly, here: https://marketplace.visualstudio.com/items?itemName=Farrellsoft.anchore-task
The task contains a full listing of the various properties that are currently available; it pales in comparison to the full functionality offered by Anchore Engine, but more functionality will be added over time.
In terms of the flow you should be thinking about, here is a diagram that lays out how I see it working:
One of the key things to note here is the “double push” of the image. We do this because we would want to segregate images created with each build with those that are suitable to move on the higher environments. Also, in the event of a rollback, we would want Ops to have to figure out which images passed the check and which ones did not.
We also do it because Anchore needs to be able to grab the image for scanning and will not be able to access it on our build agent.
Previous to the steps above you might choose to run unit tests on the artifact before it goes into the image. You could also choose to run your unit tests within the container to guarantee your assumptions within the actual execution environment.
I set up the Anchore Task to only make 100 attempts to check for status change, with a 5s wait between each attempt. In the event the Anchore Engine server is experiencing problems, I would rather the build fail than it enter an endless looping state. In the future, I intend to make this a configurable flag.
As I am writing this, we are still in the early days of the extension and there will no doubt be more features added. My main focus with this post was to cover setup and general usage.