Loading... Search articles

Search for articles

Sorry, but we couldn't find any matches...

But perhaps we can interest you in one of our more popular articles?
Securing CI/CD with 1Password

Securing CI/CD with 1Password

Aug 21, 2023

This article is written by Himesh Panchal

Secret management in shared environments like Continuous Integration and Delivery services is challenging. It’s essential to keep secrets secure and ensure they don’t end up in the wrong place, like logs or code repositories.

Integrating solutions like 1Password into CI/CD workflows offer the advantage of centralising secret management, and it also allows you to encrypt every secret, providing controlled programmatic access to applications.

In this guide, we’ll explore how to make the most of 1Password Service Accounts within your CI/CD pipelines.

Creating a Service Account in 1Password

Service accounts provide a way to interact with 1Password without using individual user credentials, making it ideal for automated processes.

  1. Log in to 1Password’s web interface.

  2. Navigate to the Integrations section. Click on other option.

  1. Click Create New Service Account and give it a name, e.g. codemagic.

  1. Select the vault(s) you want to grant access to for this service account.

  1. After creating the service account, an authentication token will be auto-generated. Save the auth token to 1Password.

  2. Copy the auth token. Here, we will use Codemagic CI/CD for demonstration purposes, but the same process should work with any CI/CD service.

Adding auth token to Codemagic

  1. Open your Codemagic app > Teams > settings > codemagic.yaml settings, and go to the Global variables and secrets tab.
  2. Enter the Variable nameOP_SERVICE_ACCOUNT_TOKEN.
  3. Paste the token as a Variable value.
  4. Enter the variable group name, e.g. 1password. Click the button to create the group.
  5. Make sure the Secure option is selected.
  6. Click the Add button to add the variable.
  7. Now, we can use this token to retrieve secrets from the 1Password vault.

Configuring 1Password in codemagic.yaml

Installing 1Password CLI using Homebrew

name: Installing 1Password CLI
script: brew install 1password-cli

Verifying the Authenticated User/Service Account in 1Password

name: Verifying the Authenticated User
script: op user get --me

op user get --me This command fetches and displays details of the currently authenticated user or service account in the 1Password CLI. The –me flag gets the authenticated user’s details.

Reading secret references with op read

Fetch the login & API credentials

The command uses curl to make a POST request to BrowserStack’s API to upload an iOS app IPA file for automated testing. It securely retrieves the username and auth token for BrowserStack from 1Password using the op read command and then uses them for authentication in the request.

name: Upload artifact to Browserstack for Testing
script: |
  curl -u "$(op read op://ci/browserstack/username):$(op read op://ci/browserstack/password)" \
  -X POST "https://api-cloud.browserstack.com/app-live/upload" \
  -F "file=@build/ios/ipa/your_app_release.ipa"  

Fetch the document file contents

In this step, we’re fetching the firebase document from a 1Password vault named ci and storing it in firebase.json file.

name: store firebase credentials
script: op read -o ./firebase_creds.json op://ci/serviceAccount/firebase.json
  • op read Read a secret by secret references.
  • o, –out-file string, Write the secret to a file instead of stdout.
  • <reference> reference of the secret path stored in the ci vault.

Reading secret references with op run

You can map environment variables to specific secret references. By utilizing op run, these secrets can be dynamically passed to applications or scripts when they’re executed.

The op run command checks the environment variables for any references to secrets, fetches the relevant values from 1Password, and then initiates the specified command in a subprocess.

During this subprocess’s lifecycle, the secrets are accessible as environment variables, ensuring they’re available only when needed and safeguarded afterwards.

Consider the below example: ci.env file, which has the 1Password secret reference. You can check into source control and use the same environment everywhere.

keyStorePass="op://ci/keystore/password"
keyAlias="op://ci/keystore/alias"
keyPass="op://ci/keystore/keypass"

Code signing Android Application using gradle

In the below script op run command, combined with the –env-file="./ci.env" option,

  1. Loads Environment Variables: It reads the ci.env file and loads the environment variables specified within.
  2. Resolves Secret References: If any of the environment variables have values starting with op://, op run recognizes them as references to secrets within 1Password. It fetches the actual secret values corresponding to those references.
  3. Runs the Command in a Subprocess: It then runs the specified command (in this case, ./gradlew bundleRelease) in a subprocess where the environment variables are set to the resolved secret values.
  4. Cleans Up: Once the subprocess finishes, the environment variables (with secrets) are cleaned up. They aren’t persisted or exposed beyond the lifecycle of the subprocess.
name: Sign Android App
script: op run --env-file="./ci.env" -- ./gradlew bundleRelease

By dynamically providing these critical credentials, developers ensure the app’s integrity while keeping sensitive information away from static build configurations.

Summary

Incorporating 1Password into your CI/CD processes adds another layer of security, centralising and streamlining the management of secrets and credentials. By centralising and securely managing secrets, you reduce risks associated with manual secret management.

Related articles

Latest articles

Show more posts