Accessing Private GitHub Repositories

This tutorial demonstrates how to use encrypted secrets and Cloud Key Management Service (KMS) to interact with private GitHub repositories.

Objectives

  • Set up a GitHub SSH key.
  • Add the SSH key to a private repository's deploy keys.
  • Encrypt the SSH key using Cloud KMS.
  • Submit a build that decrypts the key and uses it to access the private repository.

Costs

This tutorial uses billable components of Cloud Platform, including:

  • Cloud KMS
  • Cloud Build

Use the Pricing Calculator to generate a cost estimate based on your projected usage.

New Cloud Platform users might be eligible for a free trial.

Before you begin

  1. Sign in to your Google Account.

    If you don't already have one, sign up for a new account.

  2. Select or create a GCP project.

    Go to the Manage resources page

  3. Make sure that billing is enabled for your project.

    Learn how to enable billing

  4. Enable the Cloud KMS API.

    Enable the API

  5. Install and initialize the Cloud SDK.
  6. Create an SSH key for GitHub.
  7. Add a deploy key to your private repository.

You might also want to complete the Cloud KMS quickstart to become familiar with this product.

Create a Cloud KMS KeyRing and CryptoKey

To use your SSH key with Cloud Build, you must use a Cloud KMS CryptoKey to encrypt and decrypt the key. CryptoKeys are stored in KeyRing objects.

You can create KeyRings and CryptoKeys using the gcloud kms keyrings create and gcloud kms keys create commands.

To create a KeyRing, run the following command in your shell or terminal window. For the purposes of this tutorial, name the KeyRing my-keyring:

gcloud kms keyrings create my-keyring --location=global

Next, create a CryptoKey named github-key. This command creates the github-key CryptoKey in the my-keyring KeyRing:

gcloud kms keys create github-key \
--location=global --keyring=my-keyring \
--purpose=encryption

The --location=global flag indicates that Cloud KMS should serve read and write operations from multiple geographical locations.

Encrypt an SSH key

When you create an SSH key, an id_rsa key file is created in your environment. Because anyone can authenticate to your account with this file, you should encrypt the file before using it in a build.

You can encrypt resources using the gcloud kms encrypt command.

To encrypt your SSH key, run the following command. Be sure to specify the correct paths:

gcloud kms encrypt --plaintext-file=/path/to/sshkey/id_rsa \
--ciphertext-file=/path/to/save/encryptedkey/id_rsa.enc \
--location=global --keyring=my-keyring --key=github-key

This command creates a id_rsa.enc file, which is an encrypted copy of id_rsa.

Grant the Cloud Build service account decrypt permission

You need to grant the Cloud Build service account permission to access and decrypt the CryptoKey during the build.

To learn how to grant the service account decrypt permission, refer to Using Encrypted Resources.

Create or update known_hosts file

You need to provide a known_hosts file containing the rsa key for github.com.

To create a known_hosts file, run the following command:

ssh-keyscan -t rsa github.com > known_hosts

Prepare the build

To prepare the build, create a new directory in your environment containing the following:

  • the id_rsa.enc file
  • the known_hosts file
  • a build request YAML file

The following build decrypts the SSH key, configures git to use the SSH key, and clones the repository at git@github.com:[GIT-USERNAME]/[REPOSITORY].

After you change the repository placeholder values, save this example build as cloudbuild.yaml:

cloudbuild.yaml

# Decrypt the file containing the key
steps:
- name: 'gcr.io/cloud-builders/gcloud'
  args:
  - kms
  - decrypt
  - --ciphertext-file=id_rsa.enc
  - --plaintext-file=/root/.ssh/id_rsa
  - --location=global
  - --keyring=my-keyring
  - --key=github-key
  volumes:
  - name: 'ssh'
    path: /root/.ssh

# Set up git with key and domain.
- name: 'gcr.io/cloud-builders/git'
  entrypoint: 'bash'
  args:
  - '-c'
  - |
    chmod 600 /root/.ssh/id_rsa
    cat <<EOF >/root/.ssh/config
    Hostname github.com
    IdentityFile /root/.ssh/id_rsa
    EOF
    mv known_hosts /root/.ssh/known_hosts
  volumes:
  - name: 'ssh'
    path: /root/.ssh

# Use git clone.
- name: 'gcr.io/cloud-builders/git'
  args:
  - clone
  - git@github.com:[GIT-USERNAME]/[REPOSITORY]
  volumes:
  - name: 'ssh'
    path: /root/.ssh

Submit the build

To submit the build, run the following command from the directory containing the id_rsa.enc file, the known_hosts file, and cloudbuild.yaml file:

gcloud builds submit --config=cloudbuild.yaml .

The output is similar to the following:

Creating temporary tarball archive of 3 file(s) totalling 4.1 KiB before compression.
Uploading tarball of [.] to [gs://[PROJECT-ID]_cloudbuild/source/1504288639.02---.tgz]
Created [https://cloudbuild.googleapis.com/v1/projects/[PROJECT-ID]/builds/871b68bc---].
Logs are available at [https://console.cloud.google.com/gcr/builds/871b68bc---?project=[PROJECT-ID]].
----------------------------- REMOTE BUILD OUTPUT ------------------------------
starting build "871b68bc-cefc-4411-856c-2a2b7c7d2487"

FETCHSOURCE
Fetching storage object: gs://[PROJECT-ID]_cloudbuild/source/1504288639.02---.tgz#1504288640827178
Copying gs://[PROJECT-ID]_cloudbuild/source/1504288639.02---.tgz#1504288640827178...
/ [1 files][  3.9 KiB/  3.9 KiB]
Operation completed over 1 objects/3.9 KiB.
BUILD
Step #0: Already have image (with digest): gcr.io/cloud-builders/gcloud
Starting Step #0
Finished Step #0
Step #1: Already have image (with digest): gcr.io/cloud-builders/git
Starting Step #1
Step #1: # github.com SSH-2.0-libssh_0.7.0
Finished Step #1
Step #2: Already have image (with digest): gcr.io/cloud-builders/git
Starting Step #2
Step #2: Cloning into '[REPOSITORY-NAME]'...
Step #2: Warning: Permanently added the RSA host key for IP address 'XXX.XXX.XXX.XXX' to the list of known hosts.
Finished Step #2
PUSH
DONE
-----------------------------------------------------------------------------------------------------------------

ID                                    CREATE_TIME                DURATION  SOURCE                                                                              IMAGES  STATUS
871b68bc-cefc-4411-856c-2a2b7c7d2487  XXXX-XX-XXT17:57:21+00:00  13S       gs://[PROJECT-ID]_cloudbuild/source/1504288639.02---.tgz  -                                 SUCCESS

Cleaning up

To avoid incurring charges to your Google Cloud Platform account for the resources used in this tutorial:

Delete the project

The easiest way to eliminate billing is to delete the project you created for the tutorial.

To delete the project:

  1. In the GCP Console, go to the Projects page.

    Go to the Projects page

  2. In the project list, select the project you want to delete and click Delete project. After selecting the checkbox next to the project name, click
      Delete project
  3. In the dialog, type the project ID, and then click Shut down to delete the project.

What's next

Was this page helpful? Let us know how we did:

Send feedback about...

Cloud Build Documentation