Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add the op CLI in the script #5

Merged
merged 50 commits into from
Aug 30, 2022
Merged
Show file tree
Hide file tree
Changes from 49 commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
e64093d
Add the op-cli in the script
edif2008 Aug 3, 2021
4787059
Fix lint
edif2008 Aug 3, 2021
08df443
Remove surrounding $()
edif2008 Aug 3, 2021
5add51b
Change to new command signature
edif2008 Aug 16, 2021
e8da10d
Use op cli alpha v2
edif2008 Sep 1, 2021
ac12d2e
Switch to node action
edif2008 Sep 1, 2021
4baca64
Enable using loaded secrets from step's output
edif2008 Sep 1, 2021
000522e
Adjust package dependencies and add newlines
edif2008 Sep 1, 2021
fae9e58
Merge pull request #7 from 1Password/feature/output-secrets
edif2008 Sep 2, 2021
4af3346
Update README with new functionality
edif2008 Sep 6, 2021
da5dd08
Add newline to trigger pipeline
edif2008 Oct 5, 2021
2faffa0
split logic for connect and service_account flows
volodymyrZotov Aug 9, 2022
300c776
revert logic to fetch items using connect
volodymyrZotov Aug 9, 2022
cb24269
Merge branch 'main' into feature/add-cli
volodymyrZotov Aug 9, 2022
6c02b89
updated configure script
volodymyrZotov Aug 10, 2022
d78889a
updated test.yml
volodymyrZotov Aug 10, 2022
b38d015
test should fail cause not existing field provided
volodymyrZotov Aug 10, 2022
9fdfd04
revert back test change
volodymyrZotov Aug 10, 2022
302881b
use correct op cli version fo linux
volodymyrZotov Aug 10, 2022
bb28cdf
added test case for load secrets via op cli
volodymyrZotov Aug 10, 2022
b38b493
rename tests
volodymyrZotov Aug 10, 2022
858b6a8
added env variables to test secret section
volodymyrZotov Aug 10, 2022
1263fc8
updated darwin op archive link
volodymyrZotov Aug 10, 2022
c7774c7
updated darwin link
volodymyrZotov Aug 10, 2022
ada03a0
use cli to retrieve secrets if signed in via connect
volodymyrZotov Aug 11, 2022
34bed60
use op read to retrive item values
volodymyrZotov Aug 11, 2022
8052f86
added additional test cases
volodymyrZotov Aug 11, 2022
df0b228
removed logs to console
volodymyrZotov Aug 11, 2022
2a4f64c
Merge branch 'feature/add-cli' of github.com:1Password/load-secrets-a…
volodymyrZotov Aug 11, 2022
2a214a2
unset IFS at the end of the flow
volodymyrZotov Aug 11, 2022
e1b37a5
updated README and configuration.yml
volodymyrZotov Aug 11, 2022
5c5bbcb
prevent command injection vulnerability
volodymyrZotov Aug 15, 2022
8d99fc2
properly unpack tar.gz
volodymyrZotov Aug 15, 2022
d5280ef
updated README.md
volodymyrZotov Aug 15, 2022
e9bd76c
removed test-connect-export case
volodymyrZotov Aug 15, 2022
2f338e1
use node16
volodymyrZotov Aug 15, 2022
953b517
extract op to proper path
volodymyrZotov Aug 15, 2022
c27a045
use references that has ids instead of names
volodymyrZotov Aug 15, 2022
641b0d9
use ids for multiline secret
volodymyrZotov Aug 15, 2022
2ac8886
fixed multiline secret ref
volodymyrZotov Aug 15, 2022
ce8b31d
added more secrets to test
volodymyrZotov Aug 15, 2022
7d858c7
Make dedicated tests for secret references with IDs
edif2008 Aug 16, 2022
c53c263
Add service account token in env
edif2008 Aug 16, 2022
aaee191
updated README
volodymyrZotov Aug 17, 2022
a37c95c
Merge branch 'feature/add-cli' of github.com:1Password/load-secrets-a…
volodymyrZotov Aug 17, 2022
b1b82d7
updated gitignore
volodymyrZotov Aug 19, 2022
ed1f9a4
use op cli to fetch secrets for connect
volodymyrZotov Aug 19, 2022
30def81
added macos installer reference
volodymyrZotov Aug 19, 2022
e3b137e
added macos test case
volodymyrZotov Aug 19, 2022
cb83ae0
improved readme
volodymyrZotov Aug 30, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
139 changes: 125 additions & 14 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ on: push
name: Run acceptance tests

jobs:
test:
use-connect-without-export-env:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
Expand All @@ -18,34 +18,145 @@ jobs:
connect-host: http://localhost:8080
connect-token: ${{ secrets.OP_CONNECT_TOKEN }}
- name: Load secrets
id: load_secrets
uses: ./ # 1password/load-secrets-action@<version>
env:
SECRET: op://v5pz6venw4roosmkzdq2nhpv6u/hrgkzhrlvscomepxlgafb2m3ca/password
SECRET_IN_SECTION: op://v5pz6venw4roosmkzdq2nhpv6u/hrgkzhrlvscomepxlgafb2m3ca/test-section/password
UNMASKED_VALUE: op://v5pz6venw4roosmkzdq2nhpv6u/hrgkzhrlvscomepxlgafb2m3ca/test-section/username
volodymyrZotov marked this conversation as resolved.
Show resolved Hide resolved
- name: Load multiline secret
SECRET: op://acceptance-tests/test-secret/password
SECRET_IN_SECTION: op://acceptance-tests/test-secret/test-section/password
MULTILINE_SECRET: op://acceptance-tests/multiline-secret/notesPlain
- name: Assert test secret values
env:
SECRET: ${{ steps.load_secrets.outputs.SECRET }}
SECRET_IN_SECTION: ${{ steps.load_secrets.outputs.SECRET_IN_SECTION }}
MULTILINE_SECRET: ${{ steps.load_secrets.outputs.MULTILINE_SECRET }}
run: ./tests/assert-env-set.sh
use-connect-with-export-env:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Launch 1Password Connect instance
env:
OP_CONNECT_CREDENTIALS: ${{ secrets.OP_CONNECT_CREDENTIALS }}
run: |
echo "$OP_CONNECT_CREDENTIALS" > 1password-credentials.json
docker-compose -f tests/fixtures/docker-compose.yml up -d && sleep 10
- name: Configure 1Password Connect
uses: ./configure # 1password/load-secrets-action/configure@<version>
with:
connect-host: http://localhost:8080
connect-token: ${{ secrets.OP_CONNECT_TOKEN }}
- name: Load secrets
id: load_secrets
uses: ./ # 1password/load-secrets-action@<version>
with:
export-env: true
env:
MULTILINE_SECRET: op://v5pz6venw4roosmkzdq2nhpv6u/ghtz3jvcc6dqmzc53d3r3eskge/notesPlain
- name: Print environment variables with masked secrets
run: printenv
SECRET: op://acceptance-tests/test-secret/password
SECRET_IN_SECTION: op://acceptance-tests/test-secret/test-section/password
MULTILINE_SECRET: op://acceptance-tests/multiline-secret/notesPlain
- name: Assert test secret values
run: ./tests/assert-env-set.sh
- name: Remove secrets
uses: ./ # 1password/load-secrets-action@<version>
with:
unset-previous: true
- name: Print environment variables with secrets removed
run: printenv
- name: Assert removed secrets
run: ./tests/assert-env-unset.sh
- name: Load secrets by vault and item titles
use-connect-with-references-with-id:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Launch 1Password Connect instance
env:
OP_CONNECT_CREDENTIALS: ${{ secrets.OP_CONNECT_CREDENTIALS }}
run: |
echo "$OP_CONNECT_CREDENTIALS" > 1password-credentials.json
docker-compose -f tests/fixtures/docker-compose.yml up -d && sleep 10
- name: Configure 1Password Connect
uses: ./configure # 1password/load-secrets-action/configure@<version>
with:
connect-host: http://localhost:8080
connect-token: ${{ secrets.OP_CONNECT_TOKEN }}
- name: Load secrets
id: load_secrets
uses: ./ # 1password/load-secrets-action@<version>
env:
SECRET: op://v5pz6venw4roosmkzdq2nhpv6u/hrgkzhrlvscomepxlgafb2m3ca/password
SECRET_IN_SECTION: op://v5pz6venw4roosmkzdq2nhpv6u/hrgkzhrlvscomepxlgafb2m3ca/Section_tco6nsqycj6jcbyx63h5isxcny/doxu3mhkozcznnk5vjrkpdqayy
MULTILINE_SECRET: op://v5pz6venw4roosmkzdq2nhpv6u/ghtz3jvcc6dqmzc53d3r3eskge/notesPlain
- name: Assert test secret values
env:
SECRET: ${{ steps.load_secrets.outputs.SECRET }}
SECRET_IN_SECTION: ${{ steps.load_secrets.outputs.SECRET_IN_SECTION }}
MULTILINE_SECRET: ${{ steps.load_secrets.outputs.MULTILINE_SECRET }}
run: ./tests/assert-env-set.sh
use-service-account-without-export-env:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Load secrets
id: load_secrets
uses: ./ # 1password/load-secrets-action@<version>
env:
OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }}
SECRET: op://acceptance-tests/test-secret/password
SECRET_IN_SECTION: op://acceptance-tests/test-secret/test-section/password
MULTILINE_SECRET: op://acceptance-tests/multiline-secret/notesPlain
- name: Assert test secret values
env:
SECRET: ${{ steps.load_secrets.outputs.SECRET }}
SECRET_IN_SECTION: ${{ steps.load_secrets.outputs.SECRET_IN_SECTION }}
MULTILINE_SECRET: ${{ steps.load_secrets.outputs.MULTILINE_SECRET }}
run: ./tests/assert-env-set.sh
use-service-account-with-export-env:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Load secrets
id: load_secrets
uses: ./ # 1password/load-secrets-action@<version>
with:
export-env: true
env:
OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }}
SECRET: op://acceptance-tests/test-secret/password
SECRET_IN_SECTION: op://acceptance-tests/test-secret/test-section/password
MULTILINE_SECRET: op://acceptance-tests/multiline-secret/notesPlain
- name: Assert test secret values
run: ./tests/assert-env-set.sh
use-service-account-with-references-with-id:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Load secrets
id: load_secrets
uses: ./ # 1password/load-secrets-action@<version>
env:
OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }}
SECRET: op://v5pz6venw4roosmkzdq2nhpv6u/hrgkzhrlvscomepxlgafb2m3ca/password
SECRET_IN_SECTION: op://v5pz6venw4roosmkzdq2nhpv6u/hrgkzhrlvscomepxlgafb2m3ca/Section_tco6nsqycj6jcbyx63h5isxcny/doxu3mhkozcznnk5vjrkpdqayy
MULTILINE_SECRET: op://v5pz6venw4roosmkzdq2nhpv6u/ghtz3jvcc6dqmzc53d3r3eskge/notesPlain
- name: Assert test secret values
env:
SECRET: ${{ steps.load_secrets.outputs.SECRET }}
SECRET_IN_SECTION: ${{ steps.load_secrets.outputs.SECRET_IN_SECTION }}
MULTILINE_SECRET: ${{ steps.load_secrets.outputs.MULTILINE_SECRET }}
run: ./tests/assert-env-set.sh
run-on-macos-12:
runs-on: macos-12
steps:
- uses: actions/checkout@v2
- name: Load secrets
id: load_secrets
uses: ./ # 1password/load-secrets-action@<version>
env:
OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }}
SECRET: op://acceptance-tests/test-secret/password
SECRET_IN_SECTION: op://acceptance-tests/test-secret/test-section/password
MULTILINE_SECRET: op://acceptance-tests/multiline-secret/notesPlain
- name: Print environment variables with masked secrets
run: printenv
- name: Assert test secret values again
- name: Assert test secret values
env:
SECRET: ${{ steps.load_secrets.outputs.SECRET }}
SECRET_IN_SECTION: ${{ steps.load_secrets.outputs.SECRET_IN_SECTION }}
MULTILINE_SECRET: ${{ steps.load_secrets.outputs.MULTILINE_SECRET }}
run: ./tests/assert-env-set.sh
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
node_modules/
.vscode
.idea
.secrets
volodymyrZotov marked this conversation as resolved.
Show resolved Hide resolved
124 changes: 115 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,28 @@
# Load Secrets from 1Password - GitHub Action

The action to load secrets from [1Password Connect](https://1password.com/secrets/) into GitHub Actions.
This action loads secrets from 1Password into GitHub Actions using [1Password Connect](https://1password.com/secrets/) or a Service Account.


Specify right from your workflow YAML which secrets from 1Password should be loaded into your job, and the action will make them available as environment variables for the next steps.

## Usage

You can configure the action to use either 1Password Connect instance or a 1Password Service Account. Service Accounts are currently in Beta and are only available to select users.
volodymyrZotov marked this conversation as resolved.
Show resolved Hide resolved

If you provide `OP_CONNECT_HOST` and `OP_CONNECT_TOKEN` variables, the Connect instance will be used to load secrets. Make sure [1Password Connect](https://support.1password.com/secrets-automation/#step-2-deploy-a-1password-connect-server) deployed in your infrastructure.
volodymyrZotov marked this conversation as resolved.
Show resolved Hide resolved

If you provide `OP_SERVICE_ACCOUNT_TOKEN` variable, the service account will be used to load secrets.
volodymyrZotov marked this conversation as resolved.
Show resolved Hide resolved

***Note***: If all environment variables have been set, the Connect credentials will take precedence over the provided service account token. You must unset the Connect environment variables to ensure the action uses the service account token.

There are two ways that secrets can be loaded:
- [use the secrets from the action's ouput](#use-secrets-from-the-actions-output)
- [export secrets as environment variables](#export-secrets-as-environment-variables)

### Use secrets from the action's output

This method allows for you to use the loaded secrets as an output from the step: `steps.step-id.outputs.secret-name`. You will need to set an id for the step that uses this action to be able to access its outputs. More details about the metadata syntax [here](https://docs.github.com/en/actions/creating-actions/metadata-syntax-for-github-actions#outputsoutput_id).
volodymyrZotov marked this conversation as resolved.
Show resolved Hide resolved

```yml
on: push
jobs:
Expand All @@ -15,12 +32,83 @@ jobs:
- uses: actions/checkout@v2

- name: Load secret
id: op-load-secret
uses: 1password/load-secrets-action@v1
env:
OP_CONNECT_HOST: <Your Connect instance URL>
OP_CONNECT_TOKEN: ${{ secrets.OP_CONNECT_TOKEN }}
SECRET: op://app-cicd/hello-world/secret

- name: Print masked secret
run: echo "Secret: ${{ steps.op-load-secret.outputs.SECRET }}"
# Prints: Secret: ***
```

<details>
<summary><b>Longer usage example</b></summary>

```yml
on: push
name: Deploy app

jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2

- name: Configure 1Password Connect
uses: 1password/load-secrets-action/configure@v1
with:
# Persist the 1Password Connect URL for next steps. You can also persist
# the Connect token using input `connect-token`, but keep in mind that
# every single step in the job would then be able to access the token.
connect-host: https://1password.acme.com

- name: Load Docker credentials
id: load-docker-credentials
uses: 1password/load-secrets-action@v1
env:
OP_CONNECT_TOKEN: ${{ secrets.OP_CONNECT_TOKEN }}
DOCKERHUB_USERNAME: op://app-cicd/docker/username
DOCKERHUB_TOKEN: op://app-cicd/docker/token

- name: Login to Docker Hub
uses: docker/login-action@v1
with:
username: ${{ steps.load-docker-credentials.outputs.DOCKERHUB_USERNAME }}
password: ${{ steps.load-docker-credentials.outputs.DOCKERHUB_TOKEN }}

- name: Build and push Docker image
uses: docker/build-push-action@v2
with:
push: true
tags: acme/app:latest
```
</details>

### Export secrets as environment variables

This method, allows the action to access the loaded secrets as environment variables. These environment variables are accessible at a job level.

```yml
on: push
jobs:
hello-world:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2

- name: Load secret
uses: 1password/load-secrets-action@v1
with:
# Export loaded secrets as environment variables
export-env: true
env:
OP_CONNECT_HOST: <Your Connect instance URL>
OP_CONNECT_TOKEN: ${{ secrets.OP_CONNECT_TOKEN }}
SECRET: op://app-cicd/hello-world/secret

- name: Print masked secret
run: echo "Secret: $SECRET"
# Prints: Secret: ***
Expand Down Expand Up @@ -48,6 +136,9 @@ jobs:

- name: Load Docker credentials
uses: 1password/load-secrets-action@v1
with:
# Export loaded secrets as environment variables
export-env: true
env:
OP_CONNECT_TOKEN: ${{ secrets.OP_CONNECT_TOKEN }}
DOCKERHUB_USERNAME: op://app-cicd/docker/username
Expand All @@ -71,6 +162,8 @@ jobs:
- name: Load AWS credentials
uses: 1password/load-secrets-action@v1
with:
# Export loaded secrets as environment variables
export-env: true
# Remove local copies of the Docker credentials, which are not needed anymore
unset-previous: true
env:
Expand All @@ -89,6 +182,7 @@ jobs:

| Name | Default | Description |
|---|---|---|
| `export-env` | `false` | Export the loaded secrets as environment variables |
| `unset-previous` | `false` | Whether to unset environment variables populated by 1Password in earlier job steps |

## Secrets Reference Syntax
Expand All @@ -107,16 +201,15 @@ So for example, the reference URI `op://app-cicd/aws/secret-access-key` would be

## Masking

Similar to regular GitHub repository secrets, secret fields from 1Password will automatically be masked from the GitHub Actions logs too.
A 1Password field is considered 'secret' when it's marked as concealed (which shows as `•••••••` in the 1Password GUI) or when it's a secure note.
Similar to regular GitHub repository secrets, fields from 1Password will automatically be masked from the GitHub Actions logs too.
So if one of these values accidentally gets printed, it'll get replaced with `***`.

This means that a username or port field for example will not get masked.

## 1Password Connect Configuration
## 1Password Configuration

To use the action, you need to have a [1Password Connect](https://support.1password.com/secrets-automation/#step-1-set-up-a-secrets-automation-workflow) instance deployed somewhere.
To configure the action with your Connect URL and a Connect token, you can set the `OP_CONNECT_HOST` and `OP_CONNECT_TOKEN` variables.
To use the action with Connect, you need to have a [1Password Connect](https://support.1password.com/secrets-automation/#step-1-set-up-a-secrets-automation-workflow) instance deployed somewhere.
To configure the action with your Connect host and token, set the `OP_CONNECT_HOST` and `OP_CONNECT_TOKEN` environment variables.
To configure the action with your service account token, set the `OP_SERVICE_ACCOUNT_TOKEN` environment variable.
*** Note: *** Service Accounts are currently in Beta and are only available to select users.

If you're using the `load-secrets` action more than once in a single job, you can use the `configure` action to avoid duplicate configuration:

Expand All @@ -133,7 +226,7 @@ jobs:
with:
connect-host: <Your Connect instance URL>
connect-token: ${{ secrets.OP_CONNECT_TOKEN }}

service-account-token: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }}
volodymyrZotov marked this conversation as resolved.
Show resolved Hide resolved
- name: Load secret
uses: 1password/load-secrets-action@v1
env:
Expand All @@ -146,7 +239,20 @@ jobs:
|---|---|---|---|
| `connect-host` | | `OP_CONNECT_HOST` | Your 1Password Connect instance URL |
| `connect-token` | | `OP_CONNECT_TOKEN` | Token to authenticate to your 1Password Connect instance |
| `service-account-token` | | `OP_SERVICE_ACCOUNT_TOKEN` | Your 1Password service account token |

## Supported Runners

You can run the action on Linux and macOS runners. Windows is currently not supported.

## Security

1Password requests you practice responsible disclosure if you discover a vulnerability.

Please file requests via [**BugCrowd**](https://bugcrowd.com/agilebits).

For information about security practices, please visit our [Security homepage](https://bugcrowd.com/agilebits).

## Getting help

If you find yourself stuck, visit our [**Support Page**](https://support.1password.com/) for help.
12 changes: 5 additions & 7 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,9 @@ inputs:
unset-previous:
description: Whether to unset environment variables populated by 1Password in earlier job steps
default: false
export-env:
description: Export the secrets as environment variables
default: false
runs:
using: composite
steps:
- shell: bash
env:
INPUT_UNSET_PREVIOUS: ${{ inputs.unset-previous }}
run: |
${{ github.action_path }}/entrypoint.sh
using: 'node16'
main: 'dist/index.js'
Loading