@@ -27,6 +27,7 @@ import * as iam from "aws-cdk-lib/aws-iam"
2727import * as ops from "aws-cdk-lib/aws-opensearchserverless"
2828import * as cr from "aws-cdk-lib/custom-resources"
2929import * as ssm from "aws-cdk-lib/aws-ssm"
30+ import * as lambda from "aws-cdk-lib/aws-lambda"
3031import { nagSuppressions } from "../nagSuppressions"
3132
3233export interface EpsAssistMeStackProps extends StackProps {
@@ -376,6 +377,38 @@ export class EpsAssistMeStack extends Stack {
376377 ]
377378 } )
378379
380+ // ==== Bedrock model invocation policy ====
381+ const slackLambdaBedrockModelPolicy = new PolicyStatement ( {
382+ actions : [ "bedrock:InvokeModel" ] ,
383+ resources : [
384+ `arn:aws:bedrock:${ this . region } ::foundation-model/${ lambdaEnv . RAG_MODEL_ID } `
385+ ]
386+ } )
387+
388+ // ==== Bedrock KB retrieve and retrieveAndGenerate policy ====
389+ const slackLambdaBedrockKbPolicy = new PolicyStatement ( {
390+ actions : [ "bedrock:Retrieve" , "bedrock:RetrieveAndGenerate" ] ,
391+ resources : [
392+ `arn:aws:bedrock:${ this . region } :${ this . account } :knowledge-base/${ kb . attrKnowledgeBaseId } `
393+ ]
394+ } )
395+
396+ // ==== Guardrail policy ====
397+ const slackLambdaGuardrailPolicy = new PolicyStatement ( {
398+ actions : [ "bedrock:ApplyGuardrail" ] ,
399+ resources : [
400+ `arn:aws:bedrock:${ this . region } :${ this . account } :guardrail/*`
401+ ]
402+ } )
403+
404+ // ==== Lambda self-invoke policy ====
405+ const slackLambdaSelfInvokePolicy = new PolicyStatement ( {
406+ actions : [ "lambda:InvokeFunction" ] ,
407+ resources : [
408+ `arn:aws:lambda:${ this . region } :${ this . account } :function:*`
409+ ]
410+ } )
411+
379412 // ==== Lambda environment variables ====
380413 const lambdaEnv : { [ key : string ] : string } = {
381414 RAG_MODEL_ID : "anthropic.claude-3-sonnet-20240229-v1:0" ,
@@ -407,16 +440,10 @@ export class EpsAssistMeStack extends Stack {
407440
408441 // ==== Attach all policies to SlackBot Lambda role ====
409442 slackBotLambda . function . addToRolePolicy ( slackLambdaSSMPolicy )
410-
411- // ==== IAM Policy for Lambda to invoke itself ====
412- const lambdaSelfInvokePolicy = new PolicyStatement ( {
413- actions : [ "lambda:InvokeFunction" ] ,
414- resources : [
415- `arn:aws:lambda:${ this . region } :${ this . account } :function:*`
416- ]
417- } )
418- // Attach the self-invoke policy to the SlackBot Lambda
419- slackBotLambda . function . addToRolePolicy ( lambdaSelfInvokePolicy )
443+ slackBotLambda . function . addToRolePolicy ( slackLambdaSelfInvokePolicy )
444+ slackBotLambda . function . addToRolePolicy ( slackLambdaBedrockModelPolicy )
445+ slackBotLambda . function . addToRolePolicy ( slackLambdaBedrockKbPolicy )
446+ slackBotLambda . function . addToRolePolicy ( slackLambdaGuardrailPolicy )
420447
421448 // ==== API Gateway & Slack Route ====
422449 const apiGateway = new RestApiGateway ( this , "EpsAssistApiGateway" , {
@@ -426,12 +453,18 @@ export class EpsAssistMeStack extends Stack {
426453 trustStoreKey : "unused" ,
427454 truststoreVersion : "unused"
428455 } )
429- // Add SlackBot Lambda to API Gateway
430456 const slackRoute = apiGateway . api . root . addResource ( "slack" ) . addResource ( "ask-eps" )
431457 slackRoute . addMethod ( "POST" , new LambdaIntegration ( slackBotLambda . function , {
432458 credentialsRole : apiGateway . role
433459 } ) )
434- // apiGateway.role.addManagedPolicy(slackBotLambda.executionPolicy)
460+
461+ // ==== Allow API Gateway to invoke the Lambda ====
462+ new lambda . CfnPermission ( this , "ApiGatewayInvokeSlackBotLambda" , {
463+ action : "lambda:InvokeFunction" ,
464+ functionName : slackBotLambda . function . functionName ,
465+ principal : "apigateway.amazonaws.com" ,
466+ sourceArn : `arn:aws:execute-api:${ this . region } :${ this . account } :${ apiGateway . api . restApiId } /*/POST/slack/ask-eps`
467+ } )
435468
436469 // ==== Output: SlackBot Endpoint ====
437470 new CfnOutput ( this , "SlackBotEndpoint" , {
0 commit comments