One frequent problem we all struggle with is the propagation of persisted secrets. Whether it is a database password or a credential to update our source repositories, we try to minimize the number of spread-out secrets we must track and manage.
The common term often used is "blast radius." Blast radius speaks to the size of the problem - all the areas possibly affected - should a particular secret be exposed. Additionally, as anyone who has used a computer in the last decade knows, the longevity of the secret has just as big an impact. Examples we can readily think about are compromised passwords in online apps or dealing with a credit card leak from a major vendor.
OAuth and OIDC
To help alleviate some of these issues around propagation, duration, and blast radius, we can consider using a short-term key exchange we pre-authorize. This federated system, based on OAuth, is called OpenID Connect and has been around for a while.
OIDC is a simple identity layer built as an authentication protocol on the OAuth 2.0 framework. It uses JSON Web Tokens (JWT) to transmit information. It took off in 2008 after the adoption by Yahoo! and Myspace. OpenID is just focused on authentication (AuthN) and has no opinion on authorization (AuthZ). That is, it is designed to reliably identify an identity, but not make decisions on what that identity can or cannot do.
OIDC is used throughout the web. You will likely use it when you use "Log on with…" and a favorite identity provider (IdP) like Google, Facebook, or GitHub. In our case, we are going to use it to solve the big issue of authentication ephemeral CICD pipelines to our cloud provider.
We could use a plethora of CICD frameworks and cloud providers, but today we will keep this simple by leveraging two of our favorites; GitHub Workflows and Google Cloud (GCP).
GCP Steps
The first thing we'll need in GCP is a service account.
Then we need a workload identity pool and a pool provider
Before we use the SA in any way, we need to say what things the account will be able to do.
For instance, we may desire this SA to access GCP Secrets Manager.
I'll first create a secret by hand. I'll create "mytestsecret" and add a new secret version (the value for the secret).
Next, for the service account we created, let's update it to be able to see secrets —specifically the secret versions on the "mytestsecret" secret:
At this point we have a service account, role, and a workload identity pool - but they are not yet connected. We'll want to bind the SA with a role to the workload identity pool by way of an IAM policy binding. This then ties it to an approved GitHub path, in our case "/idjohnson/secretAccessor"
Implementing a GitHub Workflow
With the binding in place, we can now use it in a basic OIDC Github action workflow:
Here we leverage the google-GitHub-actions auth block to specify a workload identity provider to use.
Because this project lives in "/idjohnson/secretAccessor" in GitHub, it is "pre-authorized.". In other words, should you copy and paste the above yaml into your GitHub project, it would call out to GCP from your path and be denied access to that 'mytestsecret.'.
Seeing in Action
If we look in the GitHub Action, we can see the Base64 output of the secret:
We can easily translate that to its plain text using Windows Powershell:
or BASH
This proves our end-to-end access of GCP secrets using federated OIDC authentication between Github and GCP.
The use of OIDC enables common CICD tooling like GitHub, Azure DevOps, and Gitlab to federate to any leading cloud provider in a scalable effortless way and avoid the problems associated with managing persisted secrets.
Here, at WellSky Engineering, we are always looking to further enhance the security posture of our tooling and improve our CICD flows. Thanks for joining us today in this OIDC implementation example!