-
Notifications
You must be signed in to change notification settings - Fork 74
feat: managed service account querying strategy #2433
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: managed service account querying strategy #2433
Conversation
|
Hi @wojtekmach , would need some advice on the service account impersonation via Goth here. I've tried achieving the SA impersonation using the custom claims map as documented, but it does not seem to work This issue mentions the docs discrepancy, but i suspect why they're able to successfully impersonate is due to domain-wide delegation vs the gcp-specific iam role granted as documented here in the GCP docs. Any ideas? |
|
@Ziinc unfortunately this particular flow is not supported out of the box. And you're right custom claims map didn't work for me either. Could you check the following snippet and see if it does what you need? Remember to use a test gcloud account :) # $ PROJECT_ID="wojtekmach"
# $ gcloud services enable iam.googleapis.com iamcredentials.googleapis.com
# $ gcloud iam service-accounts create goth-test-sa1
# $ gcloud iam service-accounts create goth-test-sa2
# $ sa1="goth-test-sa1@${PROJECT_ID}.iam.gserviceaccount.com"
# $ sa2="goth-test-sa2@${PROJECT_ID}.iam.gserviceaccount.com"
# $ gcloud iam service-accounts keys create ~/sa1.json --iam-account=$sa1
# $ cloudshell download ~/sa1.json
# $ gcloud projects add-iam-policy-binding $PROJECT_ID \
# --member="serviceAccount:$sa2" \
# --role="roles/iam.serviceAccountViewer"
# $ gcloud iam service-accounts add-iam-policy-binding $sa2 \
# --member="serviceAccount:$sa1" \
# --role="roles/iam.serviceAccountTokenCreator"
Mix.install([:goth, :req])
project_id = "wojtekmach"
sa1 = "goth-test-sa1@#{project_id}.iam.gserviceaccount.com"
sa2 = "goth-test-sa2@#{project_id}.iam.gserviceaccount.com"
# 1. sa1 tries to view itself, fails because it does not have iam.serviceAccountViewer role
sa1_credentials =
File.read!(Path.expand("~/Downloads/sa1.json"))
|> Jason.decode!()
{:ok, %{token: sa1_token}} = Goth.Token.fetch(source: {:service_account, sa1_credentials})
Req.get!(
"https://iam.googleapis.com/v1/projects/-/serviceAccounts/#{sa1}",
auth: {:bearer, sa1_token}
).body
|> dbg()
# 2. sa1 creates a shortlived token for s2 and uses it to view s2
%{status: 200, body: %{"accessToken" => sa2_token}} =
Req.post!(
"https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/#{sa2}:generateAccessToken",
auth: {:bearer, sa1_token},
json: %{
"scope" => ["https://www.googleapis.com/auth/cloud-platform"]
}
)
Req.get!(
"https://iam.googleapis.com/v1/projects/-/serviceAccounts/#{sa2}",
auth: {:bearer, sa2_token}
).body
|> dbg()Btw, please always ping @Logflare/dashbit even if you have a question to any of us in particular. This way we're all up to date and can respond to you when someone is off etc. |
|
@wojtekmach thanks for the hint, I was able to get the impersonation up and running with our fork 🎉 |
|
That's great, thanks for opening up a PR too! |
438825d to
c97f72f
Compare
wojtekmach
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me, I left a couple minor comments below.
This PR adds in managed service account querying, to get around Google's 100 rps rate limit on core REST api calls.