0
votes

Hello and thank you for the help,

I am using the php-sdk for the aws lambda invoke method WITHOUT the use of an API.

I am following the docs per this https://docs.aws.amazon.com/aws-sdk-php/v2/api/class-Aws.Lambda.LambdaClient.html#_invoke

What's weird is that I use the SNS class with my external credentials file located in ~/.aws/credentials and ~/.aws/config and it works fine so I don't think it's a problem with the credentials although I could be wrong.

My code is:

$client = LambdaClient::factory([
    'version'  => 'latest',
    'key' => $f_key,
    'secret' => $f_secret,
    'region' => 'us-east-1'
]);

$result = $client->invoke(array(

    'FunctionName' => 'MY_FUNC',

//  NOT SET AWS SAYS IT DEFAULTS

//    'InvocationType' => 'string',

//    'LogType' => 'string',

//    'Qualifier' => 'string',

    'ClientContext' => '
        'ClientContext' => '{
            "id": 1006410,
            "title": "LAMBDA TEST"
        }',
',

    'Payload' => 'mixed type: string|resource|\Guzzle\Http\EntityBodyInterface',

));

Error I am getting:

PHP Fatal error:  Uncaught exception 'Aws\Lambda\Exception\LambdaException' with message 'Error executing "Invoke" on "https://lambda.us-east-1.amazonaws.com/2015-03-31/ARN_REMOVED/invocations"; AWS HTTP error: Client error: `POST https://lambda.us-east-1.amazonaws.com/2015-03-31/functions/ARN_REMOVED/invocations` resulted in a `403 Forbidden` response:
{"message":"The request signature we calculated does not match the signature you provided. Check your AWS Secret Access  (truncated...)
 InvalidSignatureException (client): 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. - {"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  in /home/USER/Documents/symphonic/SMS-v1/vendor/aws/aws-sdk-php/src/WrappedHttpHandler.php on line 191
1
Isn't ClientContext supposed to be a string containing base64-encoded JSON, rather than an array? I would suggest that you test with that element removed entirely. - Michael - sqlbot
@Michael-sqllbot I think you are correct and now looking at my code I see that it is in an array format and probably not properly encoded thank you for the suggestion I will try that out and if it works i'll accept your answer - Patrick Florian
@Michael-sqllbot THANK YOU SO MUCH! This worked for me: - Patrick Florian
$str = '{"Type":"User"}'; $base64str = base64_encode($str); 'ClientContext' => $base64str, - Patrick Florian

1 Answers

0
votes

This PHP SDK expects the optional ClientContext to be a base64-encoded JSON object, rather than an array.

ClientContext => (string)

Using the ClientContext you can pass client-specific information to the Lambda function you are invoking. You can then process the client information in your Lambda function as you choose through the context variable. For an example of a ClientContext JSON, go to PutEvents in the Amazon Mobile Analytics API Reference and User Guide.

The ClientContext JSON must be base64-encoded.

https://docs.aws.amazon.com/aws-sdk-php/v2/api/class-Aws.Lambda.LambdaClient.html#_invoke

The signing error, presumably, results from a discrepancy between two parts of the internals: the way the SDK handles the incorrect argument type when generating the signature, and the way it handles it when generating the actual request. It seems like an SDK bug that the incorrect argument type is silently handled all the way past the point of sending a request to the API, which throws a vague error.

The service API isn't at fault, though.

When requests arrive at AWS, several things happen in very rapid succession, and always in the same order. The first failure to be encountered causes the entire request to fail.

The first thing checked is whether the signature has expired, either by an explicit expiration or by the Date or x-amz-date value being too skewed.

Next, the AWSAccessKeyId or X-Amz-Credential is checked for validity (and scope, in the latter case).

Then, the signature is validated, to ensure that it was signed with the correct matching secret key, and hasn't been tampered with since it was signed. Assuming the request was not corrupted in-flight or tampered with, there are two things that can cause this: an invalid access key secret, or a bug in the code that signed the request... hence, the error message:

Check your AWS Secret Access Key and signing method

The reason the message is vague is that one security mechanism that the request signing algorithms use (HMAC-SHA) makes it impossible to distinguish between the two conditions (invalid secret key vs. bug). Every Signature V4 request has exactly 1 possible valid signature, and 16^64 - 1 other possible signatures, all of which are equally wrong, and convey no information about the cause of the signature mismatch. (The number is smaller for Signature V2, but not meaningfully so, for this discussion.) The tiniest of errors throw the entire algorithm into unrecognizable chaos, which is an intrinsic part of the security.

It is only after these steps complete that the request is evaluated for syntax and structure, permissions are checked, and the rest of the request processing proceeds, which is why a more helpful error isn't all that practical to provide.