kms-vault: Encrypt and Decrypt Files with AWS KMS
A tiny bash wrapper around aws kms encrypt and aws kms decrypt, from my AWS days in 2018. I used it for stashing small secrets — config files, credentials — encrypted at rest under a KMS key alias instead of plaintext on disk. Requirements: the AWS CLI and jq.
#!/usr/bin/env bash
# License: MIT - https://opensource.org/licenses/MIT
#
# Usage:
#
# Encrypt a file:
# kms-vault encrypt My-Key-Alias some-file-i-want-encrypted.txt > topsecret.asc
#
# Decrypt a file:
# kms-vault decrypt topsecret.asc
#
#
# Requirements: AWS CLI, jq
#
# Your AWS profile / default profile needs to have access to the KMS key you want to use
# and the kms:ListAliases permission.
#
set -eu -o pipefail
command=$1
if [[ $command = "encrypt" ]]; then
key_alias="$2"
key_info=$(aws kms list-aliases | jq -r ".Aliases[] | select(.AliasName | contains (\"$key_alias\"))")
echo "Using key:" 1>&2
echo "$key_info" | jq 1>&2
key_id=$(echo "$key_info" | jq -r .TargetKeyId)
plaintext_path="$3"
aws kms encrypt --key-id "$key_id" --plaintext "fileb://$plaintext_path" --query CiphertextBlob --output text
exit 0
elif [[ $command = "decrypt" ]]; then
ciphertext_path="$2"
aws kms decrypt --ciphertext-blob fileb://<(cat $ciphertext_path | base64 -d) --output text --query Plaintext | base64 -d
exit 0
else
echo "Unknown command: $command"
exit 1
fi
Worth knowing if you borrow this: a raw kms encrypt call caps out at 4KB of plaintext, since it’s not doing envelope encryption — no data key, no local AES step, just KMS directly. Fine for a small config file or credential; not what you want for anything larger.