- A basic understanding of HashiCorp Vault (see What is Vault? for details).
- A HashiCorp Vault server.
- Note: This guide also includes quick start instructions for running a Vault server in development mode if you'd like to evaluate this plugin before starting to use it.
- The HashiCorp Vault CLI installed on your device.
- A 1Password Connect server deployed on your infrastructure.
- Go (if you want to build the plugin from source).
You can start HashiCorp Vault server in development mode to demonstrate and evaluate the 1Password secrets engine. Vault starts unsealed in this configuration, and you do not need to register the plugin.
vault server -dev -dev-root-token-id=root -dev-plugin-dir=./vault/plugins -log-level=debug
Warning: Running Vault in development mode is useful for evaluating the plugin, but should never be used in production.
Connect to the Vault server in a new terminal to enable the secrets engine and start using it.
- Download the release for your HashiCorp Vault server's architecture.
- Extract the binary and move it to the plugin directory for your Vault server.
Example for a Vault server running on a Linux machine with AMD64 architecture (note that you may need to update the filename depending on which OS and architecture you're using):
# Unzip the release archive
unzip ./vault-plugin-secrets-onepassword_1.1.0_linux_amd64.zip
# Create a plugin directory
mkdir -p ./vault/plugins
# Move the binary to the plugin directory and rename to op-connect
mv ./vault-plugin-secrets-onepassword_v1.1.0 ./vault/plugins/op-connect
Alternatively, you can also build the plugin binary from source:
# Clone this repository
git clone https://github.com/1Password/vault-plugin-secrets-onepassword.git
# Build the binary
go build -o ../vault/plugins/op-connect -C ./vault-plugin-secrets-onepassword ./main.go
Write the configuration file for the Vault server. For example:
cat > ./vault/server.hcl << EOF
plugin_directory = "$(pwd)/vault/plugins"
api_addr = "http://127.0.0.1:8200"
storage "inmem" {}
listener "tcp" {
address = "127.0.0.1:8200"
tls_disable = "true"
}
EOF
Note: You must set
plugin_directory
to point to the folder with your custom secrets engine andapi_addr
for the plugin to communicate with Vault. The Vault instance stores everything in memory and runs locally.
Start the Vault server with this configuration file:
vault server -config=./vault/server.hcl
Finally, connect to the Vault server in a new terminal.
Initialize and unseal Vault:
# Set VAULT_ADDR to connect to the local Vault server
export VAULT_ADDR='http://127.0.0.1:8200'
# Initialize Vault
vault operator init
# Unseal Vault with the unseal key
vault operator unseal
Next, calculate the SHA256 checksum of the plugin binary. For example, on Linux:
SHA256_CHECKSUM=$(sha256sum ./vault/plugins/op-connect | cut -d ' ' -f1)
Or, on macOS:
SHA256_CHECKSUM=$(shasum -a 256 .vault/plugins/op-connect | cut -d ' ' -f1)
Next, register the plugin to the catalog for the Vault server:
vault plugin register -sha256=$SHA256_CHECKSUM secret op-connect
Enable the op-connect
secrets engine at the op/
path:
vault secrets enable --path="op" op-connect
Note: You will need to provide the URL for your 1Password Connect server and your Connect access token for the next steps.
Write the configuration data to access your Connect server to op/config
in a single command (assuming the OP_CONNECT_
environment variables have been set):
vault write op/config \
op_connect_host=$OP_CONNECT_HOST \
op_connect_token=$OP_CONNECT_TOKEN
Alternatively, create a JSON file with your 1Password Connect server details. For example, save the following as op-connect-config.json
:
{
"op_connect_host": "https://op-connect.example.com:8443/",
"op_connect_token": "your_access_token"
}
Write the data to the op/config
path using this file to configure the secrets engine to access 1Password Connect server.
vault write op/config @op-connect-config.json
OP_CONNECT_TOKEN
: (required ifop_connect_token
is not set in configuration): The API token used to authenticate with the 1Password Connect API.
Note: When specifying the 1Password vault name or item title in the path, if multiple vaults or items have the same respective name or title, the action will be performed on the oldest vault or item. Item titles or vault names that include white space characters cannot be used (you can reference them using UUID instead).
Returns the names and UUIDs for the vault(s) that are accessible to the Connect access token:
vault list op/vaults
Returns the title and UUID for items stored in the specified 1Password vault:
vault list op/vaults/<vault_name_or_uuid>/items
Returns the data for the specified item:
vault read op/vaults/<vault_name_or_uuid>/items/<item_title_or_uuid>
Create an item from a JSON file (see Details for creating and updating items for more information on the JSON schema):
vault write op/vaults/<vault_name_or_uuid>/items @some_json_file.json
Update the specified item using a JSON file (see Details for creating and updating items for more information on the JSON schema):
vault write op/vaults/<vault_name_or_uuid>/items/<item_title_or_uuid> @some_json_file.json
Delete the specified item:
vault delete op/vaults/<vault_name_or_uuid>/items/<item_title_or_uuid>
See 1Password Connect Server API Reference for more details:
category
(required): the category of the item to create (database
,login
, andpassword
are currently supported)title
(required on create): a name for the itemurl
: the URL where the item may be filledfields
: an array of fields to create for the item; each field can be described with the following:id
: the ID of the field to createlabel
: the field name displayed in 1Password appstype
: the type of the field (STRING
,EMAIL
,CONCEALED
,URL
,TOTP
,DATE
,MONTH_YEAR
, andMENU
are currently supported)purpose
: the purpose of the field (""
,USERNAME
,PASSWORD
,NOTES
are currently supported)value
: the value stored in the fieldgenerate
(used forPASSWORD
fields): set totrue
to have 1Password generate the value.entropy
(used forPASSWORD
fields): set to an integer entropy valuesection
: the section to place the field; if not specified, the field will be placed in the default sectionid
: the ID of the section
sections
: an array of sections to create for the item; each section can be described with the following:id
: an ID for the sectionlabel
: how the section will be titled in the UI
{
"category": "login",
"title": "Example Login",
"fields": [
{
"id": "username",
"label": "username",
"type": "STRING",
"purpose": "USERNAME",
"value": "my_user"
},
{
"id": "password",
"label": "password",
"purpose": "PASSWORD",
"type": "CONCEALED",
"value": "",
"generate": true
},
{
"id": "custom_field_id",
"type": "STRING",
"label": "My Custom Field",
"value": "my custom value",
"section": {
"id": "my_new_section"
}
}
],
"sections": [
{
"id": "my_new_section",
"label": "New Section"
}
]
}
{
"category": "password",
"title": "Example Password",
"fields": [
{
"id": "password",
"label": "password",
"purpose": "PASSWORD",
"type": "CONCEALED",
"value": "",
"generate": true
}
]
}
{
"category": "database",
"title": "Example Database",
"fields": [
{
"id": "username",
"label": "username",
"type": "STRING",
"purpose": "USERNAME",
"value": "my_user"
},
{
"id": "password",
"label": "password",
"purpose": "PASSWORD",
"type": "CONCEALED",
"value": "",
"generate": true
},
{
"id": "hostname",
"label": "hostname",
"type": "STRING",
"value": "my_host"
},
{
"id": "database",
"label": "database",
"type": "STRING",
"value": "my_database"
},
{
"id": "port",
"label": "port",
"type": "STRING",
"value": "8080"
}
]
}
The 1Password secrets engine supports Vault Enterprise Namespaces. If you are using namespaces, the secrets engine must be enabled for each namespace.
You can use -namespace
to enable the plugin for each namespace. For example:
vault secrets enable -namespace=ns_example op
The plugin also requires configuration in the namespace. Write the configuration in a single command:
vault write -namespace=ns_example op/config \
op_connect_host=$OP_CONNECT_HOST \
op_connect_token=$OP_CONNECT_TOKEN
Alternatively, you can also create a file for the configuration and write the contents to the path (see Enable and configure the plugin above for an example file):
vault write -namespace=ns_example op/config @op-connect-config.json