From aec0fea33a8092b1059275c19ffc17b8fe2a2db7 Mon Sep 17 00:00:00 2001 From: Mariusz Sabath Date: Thu, 28 May 2020 22:57:05 +0200 Subject: [PATCH 01/17] Fixed the policies --- examples/myubuntu.yaml | 23 +- examples/vault/demo.load-sample-policies.sh | 2 +- examples/vault/demo.policy-maker.sh | 283 ++++++++++++++++++ examples/vault/demo.policy-reviewer.sh | 155 ++++++++++ ...-policy.r.hcl.tpl => tsi-policy.r.hcl.tpl} | 0 ...icy.rcn.hcl.tpl => tsi-policy.rcn.hcl.tpl} | 1 - 6 files changed, 449 insertions(+), 15 deletions(-) create mode 100755 examples/vault/demo.policy-maker.sh create mode 100755 examples/vault/demo.policy-reviewer.sh rename examples/vault/{ti-policy.r.hcl.tpl => tsi-policy.r.hcl.tpl} (100%) rename examples/vault/{ti-policy.rcn.hcl.tpl => tsi-policy.rcn.hcl.tpl} (87%) diff --git a/examples/myubuntu.yaml b/examples/myubuntu.yaml index 2cab542a..ff267154 100644 --- a/examples/myubuntu.yaml +++ b/examples/myubuntu.yaml @@ -15,28 +15,25 @@ spec: admission.trusted.identity/inject: "true" tsi.secrets: | - tsi.secret/name: "mysecret1" - tsi.secret/role: "tsi-role-rcni" - tsi.secret/vault-path: "secret/tsi-rcni" + tsi.secret/constrains: "region,cluster-name,namespace,images" tsi.secret/local-path: "mysecrets/myubuntu" - tsi.secret/name: "mysecret2.json" - tsi.secret/role: "tsi-role-r" - tsi.secret/vault-path: "secret/tsi-r" + tsi.secret/constrains: "region,images" tsi.secret/local-path: "mysecrets/" + - tsi.secret/name: "mysecret3" + tsi.secret/constrains: "region,cluster-name,namespace" + tsi.secret/local-path: "mysecrets/myubuntu" - tsi.secret/name: "mysecret4" - tsi.secret/role: "tsi-role-r" - tsi.secret/vault-path: "secret/tsi-r" + tsi.secret/constrains: "region" tsi.secret/local-path: "mysecrets" - tsi.secret/name: "password" - tsi.secret/role: "tsi-role-r" - tsi.secret/vault-path: "secret/tsi-r" + tsi.secret/constrains: "region" tsi.secret/local-path: "mysecrets" - tsi.secret/name: "invalid" - tsi.secret/role: "tsi-role-rcni" - tsi.secret/vault-path: "secret/tsi-rcni" - tsi.secret/local-path: "mysecrets" + tsi.secret/constrains: "region" + tsi.secret/local-path: "mysecretsx" - tsi.secret/name: "non-existing" - tsi.secret/role: "tsi-role-rcni" - tsi.secret/vault-path: "secret/nothing" + tsi.secret/constrains: "regionx" tsi.secret/local-path: "mysecrets" labels: app: myubuntu diff --git a/examples/vault/demo.load-sample-policies.sh b/examples/vault/demo.load-sample-policies.sh index fd44691e..79791a0f 100755 --- a/examples/vault/demo.load-sample-policies.sh +++ b/examples/vault/demo.load-sample-policies.sh @@ -40,7 +40,7 @@ loadVault() vault policy read tsi-policy-rcni vault policy write tsi-policy-rcn tsi-policy.rcn.hcl vault policy read tsi-policy-rcn - vault policy write tsi-policy-rcn tsi-policy.ri.hcl + vault policy write tsi-policy-ri tsi-policy.ri.hcl vault policy read tsi-policy-ri vault policy write tsi-policy-r tsi-policy.r.hcl vault policy read tsi-policy-r diff --git a/examples/vault/demo.policy-maker.sh b/examples/vault/demo.policy-maker.sh new file mode 100755 index 00000000..c1b6479e --- /dev/null +++ b/examples/vault/demo.policy-maker.sh @@ -0,0 +1,283 @@ +#!/bin/bash + +# Print the header: +header() +{ +cat << EOF +#!/bin/bash + +# **** Trusted Service Identity **** +# **** IBM Research **************** +# https://github.com/IBM/trusted-service-identity/ +# +# This auto-generated script provides helpful tooling +# for injecting TSI secrets into Vault based on the input +# deployment file +# +# Assumptions: +# 1. File has properly defined annotations including +# a. 'tsi.secrets' +# b. 'admission.trusted.identity/inject: "true"' +# 2. + + +# Define values for the SECRET_VALUE(s) +# they must be in "key=value" format +# For more info see: +# https://github.com/IBM/trusted-service-identity/examples/vault/README.md#secrets +export SECRET_VALUE="secret=" + +# To access vault, obtain the Vault Client from (...) +# and define ROOT_TOKEN and VAULT_ADDR env. variables: +# +# export ROOT_TOKEN= +# export VAULT_ADDR=(vault address in format http://vault.server:8200) +# +EOF + +# prevent expression expending by using a single quote: +echo 'vault login -no-print "${ROOT_TOKEN}" +RT=$? +if [ $RT -ne 0 ] ; then + echo "ROOT_TOKEN is not set correctly" + exit 1 +fi' + +} + +SECRET_VALUE='$SECRET_VALUE' + + +## create help menu: +helpme() +{ + cat < ${CLYM1} +CLJS1=$(yq r -j ${CLYM1} |jq -r '.data."cluster-config.json"') +rm "${CLYM1}" +#echo $CLJS1 +CLUSTER=$(echo "$CLJS1" | jq -r '.name') +DC=$(echo "$CLJS1" | jq -r '.datacenter') + +# Confirmed with Armada team that CRN format should stay consistent for a while +# CRN format example: +# crn:v1:bluemix:public:containers-kubernetes:eu-de:586283a9abda5102d46e1b94b923a6c5:5f4306a2738d4cdd89ff067c9481555e +REGION=$(echo "$CLJS1" | jq -r '."crn"' | cut -d":" -f6) + +# extract the deployment information from the deployment file +DEPLOY=$(kubectl create -f ${FILE} -n ${NS} --dry-run=true -ojson |jq) + +NS=$(echo $DEPLOY | jq -r '.metadata.namespace') +# TODO we need to add support for multiple images in one pod. +# Sort them alphabetically. Do the same algorithm in TSI +IMG=$(echo $DEPLOY | jq -r '.spec.template.spec.containers[0].image') + +# Get the SHA-256 encoded image name. +# Encoder depends on the OS: +if [[ "$OSTYPE" == "linux-gnu" ]]; then + # Linux + IMGSHA=$(echo -n "$IMG" | sha256sum | awk '{print $1}') +elif [[ "$OSTYPE" == "darwin"* ]]; then + # Mac OSX + IMGSHA=$(echo -n "$IMG" | shasum -a 256 | awk '{print $1}') +else + # Unknown. + echo "ERROR: Cannot encode the image name. Unsupported platform" + exit 1 +fi + + +# validate if tsiEnabled is provided correctly +# tsiEnabled - convert to lowercase: +tsiEnabled=$(echo $DEPLOY | jq -r '.spec.template.metadata.annotations."admission.trusted.identity/inject"' | awk '{print tolower($0)}') +if [[ "$tsiEnabled" == "true" || "$tsiEnabled" == "yes" || "$tsiEnabled" == "on" || "$tsiEnabled" == "y" ]] ; then + header + echo "# TSI is enabled" +else + echo "# ERROR: TSI must be enabled to continue! " + echo "# Set 'admission.trusted.identity/inject' annotation to 'true'" + exit 1 +fi + +echo "# Cluster: $CLUSTER DataCenter: $DC Region: $REGION" + +#secrets=$(echo $DEPLOY | jq -r '.spec.template.metadata.annotations."tsi.secrets"') +#echo $DEPLOY | jq -r '.spec.template.metadata.annotations' +echo "# NS=$NS, IMG: $IMG, IMGSHA: $IMGSHA" +#echo "$secrets" + +POLICIES=() + + +buildSecrets() +{ + local SECNAME=$1 + local CONSTR=$2 + + # Then parse the response to get other attributes associated + # with this token. + # Doublequotes required when the key name contains '-' + # REGION=$(echo $RESP | jq -r '.auth.metadata."region"') + # CLUSTER=$(echo $RESP | jq -r '.auth.metadata."cluster-name"') + # IMGSHA=$(echo $RESP | jq -r '.auth.metadata.images') + # NS=$(echo $RESP | jq -r '.auth.metadata.namespace') + # + # echo "Getting $SECNAME from Vault $VAULT_PATH and output to $LOCPATH" + # if [ "$VAULT_PATH" == "secret/tsi-rcni" ]; then + # CMD="vault kv get -format=json ${VAULT_PATH}/${REGION}/${CLUSTER}/${NS}/${IMGSHA}/${SECNAME}" + # elif [ "$VAULT_PATH" == "secret/tsi-r" ]; then + # CMD="vault kv get -format=json ${VAULT_PATH}/${REGION}/${SECNAME}" + # elif [ "$VAULT_PATH" == "secret/tsi-rcn" ]; then + # CMD="vault kv get -format=json ${VAULT_PATH}/${REGION}/${CLUSTER}/${NS}/${SECNAME}" + # else + # echo "Unknown Vault path value!" + # rm -rf "${LOCPATHDIR}/${LOCPATH}/${SECNAME}" + # return 1 + # fi + + case $CONSTR in + "region") + echo "# using policy $CONSTR" + # PL="tsi-ri" + # REGION=`echo $CLAIMS |jq -r '."region"'` + # IMG=`echo $CLAIMS |jq -r '."images"'` + echo "vault kv put secret/tsi-r/${REGION}/${SECNAME} ${SECRET_VALUE}" + POLICIES+=('tsi-r') + ;; + "region,images") + echo "# using policy $CONSTR" + # PL="tsi-r" + # REGION=`echo $CLAIMS |jq -r '."region"'` + # CLUSTER=`echo $CLAIMS |jq -r '."cluster-name"'` + # IMG=`echo $CLAIMS |jq -r '."images"'` + echo "vault kv put secret/tsi-ri/${REGION}/${IMGSHA}/${SECNAME} ${SECRET_VALUE}" + POLICIES+=('tsi-ri') + ;; + "region,cluster-name,namespace") + echo "# using policy $CONSTR" + ROLE="tsi-role-rcn" + VAULT_PATH="secret/tsi-rcn" + # PL="tsi-r" + # REGION=`echo $CLAIMS |jq -r '."region"'` + # CLUSTER=`echo $CLAIMS |jq -r '."cluster-name"'` + # IMG=`echo $CLAIMS |jq -r '."images"'` + echo "vault kv put secret/tsi-rcn/${REGION}/${CLUSTER}/${NS}/${SECNAME} ${SECRET_VALUE}" + POLICIES+=('tsi-rcn') + ;; + "region,cluster-name,namespace,images") + echo "# using policy $CONSTR" + # PL="tsi-rcni" + # REGION=`echo $CLAIMS |jq -r '."region"'` + # CLUSTER=`echo $CLAIMS |jq -r '."cluster-name"'` + # NS=`echo $CLAIMS |jq -r '."namespace"'` + # IMG=`echo $CLAIMS |jq -r '."images"'` + echo "vault kv put secret/tsi-rcni/${REGION}/${CLUSTER}/${NS}/${IMGSHA}/${SECNAME} ${SECRET_VALUE}" + POLICIES+=('tsi-rcni') + ;; + *) echo "# ERROR: invalid constrains requested: ${CONSTR}" + ;; + esac + +} + +# getting the secrets annotations require a bit more work +TMPTSI="/tmp/tsi.$$" +kubectl create -f ${FILE} -n ${NS} --dry-run=true -oyaml > ${TMPTSI}.1 +yq r -j ${TMPTSI}.1 |jq -r '.spec.template.metadata.annotations."tsi.secrets"' > ${TMPTSI}.2 +#JSON1=$(yq r -j /tmp/tsi.1) +#echo $JSON1 | jq -r '.spec.template.metadata.annotations."tsi.secrets"' > /tmp/tsi.2 +JSON=$(yq r -j ${TMPTSI}.2) +rm ${TMPTSI}.1 ${TMPTSI}.2 + +for row in $(echo "${JSON}" | jq -c '.[]' ); do + # for each requested secret parse its attributes + SECNAME=$(echo "$row" | jq -r '."tsi.secret/name"') + CONSTR=$(echo "$row" | jq -r '."tsi.secret/constrains"') + LOCPATH=$(echo "$row" | jq -r '."tsi.secret/local-path"') + + # local-path must start with "mysecrets" + if [[ ${LOCPATH} == "mysecrets" ]] || [[ ${LOCPATH} == "/mysecrets" ]] || [[ ${LOCPATH} == /mysecrets/* ]] || [[ ${LOCPATH} == mysecrets/* ]]; then + + # build the injection of secret: + buildSecrets "$SECNAME" "$CONSTR" + RT=$? + if [ "$RT" != "0" ]; then + echo "Error building a secret SECNAME=${SECNAME}, CONSTR=${CONSTR}, LOCPATH=${LOCPATH}" + fi + + else + echo "# ERROR: invalid local-path value: $LOCPATH" + fi + + + +done + +#echo "# ${POLICIES[@]}" +# remove duplicated policies: +sorted_unique_ids=($(echo "${POLICIES[@]}" | tr ' ' '\n' | sort -u | tr '\n' ' ')) +echo "# this deployment uses the following policies/paths: " +echo "# ${sorted_unique_ids[@]}" diff --git a/examples/vault/demo.policy-reviewer.sh b/examples/vault/demo.policy-reviewer.sh new file mode 100755 index 00000000..7afb5e54 --- /dev/null +++ b/examples/vault/demo.policy-reviewer.sh @@ -0,0 +1,155 @@ +#!/bin/bash +x + +SECRET_NAME="SECRET_NAME" +SECRET_VALUE='SECRET_VALUE' + +## create help menu: +helpme() +{ + cat <.metadata.region}}/{{identity.entity.aliases.<%MOUNT_ACCESSOR%>.metadata.cluster-name}}/{{identity.entity.aliases.<%MOUNT_ACCESSOR%>.metadata.namespace}}/*" { # list allows listing the secrets: # capabilities = ["read", "list"] From 7b312a0ef5257252e5bedacb2b1b1e59f577a085 Mon Sep 17 00:00:00 2001 From: Mariusz Sabath Date: Fri, 29 May 2020 22:46:56 +0200 Subject: [PATCH 02/17] Containerizing the solution --- components/node-setup/Dockerfile | 13 +- components/node-setup/secret-maker.sh | 287 ++++++++++++++++++++++ examples/myubuntu-all.yaml | 27 +- examples/myubuntu.yaml | 17 +- examples/vault/demo.claim-reviewer.sh | 45 ++++ examples/vault/demo.policy-reviewer.sh | 155 ------------ examples/vault/demo.secret-maker.local.sh | 78 ++++++ examples/vault/demo.secret-maker.sh | 76 ++++++ 8 files changed, 507 insertions(+), 191 deletions(-) create mode 100755 components/node-setup/secret-maker.sh create mode 100755 examples/vault/demo.claim-reviewer.sh delete mode 100755 examples/vault/demo.policy-reviewer.sh create mode 100755 examples/vault/demo.secret-maker.local.sh create mode 100755 examples/vault/demo.secret-maker.sh diff --git a/components/node-setup/Dockerfile b/components/node-setup/Dockerfile index 1e17c5bc..42f5795c 100644 --- a/components/node-setup/Dockerfile +++ b/components/node-setup/Dockerfile @@ -3,18 +3,17 @@ RUN apt update && \ apt install -y curl jq vim && \ apt install -y openssl +# install yq required for xform YAML to JSON +RUN apt-get install -y software-properties-common && \ + add-apt-repository ppa:rmescandon/yq && \ + apt update && apt install -y yq + RUN cd /usr/local/bin && \ curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl && \ chmod +x kubectl COPY init-node.sh /usr/local/bin/ - - -# Default values for JWT, issuer and token expiration in seconds -#ARG DEFAULT_ISS="wsched@us.ibm.com" -#ARG DEFAULT_TTL_SEC=30 -#ENV ISS=${DEFAULT_ISS} -#ENV TTL_SEC=${DEFAULT_TTL_SEC} +COPY secret-maker.sh /usr/local/bin/ ARG DEFAULT_PRIVATE_DIR="/host/tsi-secure" ENV PRIVATEDIR=${DEFAULT_PRIVATE_DIR} diff --git a/components/node-setup/secret-maker.sh b/components/node-setup/secret-maker.sh new file mode 100755 index 00000000..6073b3fd --- /dev/null +++ b/components/node-setup/secret-maker.sh @@ -0,0 +1,287 @@ +#!/bin/bash + +SECRET_VALUE='$SECRET_VALUE' + +### Functions: + +# Print the header: +header() +{ +cat << EOF +#!/bin/bash + +# **** Trusted Service Identity **** +# **** IBM Research **************** +# https://github.com/IBM/trusted-service-identity/ +# +# This auto-generated script provides helpful tooling +# for injecting TSI secrets into Vault based on the input +# deployment file +# +# Assumptions: +# 1. File has properly defined annotations including +# a. 'tsi.secrets' +# b. 'admission.trusted.identity/inject: "true"' +# 2. + + +# Define values for the SECRET_VALUE(s) +# they must be in "key=value" format +# For more info see: +# https://github.com/IBM/trusted-service-identity/examples/vault/README.md#secrets +export SECRET_VALUE="secret=" + +# To access vault, obtain the Vault Client from (...) +# and define ROOT_TOKEN and VAULT_ADDR env. variables: +# +# export ROOT_TOKEN= +# export VAULT_ADDR=(vault address in format http://vault.server:8200) +# +EOF + +# prevent expression expending by using a single quote: +echo 'vault login -no-print "${ROOT_TOKEN}" +RT=$? +if [ $RT -ne 0 ] ; then + echo "ROOT_TOKEN is not set correctly" + exit 1 +fi' + +} + +## create help menu: +helpme() +{ + cat < ${CLYM1} +cat ${CLUSTER_YAML} > ${CLYM1} +CLJS1=$(yq r -j ${CLYM1} |jq -r '.data."cluster-config.json"') +rm "${CLYM1}" +#echo $CLJS1 +CLUSTER=$(echo "$CLJS1" | jq -r '.name') +DC=$(echo "$CLJS1" | jq -r '.datacenter') + +# Confirmed with Armada team that CRN format should stay consistent for a while +# CRN format example: +# crn:v1:bluemix:public:containers-kubernetes:eu-de:586283a9abda5102d46e1b94b923a6c5:5f4306a2738d4cdd89ff067c9481555e +REGION=$(echo "$CLJS1" | jq -r '."crn"' | cut -d":" -f6) +echo "# Cluster: $CLUSTER DataCenter: $DC Region: $REGION" + +# Get Pod information + +# extract the deployment information from the deployment file +# DEPLOY=$(cat ${POD_JSON} |jq) +# DEPLOY=$(kubectl create -f ${FILE} -n ${NS} --dry-run=true -ojson |jq) + +# OLD CODE... >>> + + + +#secrets=$(echo $DEPLOY | jq -r '.spec.template.metadata.annotations."tsi.secrets"') +#echo $DEPLOY | jq -r '.spec.template.metadata.annotations' + +#echo "$secrets" + + + + + +# getting the secrets annotations require a bit more work +TMPTSI="/tmp/tsi.$$" +# kubectl create -f ${FILE} -n ${NS} --dry-run=true -oyaml > ${TMPTSI}.1 + +cat ${POD_JSON} > ${TMPTSI}.1 +yq r -j ${TMPTSI}.1 |jq -r '.spec.template.metadata.annotations."tsi.secrets"' > ${TMPTSI}.2 + +DEPLOY=$(yq r -j ${TMPTSI}.1) +NS=$(echo $DEPLOY | jq -r '.metadata.namespace') + +# TODO we need to add support for multiple images in one pod. +# Sort them alphabetically. Do the same algorithm in TSI +IMG=$(echo $DEPLOY | jq -r '.spec.template.spec.containers[0].image') + +# Get the SHA-256 encoded image name. +# Encoder depends on the OS: +if [[ "$OSTYPE" == "linux-gnu" ]]; then + # Linux + IMGSHA=$(echo -n "$IMG" | sha256sum | awk '{print $1}') +elif [[ "$OSTYPE" == "darwin"* ]]; then + # Mac OSX + IMGSHA=$(echo -n "$IMG" | shasum -a 256 | awk '{print $1}') +else + # Unknown. + echo "ERROR: Cannot encode the image name. Unsupported platform" + exit 1 +fi + + +# validate if tsiEnabled is provided correctly +# tsiEnabled - convert to lowercase: +tsiEnabled=$(echo $DEPLOY | jq -r '.spec.template.metadata.annotations."admission.trusted.identity/inject"' | awk '{print tolower($0)}') +if [[ "$tsiEnabled" == "true" || "$tsiEnabled" == "yes" || "$tsiEnabled" == "on" || "$tsiEnabled" == "y" ]] ; then + header + echo "# TSI is enabled" +else + echo "# ERROR: TSI must be enabled to continue! " + echo "# Set 'admission.trusted.identity/inject' annotation to 'true'" + exit 1 +fi + + + +echo "# NS=$NS, IMG: $IMG, IMGSHA: $IMGSHA" + + + + +#JSON1=$(yq r -j /tmp/tsi.1) +#echo $JSON1 | jq -r '.spec.template.metadata.annotations."tsi.secrets"' > /tmp/tsi.2 +JSON=$(yq r -j ${TMPTSI}.2) +rm ${TMPTSI}.1 ${TMPTSI}.2 + +POLICIES=() + +for row in $(echo "${JSON}" | jq -c '.[]' ); do + # for each requested secret parse its attributes + SECNAME=$(echo "$row" | jq -r '."tsi.secret/name"') + CONSTR=$(echo "$row" | jq -r '."tsi.secret/constrains"') + LOCPATH=$(echo "$row" | jq -r '."tsi.secret/local-path"') + + # local-path must start with "mysecrets" + if [[ ${LOCPATH} == "mysecrets" ]] || [[ ${LOCPATH} == "/mysecrets" ]] || [[ ${LOCPATH} == /mysecrets/* ]] || [[ ${LOCPATH} == mysecrets/* ]]; then + + # build the injection of secret: + buildSecrets "$SECNAME" "$CONSTR" + RT=$? + if [ "$RT" != "0" ]; then + echo "Error building a secret SECNAME=${SECNAME}, CONSTR=${CONSTR}, LOCPATH=${LOCPATH}" + fi + + else + echo "# ERROR: invalid local-path value: $LOCPATH" + fi + + + +done + +#echo "# ${POLICIES[@]}" +# remove duplicated policies: +sorted_unique_ids=($(echo "${POLICIES[@]}" | tr ' ' '\n' | sort -u | tr '\n' ' ')) +echo "# this deployment uses the following policies/paths: " +echo "# ${sorted_unique_ids[@]}" diff --git a/examples/myubuntu-all.yaml b/examples/myubuntu-all.yaml index 357b6ab7..3060277d 100644 --- a/examples/myubuntu-all.yaml +++ b/examples/myubuntu-all.yaml @@ -15,24 +15,25 @@ spec: admission.trusted.identity/inject: "true" tsi.secrets: | - tsi.secret/name: "mysecret1" - tsi.secret/role: "tsi-role-rcni" - tsi.secret/vault-path: "secret/tsi-rcni" + tsi.secret/constrains: "region,cluster-name,namespace,images" tsi.secret/local-path: "mysecrets/myubuntu" - tsi.secret/name: "mysecret2.json" - tsi.secret/role: "tsi-role-r" - tsi.secret/vault-path: "secret/tsi-r" - tsi.secret/local-path: "mysecrets" + tsi.secret/constrains: "region,images" + tsi.secret/local-path: "mysecrets/" + - tsi.secret/name: "mysecret3" + tsi.secret/constrains: "region,cluster-name,namespace" + tsi.secret/local-path: "mysecrets/myubuntu" - tsi.secret/name: "mysecret4" - tsi.secret/role: "tsi-role-r" - tsi.secret/vault-path: "secret/tsi-r" + tsi.secret/constrains: "region" tsi.secret/local-path: "mysecrets" - - tsi.secret/name: "mysecret5" - tsi.secret/role: "tsi-role-r" - tsi.secret/vault-path: "secret/tsi-r" + - tsi.secret/name: "password" + tsi.secret/constrains: "region" tsi.secret/local-path: "mysecrets" - - tsi.secret/name: "test.json" - tsi.secret/role: "tsi-role-r" - tsi.secret/vault-path: "secret/tsi-r" + - tsi.secret/name: "invalid" + tsi.secret/constrains: "region" + tsi.secret/local-path: "mysecretsx" + - tsi.secret/name: "non-existing" + tsi.secret/constrains: "regionx" tsi.secret/local-path: "mysecrets" labels: app: myubuntu-all diff --git a/examples/myubuntu.yaml b/examples/myubuntu.yaml index ff267154..1865f938 100644 --- a/examples/myubuntu.yaml +++ b/examples/myubuntu.yaml @@ -15,26 +15,11 @@ spec: admission.trusted.identity/inject: "true" tsi.secrets: | - tsi.secret/name: "mysecret1" - tsi.secret/constrains: "region,cluster-name,namespace,images" - tsi.secret/local-path: "mysecrets/myubuntu" - - tsi.secret/name: "mysecret2.json" tsi.secret/constrains: "region,images" tsi.secret/local-path: "mysecrets/" - - tsi.secret/name: "mysecret3" - tsi.secret/constrains: "region,cluster-name,namespace" - tsi.secret/local-path: "mysecrets/myubuntu" - - tsi.secret/name: "mysecret4" + - tsi.secret/name: "mysecret2" tsi.secret/constrains: "region" tsi.secret/local-path: "mysecrets" - - tsi.secret/name: "password" - tsi.secret/constrains: "region" - tsi.secret/local-path: "mysecrets" - - tsi.secret/name: "invalid" - tsi.secret/constrains: "region" - tsi.secret/local-path: "mysecretsx" - - tsi.secret/name: "non-existing" - tsi.secret/constrains: "regionx" - tsi.secret/local-path: "mysecrets" labels: app: myubuntu name: myubuntu diff --git a/examples/vault/demo.claim-reviewer.sh b/examples/vault/demo.claim-reviewer.sh new file mode 100755 index 00000000..a6410e8c --- /dev/null +++ b/examples/vault/demo.claim-reviewer.sh @@ -0,0 +1,45 @@ +#!/bin/bash + +## create help menu: +helpme() +{ + cat < ${SYSINFO} +PODINFO="/tmp/podinfo.$$" +kubectl create -f ${FILE} -n ${NS} --dry-run=true -o yaml > ${PODINFO} +../../components/node-setup/secret-maker.sh ${SYSINFO} ${PODINFO} +rm ${SYSINFO} ${PODINFO} diff --git a/examples/vault/demo.secret-maker.sh b/examples/vault/demo.secret-maker.sh new file mode 100755 index 00000000..09bf43c7 --- /dev/null +++ b/examples/vault/demo.secret-maker.sh @@ -0,0 +1,76 @@ +#!/bin/bash + +# NS - a TSI namespace (where the tsi-setup daemonset is deployed) +TSINS="trusted-identity" + +## create help menu: +helpme() +{ + cat < ${SYSINFO} +PODINFO="/tmp/podinfo.$$" +kubectl create -f ${FILE} -n ${NS} --dry-run=true -o yaml > ${PODINFO} + +kk="kubectl -n ${TSINS}" +# get the first `tsi-node-setup` pod in Running state +SETPOD=$(${kk} get po | grep tsi-node-setup | grep 'Running' | awk '{print $1}' | sed -n 1p ) +if [[ "$SETPOD" == "" ]]; then + echo "Required tsi-node-setup daemonset is not running" + echo "For more information, please visit: " + echo " https://github.com/IBM/trusted-service-identity/examples/vault/README.md#secrets" + exit 1 +fi + +# copy the files into the pod +${kk} cp ${SYSINFO} ${SETPOD}:/tmp/sysinfo +${kk} cp ${PODINFO} ${SETPOD}:/tmp/podinfo +${kk} exec -it $SETPOD -- sh -c '/usr/local/bin/secret-maker.sh /tmp/sysinfo /tmp/podinfo' +rm ${SYSINFO} ${PODINFO} From b27d51996246d7f2a92127b504faeeab96f2b298 Mon Sep 17 00:00:00 2001 From: Mariusz Sabath Date: Fri, 29 May 2020 23:04:12 +0200 Subject: [PATCH 03/17] Code cleanup --- components/node-setup/secret-maker.sh | 91 +-------- examples/vault/demo.policy-maker.sh | 283 -------------------------- 2 files changed, 2 insertions(+), 372 deletions(-) delete mode 100755 examples/vault/demo.policy-maker.sh diff --git a/components/node-setup/secret-maker.sh b/components/node-setup/secret-maker.sh index 6073b3fd..3222f0eb 100755 --- a/components/node-setup/secret-maker.sh +++ b/components/node-setup/secret-maker.sh @@ -29,7 +29,7 @@ cat << EOF # they must be in "key=value" format # For more info see: # https://github.com/IBM/trusted-service-identity/examples/vault/README.md#secrets -export SECRET_VALUE="secret=" +export SECRET_VALUE="secret=xxx" # To access vault, obtain the Vault Client from (...) # and define ROOT_TOKEN and VAULT_ADDR env. variables: @@ -70,42 +70,14 @@ buildSecrets() local SECNAME=$1 local CONSTR=$2 - # Then parse the response to get other attributes associated - # with this token. - # Doublequotes required when the key name contains '-' - # REGION=$(echo $RESP | jq -r '.auth.metadata."region"') - # CLUSTER=$(echo $RESP | jq -r '.auth.metadata."cluster-name"') - # IMGSHA=$(echo $RESP | jq -r '.auth.metadata.images') - # NS=$(echo $RESP | jq -r '.auth.metadata.namespace') - # - # echo "Getting $SECNAME from Vault $VAULT_PATH and output to $LOCPATH" - # if [ "$VAULT_PATH" == "secret/tsi-rcni" ]; then - # CMD="vault kv get -format=json ${VAULT_PATH}/${REGION}/${CLUSTER}/${NS}/${IMGSHA}/${SECNAME}" - # elif [ "$VAULT_PATH" == "secret/tsi-r" ]; then - # CMD="vault kv get -format=json ${VAULT_PATH}/${REGION}/${SECNAME}" - # elif [ "$VAULT_PATH" == "secret/tsi-rcn" ]; then - # CMD="vault kv get -format=json ${VAULT_PATH}/${REGION}/${CLUSTER}/${NS}/${SECNAME}" - # else - # echo "Unknown Vault path value!" - # rm -rf "${LOCPATHDIR}/${LOCPATH}/${SECNAME}" - # return 1 - # fi - case $CONSTR in "region") echo "# using policy $CONSTR" - # PL="tsi-ri" - # REGION=`echo $CLAIMS |jq -r '."region"'` - # IMG=`echo $CLAIMS |jq -r '."images"'` echo "vault kv put secret/tsi-r/${REGION}/${SECNAME} ${SECRET_VALUE}" POLICIES+=('tsi-r') ;; "region,images") echo "# using policy $CONSTR" - # PL="tsi-r" - # REGION=`echo $CLAIMS |jq -r '."region"'` - # CLUSTER=`echo $CLAIMS |jq -r '."cluster-name"'` - # IMG=`echo $CLAIMS |jq -r '."images"'` echo "vault kv put secret/tsi-ri/${REGION}/${IMGSHA}/${SECNAME} ${SECRET_VALUE}" POLICIES+=('tsi-ri') ;; @@ -113,47 +85,21 @@ buildSecrets() echo "# using policy $CONSTR" ROLE="tsi-role-rcn" VAULT_PATH="secret/tsi-rcn" - # PL="tsi-r" - # REGION=`echo $CLAIMS |jq -r '."region"'` - # CLUSTER=`echo $CLAIMS |jq -r '."cluster-name"'` - # IMG=`echo $CLAIMS |jq -r '."images"'` echo "vault kv put secret/tsi-rcn/${REGION}/${CLUSTER}/${NS}/${SECNAME} ${SECRET_VALUE}" POLICIES+=('tsi-rcn') ;; "region,cluster-name,namespace,images") echo "# using policy $CONSTR" - # PL="tsi-rcni" - # REGION=`echo $CLAIMS |jq -r '."region"'` - # CLUSTER=`echo $CLAIMS |jq -r '."cluster-name"'` - # NS=`echo $CLAIMS |jq -r '."namespace"'` - # IMG=`echo $CLAIMS |jq -r '."images"'` echo "vault kv put secret/tsi-rcni/${REGION}/${CLUSTER}/${NS}/${IMGSHA}/${SECNAME} ${SECRET_VALUE}" POLICIES+=('tsi-rcni') ;; *) echo "# ERROR: invalid constrains requested: ${CONSTR}" ;; esac - } #### End of functions -# { -# "cluster-name": "my-cluster-name", -# "region": "eu-de", -# "exp": 1590494405, -# "iat": 1590494345, -# "images": "30beed0665d9cb4df616cca84ef2c06d2323e02869fcca8bbfbf0d8c5a3987cc", -# "images-names": "ubuntu@sha256:250cc6f3f3ffc5cdaa9d8f4946ac79821aafb4d3afc93928f0de9336eba21aa4", -# "iss": "wsched@us.ibm.com", -# "machineid": "b46e165c32d342d9896d9eeb43c4d5dd", -# "namespace": "test", -# "pod": "myubuntu-6756d665bc-cb49l", -# "sub": "wsched@us.ibm.com" -# } -# root@myubuntu-6756d665bc-cb49l:/# cat jwt/token | cut -d"." -f2 |base64 --decode |jq -r '.images' -# 30beed0665d9cb4df616cca84ef2c06d2323e02869fcca8bbfbf0d8c5a3987cc - # validate the arguments if [[ "$1" == "-?" || "$1" == "-h" || "$1" == "--help" || "$2" == "" ]] ; then helpme @@ -166,13 +112,11 @@ POD_JSON="$2" ### Get Cluter Information -# extract cluster and region info from K8s +# extract cluster and region info from provided data CLYM1="/tmp/cl1.$$" -#kubectl get cm -n kube-system cluster-info -o yaml > ${CLYM1} cat ${CLUSTER_YAML} > ${CLYM1} CLJS1=$(yq r -j ${CLYM1} |jq -r '.data."cluster-config.json"') rm "${CLYM1}" -#echo $CLJS1 CLUSTER=$(echo "$CLJS1" | jq -r '.name') DC=$(echo "$CLJS1" | jq -r '.datacenter') @@ -184,27 +128,8 @@ echo "# Cluster: $CLUSTER DataCenter: $DC Region: $REGION" # Get Pod information -# extract the deployment information from the deployment file -# DEPLOY=$(cat ${POD_JSON} |jq) -# DEPLOY=$(kubectl create -f ${FILE} -n ${NS} --dry-run=true -ojson |jq) - -# OLD CODE... >>> - - - -#secrets=$(echo $DEPLOY | jq -r '.spec.template.metadata.annotations."tsi.secrets"') -#echo $DEPLOY | jq -r '.spec.template.metadata.annotations' - -#echo "$secrets" - - - - - # getting the secrets annotations require a bit more work TMPTSI="/tmp/tsi.$$" -# kubectl create -f ${FILE} -n ${NS} --dry-run=true -oyaml > ${TMPTSI}.1 - cat ${POD_JSON} > ${TMPTSI}.1 yq r -j ${TMPTSI}.1 |jq -r '.spec.template.metadata.annotations."tsi.secrets"' > ${TMPTSI}.2 @@ -241,16 +166,8 @@ else echo "# Set 'admission.trusted.identity/inject' annotation to 'true'" exit 1 fi - - - echo "# NS=$NS, IMG: $IMG, IMGSHA: $IMGSHA" - - - -#JSON1=$(yq r -j /tmp/tsi.1) -#echo $JSON1 | jq -r '.spec.template.metadata.annotations."tsi.secrets"' > /tmp/tsi.2 JSON=$(yq r -j ${TMPTSI}.2) rm ${TMPTSI}.1 ${TMPTSI}.2 @@ -275,12 +192,8 @@ for row in $(echo "${JSON}" | jq -c '.[]' ); do else echo "# ERROR: invalid local-path value: $LOCPATH" fi - - - done -#echo "# ${POLICIES[@]}" # remove duplicated policies: sorted_unique_ids=($(echo "${POLICIES[@]}" | tr ' ' '\n' | sort -u | tr '\n' ' ')) echo "# this deployment uses the following policies/paths: " diff --git a/examples/vault/demo.policy-maker.sh b/examples/vault/demo.policy-maker.sh deleted file mode 100755 index c1b6479e..00000000 --- a/examples/vault/demo.policy-maker.sh +++ /dev/null @@ -1,283 +0,0 @@ -#!/bin/bash - -# Print the header: -header() -{ -cat << EOF -#!/bin/bash - -# **** Trusted Service Identity **** -# **** IBM Research **************** -# https://github.com/IBM/trusted-service-identity/ -# -# This auto-generated script provides helpful tooling -# for injecting TSI secrets into Vault based on the input -# deployment file -# -# Assumptions: -# 1. File has properly defined annotations including -# a. 'tsi.secrets' -# b. 'admission.trusted.identity/inject: "true"' -# 2. - - -# Define values for the SECRET_VALUE(s) -# they must be in "key=value" format -# For more info see: -# https://github.com/IBM/trusted-service-identity/examples/vault/README.md#secrets -export SECRET_VALUE="secret=" - -# To access vault, obtain the Vault Client from (...) -# and define ROOT_TOKEN and VAULT_ADDR env. variables: -# -# export ROOT_TOKEN= -# export VAULT_ADDR=(vault address in format http://vault.server:8200) -# -EOF - -# prevent expression expending by using a single quote: -echo 'vault login -no-print "${ROOT_TOKEN}" -RT=$? -if [ $RT -ne 0 ] ; then - echo "ROOT_TOKEN is not set correctly" - exit 1 -fi' - -} - -SECRET_VALUE='$SECRET_VALUE' - - -## create help menu: -helpme() -{ - cat < ${CLYM1} -CLJS1=$(yq r -j ${CLYM1} |jq -r '.data."cluster-config.json"') -rm "${CLYM1}" -#echo $CLJS1 -CLUSTER=$(echo "$CLJS1" | jq -r '.name') -DC=$(echo "$CLJS1" | jq -r '.datacenter') - -# Confirmed with Armada team that CRN format should stay consistent for a while -# CRN format example: -# crn:v1:bluemix:public:containers-kubernetes:eu-de:586283a9abda5102d46e1b94b923a6c5:5f4306a2738d4cdd89ff067c9481555e -REGION=$(echo "$CLJS1" | jq -r '."crn"' | cut -d":" -f6) - -# extract the deployment information from the deployment file -DEPLOY=$(kubectl create -f ${FILE} -n ${NS} --dry-run=true -ojson |jq) - -NS=$(echo $DEPLOY | jq -r '.metadata.namespace') -# TODO we need to add support for multiple images in one pod. -# Sort them alphabetically. Do the same algorithm in TSI -IMG=$(echo $DEPLOY | jq -r '.spec.template.spec.containers[0].image') - -# Get the SHA-256 encoded image name. -# Encoder depends on the OS: -if [[ "$OSTYPE" == "linux-gnu" ]]; then - # Linux - IMGSHA=$(echo -n "$IMG" | sha256sum | awk '{print $1}') -elif [[ "$OSTYPE" == "darwin"* ]]; then - # Mac OSX - IMGSHA=$(echo -n "$IMG" | shasum -a 256 | awk '{print $1}') -else - # Unknown. - echo "ERROR: Cannot encode the image name. Unsupported platform" - exit 1 -fi - - -# validate if tsiEnabled is provided correctly -# tsiEnabled - convert to lowercase: -tsiEnabled=$(echo $DEPLOY | jq -r '.spec.template.metadata.annotations."admission.trusted.identity/inject"' | awk '{print tolower($0)}') -if [[ "$tsiEnabled" == "true" || "$tsiEnabled" == "yes" || "$tsiEnabled" == "on" || "$tsiEnabled" == "y" ]] ; then - header - echo "# TSI is enabled" -else - echo "# ERROR: TSI must be enabled to continue! " - echo "# Set 'admission.trusted.identity/inject' annotation to 'true'" - exit 1 -fi - -echo "# Cluster: $CLUSTER DataCenter: $DC Region: $REGION" - -#secrets=$(echo $DEPLOY | jq -r '.spec.template.metadata.annotations."tsi.secrets"') -#echo $DEPLOY | jq -r '.spec.template.metadata.annotations' -echo "# NS=$NS, IMG: $IMG, IMGSHA: $IMGSHA" -#echo "$secrets" - -POLICIES=() - - -buildSecrets() -{ - local SECNAME=$1 - local CONSTR=$2 - - # Then parse the response to get other attributes associated - # with this token. - # Doublequotes required when the key name contains '-' - # REGION=$(echo $RESP | jq -r '.auth.metadata."region"') - # CLUSTER=$(echo $RESP | jq -r '.auth.metadata."cluster-name"') - # IMGSHA=$(echo $RESP | jq -r '.auth.metadata.images') - # NS=$(echo $RESP | jq -r '.auth.metadata.namespace') - # - # echo "Getting $SECNAME from Vault $VAULT_PATH and output to $LOCPATH" - # if [ "$VAULT_PATH" == "secret/tsi-rcni" ]; then - # CMD="vault kv get -format=json ${VAULT_PATH}/${REGION}/${CLUSTER}/${NS}/${IMGSHA}/${SECNAME}" - # elif [ "$VAULT_PATH" == "secret/tsi-r" ]; then - # CMD="vault kv get -format=json ${VAULT_PATH}/${REGION}/${SECNAME}" - # elif [ "$VAULT_PATH" == "secret/tsi-rcn" ]; then - # CMD="vault kv get -format=json ${VAULT_PATH}/${REGION}/${CLUSTER}/${NS}/${SECNAME}" - # else - # echo "Unknown Vault path value!" - # rm -rf "${LOCPATHDIR}/${LOCPATH}/${SECNAME}" - # return 1 - # fi - - case $CONSTR in - "region") - echo "# using policy $CONSTR" - # PL="tsi-ri" - # REGION=`echo $CLAIMS |jq -r '."region"'` - # IMG=`echo $CLAIMS |jq -r '."images"'` - echo "vault kv put secret/tsi-r/${REGION}/${SECNAME} ${SECRET_VALUE}" - POLICIES+=('tsi-r') - ;; - "region,images") - echo "# using policy $CONSTR" - # PL="tsi-r" - # REGION=`echo $CLAIMS |jq -r '."region"'` - # CLUSTER=`echo $CLAIMS |jq -r '."cluster-name"'` - # IMG=`echo $CLAIMS |jq -r '."images"'` - echo "vault kv put secret/tsi-ri/${REGION}/${IMGSHA}/${SECNAME} ${SECRET_VALUE}" - POLICIES+=('tsi-ri') - ;; - "region,cluster-name,namespace") - echo "# using policy $CONSTR" - ROLE="tsi-role-rcn" - VAULT_PATH="secret/tsi-rcn" - # PL="tsi-r" - # REGION=`echo $CLAIMS |jq -r '."region"'` - # CLUSTER=`echo $CLAIMS |jq -r '."cluster-name"'` - # IMG=`echo $CLAIMS |jq -r '."images"'` - echo "vault kv put secret/tsi-rcn/${REGION}/${CLUSTER}/${NS}/${SECNAME} ${SECRET_VALUE}" - POLICIES+=('tsi-rcn') - ;; - "region,cluster-name,namespace,images") - echo "# using policy $CONSTR" - # PL="tsi-rcni" - # REGION=`echo $CLAIMS |jq -r '."region"'` - # CLUSTER=`echo $CLAIMS |jq -r '."cluster-name"'` - # NS=`echo $CLAIMS |jq -r '."namespace"'` - # IMG=`echo $CLAIMS |jq -r '."images"'` - echo "vault kv put secret/tsi-rcni/${REGION}/${CLUSTER}/${NS}/${IMGSHA}/${SECNAME} ${SECRET_VALUE}" - POLICIES+=('tsi-rcni') - ;; - *) echo "# ERROR: invalid constrains requested: ${CONSTR}" - ;; - esac - -} - -# getting the secrets annotations require a bit more work -TMPTSI="/tmp/tsi.$$" -kubectl create -f ${FILE} -n ${NS} --dry-run=true -oyaml > ${TMPTSI}.1 -yq r -j ${TMPTSI}.1 |jq -r '.spec.template.metadata.annotations."tsi.secrets"' > ${TMPTSI}.2 -#JSON1=$(yq r -j /tmp/tsi.1) -#echo $JSON1 | jq -r '.spec.template.metadata.annotations."tsi.secrets"' > /tmp/tsi.2 -JSON=$(yq r -j ${TMPTSI}.2) -rm ${TMPTSI}.1 ${TMPTSI}.2 - -for row in $(echo "${JSON}" | jq -c '.[]' ); do - # for each requested secret parse its attributes - SECNAME=$(echo "$row" | jq -r '."tsi.secret/name"') - CONSTR=$(echo "$row" | jq -r '."tsi.secret/constrains"') - LOCPATH=$(echo "$row" | jq -r '."tsi.secret/local-path"') - - # local-path must start with "mysecrets" - if [[ ${LOCPATH} == "mysecrets" ]] || [[ ${LOCPATH} == "/mysecrets" ]] || [[ ${LOCPATH} == /mysecrets/* ]] || [[ ${LOCPATH} == mysecrets/* ]]; then - - # build the injection of secret: - buildSecrets "$SECNAME" "$CONSTR" - RT=$? - if [ "$RT" != "0" ]; then - echo "Error building a secret SECNAME=${SECNAME}, CONSTR=${CONSTR}, LOCPATH=${LOCPATH}" - fi - - else - echo "# ERROR: invalid local-path value: $LOCPATH" - fi - - - -done - -#echo "# ${POLICIES[@]}" -# remove duplicated policies: -sorted_unique_ids=($(echo "${POLICIES[@]}" | tr ' ' '\n' | sort -u | tr '\n' ' ')) -echo "# this deployment uses the following policies/paths: " -echo "# ${sorted_unique_ids[@]}" From 43010dd4031cdec144f076235b2633ad62a86fdd Mon Sep 17 00:00:00 2001 From: Mariusz Sabath Date: Wed, 3 Jun 2020 22:54:16 +0200 Subject: [PATCH 04/17] Post-review updates --- buildTSI.sh | 1 + components/jwt-sidecar/get-vault-secrets.sh | 10 ++--- components/tsi-util/Dockerfile | 18 ++++++++ components/tsi-util/Makefile | 36 ++++++++++++++++ .../{node-setup => tsi-util}/secret-maker.sh | 29 ++++++++----- examples/myubuntu-all.yaml | 14 +++---- examples/myubuntu.yaml | 4 +- examples/vault/demo.registerJSS.sh | 18 +++++--- examples/vault/demo.secret-maker.local.sh | 15 ++++--- examples/vault/demo.secret-maker.sh | 41 +++++++++++-------- 10 files changed, 132 insertions(+), 54 deletions(-) create mode 100644 components/tsi-util/Dockerfile create mode 100644 components/tsi-util/Makefile rename components/{node-setup => tsi-util}/secret-maker.sh (88%) diff --git a/buildTSI.sh b/buildTSI.sh index 6a6d928e..762908c2 100755 --- a/buildTSI.sh +++ b/buildTSI.sh @@ -34,6 +34,7 @@ run() { run "make $ALL$PUSH" run "make $ALL$PUSH -C components/jss/" +run "make $ALL$PUSH -C components/tsi-util/" run "make $ALL$PUSH -C components/vtpm2-server/" run "make $ALL$PUSH -C components/jwt-sidecar/" run "make $ALL$PUSH -C components/node-setup/" diff --git a/components/jwt-sidecar/get-vault-secrets.sh b/components/jwt-sidecar/get-vault-secrets.sh index d8de379d..47fd156f 100755 --- a/components/jwt-sidecar/get-vault-secrets.sh +++ b/components/jwt-sidecar/get-vault-secrets.sh @@ -72,7 +72,7 @@ HELPMEHELPME # run secret retrieval and output results to specified location run() { - # SECNAME=${SECNAME}, CONSTRAINS=${CONSTR}, LOCPATH=${LOCPATH} + # SECNAME=${SECNAME}, CONSTRAINTS=${CONSTR}, LOCPATH=${LOCPATH} local SECNAME=$1 local CONSTR=$2 local LOCPATH=$3 @@ -91,7 +91,7 @@ run() # 2. Using claims associated with the Role, build the Vault Path to the # given secret. - # convert CONSTRAINS into Vault Roles and Vault Paths: + # convert CONSTRAINTS into Vault Roles and Vault Paths: ROLE= VAULT_PATH= @@ -119,7 +119,7 @@ run() ROLE="tsi-role-rcni" VAULT_PATH="secret/tsi-rcni" ;; - *) echo "# ERROR: invalid constrains requested: ${CONSTR}" + *) echo "# ERROR: invalid constraints requested: ${CONSTR}" return 1 ;; esac @@ -193,13 +193,13 @@ run() for row in $(echo "${JSON}" | jq -c '.[]' ); do # for each requested secret parse its attributes SECNAME=$(echo "$row" | jq -r '."tsi.secret/name"') - CONSTR=$(echo "$row" | jq -r '."tsi.secret/constrains"') + CONSTR=$(echo "$row" | jq -r '."tsi.secret/constraints"') LOCPATH=$(echo "$row" | jq -r '."tsi.secret/local-path"') # then run secret retrieval from Vault run "$SECNAME" "$CONSTR" "$LOCPATH" RT=$? if [ "$RT" != "0" ]; then - echo "Error processing secret SECNAME=${SECNAME}, CONSTRAINS=${CONSTR}, LOCPATH=${LOCPATH}" + echo "Error processing secret SECNAME=${SECNAME}, CONSTRAINTS=${CONSTR}, LOCPATH=${LOCPATH}" fi done diff --git a/components/tsi-util/Dockerfile b/components/tsi-util/Dockerfile new file mode 100644 index 00000000..625e905b --- /dev/null +++ b/components/tsi-util/Dockerfile @@ -0,0 +1,18 @@ +FROM ubuntu:18.04 +RUN apt update && \ + apt install -y curl jq vim && \ + apt install -y openssl + +# install yq required for xform YAML to JSON +RUN apt-get install -y software-properties-common && \ + add-apt-repository ppa:rmescandon/yq && \ + apt update && apt install -y yq + +RUN cd /usr/local/bin && \ + curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl && \ + chmod +x kubectl + +COPY secret-maker.sh /usr/local/bin/ + +# run it forever +CMD ["/bin/bash", "-c", "tail -f /dev/null"] diff --git a/components/tsi-util/Makefile b/components/tsi-util/Makefile new file mode 100644 index 00000000..3ae5fc6a --- /dev/null +++ b/components/tsi-util/Makefile @@ -0,0 +1,36 @@ +TSI_VERSION=$(shell cat ../../tsi-version.txt) +GIT_COMMIT_SHA="$(shell git rev-parse --short HEAD 2>/dev/null)" +GIT_REMOTE_URL="$(shell git config --get remote.origin.url 2>/dev/null)" +BUILD_DATE="$(shell date -u +"%Y-%m-%dT%H:%M:%SZ")" +BINARY_NAME="tsi-util" +REPO ?= trustedseriviceidentity +IMAGE := $(REPO)/$(BINARY_NAME):$(GIT_COMMIT_SHA) +MUTABLE_IMAGE := $(REPO)/$(BINARY_NAME):$(TSI_VERSION) +LATEST := $(REPO)/$(BINARY_NAME):latest + +all: docker timestamp + +allpush: docker docker-push timestamp + +fastpush: fast docker-push timestamp + +fast: + docker build -t $(IMAGE) . + docker tag $(IMAGE) $(MUTABLE_IMAGE) + docker tag $(IMAGE) $(LATEST) + date + +docker: + docker build --no-cache -t $(IMAGE) . + docker tag $(IMAGE) $(MUTABLE_IMAGE) + docker tag $(IMAGE) $(LATEST) + +docker-push: + docker push $(IMAGE) + docker push $(MUTABLE_IMAGE) + docker push $(LATEST) + +timestamp: + date + +.PHONY: all fast allpush fastpush docker docker-push timestamp diff --git a/components/node-setup/secret-maker.sh b/components/tsi-util/secret-maker.sh similarity index 88% rename from components/node-setup/secret-maker.sh rename to components/tsi-util/secret-maker.sh index 3222f0eb..4147b1d1 100755 --- a/components/node-setup/secret-maker.sh +++ b/components/tsi-util/secret-maker.sh @@ -56,11 +56,10 @@ helpme() This script helps building TSI policies syntax: - $0 [cluster-info.yaml] [pod-info.json] + $0 [cluster-info.yaml] [pod-info.yaml] where: - [cluster-info.yaml] - cluster info - [pod-info.json] - pod info - + [cluster-info.yaml] - cluster info, otherwise defaults to '/tmp/clusterinfo' + [pod-info.yaml] - pod info, otherwise defaults to '/tmp/podinfo' HELPMEHELPME } @@ -93,7 +92,7 @@ buildSecrets() echo "vault kv put secret/tsi-rcni/${REGION}/${CLUSTER}/${NS}/${IMGSHA}/${SECNAME} ${SECRET_VALUE}" POLICIES+=('tsi-rcni') ;; - *) echo "# ERROR: invalid constrains requested: ${CONSTR}" + *) echo "# ERROR: invalid constraints requested: ${CONSTR}" ;; esac } @@ -101,14 +100,22 @@ buildSecrets() #### End of functions # validate the arguments -if [[ "$1" == "-?" || "$1" == "-h" || "$1" == "--help" || "$2" == "" ]] ; then +if [[ "$1" == "-?" || "$1" == "-h" || "$1" == "--help" ]] ; then helpme exit 1 fi -CLUSTER_YAML="$1" -POD_JSON="$2" +if [[ "$1" == "" ]] ; then + CLUSTER_YAML="/tmp/clusterinfo" +else + CLUSTER_YAML="$1" +fi +if [[ "$2" == "" ]] ; then + POD_YAML="/tmp/podinfo" +else + POD_YAML="$2" +fi ### Get Cluter Information @@ -130,7 +137,7 @@ echo "# Cluster: $CLUSTER DataCenter: $DC Region: $REGION" # getting the secrets annotations require a bit more work TMPTSI="/tmp/tsi.$$" -cat ${POD_JSON} > ${TMPTSI}.1 +cat ${POD_YAML} > ${TMPTSI}.1 yq r -j ${TMPTSI}.1 |jq -r '.spec.template.metadata.annotations."tsi.secrets"' > ${TMPTSI}.2 DEPLOY=$(yq r -j ${TMPTSI}.1) @@ -176,7 +183,7 @@ POLICIES=() for row in $(echo "${JSON}" | jq -c '.[]' ); do # for each requested secret parse its attributes SECNAME=$(echo "$row" | jq -r '."tsi.secret/name"') - CONSTR=$(echo "$row" | jq -r '."tsi.secret/constrains"') + CONSTR=$(echo "$row" | jq -r '."tsi.secret/constraints"') LOCPATH=$(echo "$row" | jq -r '."tsi.secret/local-path"') # local-path must start with "mysecrets" @@ -186,7 +193,7 @@ for row in $(echo "${JSON}" | jq -c '.[]' ); do buildSecrets "$SECNAME" "$CONSTR" RT=$? if [ "$RT" != "0" ]; then - echo "Error building a secret SECNAME=${SECNAME}, CONSTR=${CONSTR}, LOCPATH=${LOCPATH}" + echo "# Error building a secret SECNAME=${SECNAME}, CONSTR=${CONSTR}, LOCPATH=${LOCPATH}" fi else diff --git a/examples/myubuntu-all.yaml b/examples/myubuntu-all.yaml index 3060277d..60cd28bc 100644 --- a/examples/myubuntu-all.yaml +++ b/examples/myubuntu-all.yaml @@ -15,25 +15,25 @@ spec: admission.trusted.identity/inject: "true" tsi.secrets: | - tsi.secret/name: "mysecret1" - tsi.secret/constrains: "region,cluster-name,namespace,images" + tsi.secret/constraints: "region,cluster-name,namespace,images" tsi.secret/local-path: "mysecrets/myubuntu" - tsi.secret/name: "mysecret2.json" - tsi.secret/constrains: "region,images" + tsi.secret/constraints: "region,images" tsi.secret/local-path: "mysecrets/" - tsi.secret/name: "mysecret3" - tsi.secret/constrains: "region,cluster-name,namespace" + tsi.secret/constraints: "region,cluster-name,namespace" tsi.secret/local-path: "mysecrets/myubuntu" - tsi.secret/name: "mysecret4" - tsi.secret/constrains: "region" + tsi.secret/constraints: "region" tsi.secret/local-path: "mysecrets" - tsi.secret/name: "password" - tsi.secret/constrains: "region" + tsi.secret/constraints: "region" tsi.secret/local-path: "mysecrets" - tsi.secret/name: "invalid" - tsi.secret/constrains: "region" + tsi.secret/constraints: "region" tsi.secret/local-path: "mysecretsx" - tsi.secret/name: "non-existing" - tsi.secret/constrains: "regionx" + tsi.secret/constraints: "regionx" tsi.secret/local-path: "mysecrets" labels: app: myubuntu-all diff --git a/examples/myubuntu.yaml b/examples/myubuntu.yaml index 1865f938..38e3dadc 100644 --- a/examples/myubuntu.yaml +++ b/examples/myubuntu.yaml @@ -15,10 +15,10 @@ spec: admission.trusted.identity/inject: "true" tsi.secrets: | - tsi.secret/name: "mysecret1" - tsi.secret/constrains: "region,images" + tsi.secret/constraints: "region,images" tsi.secret/local-path: "mysecrets/" - tsi.secret/name: "mysecret2" - tsi.secret/constrains: "region" + tsi.secret/constraints: "region" tsi.secret/local-path: "mysecrets" labels: app: myubuntu diff --git a/examples/vault/demo.registerJSS.sh b/examples/vault/demo.registerJSS.sh index 1dc83179..366a8f3b 100755 --- a/examples/vault/demo.registerJSS.sh +++ b/examples/vault/demo.registerJSS.sh @@ -1,5 +1,8 @@ #!/bin/bash +TEMPDIR="/tmp/tsi" +mkdir -p ${TEMPDIR} + ## create help menu: helpme() { @@ -25,7 +28,7 @@ register() echo "processing pod $1 for node IP $nodeIP" # get CSR for each node represented by pod-name - CSR=$1.csr + CSR="${TEMPDIR}/$1.csr" # first obtain CSR from each node $kk exec -it $1 -- sh -c 'curl $HOST_IP:5000/public/getCSR' > $CSR #cat $CSR @@ -36,7 +39,7 @@ register() fi # extract the X509v3 TSI fields: - TSIEXT=$1.csr.tsi + TSIEXT="${TEMPDIR}/$1.csr.tsi" openssl req -in "${CSR}" -noout -text |grep "URI:TSI" > $TSIEXT RT=$? if [ $RT -ne 0 ] ; then @@ -61,16 +64,19 @@ register() # remove any previously set VAULT_TOKEN, that overrides ROOT_TOKEN in Vault client export VAULT_TOKEN= - X5C="$1.x5c" + X5C="${TEMPDIR}/$1.x5c" + OUT="${TEMPDIR}/out.$$" + # create an intermedate certificate for 50 years - vault write pki/root/sign-intermediate csr=@$CSR format=pem_bundle ttl=438000h uri_sans="$TSI_URI" -format=json > out - CERT=$(cat out | jq -r '.["data"].certificate' | grep -v '\-\-\-') - CHAIN=$(cat out | jq -r '.["data"].issuing_ca' | grep -v '\-\-\-') + vault write pki/root/sign-intermediate csr=@$CSR format=pem_bundle ttl=438000h uri_sans="$TSI_URI" -format=json > ${OUT} + CERT=$(cat ${OUT} | jq -r '.["data"].certificate' | grep -v '\-\-\-') + CHAIN=$(cat ${OUT} | jq -r '.["data"].issuing_ca' | grep -v '\-\-\-') echo "[\"${CERT}\",\"${CHAIN}\"]" > "$X5C" # cleanup CSR rm "${CSR}" rm "${TSIEXT}" + rm "${OUT}" # cat "$X5C" # copy the x5c file to the setup pod: diff --git a/examples/vault/demo.secret-maker.local.sh b/examples/vault/demo.secret-maker.local.sh index ed8a137a..af1bc3dd 100755 --- a/examples/vault/demo.secret-maker.local.sh +++ b/examples/vault/demo.secret-maker.local.sh @@ -25,7 +25,7 @@ if [[ "$1" == "-?" || "$1" == "-h" || "$1" == "--help" || "$2" == "" ]] ; then exit 1 fi -# check prereqs +# check prereqs jq_cmd="jq --version" yq_cmd="yq --version" @@ -70,9 +70,12 @@ case $key in esac done -SYSINFO="/tmp/sysinfo.$$" -kubectl get cm -n kube-system cluster-info -o yaml > ${SYSINFO} -PODINFO="/tmp/podinfo.$$" +TEMPDIR="/tmp/tsi" +mkdir -p ${TEMPDIR} + +CLUSTERINFO="${TEMPDIR}/clusterinfo.$$" +kubectl get cm -n kube-system cluster-info -o yaml > ${CLUSTERINFO} +PODINFO="${TEMPDIR}/podinfo.$$" kubectl create -f ${FILE} -n ${NS} --dry-run=true -o yaml > ${PODINFO} -../../components/node-setup/secret-maker.sh ${SYSINFO} ${PODINFO} -rm ${SYSINFO} ${PODINFO} +../../components/node-setup/secret-maker.sh ${CLUSTERINFO} ${PODINFO} +rm ${CLUSTERINFO} ${PODINFO} diff --git a/examples/vault/demo.secret-maker.sh b/examples/vault/demo.secret-maker.sh index 09bf43c7..aeceaf32 100755 --- a/examples/vault/demo.secret-maker.sh +++ b/examples/vault/demo.secret-maker.sh @@ -25,6 +25,15 @@ if [[ "$1" == "-?" || "$1" == "-h" || "$1" == "--help" || "$2" == "" ]] ; then exit 1 fi +docker_cmd="docker --version" + +if [[ ! $(eval ${docker_cmd}) ]]; then + echo "docker installation required to proceed" + echo "(https://docs.docker.com/get-docker/)" + exit 1 +fi + + NS="default" POSITIONAL=() @@ -54,23 +63,21 @@ case $key in esac done -SYSINFO="/tmp/sysinfo.$$" -kubectl get cm -n kube-system cluster-info -o yaml > ${SYSINFO} -PODINFO="/tmp/podinfo.$$" +# check if the pod deployment file exists: +if [ ! -f "$FILE" ]; then + echo "File $FILE does not exist" + exit 1 +fi + +TEMPDIR="/tmp/tsi" +mkdir -p ${TEMPDIR} + +CLUSTERINFO="${TEMPDIR}/clusterinfo.$$" +kubectl get cm -n kube-system cluster-info -o yaml > ${CLUSTERINFO} +PODINFO="${TEMPDIR}/podinfo.$$" kubectl create -f ${FILE} -n ${NS} --dry-run=true -o yaml > ${PODINFO} -kk="kubectl -n ${TSINS}" -# get the first `tsi-node-setup` pod in Running state -SETPOD=$(${kk} get po | grep tsi-node-setup | grep 'Running' | awk '{print $1}' | sed -n 1p ) -if [[ "$SETPOD" == "" ]]; then - echo "Required tsi-node-setup daemonset is not running" - echo "For more information, please visit: " - echo " https://github.com/IBM/trusted-service-identity/examples/vault/README.md#secrets" - exit 1 -fi +docker run -v ${CLUSTERINFO}:/tmp/clusterinfo -v ${PODINFO}:/tmp/podinfo \ +docker.io/trustedseriviceidentity/tsi-util:latest /usr/local/bin/secret-maker.sh /tmp/clusterinfo /tmp/podinfo -# copy the files into the pod -${kk} cp ${SYSINFO} ${SETPOD}:/tmp/sysinfo -${kk} cp ${PODINFO} ${SETPOD}:/tmp/podinfo -${kk} exec -it $SETPOD -- sh -c '/usr/local/bin/secret-maker.sh /tmp/sysinfo /tmp/podinfo' -rm ${SYSINFO} ${PODINFO} +rm ${CLUSTERINFO} ${PODINFO} From f63b316ee8ff8aca6c43281a0353adface60ef33 Mon Sep 17 00:00:00 2001 From: Mariusz Sabath Date: Wed, 3 Jun 2020 22:58:25 +0200 Subject: [PATCH 05/17] Update Dockerfile --- components/node-setup/Dockerfile | 5 ----- 1 file changed, 5 deletions(-) diff --git a/components/node-setup/Dockerfile b/components/node-setup/Dockerfile index 42f5795c..e109647b 100644 --- a/components/node-setup/Dockerfile +++ b/components/node-setup/Dockerfile @@ -3,11 +3,6 @@ RUN apt update && \ apt install -y curl jq vim && \ apt install -y openssl -# install yq required for xform YAML to JSON -RUN apt-get install -y software-properties-common && \ - add-apt-repository ppa:rmescandon/yq && \ - apt update && apt install -y yq - RUN cd /usr/local/bin && \ curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl && \ chmod +x kubectl From ced35e46f1b596b5e4681874059506dfe22946c5 Mon Sep 17 00:00:00 2001 From: Mariusz Sabath Date: Wed, 3 Jun 2020 22:59:23 +0200 Subject: [PATCH 06/17] Update Dockerfile --- components/node-setup/Dockerfile | 1 - 1 file changed, 1 deletion(-) diff --git a/components/node-setup/Dockerfile b/components/node-setup/Dockerfile index e109647b..cca77e2d 100644 --- a/components/node-setup/Dockerfile +++ b/components/node-setup/Dockerfile @@ -8,7 +8,6 @@ RUN cd /usr/local/bin && \ chmod +x kubectl COPY init-node.sh /usr/local/bin/ -COPY secret-maker.sh /usr/local/bin/ ARG DEFAULT_PRIVATE_DIR="/host/tsi-secure" ENV PRIVATEDIR=${DEFAULT_PRIVATE_DIR} From c4369af1d9eeb5bb868e1a75947bd0620bc278b4 Mon Sep 17 00:00:00 2001 From: Mariusz Sabath Date: Thu, 4 Jun 2020 14:43:03 +0200 Subject: [PATCH 07/17] Containeraized load-sample-policies.sh script --- components/tsi-util/Dockerfile | 8 ++ components/tsi-util/load-sample-policies.sh | 86 +++++++++++++++++++ .../tsi-util/vault-tpl/tsi-policy.r.hcl.tpl | 6 ++ .../tsi-util/vault-tpl/tsi-policy.rcn.hcl.tpl | 10 +++ .../vault-tpl/tsi-policy.rcni.hcl.tpl | 9 ++ .../tsi-util/vault-tpl/tsi-policy.ri.hcl.tpl | 7 ++ examples/vault/demo.load-sample-policies.sh | 69 ++++----------- 7 files changed, 141 insertions(+), 54 deletions(-) create mode 100755 components/tsi-util/load-sample-policies.sh create mode 100644 components/tsi-util/vault-tpl/tsi-policy.r.hcl.tpl create mode 100644 components/tsi-util/vault-tpl/tsi-policy.rcn.hcl.tpl create mode 100644 components/tsi-util/vault-tpl/tsi-policy.rcni.hcl.tpl create mode 100644 components/tsi-util/vault-tpl/tsi-policy.ri.hcl.tpl diff --git a/components/tsi-util/Dockerfile b/components/tsi-util/Dockerfile index 625e905b..2283af4c 100644 --- a/components/tsi-util/Dockerfile +++ b/components/tsi-util/Dockerfile @@ -1,5 +1,6 @@ FROM ubuntu:18.04 RUN apt update && \ + apt install -y wget unzip && \ apt install -y curl jq vim && \ apt install -y openssl @@ -12,7 +13,14 @@ RUN cd /usr/local/bin && \ curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl && \ chmod +x kubectl +RUN wget https://releases.hashicorp.com/vault/1.4.2/vault_1.4.2_linux_amd64.zip && \ + unzip vault_1.4.2_linux_amd64.zip && \ + mv vault /usr/local/bin/ && \ + rm -f vault_1.4.2_linux_amd64.zip + COPY secret-maker.sh /usr/local/bin/ +COPY load-sample-policies.sh /usr/local/bin/ +COPY vault-tpl/ /vault-tpl # run it forever CMD ["/bin/bash", "-c", "tail -f /dev/null"] diff --git a/components/tsi-util/load-sample-policies.sh b/components/tsi-util/load-sample-policies.sh new file mode 100755 index 00000000..7ca16a8a --- /dev/null +++ b/components/tsi-util/load-sample-policies.sh @@ -0,0 +1,86 @@ +#!/bin/bash + +# Trusted Service Identiy plugin name +export PLUGIN="vault-plugin-auth-ti-jwt" + +## create help menu: +helpme() +{ + cat < + Where: + vault_addr - vault address (or ingress) in format http://vault.server:8200 + token - vault root token to setup the plugin + +Or make sure ROOT_TOKEN and VAULT_ADDR are set as environment variables. +export ROOT_TOKEN= +export VAULT_ADDR=(vault address in format http://vault.server:8200) + +HELPMEHELPME +} + +loadVault() +{ + #docker run -d --name=dev-vault -v ${PWD}/local.json:/vault/config/local.json -v ${PWD}/pkg/linux_amd64/${PLUGIN}:/plugins/${PLUGIN} -p 127.0.0.1:8200:8200/tcp vault + # echo "Root Token: ${ROOT_TOKEN}" + vault login -no-print ${ROOT_TOKEN} + RT=$? + + if [ $RT -ne 0 ] ; then + echo "Vault login failed!" + exit 1 + fi + + export MOUNT_ACCESSOR=$(curl --header "X-Vault-Token: ${ROOT_TOKEN}" --request GET ${VAULT_ADDR}/v1/sys/auth | jq -r '.["trusted-identity/"].accessor') + + # Use policy templates to create policy files. + # The example below uses 4 different policies with the following constraints: + # - rcni - uses region, cluster-name, namespace and images + # - rcn - uses region, cluster-name, namespace + # - ri - uses region and images + # - r - uses region only + + # replace mount accessor in policy + sed "s/<%MOUNT_ACCESSOR%>/$MOUNT_ACCESSOR/g" /vault-tpl/tsi-policy.rcni.hcl.tpl > /vault-tpl/tsi-policy.rcni.hcl + sed "s/<%MOUNT_ACCESSOR%>/$MOUNT_ACCESSOR/g" /vault-tpl/tsi-policy.rcn.hcl.tpl > /vault-tpl/tsi-policy.rcn.hcl + sed "s/<%MOUNT_ACCESSOR%>/$MOUNT_ACCESSOR/g" /vault-tpl/tsi-policy.ri.hcl.tpl > /vault-tpl/tsi-policy.ri.hcl + sed "s/<%MOUNT_ACCESSOR%>/$MOUNT_ACCESSOR/g" /vault-tpl/tsi-policy.r.hcl.tpl > /vault-tpl/tsi-policy.r.hcl + + # write policy to grant access to secrets + vault policy write tsi-policy-rcni /vault-tpl/tsi-policy.rcni.hcl + vault policy read tsi-policy-rcni + vault policy write tsi-policy-rcn /vault-tpl/tsi-policy.rcn.hcl + vault policy read tsi-policy-rcn + vault policy write tsi-policy-ri /vault-tpl/tsi-policy.ri.hcl + vault policy read tsi-policy-ri + vault policy write tsi-policy-r /vault-tpl/tsi-policy.r.hcl + vault policy read tsi-policy-r + + # create role to associate policy with login + # we choosed to use one role, one policy association + # *NOTE* the first role MUST include all the metadata that would be used by other roles/policies, not only the first one. + vault write auth/trusted-identity/role/tsi-role-rcni bound_subject="wsched@us.ibm.com" user_claim="pod" metadata_claims="cluster-name,region,namespace,images" policies=tsi-policy-rcni + vault read auth/trusted-identity/role/tsi-role-rcni + + vault write auth/trusted-identity/role/tsi-role-rcn bound_subject="wsched@us.ibm.com" user_claim="pod" metadata_claims="cluster-name,region,namespace" policies=tsi-policy-rcn + vault read auth/trusted-identity/role/tsi-role-rcn + + vault write auth/trusted-identity/role/tsi-role-ri bound_subject="wsched@us.ibm.com" user_claim="pod" metadata_claims="cluster-name,images" policies=tsi-policy-rcn + vault read auth/trusted-identity/role/tsi-role-ri + + vault write auth/trusted-identity/role/tsi-role-r bound_subject="wsched@us.ibm.com" user_claim="pod" metadata_claims="region" policies=tsi-policy-r + vault read auth/trusted-identity/role/tsi-role-r +} + +# validate the arguments +if [[ "$1" != "" && "$2" != "" ]] ; then + export VAULT_ADDR="$1" + export ROOT_TOKEN="$2" + loadVault +elif [[ "$ROOT_TOKEN" == "" || "$VAULT_ADDR" == "" ]] ; then + echo "ROOT_TOKEN and VAULT_ADDR must be set" + helpme +else + loadVault +fi diff --git a/components/tsi-util/vault-tpl/tsi-policy.r.hcl.tpl b/components/tsi-util/vault-tpl/tsi-policy.r.hcl.tpl new file mode 100644 index 00000000..a578cdd2 --- /dev/null +++ b/components/tsi-util/vault-tpl/tsi-policy.r.hcl.tpl @@ -0,0 +1,6 @@ +# This policy template controls the path using: +# * region + +path "secret/data/tsi-r/{{identity.entity.aliases.<%MOUNT_ACCESSOR%>.metadata.region}}/*" { + capabilities = ["read"] +} diff --git a/components/tsi-util/vault-tpl/tsi-policy.rcn.hcl.tpl b/components/tsi-util/vault-tpl/tsi-policy.rcn.hcl.tpl new file mode 100644 index 00000000..88a29953 --- /dev/null +++ b/components/tsi-util/vault-tpl/tsi-policy.rcn.hcl.tpl @@ -0,0 +1,10 @@ +# This policy template controls the path using: +# * region +# * cluster-name +# * namespace + +path "secret/data/tsi-rcn/{{identity.entity.aliases.<%MOUNT_ACCESSOR%>.metadata.region}}/{{identity.entity.aliases.<%MOUNT_ACCESSOR%>.metadata.cluster-name}}/{{identity.entity.aliases.<%MOUNT_ACCESSOR%>.metadata.namespace}}/*" { + # list allows listing the secrets: + # capabilities = ["read", "list"] + capabilities = ["read"] +} diff --git a/components/tsi-util/vault-tpl/tsi-policy.rcni.hcl.tpl b/components/tsi-util/vault-tpl/tsi-policy.rcni.hcl.tpl new file mode 100644 index 00000000..51e190f8 --- /dev/null +++ b/components/tsi-util/vault-tpl/tsi-policy.rcni.hcl.tpl @@ -0,0 +1,9 @@ +# This policy template controls the path using: +# * region +# * cluster-name +# * namespace +# * images + +path "secret/data/tsi-rcni/{{identity.entity.aliases.<%MOUNT_ACCESSOR%>.metadata.region}}/{{identity.entity.aliases.<%MOUNT_ACCESSOR%>.metadata.cluster-name}}/{{identity.entity.aliases.<%MOUNT_ACCESSOR%>.metadata.namespace}}/{{identity.entity.aliases.<%MOUNT_ACCESSOR%>.metadata.images}}/*" { + capabilities = ["read"] +} diff --git a/components/tsi-util/vault-tpl/tsi-policy.ri.hcl.tpl b/components/tsi-util/vault-tpl/tsi-policy.ri.hcl.tpl new file mode 100644 index 00000000..3c94cc46 --- /dev/null +++ b/components/tsi-util/vault-tpl/tsi-policy.ri.hcl.tpl @@ -0,0 +1,7 @@ +# This policy template controls the path using: +# * region +# * images + +path "secret/data/tsi-ri/{{identity.entity.aliases.<%MOUNT_ACCESSOR%>.metadata.region}}/{{identity.entity.aliases.<%MOUNT_ACCESSOR%>.metadata.images}}/*" { + capabilities = ["read"] +} diff --git a/examples/vault/demo.load-sample-policies.sh b/examples/vault/demo.load-sample-policies.sh index 79791a0f..bd89c1c4 100755 --- a/examples/vault/demo.load-sample-policies.sh +++ b/examples/vault/demo.load-sample-policies.sh @@ -1,70 +1,31 @@ #!/bin/bash -# Trusted Service Identiy plugin name -export PLUGIN="vault-plugin-auth-ti-jwt" - ## create help menu: helpme() { cat < + Where: + vault_addr - vault address (or ingress) in format http://vault.server:8200 + token - vault root token to setup the plugin + +Or make sure ROOT_TOKEN and VAULT_ADDR are set as environment variables. export ROOT_TOKEN= export VAULT_ADDR=(vault address in format http://vault.server:8200) HELPMEHELPME -} - -loadVault() -{ - #docker run -d --name=dev-vault -v ${PWD}/local.json:/vault/config/local.json -v ${PWD}/pkg/linux_amd64/${PLUGIN}:/plugins/${PLUGIN} -p 127.0.0.1:8200:8200/tcp vault - # echo "Root Token: ${ROOT_TOKEN}" - vault login -no-print ${ROOT_TOKEN} - - export MOUNT_ACCESSOR=$(curl --header "X-Vault-Token: ${ROOT_TOKEN}" --request GET ${VAULT_ADDR}/v1/sys/auth | jq -r '.["trusted-identity/"].accessor') - - # Use policy templates to create policy files. - # The example below uses 4 different policies with the following constraints: - # - rcni - uses region, cluster-name, namespace and images - # - rcn - uses region, cluster-name, namespace - # - ri - uses region and images - # - r - uses region only - - # replace mount accessor in policy - sed "s/<%MOUNT_ACCESSOR%>/$MOUNT_ACCESSOR/g" tsi-policy.rcni.hcl.tpl > tsi-policy.rcni.hcl - sed "s/<%MOUNT_ACCESSOR%>/$MOUNT_ACCESSOR/g" tsi-policy.rcn.hcl.tpl > tsi-policy.rcn.hcl - sed "s/<%MOUNT_ACCESSOR%>/$MOUNT_ACCESSOR/g" tsi-policy.ri.hcl.tpl > tsi-policy.ri.hcl - sed "s/<%MOUNT_ACCESSOR%>/$MOUNT_ACCESSOR/g" tsi-policy.r.hcl.tpl > tsi-policy.r.hcl - - # write policy to grant access to secrets - vault policy write tsi-policy-rcni tsi-policy.rcni.hcl - vault policy read tsi-policy-rcni - vault policy write tsi-policy-rcn tsi-policy.rcn.hcl - vault policy read tsi-policy-rcn - vault policy write tsi-policy-ri tsi-policy.ri.hcl - vault policy read tsi-policy-ri - vault policy write tsi-policy-r tsi-policy.r.hcl - vault policy read tsi-policy-r - - # create role to associate policy with login - # we choosed to use one role, one policy association - # *NOTE* the first role MUST include all the metadata that would be used by other roles/policies, not only the first one. - vault write auth/trusted-identity/role/tsi-role-rcni bound_subject="wsched@us.ibm.com" user_claim="pod" metadata_claims="cluster-name,region,namespace,images" policies=tsi-policy-rcni - vault read auth/trusted-identity/role/tsi-role-rcni - - vault write auth/trusted-identity/role/tsi-role-rcn bound_subject="wsched@us.ibm.com" user_claim="pod" metadata_claims="cluster-name,region,namespace" policies=tsi-policy-rcn - vault read auth/trusted-identity/role/tsi-role-rcn - - vault write auth/trusted-identity/role/tsi-role-ri bound_subject="wsched@us.ibm.com" user_claim="pod" metadata_claims="cluster-name,images" policies=tsi-policy-rcn - vault read auth/trusted-identity/role/tsi-role-ri - - vault write auth/trusted-identity/role/tsi-role-r bound_subject="wsched@us.ibm.com" user_claim="pod" metadata_claims="region" policies=tsi-policy-r - vault read auth/trusted-identity/role/tsi-role-r +exit 1 } # validate the arguments -if [[ "$ROOT_TOKEN" == "" || "$VAULT_ADDR" == "" ]] ; then +if [[ "$1" != "" && "$2" != "" ]] ; then + VAULT_ADDR="$1" + ROOT_TOKEN="$2" +elif [[ "$ROOT_TOKEN" == "" || "$VAULT_ADDR" == "" ]] ; then echo "ROOT_TOKEN and VAULT_ADDR must be set" helpme -else - loadVault fi + + +docker run trustedseriviceidentity/tsi-util:latest load-sample-policies.sh ${VAULT_ADDR} ${ROOT_TOKEN} From dc1af542a3c92d60ec1364c0d0ff4ba69b01a9f5 Mon Sep 17 00:00:00 2001 From: Mariusz Sabath Date: Wed, 10 Jun 2020 17:36:54 +0200 Subject: [PATCH 08/17] new, containerized utilities --- README.md | 10 ++--- charts/ti-key-release-2/templates/NOTES.txt | 10 ++++- components/tsi-util/Dockerfile | 1 + components/tsi-util/getClusterInfo.sh | 45 +++++++++++++++++++++ components/tsi-util/load-sample-policies.sh | 6 +-- components/tsi-util/secret-maker.sh | 25 +++++------- examples/vault/demo.getClusterInfo.sh | 19 +++++++++ examples/vault/demo.secret-maker.sh | 3 -- examples/vault/tsi-policy.r.hcl.tpl | 6 --- examples/vault/tsi-policy.rcn.hcl.tpl | 10 ----- examples/vault/tsi-policy.rcni.hcl.tpl | 9 ----- examples/vault/tsi-policy.ri.hcl.tpl | 7 ---- 12 files changed, 90 insertions(+), 61 deletions(-) create mode 100755 components/tsi-util/getClusterInfo.sh create mode 100755 examples/vault/demo.getClusterInfo.sh delete mode 100644 examples/vault/tsi-policy.r.hcl.tpl delete mode 100644 examples/vault/tsi-policy.rcn.hcl.tpl delete mode 100644 examples/vault/tsi-policy.rcni.hcl.tpl delete mode 100644 examples/vault/tsi-policy.ri.hcl.tpl diff --git a/README.md b/README.md index 5e3b3183..481d4217 100644 --- a/README.md +++ b/README.md @@ -220,7 +220,7 @@ To use vTPM, deploy TSI Node Setup helm charts with all the functions disabled. Replace X.X.X with a proper version numbers (typically the highest, the most recent). ```console helm install charts/tsi-node-setup-X.X.X --debug --name tsi-setup --set reset.all=false \ ---set reset.x5c=false --set cluster.name=CLUSTER_NAME --set cluster.region=CLUSTER_REGION +--set reset.x5c=false --set cluster.name=$CLUSTER_NAME --set cluster.region=$REGION ``` In order to run JSS server, all worker nodes have to be setup with private keys. This operation needs to be executed only once. @@ -230,13 +230,13 @@ If you are running this setup for the first time or like to override previous se ```console helm install charts/tsi-node-setup-X.X.X --debug --name tsi-setup --set reset.all=true \ ---set cluster.name=CLUSTER_NAME --set cluster.region=CLUSTER_REGION +--set cluster.name=$CLUSTER_NAME --set cluster.region=$REGION ``` To keep the existing private key, but just reset the intermediate CA (`x5c`) ```console helm install charts/tsi-node-setup-X.X.X --debug --name tsi-setup --set reset.x5c=true \ ---set cluster.name=CLUSTER_NAME --set cluster.region=CLUSTER_REGION +--set cluster.name=$CLUSTER_NAME --set cluster.region=$REGION ``` Once the worker nodes are setup, deploy the TSI environment @@ -263,8 +263,8 @@ Replace X.X.X with a proper version numbers (typically the highest, the most rec ```console export VAULT_ADDR=http:// helm install charts/ti-key-release-2-X.X.X.tgz --debug --name tsi \ ---set ti-key-release-1.cluster.name=CLUSTER_NAME \ ---set ti-key-release-1.cluster.region=CLUSTER_REGION \ +--set ti-key-release-1.cluster.name=$CLUSTER_NAME \ +--set ti-key-release-1.cluster.region=$REGION \ --set ti-key-release-1.vaultAddress=$VAULT_ADDR \ --set jssService.type=jss-server ``` diff --git a/charts/ti-key-release-2/templates/NOTES.txt b/charts/ti-key-release-2/templates/NOTES.txt index 9fa2ab1d..44bf91ef 100644 --- a/charts/ti-key-release-2/templates/NOTES.txt +++ b/charts/ti-key-release-2/templates/NOTES.txt @@ -10,7 +10,7 @@ This helm chart installs environment for Trusted Identity # however, there is a problem with retrieving values that contain "-" # see the helm issue: https://github.com/helm/helm/issues/2192 This chart tiVersion: {{ .Chart.AppVersion }} - + vaultAddress: {{ index .Values "ti-key-release-1" "vaultAddress" }} cluster.name: {{ index .Values "ti-key-release-1" "cluster" "name" }} cluster.region: {{ index .Values "ti-key-release-1" "cluster" "region" }} @@ -18,8 +18,14 @@ This helm chart installs environment for Trusted Identity secrets.refreshSec: {{ index .Values "ti-key-release-1" "secrets" "refreshSec" }} jssService.type: {{ .Values.jssService.type }} -To execute a test, create a new namespace then deploy the test application: +To execute a test, create a new namespace, load the application secrets to vault, +then deploy the test application: + kubectl create ns test + examples/vault/demo.secret-maker.sh -f examples/myubuntu.yaml -n test > myubuntu.secrets.sh + # update the myubuntu + chmod + myubuntu.secrets.sh + ./myubuntu.secrets.sh kubectl create -f examples/myubuntu.yaml -n test Then check if the secret is available: kubectl -n test exec -it $(k -n test get pods | grep myubuntu | awk '{print $1}' ) cat /tsi-secrets/mysecrets/mysecret4 diff --git a/components/tsi-util/Dockerfile b/components/tsi-util/Dockerfile index 2283af4c..23dd48a7 100644 --- a/components/tsi-util/Dockerfile +++ b/components/tsi-util/Dockerfile @@ -19,6 +19,7 @@ RUN wget https://releases.hashicorp.com/vault/1.4.2/vault_1.4.2_linux_amd64.zip rm -f vault_1.4.2_linux_amd64.zip COPY secret-maker.sh /usr/local/bin/ +COPY getClusterInfo.sh /usr/local/bin/ COPY load-sample-policies.sh /usr/local/bin/ COPY vault-tpl/ /vault-tpl diff --git a/components/tsi-util/getClusterInfo.sh b/components/tsi-util/getClusterInfo.sh new file mode 100755 index 00000000..b9759305 --- /dev/null +++ b/components/tsi-util/getClusterInfo.sh @@ -0,0 +1,45 @@ +#!/bin/bash + +## create help menu: +helpme() +{ + cat < ${CLYM1} +CLJS1=$(yq r -j ${CLYM1} |jq -r '.data."cluster-config.json"') +rm "${CLYM1}" +CLUSTER=$(echo "$CLJS1" | jq -r '.name') +# DC=$(echo "$CLJS1" | jq -r '.datacenter') + +# Confirmed with Armada team that CRN format should stay consistent for a while +# CRN format example: +# crn:v1:bluemix:public:containers-kubernetes:eu-de:586283a9abda5102d46e1b94b923a6c5:5f4306a2738d4cdd89ff067c9481555e +REGION=$(echo "$CLJS1" | jq -r '."crn"' | cut -d":" -f6) +echo "export CLUSTER_NAME=$CLUSTER" +echo "export REGION=$REGION" +# echo "export DATA_CENTER=$DC" diff --git a/components/tsi-util/load-sample-policies.sh b/components/tsi-util/load-sample-policies.sh index 7ca16a8a..28c1777d 100755 --- a/components/tsi-util/load-sample-policies.sh +++ b/components/tsi-util/load-sample-policies.sh @@ -60,13 +60,13 @@ loadVault() # create role to associate policy with login # we choosed to use one role, one policy association # *NOTE* the first role MUST include all the metadata that would be used by other roles/policies, not only the first one. - vault write auth/trusted-identity/role/tsi-role-rcni bound_subject="wsched@us.ibm.com" user_claim="pod" metadata_claims="cluster-name,region,namespace,images" policies=tsi-policy-rcni + vault write auth/trusted-identity/role/tsi-role-rcni bound_subject="wsched@us.ibm.com" user_claim="pod" metadata_claims="region,cluster-name,namespace,images" policies=tsi-policy-rcni vault read auth/trusted-identity/role/tsi-role-rcni - vault write auth/trusted-identity/role/tsi-role-rcn bound_subject="wsched@us.ibm.com" user_claim="pod" metadata_claims="cluster-name,region,namespace" policies=tsi-policy-rcn + vault write auth/trusted-identity/role/tsi-role-rcn bound_subject="wsched@us.ibm.com" user_claim="pod" metadata_claims="region,cluster-name,namespace" policies=tsi-policy-rcn vault read auth/trusted-identity/role/tsi-role-rcn - vault write auth/trusted-identity/role/tsi-role-ri bound_subject="wsched@us.ibm.com" user_claim="pod" metadata_claims="cluster-name,images" policies=tsi-policy-rcn + vault write auth/trusted-identity/role/tsi-role-ri bound_subject="wsched@us.ibm.com" user_claim="pod" metadata_claims="region,images" policies=tsi-policy-ri vault read auth/trusted-identity/role/tsi-role-ri vault write auth/trusted-identity/role/tsi-role-r bound_subject="wsched@us.ibm.com" user_claim="pod" metadata_claims="region" policies=tsi-policy-r diff --git a/components/tsi-util/secret-maker.sh b/components/tsi-util/secret-maker.sh index 4147b1d1..1f0d81f0 100755 --- a/components/tsi-util/secret-maker.sh +++ b/components/tsi-util/secret-maker.sh @@ -19,11 +19,14 @@ cat << EOF # deployment file # # Assumptions: -# 1. File has properly defined annotations including +# 1. Input file has properly defined annotations including # a. 'tsi.secrets' # b. 'admission.trusted.identity/inject: "true"' -# 2. - +# 2. Script is executed in the environment that has Vault client installed +# (https://www.vaultproject.io/downloads) +# 3. Vault env. variables are set +# export ROOT_TOKEN= +# export VAULT_ADDR=(vault address in format http://vault.server:8200) # Define values for the SECRET_VALUE(s) # they must be in "key=value" format @@ -31,12 +34,7 @@ cat << EOF # https://github.com/IBM/trusted-service-identity/examples/vault/README.md#secrets export SECRET_VALUE="secret=xxx" -# To access vault, obtain the Vault Client from (...) -# and define ROOT_TOKEN and VAULT_ADDR env. variables: -# -# export ROOT_TOKEN= -# export VAULT_ADDR=(vault address in format http://vault.server:8200) -# + EOF # prevent expression expending by using a single quote: @@ -92,7 +90,7 @@ buildSecrets() echo "vault kv put secret/tsi-rcni/${REGION}/${CLUSTER}/${NS}/${IMGSHA}/${SECNAME} ${SECRET_VALUE}" POLICIES+=('tsi-rcni') ;; - *) echo "# ERROR: invalid constraints requested: ${CONSTR}" + *) echo "# ERROR: invalid constraints requested: ${CONSTR} for ${SECNAME}" ;; esac } @@ -131,7 +129,6 @@ DC=$(echo "$CLJS1" | jq -r '.datacenter') # CRN format example: # crn:v1:bluemix:public:containers-kubernetes:eu-de:586283a9abda5102d46e1b94b923a6c5:5f4306a2738d4cdd89ff067c9481555e REGION=$(echo "$CLJS1" | jq -r '."crn"' | cut -d":" -f6) -echo "# Cluster: $CLUSTER DataCenter: $DC Region: $REGION" # Get Pod information @@ -173,6 +170,7 @@ else echo "# Set 'admission.trusted.identity/inject' annotation to 'true'" exit 1 fi +echo "# Cluster: $CLUSTER DataCenter: $DC Region: $REGION" echo "# NS=$NS, IMG: $IMG, IMGSHA: $IMGSHA" JSON=$(yq r -j ${TMPTSI}.2) @@ -191,11 +189,6 @@ for row in $(echo "${JSON}" | jq -c '.[]' ); do # build the injection of secret: buildSecrets "$SECNAME" "$CONSTR" - RT=$? - if [ "$RT" != "0" ]; then - echo "# Error building a secret SECNAME=${SECNAME}, CONSTR=${CONSTR}, LOCPATH=${LOCPATH}" - fi - else echo "# ERROR: invalid local-path value: $LOCPATH" fi diff --git a/examples/vault/demo.getClusterInfo.sh b/examples/vault/demo.getClusterInfo.sh new file mode 100755 index 00000000..1e9355a6 --- /dev/null +++ b/examples/vault/demo.getClusterInfo.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +docker_cmd="docker --version" +if [[ ! $(eval ${docker_cmd}) ]]; then + echo "docker installation required to proceed" + echo "(https://docs.docker.com/get-docker/)" + exit 1 +fi + +TEMPDIR="/tmp/tsi" +mkdir -p ${TEMPDIR} + +CLUSTERINFO="${TEMPDIR}/clusterinfo.$$" +kubectl get cm -n kube-system cluster-info -o yaml > ${CLUSTERINFO} + +docker run -v ${CLUSTERINFO}:/tmp/clusterinfo \ +docker.io/trustedseriviceidentity/tsi-util:latest /usr/local/bin/getClusterInfo.sh /tmp/clusterinfo + +rm ${CLUSTERINFO} diff --git a/examples/vault/demo.secret-maker.sh b/examples/vault/demo.secret-maker.sh index aeceaf32..2b1a2707 100755 --- a/examples/vault/demo.secret-maker.sh +++ b/examples/vault/demo.secret-maker.sh @@ -1,8 +1,5 @@ #!/bin/bash -# NS - a TSI namespace (where the tsi-setup daemonset is deployed) -TSINS="trusted-identity" - ## create help menu: helpme() { diff --git a/examples/vault/tsi-policy.r.hcl.tpl b/examples/vault/tsi-policy.r.hcl.tpl deleted file mode 100644 index a578cdd2..00000000 --- a/examples/vault/tsi-policy.r.hcl.tpl +++ /dev/null @@ -1,6 +0,0 @@ -# This policy template controls the path using: -# * region - -path "secret/data/tsi-r/{{identity.entity.aliases.<%MOUNT_ACCESSOR%>.metadata.region}}/*" { - capabilities = ["read"] -} diff --git a/examples/vault/tsi-policy.rcn.hcl.tpl b/examples/vault/tsi-policy.rcn.hcl.tpl deleted file mode 100644 index 88a29953..00000000 --- a/examples/vault/tsi-policy.rcn.hcl.tpl +++ /dev/null @@ -1,10 +0,0 @@ -# This policy template controls the path using: -# * region -# * cluster-name -# * namespace - -path "secret/data/tsi-rcn/{{identity.entity.aliases.<%MOUNT_ACCESSOR%>.metadata.region}}/{{identity.entity.aliases.<%MOUNT_ACCESSOR%>.metadata.cluster-name}}/{{identity.entity.aliases.<%MOUNT_ACCESSOR%>.metadata.namespace}}/*" { - # list allows listing the secrets: - # capabilities = ["read", "list"] - capabilities = ["read"] -} diff --git a/examples/vault/tsi-policy.rcni.hcl.tpl b/examples/vault/tsi-policy.rcni.hcl.tpl deleted file mode 100644 index 51e190f8..00000000 --- a/examples/vault/tsi-policy.rcni.hcl.tpl +++ /dev/null @@ -1,9 +0,0 @@ -# This policy template controls the path using: -# * region -# * cluster-name -# * namespace -# * images - -path "secret/data/tsi-rcni/{{identity.entity.aliases.<%MOUNT_ACCESSOR%>.metadata.region}}/{{identity.entity.aliases.<%MOUNT_ACCESSOR%>.metadata.cluster-name}}/{{identity.entity.aliases.<%MOUNT_ACCESSOR%>.metadata.namespace}}/{{identity.entity.aliases.<%MOUNT_ACCESSOR%>.metadata.images}}/*" { - capabilities = ["read"] -} diff --git a/examples/vault/tsi-policy.ri.hcl.tpl b/examples/vault/tsi-policy.ri.hcl.tpl deleted file mode 100644 index 3c94cc46..00000000 --- a/examples/vault/tsi-policy.ri.hcl.tpl +++ /dev/null @@ -1,7 +0,0 @@ -# This policy template controls the path using: -# * region -# * images - -path "secret/data/tsi-ri/{{identity.entity.aliases.<%MOUNT_ACCESSOR%>.metadata.region}}/{{identity.entity.aliases.<%MOUNT_ACCESSOR%>.metadata.images}}/*" { - capabilities = ["read"] -} From fadedefe5bc1d92d518171ea7fc688fbc02c0ef6 Mon Sep 17 00:00:00 2001 From: Mariusz Sabath Date: Wed, 10 Jun 2020 19:10:29 +0200 Subject: [PATCH 09/17] consistent naming convention --- .../vault/{demo.getClusterInfo.sh => demo.get-cluster-info.sh} | 0 examples/vault/{demo.registerJSS.sh => demo.register-JSS.sh} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename examples/vault/{demo.getClusterInfo.sh => demo.get-cluster-info.sh} (100%) rename examples/vault/{demo.registerJSS.sh => demo.register-JSS.sh} (100%) diff --git a/examples/vault/demo.getClusterInfo.sh b/examples/vault/demo.get-cluster-info.sh similarity index 100% rename from examples/vault/demo.getClusterInfo.sh rename to examples/vault/demo.get-cluster-info.sh diff --git a/examples/vault/demo.registerJSS.sh b/examples/vault/demo.register-JSS.sh similarity index 100% rename from examples/vault/demo.registerJSS.sh rename to examples/vault/demo.register-JSS.sh From 10aab9fa47e5d95b359975d3dfe3278dcfc85171 Mon Sep 17 00:00:00 2001 From: Mariusz Sabath Date: Thu, 11 Jun 2020 12:44:25 +0200 Subject: [PATCH 10/17] added support for pods and daemonsets --- components/tsi-util/secret-maker.sh | 40 ++++++++++++++++--- examples/sample-daemonset.yaml | 26 ++++++++++++ ...ubuntu-all.yaml => sample-deployment.yaml} | 0 examples/sample-pod.yaml | 17 ++++++++ 4 files changed, 77 insertions(+), 6 deletions(-) create mode 100644 examples/sample-daemonset.yaml rename examples/{myubuntu-all.yaml => sample-deployment.yaml} (100%) create mode 100644 examples/sample-pod.yaml diff --git a/components/tsi-util/secret-maker.sh b/components/tsi-util/secret-maker.sh index 1f0d81f0..095b6d79 100755 --- a/components/tsi-util/secret-maker.sh +++ b/components/tsi-util/secret-maker.sh @@ -135,14 +135,41 @@ REGION=$(echo "$CLJS1" | jq -r '."crn"' | cut -d":" -f6) # getting the secrets annotations require a bit more work TMPTSI="/tmp/tsi.$$" cat ${POD_YAML} > ${TMPTSI}.1 -yq r -j ${TMPTSI}.1 |jq -r '.spec.template.metadata.annotations."tsi.secrets"' > ${TMPTSI}.2 + +# get the kind of the deployment: +KIND=$(yq r -j ${TMPTSI}.1 |jq -r '.kind') + +# get the attribute path based on kind: +case $KIND in + "Deployment") + TSI_INJECT='.spec.template.metadata.annotations."admission.trusted.identity/inject"' + TSI_SECRETS='.spec.template.metadata.annotations."tsi.secrets"' + TSI_IMG='.spec.template.spec.containers[0].image' + ;; + "DaemonSet") + TSI_INJECT='.spec.template.metadata.annotations."admission.trusted.identity/inject"' + TSI_SECRETS='.spec.template.metadata.annotations."tsi.secrets"' + TSI_IMG='.spec.template.spec.containers[0].image' + ;; + "Pod") + TSI_INJECT='.metadata.annotations."admission.trusted.identity/inject"' + TSI_SECRETS='.metadata.annotations."tsi.secrets"' + TSI_IMG='.spec.containers[0].image' + ;; + *) echo "# ERROR: Unsupported kind: ${KIND}" + exit 1 + ;; +esac + + +yq r -j ${TMPTSI}.1 |jq -r "${TSI_SECRETS}" > ${TMPTSI}.2 DEPLOY=$(yq r -j ${TMPTSI}.1) NS=$(echo $DEPLOY | jq -r '.metadata.namespace') # TODO we need to add support for multiple images in one pod. # Sort them alphabetically. Do the same algorithm in TSI -IMG=$(echo $DEPLOY | jq -r '.spec.template.spec.containers[0].image') +IMG=$(echo $DEPLOY | jq -r "${TSI_IMG}") # Get the SHA-256 encoded image name. # Encoder depends on the OS: @@ -161,17 +188,18 @@ fi # validate if tsiEnabled is provided correctly # tsiEnabled - convert to lowercase: -tsiEnabled=$(echo $DEPLOY | jq -r '.spec.template.metadata.annotations."admission.trusted.identity/inject"' | awk '{print tolower($0)}') +tsiEnabled=$(echo $DEPLOY | jq -r "${TSI_INJECT}" | awk '{print tolower($0)}') if [[ "$tsiEnabled" == "true" || "$tsiEnabled" == "yes" || "$tsiEnabled" == "on" || "$tsiEnabled" == "y" ]] ; then header + echo "# Using kind: $KIND" echo "# TSI is enabled" + echo "# Cluster: $CLUSTER DataCenter: $DC Region: $REGION" + echo "# NS: $NS, IMG: $IMG, IMGSHA: $IMGSHA" else echo "# ERROR: TSI must be enabled to continue! " echo "# Set 'admission.trusted.identity/inject' annotation to 'true'" exit 1 fi -echo "# Cluster: $CLUSTER DataCenter: $DC Region: $REGION" -echo "# NS=$NS, IMG: $IMG, IMGSHA: $IMGSHA" JSON=$(yq r -j ${TMPTSI}.2) rm ${TMPTSI}.1 ${TMPTSI}.2 @@ -196,5 +224,5 @@ done # remove duplicated policies: sorted_unique_ids=($(echo "${POLICIES[@]}" | tr ' ' '\n' | sort -u | tr '\n' ' ')) -echo "# this deployment uses the following policies/paths: " +echo "# this $KIND uses the following policies/paths: " echo "# ${sorted_unique_ids[@]}" diff --git a/examples/sample-daemonset.yaml b/examples/sample-daemonset.yaml new file mode 100644 index 00000000..54442097 --- /dev/null +++ b/examples/sample-daemonset.yaml @@ -0,0 +1,26 @@ +apiVersion: extensions/v1beta1 +kind: DaemonSet +metadata: + name: alpine-daemonset +spec: + selector: + matchLabels: + name: alpine-daemonset + template: + metadata: + annotations: + admission.trusted.identity/inject: "true" + tsi.secrets: | + - tsi.secret/name: "alpinesecret1" + tsi.secret/constraints: "region,images" + tsi.secret/local-path: "mysecrets/" + - tsi.secret/name: "alpinesecret2" + tsi.secret/constraints: "region" + tsi.secret/local-path: "mysecrets" + labels: + name: alpine-daemonset + spec: + containers: + - image: alpine + name: alpine-daemonset + command: [ "tail", "-f", "/dev/null" ] diff --git a/examples/myubuntu-all.yaml b/examples/sample-deployment.yaml similarity index 100% rename from examples/myubuntu-all.yaml rename to examples/sample-deployment.yaml diff --git a/examples/sample-pod.yaml b/examples/sample-pod.yaml new file mode 100644 index 00000000..5ebda26a --- /dev/null +++ b/examples/sample-pod.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: Pod +metadata: + name: redis-pod + annotations: + admission.trusted.identity/inject: "true" + tsi.secrets: | + - tsi.secret/name: "redissecret1" + tsi.secret/constraints: "region,images" + tsi.secret/local-path: "mysecrets/" + - tsi.secret/name: "redissecret2" + tsi.secret/constraints: "region" + tsi.secret/local-path: "mysecrets" +spec: + containers: + - name: redis-pod + image: redis From b61f5f571a0d3cabf0e02fe89c1dd0135c0d6ce8 Mon Sep 17 00:00:00 2001 From: Mariusz Sabath Date: Thu, 11 Jun 2020 12:49:11 +0200 Subject: [PATCH 11/17] Changed the HTTP error code to 403 --- components/jss/web-server-priv.py | 2 +- components/vtpm2-server/jss-server-priv.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/components/jss/web-server-priv.py b/components/jss/web-server-priv.py index 895b020f..8a8f1486 100644 --- a/components/jss/web-server-priv.py +++ b/components/jss/web-server-priv.py @@ -27,4 +27,4 @@ def get(): return str(out) except Exception as e: print e.output - return "",503 + return "",403 diff --git a/components/vtpm2-server/jss-server-priv.py b/components/vtpm2-server/jss-server-priv.py index 95458398..1f04bf21 100755 --- a/components/vtpm2-server/jss-server-priv.py +++ b/components/vtpm2-server/jss-server-priv.py @@ -31,4 +31,4 @@ def get(): return str(out) except Exception as e: print e.output - return "",503 + return "",403 From 4b0e6e81dc5d5ba43720106ad1557aaa149bbae9 Mon Sep 17 00:00:00 2001 From: Mariusz Sabath Date: Thu, 11 Jun 2020 15:30:00 +0200 Subject: [PATCH 12/17] Final build helm charts --- charts/ti-key-release-2-v1.7.0.tgz | Bin 0 -> 7030 bytes charts/tsi-node-setup-v1.7.0.tgz | Bin 0 -> 2259 bytes go.mod | 4 ++-- go.sum | 10 ++++++---- 4 files changed, 8 insertions(+), 6 deletions(-) create mode 100644 charts/ti-key-release-2-v1.7.0.tgz create mode 100644 charts/tsi-node-setup-v1.7.0.tgz diff --git a/charts/ti-key-release-2-v1.7.0.tgz b/charts/ti-key-release-2-v1.7.0.tgz new file mode 100644 index 0000000000000000000000000000000000000000..91287deb2fb596b094ae7444535a0eb2490f5b5d GIT binary patch literal 7030 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 U^jXvY4*&rF|A^g(dH}ot0GxdGjsO4v literal 0 HcmV?d00001 diff --git a/charts/tsi-node-setup-v1.7.0.tgz b/charts/tsi-node-setup-v1.7.0.tgz new file mode 100644 index 0000000000000000000000000000000000000000..50c2922ab30c27b33a8c9fa941400e99a72eb1d9 GIT binary patch literal 2259 zcmV;^2rTy>iwG0|00000|0w_~VMtOiV@ORlOnEsqVl!4SWK%V1T2nbTPgYhoO;>Dc zVQyr3R8em|NM&qo0PI@bZ{xTT-)H_6Q@e-Wr7PL_umcD<;BraY3z|)WINi2S0WFO! zUMNyWQcir?^lvXn%Ce-`Np3gIVgb*CEtA8UAHU|yGMWWKCKzZmMczA1sWRc5X8hgj zQNQ2s?+*skqfzLH`votffL5s^0a#SXX;; z-w4s1eMF_16cNm}3C;7`&u~BNlLU3FSZ-X~0sMkIgV-Jum`DX0jbUO6MGjY^6R<}~ zlT>CHL268{qh4>yOj?Y?SZ2MGpFi}BDzw2Q(5PlC#(*U#3^Q|*Q6>y!0+o(P0GLt6 zBluZSkw_7q7THg1oLMmhKv1ip?1R%HTMp24OilVzp~E)&2dY@1e}|FdAilAA0m!U1 z`>(w}|8HvD{~6^4>Q^=Z&)om*!Ol+m{_pN=?*E%m7mjd33vR$~y}Q)SLlKfLT%}9{ z(?H=r2Omy@iBuUi1{0Vtj+WsFV@?&qj4DRQ95omTV}zV)jR`PeB+O-@z+jehYEXxS zbiq(HMdR+L&S{KZeTtA^&gDEqVMx^(!NPV_He)Fwk?{>GP?$?%G`qxHR{R^(>YH;8$2v=pd;+V!+6$0i<2NIAE9?ZS18DzH;Sk}j?8I#8qwxneV``v&Ll z;c#^65Zw)8_g&%=cw6UlU5BH~kaX)<>>#F_aNaw0Z6s3gc^%H(Ahw&5QUjE8d8@r* zJ8$ZgOMzb5sB|56rJR-tZEH|xi&kuybG2@ zioY1*CKVB|kfMbm0v2pk&d#2RLvD|Yf)n8nIFo|JzAdV}NZAnBUj#tm)cK1-2U->; z{l+{-%l=olvv+oWbvz2qo%wPd&)NU}Zae-P3#(GDKcVRqM zaQiOHPYx#5DCr`OQR_*;7sI`8ux7crhgqSG^}PvlG?-Y^<;}KlfFQ^VHMQRfj*IEa zCH&gwazk%JYwiDaiabZ9Lz91LD)5Z`-x&_KTlRmrH{9LW|F@v~``#AJSQfch&qniR zp5u?!gwQy}2)23;55#hjkE(g+|aaL-p-c{vjkMlZD6fLSpGk9lEsGu8oxu^%$YBITN+%mIYs;eQt#jUy&zqP=zCH@AZFpt-zt;aJ6f-Go zi2KFGz-Rpb?qGYb<^T8l{hf{fe+#PD|7o7<-fWxPFp)%X544?88vZw>MV$FSZFtmiak_0V>zsb))H?>SSQ1iOK(?q z)&3Z8Z41oq*Q04$?ZjG$9nz_P{( z4-dWNkZ4Vg-D%6ZC^)~6oW=794)`sd>l%lvZZb1Jl)~VhiE3ToYKM&D6cblo#abtd zS(A4$t;^%l@zufUX`>T-HLp3Vdg|R-FYDif!!nhg zp5My2P`Fym;psm|SI3vvX9pjSpNG{d2RtqE^7!v3=Vvb$T2&1?tubAgqVWY>sSTW5 zxNsz=+Et=a%tDw^wGzuO=cB9ZlZ#a#{-$IWwK~8@$d@>I+*9^lP?JWW4K;-hEuMz- zndC)=AM91qbrAt%w#^T2?@U8gb(y@Vr)8jtR}9W*oHBs{OB$UDX>u<3{L$H8A(+dl zULo1`1+_kpv6^YH7QG$lMn(v-#Z z8kHo+}^Xws5alxK{w)+N2hg7KHW+zY2mGRdz?8Lh-eI`RCBu`0ug*`s_gP zx%WS|2g7Fkx6|L-8*bvix1iShA3pROHR72S@!!he<^_S?*PiW$+SI!Lq0O_|R7i!d zr{lT%KiCc3mbmt;WkA9a3(M$;nC=NWTZmUg|Y Date: Fri, 12 Jun 2020 19:15:15 +0200 Subject: [PATCH 13/17] Containerized vault setup --- components/tsi-util/Dockerfile | 1 + components/tsi-util/vault-setup.sh | 125 ++++++++++++++++++++ examples/sample-pod.yaml | 4 +- examples/vault/demo.load-sample-policies.sh | 2 + examples/vault/demo.vault-setup.sh | 104 ++++------------ 5 files changed, 151 insertions(+), 85 deletions(-) create mode 100755 components/tsi-util/vault-setup.sh diff --git a/components/tsi-util/Dockerfile b/components/tsi-util/Dockerfile index 23dd48a7..506e410e 100644 --- a/components/tsi-util/Dockerfile +++ b/components/tsi-util/Dockerfile @@ -22,6 +22,7 @@ COPY secret-maker.sh /usr/local/bin/ COPY getClusterInfo.sh /usr/local/bin/ COPY load-sample-policies.sh /usr/local/bin/ COPY vault-tpl/ /vault-tpl +COPY vault-setup.sh /usr/local/bin/ # run it forever CMD ["/bin/bash", "-c", "tail -f /dev/null"] diff --git a/components/tsi-util/vault-setup.sh b/components/tsi-util/vault-setup.sh new file mode 100755 index 00000000..153a17ca --- /dev/null +++ b/components/tsi-util/vault-setup.sh @@ -0,0 +1,125 @@ +#!/bin/bash + +#ibmcloud plugin install cloud-object-storage +export PLUGIN="vault-plugin-auth-ti-jwt" +COMMON_NAME="trusted-identity.ibm.com" +CONFIG="/tmp/plugin-config.json" + +## create help menu: +helpme() +{ + cat < +Where: + vault-plugin-sha - SHA 256 of the TSI Vault plugin (required) + token - vault root token to setup the plugin (optional, if set as env. var) + vault_addr - vault address in format http://vault.server:8200 (optional, if set as env. var) + +HELPMEHELPME +} + +setupVault() +{ + vault login -no-print "${ROOT_TOKEN}" + RT=$? + if [ $RT -ne 0 ] ; then + echo "ROOT_TOKEN is not correctly set" + echo "ROOT_TOKEN=${ROOT_TOKEN}" + exit 1 + fi + # remove any previously set VAULT_TOKEN, that overrides ROOT_TOKEN in Vault client + export VAULT_TOKEN= + + # vault status + vault secrets enable pki + RT=$? + if [ $RT -ne 0 ] ; then + echo " 'vault secrets enable pki' command failed" + echo "maybe already set?" + read -n 1 -s -r -p 'Press any key to continue' + #exit 1 + fi + # Increase the TTL by tuning the secrets engine. The default value of 30 days may + # be too short, so increase it to 1 year: + vault secrets tune -max-lease-ttl=8760h pki + vault delete pki/root + + # create internal root CA + # expire in 100 years + export OUT + OUT=$(vault write pki/root/generate/internal common_name=${COMMON_NAME} \ + ttl=876000h -format=json) + # echo "$OUT" + + # capture the public key as plugin-config.json + CERT=$(echo "$OUT" | jq -r '.["data"].issuing_ca'| awk '{printf "%s\\n", $0}') + echo "{ \"jwt_validation_pubkeys\": \"${CERT}\" }" > ${CONFIG} + + # register the trusted-identity plugin + vault write /sys/plugins/catalog/auth/vault-plugin-auth-ti-jwt sha_256="${SHA256}" command="vault-plugin-auth-ti-jwt" + RT=$? + if [ $RT -ne 0 ] ; then + echo " 'vault write /sys/plugins/catalog/auth/vault-plugin-auth-ti-jwt ...' command failed" + exit 1 + fi + # useful for debugging: + # vault read sys/plugins/catalog/auth/vault-plugin-auth-ti-jwt -format=json + + # then enable this plugin + vault auth enable -path="trusted-identity" -plugin-name="vault-plugin-auth-ti-jwt" plugin + RT=$? + if [ $RT -ne 0 ] ; then + echo " 'vault auth enable plugin' command failed" + exit 1 + fi + + export MOUNT_ACCESSOR + MOUNT_ACCESSOR=$(curl -sS --header "X-Vault-Token: ${ROOT_TOKEN}" --request GET "${VAULT_ADDR}/v1/sys/auth" | jq -r '.["trusted-identity/"].accessor') + + # configure plugin using the Issuing CA created internally above + curl -sS --header "X-Vault-Token: ${ROOT_TOKEN}" --request POST --data @${CONFIG} "${VAULT_ADDR}/v1/auth/trusted-identity/config" + RT=$? + if [ $RT -ne 0 ] ; then + echo "failed to configure trusted-identity plugin" + exit 1 + fi + + # for debugging only: + # CONFIG=$(curl -sS --header "X-Vault-Token: ${ROOT_TOKEN}" --request GET "${VAULT_ADDR}/v1/auth/trusted-identity/config" | jq) + # echo "*** $CONFIG" + } + +if [ ! "$1" == "" ] ; then + export ROOT_TOKEN=$1 +fi +if [ ! "$2" == "" ] ; then + export VAULT_ADDR=$2 +fi + +# validate the arguments +if [[ "$1" == "-?" || "$1" == "-h" || "$1" == "--help" ]] ; then + helpme +fi + +# SHA256 of the TSI plugin must be provided +if [[ "$1" == "" ]] ; then + helpme + exit 1 +else + SHA256="$1" +fi + +# validate the Vault arguments +if [[ "$3" != "" ]] ; then + export ROOT_TOKEN="$2" + export VAULT_ADDR="$3" +elif [[ "$ROOT_TOKEN" == "" || "$VAULT_ADDR" == "" ]] ; then + echo "ROOT_TOKEN and VAULT_ADDR must be set" + helpme + exit 1 +fi + +setupVault +# once the vault is setup, load the sample policies +load-sample-policies.sh diff --git a/examples/sample-pod.yaml b/examples/sample-pod.yaml index 5ebda26a..1605e8a4 100644 --- a/examples/sample-pod.yaml +++ b/examples/sample-pod.yaml @@ -5,10 +5,10 @@ metadata: annotations: admission.trusted.identity/inject: "true" tsi.secrets: | - - tsi.secret/name: "redissecret1" + - tsi.secret/name: "redis-secret1" tsi.secret/constraints: "region,images" tsi.secret/local-path: "mysecrets/" - - tsi.secret/name: "redissecret2" + - tsi.secret/name: "redis-secret2" tsi.secret/constraints: "region" tsi.secret/local-path: "mysecrets" spec: diff --git a/examples/vault/demo.load-sample-policies.sh b/examples/vault/demo.load-sample-policies.sh index bd89c1c4..28a22108 100755 --- a/examples/vault/demo.load-sample-policies.sh +++ b/examples/vault/demo.load-sample-policies.sh @@ -27,5 +27,7 @@ elif [[ "$ROOT_TOKEN" == "" || "$VAULT_ADDR" == "" ]] ; then helpme fi +echo "sample policies are now preloaded during the vault setup" +read -n 1 -s -r -p 'Press any key to continue' docker run trustedseriviceidentity/tsi-util:latest load-sample-policies.sh ${VAULT_ADDR} ${ROOT_TOKEN} diff --git a/examples/vault/demo.vault-setup.sh b/examples/vault/demo.vault-setup.sh index fd519c15..74c9ee32 100755 --- a/examples/vault/demo.vault-setup.sh +++ b/examples/vault/demo.vault-setup.sh @@ -1,18 +1,12 @@ #!/bin/bash -#ibmcloud plugin install cloud-object-storage -export PLUGIN="vault-plugin-auth-ti-jwt" -COMMON_NAME="trusted-identity.ibm.com" -CONFIG="plugin-config.json" - ## create help menu: helpme() { cat < +Syntax: ${0} Where: - token - vault root token to setup the plugin (optional, if set as ROOT_TOKEN) vault_addr - vault address in format http://vault.server:8200 TSI_namespace - if different than trusted-identity (optional) @@ -21,44 +15,10 @@ HELPMEHELPME setupVault() { - vault login -no-print "${ROOT_TOKEN}" - RT=$? - if [ $RT -ne 0 ] ; then - echo "ROOT_TOKEN is not correctly set" - echo "ROOT_TOKEN=${ROOT_TOKEN}" - exit 1 - fi # remove any previously set VAULT_TOKEN, that overrides ROOT_TOKEN in Vault client export VAULT_TOKEN= - # vault status - vault secrets enable pki - RT=$? - if [ $RT -ne 0 ] ; then - echo " 'vault secrets enable pki' command failed" - echo "maybe already set?" - read -n 1 -s -r -p 'Press any key to continue' - #exit 1 - fi - # Increase the TTL by tuning the secrets engine. The default value of 30 days may - # be too short, so increase it to 1 year: - vault secrets tune -max-lease-ttl=8760h pki - vault delete pki/root - - # create internal root CA - # expire in 100 years - export OUT - OUT=$(vault write pki/root/generate/internal common_name=${COMMON_NAME} \ - ttl=876000h -format=json) - # echo "$OUT" - - # capture the public key as plugin-config.json - CERT=$(echo "$OUT" | jq -r '.["data"].issuing_ca'| awk '{printf "%s\\n", $0}') - echo "{ \"jwt_validation_pubkeys\": \"${CERT}\" }" > ${CONFIG} - - # obtain the SHA256 for the plugin - # if the deployed image has the same binary as the one on your system, use the - # following method: + # get the id of the vault container: VAULTPOD=$($kk get po | grep tsi-vault- | grep Running | awk '{print $1}') if [ "$VAULTPOD" == "" ]; then echo "No running Vault container in this namespace. Perhaps Vault is running in a different location" @@ -66,6 +26,17 @@ setupVault() echo " $kk get po | grep tsi-vault- | grep Running" exit 1 fi + + # get the vault token and validate the connection: + ROOT_TOKEN=$($kk logs "$VAULTPOD" | grep "Root Token" | cut -d' ' -f3) + vault login -no-print "${ROOT_TOKEN}" + RT=$? + if [ $RT -ne 0 ] ; then + echo "ROOT_TOKEN is not set correctly" + echo "ROOT_TOKEN=${ROOT_TOKEN}" + exit 1 + fi + export SHA256 SHA256=$($kk exec "$VAULTPOD" /usr/bin/sha256sum /plugins/vault-plugin-auth-ti-jwt | cut -d' ' -f1) # another way to obtain this SHA, use a local plugin created by the build process @@ -76,47 +47,16 @@ setupVault() exit 1 fi - # register the trusted-identity plugin - vault write /sys/plugins/catalog/auth/vault-plugin-auth-ti-jwt sha_256="${SHA256}" command="vault-plugin-auth-ti-jwt" - RT=$? - if [ $RT -ne 0 ] ; then - echo " 'vault write /sys/plugins/catalog/auth/vault-plugin-auth-ti-jwt ...' command failed" - exit 1 - fi - # useful for debugging: - # vault read sys/plugins/catalog/auth/vault-plugin-auth-ti-jwt -format=json - - # then enable this plugin - vault auth enable -path="trusted-identity" -plugin-name="vault-plugin-auth-ti-jwt" plugin - RT=$? - if [ $RT -ne 0 ] ; then - echo " 'vault auth enable plugin' command failed" - exit 1 - fi - - export MOUNT_ACCESSOR - MOUNT_ACCESSOR=$(curl -sS --header "X-Vault-Token: ${ROOT_TOKEN}" --request GET "${VAULT_ADDR}/v1/sys/auth" | jq -r '.["trusted-identity/"].accessor') - - # configure plugin using the Issuing CA created internally above - curl -sS --header "X-Vault-Token: ${ROOT_TOKEN}" --request POST --data @${CONFIG} "${VAULT_ADDR}/v1/auth/trusted-identity/config" - RT=$? - if [ $RT -ne 0 ] ; then - echo "failed to configure trusted-identity plugin" - exit 1 - fi - - CONFIG=$(curl -sS --header "X-Vault-Token: ${ROOT_TOKEN}" --request GET "${VAULT_ADDR}/v1/auth/trusted-identity/config" | jq) - # echo "*** $CONFIG" + docker run trustedseriviceidentity/tsi-util:latest vault-setup.sh ${SHA256} ${ROOT_TOKEN} ${VAULT_ADDR} } + if [ ! "$1" == "" ] ; then - export ROOT_TOKEN=$1 -fi -if [ ! "$2" == "" ] ; then - export VAULT_ADDR=$2 + export VAULT_ADDR=$1 fi + kk="kubectl -n trusted-identity" -if [ ! "$3" == "" ] ; then +if [ ! "$2" == "" ] ; then kk="kubectl -n $3" fi @@ -124,11 +64,9 @@ fi if [[ "$1" == "-?" || "$1" == "-h" || "$1" == "--help" ]] ; then helpme #check if token exists: -elif [[ "$ROOT_TOKEN" == "" || "$VAULT_ADDR" == "" ]] ; then - echo "ROOT_TOKEN or VAULT_ADDR not set" +elif [[ "$VAULT_ADDR" == "" ]] ; then + echo "VAULT_ADDR not set" helpme -# elif [ ! -f "${PWD}/pkg/linux_amd64/${PLUGIN}" ]; then -# echo "Plugin directory missing \"${PWD}/pkg/linux_amd64/${PLUGIN}\"" else - setupVault "$1 $2" + setupVault fi From 4017a3b2c6961e3f5e8be4f1daaa0381bdb8b6ba Mon Sep 17 00:00:00 2001 From: Mariusz Sabath Date: Mon, 15 Jun 2020 14:46:01 +0200 Subject: [PATCH 14/17] Updated documentation and final helm charts --- CONTRIBUTING.md | 6 + README.md | 11 +- charts/ti-key-release-2-v1.7.0.tgz | Bin 7030 -> 7031 bytes charts/tsi-node-setup-v1.7.0.tgz | Bin 2259 -> 2259 bytes examples/vault/README.md | 244 +++++++++++++++-------------- examples/vault/demo.vault-setup.sh | 2 +- go.mod | 2 +- go.sum | 4 +- 8 files changed, 148 insertions(+), 121 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2ca7de3f..fc34f559 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -42,6 +42,12 @@ To run a full build that compiles the code, builds images and creates helm packa ./buildTSI.sh ``` +If you have credentials to push the image into Docker Hub: + +```console +./buildTSI.sh push +``` + When pushing the images to the registry, the user has to be logged in to Docker Hub with permissions to push images to `hub.docker.com/repository/docker/trustedseriviceidentity`. Make sure you are part of the Organization: [https://hub.docker.com/orgs/trustedseriviceidentity](https://hub.docker.com/orgs/trustedseriviceidentity) or if you like to build individual components: diff --git a/README.md b/README.md index 481d4217..93fbb1b5 100644 --- a/README.md +++ b/README.md @@ -211,6 +211,16 @@ At this point, this is an expected result. The following information is required to deploy TSI node-setup helm chart: * cluster name - name of the cluster. This must correspond to the actual name of the cluster * cluster region - label associated with the actual region for the data center (e.g. eu-de, us-south, eu-gb) +When using IKS, these values can be obtain via a script: + +```console +examples/vault/demo.get-cluster-info.sh + +export CLUSTER_NAME=ti-test1 +export REGION=eu-de +``` +Then use the provided output to setup env. variables to be used later. + TSI currently supports 2 methods for signing JWT Tokens: * using TPM2 - private keys are obtained directly from TPM using TPM wrapper (VTPM2) * using custom signing service JSS (JWT Signing Service) @@ -227,7 +237,6 @@ In order to run JSS server, all worker nodes have to be setup with private keys. If you are running this setup for the first time or like to override previous setup values, execute the helm command below. - ```console helm install charts/tsi-node-setup-X.X.X --debug --name tsi-setup --set reset.all=true \ --set cluster.name=$CLUSTER_NAME --set cluster.region=$REGION diff --git a/charts/ti-key-release-2-v1.7.0.tgz b/charts/ti-key-release-2-v1.7.0.tgz index 91287deb2fb596b094ae7444535a0eb2490f5b5d..cae68d3243e8fef7a976f8d8566f77112a4b9d12 100644 GIT binary patch delta 5958 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 delta 5955 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 delta 2223 zcmV;g2vGOa5z`TnJb&G9CHL268{qh4>yOj?Y?SZ2MGpFi}BDzw2Q(5PlC#(*U#3^Q|*Q6>y!0+o(P0GLt6 zBluZSkw_7q7Ju1KY@As!1VB)$q3naxB3lm7bWBb9Q=!8)`v7Vc>&0* zHT$oKie9~&INUPML189m=vwiPX=m*;#)UF$PP!1wESCa>(LhB4 z3S))TIDh`^JxB#NhZEH|xi&ku zybG2@ioY1*CKVB|kfMbm0v2pk&d#2RLvD|Yf)n8nIFo|JzAdV}NZAnBUj#tm)cK1- z2U->;{l+{-%l=olvv+oWbvz2qo%wPd&)NU}Zae-P3Sl$sSe_)%`t$KEF7qqRf)d>3&+UV_8a8 z$dPLFQZN0F@Qh|y_Sc+-<@o61nx&svNGT0(gKKGy>s-!OJmRv3vYdmr3!%3XHO6{J zi+5o>R&e_+%TEp_)+p&Bj#2AL!5725Z-206xw(f~p^f#u334=;SkvXrwr_wS$O|>K z-wBS3>B=Si+UIgZZ$oSC|8FIdJhl8a*^Y^+y;x*D>zdoCq6cFCY_Xg0VFtKVx40MmVZnx z=_nn7vpRJneLh2_Sc34$#_%GB;jVjR*{GOI*d26&r7#qUd-gC7eI!UL9g~9dIs8^o z&L#{K>y+FCLh>*4(jC9CI_zXLj4`H#M$j@t_(w5DCD3LFZrT%uJkem29nLallOQ9# z4gP*ScS~|~HnO}fQ^+y?AtWc0g@4ELLSpGk9lEsGu8oxu^%$YBITN+%mIYs;eQt#< zYjc&^q*~NPXSJ{kp0x}wT6wOQlK$*w5&ih`&8^|A7Q{(1xgE}3Ogc&PeWsGiNsva#Szb(caWdsU>wM9hoi$zamPFQHC*%SdtE zpn9PASSJ(OP!X>Q92b{nRhar%*3*&gC-|+9rV?wHaix@u3OdCk7|)xSM!r4@t!;Q^ z`@h!zCloU&Y>4~C#lUC$|9|dad#~mH_xt^wjsJfOs@MN%p6lLho7^ywL~!H|zz7Y= z(9nb$x~zdbas8HFs7%#fkcn9*X@zU#7#rz|EdUucaeC@3h;LYEH;sxtR5@cgtcKPS zZ%9}t!;?#IS9jI^7;tS1%f zETdD5pi^7Gvc?Gy5547(XibjYY0J7OIKPmb#q$Ub_${658i%WHGBZDv!r+~WYF*%J zhm7MC6IWivS|^HGlXo$#%j41U)xqg$qZ52JuQ{uF>fKo{>)(UJm&)=9`f6DhmnR<& zu8xmRF4suwrBa)o-+#)uP`Fym;psm|SI3vvX9pjSpNG{d2RtqE^7!v3=Vvb$T2&1? ztubAgqVWY>sSTW5xNsz=+Et=a%tDw^wGzuO=cB9ZlZ#a#{-$IWwK~8@$d@>I+*9^l zP?JWW4K;-hEuMz-ndC)=AM91qbrAt%w#^T2?@U8gb(y@Vr+;OjiB}BHXq+;E0ZSU4 z3TbjK`25k?Um=*wsa_%3_64;*kFlC*uok@?=;YUgb|GQP*~~d`8M~4-Na1+vx^s_f z^?KEXWNexm5Ym*z^%|Q^3?n#Nu%0U);4Lzi_q5;V3McFi z6S!q2g+Kief(@)d3OCY1f*ciaCNL!7(dc?)q(ah#vIO< +# e.g. +$ export VAULT_ADDR=http://tsi-test.eu-de.containers.appdomain.cloud ``` -Assign the Vault address (using Vault Ingress tested above): +If you have a Vault client installed, you can try to get the admin token directly: ```sh -$ export VAULT_ADDR=http:// -# e.g. -$ export VAULT_ADDR=http://tsi-test.eu-de.containers.appdomain.cloud +$ export ROOT_TOKEN=$(kk logs $(kk get po | grep tsi-vault-| awk '{print $1}') | grep Root | cut -d' ' -f3) ``` -Once you have `ROOT_TOKEN` and `VAULT_ADDR` environment variables defined, test -the connection + +And then test the connection: ```sh vault login $ROOT_TOKEN vault status ``` - - Then execute the Vault plugin setup script. +Then run the vault setup: ```sh $ ./demo.vault-setup.sh ``` + +Optionally, the vault address can be also passed directly to the script: + +```sh +$ ./demo.vault-setup.sh $VAULT_ADDR +``` + If the TSI namespace is different than `trusted-identity`, pass the TSI namespace as follow: ```sh -$ ./demo.vault-setup.sh $ROOT_TOKEN $VAULT_ADDR +$ ./demo.vault-setup.sh $VAULT_ADDR ``` +Currently, the vault setup includes the process of loading sample policies. If no errors, proceed to the JSS registration ### Register JWT Signing Service (JSS) with Vault @@ -141,125 +148,121 @@ $ # or simply use the following script: $ helm ls --all | grep tsi-node-setup | awk '{print $1}' | sort -r| xargs helm delete --purge ``` -### Define sample policies and roles -Policies are structured as paths for keys based on claims provided in JWT. -By default JWT Tokens are created every 30 seconds and they are placed in `/jwt-tokens` -directory of the application. One can inspect the content of the token by simply pasting it into -[Debugger](https://jwt.io/) in Encoded window. -Sample Payload: +## Secrets +TSI injects the secrets to application using the file mount. +There are few sample applications available in [example/](/examples/) directory. -```json -{ - "cluster-name": "ti_demo", - "region": "us-south", - "exp": 1557170306, - "iat": 1557170276, - "images": "f36b6d491e0a62cb704aea74d65fabf1f7130832e9f32d0771de1d7c727a79cc", - "images-names": "trustedseriviceidentity/myubuntu@sha256:5b224e11f0e8daf35deb9aebc86218f1c444d2b88f89c57420a61b1b3c24584c", - "iss": "wsched@us.ibm.com", - "machineid": "fa967df1a948495596ad6ba5f665f340", - "namespace": "test", - "pod": "vault-cli-84c8d647c-s6cgb", - "sub": "wsched@us.ibm.com" -} +In order for the secrets to be injected, an application must contain an annotation +requesting the secret injection + +```yaml +annotations: + admission.trusted.identity/inject: "true" ``` -Load some sample policies to Vault. Review the policy templates `ti.policy.X.hcl.tpl` -and the [demo.load-sample-policies.sh](demo.load-sample-policies.sh) script. +The format of the secrets is following: +* `tsi.secret/name` - name of the secret, as specified in Vault +* `tsi.secret/constraints` - list of constraints that define the measurements used for validation. This typically means any combination of claim values created by TSI. To see a complete list, visit [claims](./README.md#claims). E.g, (region,images) means that only applications matching the specific region and the image will have the secret injected. +* `tsi.secret/local-path` - the location where the secret will be mounted inside the container. This path always starts with `/tsi-secrets`, so it can be a relative e.g. `mysecrets/` or absolute `/tsi-secrets/mysecrets/`. -```sh -$ ./demo.load-sample-policies.sh +Here are the sample secrets: + +```yaml +annotations: + admission.trusted.identity/inject: "true" + tsi.secrets: | + - tsi.secret/name: "mysecret1" + tsi.secret/constraints: "region,cluster-name,namespace,images" + tsi.secret/local-path: "mysecrets/myubuntu" + - tsi.secret/name: "mysecret2.json" + tsi.secret/constraints: "region,images" + tsi.secret/local-path: "mysecrets/" + - tsi.secret/name: "mysecret3" + tsi.secret/constraints: "region,cluster-name,namespace" + tsi.secret/local-path: "/tsi-secrets/mysecrets/" ``` -## Secrets -### Preload sample keys -Preload few sample keys that are specifically customized to use with [examples/myubuntu.yaml](/examples/myubuntu.yaml) (see example below). +### Application on-boarding + +Before on-boarding the application, you must populate Vault with secrets, that would be injected to the application. To inject the secrets to Vault, use the script [examples/vault/demo.secret-maker.sh](/examples/vault/demo.secret-maker.sh) +This script requires a local installation of Docker. + +In order to create secrets for an application, pass the application into the script along with the namespace name. For example, to create secrets for [examples/myubuntu.yaml](/examples/myubuntu.yaml) in `test` namespace: -Since version 1.4, the application must be running in a separate namespace. Use -*the application namespace* to load the sample keys: ```console -$ demo.load-sample-keys.sh --help -$ demo.load-sample-keys.sh [region] [cluster] [app. namespace] +cd examples +vault/demo.secret-maker.sh -f myubuntu.yaml -n test ``` -### Start sample application -Now is time to start some sample application. The simplest one is `myubuntu` -available [here](/examples/myubuntu.yaml). Application will get a TSI sidecar as long -as it contains the following annotation: +The output is the script that can be used for inserting the secrets into Vault, so re-direct it to the file: -```yaml -admission.trusted.identity/inject: "true" +```console +vault/demo.secret-maker.sh -f myubuntu.yaml -n test > my-secrets.sh ``` -There is also an [example](/examples/myubuntu.yaml#L16-L40) showing how to request secrets for the application. -Staring with TSI version 1.4, all applications must be -created in a namespace that is not used for TSI components e.g. _test_ +This script is intended for a person, or a process, managing the secrets for the application, who has write access to the Vault. +Review the `my-secrets.sh` for any errors and provide the new values for all the secrets. Once all the secrets are specified, execute the script. This assumes the vault credentials are provided. -Start the application from a new console. It does not require Vault admin (as above). -Use `KUBECONFIG` as before, to access the cluster: +```console +export ROOT_TOKEN= +export VAULT_ADDR= +sh ./my-secrets.sh +`` + +The TSI environment is ready for the application on-boarding, so create a new namespace for the application, and deploy it: ```console export KUBECONFIG= -cd TI-KeyRelease + kubectl create namespace test -kubectl -n test create -f examples/myubuntu.yaml +kubectl -n test create -f myubuntu.yaml kubectl -n test get po ``` -The secrets will be mounted to your pod under `/tsi-secrets` directory, using -the path requested via pod annotation. +The secrets will be mounted to the application container under `/tsi-secrets` directory, using the path requested via pod annotation. -Validate if the sample secrets loaded earlier to Vault via 'demo.load-sample-keys.sh' script and -requested via pod annotation are available on the container: +Validate if the secrets were properly injected: ```console -kubectl -n test exec -it $(kubectl -n test get pods | grep myubuntu | awk '{print $1}') cat /tsi-secrets/mysecrets/mysecret4 +kubectl -n test exec -it $(kubectl -n test get pods | grep myubuntu | awk '{print $1}') ls /tsi-secrets/mysecrets + +kubectl -n test exec -it $(kubectl -n test get pods | grep myubuntu | awk '{print $1}') cat /tsi-secrets/mysecrets/mysecret2 ``` -To test the sidecar access to Vault: +## Claims +By default JWT Tokens are created every 60 seconds and they are placed in `/jwt-tokens` +directory of the application sidecar. +To inspect the current claim for a running application, use the `demo.claim-reviewer.sh` script. ```console -$ kubectl -n test exec -it myubuntu-xxxx -c jwt-sidecar /test-vault-cli.sh -# or -$ kubectl -n test exec -it $(kubectl -n test get pods | grep myubuntu | awk '{print $1}') -c jwt-sidecar /test-vault-cli.sh -Testing the default demo role: -A01 Test successful! RT: 0 -A02 Test successful! RT: 2 -A03 Test successful! RT: 2 -A04 Test successful! RT: 2 -A05 Test successful! RT: 2 -Testing the 'demo' role: -D01 Test successful! RT: 0 -D02 Test successful! RT: 2 -D03 Test successful! RT: 2 -D04 Test successful! RT: 2 -D05 Test successful! RT: 2 -Testing the 'tsi-role-rcn' role: -N01 Test successful! RT: 0 -N02 Test successful! RT: 2 -N03 Test successful! RT: 2 -N04 Test successful! RT: 2 -Testing the 'tsi-role-r' role: -R01 Test successful! RT: 0 -R02 Test successful! RT: 2 -R03 Test successful! RT: 0 -R04 Test successful! RT: 0 -R05 Test successful! RT: 0 -Testing non-existing role -E01 Test successful! RT: 0 -Testing access w/o token -E02 Test successful! RT: 2 -E03 Test successful! RT: 2 -Make sure to re-run 'setup-vault-cli.sh' as this script overrides the environment values +kubectl -n test get po +NAME READY STATUS RESTARTS AGE +myubuntu-7b8969b898-gmzhf 2/2 Running 0 2h +vault/demo.claim-reviewer.sh myubuntu-7b8969b898-gmzhf test ``` +and the output might be: + +```json +{ + "cluster-name": "ti-test1", + "exp": 1592221326, + "iat": 1592221266, + "images": "30beed0665d9cb4df616cca84ef2c06d2323e02869fcca8bbfbf0d8c5a3987cc", + "images-names": "ubuntu@sha256:250cc6f3f3ffc5cdaa9d8f4946ac79821aafb4d3afc93928f0de9336eba21aa4", + "iss": "wsched@us.ibm.com", + "machineid": "b46e165c32d342d9896d9eeb43c4d5dd", + "namespace": "test", + "pod": "myubuntu-7b8969b898-gmzhf", + "region": "eu-de", + "sub": "wsched@us.ibm.com" +} + +Alternatively, the JWT token can be obtained directly from the sidecar: -To see the JWT token: ```console -kubectl -n test exec -it {myubuntu-pod-id} -c jwt-sidecar cat /jwt/token +kubectl -n test exec -it myubuntu-7b8969b898-gmzhf -c jwt-sidecar cat /jwt/token ``` - -You can inspect the content of the token by simply pasting its content into -[Debugger](https://jwt.io/) in Encoded window. +and inspected by simply pasting it into [Debugger](https://jwt.io/) in Encoded window. ### More testing and exploring Get inside the sidecar: @@ -277,16 +280,16 @@ export VAULT_TOKEN=$(echo $RESP | jq -r '.auth.client_token') export VAULT_TOKEN=$(curl --request POST --data '{"jwt": "'"$(cat /jwt/token)"'", "role": "'tsi-role-r'"}' "${VAULT_ADDR}"/v1/auth/trusted-identity/login | jq -r '.auth.client_token') -vault kv get -format=json secret/tsi-r/eu-de/mysecret4 +vault kv get -format=json secret/tsi-r/eu-de/mysecret2 ``` To view all the attributes (measurement) associate with this pod, you can execute a following call: ```console -root@vault-cli-fd855bc5f-2cs4d:/# curl -s --request POST --data '{"jwt": "'"$(cat /jwt/token)"'", "role": "demo"}' ${VAULT_ADDR}/v1/auth/trusted-identity/login |jq +root@vault-cli-fd855bc5f-2cs4d:/# curl -s --request POST --data '{"jwt": "'"$(cat /jwt/token)"'", "role": "tsi-role-r"}' ${VAULT_ADDR}/v1/auth/trusted-identity/login |jq { - "request_id": "61bbd112-d779-03ef-5419-3bb36eb006db", + "request_id": "fbd9e2f3-6eba-e4f4-4b41-2e6a320810ba", "lease_id": "", "renewable": false, "lease_duration": 0, @@ -294,30 +297,39 @@ root@vault-cli-fd855bc5f-2cs4d:/# curl -s --request POST --data '{"jwt": "'"$(ca "wrap_info": null, "warnings": null, "auth": { - "client_token": "s.Ezz0TKByMUNnuZpOxnHZ7Jgr", - "accessor": "kvxDUNogiTfBsDNwWz4jGTOF", + "client_token": "s.LlqsTxXxXT4bRTU5L8l5RaFN", + "accessor": "7kaLfoKDo2iZsGoU4FRUkKc4", "policies": [ "default", - "tsi-policy-rcni" + "tsi-policy-r" ], "token_policies": [ "default", - "tsi-policy-rcni" + "tsi-policy-r" ], "metadata": { - "cluster-name": "EUcluster", "region": "eu-de", - "images": "f36b6d491e0a62cb704aea74d65fabf1f7130832e9f32d0771de1d7c727a79cc", - "namespace": "trusted-identity", - "role": "demo" + "role": "tsi-role-r" }, "lease_duration": 2764800, "renewable": true, - "entity_id": "8c3e1e09-7bbc-bd6f-2f75-7c47486384b5", - "token_type": "service" + "entity_id": "7a01b56f-8d6b-4e47-3aab-ede31152df58", + "token_type": "service", + "orphan": true } } root@vault-cli-fd855bc5f-2cs4d:/# ``` The measurements are grouped under "metadata" section. The members of "metadata" -depend on the `role` value used for login +depend on the `role` value used for login. + +Here is a sample for role `tsi-policy-rcni`: +```json +"metadata": { + "cluster-name": "ti-test1", + "images": "30beed0665d9cb4df616cca84ef2c06d2323e02869fcca8bbfbf0d8c5a3987cc", + "namespace": "test", + "region": "eu-de", + "role": "tsi-role-rcni" +} +``` diff --git a/examples/vault/demo.vault-setup.sh b/examples/vault/demo.vault-setup.sh index 74c9ee32..8ee8f016 100755 --- a/examples/vault/demo.vault-setup.sh +++ b/examples/vault/demo.vault-setup.sh @@ -57,7 +57,7 @@ fi kk="kubectl -n trusted-identity" if [ ! "$2" == "" ] ; then - kk="kubectl -n $3" + kk="kubectl -n $2" fi # validate the arguments diff --git a/go.mod b/go.mod index f6272e8d..9693c36d 100644 --- a/go.mod +++ b/go.mod @@ -57,7 +57,7 @@ require ( golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e // indirect golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527 // indirect golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 // indirect - golang.org/x/tools v0.0.0-20200611032120-1fdcbd130028 // indirect + golang.org/x/tools v0.0.0-20200612220849-54c614fe050c // indirect google.golang.org/appengine v1.5.0 // indirect google.golang.org/genproto v0.0.0-20190321212433-e79c0c59cdb5 // indirect google.golang.org/grpc v1.19.1 // indirect diff --git a/go.sum b/go.sum index dfb9f745..509f745f 100644 --- a/go.sum +++ b/go.sum @@ -245,8 +245,8 @@ golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59 h1:QjA/9ArTfVTLfEhClDCG7SG golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200611032120-1fdcbd130028 h1:xJs6MRJy4IDbnfYLxXlE0OFvyMax6fINqzbOpWhhHQw= -golang.org/x/tools v0.0.0-20200611032120-1fdcbd130028/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200612220849-54c614fe050c h1:g6oFfz6Cmw68izP3xsdud3Oxu145IPkeFzyRg58AKHM= +golang.org/x/tools v0.0.0-20200612220849-54c614fe050c/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From 40da63d7b3e084dfc22b28a00a0cb3529d2c80ce Mon Sep 17 00:00:00 2001 From: Mariusz Sabath Date: Mon, 15 Jun 2020 20:26:22 +0200 Subject: [PATCH 15/17] Post-revew updates --- components/tsi-util/load-sample-policies.sh | 5 +++-- components/tsi-util/secret-maker.sh | 2 +- examples/vault/demo.get-cluster-info.sh | 4 +++- examples/vault/demo.load-sample-policies.sh | 4 +++- examples/vault/demo.secret-maker.sh | 4 +++- 5 files changed, 13 insertions(+), 6 deletions(-) diff --git a/components/tsi-util/load-sample-policies.sh b/components/tsi-util/load-sample-policies.sh index 28c1777d..727bd71e 100755 --- a/components/tsi-util/load-sample-policies.sh +++ b/components/tsi-util/load-sample-policies.sh @@ -77,8 +77,9 @@ loadVault() if [[ "$1" != "" && "$2" != "" ]] ; then export VAULT_ADDR="$1" export ROOT_TOKEN="$2" - loadVault -elif [[ "$ROOT_TOKEN" == "" || "$VAULT_ADDR" == "" ]] ; then +fi + +if [[ "$ROOT_TOKEN" == "" || "$VAULT_ADDR" == "" ]] ; then echo "ROOT_TOKEN and VAULT_ADDR must be set" helpme else diff --git a/components/tsi-util/secret-maker.sh b/components/tsi-util/secret-maker.sh index 095b6d79..4d26decd 100755 --- a/components/tsi-util/secret-maker.sh +++ b/components/tsi-util/secret-maker.sh @@ -156,7 +156,7 @@ case $KIND in TSI_SECRETS='.metadata.annotations."tsi.secrets"' TSI_IMG='.spec.containers[0].image' ;; - *) echo "# ERROR: Unsupported kind: ${KIND}" + *) echo "# ERROR: Unsupported kind: ${KIND} in ${CLUSTER_YAML}" exit 1 ;; esac diff --git a/examples/vault/demo.get-cluster-info.sh b/examples/vault/demo.get-cluster-info.sh index 1e9355a6..ab8c4fb8 100755 --- a/examples/vault/demo.get-cluster-info.sh +++ b/examples/vault/demo.get-cluster-info.sh @@ -1,4 +1,6 @@ #!/bin/bash +SCRIPT_PATH=$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P ) +TSI_VERSION=$(cat ${SCRIPT_PATH}/../../tsi-version.txt) docker_cmd="docker --version" if [[ ! $(eval ${docker_cmd}) ]]; then @@ -14,6 +16,6 @@ CLUSTERINFO="${TEMPDIR}/clusterinfo.$$" kubectl get cm -n kube-system cluster-info -o yaml > ${CLUSTERINFO} docker run -v ${CLUSTERINFO}:/tmp/clusterinfo \ -docker.io/trustedseriviceidentity/tsi-util:latest /usr/local/bin/getClusterInfo.sh /tmp/clusterinfo +docker.io/trustedseriviceidentity/tsi-util:${TSI_VERSION} /usr/local/bin/getClusterInfo.sh /tmp/clusterinfo rm ${CLUSTERINFO} diff --git a/examples/vault/demo.load-sample-policies.sh b/examples/vault/demo.load-sample-policies.sh index 28a22108..7ebd46c8 100755 --- a/examples/vault/demo.load-sample-policies.sh +++ b/examples/vault/demo.load-sample-policies.sh @@ -1,4 +1,6 @@ #!/bin/bash +SCRIPT_PATH=$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P ) +TSI_VERSION=$(cat ${SCRIPT_PATH}/../../tsi-version.txt) ## create help menu: helpme() @@ -30,4 +32,4 @@ fi echo "sample policies are now preloaded during the vault setup" read -n 1 -s -r -p 'Press any key to continue' -docker run trustedseriviceidentity/tsi-util:latest load-sample-policies.sh ${VAULT_ADDR} ${ROOT_TOKEN} +docker run trustedseriviceidentity/tsi-util:${TSI_VERSION} load-sample-policies.sh ${VAULT_ADDR} ${ROOT_TOKEN} diff --git a/examples/vault/demo.secret-maker.sh b/examples/vault/demo.secret-maker.sh index 2b1a2707..d4efa973 100755 --- a/examples/vault/demo.secret-maker.sh +++ b/examples/vault/demo.secret-maker.sh @@ -1,4 +1,6 @@ #!/bin/bash +SCRIPT_PATH=$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P ) +TSI_VERSION=$(cat ${SCRIPT_PATH}/../../tsi-version.txt) ## create help menu: helpme() @@ -75,6 +77,6 @@ PODINFO="${TEMPDIR}/podinfo.$$" kubectl create -f ${FILE} -n ${NS} --dry-run=true -o yaml > ${PODINFO} docker run -v ${CLUSTERINFO}:/tmp/clusterinfo -v ${PODINFO}:/tmp/podinfo \ -docker.io/trustedseriviceidentity/tsi-util:latest /usr/local/bin/secret-maker.sh /tmp/clusterinfo /tmp/podinfo +docker.io/trustedseriviceidentity/tsi-util:${TSI_VERSION} /usr/local/bin/secret-maker.sh /tmp/clusterinfo /tmp/podinfo rm ${CLUSTERINFO} ${PODINFO} From b6c16b450d7f563a8ee428db16f24f514614ae87 Mon Sep 17 00:00:00 2001 From: Mariusz Sabath Date: Mon, 15 Jun 2020 20:47:04 +0200 Subject: [PATCH 16/17] Update demo.vault-setup.sh --- examples/vault/demo.vault-setup.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/examples/vault/demo.vault-setup.sh b/examples/vault/demo.vault-setup.sh index 8ee8f016..86557116 100755 --- a/examples/vault/demo.vault-setup.sh +++ b/examples/vault/demo.vault-setup.sh @@ -1,4 +1,6 @@ #!/bin/bash +SCRIPT_PATH=$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P ) +TSI_VERSION=$(cat ${SCRIPT_PATH}/../../tsi-version.txt) ## create help menu: helpme() @@ -47,7 +49,7 @@ setupVault() exit 1 fi - docker run trustedseriviceidentity/tsi-util:latest vault-setup.sh ${SHA256} ${ROOT_TOKEN} ${VAULT_ADDR} + docker run trustedseriviceidentity/tsi-util:${TSI_VERSION} vault-setup.sh ${SHA256} ${ROOT_TOKEN} ${VAULT_ADDR} } From 6a47a4bc2cd8a84475c3b196aa189b6cc7cf8696 Mon Sep 17 00:00:00 2001 From: Mariusz Sabath Date: Tue, 16 Jun 2020 14:08:27 +0200 Subject: [PATCH 17/17] Missing error code return --- components/tsi-util/load-sample-policies.sh | 1 + examples/vault/demo.load-sample-policies.sh | 1 + examples/vault/demo.register-JSS.sh | 1 + examples/vault/demo.vault-setup.sh | 1 + 4 files changed, 4 insertions(+) diff --git a/components/tsi-util/load-sample-policies.sh b/components/tsi-util/load-sample-policies.sh index 727bd71e..b0f9ea83 100755 --- a/components/tsi-util/load-sample-policies.sh +++ b/components/tsi-util/load-sample-policies.sh @@ -82,6 +82,7 @@ fi if [[ "$ROOT_TOKEN" == "" || "$VAULT_ADDR" == "" ]] ; then echo "ROOT_TOKEN and VAULT_ADDR must be set" helpme + exit 1 else loadVault fi diff --git a/examples/vault/demo.load-sample-policies.sh b/examples/vault/demo.load-sample-policies.sh index 7ebd46c8..4a76fbe5 100755 --- a/examples/vault/demo.load-sample-policies.sh +++ b/examples/vault/demo.load-sample-policies.sh @@ -27,6 +27,7 @@ if [[ "$1" != "" && "$2" != "" ]] ; then elif [[ "$ROOT_TOKEN" == "" || "$VAULT_ADDR" == "" ]] ; then echo "ROOT_TOKEN and VAULT_ADDR must be set" helpme + exit 1 fi echo "sample policies are now preloaded during the vault setup" diff --git a/examples/vault/demo.register-JSS.sh b/examples/vault/demo.register-JSS.sh index 366a8f3b..01ca3595 100755 --- a/examples/vault/demo.register-JSS.sh +++ b/examples/vault/demo.register-JSS.sh @@ -121,6 +121,7 @@ if [[ "$1" == "-?" || "$1" == "-h" || "$1" == "--help" ]] ; then elif [[ "$ROOT_TOKEN" == "" || "$VAULT_ADDR" == "" ]] ; then echo "ROOT_TOKEN or VAULT_ADDR not set" helpme + exit 1 else # get the list of all 'ti-node-setup' pods for each node instance # select only Running instances, to eliminate "Terminating" (helm operations) diff --git a/examples/vault/demo.vault-setup.sh b/examples/vault/demo.vault-setup.sh index 86557116..26151c43 100755 --- a/examples/vault/demo.vault-setup.sh +++ b/examples/vault/demo.vault-setup.sh @@ -69,6 +69,7 @@ if [[ "$1" == "-?" || "$1" == "-h" || "$1" == "--help" ]] ; then elif [[ "$VAULT_ADDR" == "" ]] ; then echo "VAULT_ADDR not set" helpme + exit 1 else setupVault fi