HashiCorp Vault — Sign & Verify

2 minute read

Transit supports digital signatures and HMAC for verifying data integrity and authenticity.


Signing Key Types

Key Type Supports Signing Algorithm
ed25519 ✅ EdDSA
ecdsa-p256 ✅ ECDSA
ecdsa-p384 ✅ ECDSA
ecdsa-p521 ✅ ECDSA
rsa-2048 ✅ RSA-PSS / PKCS1v15
rsa-3072 ✅ RSA-PSS / PKCS1v15
rsa-4096 ✅ RSA-PSS / PKCS1v15
aes256-gcm96 ❌ (HMAC only) —

Create a Signing Key

vault write transit/keys/signing-key type=ed25519

Sign Data

# Sign data
vault write transit/sign/signing-key \
    input=$(echo -n "data to sign" | base64)

Expected output:

Key            Value
---            -----
key_version    1
signature      vault:v1:MEUCIQDl...base64signature...

Pre-hashed Signing

If you’ve already hashed the data:

# Hash first, then sign
HASH=$(echo -n "data to sign" | shasum -a 256 | cut -d' ' -f1 | xxd -r -p | base64)

vault write transit/sign/signing-key \
    input="$HASH" \
    prehashed=true \
    hash_algorithm=sha2-256

Verify Signature

vault write transit/verify/signing-key \
    input=$(echo -n "data to sign" | base64) \
    signature="vault:v1:MEUCIQDl..."

Expected output:

Key      Value
---      -----
valid    true

If the data or signature is tampered with:

vault write transit/verify/signing-key \
    input=$(echo -n "tampered data" | base64) \
    signature="vault:v1:MEUCIQDl..."
Key      Value
---      -----
valid    false

HMAC

HMAC uses symmetric keys (works with aes256-gcm96 keys):

# Generate HMAC
vault write transit/hmac/my-app-key \
    input=$(echo -n "data to authenticate" | base64)

Expected output:

Key     Value
---     -----
hmac    vault:v1:base64hmac...
# Verify HMAC
vault write transit/verify/my-app-key \
    input=$(echo -n "data to authenticate" | base64) \
    hmac="vault:v1:base64hmac..."

Use Cases

Artifact Signing in CI/CD

# In CI pipeline: sign the build artifact
ARTIFACT_HASH=$(sha256sum my-app.tar.gz | cut -d' ' -f1 | xxd -r -p | base64)
SIGNATURE=$(vault write -field=signature transit/sign/ci-signing-key \
    input="$ARTIFACT_HASH" prehashed=true hash_algorithm=sha2-256)

# Store signature with artifact
echo "$SIGNATURE" > my-app.tar.gz.sig

# In deployment: verify the artifact
ARTIFACT_HASH=$(sha256sum my-app.tar.gz | cut -d' ' -f1 | xxd -r -p | base64)
RESULT=$(vault write -field=valid transit/verify/ci-signing-key \
    input="$ARTIFACT_HASH" \
    signature="$(cat my-app.tar.gz.sig)" \
    prehashed=true \
    hash_algorithm=sha2-256)

if [ "$RESULT" = "true" ]; then
    echo "✅ Artifact verified — safe to deploy"
else
    echo "❌ Signature invalid — DO NOT deploy"
    exit 1
fi

API Request Signing

# Sign an API payload
PAYLOAD='{"amount": 100, "currency": "USD"}'
SIGNATURE=$(vault write -field=signature transit/sign/api-key \
    input=$(echo -n "$PAYLOAD" | base64))

# Send signed request
curl -H "X-Signature: $SIGNATURE" \
     -H "Content-Type: application/json" \
     -d "$PAYLOAD" \
     https://api.example.com/payment

Hash (No Key Required)

Transit can also hash data without an encryption key:

vault write transit/hash \
    input=$(echo -n "data to hash" | base64) \
    algorithm=sha2-256

Expected output:

Key     Value
---     -----
sum     a1b2c3d4...hex-hash...

Quick Reference

Command Description
vault write transit/keys/KEY type=ed25519 Create signing key
vault write transit/sign/KEY input=BASE64 Sign data
vault write transit/verify/KEY input=BASE64 signature=SIG Verify signature
vault write transit/hmac/KEY input=BASE64 Generate HMAC
vault write transit/hash input=BASE64 algorithm=sha2-256 Hash data

Next: Practice Exercises