google-cloud

Google Cloud Platform: Clojure + {GAE, GCE, anything else on Google Platform}
mozinator2 2020-12-15T08:10:39.055300Z

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
          (-&gt; (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>"])

mozinator2 2020-12-15T08:12:33.056400Z

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