Skip to content

HashiCorp Vault

HashiCorp Vault is a software based general purpose secure storage for any sensitive information, such as keys, password or certificates. It has both opensource and commercial editions. The underlying architecture is extensible with plugins. Kaleido has taken advantage of the extensibility feature and provided a vault plugin that can be mounted as a secret engine and only supports using secret keys to sign transactions, without ever giving away the secret keys themselves. The vault can be installed by the customers themselves either under their own cloud accounts, or on-premise. This allows customers to deploy key management that meets all but the most stringent security criteria.

This document details the steps to:

  • Install and configure a HashiCorp Vault server with mutual TLS
  • Enable the vault plugin to create, store Ethereum compatible keys and sign Ethereum transactions
  • Create one or more keys in the vault that can be used to sign Ethereum transactions
  • Create user policies to restrict access privileges by Kaleido
  • Create and configure a Kaleido CloudHSM signer service which has the ability to interact with the Hashicorp Vault to sign and send transactions to an Ethereum node

Install and Configure a HashiCorp Vault server with Mutual TLS

HashiCorp offers both open source and commercial editions of the Vault server. Acquiring and installing a commercial edition for their additional features is beyond the scope of this documentation, but the basic steps are common to the open source edition, which are used for the steps below.

Install

Downloading and installing the HashiCorp Vault can be done easily at https://learn.hashicorp.com/vault/getting-started/install.

Server Start and Initialization

The server can be started with command line parameters or using a configuration file. Using a configuration file makes managing the parameters much easier. A sample configuration is provided below.

Sample server configuartion:

$ cat vault-config.hcl
/*
 * Production deployments obviously should use a database to save the secrets
 * "inmem" (in-memory) should only be used for non-production deployments
 */
storage "inmem" {}

listener "tcp" {
    address = "0.0.0.0:8200"
    /*
     * Configuration required for mutual TLS
     */
    tls_min_version = "tls12"
    tls_cert_file = "/home/ubuntu/certs/cert.pem"      // path to pem encoded server certificate
    tls_key_file = "/home/ubuntu/certs/key.pem"        // path to pem encoded server private key
    tls_require_and_verify_client_cert = "true"        // require client certificate from inbound requests
    tls_client_ca_file = "/home/ubuntu/certs/cert.pem" // path to client CA cert used to validate client certs
}

listener "tcp" {
    /*
     * Listener for local requests, used by operator who has access to vm where vault server is running.
     * can be used to initialize, seal and unseal vault server.
     * can also be used to create, revoke tokens and keys.
     */
    address = "127.0.0.1:8202"
    tls_disable = 1
}
/*
 * address used by server for api requests, plugins also talk to server using this address
 */
"api_addr"="https://127.0.0.1:8200"
"cluster_address"="http://127.0.0.1:8201"
"disable_mlock"="false"
/*
 * path where plugin binaries are stored, must NOT be a symbolic link
 */
"plugin_directory" = "/home/ubuntu/.vault_plugins"
  • Start the server.
$ sudo vault server -config=sample.hcl
  • Initialize the server. set VAULT_ADDR to the address you want to sent api request. Here we will use http://127.0.0.1:8202, per configuration above for local admin access, so that we can finish setting up our vault server.
$ export VAULT_ADDR=http://127.0.0.1:8202
$ vault operator init
Unseal Key 1: 5tUPxUzWDgbbAd1Loj80pPrCvndzPvD7/u/c8iyR7JzG
Unseal Key 2: iOD7FBvfVWK5dHRRd+tB6hnpCw0OqBZkH/8gayOhoAVd
Unseal Key 3: KxzDsijYWdT5ZtVxN4gd+pNWpZj14n+qCHdh7dZ+vytl
Unseal Key 4: gn3jTxK18m9LPihIZ9/hRsjDK++NFuHdZNM1W0aqGiZC
Unseal Key 5: 7kIeOztGOJqP2rQ1KIavDRsND+2yxD5ohw4aek+VgIDN

Initial Root Token: s.jTjGerieQNZCx4VZxqLWXl8p
  • We need to unseal the server. A sealed server can't accept any requests. Since vault was initialized with 5 key shares and requires a minimum of 3 keys to reconstruct master key, we need to send 3 unseal requests with these 3 keys. These keys should be distributed across the organization to be owned by different parties to enhance the security of the system. After 3 unseal keys are provided, Sealed in the server status turns to false, and the server is ready to be further configured.
$ vault operator unseal 7kIeOztGOJqP2rQ1KIavDRsND+2yxD5ohw4aek+VgIDN
Key                Value
---                -----
Seal Type          shamir
Initialized        true
Sealed             true
Total Shares       5
Threshold          3
Unseal Progress    1/3
Unseal Nonce       f905b0d4-1769-9d77-2a99-304b6e8fbdba
Version            1.3.2
HA Enabled         false
$ vault operator unseal 5tUPxUzWDgbbAd1Loj80pPrCvndzPvD7/u/c8iyR7JzG
Key                Value
---                -----
Seal Type          shamir
Initialized        true
Sealed             true
Total Shares       5
Threshold          3
Unseal Progress    2/3
Unseal Nonce       f905b0d4-1769-9d77-2a99-304b6e8fbdba
Version            1.3.2
HA Enabled         false
$ vault operator unseal gn3jTxK18m9LPihIZ9/hRsjDK++NFuHdZNM1W0aqGiZC
Key                Value
---                -----
Seal Type          shamir
Initialized        true
Sealed             false
Total Shares       5
Threshold          3
Unseal Progress    3/3
Unseal Nonce       f905b0d4-1769-9d77-2a99-304b6e8fbdba
Version            1.3.2
HA Enabled         false

Set Up Access Policies

HashiCorp Vault supports flexible management of policy-based access control and attaching policies to user credentials. Here we want to create a user for Kaleido to use as the transaction signer. It must have the ability to list signing accounts and sign transactions. It does not need the ability to create and delete keys, as the Kaleido service does not perform those functions.

The privilege to create and delete keys can be reserved to a separate administrator user under the customer control. The credentials with administrative privileges do not need to be shared with Kaleido.

  • Login into the vault using root token. This will allow us to setup access control policies and create corresponding token credentials via cli:
$ vault login s.jTjGerieQNZCx4VZxqLWXl8p
  • First create a policy with full administrative privileges over the signing key resources:
$ cat admin-policy.hcl
/*
 * Ability to create key and list existing keys
 */
path "ethereum/accounts" {
  capabilities = ["update", "list"]
}
/*
 * Ability to retrieve individual keys, sign transactions and delete keys
 */
path "ethereum/accounts/*" {
  capabilities = ["create", "read", "delete"]
}
/*
 * Ability to export private keys
 */
path "ethereum/export/accounts/*" {
  capabilities = ["read"]
}

$ vault policy write admin admin-policy.hcl
Success! Uploaded policy: admin
  • Create a user credential with the admin privileges defined above:
$ vault token create -policy=admin
Key                  Value
---                  -----
token                s.Qd8DJ5DyuZSiqEI7e4mADNsL
token_accessor       uWAQqubWbqFhTfQmQD5E1znA
token_duration       768h
token_renewable      true
token_policies       ["default" "admin"]
identity_policies    []
policies             ["default" "admin"] 

The token will be kept private by the customer for managing the keys.

  • Create another policy with key discovery and signing priviledges:
$ cat signer-policy.hcl
/*
 * Ability to list existing keys
 */
path "ethereum/accounts" {
  capabilities = ["list"]
}
/*
 * Ability to retrieve individual keys, sign transactions
 */
path "ethereum/accounts/*" {
  capabilities = ["create", "read"]
}

$ vault policy write signer signer-policy.hcl
Success! Uploaded policy: signer
  • Create a user token using signer policy:
$ vault token create -policy="signer"
Key                  Value
---                  -----
token                s.iEeZIJUKxsUSn2bj8gusUsUM
token_accessor       uWAQqubWbqFhTfQmQD5E1znA
token_duration       768h
token_renewable      true
token_policies       ["default" "signer"]
identity_policies    []
policies             ["default" "signer"] 

This token will later be shared with Kaleido when creating the Kaleido CloudHSM service.

Install Ethereum Signing Plugin

Kaleido has developed a HashiCorp Vault secret engine plugin that is able to generate secp256k1 EC signing keys and store them in the vault as secrets. The plugin provides abilities to create, read, delete, list key and using them to sign Ethereum transactions. This plugin must be installed on the Vault server.

  • Download the plugin code from the plugin repository.
  • Build the code by following the instructions in the README.
  • calculate checksum of the binary from the build.
$ export SHASUM256=$(shasum -a 256 "ethsign" | cut -d' ' -f1)
  • copy the binary to the plugins directory. This must be the same directory specified in the server configuration used to start the server.
$ cp ethsign /home/ubuntu/.vault_plugins/
  • Register the binary with vault server.
$ vault write sys/plugins/catalog/ethsign sha_256="${SHASUM256}" command="ethsign -tls-skip-verify -client-cert=/home/ubuntu/certs/cert.pem -client-key=/home/ubuntu/certs/key.pem -ca-cert=/home/ubuntu/certs/cert.pem"
Success! Data written to: sys/plugins/catalog/ethsign

Note: we pass the tls configurations to the plugin command as plugin communicates with the vault server at api_addr which is configured with Mutual TLS. -tls-skip-verify is not needed if the Vault server TLS cert is properly issued with a CN matching the server's hostname, or contains a Subject Alternative Name (SAN) extension that maps to the DNS hostname used by the server.

  • Enable the plugin. Note that the path used here, ethereum, must match the root path used to define the access policy as shown above, as in ethereum/accounts.
$ vault secrets enable -path=ethereum -description="Eth Signing Wallet" -plugin-name=ethsign plugin
Success! Enabled the ethsign secrets engine at: ethereum/
  • To confirm that plugin is enabled, check if it is listed as a secret engine.
$ vault secrets list
Path          Type         Accessor              Description
----          ----         --------              -----------
cubbyhole/    cubbyhole    cubbyhole_e64fa33a    per-token private secret storage
ethereum/     ethsign      ethsign_cc748358      Eth Signing Wallet
identity/     identity     identity_d91781f8     identity store
sys/          system       system_2f90e818       system endpoints used for control, policy and debugging

Create Ethereum Signing Keys

Create one or more Ethereum signing keys via the cli:

$ vault write  /ethereum/accounts ""
Key        Value
---        -----
address    0x1510dc6d97952c04c02adf712be35796a9993c45

Create keys using the REST API. Make sure the token with admin privileges are used:

$ export ADMIN=s.Qd8DJ5DyuZSiqEI7e4mADNsL
$ curl -H "Authorization: Bearer $ADMIN" -H "Content-Type: application/json" -d {} https://localhost:8200/v1/ethereum/accounts -X POST --cacert cert.pem  --key key.pem --cert cert.pem |jq
{
  "request_id": "81611246-8723-7cbf-0d89-a74574360c22",
  "lease_id": "",
  "renewable": false,
  "lease_duration": 0,
  "data": {
    "address": "0xd800a096000cc4eff8158d8bdafc8dae80c7c936",
  },
  "wrap_info": null,
  "warnings": null,
  "auth": null
}

Listing the keys inside the vault:

$  curl -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" https://localhost:8200/v1/ethereum/accounts -X LIST --cacert cert.pem  --key key.pem --cert cert.pem  |jq
{
  "request_id": "3cfa8897-4277-49a1-3e7c-748e38b58aae",
  "lease_id": "",
  "renewable": false,
  "lease_duration": 0,
  "data": {
    "keys": [
      "0x43e96b77cb6aee15fb82e85441f00a4ab07dbb93",
      "0x1510dc6d97952c04c02adf712be35796a9993c45",
      "0xd800a096000cc4eff8158d8bdafc8dae80c7c936"
    ]
  },
  "wrap_info": null,
  "warnings": null,
  "auth": null
}

For a full description of the APIs and commands to use with the vault plugin, visit the open source repository.

Provision Kaleido CloudHSM Signer service

We are now ready to provision the CloudHSM Signer service inside Kaleido.

  • Create a cloudhsm configuration to be used by the service to communicate with the HashiCorp Vault server.

The configuration for Azure Key Vault has the following mandatory parameters:

Field Usage
type Type of configuration. Must be cloudhsm
name Optional use-defined name for the configuration
membership_id ID of the membership under which this configuration is available
details
-- provider Cloud HSM backend provider. Must be hashicorp
-- target_address The base URL for key vault. For instance, https://ec2-3-143-201-31.us-east-2.compute.amazonaws.com:8200
-- user_secret Vault token created above for the signer user, which is authorized to list keys and sign transactions
-- vault_name Set this to the path for the Ethereum signing plugin. For instance ethereum as in the example above
-- tls
---- ca_certs Vault server TLS CA certificate
---- client_certs Client TLS certificate
---- client_cert_secret Client TLS secret key
---- insecure_skip_verify Only use this if the Vault server does not have a properly signed TLS server certificate during development or testing phase

The following is a sample POST request to create a HashiCorp Vault cloudhsm configuration:

https://console.kaleido.io/api/v1/consortia/:consortia_id/environments/:environment_is/configurations
POST body:
{
    "type": "cloudhsm",
    "name": "hsm-config-hashicorp",
    "membership_id": "azt2pkxbmd",
    "details": {
    "provider":"hashicorp",
    "target_address": "https://ec2-3-133-155-82.us-east-2.compute.amazonaws.com:8200",
    "user_secret":"s.jTjGerieQNZCx4VZxqLWXl8p",
    "vault_name": "ethereum",
    "tls": {
            "ca_certs":"-----BEGIN CERTIFICATE-----\nMIIFcTCCA1mgAwIBAgIUEfUF4NWVi8Uc9XexbVe8DZZteGowDQYJKoZIhvcNAQEL\nBQAwSDELMAkGA1UEBhMCVVMxOTA3BgNVBAMMMGVjMi0zLTEzMy0xNTUtODIudXMt\nZWFzdC0yLmNvbXB1dGUuYW1hem9uYXdzLmNvbTAeFw0yMDA0MTMxNjU0MTlaFw0y\nMTA0MTMxNjU0MTlaMEgxCzAJBgNVBAYTAlVTMTkwNwYDVQQDDDBlYzItMy0xMzMt\nMTU1LTgyLnVzLWVhc3QtMi5jb21wdXRlLmFtYXpvbmF3cy5jb20wggIiMA0GCSqG\nSIb3DQEBAQUAA4ICDwAwggIKAoICAQC+Jh6Inub4d+H/FxRb01lfY01HGME9aEVH\n492vNTvVESwyH9WQ8Yye0XZJo8rW+/ijI6sD3uNosE0KPofbDIehejPtOYwnOA+m\noGH3pWN0tFzqFCM0am6Ym8SSvWsmyYioWxGKNw+bhDXimIt7b6lOwfyTZvuzLzvd\n/PfbJCGadX59WjZnTkxUFzLrb4Vg3R3YPd/7Rey3wuuZ1KHVgNcnUjNluOTajn19\nN5d0P7EW8LlQbrFSYBLXD/65oIBke3aFe3BCDKaWFPZDYYfwFzm5bbQ2ifPKonhT\neO8jpA1ViOGA0e5cULylU9ZZiedzOjqdJGXtU/urAHiOXTbAtJua0Jzpqt0mrMOt\n4rfVtDS2hmfpwnJfNlE8ezLgCZZj74NEGueLZHHHzTJ8g/vH2xLlJD+Bo6DvkMND\nGXcYCEtzLZKQeXrVnTx/SVrBVyB1l86naHvzleO6z6QIBJyXz/P8D7ctTMYLQGQi\nvPYaWrHZLzVPaFRsIAVByDmH04BPT5YJ8MioZpzpd5ELc9g1BwjEj83peJQXqBZr\ndjRjhhlMxypTbXik8ganOL6Ks2fVkV5gN5oYcOSOIhvr9uFgBJhKMBFaINscHHkw\nz1V8RImsh+vDS+ftnfVANgCTYAOGqy4FSyn5bBA30xic4x6WrI60R2/8RaWS0uBf\nI8o6tN999wIDAQABo1MwUTAdBgNVHQ4EFgQU4JHuyWbpS1i1/d59PtXawz5kVssw\nHwYDVR0jBBgwFoAU4JHuyWbpS1i1/d59PtXawz5kVsswDwYDVR0TAQH/BAUwAwEB\n/zANBgkqhkiG9w0BAQsFAAOCAgEASVOf3UCoVcuE43C5gM14JONgIb5KkpiCCWQF\ndaBG1Wh3W6sO4ya+6KPBB6qNyPiXE5z8q6MB5Wpq6O714RovscpLSxgIf9x7icVv\nSriKomTp3NUqRGJ1jhkEmoQA6QoQS77IJwq78Cq2ad/kHhL5Tvg+/Yx3QU9InZhI\nYEIfL3NYnsNQeng03URBdXoZlL6MBXTMx1n30Wyo1VkvcGaNMJVugQ2Y8RXSPd6M\nPbxEmZ/EIBqtJh6ARjSF3FmeaWb05ltoX/t3iecXX/ypCOVc8qfR3+nFoSW9tAFi\nfTJ/OQTcyQjuWyRrqobZLKB5ThOs02OtaFJ3yehk6QXDsjRhtUDLH+Z8fCM+VWIx\nLgPYHS8KYN3e6CWCtzhLoVoFnVSvpu2Z0m7CBizV2dByo9NWwEGZGRWsU8tOWAOp\nHp9VTAfKXj7O7VbbHOQAP2oMaajDZEeXr1giqJUw3R/r4GC/z8UCvynW0cRhH1xh\nw90uRD6wB1QwYzzA9OLJPRXx5pzYfLGJMqK6xCQNP+VirEXJczWJkRu0xTkB3GHd\nVsqz0Yn6kKCsB7rAC4nfBpOQ+8Ah3LX8Bez2ek7kOJ7AZSRxGj7w+TILqxgvQQcU\nhMfzLAQiMpsN0VW8jOUW7Z1p8w4l8MzERIM2SK/BXHvpbZfHAImO70/74mXiwyYe\n/8urU9I=\n-----END CERTIFICATE-----\n",
            "client_certs": "-----BEGIN CERTIFICATE-----\nMIIFcTCCA1mgAwIBAgIUEfUF4NWVi8Uc9XexbVe8DZZteGowDQYJKoZIhvcNAQEL\nBQAwSDELMAkGA1UEBhMCVVMxOTA3BgNVBAMMMGVjMi0zLTEzMy0xNTUtODIudXMt\nZWFzdC0yLmNvbXB1dGUuYW1hem9uYXdzLmNvbTAeFw0yMDA0MTMxNjU0MTlaFw0y\nMTA0MTMxNjU0MTlaMEgxCzAJBgNVBAYTAlVTMTkwNwYDVQQDDDBlYzItMy0xMzMt\nMTU1LTgyLnVzLWVhc3QtMi5jb21wdXRlLmFtYXpvbmF3cy5jb20wggIiMA0GCSqG\nSIb3DQEBAQUAA4ICDwAwggIKAoICAQC+Jh6Inub4d+H/FxRb01lfY01HGME9aEVH\n492vNTvVESwyH9WQ8Yye0XZJo8rW+/ijI6sD3uNosE0KPofbDIehejPtOYwnOA+m\noGH3pWN0tFzqFCM0am6Ym8SSvWsmyYioWxGKNw+bhDXimIt7b6lOwfyTZvuzLzvd\n/PfbJCGadX59WjZnTkxUFzLrb4Vg3R3YPd/7Rey3wuuZ1KHVgNcnUjNluOTajn19\nN5d0P7EW8LlQbrFSYBLXD/65oIBke3aFe3BCDKaWFPZDYYfwFzm5bbQ2ifPKonhT\neO8jpA1ViOGA0e5cULylU9ZZiedzOjqdJGXtU/urAHiOXTbAtJua0Jzpqt0mrMOt\n4rfVtDS2hmfpwnJfNlE8ezLgCZZj74NEGueLZHHHzTJ8g/vH2xLlJD+Bo6DvkMND\nGXcYCEtzLZKQeXrVnTx/SVrBVyB1l86naHvzleO6z6QIBJyXz/P8D7ctTMYLQGQi\nvPYaWrHZLzVPaFRsIAVByDmH04BPT5YJ8MioZpzpd5ELc9g1BwjEj83peJQXqBZr\ndjRjhhlMxypTbXik8ganOL6Ks2fVkV5gN5oYcOSOIhvr9uFgBJhKMBFaINscHHkw\nz1V8RImsh+vDS+ftnfVANgCTYAOGqy4FSyn5bBA30xic4x6WrI60R2/8RaWS0uBf\nI8o6tN999wIDAQABo1MwUTAdBgNVHQ4EFgQU4JHuyWbpS1i1/d59PtXawz5kVssw\nHwYDVR0jBBgwFoAU4JHuyWbpS1i1/d59PtXawz5kVsswDwYDVR0TAQH/BAUwAwEB\n/zANBgkqhkiG9w0BAQsFAAOCAgEASVOf3UCoVcuE43C5gM14JONgIb5KkpiCCWQF\ndaBG1Wh3W6sO4ya+6KPBB6qNyPiXE5z8q6MB5Wpq6O714RovscpLSxgIf9x7icVv\nSriKomTp3NUqRGJ1jhkEmoQA6QoQS77IJwq78Cq2ad/kHhL5Tvg+/Yx3QU9InZhI\nYEIfL3NYnsNQeng03URBdXoZlL6MBXTMx1n30Wyo1VkvcGaNMJVugQ2Y8RXSPd6M\nPbxEmZ/EIBqtJh6ARjSF3FmeaWb05ltoX/t3iecXX/ypCOVc8qfR3+nFoSW9tAFi\nfTJ/OQTcyQjuWyRrqobZLKB5ThOs02OtaFJ3yehk6QXDsjRhtUDLH+Z8fCM+VWIx\nLgPYHS8KYN3e6CWCtzhLoVoFnVSvpu2Z0m7CBizV2dByo9NWwEGZGRWsU8tOWAOp\nHp9VTAfKXj7O7VbbHOQAP2oMaajDZEeXr1giqJUw3R/r4GC/z8UCvynW0cRhH1xh\nw90uRD6wB1QwYzzA9OLJPRXx5pzYfLGJMqK6xCQNP+VirEXJczWJkRu0xTkB3GHd\nVsqz0Yn6kKCsB7rAC4nfBpOQ+8Ah3LX8Bez2ek7kOJ7AZSRxGj7w+TILqxgvQQcU\nhMfzLAQiMpsN0VW8jOUW7Z1p8w4l8MzERIM2SK/BXHvpbZfHAImO70/74mXiwyYe\n/8urU9I=\n-----END CERTIFICATE-----\n",
            "client_cert_secret":"-----BEGIN PRIVATE KEY-----\n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\nbcdIDDDtGoRDNCqRRbx66DYfIh/HzFU=\n-----END PRIVATE KEY-----\n"
    }
    }
}

Create Kaleido CloudHSM Signer Service

Using the configuration created above, a Kaleido CloudHSM Signer service can be created using the request fields:

Field Usage
name Optional user-defined name for the service
membership_id ID of membership under which this service instance is available
service Type of service. Must be cloudhsm
details
-- cloudhsm_id ID of the configuration created in the previous step

The following is a sample POST request to create a Cloud HSM service that uses an Hashicorp Vault backend provider:

https://console.kaleido.io/api/v1/consortia/:consortia_id/environments/:environment_id/services
POST body:
{
  "name": "cloudhsm-hashicorp-0",
  "service": "cloudhsm",
  "membership_id": "azt2pkxbmd",
  "details": {
    "cloudhsm_id": "azq4eq76s0"
  }
}

Transaction Signing using Hashicorp Vault

Transactions can be sent to the Kaleido CloudHSM Signer service by specifying a from address that corresponds to a SECP256K1 type key that is present in the HashiCorp Vault. Any of RPC, WSS or the API Gateway interfaces can be used to send transactions. The URLs for the interfaces can be obtained by querying the service's /status route

A sample GET request to obtain the service status is as below:

https://console.kaleido.io/api/v1/consortia/:consortia_id/environments/:environment_id/services/:service_id/status

A sample response is as follows:

{
  "urls": {
    "http": "https://zztqmsszmp-zzprkw067k-cloudhsm.us0-aws.kaleido.io",
    "rpc-http": "https://zztqmsszmp-zzprkw067k-rpc.us0-aws.kaleido.io",
    "rpc-ws": "wss://zztqmsszmp-zzprkw067k-wss.us0-aws.kaleido.io"
  },
  "status": "live",
  "release": "0.1.12189",
  "awsCloudHsm": "live"
}

The rpc-http and rpc-ws URLs are used to send the transactions. When a transaction is received by the Kaleido CloudHSM Signer service, it uses the from address to determine whether the configured backend HashiCorp Vault contains the keys for the address. The service sends a /sign request with the from address and the transaction payload to Hashicorp Vault server. If the request succeeds, Vault plugin returns the signature with the proper R, S and V field as required by Ethereum, with the S field adjusted if necessary for malleability protection. The service then sends the signed transaction to the service's bound blockchain node, and completes the request.