Coder Social home page Coder Social logo

Using several service accounts about goth HOT 14 CLOSED

peburrows avatar peburrows commented on June 17, 2024 1
Using several service accounts

from goth.

Comments (14)

xingxing avatar xingxing commented on June 17, 2024 1

Honestly, I believe this issue is actually resolved by #41 and should probably be closed.

@xingxing can you help me understand what problem Gotham solves that #41 doesn't?

Why I think #41 is not good enough

Hi @peburrows, #41 requires to add at least one parameter/option (sub) to every method you need applying multiple GCP service accounts.

That seems OK for this single library, but what if you want to make some library where used Goth (e.g. kane) to support multiple service accounts, that will be come to a nightmare. I found so many option/sub-sentence need to add, actually, I have tried to deal with it (peburrows/kane#27) and given up when I thought we can do it better.

Why Gotham is better

  1. Gotham uses a dynamic supervisor to boot a set of config and token store for each service account, thus you can add/remove a service account at runtime.
  2. Inspired by elixir-lang/gettext, Gotham uses process dictionary to store service account name that you want to use in current process. You don't even have to explicitly declare a current service account. Gotham will try to use the default one that is declared in application config.
  3. Use semantically independent account name (e.g. :withdrawal_publisher) instead of “[email protected]

Usage looks like:

config :gotham,
  default_account: :account1,
  accounts: [
    {:account1, file_path: "path/to/google/json/creds.json"},
    {:account2, file_path: "path/to/google/json/creds.json"}
  ]
# Use default account
{:ok, token} = Gotham.for_scope("https://www.googleapis.com/auth/pubsub")

%Gotham.Token{
  project_id: "test",
  access_token: "TOKEN",
  account_name: :account1,
  expire_at: 1561090622,
  scope: "https://www.googleapis.com/auth/pubsub",
  token_type: "Bearer"
}

# Change acocunt

Gotham.put_account_name(:account2)
Gotham.for_scope("https://www.googleapis.com/auth/pubsub")

{:ok,
 %Gotham.Token{
   project_id: "test",
   access_token: "TOKEN",
   account_name: :account2,
   expire_at: 1561092261,
   scope: "https://www.googleapis.com/auth/pubsub",
   token_type: "Bearer"
 }}

# Run a function with a specific account

Gotham.with_account_name(:account2, fn ->
  Gotham.for_scope("https://www.googleapis.com/auth/pubsub")
end)

{:ok,
 %Gotham.Token{
   project_id: "test",
   access_token: "TOKEN",
   account_name: :account2,
   expire_at: 1561092261,
   scope: "https://www.googleapis.com/auth/pubsub",
   token_type: "Bearer"
 }}
  1. Support multiple service accounts a piece of cake for library that used Gotham. You don't even have to change any code. Compare peburrows/kane#29 and peburrows/kane#27 .

from goth.

peburrows avatar peburrows commented on June 17, 2024

Currently, Goth doesn't support multiple accounts, unfortunately. I definitely think it's worth adding, and would be happy to accept an PR that adds that functionality.

I'll take a look at implementing this when I get a chance.

from goth.

peburrows avatar peburrows commented on June 17, 2024

I should mention that Goth does, however, allow you to pass in "the email address of the user for which the application is requesting delegated access" as a second argument to certain functions like Token.for_scope/2 (this optional email address will be added as a sub claim on the JWT that is generated when requesting a token from the API). This will allow your application to make authenticated requests on behalf of another user:

{:ok, token} = 
  Goth.Token.for_scope(
    "https://www.googleapis.com/auth/pubsub", 
    "[email protected]"
  )

See https://developers.google.com/identity/protocols/OAuth2ServiceAccount#additionalclaims for details on how the sub claim works.

from goth.

apognu avatar apognu commented on June 17, 2024

The argument for Token.for_scope/2 serves its own purpose, but as I understand it, it is used to impersonate a user for the same project. What I am looking for a a way to parse, store and use credentials from projects that might have nothing to do with each other.

I might find some time to craft a PR around this, but my guess is this would change the anatomy of the project quite a lot, so it may warrant some discussion beforehand.

The way I imagined it would be using a credentials file in the form of a JSON array instead of plain maps in that particular case. Something like this:

[
  {
    "client_email": "[email protected]",
    ...
  },
  {
    "client_email", "[email protected]",
    ...
  }
]

All internals would then allow for a new argument, which would specify which service account it targets, while still keeping compatibility with regular-shape credentials file transparently (some kind of default for when only one service account is specified).

This would still allow the sub parametter, to be able to impersonate a user from each of the service account.

What do you think?

from goth.

apognu avatar apognu commented on June 17, 2024

I have something that works, I'll submit a PR when I get home tonight.

from goth.

parkerjm avatar parkerjm commented on June 17, 2024

I would also love this functionality. Let me know if I can assist with the PR.

from goth.

apognu avatar apognu commented on June 17, 2024

The PR I submitted should cover it. Waiting for merge or comment.

from goth.

exAspArk avatar exAspArk commented on June 17, 2024

From reading the current source code, looks like it should be possible with:

# config.ex
config :goth, json: "[]"

# client.ex
config = "new.json" |> File.read!() |> Poison.decode!()
Goth.Config.add_config(config)
{:ok, token} = Goth.Token.for_scope({ config["client_email"], "https://www.googleapis.com/auth/..." })

from goth.

xingxing avatar xingxing commented on June 17, 2024

Hey, guys. Allow me to introduce you a new repo that I created to resolve this issue, Gotham

we can put current service account into process dictionary, thus make our APIs invoking more naturally.

Welcome for any criticism and PR, any time.

from goth.

peburrows avatar peburrows commented on June 17, 2024

Honestly, I believe this issue is actually resolved by #41 and should probably be closed.

@xingxing can you help me understand what problem Gotham solves that #41 doesn't?

from goth.

pankaj-ag avatar pankaj-ag commented on June 17, 2024

Hi @ALL,

Any update on this one. I need to load the account info dynamically.
Please Let me know if somebody found and any solution or workaround for this.

from goth.

xingxing avatar xingxing commented on June 17, 2024

Hi @ALL,

Any update on this one. I need to load the account info dynamically.
Please Let me know if somebody found and any solution or workaround for this.

Let's check my repo https://github.com/xingxing/gotham, hopefully it can solve your requirement.

from goth.

pankaj-ag avatar pankaj-ag commented on June 17, 2024

That's my solution in case that helps.

glific/glific@a70f41f#diff-2983f2b7dd4791bffad2d17e6bd591b857afea1724e45372a2d681ef21f18443

from goth.

wojtekmach avatar wojtekmach commented on June 17, 2024

Closing in favour or #82.

from goth.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.