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

feat: support both identity and token source for gke metadata server mode #286

Merged

Conversation

nicolas-vivot
Copy link
Contributor

@nicolas-vivot nicolas-vivot commented Jul 18, 2024

Description

The changes included in this PR give us the ability to generate different token types when relying on the GKE metadata server.

In the current version, only OAuth 2.0 tokens can be generated.

What was done

In the exact same way as when using the Credential File mode, we know can:

  • generate a JWT identity token when providing an audience
  • generate a OAuth 2.0 token when providing scopes

This is useful when we want to access remote services (across shared VPC, VPC, PSC, whatever) like custom services, cloud run instances that are protected with basic authentication.

How has it been tested

  • No unit tests (no existing ones)
  • Tested within a GKE server and against remote (different project location) Vertex AI endpoints: using the usual OAuth 2.0 tokens.
  • Tested within a GKE server and against remote (different project location) Cloud Run service: with a Private Service Connect setup in between, using JWT identity tokens with specifying the Cloud Run's URL as audience and granting cloud.run.invoker role to the service account used.

///
/// Returns an error if neither audience nor scopes are provided, or if any technical error occurs.
pub async fn create_token_source_from_metadata_server(config: &Config<'_>,) -> Result<Box<dyn TokenSource>, error::Error> {
match config.audience {
Copy link
Owner

Choose a reason for hiding this comment

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

In google-cloud-pubsub and others, since the audience is set when the client is generated, this application will force the idtoken.
We checked google-cloud-go and did not see any use of idtoken, so we would like to position this as an option.

pub async fn create_token_source_from_project(
    project: &Project,
    config: Config<'_>,
) -> Result<Box<dyn TokenSource>, error::Error> {
    match project {
        Project::FromFile(file) => {
            if config.use_id_token {
                id_token_source_from_credentials(Default::default(), file, config.audience.unwrap_or_default()).await
            }else {
                create_token_source_from_credentials(file, &config).await
            }
        },
        Project::FromMetadataServer(_) => {
            let ts = if config.use_id_token {
                ComputeIdentitySource::new(&config.audience.unwrap_or_default())?
            }else {
                ComputeTokenSource::new(&config.scopes_to_string(","))?
            };
            let token = ts.token().await?;
            Ok(Box::new(ReuseTokenSource::new(Box::new(ts), token)))
        }
    }
}

How about the following code? This would allow the use of idtoken even when credentials are used.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sounds good to me.
I will update based on your feedback and test it by tomorrow.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Tested. No issue found.

My tests covered both authentication tokens (OAuth and ID) from GKE, for in-house target services (cross project cloud run through PSC setup) as well as same project/cross project Google Cloud APIs (Vertex endpoints for example)

@@ -68,7 +68,7 @@ pub async fn create_id_token_source(
}
}

async fn id_token_source_from_credentials(
pub(crate) async fn id_token_source_from_credentials(
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@yoshidan Not sure about your preference in term of visibility ?

Copy link
Owner

Choose a reason for hiding this comment

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

The scope you specified is fine.

@yoshidan yoshidan added the safe to test safe to test label Jul 25, 2024
@yoshidan yoshidan added safe to test safe to test and removed safe to test safe to test labels Jul 26, 2024
@yoshidan yoshidan merged commit 20d5baf into yoshidan:main Jul 26, 2024
8 of 9 checks passed
@yoshidan
Copy link
Owner

Thanks!

@yoshidan
Copy link
Owner

ref #287

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
safe to test safe to test
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants