Open
Description
I have a smithy model with lambda authorizer configuration -
@title("sample service")
@service(sdkId: "serviceName", arnNamespace: "execute-api")
@cors(origin: "*")
@integration(
type: "aws_proxy"
httpMethod: "POST"
uri: "arn:${AWS::Partition}:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${LambdaFunctionArn}/invocations"
credentials: "${APIGatewayExecutionRoleArn}"
)
@httpApiKeyAuth(name: "x-session-token", in: "header")
@authorizers(
PROTECTED_API_AUTH: {
scheme: "smithy.api#httpApiKeyAuth"
type: "request"
uri: "authorizer-lambdaFunction-arn"
resultTtlInSeconds: 0
}
)
@authorizer("NONE")
@restJson1
@requestValidator("full")
service ServiceName {
version: "2024-11-10"
operations: [
Create
List
Get
]
errors: [
smithy.framework#ValidationException
]
}
@http(method: "POST", uri: "/object")
@authorizer("PROTECTED_API_AUTH")
operation Create {
input: CreateObjectRequest
output: CreateObjectResponse
}
I have a typescript client generated via adding this in smithy-build.json -
"typescript-client-codegen": {
"package": "@com.base/service-name-client",
"packageVersion": "0.0.1"
},
i use the openapi file generated by this smithy model in my cdk code for configuring api gateway.
Also i am editing the open api file slightly so i can configure a second api gateway as well that does not have lambda authorizer and is IAM based instead(keeping everything else same) -
const api = new SpecRestApi(this, "ServiceApi", {
restApiName: "ServiceApi",
deployOptions: {
stageName: props.stageName,
loggingLevel: MethodLoggingLevel.INFO,
dataTraceEnabled: true,
metricsEnabled: true,
accessLogDestination: new cdk.aws_apigateway.LogGroupLogDestination(
accessLogs
), // Enable access logs
accessLogFormat: cdk.aws_apigateway.AccessLogFormat.custom(
`$context.extendedRequestId $context.identity.sourceIp $context.identity.caller $context.identity.user [$context.requestTime] "$context.httpMethod $context.resourcePath $context.protocol" $context.status $context.responseLength $context.requestId`
),
},
apiDefinition: this.restApiDefinitionWithLambdaIntegration(
resolve(__dirname, "../generated/openapi/ServiceName.openapi.json"),
[["LambdaFunctionArn", lambdaFunction]],
apiExecutionRole
),
});
const apiDef = this.restApiDefinitionWithLambdaIntegration(
resolve(__dirname, "../generated/openapi/ServiceName.openapi.json"),
[["LambdaFunctionArn", lambdaFunction]],
apiExecutionRole
);
const apiDefinitionObject = (apiDef as any).definition;
if (!apiDefinitionObject || typeof apiDefinitionObject !== "object") {
throw new Error(
"Invalid API definition object. Check if the 'definition' field is present."
);
}
const apiDefSecurityFieldRemoved = JSON.parse(
JSON.stringify(apiDefinitionObject, (key, value) =>
key === "security" ? undefined : value
)
);
const apiDefIamAuthorizer = this.createRestApiWithIamAuthorizer(
apiDefSecurityFieldRemoved
);
createRestApiWithIamAuthorizer(apiDef: any): any {
apiDef.security = [{ "aws.auth.sigv4": [] }];
apiDef.components.securitySchemes = {
"aws.auth.sigv4": {
type: "apiKey",
description: "AWS Signature Version 4 authentication",
name: "Authorization",
in: "header",
"x-amazon-apigateway-authtype": "awsSigv4",
},
};
return ApiDefinition.fromInline(apiDef);
}
const apiWithIamAuth = new SpecRestApi(this, "ServiceNameApiWithIam", {
restApiName: "ServiceNameApiInternal",
deployOptions: {
stageName: props.stageName,
loggingLevel: MethodLoggingLevel.INFO,
dataTraceEnabled: true,
metricsEnabled: true,
accessLogDestination: new cdk.aws_apigateway.LogGroupLogDestination(
accessLogsIamApig
), // Enable access logs
accessLogFormat: cdk.aws_apigateway.AccessLogFormat.custom(
`$context.extendedRequestId $context.identity.sourceIp $context.identity.caller $context.identity.user [$context.requestTime] "$context.httpMethod $context.resourcePath $context.protocol" $context.status $context.responseLength $context.requestId`
),
},
apiDefinition: apiDefIamAuthorizer,
});
// Give the the rest api execute ARN permission to invoke the lambda.
lambdaFunction.addPermission("ApiInvokeLambdaPermission", {
principal: new iam.ServicePrincipal("apigateway.amazonaws.com"),
action: "lambda:InvokeFunction",
sourceArn: api.arnForExecuteApi(),
});
lambdaFunction.addPermission("IamAuthApiInvokeLambdaPermission", {
principal: new iam.ServicePrincipal("apigateway.amazonaws.com"),
action: "lambda:InvokeFunction",
sourceArn: apiWithIamAuth.arnForExecuteApi(),
});
}
This give me 2 api gateways -


I am using this the smithy generated client to make a request from another lambda function to the IAM based api gateway -
import { Service } from "@com.base/service-name-client";
// Configure the client
export const ServiceClient = new Service({
endpoint: {
protocol: "https",
hostname: "IAMBasedApiGIDValue.execute-api.us-east-1.amazonaws.com",
path: "/Prod",
},
});
await ServiceClient.create({
Id: someValue,
});
In the lambda logs from where this client invokes that IAM based APIG, I see -
2025-01-27T20:17:23.064Z c26f0cf3-a99f-41b6-8e73-ff9510ef75c4 INFO Received an unexpected error Error: HttpAuthScheme `smithy.api#httpApiKeyAuth` did not have an IdentityProvider configured.
at /var/task/server/dist/node_modules/@com.base/service-name-client/node_modules/@smithy/core/dist-cjs/index.js:92:11
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async /var/task/server/dist/node_modules/@com.base/service-name-client/node_modules/@aws-sdk/middleware-logger/dist-cjs/index.js:34:22
at async /var/task/server/dist/operations/Search.js:26:30
at async handle (/var/task/server/dist/node_modules/@com.base/search-server/dist-cjs/server/SearchService.js:42:22)
at async Runtime.handler (/var/task/server/dist/apigateway.js:14:34)
Why is it looking for httpApiKeyAuth
? What does this error mean ?
How do i fix this ?
Metadata
Metadata
Assignees
Labels
No labels