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

Cannont generate Signed URL though google_service_account_access_token #3558

Open
salrashid123 opened this issue May 6, 2019 · 11 comments
Open

Comments

@salrashid123
Copy link
Contributor

salrashid123 commented May 6, 2019

google_service_account_access_token allows one service account to impersonate another within a template.

However, when used with google_storage_object_signed_url, the impersonated credential lacks a local service account signing object (json cert, .p12, pem) thats used sign.

That is, the following config

provider "google" {}

data "google_client_config" "default" {
  provider = "google"
}

data "google_service_account_access_token" "default" {
 provider = "google"
 target_service_account = "impersonated-account@fabled-ray-104117.iam.gserviceaccount.com"
 scopes = ["userinfo-email", "cloud-platform"]
 lifetime = "300s"
}

provider "google" {
   alias  = "impersonated"
   access_token = "${data.google_service_account_access_token.default.access_token}"
}

data "google_client_openid_userinfo" "me" {
  provider = "google.impersonated"
}

data "google_storage_object_signed_url" "artifact" {
  provider = "google.impersonated"
  bucket = "fabled-ray-104117"
  path   = "signed_url_file.txt"
}

output "target-email" {
  value = "${data.google_client_openid_userinfo.me.email}"
}

output "signedurl" {
  value = "${data.google_storage_object_signed_url.artifact.signed_url}"
}

when used with

export GOOGLE_APPLICATION_CREDENTIALS=/path/to/source_svc_account.json
(which is svc account for source_service_account@PROJECTA.iam.gserviceaccount.com)

gives a signedurl based off of the source account (not impersonated account

Outputs:

signedurl = https://storage.googleapis.com/fabled-ray-104117/signed_url_file.txt?GoogleAccessId=source_service_account@PROJECTA.iam.gserviceaccount.com&Expires=1557003947&Signature<redactd>

target-email = impersonated-account@fabled-ray-104117.iam.gserviceaccount.com

when used with

export GOOGLE_CLOUD_KEYFILE_JSON=/path/to/source_svc_account.json

gives

Error: Error refreshing state: 1 error(s) occurred:

* data.google_storage_object_signed_url.artifact: 1 error(s) occurred:

* data.google_storage_object_signed_url.artifact: data.google_storage_object_signed_url.artifact: Credentials not found in datasource, provider configuration or GOOGLE_APPLICATION_CREDENTIALS environment variable.

Baiscally, signedurl expects a local signing key. Potential solution wouldbe to 'remotely sign' via iamcredentials.signBlob() as described here:

Affected Resource(s)

  • google_service_account_access_token (data source)
    b/299683703
@rileykarson rileykarson added the bug label Jul 3, 2019
@edwardmedia edwardmedia self-assigned this Jan 8, 2020
@edwardmedia
Copy link
Contributor

@salrashid123 I followed your steps and can't repro the Error. Both return the expected outputs. I am using terraform-provider-google_v3.4.0. What version were you using? If your versions were old, could you please upgrade and then try it again? I am closing the issue. Please reopen it if you still experience the issue or you need further discussion. Thanks

@salrashid123
Copy link
Contributor Author

yeah, i can still repro this even with

$ terraform version
Terraform v0.12.19
+ provider.google v3.4.0

By expected output do you mean an actual signedURL issed by the impersonated service account as intended above?
i.,e with

  • with GOOGLE_APPLICATION_CREDENTIALS it may appear to work but pls check the value of GoogleAccessId in the URL ouptput
  • with GOOGLE_CLOUD_KEYFILE_JSON you should get an error

The code in https://github.com/terraform-providers/terraform-provider-google/blob/master/google/data_source_storage_object_signed_url.go#L144 looks for a service accoun'ts json file that will perform the actual signing

https://github.com/terraform-providers/terraform-provider-google/blob/master/google/data_source_storage_object_signed_url.go#L344

...but what the impersonated credential that is supposed to do the signing doens't have a cert ...ther's no way it can sign..the only way maybe if the impersonated credential uses the IAM API to 'sign for itself'

@salrashid123
Copy link
Contributor Author

@edwardmedia could you reopen this one? its a pretty uncommon usage but its still an issue

@hiloboy0119
Copy link

@edwardmedia I am running into this same issue, trying to deploy forseti on gke using service account impersonation

hiloboy0119 added a commit to hiloboy0119/terraform-google-forseti that referenced this issue Feb 1, 2020
Moved away from `google_storage_object_signed_url` as it requires
a local json keyfile and I am deploying using service account
impersonation.

hashicorp/terraform-provider-google#3558
hiloboy0119 added a commit to hiloboy0119/terraform-google-forseti that referenced this issue Feb 1, 2020
Moved away from `google_storage_object_signed_url` as it requires
a local json keyfile and I am deploying using service account
impersonation.

hashicorp/terraform-provider-google#3558
@salrashid123
Copy link
Contributor Author

here is an example of generating signedurl with iamcredentials signblob:

https://gist.github.com/salrashid123/b8cb77bd0119f3b48610a4d9f16cb167

in this case, the terraform signedurl function would accept the new parameters below and elect to use iamcredentials instead of the certificate file

data "google_storage_object_signed_url" "artifact" {
  provider = "google.impersonated"
  bucket = "fabled-ray-104117"
  path   = "signed_url_file.txt"

      targetPrincipal = "impersonated-account@your_project.iam.gserviceaccount.com"
     delegates := []string{}
    expires  = 1580735835
}

there are probably cleaner ways but if the last three prameters are set, youcan use iamcredentials.

@danawillow danawillow reopened this Feb 4, 2020
@edwardmedia
Copy link
Contributor

I do see the impersonated-account is not the one used for the GoogleAccessId in the signedurl

@edwardmedia edwardmedia assigned emilymye and unassigned edwardmedia Feb 28, 2020
gkowalski-google added a commit to forseti-security/terraform-google-forseti that referenced this issue Mar 12, 2020
…480)

* Updating the way Forseti Server Configuration is retrieved from GCS

Moved away from `google_storage_object_signed_url` as it requires
a local json keyfile and I am deploying using service account
impersonation.

hashicorp/terraform-provider-google#3558

* Pinning version of helm provider to ~> v0.10

* Passing helm chart version through the on_gke_end_to_end example to the on_gke module

Co-authored-by: Gregg Kowalski <10247435+gkowalski-google@users.noreply.github.com>
@shanemcd
Copy link

I also just ran into this when attempting to run terraform on a GCE instance w/ an associated service account. I unfortunately had to upload a key file and use GOOGLE_APPLICATION_CREDENTIALS.

@emilymye emilymye added persistent-bug Hard to diagnose or long lived bugs for which resolutions are more like feature work than bug work and removed bug labels Jun 16, 2020
@emilymye emilymye removed their assignment Jun 16, 2020
@danawillow danawillow added this to the Backlog milestone Jun 22, 2020
@emilymye emilymye added enhancement and removed persistent-bug Hard to diagnose or long lived bugs for which resolutions are more like feature work than bug work labels Jun 22, 2020
@emilymye
Copy link
Contributor

emilymye commented Jun 22, 2020

As is, you can use a service account key instead of an google_service_account_access_token and provide it as the credentials field.

I do also see the benefit of not requiring a local key/exposing that potentially in state. We could treat this as a datasource that just calls iam.SignBlob on a URL for the provider credentials, instead of trying to use a local private key.

If we added a service_account field, that should be enough to indicate we want to use signBlob against that service account. Otherwise, if credentials are given, use those to sign. If neither are given, use the local environment key to sign.

Work would just entail adding this if-else logic and a function that calls signBlob

@salrashid123
Copy link
Contributor Author

i don't think you an just use the service account name field alone to do this since the actual API could potentially several additional parameter for it to work (eg if the impersonation requires chained delegation, you wouln't know which ones to supply in request

@github-actions github-actions bot added the forward/review In review; remove label to forward label Aug 17, 2023
@ScottSuarez ScottSuarez added bug and removed enhancement forward/review In review; remove label to forward labels Aug 25, 2023
@benhxy
Copy link

benhxy commented Oct 12, 2023

You seem to want to create a SignedURL without service account key, which can be done by IAMCredential.SignBlob API. Instead of Terraform (which is more a infra tool), can you use gcloud/Python SDK instead? Those tools are more suitable for this type of workflows.

@melinath melinath added persistent-bug Hard to diagnose or long lived bugs for which resolutions are more like feature work than bug work and removed bug labels Jun 17, 2024
@melinath
Copy link
Collaborator

Note from triage: We're not entirely sure what the best way to handle this is, so will leave it up to the product team to decide how to proceed. However, it does seem like a thing that would reasonably make sense to support in Terraform.

@benhxy many Terraform-using companies require Terraform to be used for all API interactions, so a gcloud-based workaround may not be sufficient.

@melinath melinath added enhancement feature-request and removed persistent-bug Hard to diagnose or long lived bugs for which resolutions are more like feature work than bug work labels Jun 17, 2024
@melinath melinath modified the milestones: Backlog, Goals Jun 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

10 participants