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

Auth without a service account? #99

Open
johnrichardrinehart opened this issue Jan 31, 2023 · 5 comments
Open

Auth without a service account? #99

johnrichardrinehart opened this issue Jan 31, 2023 · 5 comments

Comments

@johnrichardrinehart
Copy link

It seems that it's required to be using a service account for interacting with Cloud Storage. Is my understanding wrong?

Google's official SDKs allow authenticating without providing service account credentials so are you open to changing the behavior of (at least) google-cloud-storage to allow for creating a Client without using a service account?

@yoshidan
Copy link
Owner

yoshidan commented Feb 6, 2023

As you indicated, it does not need to be required, so I will modify it to optional.
Thanks.

@johnrichardrinehart
Copy link
Author

Thank you! We regularly use Service Account impersonation for our development flows so this would be a great feature/improvement for us.

@yoshidan
Copy link
Owner

I removed the dependency for google-cloud-auth and published the new version.

@johnrichardrinehart
Copy link
Author

@yoshidan I'm sorry for my late response. I ran a small test whose source I've included below for future readers' convenience.

It seems to work really well! Great job and thank you!

I did encounter one behavior that concerned me, though. GCP allows you to change the application default credentials (ADC) in a few ways. One of them is using a flow like

gcloud config set auth/impersonate_service_account $SERVICE_ACCOUNT_NAME@$PROJECT_ID.iam.gserviceaccount.com

followed by

gcloud auth application-default login

and, assuming that the original user executing these commands has the Service Account Token Creator role (I think) then the ~/.config/gcloud/application_default_credentials.json file will then be replaced by

{
  "delegates": [],
  "service_account_impersonation_url": "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/$SERVICE_ACCOUNT_NAME@$PROJECT_ID.iam.gserviceaccount.com:generateAccessToken",
  "source_credentials": {
    "client_id": "$IMACLIENTID",
    "client_secret": "$IMASECRET",
    "refresh_token": "$IMAREFRESHTOKEN",
    "type": "authorized_user"
  },
  "type": "impersonated_service_account"
}

However, I'm finding that this authorization flow is not supported by google-cloud-auth. Using the source code at the bottom of this comment:

$ ./target/debug/google_cloud_storage
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: "failed to get cloud storage client: unsupported account impersonated_service_account"', src/main.rs:15:14
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

The error message is clear: impersonate_service_account is an unsupported type. But, is that intentional? Would you consider adding support for configuring and using ADC in this way?

$ cat src/main.rs     
use google_cloud_default::WithAuthExt;
use google_cloud_storage::client::ClientConfig;

fn main() {
    let rt = tokio::runtime::Builder::new_multi_thread()
        .enable_all()
        .build()
        .unwrap();

    let client = rt.block_on(async {
        let cfg = ClientConfig::default()
            .with_auth()
            .await
            .map_err(|e| format!("failed to get cloud storage client: {}", e))
            .unwrap();

        return google_cloud_storage::client::Client::new(cfg);
    });

    let req = google_cloud_storage::http::objects::list::ListObjectsRequest {
        bucket: "$MY_BUCKET".to_string(),
        max_results: Some(10),
        prefix: Some("a".to_string()),
        ..Default::default()
    };

    let res = rt.block_on(client.list_objects(&req, None)).unwrap();

    for item in res.items.unwrap() {
        println!("item {}: md5: {}", item.name, item.md5_hash.unwrap())
    }
}

and a Cargo.toml like

$ cat Cargo.toml                                            
[package]
name = "google_cloud_storage"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
google-cloud-default = { version = "0.1.0", features = ["storage"] }
google-cloud-storage = { version = "0.9.0", features = ["default"] }
tokio = { version = "1.26.0", features = ["rt", "macros", "rt-multi-thread", "time", "sync"] }

@johnrichardrinehart
Copy link
Author

johnrichardrinehart commented Mar 8, 2023

I may be slow to respond since I'm no longer rely\ing on google-cloud-rust as I've switched our bucket storage to R2 and am using an S3-compatible storage rust library, now (rusoto_s3, I think?).

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

No branches or pull requests

2 participants