Handling secrets like API keys and database passwords is a critical aspect of any CI/CD pipeline. Storing these secrets as plaintext in your code or configuration files is a significant security risk. Google Cloud Secret Manager provides a secure and centralized way to manage your secrets. This blog post will guide you through integrating Secret Manager with Cloud Build to automate secret retrieval and usage in your deployments, following security best practices.
Why Use Secret Manager with Cloud Build?
- Enhanced Security: Secret Manager encrypts secrets at rest and in transit, providing a strong layer of security.
- Centralized Management: Manage all your secrets in one place, simplifying auditing and access control.
- Version Control: Secret Manager supports versioning, allowing you to roll back to previous versions if needed.
- Reduced Risk: Avoid exposing sensitive information in your codebase or CI/CD configuration files.
- Compliance: Helps meet compliance requirements by ensuring secrets are stored and accessed securely.
Prerequisites
Before you begin, make sure you have the following:
- A Google Cloud project with billing enabled.
- The Cloud SDK installed and configured.
- The Secret Manager API enabled in your project.
- The Cloud Build API enabled in your project.
- Sufficient IAM permissions to create and access secrets in Secret Manager and run Cloud Build jobs.
Step 1: Create a Secret in Secret Manager
-
Open Cloud Shell or your local terminal with the Cloud SDK configured.
-
Create a secret: Replace
<your-secret-name>
with a descriptive name for your secret.gcloud secrets create <your-secret-name> --replication-policy="automatic"
-
Add a secret version: Replace
<your-secret-name>
with the name you chose and<your-secret-value>
with the actual secret value. Be extremely careful not to expose this value.echo -n "<your-secret-value>" | gcloud secrets versions add <your-secret-name> --data-file=-
Step 2: Grant Cloud Build Access to the Secret
Cloud Build needs permission to access the secret. You can grant access by adding the Cloud Secret Manager Secret Accessor role to the Cloud Build service account.
-
Get the Cloud Build service account:
PROJECT_NUMBER=$(gcloud projects describe $(gcloud config get-value core/project) --format='value(projectNumber)') CLOUDBUILD_SA="${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com" echo $CLOUDBUILD_SA
-
Grant the Secret Manager Secret Accessor role: Replace
<your-secret-name>
with the name of your secret.gcloud secrets add-iam-policy-binding <your-secret-name> \ --member="serviceAccount:$CLOUDBUILD_SA" \ --role="roles/secretmanager.secretAccessor"
Step 3: Configure Cloud Build to Access the Secret
Now, you need to configure your cloudbuild.yaml
file to access the secret. Cloud Build provides the secrets
field in the build step to achieve this.
Here’s an example cloudbuild.yaml
file:
steps:
- name: 'ubuntu'
entrypoint: 'bash'
args:
- '-c'
- |
echo "My secret value is: $$MY_SECRET"
secretEnv: ['MY_SECRET']
availableSecrets:
secretManager:
MY_SECRET:
versionName: projects/$PROJECT_NUMBER/secrets/<your-secret-name>/versions/latest
Explanation:
steps
: Defines the build steps to be executed.name
: Specifies the container image to use for the step (in this case,ubuntu
).entrypoint
: Defines the command to execute within the container (bash
).args
: An array of arguments passed to the entrypoint. Here, we useecho
to print the secret value. Note the$$
to escape the$
for Cloud Build substitution.secretEnv
: A list of environment variables that will be populated with the secret values. In this case,MY_SECRET
will contain the value of the secret.availableSecrets
: This section defines where Cloud Build should fetch the secrets from.secretManager
: Specifies that we are using Secret Manager.MY_SECRET
: This maps the environment variableMY_SECRET
(used in theargs
section) to the Secret Manager resource.versionName
: The fully qualified resource name of the secret version. Replace<your-secret-name>
with your secret’s name. Using/versions/latest
always retrieves the most recent version.
Step 4: Trigger a Cloud Build
-
Create a Cloud Build trigger (if you don’t have one already) that points to your repository.
-
Alternatively, start a build manually from your terminal:
gcloud builds submit --config cloudbuild.yaml .
-
Check the Cloud Build logs. You should see the output from the
echo
command, displaying the secret value. The secret value itself is masked in the logs for security.
Best Practices
- Use descriptive secret names: Choose names that clearly indicate the purpose of the secret.
- Implement Secret Rotation: Regularly rotate your secrets to minimize the impact of potential breaches. Secret Manager supports secret rotation.
- Use Least Privilege: Grant only the necessary permissions to Cloud Build and other services accessing the secrets.
- Store Configuration Separately: Avoid storing sensitive information directly in your application’s configuration files. Fetch secrets dynamically at runtime.
- Monitor Secret Access: Monitor access logs in Secret Manager to detect any suspicious activity.
- Version Control your
cloudbuild.yaml
: Treat yourcloudbuild.yaml
file as code and store it in version control along with your application’s code. - Consider Using Buildpacks: If applicable, buildpacks can further abstract the process of fetching secrets, automatically injecting them at build time according to buildpack conventions.
Conclusion
By integrating Google Cloud Secret Manager with Cloud Build, you can significantly improve the security of your CI/CD pipelines. This approach prevents the exposure of sensitive information, simplifies secret management, and helps you meet compliance requirements. Remember to follow the best practices outlined in this post to maintain a secure and robust secret management strategy.