SaaS 서비스를 위한 Harness AWS 권한 최소화 계정 구성
목차
SaaS 서비스를 AWS 위에 올리고 Harness로 CI/CD를 붙이려면 제일 먼저 고민되는게 AWS 계정을 어떻게 연결할지다.
제일 쉬운건 Access Key 하나 만들고 AdministratorAccess를 붙이는 거다. 근데 운영 서비스에서 그러면 나중에 사고 났을때 영향 범위가 너무 커진다.
Harness가 AWS 리소스를 배포할 수 있게는 하되, 권한은 필요한 만큼만 주는 구성을 정리해 둔다.
기준: Harness Delegate 또는 Harness Platform에서 AWS Connector를 만들고, SaaS 서비스 배포 대상 계정에 제한된 IAM Role을 제공하는 상황
구성 순서
가능하면 아래 순서로 간다.
- IAM User Access Key를 기본값으로 두지 않는다.
- Harness가 AWS에 접근할때는 IAM Role + STS AssumeRole 구조를 먼저 쓴다.
- 외부 SaaS인 Harness가 역할을 위임받는 구조면 External ID를 trust policy에 넣는다.
- 배포 대상별로 Role을 나눈다.
harness-dev-deploy-roleharness-stg-deploy-roleharness-prod-deploy-role
- 처음부터 완벽한 least privilege를 만들려고 하지 말자. 최소 권한으로 시작하고 Access Analyzer/CloudTrail을 보면서 줄인다.
AWS도 IAM 사용자 장기 Access Key 보다는 임시 자격 증명과 Role 사용을 권장한다.
IAM 정책은 필요한 작업만 허용하는 최소 권한 원칙으로 쓰는게 기본이다.
추천 아키텍처
| |
왜 Role인가
Access Key는 한 번 유출되면 회수 전까지 계속 쓸 수 있는 장기 자격 증명이다.
Role 기반 STS 인증은 세션 시간이 제한된 임시 자격 증명을 발급받는다.
target account 쪽에서는 trust policy와 permission policy가 나뉘어 있어서 “누가 assume할 수 있는지"와 “assume한 뒤 뭘 할 수 있는지"를 따로 통제할 수 있다.
Harness AWS Connector도 cross-account role ARN과 External ID를 입력하는 구성을 지원한다.
Connector의 기본 credential이 target account의 role을 assume하고, assume된 role에 실제 배포에 필요한 S3/ECS/EC2/EKS 등의 권한을 붙이는 방식.
계정/역할 설계
개인적으로는 SaaS 운영 환경을 최소한 아래처럼 나누는 쪽이 좋다.
| 구분 | 용도 | Harness 권한 |
|---|---|---|
shared | ECR, 공통 artifact, CI infra | 이미지 push/pull, artifact read/write |
dev | 개발 배포 | 넓게 허용 가능하지만 admin은 지양 |
stg | 운영 전 검증 | 운영과 유사하게 제한 |
prod | 실제 고객 트래픽 | 가장 좁은 권한, 승인 단계 필수 |
처음엔 AWS Organizations까지 안 쓰더라도 dev/stg/prod Role은 이름과 정책을 분리해 두자.
나중에 계정을 나누거나 Control Tower를 도입할때 이전 비용이 줄어든다.
Trust policy 예시
외부에서 Harness가 assume할 Role의 trust policy는 아래처럼 시작하면 된다.
| |
여기서 볼건 두 가지.
Principal은 가능한 구체적인 AWS account/role로 제한한다.sts:ExternalId를 넣어 confused deputy 문제를 줄인다.
External ID는 비밀번호처럼 숨기는 값은 아니다.
다만 제3자가 여러 고객 계정에 접근하는 상황에서 “이 assume 요청이 우리 계정을 위한 요청인지” 구분하는 방어선으로 쓸 수 있다.
Permission policy 예시: ECS 배포
서비스가 ECS/Fargate 기반이라고 치면 Harness 배포 Role은 대략 아래 권한에서 시작하면 된다.
| |
실제 운영에서는 Resource: "*"를 최대한 줄이는게 좋다.
근데 ECR의 GetAuthorizationToken처럼 리소스 제한이 어려운 action도 있다.
그래서 처음엔 동작만 확인하고 repository ARN, cluster ARN, service ARN으로 조금씩 좁혀 간다.
Permission policy 예시: Terraform/IaC
Harness에서 Terraform으로 VPC, ECS, RDS까지 만들 생각이면 권한 범위가 훨씬 커진다.
이럴땐 Role 하나에 다 몰아주지 말고 아래처럼 나눈다.
| Role | 책임 |
|---|---|
harness-iac-plan-role | terraform plan, read 중심 |
harness-iac-apply-role | terraform apply, 승인 후 사용 |
harness-app-deploy-role | 애플리케이션 이미지/서비스 배포 |
iam:*, organizations:*, account:*, kms:* 같은 권한은 처음부터 열지 않는다.
필요해도 특정 path, prefix, tag condition을 붙여서 제한한다.
Harness Connector 설정 순서
- AWS IAM에서 target account에
harness-prod-deploy-role을 만든다. - Trust policy에 Harness 쪽 principal과 External ID를 넣는다.
- Permission policy는 배포 방식(ECS/EKS/Lambda/Terraform)에 맞춰 최소 권한으로 붙인다.
- Harness에서 AWS Connector를 만든다.
- 인증 방식으로 cross-account role ARN 또는 delegate 기반 AssumeRole 구성을 선택한다.
- External ID를 입력한다.
- Test connection을 실행한다.
- 실패한 action만 CloudTrail이나 Harness 로그에서 확인해서 정책에 추가
Harness 문서 기준으로 AWS Connector의 connection test에는 기본적으로
ec2:DescribeRegions가 필요할 수 있다고 한다. 테스트가 실패했는데 배포 권한 문제 같지 않으면 이 action이 빠졌는지도 같이 보자.
운영 체크리스트
- root 계정 MFA 활성화
- Harness용 장기 Access Key를 만들었다면 만료/회전 주기 지정
- prod Role에는 배포에 필요한 action만 허용
-
iam:PassRole은 특정 task role/execution role만 허용 - External ID 사용
- CloudTrail 활성화
- IAM Access Analyzer로 외부 접근과 미사용 권한 점검
- prod 배포 파이프라인에는 Harness approval 또는 Change Management 단계 추가
- dev/stg/prod Connector 분리
- break-glass 관리자 계정은 별도 관리하고 평소에는 사용하지 않기
내가 잡은 원칙
SaaS 서비스 CI/CD 권한은 “배포 자동화가 편해야 한다"와 “사고가 나도 blast radius가 작아야 한다” 사이 어딘가인듯.
일단 아래 원칙으로 시작하려고 한다.
- Harness에는 admin 권한을 주지 않는다.
- 사람이 쓰는 계정과 자동화가 쓰는 Role을 분리한다.
- 배포 Role은 환경별로 나눈다.
PassRole과KMS권한은 특히 보수적으로 관리한다.- 처음에는 배포 성공이 목표. 성공하면 바로 Access Analyzer/CloudTrail 기반으로 권한을 줄인다.