-
Notifications
You must be signed in to change notification settings - Fork 1k
feat(auth): support Domain-Wide Delegation for Service Accounts #543
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| ---\n"@googleworkspace/cli": patch\n---\n\nfeat(auth): support Domain-Wide Delegation for Service Accounts |
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -200,11 +200,20 @@ async fn get_token_inner( | |||||||||
| .map(|f| f.to_string_lossy().to_string()) | ||||||||||
| .unwrap_or_else(|| "token_cache.json".to_string()); | ||||||||||
| let sa_cache = token_cache_path.with_file_name(format!("sa_{tc_filename}")); | ||||||||||
| let builder = yup_oauth2::ServiceAccountAuthenticator::builder(key).with_storage( | ||||||||||
| Box::new(crate::token_storage::EncryptedTokenStorage::new(sa_cache)), | ||||||||||
| ); | ||||||||||
|
|
||||||||||
| // Support Domain-Wide Delegation (impersonation) | ||||||||||
| let mut builder = yup_oauth2::ServiceAccountAuthenticator::builder(key); | ||||||||||
| if let Ok(sub) = std::env::var("GOOGLE_WORKSPACE_IMPERSONATE_USER") { | ||||||||||
| if !sub.is_empty() { | ||||||||||
| tracing::debug!(impersonate = %sub, "Using Domain-Wide Delegation"); | ||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The Please sanitize the user-provided input before logging it. The project already has a utility for this:
Suggested change
References
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The user-provided
Suggested change
References
|
||||||||||
| builder = builder.subject(sub); | ||||||||||
| } | ||||||||||
| } | ||||||||||
|
Comment on lines
+206
to
+211
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is a critical token cache collision issue. The token cache for service accounts is keyed by scopes, but the cache filename is the same whether impersonation is used or not ( This will lead to incorrect authentication, causing either permission errors or actions being performed as the wrong identity. To fix this, you should use a different cache file when impersonation is active. I recommend modifying the For example: // (on line 202, which is outside the diff)
let impersonate_user = std::env::var("GOOGLE_WORKSPACE_IMPERSONATE_USER").ok().filter(|s| !s.is_empty());
let cache_key_suffix = if let Some(sub) = &impersonate_user {
// Use a hash to create a unique, filename-safe suffix.
// You'll need to add a dependency like `sha256`.
use sha256::digest;
let hash = digest(sub.as_bytes());
format!("_impersonate_{}", &hash[..12])
} else {
String::new()
};
let sa_cache = token_cache_path.with_file_name(format!("sa{}_{tc_filename}", cache_key_suffix));
// ... then later use `impersonate_user` to set the subject
if let Some(sub) = impersonate_user {
// ...
} |
||||||||||
|
|
||||||||||
| let auth = builder | ||||||||||
| .with_storage(Box::new(crate::token_storage::EncryptedTokenStorage::new( | ||||||||||
| sa_cache, | ||||||||||
| ))) | ||||||||||
| .build() | ||||||||||
| .await | ||||||||||
| .context("Failed to build service account authenticator")?; | ||||||||||
|
|
||||||||||
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.
The
subvariable, read from theGOOGLE_WORKSPACE_IMPERSONATE_USERenvironment variable, is logged without proper sanitization. This can lead to a terminal escape sequence injection vulnerability if the environment variable contains malicious control characters. While the repository's general rule specifically mentions 'error strings', the principle of sanitizing any untrusted input printed to the terminal should be applied to prevent this security risk.References