Skip to content

Instantly share code, notes, and snippets.

@plamb
Last active December 9, 2020 14:31
Show Gist options
  • Star 9 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save plamb/8c8f39cfba9e69cb034a to your computer and use it in GitHub Desktop.
Save plamb/8c8f39cfba9e69cb034a to your computer and use it in GitHub Desktop.
Authenticate with Google Cloud using service account json key and Elixir
# https://developers.google.com/identity/protocols/OAuth2ServiceAccount
key_json = File.read!("some-service-account-key-file.json")
key_map = JOSE.decode(key_json)
jwk = JOSE.JWK.from_pem(key_map["private_key"])
jws = %{"alg" => "RS256"}
header = %{
"alg" => "RS256",
"typ" => "JWT"
}
iat = :os.system_time(:seconds)
exp = iat + 3600
claims = %{
"iss" => key_map["client_email"],
"scope" => "https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/datastore",
"aud" => "https://www.googleapis.com/oauth2/v3/token",
"exp" => exp,
"iat" => iat
}
# ok we are finally going to put it altogether and sign it
{_, assertion} = JOSE.JWS.sign(jwk, JOSE.encode(claims), header, jws) |> JOSE.JWS.compact
# these come from the google auth docs, link at top
token_auth_uri = "https://www.googleapis.com/oauth2/v3/token"
headers = %{"Content-type" => "application/x-www-form-urlencoded"}
form = {:form, [assertion: assertion, grant_type: "urn:ietf:params:oauth:grant-type:jwt-bearer"]}
#IO.inspect token
HTTPoison.start
{:ok, response} = HTTPoison.post(token_auth_uri, form, headers)
body = JOSE.decode(response.body)
access_token = body["access_token"]
@plamb
Copy link
Author

plamb commented Nov 30, 2015

Andrew has updated JOSE to handle the PKCS#8 formatted key, so I updated to reflect the directness of it all now.

@potatosalad
Copy link

Not a huge savings, but the code could be simplified a little bit on line 27:

assertion = JOSE.JWT.sign(jwk, jws, claims) |> JOSE.JWS.compact |> elem(1)

The {"typ":"JWT"} will be added to the jws when using the JOSE.JWT.sign/3 function, so you wouldn't need the header variable from lines 10-13.

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