Skip to content

Instantly share code, notes, and snippets.

Last active March 15, 2023 18:46
What would you like to do?
Script to generate JWT for use with Github apps
#!/usr/bin/env bash
# Generate JWT for Github App
# Inspired by implementation by Will Haley at:
# From:
thisdir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
set -o pipefail
# Change these variables:
app_private_key="$(< $thisdir/app.key)"
# Shared content to use as template
"alg": "RS256",
"typ": "JWT"
build_payload() {
jq -c \
--arg iat_str "$(date +%s)" \
--arg app_id "${app_id}" \
($iat_str | tonumber) as $iat
| .iat = $iat
| .exp = ($iat + 300)
| .iss = ($app_id | tonumber)
' <<< "${payload_template}" | tr -d '\n'
b64enc() { openssl enc -base64 -A | tr '+/' '-_' | tr -d '='; }
json() { jq -c . | LC_CTYPE=C tr -d '\n'; }
rs256_sign() { openssl dgst -binary -sha256 -sign <(printf '%s\n' "$1"); }
sign() {
local algo payload sig
algo=${1:-RS256}; algo=${algo^^}
payload=$(build_payload) || return
signed_content="$(json <<<"$header" | b64enc).$(json <<<"$payload" | b64enc)"
sig=$(printf %s "$signed_content" | rs256_sign "$app_private_key" | b64enc)
printf '%s.%s\n' "${signed_content}" "${sig}"
Copy link

carestad commented Dec 9, 2020

Thanks. Where do you get "generated_jwt"? I don't see it in your script. Is "generated_jwt" as same as ${sig}?

I am trying to find out which one is the JWT token. Is it "${sig} or Is it "${signed_content}"."${sig}"?

I see you figured it out, @michaelsync. $generated_jwt is basically the output of the entire script there. I will update my previous response so it is more clear 👍

Copy link

It helped me a lot. THX!

Copy link

kapcod commented Nov 1, 2021

Thanks! Works great. Strange that Gihub doesn't give bash script as official example, only Ruby.

Copy link

samsen1 commented Nov 17, 2021

Jesus - finally. Went in circles looking for a solution but this one works.

Copy link

vibin commented Feb 15, 2023

Just wanted to say thanks for this. Very helpful!

Copy link

Thanks a lot, I tried with several methods to create this token without lucky until I used this method.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment