VICTOR SZALVAY: I'm Victor Szalvay.
I'm an outbound product manager.
And I work on securely delivering applications
in Google Cloud.
Today I'm going to be walking through an end-to-end
development workflow with security capabilities provided
by Google Cloud, with the ultimate goal of strengthening
your software supply chain security.
So let's get started and take a look at the flow.
We're going to be going through a relatively typical
development workflow, which includes a developer checking
in, or doing a PR to a Git repository, which will then
trigger a CI process.
This builds a containerized application,
which pushes the image to artifact registry.
So artifact registry will actually use container analysis
to automatically scan for vulnerabilities in my image.
And I've configured my Cloud Build process
with a policy check step.
So this is based on open source credits.
And what it will do is ensure that my image meets
the requirements that have been set out before advancing
to the next step.
And if not, my build will fail.
Finally, we'll use Cloud Deploy to progress our image
into GKE environments.
In a controlled fashion, you can include
things like manual approval steps at key junctures
with Cloud Deploy.
But I've also enabled binary authorization
on this project to ensure that any deployed image, to GKE
or Cloud Run, meets policy requirements.
We'll talk about the specific policies I've set out
for this project in a moment.
So let's talk about the application itself.
Now, my application is a simple Python Flask-based application.
And I've containerized it with Docker.
I mentioned earlier that I'm going
to use Cloud Build to actually build and push
this application, at which point Artifact Registry will use
Container Analysis to automatically scan
my images for vulnerabilities.
Now, if those vulnerabilities exceed my policy requirements,
my build will fail.
So I'm going to be doing that based on a policy
that I've set out in this particular file.
So in this particular case, anything
that exceeds a medium severity, it
will basically fail my build.
Let's see an example where I build a known vulnerable image
before we go and actually look at my application.
And let's see how this works in a failure mode.
So I've got a Build file here that's going to be pulling
from my bad Docker file.
And my bad Docker file has an old Debian9 image, which
has some vulnerabilities in it.
So let's take a look at how that actually works.
And I'm going to go ahead and kick off the build.
So I can see that I've already got my build started here.
And we can actually take a look at the progress
as it goes through all of the steps.
OK, so you can see that my build actually
failed on this vuln sign step.
And this particular step, what it
does, as I mentioned earlier, it's a policy check.
So it checks to make sure that that policy file
that I mentioned earlier--
that the thresholds in it have not been exceeded.
And in this case, you can see that my medium medium policy
requirement was in place.
And we found actually nine violations within this image,
which is why it failed.
So let's take a look at this in Artifact analysis.
You can see that just a minute ago we
have an image built with a lot of vulnerabilities, including
12 high vulnerabilities.
But I also mentioned another layer of policy enforcement
with Binary Authorization.
So in this case, I have a relatively simple policy,
which I'm going to share.
In my Binary Authorization policy file,
I have two requirements that any image
must have in order to be deployed to my environments.
So the first is that the image must be built by Cloud Build.
So it has to be signed by the Cloud Build system
to note that we've used Cloud Build to build
this particular image.
And second, it has to pass my vulnerability policy
thresholds, which we just walked through.
Now, before we deploy our application,
let's, again, take a look at an example
where we try to deploy something that
does not conform to policy.
So in this case, I'm going to be attempting
to deploy a Nginx image.
And this particular image has not,
of course, gone through the various scrutiny that's
required.
And we're going to go ahead and try to deploy that and see
how that works.
All right, so now I can see that I'm waiting for this thing
to roll out.
But you notice that it has not actually rolled out.
And when I go into my workloads view within Kubernetes Engine,
and I refresh, I see that I actually
have here an error message that's
letting me know that this particular image was rejected
by Binary Authorization.
Now, it also specifies that it had no attestations, which
are assurances that this particular image was built
by Cloud Build, nor did it go through my vulnerability
checks.
So in a nutshell, Binary Authorization
provided admission control right before it went into production.
But now let's take a look at our application.
Let's take a look at the Cloud Build steps
that are going to take place here within our CI process,
within our Build process.
We're first going to build the Docker image, or the container
image.
We're then going to run some API tests.
We're then going to go ahead and push to Artifact Registry.
So build, run tests, push.
OK?
At that point, we're also going to be doing a vulnerability
analysis, just like we did in the last example
where it failed.
And finally, it's going to kick off
a deployment if that vulnerability scan
passes via Cloud Deploy.
And Cloud Deploy is going to progress it into the first test
environment.
Now, the other thing that I want to point out here
is that I'm also running this build within what's
called a private pool.
For added security, we've configured our Cloud Build job
to run in a private pool, which provides the ability
to peer into private networks.
It allows things like eliminating public internet
egress, if you choose.
You can run in a specific region.
You can also utilize a variety of machine-type configurations.
So you can really kind of tailor and customize
your Build environment.
I'm going to be triggering our application via a commit.
We'll commit it.
And now we'll push.
OK.
So the build is finished in just a couple of minutes.
And we can see that everything has passed.
Now I'm going to point out that vulnerability scanning
requirement.
And you can see that, in this case,
the same policy applied, the medium medium policy.
We can also see that we were able to pass that requirement.
So we were able to obtain the attestation, which is required
in Binary Authorization later.
It's also required to pass this particular Build step.
And see that on the vulnerability side,
there's only three mediums and zero highs.
So we've actually passed this particular check.
Now the other thing I can do here,
and [INAUDIBLE] talked about SALSA Level 2 compliance,
I can inspect the provenance of this particular artifact.
So SALSA Level 2 compliance hinges on signed provenance
of built artifacts.
Cloud Build automatically generates
and stores signed provenance for artifacts, which
we can inspect at any time.
Let's take a look at the artifact provenance
for this particular image that was just built.
And we can see here that the provenance is
stored in an in-toto format.
We can see the commit that triggered
this particular build.
We can see a lot of information, including all of the steps that
were actually run.
And you can see at the end that it also
has been signed by Cloud Build.
OK, so we can also now take a look
at Cloud Deploy, which likely has started rolling out
our application at this point.
And in fact, you can see that this was actually
just rolled out.
And if we go back to our workload screen and refresh it,
you'll see that the pop stats workload, the application
that we just deployed, was deployed OK,
in contrast to the Nginx we tried to deploy earlier.
So I hope this demonstration provided a useful view
into how Google Cloud's CI/CD artifact management and policy
enforcement measures can be used together to help secure
your software supply chain.
Thanks.