This is how you can request an access-token for a service account key file in babashka. Had to use shell to openssl because babashka doesnt support buddy-sign.
(defn request-access-token-for-service-account-file! [sa-file scopes]
(let [sa (json/parse-string (slurp sa-file) true)
claim
(let [now (int (/ (System/currentTimeMillis) 1000))]
{:iss (:client_email sa)
:scope (s/join " " scopes)
:aud (:token_uri sa) ,
:exp (+ now (* 60 10)) ; 10 minutes
:iat now})
header (json/generate-string {:alg "RS256" :typ "JWT"})
request-body (str (encode-base64 header) "." (encode-base64 (json/generate-string claim)))
signature
(let [pkf (java.io.File/createTempFile "private-key" ".txt")
rbf (java.io.File/createTempFile "request-body" ".txt")]
(with-open [pk (<http://clojure.java.io/writer|clojure.java.io/writer> pkf)
rb (<http://clojure.java.io/writer|clojure.java.io/writer> rbf)]
(.write pk (:private_key sa))
(.write rb request-body))
(let [res
(sh "openssl" "dgst" "-sha256" "-sign" (.getCanonicalPath pkf) (.getCanonicalPath rbf) :out-enc :bytes)]
(.delete pkf)
(.delete rbf)
(String. (.encode (java.util.Base64/getEncoder) (:out res)))))
token (str request-body "." signature)
access-token
(-> (curl/post
(:token_uri sa)
{:form-params
{"grant_type" "urn:ietf:params:oauth:grant-type:jwt-bearer"
"assertion" token}})
:body
(json/parse-string true)
:access_token)]
access-token))
(request-access-token-for-service-account-file sa-file ["<https://www.googleapis.com/auth/cloud-platform>"])
Now you can use the access token to directly interact with the google cloud api's and you don't have any dependency on the java libraries or the gcloud cli to request an access token