Skip to main content

Build your own shell plugins (beta)

If you don't see your favorite command-line tool listed in the 1Password Shell Plugin registry, you can write your own plugin.

1Password CLI allows you to build and test shell plugins locally, so you can add support for authenticating your favorite CLI using a credential you saved in 1Password.

If you want to make your plugin available to others, you can create a pull request in the shell plugins GitHub repository.

Requirements

Concepts

A 1Password Shell Plugin should describe the following:

  • The credential offered by a platform
  • The CLI or executable offered by a platform
  • How the credential should be provisioned for the respective CLI to authenticate
  • Which commands for the respective CLI need authentication
  • How credentials stored on the local filesystem can be imported into 1Password

Shell plugins are written in Go and consist of a set of Go structs in a package that together make up the plugin for a certain platform, service, or product. Don't worry if you're not a Go expert – there are lots of examples you can learn from to build your plugin!

Step 1: Use the plugin template

First, clone or fork the 1Password Shell Plugins repository on GitHub. It contains the current plugin registry, as well as the SDK needed to contribute.

To get started with those, use the following Makefile command:

You'll be prompted to enter the following information:

  • Plugin name: Lowercase identifier for the platform, e.g. aws, github, digitalocean, azure. This will also be used as the name of the Go package.
  • Plaform display name: The display name of the platform, e.g AWS, GitHub, DigitalOcean, Azure.
  • Credential name: The credentials the platform offers, e.g. Personal Access Token, API Key, Auth Token.
  • Executable name: The command to invoke, e.g. aws, gh, doctl, az.

After filling in the form, you'll see a Go package created in the plugins directory, with separate files for the plugin, credential, and executable. For example:

To save you some time, the generated files will be stubbed out with information that's derived from the Makefile prompts on a best-effort basis. It contains TODO comments in the code to steer you in the direction of what to change or validate for correctness.

Step 2: Edit the plugin definition

The plugin.go file contains basic information about the plugin and the platform it represents, including which credential types and executables make up the plugin.

Plugin Examples

Step 3: Edit the credential definition

The credential definition file describes the schema of the credential, how the credential should get provisioned to executables, and how the credential can be imported into 1Password.

Credential information and schema

The first section of the credential definition is where you can add information about the credential:

  • The name of the credential, as the platform calls it.
  • The documentation URL provided by the platform that describes the credential. (optional)
  • The management URL on the platform where the credential can be created and revoked. This is usually a URL to the dashboard, console, or authentication settings of the platform. (optional)

The next section is where you define the schema of the credential. This is segmented into fields. Many credentials consist of just a single secret field, but you can add more fields to add more details to the 1Password item that are related to authentication, even if the fields are not secret.

Examples of additional fields are: the host, username, account ID, and all other things that are needed to authenticate and make sense to include in the 1Password item for the credential type. All fields you declare here will also show up in the end user's 1Password item.

Here's what you can specify per field:

  • The field name, titlecased. (required)
  • A short description of the field. This supports markdown. (required)
  • Whether the field is optional. Defaults to false.
  • Whether the field is secret, and should be concealed in the 1Password GUI. Defaults to not secret.
    Note: The credential schema is expected to contain at least 1 secret field.
  • What the actual credential value is composed of. The length, character set, and whether it contains a fixed prefix.

Provisioner

The credential definition also specifies how the credential is usually provisioned to exectuables, in order for them to use the credential for authentication.

Provisioners are in essence hooks that get executed before the executable is run by 1Password CLI, and after the executable exits in case any cleanup is needed. In those hooks, provisioners can do all the setup required for the executable to authenticate, including setting environment variables, creating files, adding command-line arguments, or even generating temporary credentials. After the executable exits, there should be no trace of the credentials on the user's filesystem.

The SDK provides a few common provisioners out of the box, so in most cases you don't have to care about the provisioning internals.

Some CLIs only support reading credentials from files on disk. In that case, you can use the file provisioner provided by the SDK. The file provisioner takes care of creating the file in a temporary directory and deleting it afterwards.

For security purposes, the file created by the file provisioner can only be read once by the executable. If that limitation does not work for your use case, you can file an issue on GitHub.

Here are a few examples on how you can use the file provisioner to provision a temporary JSON file and pass the generated path to the executable:

Create a file provisioner and pass output path as --config-file

Create a file provisioner and set output path as CONFIG_FILE_PATH

Create a file provisioner and pass output path as Java property

Code to generate JSON file contents

Importer

The credential definition also lets you specify importers. Importers are responsible for scanning the user's environment and file system for any occurrences of the needed credentials. 1Password CLI will run the importer and prompt the user to import their credentials one by one into 1Password.

It's very common for CLIs to write authentication data to disk, most commonly in a hidden config file in your home directory. This is not always documented by the CLI, so here are some tips to figure out if such a config file exists:

  • Check the platform's documentation for mentions of config files.
  • See if the CLI offers a login, auth, configure, or setup command that covers authentication. If it does, it's pretty likely there's a credential being stored in your home directory after completing such a flow.
  • If the CLI is open source, check the source code to see if such a file exists.
  • Look at your own home directory or ~/.config directory to see if there are files related to the platform. Here's an example command to find local aws configuration files:

The SDK provides helper functions to load files, parse files, and scan environment variables to make writing an importer for your credential type easier.

Importer Examples

Step 4: Edit the executable definition

The last thing the plugin is responsible for is to define the CLI or executable that you'd like 1Password to handle authentication for. This is the final piece that glues everything together.

The executable definition describes the following:

  • The command that should get executed by the 1Password CLI.
  • The display name of the CLI, as the platform calls it.
  • The documentation URL provided by the platform that describes the executable. (optional)
  • When the executable needs authentication. For example, many CLIs don't require authentication when the --help or --version flags are present.
  • The credentials that the executable uses.
Executable Examples

Step 5: Build and test your plugin locally

To see if you've properly filled out the plugin, credential, and executable defintions, you can run the following Makefile command to validate the definitions:

If that succeeds, it's now time to locally build and test your plugin! You can do so using the following command:

The build artifact will be placed in ~/.op/plugins/local. It should show up in op if you run the following command:

To see it in action, you can use the op plugin init command:

Submit a PR

While you're free to keep on using the plugin locally, we'd encourage you to submit a PR on the main registry on GitHub so others can use it too!

Before doing so, be sure to read the CONTRIBUTING.md file on GitHub.

If you feel that the SDK does not serve your use case well, reach out to us by creating an issue on GitHub or by joining our Developer Slack workspace to tell us about your plugin proposal. We can advise you on the most suitable approach for your use case.

Learn more

Was this page helpful?