pmv

command module
v3.19.6 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 11, 2024 License: MIT Imports: 1 Imported by: 0

README ΒΆ

PMV

A tiny utility for working with the 1Password CLI.

1Password CLI Caveats

Macos

On Macos, the 1Password CLI uses the Secure Enclave. For this reason, it's recommended to not use asdf or other version management tools to install the 1Password CLI. This is because they will likely not install 1password-cli in /usr/local/bin, which is required for usage with the Secure Enclave.

It's recommended that you either uninstall the asdf 1password-cli plugin, or use "system" as the version in your .tool-versions.

Then, install 1password-cli manually, following the instructions at https://developer.1password.com/docs/cli/get-started#install.

Installation

If you have Golang installed run the following to install the latest release.

go install gitlab.com/gitlab-com/gl-infra/pmv/v3

Otherwise download the latest release and move it to a directory in your $PATH.

Note: pmv v3 requires 1Password CLI v2. If you need to use pmv with 1Password CLI v1, please use pmv v2.

pmv Commands

env

Generates a set of environment export variables from a 1password tag.

  1. Login to 1password, eg eval $(op signin --account gitlab)
  2. Create an item in 1password and configure it with a unique tag. Note that slashes (/) in tags will be shown hierarchically in the 1password UI, which can be useful for categorization.
  3. Each field with a env: prefix will be emitted as an export. For example env:GITLAB_TOKEN=xyz will generate export GITLAB_TOKEN=xyz.
  4. Use eval $(pmv env Tag) to export the environment variables into the current shell.
  5. To add a prefix to each item, use the optional --prefix PREFIX_ argument.
  6. By default pmv env will create a temporary session if an MFA is registered. This behavior can be disabled with the --skip-mfa flag. Warning: this option is dangerous as it can circumvent MFA and could expose underlying credentials. Use with caution.
  7. Use the --assume-role parameter to assume another role. This parameter will accept a role name, or a role ARN.
  8. Use the --validate-tokens parameter to validate a token. Currently supports GitLab and AWS tokens. Other tokens will pass.
Usage
$ # Before using pmv, log using 1password client
$ eval $(op signin --account gitlab)
$ # Sample usage of `pmv env`
$ pmv env ProductName/Env:Test
export SECRET=abc
export OTHER_SECRET=xyz
$ # More useful usage, exports variables to shell
$ eval $(pmv env ProductName/Env:Test)
$ # Secrets are now loaded into the environment
$ # Add a prefix to the items
$ pmv env ProductName/Env:Test --prefix HUB_
export HUB_SECRET=abc
export HUB_OTHER_SECRET=xyz

The above usage can be combined with direnv to automatically load and unload environment variables from 1Password. While this can be achieved using direnv alone, a single call to 1Password is a lot faster when loading multiple environment variables.

Add the following to a file called .envrc to any directory and these environment variables will be loaded at that directory and any child directories.

#!/bin/bash

eval "$(pmv env ProductName/Env:Test)"
json

Generates a secrets blob in JSON

  1. Login to 1password, eg eval $(op signin --account gitlab)
  2. Create an item in 1password and configure it with a unique tag. Note that slashes (/) in tags will be shown hierarchically in the 1password UI, which can be useful for categorization.
  3. Each field with a json: prefix will be emitted as an export. For example json:secret=xyz will generate {"secret": "xyz"}.
  4. Use pmv env Tag > secrets.json to write the secrets to a file.
Usage
$ # Before using pmv, log using 1password client
$ eval $(op signin --account gitlab)
$ # Sample usage of `pmv json`
$ pmv json ProductName/Env:Test > secrets.json
capture aws

Captures credentials to AWS for use in Environments. Will validate the credentials before saving them.

  1. Login to 1password, eg eval $(op signin --account gitlab)
  2. Run: pmv capture aws --description "My Production Credentials" --tags "MyTag,MyOtherTag" --vault "DefaultsToPersonal" --delete-tagged-items
  3. You can set a title for the item with --title, but if you choose --description, a title, including details such as AWS Account ID, Account Alias, Username and your chosen Description will be generated.
  4. ⚠️ Note: using --delete-tagged-items will remove any others items with the given tags from the vault.
Setting up Virtual MFA

pmv capture aws will, by default, setup a Virtual MFA device if one is not setup for the account. The AWS API does not support U2F (eg Yubikey) MFA devices, so a virtual device (eg, Google Authenticator, Microsoft Authenticator) will need to be used.

On setup, a QR Code containing the secret will be displayed in the console, and two subsequent codes will need to be entered to confirm and enable the Virtual MFA device.

The serial number/arn of the Virtual MFA will then be saved along with the captured authentication details in the newly created 1password item.

Note, MFA setup can be disabled with the --skip-mfa argument.

Usage
$ # Before using pmv, log using 1password client
$ eval $(op signin --account gitlab)
$ # Sample usage of `pmv capture aws`
$ pmv capture aws --description "My Production Credentials" --tags "MyTag"  --delete-tagged-items
pmv: πŸ”“ Enter AWS_ACCESS_KEY: AK000000000000000000
pmv: πŸ”“ Enter AWS_SECRET_ACCESS_KEY:
pmv: πŸ”“ Thanks. Verifying the credentials with AWS...
pmv: βœ… Verification passed. Greetings, `andrew-api`!πŸ‘‹
pmv: πŸ“² OK, time to setup a virtual MFA.
pmv: πŸ“² AWS doesn't support U2F from the API or CLI, so you'll need to use a virtual device,
pmv: πŸ“² like Authenticator on your phone.
β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ
β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ
β–ˆβ–ˆβ–ˆβ–ˆ β–„β–„β–„β–„β–„ β–ˆβ–„ β–€β–ˆβ–ˆβ–ˆ β–„β–€β–ˆβ–ˆβ–„β–„β–„β–€ β–„ β–„ β–ˆβ–ˆ β–„β–„β–„β–„β–„ β–ˆβ–ˆβ–ˆβ–ˆ
β–ˆβ–ˆβ–ˆβ–ˆ β–ˆ   β–ˆ β–ˆβ–€β–€β–„ β–„β–ˆβ–ˆβ–€β–€β–ˆ β–„β–„β–€β–ˆβ–€β–„β–ˆβ–„ β–„β–ˆ β–ˆ   β–ˆ β–ˆβ–ˆβ–ˆβ–ˆ
β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–„β–„β–„β–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–€β–„ β–€β–€  β–ˆβ–ˆβ–ˆβ–€β–ˆ β–ˆβ–ˆβ–€  β–ˆ β–ˆβ–„β–„β–„β–ˆ β–ˆβ–ˆβ–ˆβ–ˆ
β–ˆβ–ˆβ–ˆβ–ˆβ–„β–„β–„β–„β–„β–„β–„β–ˆβ–„β–€β–„β–ˆ β–€ β–ˆβ–„β–ˆ β–€ β–ˆ β–ˆβ–„β–€β–„β–ˆ β–ˆβ–„β–„β–„β–„β–„β–„β–„β–ˆβ–ˆβ–ˆβ–ˆ
β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–€β–„β–ˆ β–„β–„β–ˆβ–„β–ˆβ–€β–ˆ β–ˆβ–„β–ˆβ–ˆβ–„β–ˆβ–ˆβ–€β–ˆβ–ˆβ–„β–ˆβ–ˆβ–ˆ  β–„β–ˆβ–ˆβ–ˆ β–ˆβ–€ β–ˆβ–ˆβ–ˆβ–ˆ
β–ˆβ–ˆβ–ˆβ–ˆβ–€β–„  β–ˆ β–„ β–„ β–„ β–„β–ˆ  β–€β–€ β–„ β–€β–€β–€β–€ β–€β–ˆβ–ˆβ–€β–„β–€β–€β–„β–„β–„ β–ˆβ–ˆβ–ˆβ–ˆ
β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–„β–„β–„β–ˆβ–„β–ˆ  β–„β–ˆ β–„β–ˆ β–€β–„β–€β–ˆβ–„β–ˆ β–€β–„ β–„ β–ˆβ–ˆ β–€ β–€β–ˆβ–ˆβ–ˆβ–ˆ
β–ˆβ–ˆβ–ˆβ–ˆ  β–€  β–ˆβ–„β–€β–„β–ˆβ–ˆβ–ˆβ–ˆβ–€β–€β–ˆβ–€β–€β–„β–€β–ˆβ–ˆβ–€ β–ˆβ–€β–€β–ˆβ–ˆβ–„β–„β–„β–ˆβ–ˆβ–„β–ˆ β–ˆβ–ˆβ–ˆβ–ˆ
β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–€β–„β–ˆβ–„β–€β–ˆβ–ˆβ–€β–€β–ˆ β–ˆβ–€β–ˆβ–ˆ  β–„β–„β–„ β–„β–„β–„β–ˆ β–„ β–„β–ˆβ–„β–€  β–ˆβ–ˆβ–ˆβ–ˆ
β–ˆβ–ˆβ–ˆβ–ˆβ–€ β–ˆβ–„β–ˆβ–€β–„β–„β–€β–ˆ β–„β–„β–„β–„ β–€β–ˆβ–€β–„β–ˆβ–€ β–€β–€ β–€β–€β–€β–ˆβ–„β–„β–€β–ˆβ–ˆβ–„ β–ˆβ–ˆβ–ˆβ–ˆ
β–ˆβ–ˆβ–ˆβ–ˆ   β–ˆβ–€β–ˆβ–„β–€ β–ˆβ–€β–€β–ˆ  β–ˆβ–€β–€β–ˆβ–ˆβ–ˆβ–„β–„β–„β–ˆ β–€β–ˆβ–„β–„ β–„β–ˆβ–„β–€β–€β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ
β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ  β–ˆβ–ˆβ–„β–„β–€ β–„β–ˆβ–ˆβ–„β–„β–„ β–€β–€  β–ˆβ–„β–€  β–€β–ˆβ–ˆβ–„β–„β–„β–ˆβ–„ β–„β–„ β–ˆβ–ˆβ–ˆβ–ˆ
β–ˆβ–ˆβ–ˆβ–ˆβ–„β–„β–ˆβ–„β–ˆ β–„β–„  β–ˆβ–€β–„β–„β–ˆβ–€β–„β–€β–„ β–€β–ˆβ–€  β–€β–€   β–„β–„β–ˆβ–€β–€β–€ β–ˆβ–ˆβ–ˆβ–ˆ
β–ˆβ–ˆβ–ˆβ–ˆβ–„β–€β–ˆβ–„ β–€β–„β–„β–ˆβ–ˆ β–ˆ β–„β–ˆβ–„β–ˆ  β–„β–„ β–ˆβ–„  β–€β–€ β–ˆ β–ˆβ–„ β–„β–„ β–ˆβ–ˆβ–ˆβ–ˆ
β–ˆβ–ˆβ–ˆβ–ˆβ–„β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–„β–ˆ β–ˆβ–€β–„ β–ˆβ–„β–„β–ˆ  β–ˆ β–„β–„β–„ β–„β–€  β–„β–„β–„ β–„β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ
β–ˆβ–ˆβ–ˆβ–ˆ β–„β–„β–„β–„β–„ β–ˆβ–€β–„β–„ β–€β–€β–„β–€β–„β–€β–€ β–€β–„β–€β–€β–€ β–ˆβ–„ β–ˆβ–„β–ˆ β–ˆβ–„β–„ β–ˆβ–ˆβ–ˆβ–ˆ
β–ˆβ–ˆβ–ˆβ–ˆ β–ˆ   β–ˆ β–ˆβ–„β–ˆ  β–„β–ˆβ–ˆ β–€β–ˆβ–€β–„β–€β–€β–€ β–„ β–ˆβ–€β–„ β–„β–„  β–€  β–ˆβ–ˆβ–ˆβ–ˆ
β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–„β–„β–„β–ˆ β–ˆβ–„β–„β–ˆβ–€ β–€β–ˆ  β–€β–„  β–€β–€β–€β–€ β–ˆβ–„ β–„β–ˆβ–„ β–„β–„β–€β–„β–ˆβ–ˆβ–ˆβ–ˆ
β–ˆβ–ˆβ–ˆβ–ˆβ–„β–„β–„β–„β–„β–„β–„β–ˆβ–ˆβ–ˆβ–ˆβ–„β–„β–„β–ˆβ–ˆβ–„β–„β–ˆβ–„β–„β–ˆβ–ˆβ–ˆβ–ˆβ–„β–„β–„β–„β–ˆβ–„β–„β–ˆβ–ˆβ–ˆβ–„β–„β–ˆβ–ˆβ–ˆβ–ˆ
β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ
β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€β–€
pmv: πŸ“² When you're ready, enter two consecutive codes.
pmv: πŸ“²  Code 1: 111111
pmv: πŸ“²  Code 2: 222222
pmv: πŸ—‘  Deleting old items with tag `MyTag`
{"uuid":"4jedpsrc4vojvat2r5rusgprw4","createdAt":"2022-08-29T19:00:13.24686+02:00","updatedAt":"2022-08-29T19:00:13.24686+02:00","vaultUuid":"5albo45xgknr5k4xm4dlq3whk4"}
Performing Multi-factor Authentication using the Virtual MFA

After the MFA has been setup with pmv capture aws, the pmv env command will automatically perform multi-factor authentication using the configuration virtual MFA device.

$ # Log into the account, with Multi-Factor Authentication
$ eval $(pmv env MyTag)
pmv: πŸ”“ Fetching 1password items with tag MyTag...
pmv: 🧩 Loaded: `AWS Access: andrew-api: Account ID 11111111111`
pmv: πŸ“² Use your Authenticator app to provide a token code for `AWS Access: andrew-api: Account ID 11111111111`:
token: 111111
pmv: πŸ”“ Complete, loaded items...
$ # Notice that the AWS_ACCESS_KEY now starts with an `AS..` instead of the `AK`. This indicates a temporary session key is in use.
$ set | grep AWS_
AWS_ACCESS_KEY=AS1111111111111111
AWS_ACCESS_KEY_ID=AS1111111111111111
AWS_SECRET_ACCESS_KEY=K11111...
AWS_SESSION_TOKEN=F1111...
...
$ # Check the session expiry time stored in AWS_SESSION_EXPIRATION. The 12 hour default is used.
$ echo $AWS_SESSION_EXPIRATION
2022-08-30T08:09:05Z
capture gitlab

Captures credentials for GitLab token usage, into an environment variable, GITLAB_TOKEN. Will validate the credentials before saving them.

  1. Login to 1password, eg eval $(op signin --account gitlab)
  2. Run: pmv capture gitlab --description "My GitLab Access Token" --tags "MyGitLabTag" --vault "DefaultsToPersonal" --delete-tagged-items
  3. You can set a title for the item with --title, but if you choose --description, a title, including details such as Username, GitLab Instance and your chosen Description will be generated.
  4. By default, the token will be tested against GitLab.com, but this can be changed with --gitlab-instance https://gitlab.example.com
  5. ⚠️ Note: using --delete-tagged-items will remove any others items with the given tags from the vault.
capture aws-secret

Captures credentials from AWS SecretsManager, into an 1password item.

  1. The AWS client uses the AWS_* environment variables to initialize AWS communications. pmv will fail to fetch AWS SecretsManager items unless these are properly configured. This can be validated by running aws sts get-caller-identity.
  2. Login to 1password, eg eval $(op signin --account gitlab)
  3. Run: pmv capture aws-secret --secret-id "gitlab/dedicated/env/pagerduty_service_key" --title "Pagerduty Service Key" --tags PagerdutyServiceKey --delete-tagged-items
  4. The --title and --secret-id arguments are both required.
  5. ⚠️ Note: using --delete-tagged-items will remove any others items with the given tags from the vault.
rotate aws <tag>

This allows a AWS Secrets Manager secret, previously created using capture aws to be automatically rotated.

$ pmv rotate aws "MyTag"
pmv: πŸ”“ Fetching 1password items with tag MyTag...
pmv: 🧩 Loaded: `MyTag`
pmv: πŸ”“ Complete, loaded items...
pmv: πŸ”‘  Creating new access key in AWS...
pmv: 🐣  Creating new 1password item...
pmv: ❌  Deleting old key in AWS...
pmv: ✨  Created item: https://start.1password.com/open/i?a=xx&v=xx&i=xx&h=gitlab.1password.com
pmv: πŸ—‘οΈ  Deleting old 1password item...
pmv: πŸš€ Rotation complete...
  1. By default, the old key will be deleted, but you can chose to inactivate it instead. This can be done using the --inactivate-old-key argument.
  2. By default, AWS accounts will allow a maximum of two access keys. If you have two active, you will need to delete one of your keys first, since the rotation will create the new key before removing the old one.
rotate gitlab <tag>

Uses the GitLab Token rotation API to rotate a token. By default, the new token will have an expiry 1 day less than 1 year into the future.

$ pmv rotate gitlab "MyTag"
pmv: πŸ”“ Fetching 1password items tag=Dedicated/Sandbox/GitLab.com/PAT:Personal
pmv: 🧩 Loaded item title="GitLab Access Token: GitLab.com PAT for Sandbox Access (api): https://gitlab.com: andrewn"
pmv: πŸ”“ Complete, loaded items...
pmv: πŸ”‘  Rotating token in GitLab...
pmv: πŸ”‘  New token expiry date... expires_at=2025-05-16
pmv: 🐣  Creating new 1password item...
pmv: 🐣 Created item link=https://start.1password.com/open/...
pmv: πŸ—‘οΈ  Deleting old 1password item.
pmv: πŸš€ Rotation complete...
  1. Unfortunately this can only be used for Personal Access Tokens at present, until https://gitlab.com/gitlab-org/gitlab/-/issues/462419 is resolved.
  2. Use the --expires argument to set an expiry. This can either be a date in YYYY-MM-DD format, or a duration, eg: 30d.
  3. If your token does not have the api scope, it will be possible to rotate it using another token for the same user specifying the --with parameter.
sso env

This performs an SSO sign-on into a AWS account using an OIDC exchange.

$ # Use OIDC to authenticate with AWS Identity Center SSO
$ eval $(pmv sso env --start-url https://d-9067908776.awsapps.com/start --account-id 787839063675 --role-name AdministratorAccess)
$ aws sts get-caller-identity
{
    "UserId": "XXXXXXXXXXXXXXXXXXXXXX:andrew@gitlab.com",
    "Account": "787839063675",
    "Arn": "arn:aws:sts::787839063675:assumed-role/AWSReservedSSO_AdministratorAccess_XXXXXXXX/andrew@gitlab.com"
}
gitlab env

This performs an OAuth2 PKCE exchange against gitlab.com and exports a temporary access token to the environment.

$ # Use OAuth2 to authenticate with GitLab.com
$ eval $(pmv gitlab env)
$ # Pass the OAuth2 token through the Authorization header
$ curl --header "Authorization: Bearer $GITLAB_OAUTH_TOKEN" https://gitlab.com/api/v4/user
{"id":895869,"username":"andrewn" ... }
$ # Alternatively, use the token with access_token request parameter
$ curl "https://gitlab.com/api/v4/user?access_token=$GITLAB_OAUTH_TOKEN"
{"id":895869,"username":"andrewn" ... }
google env

Performs an OAuth2 PKCE exchange against Google, and exports a temporary access token to the environment.

Unlike the default CLI, this command does not write credentials to the file ~/.config/gcloud/application_default_credentials.json.

$ # Use OAuth2 to authenticate with Google
$ eval $(pmv google env)
$ gcloud projects list
PROJECT_ID                      NAME                            PROJECT_NUMBER
aaa-111                         aaa-111                         123456789012
...
Organization Support

By default pmv google env will use the gitlab.com Google Organization, but other GitLab-controlled organizations can be selected using the --organization command-line argument.

Currently supported organizations are:

  1. gitlab.com: pmv google env --organization "gitlab.com" GitLab Main Organization
  2. gitlab-private.org: pmv google env --organization "gitlab-private.org" GitLab Dedicated Dev Organization

Additional organizations can be registered as needed.

Documentation ΒΆ

The Go Gopher

There is no documentation for this package.

Directories ΒΆ

Path Synopsis
internal
aws
op

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL