Skip to content

Instantly share code, notes, and snippets.

@Guilhem7
Created February 26, 2026 11:31
Show Gist options
  • Select an option

  • Save Guilhem7/fe39399d0b94a89d17aaebbe932e7a52 to your computer and use it in GitHub Desktop.

Select an option

Save Guilhem7/fe39399d0b94a89d17aaebbe932e7a52 to your computer and use it in GitHub Desktop.
Parse Jwt and update keys / values using jq
#!/bin/bash
set -e
## Style
RED='\e[31m'
GREEN='\e[32m'
BLUE='\e[34m'
BOLD='\e[1m'
N='\e[0m'
msg(){
echo -e "${GREEN}[+]${N} $*"
}
info(){
echo -e "${BLUE}[-]${N} $*"
}
err(){
echo -e "${RED}[x]${N} $*" >&2
}
dump_jwt(){
### Takes the splitted Jwt as argument
IFS='.' read -ra parts <<< "$1"
if [ "${#parts[@]}" -ne 3 ];then
err "Invalid ${BOLD}JWT${N} input"
exit 1
fi
### Show header
info "${BOLD}Header${N}: ${BLUE}${parts[0]}${N}"
echo -n "${parts[0]}" |jq -R '@base64d |fromjson'
### Show payload
info "${BOLD}Payload${N}: ${BLUE}${parts[1]}${N}"
echo -n "${parts[1]}" |jq -R '@base64d |fromjson'
### Show signature for this token
info "${BOLD}Signature${N}: ${BLUE}${parts[2]}${N}"
}
update_jwt(){
### Update the key "$2" with the new value "$3" within the jwt provided in "$1"
echo -n "$1" |jq \
--argjson keys "$2" --argjson values "$3" -Rr \
'split(".") |.[0:2] |map(@base64d) |map(fromjson) |
map(
reduce (range(0; ($keys|length))) as $i
(.;
if has($keys[$i]) then
.[$keys[$i]] = $values[$i]
else
.
end
)
|@base64 |gsub("="; "") |gsub("-"; "+") |gsub("_"; "/")
)
|join(".")'
}
show_help(){
local indent=" "
echo "usage: ${0} [-h] [--token TOKEN] [-k KEY [KEY ...]] [-v VALUE [VALUE ...]]"
if [[ "$1" == "error" ]];then
echo ""
err "${0}: error: the following argument is required: ${BOLD}-t/--token${N}"
fi
echo -e "\nScript to manipulate ${BOLD}jwt${N}\n"
echo "options:"
echo "${indent}-h, --help show this help message and exit"
echo "${indent}-t TOKEN, --token TOKEN"
echo " jwt token to update"
echo "${indent}-k KEY [KEY ...], --keys KEY [KEY ...]"
echo " Keys to update on the token"
echo "${indent}-v VALUE [VALUE ...], --values VALUE [VALUE ...]"
echo " Values to update on the token"
}
keys=()
values=()
token=""
mode=""
## Simple args parsing
for arg in "$@"; do
case "$arg" in
-k|--keys) mode="keys" ;;
-v|--values) mode="values" ;;
-t|--token) mode="token" ;;
-h|--help)
show_help
exit
;;
*)
if [[ $mode == "keys" ]]; then
keys+=("$arg")
elif [[ $mode == "values" ]]; then
values+=("$arg")
elif [[ $mode == "token" ]]; then
token="$arg"
fi
;;
esac
done
if [ "${#keys[@]}" -ne "${#values[@]}" ];then
err "Length of keys and values must be the same"
exit
elif [ -z "$token" ];then
show_help "error"
exit
fi
json_keys=$(jq -nc '$ARGS.positional' --args "${keys[@]}")
json_values=$(jq -nc '$ARGS.positional' --args "${values[@]}")
msg "Original JWT"
dump_jwt "$token"
signature=$(echo "$token" |cut -d '.' -f 2)
if [ "${#keys[@]}" -gt 0 ];then
new_jwt=$(update_jwt $token "$json_keys" "$json_values")
new_jwt="$new_jwt.$signature"
echo ""
msg "Changed JWT"
dump_jwt "${new_jwt}"
echo "$new_jwt"
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment