Skip to content
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

Add Application Default Credentials & Service Account impersonation #1148

Merged
merged 3 commits into from
Nov 12, 2024

Conversation

a-mackay
Copy link
Contributor

@a-mackay a-mackay commented Nov 5, 2024

Context

Usage of Service Account keys is generally discouraged, with service account impersonation being a recommended alternative.

Changes

Allow Application Default Credentials to be used, and support Service Account impersonation with it. This could be used as an alternative to the existing Service Account key authentication. Since it is an alternative method, it should not affect backwards compatibility.

One point of discussion is the default values used to build ImpersonatedCredentials in AndroidPublisher.kt. We think these are suitable defaults - hardcoded values for the token lifetime was taken from GCP documentation and seems adequate given that tokens are autogenerated/refreshed by the underlying SDK as HTTP requests are constructed.

@a-mackay a-mackay requested a review from SUPERCILEX as a code owner November 5, 2024 05:29
@a-mackay a-mackay marked this pull request as draft November 5, 2024 05:29
@a-mackay a-mackay marked this pull request as ready for review November 5, 2024 22:14
@SUPERCILEX
Copy link
Collaborator

Did you test this locally?

@a-mackay
Copy link
Contributor Author

a-mackay commented Nov 6, 2024

Yep, we built the plugin locally, and published our Android app successfully. It used my personal Google account set up via the gcloud CLI, and impersonated our publisher Service Account.

@pauldthomson
Copy link
Contributor

Just to add, we contemplated some more tests around this but the only "logic" added resulted in a different instantiation of a GoogleCredentials, so it meant several levels of mocking to assert on a type and the logic is fairly simple so it didn't seem like the cost of the test added much value.
The actual logic of using ADC and impersonation lives in the Google SDK anyway..

@SUPERCILEX
Copy link
Collaborator

Good enough for me, thanks! I'll try to review this before the end of the weekend.

@SUPERCILEX
Copy link
Collaborator

Can you give me edit access to the PR? I'd like to tweak some stuff

credentialStream().use {
PlayPublisher(it, parameters.appId.get())
val useAppDefaultCreds = parameters.useApplicationDefaultCredentials.getOrElse(false)
val useExplicitCreds = (parameters.credentials.asFile.orNull != null ||
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should fail even if the file doesn't exist.

Suggested change
val useExplicitCreds = (parameters.credentials.asFile.orNull != null ||
val useExplicitCreds = (parameters.credentials.present ||

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean isPresent??

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah sorry I'm forgetting how Kotlin works 😅

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know the feeling 😛

.setSourceCredentials(appDefaultCreds)
.setTargetPrincipal(impersonateServiceAccount)
.setScopes(listOf(AndroidPublisherScopes.ANDROIDPUBLISHER))
.setLifetime(300)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Max this out to 3600. We don't want folks with really long builds getting timed out.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems the tokens are generated as the task is about to make a HTTP call (rather than at the start of a build) and also automatically refreshed if "stale" (i.e. expired or within 5mins of expiry), so the thinking was that this lower value was pretty safe..
But an hour isn't the end of the world so happy to just max it out if preferred...

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I don't see how a token living for an hour is going to hurt much more than 5 mins.

@pauldthomson
Copy link
Contributor

@SUPERCILEX all done

@SUPERCILEX
Copy link
Collaborator

@pauldthomson
Copy link
Contributor

Don't think we can as this is forked into a non-personal repo... The link above seems to allude to it being in personal repos and I don't see the option on this PR either.. Might have to just suggest the clean ups and have us do them?

@SUPERCILEX
Copy link
Collaborator

Ah, sounds good.

Copy link
Collaborator

@SUPERCILEX SUPERCILEX left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll do another pass tomorrow, but this what I was going to tweak for now.

@pauldthomson
Copy link
Contributor

I'll do another pass tomorrow, but this what I was going to tweak for now.

Fixed those ones, let us know if there's anything else :)

@SUPERCILEX SUPERCILEX merged commit c33d4d5 into Triple-T:master Nov 12, 2024
4 checks passed
@pauldthomson pauldthomson deleted the add-app-default-creds branch November 12, 2024 02:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants