How to use Appsync Http Resolver with AWS services which expected post but without an request body?
I try to make a request to this endpoint: https://docs.aws.amazon.com/codeartifact/latest/APIReference/API_ListPackages.html
Appsync Setup
Http datasource endpoint: https://codeartifact.eu-central-1.amazonaws.com/
I use following http resolver:
function request(ctx) {
return {
method: "POST",
params: {
query: {
"domain": "<redacted>",
"domain-owner": "<redacted>",
"repository": "<redacted>"
},
},
resourcePath: "/v1/packages",
};
}
function response(ctx) {
return [ctx.result.body];
}
export {
request,
response
};
Then I get following 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.
JS script
So I tried to create a js script to send such a request:
When I set applyChecksum
to false
, the request works.
When I set the applyChecksum
to true
, the request fails with the same error message above.
import {SignatureV4} from "@smithy/signature-v4";
import {Sha256} from "@aws-crypto/sha256-js";
import {defaultProvider} from "@aws-sdk/credential-provider-node";
const signatureV4 = new SignatureV4({
service: "codeartifact",
applyChecksum: false, //if set to true, the reuqest fails
region: "eu-central-1",
credentials: defaultProvider(),
sha256: Sha256
});
const url = new URL("https://codeartifact.eu-central-1.amazonaws.com/v1/packages")
const signedRequest = await signatureV4.sign({
method: "POST",
protocol: url.protocol,
hostname: url.hostname,
path: url.pathname,
headers: {
host: url.host
},
query: {
'domain': "<redacted>",
'domain-owner': "<redacted>",
'repository': "<redacted>",
}
});
edit:
cdk
this.graphqlApi = new GraphqlApi(this, 'AppSyncApi', {
...
})
const codeArtifactHttpDataSource = this.graphqlApi.addHttpDataSource('CodeArtifactHttpDataSource', `https://codeartifact.eu-central-1.amazonaws.com/`, {
authorizationConfig: {
signingRegion: 'eu-central-1',
signingServiceName: 'codeartifact',
},
});
codeArtifactHttpDataSource.grantPrincipal.addToPrincipalPolicy(new PolicyStatement({
actions: ['codeartifact:DescribePackageVersion',
'codeartifact:DescribeRepository',
'codeartifact:GetPackageVersionReadme',
'codeartifact:GetRepositoryEndpoint',
'codeartifact:ListPackages',
'codeartifact:ListPackageVersions',
'codeartifact:ListPackageVersionAssets',
'codeartifact:ListPackageVersionDependencies',
'codeartifact:ReadFromRepository',
'codeartifact:GetAuthorizationToken'],
resources: ['*'],
}));
const appsyncFunction = new AppsyncFunction(this, 'AppsyncFunction', {
api: this.graphqlApi ,
dataSource: codeArtifactHttpDataSource,
name: 'js_function',
code: Code.fromAsset(path.join(__dirname, '<path-to-js>')),
runtime: FunctionRuntime.JS_1_0_0,
});
new Resolver(this, 'Resolver', {
api: this.graphqlApi,
pipelineConfig: [appsyncFunction],
typeName: 'Query',
fieldName: '<fieldname>',
runtime: FunctionRuntime.JS_1_0_0,
code: Code.fromInline(`
// The before step
export function request(ctx) {
return {}
}
// The after step
export function response(ctx) {
return ctx.prev.result
}`)
});
Is it the case that you're receiving this error even after setting up the role and HTTP data source, and if so could you provide the details of the http configuration file used?
@jthwaits i added the cdk part, with signing part. We use this with kms signing services to sigin jwts, which works great.