Skip to content

yaml set Examples

William W. Kimball, Jr., MBA, MSIS edited this page Oct 12, 2020 · 22 revisions
  1. Introduction

Introduction

This page explores various real-world use-cases for the yaml-set command-line tool. This is not an exploration of the Segments-of-a-YAML-Path. Rather, some real-world use-cases will be presented here along with their solutions.

Password Rotation

When dealing with secrets, use some form of encryption. The yaml-set tool has native support for EYAML, which will be demonstrated here. You can pipe in new values from any other encryption solution you have, but yaml-set won't be able to compare decrypted values for the --check (-c) option unless you use EYAML.

Note that rotating a password is slightly different from changing a password. When you change a password, you just write the new value to the correct field and you're done. To rotate a password, you need to save off the old value so it can be used to affect the same change in some other system. Such will be the case for this use-case.

For this presentation, the original YAML file will be:

File: CREDENTIALS.YAML

---
credentials:
  username: >
    ENC[PKCS7,MIIBeQYJKoZIhvcNAQcDoIIBajCCAWYCAQAxggEhMIIBHQIBADAFMAACAQEw
    DQYJKoZIhvcNAQEBBQAEggEAiT2ZIXN5RGzIFPdBuXq6gL46q+8qsvQN7riR
    zApiSfC8D5jbNXONXUdC67ClYSf0wyAfMvGCfqd6pv3KQ2wi8tDe58SJ16Of
    BJrpIb6AtKZAsHYY6wTa4D8DST9sCp1REibVXbIF4kqphvgaR9LilmhCJ/Y0
    Xj74sT0QBBL5SGgA9TAUVio2Eo2sEZGV5fTntFplT17qi9AyigYlwANUmMz6
    quVv64GwBe+E7hCUQw7NjVC8UhydZM+DXxJBmTvp7kKTkJwfOxKHdgLPJa9u
    UvKzKTO0GnX7uShHKGuViKsDxXxrg1/KII48zF35jCjdeE4g+MQ5C4tfBWUv
    kh3aKzA8BgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBC31J5O4xavJNOU2JEr
    CVGVgBBi/wYVAANhLHN2Ah4ThNxC]
  password: >
    ENC[PKCS7,MIIBiQYJKoZIhvcNAQcDoIIBejCCAXYCAQAxggEhMIIBHQIBADAFMAACAQEw
    DQYJKoZIhvcNAQEBBQAEggEAQcvTDq8m2G+9bBC9xrZgHhyg8tjjvZeufFxU
    p12TAUZ5Kf1FD4Rp45NUJ7/9cWV09oTBCN4CW6SFh7X/aFoIvv8mKqzk9Up2
    KLBQIUVbhlh+5dVPPsZ8xX+I7zipL743XGzRHWm3KqzIR1cvpkq+eNsgPRMG
    qvOh2JaMkampbK3StMgVPrt8R4JcMABlyV2ICRN9yyXPlF7N3agYiREn+skn
    0sKwFdjn4n/V3JwDsm1ELzbVmsCzvr9M5dIO95pUhs+c3T/MmoOIjmR+X0/T
    cKed2qcycHLE0PPOJktT0Hiiv9Bmz0pgx5yF5SY8g44+yyXyFaT8NSADc/+4
    G/9C5zBMBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBAvEEg8whyHuW228o5S
    EI38gCDw0Jvdzzv7oQ439Js8Hc8rANdbgu6IFYk5HM7ddI2lew==]

Any values which take the form of ENC[algorythm,value] are EYAML values which were encrypted using a key-pair. For this demonstration, they use block (i.e.: folded) values to make them presentable; they are valid in this form.

The data file is one small part of a holistic credential management system. Another part would be some code which actually performs the remote credential change. For simplicity sake, this hypothetical shell script serves such a purpose:

File: ROTATE-PASSWORD.SH

#!/bin/bash
###############################################################################
# Conduct a (fictional) password rotation.
#
# This works by attempting a remote system connection using the "present"
# credentials.  Should it fail due to bad credentials, the change is attempted
# using the "former" credentials.
###############################################################################
dataFile=${1:?"ERROR:  A credentials file (YAML or JSON) must be provided!"}
userName=$(yaml-get --query=/credentials/username "$dataFile")
passWord=$(yaml-get --query=/credentials/password "$dataFile")

# Verify data was retrieved
if [ -z "$userName" -o -z "$passWord" ]; then
	echo "ERROR:  Verify both username and password are at /credentials in ${dataFile}." >&2
	exit 1
fi

# Attempt to connect using the present credentials
some-client --username="$userName" --password="$passWord"
exitState=$?

# Assume an exit-state of 86 means "wrong credentials"
if [ 86 -eq $exitState ]; then
	# Get the former password and attempt a rotation
	oldPass=$(yaml-get --query=/credentials/password_old "$dataFile")
	if [ -z "$oldPass" ]; then
		echo "ERROR:  Bad credentials and no former password to rotate!" >&2
		exit 1
	fi

	some-client --username="$userName" --password="$oldPass" --newpassword="$passWord"
	exitState=$?
fi

# Report success/fail to the calling process
exit $exitState

Note that this script requires the former password to be found at /credentials/password_old with the present password at /credentials/password.

Unverified Changes

It is best-practice to verify sensitive values before changing them, when you have knowledge of the former values. When you do not have the old value or simply don't care, you can make an unverified change. This would look like: some-password-generator | yaml-set --change=/credentials/password --saveto=/credentials/password_old --stdin --eyamlcrypt CREDENTIALS.YAML

In this example, another fictitious command, some-password-generator, securely produces a new password which is piped into yaml-set across STDIN. This value cannot be snooped. Further, the yaml-set command encrypts the value using EYAML and the system- or user-default encryption keys available to the system running the command.

(more to come)

Clone this wiki locally