This plugin implements a platform-agnostic REST-based HSM interface with zero library installation, while eliminating connectivity hurdles by using secure web connections (TLS). This facilitates the use and deployment in clustered and multi-cloud environments. Moreover, all Securosys HSM innovations like hardware enforced multi-authorization and high-performance encryption (ECIES, AES-GCM) are at one's disposal, for Vault Enterprise and Community Edition.
- Manage keys securely stored on the HSM
- Perform cryptographic operations on the HSM
- Use enhanced Primus HSM features such as high-performance encryption (ECIES, AES-GCM), or hardware-enforced multi-authorization workflows for compliance, signature services, or blockchain transactions.
This plugin is actively maintained by Securosys SA.
- Glossary
- How to build
- How to run
- Additional command options
- Help
- Test Suite
- Integrations
- Appendix
- Getting Support
- License
Term | Description |
---|---|
CloudsHSM | HSM as a service, operated by Securosys |
HSM | Hardware Security Module |
JSON | JavaScript Object Notation object |
JWT | JSON Web Token, used to authenticate and authorize users in web applications and APIs |
SKA | Smart Key Attributes, attributes adding rules to individual keys |
TSB | Transaction Security Broker, providing the REST interface |
XML | Extensible Markup Language, defines a set of rules for encoding documents in a format that is both human-readable and machine-readable. Format used for HSM key attestation. |
You can find pre-built releases of the plugin on the Securosys JFrog artifactory. Download the latest binary file corresponding to your target OS.
Further documentation and credentials are available via the Securosys Support Portal or the Securosys web-site.
Prerequisites: Install Golang 1.16+ (download)
-
Run
go mod init
. -
Build the secrets engine as plugin using Go.
$ CGO_ENABLED=0 go build -o vault/plugins/securosys_hsm cmd/securosys_hsm/main.go
-
Find the binary in
vault/plugins/
.$ ls vault/plugins/
-
Run a Vault server in
dev
mode to register and try out the plugin.$ vault server -dev -dev-root-token-id=root -dev-plugin-dir=./vault/plugins
-
Build and test in
dev
mode.$ make
-
Or to build
production
plugin with the samearchitecture
andos
on used machine$ make build
-
To build
production
version of this plugin, then use the command$ make release VERSION="1.0" #builds the plugin for the same architecture as the current machine
$ make release VERSION="1.0" OS="win" ARCH="i386" #builds the defined plugin version
-
To build
production
for all versions of this plugin, then use the command$ make release-all VERSION="1.0" #builds all available versions of the plugin
This command will build
production
versions for the following architectures and operating systemsOS Arch Darwin amd64 Darwin arm64 Windows 386 Windows amd64 Linux 386 Linux amd64 Linux arm Linux arm64 FreeBSD 386 FreeBSD amd64 FreeBSD arm NetBSD 386 NetBSD amd64 NetBSD arm OpenBSD 386 OpenBSD amd64 OpenBSD arm Solaris amd64 All these builds will be zipped, calculated and stored inside the build folder of this project.
In production mode the plugin has to be registered manually.
Add the following parameter in the configuration file config.hcl
plugin_directory
- must contain the absolute path to the directory where the plugins are stored
Command to register the plugin
$ vault plugin register -sha256={binary_checksum} secret securosys-hsm
To upgrade a binary of an existing working plugin, follow the steps below:
- Copy the new plugin binary to the plugin_directory.
- Register a new version of the plugin.
$ vault plugin register -sha256={binary_checksum} -version={new-version} secret securosys-hsm
- Tune the existing mount to reconfigure it to use the newly registered version.
$ vault secrets tune -plugin-version={new-version} securosys-hsm
- Reload the plugin
$ vault plugin reload -plugin securosys-hsm
After building the plugin, before running it on test server, it must be enabled with the following command:
$ vault secrets enable securosys-hsm
The result should be
$ Success! Enabled the securosys-hsm secrets engine at: securosys-hsm/
Configure the plugin for accessing the Securosys Primus HSM or CloudsHSM.
Required attributes:
auth
- Attribute defines the authorization type to TSB. Values for this attribute can beTOKEN
,CERT
orNONE
restapi
- REST API URL to access the REST/TSB endpoint (available from your Security Officer or CloudsHSM service provider)
Define additional attributes based on the selected authorization type auth
:
TOKEN
Add the attributebearertoken
with the JWT tokenCERT
Setupcertpath
with local PATH to the certificate andkeypath
with local PATH to the key.NONE
No additional attributes required.
Command to write the configuration to the plugin
$ vault write securosys-hsm/config {config_attributes}
curl --location --request PUT '<server_addr>/v1/securosys-hsm/config' \
--header 'X-Vault-Token: <vault_access_token>' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode '{config_attribute_key}={config_attribute_value}' \
Example for disabled authorization:
$ vault write securosys-hsm/config
auth="NONE"
restapi="https://primusdev.cloudshsm.com"
curl --location --request PUT '<server_addr>/v1/securosys-hsm/config' \
--header 'X-Vault-Token: <vault_access_token>' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'auth=NONE' \
--data-urlencode 'restapi=https://primusdev.cloudshsm.com'
Example for JWT token authorization:
$ vault write securosys-hsm/config
auth="TOKEN"
bearertoken="jwt token string"
restapi="https://primusdev.cloudshsm.com"
curl --location --request PUT '<server_addr>/v1/securosys-hsm/config' \
--header 'X-Vault-Token: <vault_access_token>' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'auth=TOKEN' \
--data-urlencode 'bearertoken=jwt token string' \
--data-urlencode 'restapi=https://primusdev.cloudshsm.com'
Example for Certificate authorization:
$ vault write securosys-hsm/config
auth="CERT"
certpath="local_absolute_path_to_certificate.pem"
keypath="local_absolute_path_to_private.key"
restapi="https://primusdev.cloudshsm.com"
curl --location --request PUT '<server_addr>/v1/securosys-hsm/config' \
--header 'X-Vault-Token: <vault_access_token>' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'auth=CERT' \
--data-urlencode 'certpath=local_absolute_path_to_certificate.pem' \
--data-urlencode 'keypath=local_absolute_path_to_private.pem' \
--data-urlencode 'restapi=https://primusdev.cloudshsm.com'
Note: On any changes of the configuration, the plugin will try to reach out the defined TSB using the provided configuration. If the connection was successful, the plugin will write/overwrite the configuration, otherwise the previous configuration remains unchanged.
From version 1.2.0
Additionally there is a option to generate signature for metadata on all asynchronous requests.
applicationKeyPair option is using to provide RSA public key and private key.
Using this key will be generated signature for metadata.
format '{\"privateKey\":\"private_key_string\",\"publicKey\":\"public_key_string\"}'
Note: You have to provide private key and public key without headers
Example:
$ vault write securosys-hsm/config
auth="CERT"
certpath="local_absolute_path_to_certificate.pem"
keypath="local_absolute_path_to_private.key"
restapi="https://primusdev.cloudshsm.com"
applicationKeyPair="{\"privateKey\":\"MIIEvgIBADANBg...\",\"publicKey\":\"MIIBIjANBgkqh...\"}"
From version 1.2.0 Secrets engine use only 3 of TSB api keys:
- ServiceToken - for health check
- KeyManagementToken - for creating/listing/deleting keys
- KeyOperationToken - for operations on keys like decrypt/encrypt, sign/verify etc.
Structure for api keys: There is a option to provide multiple api keys per single token. Plugin will check witch one of the list is correct one, and use only working token for operation.
apiKeys="{\"KeyManagementToken\":[\"tsb-x-token_key_management1\",\"tsb-x-token_key_management2\",\"tsb-x-token_key_management3\" ...],\"KeyOperationToken\":[\tsb-x-token_key_operation\"],\"ServiceToken\":[\"tsb-x-token_service\"]}"
Plugin configuration with api keys:
$ vault write securosys-hsm/config
auth="CERT"
certpath="local_absolute_path_to_certificate.pem"
keypath="local_absolute_path_to_private.key"
restapi="https://primusdev.cloudshsm.com"
apiKeys="{\"KeyManagementToken\":[\"tsb-x-token_key_management\"],\"KeyOperationToken\":[\tsb-x-token_key_operation\"],\"ServiceToken\":[\"tsb-x-token_service\"]}"
The plugin allows to create, modify, and manage keys on the Securosys Primus HSM or CloudsHSM by the following command sets:
-
list - List all keys stored in the HSM
$ vault list securosys-hsm/keys_hsm
curl --location --request LIST '<server_addr>/v1/securosys-hsm/keys_hsm' \ --header 'X-Vault-Token: <vault_access_token>'
-
list - List all keys stored in the Secrets Engine
$ vault list securosys-hsm/keys
or for more a more detailed list
$ vault list -detailed securosys-hsm/keys
curl --location --request LIST '<server_addr>/v1/securosys-hsm/keys' \ --header 'X-Vault-Token: <vault_access_token>'
-
list key versions - List all key versions stored in the Secrets Engine
$ vault list securosys-hsm/keys/{key-name}
or for a more detailed list
$ vault list -detailed securosys-hsm/keys/{key-name}
curl --location --request LIST '<server_addr>/v1/securosys-hsm/keys' \ --header 'X-Vault-Token: <vault_access_token>'
-
read - Read stored key info like key label, policy or public key
$ vault read securosys-hsm/keys/{key-name}
curl --location --request GET '<server_addr>/v1/securosys-hsm/keys/{key-name}' \ --header 'X-Vault-Token: <vault_access_token>'
Result of this command will be
Key Value --- --- algorithm {key-type} //For example: RSA, AES etc. attributes {key-attributes} key_size {key-size} keyLabel {key-label-hsm} policy {policy} //If exists public_key {public-key-from-hsm} //If exists. Only in asymetric key curveOid {cureveoid} //If exists. Only in EC or ED algorithms ...
-
write - Create or update a key on the HSM and store the reference in Secrets Engine Available key types:
-
aes
Required: keyLabel, attributes and keySize[128,192,256] Optionally: password
-
bls
Required: keyLabel and attributes Optionally: policy and password
-
camellia
Required: keyLabel, attributes and keySize[128,192,256] Optionally: password
-
chacha20
Required: keyLabel and attributes Optionally: password
-
dsa
Required: keyLabel, attributes and keySize[512,1024,2048] Optionally: policy and password
-
ec
Required: keyLabel, attributes and curveOid Optionally: policy and password
-
ed
Required: keyLabel, attributes and curveOid Optionally: policy and password
-
rsa
Required: keyLabel, attributes and keySize[1024,2048,3072,4096] Optionally: policy and password
-
tdea
Required: keyLabel, attributes Optionally: password
NOTE: All fields are described in Appendix: Key Arguments
IMPORTANT: All keys created via Secrets Engine, have by default set the key attributes [destroyable] and [modifiable]. These attributes can be changed or extended by defining them in the
attributes
argument.$ vault write securosys-hsm/keys/{key-type}/{key-name} keyLabel="{key-label-hsm}" keySize={key-size} #{key-attriute}:{true/false} attributes='{"decrypt": true,"sign": false,"unwrap": true,"derive": true,"sensitive": true,"extractable": false,"modifiable": true,"copyable": false,"destroyable": true}'
curl --location --request PUT '<server_addr>/v1/securosys-hsm/keys/{key-type}/{key-name}' \ --header 'X-Vault-Token: <vault_access_token>' \ --header 'Content-Type: application/x-www-form-urlencoded' \ --data-urlencode 'keyLabel={key-label-hsm}' \ --data-urlencode 'keySize={key-size}' \ --data-urlencode 'attributes={ #{key-attriute}:{true/false} "decrypt": true, "sign": false, "unwrap": true, "derive": true, "sensitive": true, "alwaysSensitive": true, "extractable": false, "neverExtractable": true, "modifiable": true, "copyable": false, "destroyable": true }'
Or here an example creating a key with attached simple approval policy:
$ vault write securosys-hsm/keys/{key-type}/{key-name} keyLabel="{key-label-hsm}" keySize={key-size} #{key-attriute}:{true/false} attributes='{"decrypt": true,"sign": false,"unwrap": true,"derive": true,"sensitive": true,"extractable": false,"modifiable": true,"copyable": false,"destroyable": true}' simplePolicy=-<<EOF { "NameOfApprover": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArBohRHhXXjQMNlxWMmCX0fxbpcMyu3bwBerkfeTl8QoOZbDV003t1n9drCuGOJJP16sZRBkYa5C7QkFCyb10Lbp1sp8jqWVu5PQy9qEaLl4y2BW+AOs0pURv1nlyo+gFgJD6lX0QmtZDjaD98C/wC5RVXipr4nJmT5XvwCPmgz9TpgVgFMwrflPJK9mHgYKwvmPODLYSLbohkj4TWKAoL417URhPazNWJBC7fKRui3EA7a8yzuzOSVgGxjY3aeqitmZyCTJtWa2U2/UwLZRT2ISwXv0zvsBhRSbXXcFdCApgKiy9uL1tPq40DnT8cesZzKd8hDYJ5S34wwmSZKbtGwIDAQAB" } EOF
curl --location --request PUT '<server_addr>/v1/securosys-hsm/keys/{key-type}/{key-name}' \ --header 'X-Vault-Token: <vault_access_token>' \ --header 'Content-Type: application/x-www-form-urlencoded' \ --data-urlencode 'keyLabel={key-label-hsm}' \ --data-urlencode 'keySize={key-size}' \ --data-urlencode 'attributes={ #{key-attriute}:{true/false} "decrypt": true, "sign": false, "unwrap": true, "derive": true, "sensitive": true, "alwaysSensitive": true, "extractable": false, "neverExtractable": true, "modifiable": true, "copyable": false, "destroyable": true }' \ --data-urlencode 'simplePolicy={ #{name}:{public_key} "NameOfApprover": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArBohRHhXXjQMNlxWMmCX0fxbpcMyu3bwBerkfeTl8QoOZbDV003t1n9drCuGOJJP16sZRBkYa5C7QkFCyb10Lbp1sp8jqWVu5PQy9qEaLl4y2BW+AOs0pURv1nlyo+gFgJD6lX0QmtZDjaD98C/wC5RVXipr4nJmT5XvwCPmgz9TpgVgFMwrflPJK9mHgYKwvmPODLYSLbohkj4TWKAoL417URhPazNWJBC7fKRui3EA7a8yzuzOSVgGxjY3aeqitmZyCTJtWa2U2/UwLZRT2ISwXv0zvsBhRSbXXcFdCApgKiy9uL1tPq40DnT8cesZzKd8hDYJ5S34wwmSZKbtGwIDAQAB" }'
Where
simplePolicy
has to be a JSON object in which Key is the name of the approval (or the approver) and Value has to be a valid RSA public key (without the "-- Begin..." and "-- End..." lines nor line breaks).The result of these commands will show information about the created key.
NOTE: Full SKA policy json can be provided by using the policy attribute in place of simplePolicy. As a policy json statement can be very large it might be difficult to edit it on command line. In such case it is recommended to attach a file with the json, using the attribute "[email protected]". An example of the policy json file can be found in Appendix: Full Policy JSON Example
-
-
register - Register an existing key stored on the HSM to Secrets Engine
$ vault write securosys-hsm/keys/{key-name}/register keyLabel={label-of-key-on-hsm}
curl --location --request PUT '<server_addr>/v1/securosys-hsm/keys/{key-name}/register' \ --header 'X-Vault-Token: <vault_access_token>' --header 'Content-Type: application/x-www-form-urlencoded' \ --data-urlencode 'keyLabel={label-of-key-on-hsm}'
NOTE: This key will be registered in Secrets Engine with the name {key-name}
-
create key by type name - Create a key using key types compatible with HashiCorp Key Management. (https://developer.hashicorp.com/vault/api-docs/secret/key-management)
Available key types:
Key Type Description aes128-gcm96 AES-GCM with a 128-bit AES key and a 96-bit nonce (symmetric) aes256-gcm96 AES-GCM with a 256-bit AES key and a 96-bit nonce (symmetric) chacha20-poly1305 ChaCha20 (symmetric) rsa-2048 RSA with bit size of 2048 (asymmetric) rsa-3072 RSA with bit size of 3072 (asymmetric) rsa-4096 RSA with bit size of 4096 (asymmetric) ecdsa-p256 ECDSA using the P-256 elliptic curve (asymmetric) ecdsa-p384 ECDSA using the P-384 elliptic curve (asymmetric) ecdsa-p521 ECDSA using the P-521 elliptic curve (asymmetric) ed25519 ED (asymmetric) $ vault write securosys-hsm/keys/type/{key-type-name}/{key-name} keyLabel={label-of-key-on-hsm} algorithm={key-algorithm} attributes={key-attributes} password={password} simplePolicy={policy} or policy={full-policy} or [email protected]
curl --location --request PUT '<server_addr>/v1/securosys-hsm/keys/type/{key-type-name}/{key-name}' \ --header 'X-Vault-Token: <vault_access_token>' --header 'Content-Type: application/x-www-form-urlencoded' \ --data-urlencode 'keyLabel={label-of-key-on-hsm}' \ --data-urlencode 'algorithm={key-algorithm}' \ --data-urlencode 'attributes={key-attributes}' \ --data-urlencode 'password={password}' \ --data-urlencode 'simplePolicy={policy}' or --data-urlencode 'policy={full-policy}'
NOTE: This key will be generated in Secrets Engine with the name {key-name}
-
import - Import a new key into the HSM
$ vault write securosys-hsm/keys/{key-name}/import keyLabel={label-of-key-on-hsm} privateKey={private-key-base64} publicKey={public-key-base64} secretKey={secret-key-base64} certificate={certificate-base64} algorithm={key-algorithm} attributes={key-attributes} simplePolicy={policy} or policy={full-policy} or [email protected]
curl --location --request PUT '<server_addr>/v1/securosys-hsm/keys/{key-name}/import' \ --header 'X-Vault-Token: <vault_access_token>' --header 'Content-Type: application/x-www-form-urlencoded' \ --data-urlencode 'keyLabel={label-of-key-on-hsm}' \ --data-urlencode 'privateKey={private-key-base64}' \ --data-urlencode 'publicKey={public-key-base64}' \ --data-urlencode 'secretKey={secret-key-base64}' \ --data-urlencode 'certificate={certificate-base64}' \ --data-urlencode 'algorithm={key-algorithm}' \ --data-urlencode 'attributes={key-attributes}' \ --data-urlencode 'simplePolicy={policy}' or --data-urlencode 'policy={full-policy}'
NOTE: This key will be labeled in Secrets Engine with {key-name}
-
export - Export public_key, private_key, or secret from a key stored on the HSM
$ vault write securosys-hsm/keys/{key-name}/export [password={password-for-a-key}]
curl --location --request PUT '<server_addr>/v1/securosys-hsm/keys/{key-name}/export' \ --header 'X-Vault-Token: <vault_access_token>' --header 'Content-Type: application/x-www-form-urlencoded' \ --data-urlencode 'password={password-for-a-key}'
NOTE: Omit the password parameter in case no password is set.
-
modify - Modify the SKA policy of a key stored on the HSM In case the key has a policy attached, then a request-id is returned indicating the required approvals to collect. See section Requests.
$ vault write securosys-hsm/keys/{key-name}/modify [simplePolicy={policy} | policy={full-policy} | policy=@policy-file.json] [password={password-for-a-key}] [additionalMetaData={additional-meta-data-in-json-object-format}]
curl --location --request PUT '<server_addr>/v1/securosys-hsm/keys/{key-name}/modify' \ --header 'X-Vault-Token: <vault_access_token>' --header 'Content-Type: application/x-www-form-urlencoded' \ --data-urlencode 'simplePolicy={policy}' or --data-urlencode 'policy={full-policy}' \ --data-urlencode 'password={password-for-a-key}' \ --data-urlencode 'additionalMetaData={additional-meta-data-in-json-object-format}'
NOTE: Omit the password parameter in case no password is set.
-
update-password - Modify the password of a key on the HSM
$ vault write securosys-hsm/keys/{key-name}/update-password password={current-password} newPassword="{new-password}"
curl --location --request PUT '<server_addr>/v1/securosys-hsm/keys/{key-name}/update-password' \ --header 'X-Vault-Token: <vault_access_token>' --header 'Content-Type: application/x-www-form-urlencoded' \ --data-urlencode 'password={current-password}' \ --data-urlencode 'newPassword={new-password}' \
-
rotate - Rotate a key. A new key will be generated on the HSM with the same base name as the original key with an incremented version tag at the end of the original key name (_v2, _v3, ...). The previous key will remain on the HSM.
$ vault write securosys-hsm/keys/{key-name}/rotate
curl --location --request PUT '<server_addr>/v1/securosys-hsm/keys/{key-name}/rotate' \ --header 'X-Vault-Token: <vault_access_token>' \ --header 'Content-Type: application/x-www-form-urlencoded'
NOTE: Decrypt, verify, unwrap etc. is still possible by providing the parameter keyVersion in the request. All other operations like encrypt, sign, wrap, block, unblock, password etc. will always use the last key version.
-
block - Block a key stored on the HSM In case the key has a policy attached, then a request-id is returned indicating the required approvals to collect. See section Requests.
$ vault write securosys-hsm/keys/{key-name}/block [password={password-for-a-key}] [additionalMetaData={additional-meta-data-in-json-object-format}]
curl --location --request PUT '<server_addr>/v1/securosys-hsm/keys/{key-name}/block' \ --header 'X-Vault-Token: <vault_access_token>' --header 'Content-Type: application/x-www-form-urlencoded' \ --data-urlencode 'password={password-for-a-key}' \ --data-urlencode 'additionalMetaData={additional-meta-data-in-json-object-format}'
NOTE: Omit the password parameter in case no password is set.
-
unblock - Unblock a key stored on the HSM In case the key has a policy attached, then a request-id is returned indicating the required approvals to collect. See section Requests.
$ vault write securosys-hsm/keys/{key-name}/unblock [password={password-for-a-key}] [additionalMetaData={additional-meta-data-in-json-object-format}]
curl --location --request PUT '<server_addr>/v1/securosys-hsm/keys/{key-name}/unblock' \ --header 'X-Vault-Token: <vault_access_token>' --header 'Content-Type: application/x-www-form-urlencoded' \ --data-urlencode 'password={password-for-a-key}' \ --data-urlencode 'additionalMetaData={additional-meta-data-in-json-object-format}'
NOTE: Omit the password parameter in case no password is set.
-
delete - Remove a key from the HSM and Secrets Engine
$ vault delete securosys-hsm/keys/{key-name} [removeFromHSM=true]
curl --location --request DELETE '<server_addr>/v1/securosys-hsm/keys/{key-name}' \ --header 'X-Vault-Token: <vault_access_token>'
NOTE: This operation removes the key only from the Secrets Engine. It does not remove the key from the HSM. To remove all key versions from the HSM as well, then add the property removeFromHSM with true value.
-
xml - Fetch a key attestation from the HSM in XML format, signed with the HSMs attestation key.
$ vault read securosys-hsm/keys/{key-name}/xml
curl --location --request GET '<server_addr>/v1/securosys-hsm/keys/{key-name}/xml' \ --header 'X-Vault-Token: <vault_access_token>' --header 'Content-Type: application/x-www-form-urlencoded' \
Below are the cryptographic operations that can be done using keys on the HSM.
-
Encrypt - Encrypt a payload
$ vault write securosys-hsm/operation/encrypt/{key-name} payload={base64-encoded-string} password={password-of-the-key} cipherAlgorithm={cipher-algorithm} tagLength={tag-length} additionalAuthenticationData={additional-authentication-data}
curl --location --request PUT '<server_addr>/v1/securosys-hsm/operation/encrypt/{key-name}' \ --header 'X-Vault-Token: <vault_access_token>' --header 'Content-Type: application/x-www-form-urlencoded' \ --data-urlencode 'payload={base64-encoded-string}' \ --data-urlencode 'password={password-for-a-key}' \ --data-urlencode 'cipherAlgorithm={cipher-algorithm}' \ --data-urlencode 'tagLength={tag-length}' \ --data-urlencode 'additionalAuthenticationData={additional-authentication-data}'
-
Decrypt - Decrypt an encrypted payload In case the referenced key has a policy attached, then a request-id is returned indicating the required approvals to collect. See section Requests.
Note: The keyVersion has to be provided in this request, either by adding it in the url (e.g.
securosys-hsm/operation/decrypt/{key-name}/{key-version}
), or by passing it as parameter (e.g.keyVersion={key-version}
).$ vault write securosys-hsm/operation/decrypt/{key-name} password={password-for-a-key} keyVersion={key-version} encryptedPayload={base64-encoded-string} cipherAlgorithm={cipher-algorithm} initializationVector={initialization-vector} tagLength={tag-length} additionalAuthenticationData={additional-authentication-data} additionalMetaData={additional-meta-data-in-json-object-format}
curl --location --request PUT '<server_addr>/v1/securosys-hsm/operation/decrypt/{key-name}' \ --header 'X-Vault-Token: <vault_access_token>' --header 'Content-Type: application/x-www-form-urlencoded' \ --data-urlencode 'encryptedPayload={base64-encoded-string}' \ --data-urlencode 'keyVersion={key-version}' \ --data-urlencode 'cipherAlgorithm={cipher-algorithm}' \ --data-urlencode 'password={password-for-a-key}' \ --data-urlencode 'tagLength={tag-length}' \ --data-urlencode 'initializationVector={initialization-vector}' \ --data-urlencode 'additionalAuthenticationData={additional-authentication-data}' \ --data-urlencode 'additionalMetaData={additional-meta-data-in-json-object-format}'
-
Sign - Sign a payload In case the referenced key has a policy attached, then a request-id is returned, indicating the required approvals to be collected. See section Requests
$ vault write securosys-hsm/operation/sign/{key-name} password={password-for-the-key} signatureAlgorithm={algorithm} payload={payload-base64} payloadType={payload-type} additionalMetaData={additional-meta-data-in-json-object-format}
curl --location --request PUT '<server_addr>/v1/securosys-hsm/operation/sign/{key-name}' \ --header 'X-Vault-Token: <vault_access_token>' --header 'Content-Type: application/x-www-form-urlencoded' \ --data-urlencode 'signatureAlgorithm={algorithm}' \ --data-urlencode 'payload={payload-base64}' \ --data-urlencode 'payloadType={payload-type}' \ --data-urlencode 'password={password-for-a-key}' \ --data-urlencode 'additionalMetaData={additional-meta-data-in-json-object-format}'
-
Verify - Verify the signature of a signed payload
Note: The keyVersion has to be provided in this request, either by adding it in the url (e.g.
securosys-hsm/operation/verify/{key-name}/{key-version}
), or by passing it as parameter (e.g.keyVersion={key-version}
).$ vault write securosys-hsm/operation/verify/{key-name} password={password-for-the-key} signatureAlgorithm={algorithm} payload={payload-base64} signature={signature}
curl --location --request PUT '<server_addr>/v1/securosys-hsm/operation/verify/{key-name}' \ --header 'X-Vault-Token: <vault_access_token>' --header 'Content-Type: application/x-www-form-urlencoded' \ --data-urlencode 'signatureAlgorithm={algorithm}' \ --data-urlencode 'payload={payload-base64}' \ --data-urlencode 'password={password-for-a-key}' \ --data-urlencode 'signature={meta-data-signature}'
-
Wrap - Wrap a key with another (wrapper) key
$ vault write securosys-hsm/operation/wrap/{key-to-be-wrapped}/{wrap-key-name} keyToBeWrappedPassword={password-for-first-key} wrapKeyPassword={password-for-second-key} wrapMethod={wrap-method}
curl --location --request PUT '<server_addr>/v1/securosys-hsm/operation/wrap/{key-to-be-wrapped}/{wrap-key-name}' \ --header 'X-Vault-Token: <vault_access_token>' --header 'Content-Type: application/x-www-form-urlencoded' \ --data-urlencode 'keyToBeWrappedPassword={password-for-first-key}' \ --data-urlencode 'wrapKeyPassword={password-for-second-key}' \ --data-urlencode 'wrapMethod={wrap-method}'
-
UnWrap - Unwrap a key using a wrapper key In case the referenced key has a policy attached, then a request-id is returned, indicating the required approvals to collect. See section Requests.
Note: The keyVersion has to be provided in this request, either by adding it in the url (e.g.
securosys-hsm/operation/unwrap/{new-unwrapped-key-name}/{wrap-key-name}/{key-version}
), or by passing it as parameter (e.g.keyVersion={key-version}
).$ vault write securosys-hsm/operation/unwrap/{new-unwrapped-key-name}/{wrap-key-name} keyLabel={key-label-for-new-key} keyVersion={key-version} wrappedKey={wrapped-key-base64-encoded} password={password-for-wrap-key} wrapMethod={wrap-method} simplePolicy={policy} or policy={full-policy} or [email protected] attributes={attributes} additionalMetaData={additional-meta-data-in-json-object-format}
curl --location --request PUT '<server_addr>/v1/securosys-hsm/operation/unwrap/{new-unwrapped-key-name}/{wrap-key-name}' \ --header 'X-Vault-Token: <vault_access_token>' --header 'Content-Type: application/x-www-form-urlencoded' \ --data-urlencode 'keyLabel={key-label-for-new-key}' \ --data-urlencode 'keyVersion={key-version}' \ --data-urlencode 'wrappedKey={wrapped-key-base64-encoded}' \ --data-urlencode 'wrapMethod={wrap-method}' \ --data-urlencode 'simplePolicy={policy}' or --data-urlencode 'policy={full-policy}' \ --data-urlencode 'password={password-for-wrap-key}' \ --data-urlencode 'attributes={attributes}' \ --data-urlencode 'additionalMetaData={additional-meta-data-in-json-object-format}'
In case a key has an SKA policy attached, a request object is returned instead of an instant result response, indicating the required approvals to be collected to process this request.
For example:
Key Value
--- -----
approvedBy map[]
executionTime n/a
id a0d1dc5c-3c0a-415f-a184-6eaffcb9fd07
notYetApprovedBy map[NameOfApprover:MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAouyYMgsCbxdr6cN7EDIR4ZcB82/fAIZusqyNXpX6gcRTwnrxZfIlyATdAm7ascxgYIK+L2M9UFVKTPUxus/Hzfuq0Fro5tdH+DWwfYQtcB5vap3UTw3yNpi6/MUe1x1Odwwi3no3jE2OuF1k6wjyrbWBkyktF3g8BmOD0DFpGl4IIlE8u1NgOMyAzlIuzAiyl4aCHrddhfV6gFtrRqfpUMz0twXYYoHlK0khzVEVn757WZZcIQFZmjKMfp/Yl/CAkBrTGVnFHMmNOYq7L9vhoR71rPmU9u2sy6IaT97qox/e7HSW47N2YNSiuJeq08I3Tn/kyw6+pSjAMu4A48PrfQIDAQAB]
rejectedBy map[]
request map[key:custom_rsa3 keyLabel:CUSTOM_RSA_4]
result n/a
status PENDING
type UnBlock
...
etc.
To handle such requests there are the following additional commands:
-
list - List all requests initialized in Secrets Engine
$ vault list securosys-hsm/requests
or for a more detailed list
$ vault list -detailed securosys-hsm/requests
curl --location --request LIST '<server_addr>/v1/securosys-hsm/requests' \ --header 'X-Vault-Token: <vault_access_token>'
-
read - Show detailed request information
$ vault read securosys-hsm/requests/{id}
curl --location --request GET '<server_addr>/v1/securosys-hsm/requests/{id}' \ --header 'X-Vault-Token: <vault_access_token>'
-
delete - Remove a request from Secrets Engine and HSM
$ vault delete securosys-hsm/requests/{id}
curl --location --request DELETE '<server_addr>/v1/securosys-hsm/requests/{id}' \ --header 'X-Vault-Token: <vault_access_token>'
All Securosys Secrets Engine commands have the additional options:
- -field (string: "") - Print only the field with the given name. Specifying this option will take precedence over other formatting directives. The result will not have a trailing newline making it ideal for piping to other processes.
- -format (string: "table") - Print the output in the given format. Valid formats are "table", "json", "yaml", or "raw". This can also be specified via the VAULT_FORMAT environment variable.
The command path-help will print help information of a specific path
$ vault path-help {path}
This plugin contains prepared tests written in Golang, which can be used to test changes or all features with the used Securosys Transaction Security Broker (TSB) instance.
First adapt the test configuration file additional_test_config.go
var configParams map[string]interface{} = map[string]interface{}{
"restapi": "TSB_ADDRESS",
"auth": "TOKEN",
"bearertoken": "BEARER_TOKEN",
}
Provide all necessary information in the test configuration file to gain access to the REST/TSB instance of your HSM. See Configuration section.
To run all tests execute the following command in a terminal
$ go test -timeout 30m -run ^(TestOperationsEncrypt|TestOperationsSign|TestOperationsWrap|TestConfig|TestAESKey|TestBLSKey|TestCHACHA20Key|TestCamelliaKey|TestECKey|TestEDKey|TestIMPORTKey|TestRSAKey|TestTDEAKey|TestDSAKey|TestOperationsDecrypt|TestOperationsVerify|TestOperationsUnWrap|TestRequests|TestRotateKeys|TestCreateKeyUsingTypeName)$ secretengine
Or run each test separately:
Test | Description |
---|---|
TestConfig | Tests write and read configuration of the plugin |
TestAESKey | Tests connection, create, read, and delete an AES key |
TestBLSKey | Tests connection, create, read, and delete a BLS key |
TestCamelliaKey | Tests connection, create, read, and delete a Camellia key |
TestCHACHA20Key | Tests connection, create, read, and delete a ChaCha20 key |
TestDSAKey | Tests connection, create, read, and delete a DSA key |
TestECKey | Tests connection, create, read, and delete an EC key |
TestEDKey | Tests connection, create, read, and delete an ED key |
TestIMPORTKey | Tests connection, import, read, and delete an Imported AES key |
TestRSAKey | Tests connection, create, read, and delete an RSA key |
TestTDEAKey | Tests connection, create, read, and delete a TDEA key |
TestKeys | Tests connection and all key operations (modify, block, unblock, list, register) |
TestOperationsDecrypt | Tests connection and synchronous decrypt operations for all types of keys |
TestOperationsEncrypt | Tests connection and encrypt operations for all types of keys |
TestOperationsSign | Tests connection and synchronous sign operations for all types of keys |
TestOperationsUnWrap | Tests connection and synchronous unwrap operations for all types of keys |
TestOperationsVerify | Tests connection and verify operations for all types of keys |
TestOperationsWrap | Tests connection and wrap operations for all types of keys |
TestRequests | Tests connection and all asynchronous operations (with policy) for all types of keys |
TestRotateKeys | Tests key rotation option for all type of keys |
TestCreateKeyUsingTypeName | Tests key creation based on types supported by Hashicorp Vault Key Management |
Encryption on MariaDB can be enabled using existing plugin Hashicorp Key Management Plugin This integration stores generated secret in Secrets engine, encrypted by provided key. Supported Key Types/Algorithm combinations:
Key Type | Algorithm |
---|---|
RSA | RSA_PADDING_OAEP_WITH_SHA512 RSA RSA_PADDING_OAEP_WITH_SHA224 RSA_PADDING_OAEP_WITH_SHA256 RSA_PADDING_OAEP_WITH_SHA1 RSA_PADDING_OAEP RSA_PADDING_OAEP_WITH_SHA384 RSA_NO_PADDING |
AES | AES_GCM AES_CTR AES_ECB AES_CBC_NO_PADDING AES |
CHACHA20 | CHACHA20 CHACHA20_AEAD |
CAMELLIA | CAMELLIA CAMELLIA_CBC_NO_PADDING CAMELLIA_ECB |
TDEA | TDEA_CBC TDEA_ECB TDEA_CBC_NO_PADDING |
Note - Plugin supports asynchronous decrypt operation using key type RSA with policy with setup ruleUse. Using the key with policy will stop the decrypt operation and wait for approvals to be collected.
There are a serval steps that is needed to be done before setup encryption on MariaDB
-
Create / Register key into Secrets Engine
-
Generate new secret and encrypt it using stored key
$ vault write securosys-hsm/integrations/mariadb/{secret-name} keyName={key-name-from-secret-engine} cipherAlgorithm={cipher-algorithm} [additionalAuthenticationData={additional-authentication-data}] [tagLength={tag-length}] [password={password-for-a-key}]
curl --location --request PUT '<server_addr>/v1/securosys-hsm/integrations/mariadb/{secret-name} ' \ --header 'X-Vault-Token: <vault_access_token>' --header 'Content-Type: application/x-www-form-urlencoded' \ --data-urlencode 'keyName={key-name-from-secret-engine}' \ --data-urlencode 'cipherAlgorithm={cipher-algorithm}' \ --data-urlencode 'tagLength={tag-length}' \ --data-urlencode 'additionalAuthenticationData={additional-authentication-data}' \ --data-urlencode 'password={password-for-a-key}'
Note - Every request on this endpoint using same key name and secret name will rotate secret
-
The last step is add this configuration to my.cfg
[mariadb] plugin-load-add=hashicorp_key_management.so loose-hashicorp-key-management loose-hashicorp-key-management-vault-url="{vault_address}/v1/securosys-hsm/integrations/mariadb/{secret_name}/?key_name={key-name}&cipher_algorithm={cipher_algorithm}&tag_length={tag_length}&aad={additional_authentication_data}&password={password}&version=" loose-hashicorp-key-management-token="{vault_access_token}" loose-hashicorp-key-management-check-kv-version="off" #max timeout is 86400 seconds loose-hashicorp-key-management-timeout=3000 loose-hashicorp-key-management-retries=0 loose-hashicorp-key-management-use-cache-on-timeout="on" loose-hashicorp-key-management-caching-enabled="on" #1 year in miliseconds loose-hashicorp-key-management-cache-timeout=31556952000 #1 year in miliseconds loose-hashicorp-key-management-cache-version-timeout=31556952000 #Example of innodb config innodb_encrypt_tables = ON innodb_encrypt_temporary_tables = ON innodb_encrypt_log = ON innodb_encryption_threads = 4 innodb_encryption_rotate_key_age = 1
Note - In loose-hashicorp-key-management-vault-url url need to ends with &version=. Plugin from MariaDB automatically add to end of url number of secret version
This example using default configuration for Hashicorp Vault dev server.
Data | Value |
---|---|
vault address | https://localhost:8200 |
vault access token | root |
- Create key MariaDBEncryptionKey with key size 4096 with attributes at last "decrypt" equals true on HSM and store it as mariadb_encryption_key on Secrets engine
or
$ vault write securosys-hsm/keys/rsa/mariadb_encryption_key keyLabel="MariaDBEncryptionKey" keySize=4096 attributes='{"decrypt": true,"sign": false,"unwrap": false,"derive": true,"sensitive": true,"extractable": false,"modifiable": false,"copyable": false,"destroyable": true}'
curl --location --request PUT 'https://localhost:8200/v1/securosys-hsm/keys/rsa/mariadb_encryption_key' \ --header 'X-Vault-Token: root' \ --header 'Content-Type: application/x-www-form-urlencoded' \ --data-urlencode 'keyLabel=MariaDBEncryptionKey' \ --data-urlencode 'keySize=4096' \ --data-urlencode 'attributes={ "decrypt": true, "sign": false, "unwrap": false, "derive": true, "sensitive": true, "extractable": false, "neverExtractable": true, "modifiable": false, "copyable": false, "destroyable": true }'
- Generate new secret called mariadb_secret and encrypt it using cipher algorithm RSA and stored key mariadb_encryption_key in Secrets engine
or
$ vault write securosys-hsm/integrations/mariadb/mariadb_secret keyName=mariadb_encryption_key cipherAlgorithm=RSA
curl --location --request PUT 'https://localhost:8200/v1/securosys-hsm/integrations/mariadb/mariadb_secret ' \ --header 'X-Vault-Token: root' --header 'Content-Type: application/x-www-form-urlencoded' \ --data-urlencode 'keyName=mariadb_encryption_key' \ --data-urlencode 'cipherAlgorithm=RSA'
-
Configure MariaDB plugin "Hashicorp Key Management" in database configuration in my.cnf
[mariadb] plugin-load-add=hashicorp_key_management.so loose-hashicorp-key-management loose-hashicorp-key-management-vault-url="https://localhost:8200/v1/securosys-hsm/integrations/mariadb/mariadb_secret/?key_name=mariadb_encryption_key&cipher_algorithm=RSA&version=" loose-hashicorp-key-management-token="root" loose-hashicorp-key-management-check-kv-version="off" #max timeout is 86400 seconds loose-hashicorp-key-management-timeout=3000 loose-hashicorp-key-management-retries=0 loose-hashicorp-key-management-use-cache-on-timeout="on" loose-hashicorp-key-management-caching-enabled="on" #1 year in miliseconds loose-hashicorp-key-management-cache-timeout=31556952000 #1 year in miliseconds loose-hashicorp-key-management-cache-version-timeout=31556952000 #Example of innodb config innodb_encrypt_tables = ON innodb_encrypt_temporary_tables = ON innodb_encrypt_log = ON innodb_encryption_threads = 4 innodb_encryption_rotate_key_age = 1
-
I got the error 'no handler for route "securosys-hsm/...". route entry found, but backend is nil.' In case of
no handler for route "securosys-hsm/...". route entry found, but backend is nil.
error, try to replace the secrets engine binary and to register the new upgraded plugin. See How to run > Upgrade plugin -
Why I don't get a public key and policy on some key types Some key types are symmetric, and therefore don't have a public key nor a SKA policy.
-
I have an error on unwrapping a key - status: 500, body: {"errorCode":701,"reason":"res.error.in.hsm","message":"Error unwrapping key"} Probably the provided key label is already in use with another key on the HSM, or the request contains a policy for a symmetric key.
keyLabel: The created key will be stored on the HSM with this name. This parameter is required.
attributes: The attributes of the key that should be created. At least one cryptographic operation (decrypt, sign, unwrap) must be allowed (true). This parameter is required.
Available key attributes:
- encrypt - The key can be used to encrypt data.
- decrypt - The key can be used to decrypt data.
- verify - The key can be used to verify signatures.
- sign - The key can be used to create signatures.
- wrap - The key can be used to wrap another key.
- unwrap - The key can be used to unwrap keys.
- derive - The key can be derivable. default: false
- bip32 - Key derivation is done using BIP32. This option can only be true if the key's algorithm is EC and the derive attribute is true. default: false
- extractable - The key is extractable. This option can only be true for keys without smart key attributes. default: false
- modifiable - The key can be modified. default: true
- destroyable - The key can be deleted. default: true
- sensitive - The key is sensitive. To export a key sensitive must be false
- copyable - The encrypted key is stored in an external memory. default: false
Structure Allows to define the attributes as a JSON object. Key = Value structure. For example:
{
"decrypt": true,
"sign": true,
"unwrap": true,
"derive": true,
"modifiable": true,
"copyable": false,
"destroyable": true
}
curveOid: The oid of the curve used for the EC or ED algorithm. Mandatory if the chosen algorithm is set to EC or ED. Sample OID's: secp256k1=1.3.132.0.10, Ed25519=1.3.101.112, secp384r1=1.3.132.0.34, (prime256v1 / secp256r1): 1.2.840.10045.3.1.7
keySize: The length of the key. Only applicable for AES, Camellia, RSA , DSA.
policy: Defines the SKA policy of a key. Contains the rules to use this key for signing a payload in a sign request, the rules to block and unblock this key, and the rules to modify the policy of this key. If a rule is empty the associated operation can be performed without any approvals. If the policy is empty the key does not use smart key attributes, and it is not possible to add them later. If a policy is used with the key, the key cannot be exported. Structure Allows to define all required approvals as a JSON object. Key = Value structure.
For example:
{
"TM": public_key_1,
"WK": public_key_2,
}
{
"ruleUse": {
"tokens": [
{
"name": "Token Name",
"timelock": 0,
"timeout": 0,
"groups": [
{
"name": "Group Name",
"quorum": 1,
"approvals": [
{
"type": "public_key",
"name": "Name",
"value": "RSA_PUBLIC_KEY"
}
]
}
]
}
]
},
"ruleBlock": {
"tokens": [
{
"name": "Token Name",
"timelock": 0,
"timeout": 0,
"groups": [
{
"name": "Group Name",
"quorum": 1,
"approvals": [
{
"type": "public_key",
"name": "Name",
"value": "RSA_PUBLIC_KEY"
}
]
}
]
}
]
},
"ruleUnblock": {
"tokens": [
{
"name": "Token Name",
"timelock": 0,
"timeout": 0,
"groups": [
{
"name": "Group Name",
"quorum": 1,
"approvals": [
{
"type": "public_key",
"name": "Name",
"value": "RSA_PUBLIC_KEY"
}
]
}
]
}
]
},
"ruleModify": {
"tokens": [
{
"name": "Token Name",
"timelock": 0,
"timeout": 0,
"groups": [
{
"name": "Group Name",
"quorum": 1,
"approvals": [
{
"type": "public_key",
"name": "Name",
"value": "RSA_PUBLIC_KEY"
}
]
}
]
}
]
},
"keyStatus": {
"blocked": false
}
}
Community Support for Securosys open source software: In our Community we welcome contributions. The Community software is open source and community supported, there is no support SLA, but a helpful best-effort Community.
- To report a problem or suggest a new feature, use the Issues tab.
Commercial Support for REST/TSB and HSM related issues: Securosys customers having an active support contract, open a support ticket via Securosys Support Portal.
Getting a temporary CloudsHSM developer account: Check-out a time limited developer account by registering here and choosing Trial Account.
Securosys Secrets Engine is licensed under the Apache License, please see LICENSE.