-
Notifications
You must be signed in to change notification settings - Fork 957
Description
Describe the bug
We are currently attempting to implement Workload Identity Federation to call GCP from our AWS instances as outlined in Googles documentation. Upon creating the request and signing that request with the correct host and x-goog-cloud-target-resource, we then are sending over the request to be signed. Once the request is sent over and we get a signed request to send to Google, we recieve the following error message:
This attempt was done using DefaultRequest and AWS4Signer.
{"error":"invalid_grant","error_description":"Received invalid AWS response of type SignatureDoesNotMatch with error message: The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details."}
Expected Behavior
We would expect, given this script and the credentials that are being utilized here, specifically the access key and secret access key, that we would recieve a correctly signed request to pass to recieve an STS through WIF.
Current Behavior
We are seeing the error message: {"error":"invalid_grant","error_description":"Received invalid AWS response of type SignatureDoesNotMatch with error message: The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details."}
Reproduction Steps
Please see additional context section for items we have ruled out.
public String generateSubjectToken(String projectNumber, String poolId, String providerId) {
AWSCredentials credentials = new DefaultAWSCredentialsProviderChain().getCredentials();
AWS4Signer signer = new AWS4Signer();
Request<Void> request = new DefaultRequest<Void>("sts");
request.setHttpMethod(HttpMethodName.POST);
request.setEndpoint(URI.create("https://sts.amazonaws.com/?Action=GetCallerIdentity&Version=2011-06-15"));
Map<String, String> headers = new HashMap<>();
headers.put("host", "sts.amazonaws.com");
headers.put("x-goog-cloud-target-resource", "//iam.googleapis.com/projects/" + projectNumber + "/locations/global/workloadIdentityPools/" + poolId + "/providers/" + providerId);
request.setHeaders(headers);
System.out.println("Request is: " + request.toString());
System.out.println("Headers are: " + headers.toString());
signer.setServiceName("sts");
signer.setRegionName("us-east-1");
signer.sign(request, credentials);
JSONObject token = new JSONObject();
token.put("url", request.getEndpoint().toString());
token.put("method", request.getHttpMethod().toString());
JSONArray headersJsonArray = new JSONArray();
for (Map.Entry<String, String> header : request.getHeaders().entrySet()) {
JSONObject headerJson = new JSONObject();
headerJson.put("key", header.getKey());
headerJson.put("value", header.getValue());
headersJsonArray.put(headerJson);
}
token.put("headers", headersJsonArray);
String encodedToken = token.toString();
try {
encodedToken = URLEncoder.encode(encodedToken, "UTF-8");
System.out.println("URL encoded token: " + encodedToken);
} catch (UnsupportedEncodingException e) {
System.err.println("Error encoding the token");
e.printStackTrace();
}
System.out.println("Token: " + token.toString());
System.out.println("URL encoded token: " + encodedToken);
return encodedToken;
}
Possible Solution
One of our theories here is that our secret currently have a / in it. With that being passed in to the signer, is it possible that this is not being escaped and thus causing a signature mismatch?
Additional Information/Context
Here is the code that is generating this signature. I have been able to confirm the following:
- The access key is getting fetched from the environment from the
DefaultAWSCredentialsProviderChain. - The secret key is also getting fetched from the
DefaultAWSCredentialsProviderChain. - We have the correct service accounts in our GCP instance as well as the mappings properly established.
We have this working correctly using BOTO in a Python service and that service is using the same credentials. This seems to be specific to Java and the Signer is our biggest suspect at the moment.
AWS Java SDK version used
2.20.158
JDK version used
11.0.16
Operating System and version
Mac OS 13.4.1 (22F82)