From f2f31a195be1c8d81af0b3318b92b000dfe65ca0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Stormacq?= Date: Sat, 27 Sep 2025 11:24:18 +0200 Subject: [PATCH 1/4] improve example makefile --- Examples/quoteapi/Makefile | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/Examples/quoteapi/Makefile b/Examples/quoteapi/Makefile index 9660c1c..a316e90 100644 --- a/Examples/quoteapi/Makefile +++ b/Examples/quoteapi/Makefile @@ -49,6 +49,7 @@ builder-bot: docker build -f Dockerfile . -t swift-builder # prep directories + rm -rf $($@ARTIFACTS_DIR) mkdir -p $($@BUILD_DIR)/lambda $($@ARTIFACTS_DIR) # compile application inside Docker image using source code from local project folder @@ -58,8 +59,9 @@ builder-bot: # create lambda bootstrap file docker run --rm -v $($@BUILD_DIR):/build-target -v `pwd`:/build-src -w /build-src swift-builder bash -cl "cd /build-target/lambda && ln -s $($@PRODUCT) /bootstrap" - # copy binary to stage - cp $($@BUILD_DIR)/release/$($@PRODUCT) $($@STAGE)/bootstrap - - # copy app from stage to artifacts dir - cp $($@STAGE)/* $($@ARTIFACTS_DIR) + # copy binary to artifacts dir + cp $($@BUILD_DIR)/release/$($@PRODUCT) $($@ARTIFACTS_DIR)/bootstrap + + # copy resources to artifacts dir + [ -d "$($@BUILD_DIR)/release/$($@PRODUCT)_$($@PRODUCT).resources" ] && cp $($@BUILD_DIR)/release/$($@PRODUCT)_$($@PRODUCT).resources/* $($@ARTIFACTS_DIR) || true + \ No newline at end of file From 3998bc5e5c89f37531e97ded565feea5b0f62b1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Stormacq?= Date: Sat, 27 Sep 2025 11:34:58 +0200 Subject: [PATCH 2/4] address security flag CKV2_GHA_1 --- .github/workflows/pull_request.yml | 3 +++ .gitignore | 1 + 2 files changed, 4 insertions(+) diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 0cecf08..dd3edba 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -8,6 +8,9 @@ on: pull_request: types: [opened, reopened, synchronize] +# As per Checkov CKV2_GHA_1 +permissions: read-all + jobs: soundness: name: Soundness diff --git a/.gitignore b/.gitignore index c42160d..5d4b251 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,4 @@ DerivedData/ .swiftpm/config/registries.json .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata *key +.ash From fe3b1cb3e63d9e6dfd6a4d94a1e890a509915ac9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Stormacq?= Date: Sat, 27 Sep 2025 11:35:13 +0200 Subject: [PATCH 3/4] Address security flags CKV_OPENAPI_4 and CKV_OPENAPI_5 --- Examples/quoteapi/Sources/QuoteAPI/openapi.yaml | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/Examples/quoteapi/Sources/QuoteAPI/openapi.yaml b/Examples/quoteapi/Sources/QuoteAPI/openapi.yaml index 3151706..790f74c 100644 --- a/Examples/quoteapi/Sources/QuoteAPI/openapi.yaml +++ b/Examples/quoteapi/Sources/QuoteAPI/openapi.yaml @@ -1,8 +1,20 @@ +# This is an example API definition not suited for production +# +# In real life scenario, you must +# 1. Ensure that the global security field has rules defined +# 2. Ensure that security operations is not empty. +# https://learn.openapis.org/specification/security.html +# +# As per Checkov CKV_OPENAPI_4 and CKV_OPENAPI_5 + openapi: 3.1.0 info: title: StockQuoteService version: 1.0.0 - + +# security: +# - defaultApiKey: [] + components: schemas: quote: @@ -54,3 +66,5 @@ paths: description: Authentication required 404: description: Not Found + # security: + # - defaultApiKey: [] \ No newline at end of file From 5a95ca5628201edea1e351661ffdc529fcefbc2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Stormacq?= Date: Sat, 27 Sep 2025 11:56:35 +0200 Subject: [PATCH 4/4] add security notice in readme and oenapi.yaml --- Examples/quoteapi/README.md | 18 +++++++++++++++++- Examples/quoteapi/template.yml | 16 ++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/Examples/quoteapi/README.md b/Examples/quoteapi/README.md index a03de35..53dc3c9 100644 --- a/Examples/quoteapi/README.md +++ b/Examples/quoteapi/README.md @@ -2,7 +2,6 @@ This application illustrates how to deploy a Server-Side Swift workload on AWS using the [AWS Serverless Application Model (SAM)](https://aws.amazon.com/serverless/sam/) toolkit. The workload is a simple REST API that returns a string from an Amazon API Gateway. Requests to the API Gateway endpoint are handled by an AWS Lambda Function written in Swift. - ## Prerequisites To build this sample application, you need: @@ -81,3 +80,20 @@ When finished with your application, use SAM to delete it from your AWS account. ```bash sam delete ``` + +## ⚠️ Security and Reliability Notice + +This is an example application for demonstration purposes. When deploying such infrastructure in production environments, we strongly encourage you to follow these best practices for improved security and resiliency: + +- Enable access logging on API Gateway ([documentation](https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-logging.html)) +- Ensure that AWS Lambda function is configured for function-level concurrent execution limit ([concurrency documentation](https://docs.aws.amazon.com/lambda/latest/dg/lambda-concurrency.html), [configuration guide](https://docs.aws.amazon.com/lambda/latest/dg/configuration-concurrency.html)) +- Check encryption settings for Lambda environment variables ([documentation](https://docs.aws.amazon.com/lambda/latest/dg/configuration-envvars-encryption.html)) +- Ensure that AWS Lambda function is configured for a Dead Letter Queue (DLQ) ([documentation](https://docs.aws.amazon.com/lambda/latest/dg/invocation-async-retain-records.html#invocation-dlq)) +- Ensure that AWS Lambda function is configured inside a VPC when it needs to access private resources ([documentation](https://docs.aws.amazon.com/lambda/latest/dg/configuration-vpc.html), [code example](https://github.com/swift-server/swift-aws-lambda-runtime/tree/main/Examples/ServiceLifecycle%2BPostgres)) + +**Note:** The `openapi.yaml` file in this example is not suited for production. In real-world scenarios, you must: +1. Ensure that the global security field has rules defined +2. Ensure that security operations is not empty ([OpenAPI Security Specification](https://learn.openapis.org/specification/security.html)) +3. Follow proper authentication, authorization, input validation, and error handling practices + +As per Checkov CKV_OPENAPI_4 and CKV_OPENAPI_5 security checks. diff --git a/Examples/quoteapi/template.yml b/Examples/quoteapi/template.yml index 14a3507..9e5650b 100644 --- a/Examples/quoteapi/template.yml +++ b/Examples/quoteapi/template.yml @@ -2,6 +2,22 @@ AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Description: SAM Template for QuoteService +# This is an example SAM template for the purpose of this project. +# When deploying such infrastructure in production environment, +# we strongly encourage you to follow these best practices for improved security and resiliency +# - Enable access loggin on API Gateway +# See: https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-logging.html) +# - Ensure that AWS Lambda function is configured for function-level concurrent execution limit +# See: https://docs.aws.amazon.com/lambda/latest/dg/lambda-concurrency.html +# https://docs.aws.amazon.com/lambda/latest/dg/configuration-concurrency.html +# - Check encryption settings for Lambda environment variable +# See: https://docs.aws.amazon.com/lambda/latest/dg/configuration-envvars-encryption.html +# - Ensure that AWS Lambda function is configured for a Dead Letter Queue(DLQ) +# See: https://docs.aws.amazon.com/lambda/latest/dg/invocation-async-retain-records.html#invocation-dlq +# - Ensure that AWS Lambda function is configured inside a VPC when it needs to access private resources +# See: https://docs.aws.amazon.com/lambda/latest/dg/configuration-vpc.html +# Code Example: https://github.com/swift-server/swift-aws-lambda-runtime/tree/main/Examples/ServiceLifecycle%2BPostgres + Globals: Function: Timeout: 60