kOps & MFA

You can secure kops with MFA by creating an AWS role & policy that requires MFA to access to the KOPS_STATE_STORE bucket. Unfortunately the Go AWS SDK does not transparently support assuming roles with required MFA. This may change in a future version. kops plans to support this behavior eventually. You can track progress in this Github issue. If you’d like to use MFA with kops, you’ll need a work around until then.

The Workaround #1

The work around uses aws sts assume-role in combination with an MFA prompt to retrieve temporary AWS access keys. This provides AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, and AWS_SESSION_TOKEN environment variables which are automatically picked up by Go AWS SDK. You provide the MFA & Role ARNs, then invoke kops.

Here’s an example wrapper script:

  1. #!/usr/bin/env bash
  2. set -euo pipefail
  3. main() {
  4. local role_arn="${KOPS_MFA_ROLE_ARN:-}"
  5. local serial_number="${KOPS_MFA_ARN:-}"
  6. local token_code
  7. if [ -z "${role_arn}" ]; then
  8. echo "Set the KOPS_MFA_ROLE_ARN environment variable" 1>&2
  9. return 1
  10. fi
  11. if [ -z "${serial_number}" ]; then
  12. echo "Set the KOPS_MFA_ARN environment variable" 1>&2
  13. return 1
  14. fi
  15. echo -n "Enter MFA Code: "
  16. read -s token_code
  17. # NOTE: The keys should not be exported as AWS_ACCESS_KEY_ID
  18. # or AWS_SECRET_ACCESS_KEY_ID. This will not work. They
  19. # should be exported as other names which can be used below. This prevents
  20. # them from incorrectly being picked up from libraries or commands.
  21. temporary_credentials="$(aws \
  22. sts assume-role \
  23. --role-arn="${role_arn}" \
  24. --serial-number="${serial_number}" \
  25. --token-code="${token_code}" \
  26. --role-session-name="kops-access"
  27. )"
  28. unset AWS_PROFILE
  29. export "AWS_ACCESS_KEY_ID=$(echo "${temporary_credentials}" | jq -re '.Credentials.AccessKeyId')"
  30. export "AWS_SECRET_ACCESS_KEY=$(echo "${temporary_credentials}" | jq -re '.Credentials.SecretAccessKey')"
  31. export "AWS_SESSION_TOKEN=$(echo "${temporary_credentials}" | jq -re '.Credentials.SessionToken')"
  32. exec kops "$@"
  33. }
  34. main "$@"

Usage

Download the script as kops-mfa, make it executable, put it on $PATH, set the KOPS_MFA_ARN and KOPS_MFA_ROLE_ARN environment variables. Run as kops-mfa followed by any kops command.

The Workaround #2

Use awsudo to generate temp credentials. This is similar to previous but shorter:

  1. pip install awsudo
  2. env $(awsudo ${AWS_PROFILE} | grep AWS | xargs) kops ...

The Workaround #3

Use aws-vault to generate temp session credentials. After setting up aws-vault, use alias for kops command. This way terminal will ask for MFA each time the credential session is expired. Commands would be:

  1. AWS_PROFILE=sandbox
  2. aws-vault add $AWS_PROFILE
  3. alias kops="aws-vault exec ${AWS_PROFILE} -- kops"