본문 바로가기
IT/Cloud

[Cloud] AWS Lambda 보안 강화 체크리스트: 10가지 필수 설정

by 수누다 2026. 7. 11.
반응형

목차

AWS Lambda 보안 강화 체크리스트: 10가지 필수 설정

AWS Lambda 보안, 이거 처음엔 되게 단순해 보이는데요. 함수 하나 잘 올리고 이벤트만 연결하면 끝 같지만, 실제 운영으로 들어가면 얘기가 완전히 달라집니다. 저도 홈랩이랑 실제 업무에서 서버리스(Serverless, 서버 관리 부담을 줄인 실행 방식)를 만지다 보니, 초반엔 "관리할 서버가 없으니 더 안전한 거 아닌가?"라고 생각했었는데요. 근데 여기서 많이들 놓치는 포인트가 있습니다. 서버가 안 보일 뿐이지, 권한(IAM), 비밀정보(Secrets), 네트워크(Network), 로깅(Logging), 배포 체계는 그대로 남아 있거든요.

특히 AWS Lambda 보안은 한두 개 설정만으로 끝나는 문제가 아닙니다. Lambda 보안 설정을 잘못하면 함수 자체보다도, 연결된 IAM Role(아이엠 역할), Secrets Manager(시크릿 매니저), S3, DynamoDB, API Gateway 쪽에서 사고가 나는 경우가 더 많더라고요. 그래서 이번 글에서는 제가 실제로 체크하는 AWS Lambda 베스트 프랙티스 중심의 보안 체크리스트 10가지를 정리해보겠습니다. 체크리스트 형태로 보시면 운영 전에 빠르게 점검하기 좋습니다.

AWS Lambda 보안 체크리스트 아키텍처 개요 이미지

AWS Lambda 보안 체크리스트를 한눈에 보여주는 아키텍처 개요 이미지입니다. 함수, IAM, Secrets, 로그, 네트워크 관계를 이해하는 데 도움이 됩니다.

AWS Lambda 보안, 왜 따로 챙겨야 할까요?

쉽게 말해 Lambda는 코드만 올리면 돌아가는 서비스지만, 그 코드가 무엇을 할 수 있는지는 주변 설정이 결정합니다. 예를 들어 함수 코드가 단순해도 과도한 IAM 권한이 붙어 있으면 S3 버킷 전체를 읽을 수 있고, 환경 변수(Environment Variables)에 비밀키를 평문으로 넣어두면 사고 범위가 순식간에 커집니다.

제가 직접 해보니, 서버리스 보안은 EC2처럼 OS 패치만 신경 쓰는 문제가 아니었습니다. 대신 다음 질문을 계속 던져야 하더라고요.

  • 이 함수는 정말 필요한 AWS API만 호출할 수 있나요?
  • 이벤트를 누가 발생시키는지 통제되고 있나요?
  • 에러가 나면 추적 가능한 로그가 남나요?
  • 비밀정보가 코드나 환경 변수에 과하게 노출되지 않나요?

여기서 중요한 포인트! AWS Lambda 보안은 "실행 코드"보다 "실행 권한과 연결 지점"을 먼저 봐야 합니다.

핵심 개념 정리: Lambda 보안 설정은 3층으로 봐야 합니다

저는 Lambda 보안을 볼 때 보통 3층으로 나눠서 봅니다. 저도 처음엔 헷갈렸는데 이렇게 나누니까 머리에 잘 들어오더라고요.

구분 무엇을 보호하나 대표 설정
접근 제어 누가 함수를 호출하고 무엇을 하게 할지 IAM Role, Resource-based policy, Function URL 인증
데이터 보호 비밀정보와 민감 데이터 노출 방지 KMS, Secrets Manager, 환경 변수 암호화
탐지와 대응 이상 징후 확인과 사고 대응 CloudWatch Logs, CloudTrail, Alarm

결국 Lambda 보안 설정은 단일 옵션이 아니라, 권한 최소화(Least Privilege, 최소 권한 원칙) + 비밀정보 분리 + 추적 가능성 확보 이 세 가지가 같이 가야 합니다.

AWS Lambda 보안 체크리스트 10가지

1. 실행 역할(IAM Execution Role)은 최소 권한으로 시작하세요

이건 진짜 기본인데, 가장 많이 무너집니다. 처음엔 편하니까 AWSLambdaBasicExecutionRole에 이것저것 붙이다가 나중에 권한이 비대해지거든요. 실제로 써보니까 함수별로 Role을 분리하는 것만 해도 사고 범위를 꽤 줄일 수 있었습니다.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "logs:CreateLogGroup",
        "logs:CreateLogStream",
        "logs:PutLogEvents"
      ],
      "Resource": "arn:aws:logs:ap-northeast-2:123456789012:*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "dynamodb:GetItem",
        "dynamodb:PutItem"
      ],
      "Resource": "arn:aws:dynamodb:ap-northeast-2:123456789012:table/app-session"
    }
  ]
}

팁: 와일드카드 *는 진짜 마지막 수단으로만 쓰세요. 특히 s3:*, dynamodb:*, kms:*는 운영 들어가면 나중에 반드시 발목 잡습니다.

2. 환경 변수에 비밀값을 직접 넣지 말고 Secrets Manager를 쓰세요

처음엔 이게 뭔가 싶었는데, 환경 변수에 토큰이나 DB 비밀번호를 그냥 넣는 습관이 제일 위험합니다. Lambda는 환경 변수 암호화를 지원하지만, 운영 기준에선 AWS Secrets ManagerSSM Parameter Store를 통해 분리하는 쪽이 훨씬 낫습니다.

import os
import json
import boto3

secrets = boto3.client("secretsmanager")


def get_secret(secret_name: str):
    response = secrets.get_secret_value(SecretId=secret_name)
    if "SecretString" in response:
        return json.loads(response["SecretString"])
    return {}


def lambda_handler(event, context):
    secret_name = os.environ["APP_SECRET_NAME"]
    app_secret = get_secret(secret_name)
    return {"statusCode": 200, "body": "ok"}

제가 직접 해보니 비밀값 교체(rotation)나 권한 추적도 쉬워지고, 코드 저장소에 값이 새는 일도 확실히 줄더라고요.

3. Lambda 리소스 기반 정책(Resource-based Policy)을 점검하세요

람다 함수는 실행 역할만 보는 게 아니라 누가 이 함수를 invoke(호출)할 수 있는지도 중요합니다. S3, EventBridge, API Gateway, 다른 계정에서 호출하는 구조라면 리소스 기반 정책을 꼭 보셔야 합니다.

aws lambda get-policy \
  --function-name my-secure-function

여기서 예상하지 못한 Principal(프린시펄, 권한 주체)이 있으면 바로 점검하셔야 합니다. 특히 멀티 계정 환경에서는 예전에 테스트용으로 열어둔 권한이 남아 있는 경우가 종종 있습니다. 저도 한 번 이거 때문에 한참 뒤졌습니다 ㅎㅎ

4. Function URL 또는 API 엔드포인트 인증을 반드시 확인하세요

Lambda Function URL을 쓰는 경우, AuthType 설정을 대충 넘기면 안 됩니다. 공개 엔드포인트가 필요한 상황이 아니라면 IAM 기반 인증이나 API Gateway의 인증 체계를 붙이는 쪽이 안전합니다.

aws lambda get-function-url-config \
  --function-name my-secure-function

공개 호출이 필요하다면 WAF(Web Application Firewall, 웹 애플리케이션 방화벽), 인증 토큰, Rate limiting(요청 제한)까지 같이 보셔야 합니다. Lambda 보안 설정에서 의외로 이 부분을 늦게 보는 팀이 많더라고요.

5. 런타임(Runtime)과 의존성(Dependencies)을 최신 보안 상태로 유지하세요

서버가 없다고 패치 부담이 완전히 사라지는 건 아닙니다. Lambda 런타임 버전, 배포 패키지 안의 라이브러리, 컨테이너 이미지를 쓰는 경우 베이스 이미지까지 관리 대상입니다. 특히 오래된 Python 패키지나 Node.js 라이브러리에서 취약점이 발견되면 Lambda도 그대로 영향받습니다.

pip install -r requirements.txt --upgrade
pip-audit
npm audit

중요: 런타임 지원 종료(EOL, End of Life) 일정은 주기적으로 확인하세요. 이건 보안뿐 아니라 배포 지속성에도 영향을 줍니다.

AWS Lambda 보안 설정과 권한 구조를 보여주는 이미지

Lambda 보안 설정 화면, IAM 역할, Secrets Manager 연결 흐름을 보여주는 이미지입니다. 어떤 설정이 어디에 있는지 감을 잡기 좋습니다.

6. CloudWatch Logs와 CloudTrail로 추적 가능성을 확보하세요

문제가 생겼을 때 "누가 호출했는지", "어떤 권한으로 실패했는지", "비정상 호출이 있었는지"를 못 보면 답이 없습니다. 저도 예전에 로그를 대충 남겼다가 원인 분석에 시간을 엄청 썼거든요.

  • CloudWatch Logs: 함수 실행 로그 확인
  • CloudTrail: API 호출 기록 확인
  • Metric Filter + Alarm: 에러 급증, 권한 거부, 비정상 호출 감지
aws logs describe-log-groups \
  --log-group-name-prefix /aws/lambda/

함수 로그에는 민감 정보가 찍히지 않도록 조심해야 합니다. 디버깅한다고 이벤트 전체를 그대로 출력하는 습관, 이거 나중에 진짜 위험합니다.

7. VPC 연결은 필요할 때만, 그리고 보안 그룹(Security Group)을 좁게

"보안을 위해 일단 VPC에 넣자"라고 생각하기 쉬운데요. 실제로는 모든 Lambda가 VPC에 있어야 하는 건 아닙니다. RDS 같은 프라이빗 리소스 접근이 필요할 때만 넣고, 보안 그룹과 서브넷을 최소화하는 게 핵심입니다.

여기서 중요한 포인트는 아웃바운드(Egress, 외부로 나가는 통신)도 같이 봐야 한다는 점입니다. 함수가 인터넷으로 나갈 필요가 없다면, 그 경로를 열어둘 이유가 없거든요.

상황 권장 방식 주의점
외부 공개 API 호출 기본 네트워크 또는 필요한 경로만 허용 비밀값 유출 로그 주의
프라이빗 RDS 접근 VPC 연결 + 최소 보안 그룹 불필요한 넓은 CIDR 금지
내부 서비스 전용 VPC 내부 제한 NAT/엔드포인트 설계 점검

8. 비동기 호출(Asynchronous Invocation) 실패 처리와 재시도를 설계하세요

보안 글인데 왜 실패 처리를 넣냐고요? 실제 운영에서는 실패 이벤트가 무한 재시도되거나, Dead Letter Queue(DLQ, 실패 이벤트 보관 큐) 없이 사라지는 게 더 큰 운영 사고로 이어집니다. 보안 사고 탐지 신호도 잃어버릴 수 있고요.

Resources:
  SecureFunction:
    Type: AWS::Lambda::Function
    Properties:
      FunctionName: secure-function
      Handler: index.handler
      Role: arn:aws:iam::123456789012:role/secure-lambda-role
      Runtime: python3.12
  SecureInvokeConfig:
    Type: AWS::Lambda::EventInvokeConfig
    Properties:
      FunctionName: !Ref SecureFunction
      Qualifier: "$LATEST"
      MaximumRetryAttempts: 2
      MaximumEventAgeInSeconds: 3600

실패 이벤트를 SQS나 SNS로 보내서 따로 확인하게 해두면 운영 안정성이 확 올라갑니다. 서버리스 보안은 "막는 것"만이 아니라 "문제 발생 시 놓치지 않는 것"도 포함입니다.

9. 동시성(Concurrency) 제한으로 과다 호출과 비용 폭주를 막으세요

Reserved Concurrency(예약 동시성)를 적절히 걸어두면 악의적 호출이나 비정상 트래픽 급증 시 피해 범위를 줄일 수 있습니다. 이건 성능 옵션 같지만, 저는 운영 보안 체크리스트에도 꼭 넣습니다.

aws lambda put-function-concurrency \
  --function-name my-secure-function \
  --reserved-concurrent-executions 20

드디어 됐다! 싶은 순간이 이런 때입니다. 한 번 제한을 걸어두면 폭주 상황에서도 백엔드 전체가 무너지는 걸 줄일 수 있거든요.

10. 코드 서명(Code Signing)과 배포 파이프라인 권한을 분리하세요

마지막으로 놓치기 쉬운 부분이 배포 보안입니다. 함수 실행 권한만 볼 게 아니라, 누가 코드를 배포할 수 있는지, 검증되지 않은 패키지가 올라갈 수 있는지도 봐야 합니다. AWS Lambda는 Code Signing(코드 서명) 기능을 지원하므로, 신뢰된 게시자만 배포되도록 통제할 수 있습니다.

CI/CD(지속적 통합/배포) 역할과 운영자가 쓰는 수동 권한을 분리하면 실수도 줄고 추적도 쉬워집니다. 실제로 써보니까 운영 계정에서 직접 콘솔 수정하는 습관을 줄이는 것만으로도 보안 수준이 꽤 올라가더라고요.

실전 구현: 운영 전에 제가 체크하는 순서

혹시 이런 경험 있으신가요? 함수는 잘 돌았는데 보안 리뷰에서 다 다시 보자는 말 나오는 상황이요. 그래서 저는 아래 순서대로 확인합니다.

  1. IAM Role 확인: 함수별 역할 분리, 액션/리소스 최소화
  2. 비밀값 확인: 환경 변수 평문 여부, Secrets Manager 사용 여부
  3. 호출 경로 확인: API Gateway, Function URL, EventBridge, S3 등 트리거 검토
  4. 로그 확인: CloudWatch 로그 존재, 민감 정보 출력 여부 확인
  5. 재시도/실패 처리 확인: 비동기 호출 정책과 DLQ 여부 확인
  6. 동시성 제한 확인: 비용 폭주와 시스템 영향도 점검
  7. 배포 체계 확인: CI/CD 권한, 코드 서명, 수동 변경 제한 확인
aws lambda list-functions
aws lambda get-function-configuration --function-name my-secure-function
aws iam get-role --role-name secure-lambda-role
aws lambda get-policy --function-name my-secure-function

이 정도만 체크해도 Lambda 보안 설정에서 큰 구멍은 상당수 잡힙니다.

⚠️ 제가 실제로 많이 본 실수와 트러블슈팅

  • 환경 변수에 토큰 저장: 테스트 때 편해서 넣어뒀다가 운영까지 가는 경우가 많습니다. 해결은 Secrets Manager로 이동하고, 접근 권한을 함수 Role에만 최소로 부여하는 겁니다.
  • CloudWatch 로그에 이벤트 전체 출력: 요청 본문 안에 개인정보나 인증 토큰이 있으면 바로 노출됩니다. 필요한 필드만 마스킹해서 남기세요.
  • IAM 와일드카드 남발: 처음엔 빨리 되지만, 나중엔 뭐가 왜 가능한지 추적이 안 됩니다. 저는 정책 줄이는 작업에서 삽질 좀 했습니다 ㅎㅎ
  • 공개 Function URL 방치: 테스트용 URL이 계속 열려 있는 경우가 있습니다. AuthType과 리소스 정책을 같이 보셔야 합니다.
  • VPC만 넣고 안심: 네트워크에 넣는다고 끝이 아닙니다. 보안 그룹, 엔드포인트, 아웃바운드 경로까지 봐야 진짜 의미가 있습니다.

근데 여기서 중요한 건, 모든 걸 한 번에 완벽하게 하려다 보면 오히려 놓칩니다. 가장 위험한 것부터 순서대로 줄이는 접근이 현실적이더라고요.

AWS Lambda 보안 검증을 위한 로그와 알람 대시보드 이미지

CloudWatch 로그, 에러 지표, 보안 경보를 시각화한 결과 이미지입니다. 검증 단계에서 어떤 항목을 확인해야 하는지 보여줍니다.

검증: AWS Lambda 보안이 제대로 적용됐는지 확인하는 방법

설정만 하고 끝내면 안 됩니다. 검증이 있어야 합니다. 제가 보통 보는 확인 포인트는 아래와 같습니다.

  1. 권한 테스트: 허용된 리소스만 접근 가능한지 확인
  2. 비정상 호출 테스트: 권한 없는 주체가 invoke 가능한지 확인
  3. 로그 검토: 민감 정보가 로그에 찍히지 않는지 확인
  4. 실패 이벤트 테스트: 재시도와 실패 보관이 의도대로 동작하는지 확인
  5. 알람 확인: 에러, 스로틀링(Throttling, 요청 제한), 접근 거부가 감지되는지 확인
aws lambda invoke \
  --function-name my-secure-function \
  response.json

aws cloudtrail lookup-events \
  --lookup-attributes AttributeKey=EventName,AttributeValue=Invoke

이거 진짜 편하더라고요. 한 번 검증 루틴을 잡아두면 새 함수가 늘어나도 같은 패턴으로 점검할 수 있습니다.

정리: Lambda 보안 설정은 체크리스트로 운영해야 합니다

이번 글을 짧게 정리하면 이렇습니다.

  • 최소 권한 IAM이 가장 먼저입니다.
  • 비밀정보는 코드와 환경 변수에서 분리해야 합니다.
  • 호출 경로와 로그를 같이 봐야 합니다.
  • 동시성, 실패 처리, 배포 체계까지 포함해야 운영 보안이 됩니다.

AWS Lambda 보안은 한 번 설정하고 끝나는 항목이 아니라, 배포할 때마다 반복 점검해야 하는 운영 습관에 가깝습니다. 저도 처음엔 보안 체크리스트가 귀찮았는데, 실제로 사고를 줄여주는 건 이런 반복 작업이더라고요. 다음 글에서는 API Gateway와 Lambda를 함께 쓸 때 인증/인가 구조를 어떻게 나누면 좋은지도 다뤄볼 예정입니다. 이전 글에서 IAM 정책 설계 원칙을 정리해두셨다면 같이 보시면 더 잘 연결될 겁니다.

AWS Lambda 보안 체크리스트 요약 인포그래픽 이미지

글 전체 내용을 한눈에 정리한 AWS Lambda 보안 체크리스트 요약 이미지입니다. 운영 전 최종 점검용으로 보기 좋습니다.

FAQ: 자주 헷갈리는 질문

Q1. Lambda 환경 변수 암호화만 쓰면 충분한가요?

간단한 내부 용도라면 도움이 되지만, 운영에선 Secrets Manager 같은 전용 비밀정보 저장소를 쓰는 쪽이 더 낫습니다. 접근 제어와 교체 관리가 훨씬 명확합니다.

Q2. 모든 Lambda를 VPC 안에 넣어야 하나요?

아닙니다. 프라이빗 리소스 접근이 필요한 경우에만 검토하세요. 무조건 넣는다고 보안이 자동으로 좋아지는 건 아닙니다.

Q3. 서버리스 보안에서 가장 먼저 볼 항목 하나만 꼽자면요?

저는 IAM 최소 권한을 먼저 봅니다. 이유는 사고가 났을 때 피해 범위를 가장 직접적으로 줄여주기 때문입니다.

Q4. AWS Lambda 베스트 프랙티스는 어디까지가 필수인가요?

최소 권한, 비밀정보 분리, 로깅, 호출 경로 통제는 사실상 필수라고 보시면 됩니다. 나머지는 워크로드 특성에 따라 깊이를 조절하시면 됩니다.

반응형