diff --git a/lib/goth/token.ex b/lib/goth/token.ex index 5356ee5..93c5dfd 100644 --- a/lib/goth/token.ex +++ b/lib/goth/token.ex @@ -401,17 +401,26 @@ defmodule Goth.Token do handle_workload_identity_response(response, config) end + defp metadata_url(base_url, path, account, nil, nil) do + "#{base_url}#{path}#{account}/token" + end + + defp metadata_url(base_url, path, account, nil, scopes) do + scopes_query = Enum.join(scopes, ",") + "#{base_url}#{path}#{account}/token?scopes=#{scopes_query}" + end + + defp metadata_url(base_url, path, account, audience, _scopes) do + "#{base_url}#{path}#{account}/identity?audience=#{audience}" + end + defp metadata_options(options) do account = Keyword.get(options, :account, "default") audience = Keyword.get(options, :audience, nil) + scopes = Keyword.get(options, :scopes, nil) path = "/computeMetadata/v1/instance/service-accounts/" base_url = Keyword.get(options, :url, "http://metadata.google.internal") - - url = - case audience do - nil -> "#{base_url}#{path}#{account}/token" - audience -> "#{base_url}#{path}#{account}/identity?audience=#{audience}" - end + url = metadata_url(base_url, path, account, audience, scopes) {url, audience} end diff --git a/test/goth/token_test.exs b/test/goth/token_test.exs index 4aee720..0181b20 100644 --- a/test/goth/token_test.exs +++ b/test/goth/token_test.exs @@ -191,6 +191,26 @@ defmodule Goth.TokenTest do assert token.scope == nil end + test "fetch/1 from instance metadata with scopes query" do + bypass = Bypass.open() + + Bypass.expect(bypass, fn conn -> + assert conn.request_path == "/computeMetadata/v1/instance/service-accounts/alice/token" + assert conn.query_params == %{"scopes" => "scope_a,scope_b"} + + body = ~s|{"access_token":"dummy","expires_in":3599,"token_type":"Bearer"}| + Plug.Conn.resp(conn, 200, body) + end) + + config = %{ + source: {:metadata, account: "alice", url: "http://localhost:#{bypass.port}", scopes: ["scope_a", "scope_b"]} + } + + {:ok, token} = Goth.Token.fetch(config) + assert token.token == "dummy" + assert token.scope == nil + end + test "fetch/1 from workload identity" do token_bypass = Bypass.open() sa_token_bypass = Bypass.open()