Invocation:
// initialization
storage = StorageOptions.getDefaultInstance().getService();
// later
storage.signUrl(info, 5L, TimeUnit.MINUTES,
Storage.SignUrlOption.httpMethod(HttpMethod.valueOf(method)),
Storage.SignUrlOption.withContentType()
);
Stacktrace:
Caused by: java.lang.IllegalStateException: Signing key was not provided and could not be derived
at com.google.common.base.Preconditions.checkState(Preconditions.java:444)
at com.google.cloud.storage.StorageImpl.signUrl(StorageImpl.java:508)
I tracked the problem down to the com.google.auth.oauth2.GoogleCredentials.getDefaultCredentialsUnsynchronized()(https://github.com/google/google-auth-library-java/blob/51a5445b33d10f252cadfdcca82dd9e68512e483/oauth2_http/java/com/google/auth/oauth2/DefaultCredentialsProvider.java#L182) where it skips over tryGetAppEngineCredential() to return an instance of com.google.auth.oauth2.AppengineCredentials which is one of the implementations of ServiceAccountSigner required by the signUrl call with default credentials.
This may also affect other services assuming an instance of com.google.auth.oauth2.AppengineCredentials.
Is there any specific reason why to check for java7 only?
Background: We moved to the java8 runtime on GAE and upgraded our api clients to the google-cloud-java api clients version 1.10.0.
@neozwu Do you have context around this? It looks like the relevant auth library code was last updated in these PRs:
@phimar For GAE java 8 standard, metadata server is used to retreive credentials. The current implementation for AppengineCredentials uses appengine APIs, which only work for java 7. It seems that ComputeEngineCredentials didn't implement ServiceAccountSigner. @lesv @ludoch do you have any context regarding this?
/cc @lesv @ludoch
No, but its a very important thing to fix.
Thank you for your comments and the linkage to the issue on google/google-auth-library-java.
I can successfully sign urls with the default storage options (on Java8 GAE Standard) using google-cloud 0.20.3-alpha. When I upgrade to 0.32.0-alpha I see this error.
I've reverted to the old version.
Same issue is present in flexible runtime too?
@vchudnov-g FYI
@jabubake FYI
@garrettjonesgoogle FYI
@frankyn FYI
It seems #2504 can also be solved by this.
should be solved by https://github.com/google/google-auth-library-java/pull/150
doesn't look like it's resolved.
@jadekler @garrettjonesgoogle @ludoch : has anybody diagnosed what the issue is ? It seems like ComputeEngineCredentials does implement ServiceAccountSigner now ? google/google-auth-library-java#150
cc @chingor13, who dealt with the linked CL
nothing magical here, the version hasn't been bumped to the new version of the related library
current master:
https://github.com/GoogleCloudPlatform/google-cloud-java/blob/ab575d0eaf987cbc04f715310b4f23277bd84b9c/google-cloud-clients/pom.xml#L160
(the linked PR has been released in https://github.com/google/google-auth-library-java/releases/tag/v0.10.0)
@pongad Let's bump auth to 0.10.0 for the next release
Yes this issue present in flexible runtime too, and locally when running through the appengine maven plugin.
com.google.cloud.tools:appengine-maven-plugin
google.auth.version has been bumped. Please update the library to the latest version (1.38.0) and see if the problem is resolved.
I had the same problem (using 1.35.0):
Caused by: java.lang.IllegalStateException: Signing key was not provided and could not be derived
Using AppEngine standard, I solved like this:
static final AppIdentityService identityService = AppIdentityServiceFactory.getAppIdentityService();
SignUrlOption signWith = SignUrlOption.signWith(new ServiceAccountSigner() {
@Override
public byte[] sign(byte[] toSign) {
return identityService.signForApp(toSign).getSignature();
}
@Override
public String getAccount() {
return identityService.getServiceAccountName();
}
});
It would seem that this method documentation no longer applies to GCE, right?
https://github.com/GoogleCloudPlatform/google-cloud-java/blob/master/google-cloud-clients/google-cloud-storage/src/main/java/com/google/cloud/storage/Storage.java#L2045-L2047
Based on the above PRs and commentary, when running on GCE with google-cloud-storage v1.38.0, the application default credentials (ADC) should be sufficient to sign a blob, yes?
Wondering if anything else has to be done as we are still having trouble (different error message, getting a little farther in the code as far as execution) and not sure why things fail when running on GCE using ADC vs. when we provide the key file directly via GOOGLE_APPLICATION_CREDENTIALS.
thanks y'all for the support.
The ComputeEngineCredentials signing method requires 2 things:
iam.serviceAccounts.signBlob permission (available to the "Service Account Token Creator" role).@NicolaSpreafico try updating the com.google.cloud:google-cloud-storage dependency to 1.38.0 (or com.google.auth:google-auth-library-oauth2-http to 0.10.0) and ensuring the default service account has the necessary IAM access.
@noahdietz ADC prefers the key file provided by GOOGLE_APPLICATION_CREDENTIALS over the Compute Engine credentials and uses 2 different strategies for signing URLs. If you're seeing a SigningException you can inspect the underlying cause by catching the SigningException and looking at the Throwable from getCause(). It's likely that you need to set up the IAM config above.
Created https://github.com/google/google-auth-library-java/issues/175 for documentation and will open a new issue for docs here as well.
@chingor13 fixed! we had set all of the scopes and IAM policies we thought were necessary (devstorage.full_control & bucket objectAdmin). Didn't work. Turns out we needed to use the cloud-platform scope on the instance instead. At least that was the only thing that changed and it started working.
Thanks for the help.
Greetings folks! It looks like this issue has been resolved. If you're still running into problems... let us know!
I needed to grant iam.serviceAccounts.signBlob in order for the default service account to sign URLs while running in App Engine, but running locally with the same credentials didn't require this---is this a bug?
Most helpful comment
I had the same problem (using
1.35.0):Caused by: java.lang.IllegalStateException: Signing key was not provided and could not be derivedUsing AppEngine standard, I solved like this: