Overview
데이터베이스 운영에서 가장 흔하면서도 위험한 부분 중 하나가 비밀번호 관리이다. 소스 코드에 하드코딩되거나, `.env` 파일이 Git에 올라가거나, 팀원 간에 메신저로 공유되는 경우를 한 번쯤은 경험해보셨을 거다.
특히 개인정보를 다루는 시스템이라면 KISA의 개인정보 안전성 확보조치 기준에 따라 비밀번호 복잡도 요건과 주기적 로테이션이 법적으로 요구된다.
AWS RDS IAM 인증은 이 문제에 대한 근본적인 해결책이다. 데이터베이스에 접속할 때 고정된 비밀번호 대신 15분짜리 임시 인증 토큰을 발급받아 사용하는 방식으로, 비밀번호 유출 리스크를 원천적으로 제거한다.
이 글에서는 RDS IAM 인증의 동작 원리부터 설정 방법, 다른 비밀번호 관리 방식과의 비교, 그리고 Lambda/EKS 같은 컴퓨팅 환경에서의 실제 적용까지 폭넓게 다룬다.

기존 비밀번호 인증의 문제점
데이터베이스 접근은 기본적으로 계정과 비밀번호 기반 인증을 사용한다. 이 방식의 근본적인 문제는 비밀번호가 고정된 문자열이라는 점이다.
비밀번호 유출 경로는 생각보다 다양하다.
- 코드 레벨: `.env` 파일이 `.gitignore` 에서 빠져 Git에 커밋되거나, Docker 이미지에 비밀번호가 빌드 타임에 포함되는 경우
- 운영 레벨: CI/CD 파이프라인 로그에 환경변수가 노출되거나, 퇴사자가 비밀번호를 알고 있는 상태로 조직을 떠나는 경우
- 커뮤니케이션: Slack이나 이메일로 비밀번호를 공유하다가 메시지 히스토리에 남는 경우
이런 문제를 해결하는 접근법은 크게 두 가지이다.
- 주기적 비밀번호 로테이션: AWS Secrets Manager 등을 활용해 자동 교체
- 임시 자격 증명 사용: 접속할 때마다 짧은 유효기간의 토큰을 발급받아 사용
RDS IAM 인증은 두 번째 접근법에 해당한다.
Secrets Manager vs IAM 인증: 어떤 걸 써야 할까?
비밀번호 관리 문제를 해결하는 AWS 서비스는 RDS IAM 인증만 있는 게 아니다. AWS Secrets Manager도 널리 사용된다. 두 방식은 접근 철학이 다르다.
| 비교 항목 | Secrets Manager | RDS IAM 인증 |
| 인증 방식 | 비밀번호를 안전하게 저장·교체 | 비밀번호 자체를 사용하지 않음 |
| 자격 증명 수명 | 교체 주기에 따라 다름 (보통 30~90일) | 15분 |
| 비용 | Secret당 $0.40/월 + API 호출 비용 | 무료 (IAM API 호출) |
| 연결 제한 | 없음 | 초당 200건 |
| 지원 엔진 | 모든 RDS 엔진 | MySQL, PostgreSQL, MariaDB만 |
| Oracle/SQL Server | 지원 | 미지원 |
| 적합한 시나리오 | 높은 연결 빈도, 다양한 엔진 | 서버리스, 컨테이너 환경 |
Secrets Manager는 비밀번호를 "잘 관리"하는 접근이고, IAM 인증은 비밀번호를 "아예 없애는" 접근이다.
초당 200건 이내의 인증 요청이고 MySQL/PostgreSQL을 사용한다면 IAM 인증이 보안 측면에서 더 우수하다. 연결 빈도가 높거나 Oracle/SQL Server를 사용한다면 Secrets Manager가 적합하다.
실무에서는 두 방식을 함께 사용하는 경우도 많다. 예를 들어 마스터 계정은 Secrets Manager로 관리하고, 애플리케이션 계정은 IAM 인증으로 접속하는 구성이다.
RDS IAM 인증의 동작 원리
RDS IAM 인증의 흐름은 다음과 같다.
┌──────────┐ ① generate-db-auth-token ┌──────────┐
│ Client │ ──────────────────────────────► │ AWS STS │
│ (App/CLI)│ ◄────────────────────────────── │ │
│ │ ② 임시 인증 토큰 (15분) └──────────┘
│ │
│ │ ③ 토큰을 비밀번호로 사용 ┌──────────┐
│ │ ──────────────────────────────► │ RDS │
│ │ (SSL/TLS 필수) │ Instance │
│ │ ◄────────────────────────────── │ │
└──────────┘ ④ 서명 검증 후 접속 허용 └──────────┘
- 클라이언트가 AWS SDK의 generate-db-auth-token 함수를 호출한다.
- AWS가 IAM 자격 증명을 기반으로 15분간 유효한 임시 인증 토큰을 발급한다.
- 클라이언트는 이 토큰을 비밀번호 대신 사용하여 RDS에 접속한다.
- RDS는 토큰의 서명을 검증하고 접속 허용 여부를 판단한다.
발급되는 임시 토큰은 AWS Signature Version 4로 서명되며, 다음 정보를 포함한다.
- 데이터베이스 호스트명과 포트
- 데이터베이스 사용자명
- 서명 알고리즘
- 유효기간 (900초 = 15분)
- AWS 자격 증명 정보
핵심은 데이터베이스 비밀번호 자체가 인증 과정에서 사용되지 않는다는 점이다. IAM 역할 기반으로 인증이 이루어지기 때문에, 비밀번호를 저장하거나 전달할 필요가 없다.
참고로 IAM 인증을 활성화해도 기존 비밀번호 인증이 비활성화되지는 않는다. 두 방식을 병행할 수 있어 점진적 전환이 가능하다.
알아두어야 할 제한 사항
RDS IAM 인증에는 반드시 숙지해야 할 제약들이 있다.
성능 관련
- 초당 200건의 인증 요청 제한이 있다. 커넥션 풀을 사용하여 인증 요청 빈도를 줄이는 것이 필수이다.
- IAM DB 인증은 데이터베이스 인스턴스의 컴퓨팅 리소스를 사용한다. 안정적인 연결을 위해 인스턴스에 300~1,000 MiB의 추가 메모리가 필요하다.
보안 관련
- 한 번 발급된 토큰을 무효화(revoke)할 수 없다. 다만 15분 후 자동 만료된다.
- SSL/TLS 연결이 필수이다. AWS CA 인증서를 클라이언트에 미리 준비해야 한다.
- IAM Administrator 권한이 있으면 모든 DB 계정의 토큰을 발급받을 수 있으므로 최소 권한 원칙에 따라 IAM 정책을 설계해야 한다.
- CloudWatch와 CloudTrail은 generate-db-auth-token API 호출을 로깅하지 않는다. 토큰 발급 자체는 추적이 어렵다는 점을 인지해야 한다.
호환성 관련
- 지원 엔진은 MySQL, PostgreSQL, MariaDB입니다. Oracle, SQL Server는 미지원이다.
- PostgreSQL에서 IAM 인증과 Kerberos 인증을 동시에 사용할 수 없다.
- IAM 인증으로 복제(Replication) 연결을 설정할 수 없다.
- 커스텀 Route 53 DNS 레코드를 사용해서 토큰을 생성할 수 없다. 반드시 RDS 엔드포인트를 사용해야 한다.
- DBeaver 등 일부 DB IDE가 IAM 인증을 지원하지 않아 매 세션마다 수동으로 토큰을 입력해야 할 수 있다.
PostgreSQL 주의사항
- 기존 비밀번호 인증 계정에 IAM 인증(rds_iam 역할)을 추가하면, IAM 인증 방식이 우선 적용된다. 이렇게 되면 해당 계정으로 비밀번호 로그인이 불가능해져 기존 연결에 장애가 발생할 수 있다.
설정 방법
RDS IAM 인증을 활성화하려면 세 군데를 설정해야 한다.
1. RDS 인스턴스 설정
RDS 콘솔에서 IAM database authentication을 활성화한다. 이 변경은 재부팅 없이 적용된다.
콘솔 방식: RDS Console → DB 인스턴스 선택 → Modify → Database authentication에서 IAM DB Authentication 활성화
AWS CLI 방식
aws rds modify-db-instance \
--db-instance-identifier my-rds-instance \
--enable-iam-database-authentication \
--apply-immediately
Terraform 방식
resource "aws_rds_cluster" "main" {
cluster_identifier = "my-cluster"
iam_database_authentication_enabled = true
# ... 기타 설정
}
# 단일 인스턴스의 경우
resource "aws_db_instance" "main" {
identifier = "my-instance"
iam_database_authentication_enabled = true
# ... 기타 설정
}
2. IAM 정책 설정
IAM Role을 생성하고 `rds-db:connect` 권한을 부여한다. 리소스 ARN에는 RDS 리소스 ID와 데이터베이스 계정을 지정한다.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "rds-db:connect",
"Resource": "arn:aws:rds-db:<region>:<account-id>:dbuser:<dbi-resource-id>/<db-username>"
}
]
}
- 여기서 `<dbi-resource-id>` 는 RDS 인스턴스의 리소스 ID이다 (콘솔의 Configuration 탭에서 확인 가능).
- 인스턴스 ID가 아닌 `dbi-` 또는 `cluster-` 로 시작하는 리소스 ID를 사용해야 한다.
- 특정 계정만 허용하려면 `<db-username>` 에 계정명을 지정하고, 모든 계정을 허용하려면 `*` 를 사용한다. 보안상 특정 계정만 허용하는 것을 권장한다.
3. 데이터베이스 계정 설정
데이터베이스 엔진에 따라 IAM 인증 가능한 계정을 생성한다.
PostgreSQL
-- 새 계정 생성 후 IAM 인증 부여
CREATE USER app_user;
GRANT rds_iam TO app_user;
-- 필요한 데이터베이스/테이블 권한도 함께 부여
GRANT CONNECT ON DATABASE mydb TO app_user;
GRANT USAGE ON SCHEMA public TO app_user;
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO app_user;
MySQL
-- AWSAuthenticationPlugin으로 계정 생성
CREATE USER IF NOT EXISTS 'app_user'@'%' IDENTIFIED WITH AWSAuthenticationPlugin AS 'RDS';
ALTER USER 'app_user'@'%' REQUIRE SSL;
-- 권한 부여
GRANT SELECT, INSERT, UPDATE, DELETE ON mydb.* TO 'app_user'@'%';
FLUSH PRIVILEGES;
실제 적용하기
AWS CLI로 접속 테스트
토큰을 발급받아 직접 접속하는 방식으로 설정이 올바른지 확인할 수 있다.
MySQL
# 임시 인증 토큰 발급
TOKEN=$(aws rds generate-db-auth-token \
--hostname $RDS_HOST \
--port 3306 \
--region ap-northeast-2 \
--username app_user)
# AWS CA 인증서 다운로드 (최초 1회)
wget https://truststore.pki.rds.amazonaws.com/global/global-bundle.pem
# 토큰으로 RDS 접속
mysql -h $RDS_HOST \
--port 3306 \
--ssl-ca=global-bundle.pem \
--user=app_user \
--password="$TOKEN" \
--enable-cleartext-plugin
PostgreSQL
TOKEN=$(aws rds generate-db-auth-token \
--hostname $RDS_HOST \
--port 5432 \
--region ap-northeast-2 \
--username app_user)
PGPASSWORD="$TOKEN" psql -h $RDS_HOST \
--port 5432 \
--username app_user \
--dbname mydb \
"sslmode=verify-full sslrootcert=global-bundle.pem"
Spring Boot 애플리케이션 적용
Spring Boot에서는 `aws-advanced-jdbc-wrapper` 드라이버를 사용하면 토큰 발급과 갱신을 자동으로 처리할 수 있다.
spring:
datasource:
url: jdbc:aws-wrapper:mysql://${RDS_HOST}:${RDS_PORT:3306}/${RDS_DB:mydb}?wrapperPlugins=iam&iamRegion=${AWS_REGION:ap-northeast-2}&sslMode=require
username: ${RDS_USERNAME:app_user}
driver-class-name: software.amazon.jdbc.Driver
hikari:
maximum-pool-size: 10
minimum-idle: 5
max-lifetime: 840000 # 14분 (토큰 만료 15분 전에 갱신)
핵심 포인트는 세 가지이다.
- `wrapperPlugins=iam:` IAM 인증 플러그인 활성화
- `software.amazon.jdbc.Driver:` AWS JDBC 래퍼 드라이버 사용
- `max-lifetime: 840000:` 커넥션 풀의 최대 수명을 토큰 만료(15분)보다 짧게 설정하여 자동 갱신 유도
Lambda에서 사용하기
Lambda는 IAM 역할이 자동으로 부여되므로 RDS IAM 인증과 궁합이 좋다. 별도의 비밀번호 관리 없이 IAM Role만 설정하면 된다.
import boto3
import pymysql
import os
def get_db_connection():
client = boto3.client('rds')
token = client.generate_db_auth_token(
DBHostname=os.environ['RDS_HOST'],
Port=3306,
DBUsername=os.environ['DB_USER'],
Region=os.environ['AWS_REGION']
)
return pymysql.connect(
host=os.environ['RDS_HOST'],
user=os.environ['DB_USER'],
password=token,
database=os.environ['DB_NAME'],
ssl={'ca': '/opt/global-bundle.pem'},
connect_timeout=5
)
- Lambda에서 RDS에 직접 연결하면 동시 실행 수만큼 커넥션이 생성되어 DB에 부하를 줄 수 있다.
- RDS Proxy를 함께 사용하면 커넥션 풀링을 통해 이 문제를 해결할 수 있고, RDS Proxy도 IAM 인증을 지원한다.
EKS에서 사용하기
EKS 환경에서는 IRSA(IAM Roles for Service Accounts)를 활용하여 파드에 IAM 역할을 부여하고, 이를 통해 RDS IAM 인증 토큰을 발급받을 수 있다.
# ServiceAccount에 IAM Role 연결
apiVersion: v1
kind: ServiceAccount
metadata:
name: app-sa
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/rds-iam-role
---
# Pod에서 해당 ServiceAccount 사용
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
template:
spec:
serviceAccountName: app-sa
containers:
- name: app
env:
- name: RDS_HOST
value: "my-cluster.cluster-xxx.ap-northeast-2.rds.amazonaws.com"
- name: DB_USER
value: "app_user"
- 애플리케이션 코드에서는 Lambda와 동일하게 `generate-db-auth-token` 으로 토큰을 발급받아 사용한다.
- IRSA를 통해 파드에 자동으로 AWS 자격 증명이 주입되므로 별도의 Access Key 관리가 필요 없다.
마이그레이션 전략
기존에 비밀번호 인증을 사용 중인 서비스에 IAM 인증을 도입할 때는 주의가 필요하다. 특히 PostgreSQL에서는 같은 계정에 `rds_iam` 역할을 부여하면 IAM 방식이 우선 적용되어 기존 비밀번호 기반 연결이 즉시 끊길 수 있다.
안전한 무중단 마이그레이션 절차는 다음과 같다.
- RDS 인스턴스에서 `IAM database authentication` 을 활성화 (기존 연결에 영향 없음)
- IAM 인증 전용 새 데이터베이스 계정을 생성하고 `rds_iam` 역할 부여
- 새 계정에 기존 계정과 동일한 테이블/스키마 권한을 부여
- IAM 정책과 Role을 구성
- 스테이징 환경에서 충분히 테스트
- 애플리케이션을 새 계정으로 전환 배포
- 안정성이 확인되면 기존 비밀번호 계정을 비활성화
두 계정을 병행 운영하면 문제 발생 시 기존 계정으로 즉시 롤백할 수 있어 무중단 전환이 가능하다. 기존 계정에 직접 `rds_iam` 을 부여하는 것은 위험하므로 반드시 피해야 한다.
모니터링
RDS IAM 인증은 CloudWatch 메트릭을 통해 모니터링할 수 있다. 특히 다음 항목을 추적하는 것이 좋다.
- DatabaseConnections: 현재 활성 연결 수. 200 TPS 제한에 근접하는지 확인
- FailedConnectionAttempts: 인증 실패 횟수. 비정상적 증가 시 알람 설정
- Enhanced Monitoring의 프로세스 목록: IAM 인증 활성화 전후의 메모리 사용량(RES 컬럼) 비교
다만 `generate-db-auth-token` API 호출 자체는 CloudTrail에 기록되지 않는다는 점을 인지해야 한다. 토큰 발급 추적이 필요하다면 애플리케이션 레벨에서 별도 로깅을 구현해야 한다.
마무리
RDS IAM 인증은 데이터베이스 보안을 근본적으로 개선하는 실용적인 방법이다. 비밀번호를 아예 사용하지 않으니 유출 걱정이 없고, IAM 정책으로 접근 제어를 중앙에서 관리할 수 있으며, 15분 단위 토큰 만료로 자격 증명의 수명을 최소화한다.
특히 Lambda, ECS, EKS 같은 컨테이너/서버리스 환경과 궁합이 좋다. 이런 환경에서는 IAM Role이 자동으로 부여되기 때문에, 별도의 비밀번호 저장소 없이도 안전한 데이터베이스 접근이 가능하다.
물론 초당 200건의 인증 제한, 인스턴스 추가 메모리 요구, PostgreSQL 마이그레이션 시 우선순위 문제 등 제약 사항을 잘 이해하고 적용해야 한다. 고빈도 연결 환경이라면 RDS Proxy를 함께 구성하거나, Secrets Manager와 병행하는 하이브리드 전략도 고려해볼 만하다.
이미 AWS 위에서 서비스를 운영하고 있다면, 새로운 프로젝트부터 RDS IAM 인증을 기본값으로 적용해보시길 추천한다.
Reference
- AWS 공식 문서 - IAM Database Authentication for MariaDB, MySQL, and PostgreSQL
- AWS 공식 문서 - Connecting to your DB instance using IAM authentication
- AWS Blog - Securing Amazon RDS and Aurora PostgreSQL with IAM Authentication
- AWS Blog - Using IAM Authentication with pgAdmin
- AWS Blog - How to choose the right AWS service for managing secrets and configurations
- AWS Blog - Rotate Amazon RDS database credentials automatically with AWS Secrets Manager
- AWS Advanced JDBC Wrapper - IAM Plugin
- RDS IAM Authentication from EKS
- KISA 개인정보의 안전성 확보조치 기준
Somaz | DevOps Engineer | Kubernetes & Cloud Infrastructure Specialist
'AWS' 카테고리의 다른 글
| EKS 무중단 배포 — lifecycle(preStop) · Pod Readiness Gatestrategy(RollingUpdate) · PodDisruptionBudget (1) | 2026.07.09 |
|---|---|
| EKS Pod Identity vs IRSA: 파드에 IAM 권한을 주는 두 가지 방식 (0) | 2026.06.30 |
| Karpenter on EKS: Terraform과 Helm으로 구성하는 2계층 설정 (0) | 2026.06.16 |
| AWS 모니터링 스택 완전 분석 - CloudWatch vs X-Ray vs 3rd Party 솔루션 (0) | 2026.04.21 |
| AWS Lambda vs ECS vs EKS 컨테이너 전략 (0) | 2026.04.14 |