Skip to content

Martini Vault Functions

Overview

Martini Vault Functions let you interact with HashiCorp Vault directly from your services and workflows. Use them to securely store and retrieve secrets with the KV secret engine, or to encrypt, decrypt, sign, and verify data using the transit secret engine. This removes the need to manage sensitive data in application code and centralizes secrets in a dedicated, auditable secret store.

What You Will Learn

  • How to write, read, and delete secrets in HashiCorp Vault using KV Engine v1 and KV Engine v2 functions
  • How to retrieve a specific secret field value using readData and readVersionedData
  • How to restore or permanently destroy a specific secret version in KV Engine v2
  • How to encrypt and decrypt data using the transit secret engine
  • How to sign data and verify signatures using transit engine signing keys
  • How to rotate encryption keys and rewrap existing ciphertext to the latest key version

When To Use This

Use Vault Functions when you need to keep sensitive data — such as passwords, API keys, or tokens — out of your code and managed in a centralized, auditable secret store.

  • Use this when you need to read, write, or delete secrets stored in HashiCorp Vault.
  • Use this when you need to encrypt sensitive values before storing or transmitting them, or decrypt previously encrypted data at runtime.
  • Use this when you want to sign data and later verify its signature to confirm integrity and authenticity.
  • Use this when you need to rotate transit keys or rewrap ciphertext as part of a key lifecycle management process.

Prerequisites

KV Engine Secret Management

Martini provides KV Engine functions for storing, retrieving, and removing secrets in HashiCorp Vault. Functions are available for both KV Engine v1 (unversioned) and KV Engine v2 (versioned), so you can choose the appropriate engine based on how your Vault instance is configured.

Understanding the packageName Parameter

Every Vault Function accepts a packageName input parameter that determines which Martini package's Vault configuration to use. Understanding when to provide this value is essential for connecting to the correct Vault instance.

Scenario What to Set packageName To
Vault is configured in the same package you are working in Leave empty — no value required
Vault is configured in a different package in your workspace Provide the name of the package that holds the Vault configuration

No Dependency Required

The package containing the Vault configuration does not need to be a dependency of your current package. It only needs to be started in the current workspace.

Writing Secrets to Vault

Use these functions to store key-value secret data at a path in HashiCorp Vault. Each function targets a specific KV engine version.

Function Engine Version Description
write(packageName, task) KV v1 Writes secret data without versioning
writeVersioned(packageName, task) KV v2 Writes secret data and creates a new secret version

Required task properties:

Property Applicable To Description
mountPath writeVersioned only The KV v2 engine mount point
pathToKey Both The Vault path where the secret will be stored
values Both A data model array of key-value entries representing the secret's fields

The task.values property holds one entry per secret field. Specify the field name in key and its value in value. Add more entries to include additional fields:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
// Database credentials

values {
  key = username
  value = reporting_service
}

values {
  key = password
  value = mySecurePassword
}

Return values:

Function Output Model Notes
write(...) vaultResponse KV v1 does not return any data on write, so response properties are null
writeVersioned(...) versionedResponse Returns the version number and metadata of the stored secret

Reading Secrets from Vault

Use these functions to retrieve secret data stored in HashiCorp Vault. You can retrieve all fields at a path, or target a single field by name.

Retrieve all fields at a path:

Function Engine Version Description
read(packageName, task) KV v1 Reads all secret data without versioning
readVersioned(packageName, task) KV v2 Reads all secret data at a specific version

Required task properties:

Property Applicable To Description
mountPath readVersioned only The KV v2 engine mount point
pathToKey Both The Vault path to read from
version readVersioned only (Optional) The version to retrieve. Omit to return the latest version

The secret fields are returned under the data model of the response. Access them via vaultResponse.data (KV v1) or versionedResponse.data (KV v2):

1
2
3
4
data {
  userName = reporting_service
  password = mySecurePassword
}

Retrieve a single field by name:

Function Engine Version Description
readData(packageName, task, fieldKey) KV v1 Returns the value of a single field without versioning
readVersionedData(packageName, task, fieldKey) KV v2 Returns the value of a single field at a specific version

Set fieldKey to the name of the field you want to retrieve. Both functions return the field value as a String. The task properties follow the same requirements as read and readVersioned respectively.

Deleting Secrets from Vault

Use these functions to remove secret data from HashiCorp Vault. KV v2 supports soft-deletion and permanent destruction in addition to standard deletion.

Standard deletion (KV v1 and KV v2):

Function Engine Version Description
delete(packageName, task) KV v1 Removes the secret at the specified path
deleteVersioned(packageName, task) KV v2 Soft-deletes a specific version at the specified path

Required task properties:

Property Applicable To Description
mountPath deleteVersioned only The KV v2 engine mount point
pathToKey Both The Vault path of the secret to delete
version deleteVersioned only (Optional) The version to delete. Omit to target the latest version

KV v2 version lifecycle management:

KV v2 provides two additional operations for managing the lifecycle of versioned secrets beyond soft-deletion:

Function Description When to Use
undeleteVersioned(packageName, task) Restores a soft-deleted version of the secret When you need to recover a previously deleted version
destroyVersioned(packageName, task) Permanently removes a specific version — cannot be undone When you need to irreversibly destroy a version

For both undeleteVersioned and destroyVersioned, the following task properties are all required:

Property Description
mountPath The KV v2 engine mount point
pathToKey The Vault path of the secret
version The specific version to target

Transit Secret Engine Operations

The Vault transit secret engine provides cryptographic operations — encryption, decryption, signing, and signature verification — without exposing key material. Martini exposes these capabilities through transit functions that integrate directly into your services and workflows.

Transit Key Requirement

The transit key used in any transit function must already exist in Vault before invoking these functions.

All transit functions also accept a packageName parameter. See Understanding the packageName Parameter for details on when to provide it.

Encrypting Data with Vault Transit

Use these functions to encrypt plaintext data using a named transit key. The resulting ciphertext can be safely stored or transmitted, and later decrypted using decrypt(...).

Function Input Type Description
encryptString(packageName, task) String Encrypts a string plaintext value
encryptByteArray(packageName, task) Byte array Encrypts a byte array plaintext value

Required task properties:

Property Description
mountPath The transit engine mount point
transitOpts.encryptionKey The name of the transit key to use for encryption
transitOpts.plaintextAsString The string value to encrypt (for encryptString)
transitOpts.plaintextAsByteArray The byte array value to encrypt (for encryptByteArray)

Output — cipherText data model:

Property Description
cipherText The encrypted value
context A data model carrying any additional encryption context

Decrypting Data with Vault Transit

Use the decrypt function to convert a Vault-encrypted ciphertext back to its original plaintext form. Use the same transit key that was used during encryption.

Function Description
decrypt(packageName, task) Decrypts a ciphertext value using the specified transit key

Required task properties:

Property Description
mountPath The transit engine mount point
transitOpts.encryptionKey The name of the transit key to use for decryption
transitOpts.ciphertext The ciphertext value to decrypt

Output — plainText data model:

Property Description
plainText The decrypted value, returned as a byte array
context A data model carrying any additional decryption context

Rewrapping and Rotating Transit Keys

Vault lets you rotate transit keys and rewrap existing ciphertext to the new key version, enabling ongoing key hygiene without disrupting existing secrets.

Rewrap ciphertext to the latest key version:

Use rewrap(packageName, task) to re-encrypt an existing ciphertext under the latest version of its transit key. Run this after rotating a key to bring existing ciphertext up to date.

Required task properties:

Property Description
mountPath The transit engine mount point
transitOpts.encryptionKey The name of the transit key
transitOpts.ciphertext The ciphertext to re-encrypt

Output: A String containing the rewrapped ciphertext under the latest key version.


Rotate the transit key version:

Use rotate(packageName, task) to advance the transit key to a new version. After rotation, new encryption operations use the updated key version. Existing ciphertext encrypted under previous versions can be brought up to date using rewrap(...).

Required task properties:

Property Description
mountPath The transit engine mount point
transitOpts.encryptionKey The name of the transit key to rotate

Signing Data with Vault Transit

Use these functions to generate a cryptographic signature for a plaintext value using a transit key that supports signing operations. Signatures can later be verified with verifyString(...) or verifyByteArray(...).

Signing Capability Requirement

The transit key used for signing must support signing operations.

Function Input Type Description
signString(packageName, task) String Signs a string plaintext value
signByteArray(packageName, task) Byte array Signs a byte array plaintext value

Required task properties:

Property Description
mountPath The transit engine mount point
transitOpts.encryptionKey The name of the signing key
transitOpts.plaintextAsString The string plaintext to sign (for signString)
transitOpts.plaintextAsByteArray The byte array plaintext to sign (for signByteArray)

Output — signature data model:

Property Description
signature The generated signature value

Verifying Signatures with Vault Transit

Use these functions to confirm that a signature matches the expected plaintext, verifying that the data has not been altered. Use the transit key name associated with the signature.

Function Input Type Description
verifyString(packageName, task) String Verifies the signature of a string plaintext
verifyByteArray(packageName, task) Byte array Verifies the signature of a byte array plaintext

Required task properties:

Property Description
mountPath The transit engine mount point
transitOpts.encryptionKey The name of the transit key used to create the original signature
transitOpts.plaintextAsString The original string plaintext (for verifyString)
transitOpts.plaintextAsByteArray The original byte array plaintext (for verifyByteArray)
transitOpts.signature The signature to verify

Output: Returns true if the signature is valid, false if it is not.

Troubleshooting

Problem Detection Cause Fix
Error thrown when invoking any Vault function Runtime error stating that the Vault feature is not supported Vault has not been configured in Martini Configure Vault in Martini, then restart the package before retrying
readData(...) returns null Function output is null even though the secret exists at the path The value in fieldKey does not match any stored field name — field names are case-sensitive Use read(...) or readVersioned(...) to inspect the available field names at the path, then update fieldKey to match exactly
Function fails with a mount-related error Runtime error indicating the mount path was not found or is invalid The mountPath value does not match the actual engine mount point configured in Vault Verify the correct mount path in your Vault instance and update mountPath to match
Transit key not found Runtime error referencing an unknown or missing key name The key specified in transitOpts.encryptionKey does not exist in Vault Create the transit key in Vault before invoking any encryption, decryption, signing, or verification function
signString(...) or signByteArray(...) fails Runtime error from Vault indicating the key does not support signing operations The transit key specified in transitOpts.encryptionKey was not created with signing capability Use a transit key that supports signing

Helpful Resources