<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>lhywk 님의 블로그</title>
    <link>https://lhywk.tistory.com/</link>
    <description>lhywk 님의 블로그 입니다.</description>
    <language>ko</language>
    <pubDate>Sun, 31 May 2026 22:36:33 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>lhywk</managingEditor>
    <item>
      <title>LexisNexis 사고 사례 분석</title>
      <link>https://lhywk.tistory.com/111</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. 개요&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2026년 2월 24일 글로벌 법률 데이터 기업인 &lt;b&gt;LexisNexis Legal &amp;amp; Professional&lt;/b&gt;의 AWS 클라우드 인프라가 &lt;b&gt;FulcrumSec&lt;/b&gt;이라는 위협 행위자에 의해 침해되었습니다. 이 사고는 2026년 3월 3일 FulcrumSec이 약 &lt;b&gt;2.04GB 분량의 데이터를 언더그라운드 포럼에 공개 유출&lt;/b&gt;하면서 세상에 알려졌으며, LexisNexis는 이튿날인 3월 4일 침해 사실을 공식 확인하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LexisNexis는 법률, 규제, 비즈니스 정보를 전 세계 150개국 이상에서 제공하는 글로벌 데이터 기업으로, Fortune 100 기업의 91%, Fortune 500 기업의 85%를 고객으로 두고 있습니다. 이번 사고는 단순한 데이터 유출을 넘어, &lt;b&gt;미패치 취약점 방치, 과도한 클라우드 권한, 평문 자격증명 저장&lt;/b&gt;이라는 클라우드 보안의 고질적인 문제가 복합적으로 작용한 사례입니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;사고 요약&lt;/h3&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;항목&amp;nbsp;&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;내용&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;공격 행위자&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;FulcrumSec&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;최초 침투 일시&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;2026년 2월 24일&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;공개 유출 일시&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;2026년 3월 3일 (BreachForums)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;공식 확인 일시&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;2026년 3월 4일&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;초기 침투 경로&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;React2Shell 취약점 (미패치 React 프론트엔드 앱)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;유출 데이터 규모&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;약 2.04GB, 390만 건 레코드&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;영향받은 계정&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;약 400,000개 사용자 프로필, 21,042개 기업 고객 계정&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;주요 피해&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Redshift DB, VPC 인프라 맵, AWS Secrets Manager 평문 자격증명 등&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. 공격 분석&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2.1 초기 접근: React2Shell 취약점 익스플로잇&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공격자 FulcrumSec은 LexisNexis의 AWS 환경에서 운영 중이던 &lt;b&gt;미패치 React 프론트엔드 애플리케이션&lt;/b&gt;을 타깃으로 삼았습니다. 이 앱에는 &lt;b&gt;React2Shell&lt;/b&gt;이라는 알려진 보안 취약점이 존재하고 있었으며, 공격자는 이를 익스플로잇하여 AWS 인프라에 대한 비인가 접근 권한을 최초로 획득하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;React2Shell은 특정 미패치 React 프론트엔드 애플리케이션에 존재하는 보안 결함으로, 이미 공개된 익스플로잇 코드가 존재함에도 불구하고 수개월간 패치가 이루어지지 않은 상태로 방치되어 있었습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2.2 권한 남용: 과도한 ECS 태스크 역할&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;초기 접근에 성공한 공격자는 해당 컨테이너에 연결된 &lt;b&gt;ECS 태스크 역할&lt;/b&gt;을 발견하였습니다. 문제는 이 단일 태스크 역할이 AWS 계정 내 &lt;b&gt;모든 Secrets Manager 시크릿에 대한 읽기 권한&lt;/b&gt;을 보유하고 있었다는 점입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 최소 권한 원칙이 전혀 적용되지 않은 상태로, 공격자는 단 하나의 컨테이너를 침해하는 것만으로 프로덕션 데이터베이스 자격증명을 포함한 핵심 비밀 정보 전체에 접근할 수 있었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공격자가 탈취한 주요 정보는 다음과 같습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;AWS Secrets Manager&lt;/b&gt;: 53개의 평문 시크릿 (프로덕션 Redshift 마스터 자격증명, Salesforce&amp;middot;Oracle&amp;middot;분석 플랫폼용 API 키 포함)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Redshift&lt;/b&gt;: 536개 테이블&lt;/li&gt;
&lt;li&gt;&lt;b&gt;VPC 데이터베이스&lt;/b&gt;: 430개 이상의 테이블&lt;/li&gt;
&lt;li&gt;&lt;b&gt;VPC 인프라 맵&lt;/b&gt;: 내부 네트워크 구성 전체&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2.3 데이터 유출: 390만 건 레코드 탈취&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1695&quot; data-origin-height=&quot;909&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bEDhGE/dJMcacb6jq3/rUg0Tmhh7y8SF4FZ1J84Ok/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bEDhGE/dJMcacb6jq3/rUg0Tmhh7y8SF4FZ1J84Ok/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bEDhGE/dJMcacb6jq3/rUg0Tmhh7y8SF4FZ1J84Ok/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbEDhGE%2FdJMcacb6jq3%2FrUg0Tmhh7y8SF4FZ1J84Ok%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1695&quot; height=&quot;909&quot; data-origin-width=&quot;1695&quot; data-origin-height=&quot;909&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공격자는 2026년 2월 24일부터 3월 초 사이에 총 &lt;b&gt;2.04GB 규모의 구조화된 데이터&lt;/b&gt;를 유출하였습니다. 유출된 데이터의 세부 내역은 다음과 같습니다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;유출 데이터&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;규모/내용&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;전체 DB 레코드&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;약 390만 건&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;기업 고객 계정&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;21,042개 (로펌, 법원, 규제기관, 연방 정부 기관 등)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;클라우드 사용자 프로필&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;약 400,000개 (이름, 이메일, 전화번호, 직무 포함)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;정부 이메일(.gov) 프로필&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;118개 (연방 판사, DOJ 검사, SEC 직원 등)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;변호사 설문 응답자&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;5,582명&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;직원 패스워드 해시&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;45개&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;AWS Secrets Manager 시크릿&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;53개 (평문)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LexisNexis 측은 침해된 데이터가 &lt;b&gt;2020년 이전의 레거시, 비활성화 서버&lt;/b&gt;에 있던 정보임을 확인하였으며, 주민등록번호, 운전면허번호, 금융 데이터, 활성 패스워드, 고객 검색 질의 등 민감한 PII는 포함되지 않았다고 밝혔습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2.4 공격 기법 분류 (MITRE ATT&amp;amp;CK)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 공격에서 사용된 기법은 MITRE ATT&amp;amp;CK 프레임워크 기준으로 다음과 같이 분류됩니다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;T1190&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Exploit Public-Facing Application&lt;/td&gt;
&lt;td&gt;React2Shell 취약점 익스플로잇&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;T1078&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Valid Accounts&lt;/td&gt;
&lt;td&gt;ECS 태스크 역할 자격증명 남용&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;T1552.001&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Unsecured Credentials: Credentials in Files&lt;/td&gt;
&lt;td&gt;AWS Secrets Manager 평문 시크릿 탈취&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;T1530&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Data from Cloud Storage Object&lt;/td&gt;
&lt;td&gt;Redshift 및 VPC DB 데이터 유출&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;T1041&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Exfiltration Over C2 Channel&lt;/td&gt;
&lt;td&gt;AWS 환경에서 데이터 외부 반출&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2.5 공격 타임라인&lt;/h3&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;날짜&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;주요 이벤트&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;2026년 2월 24일&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;FulcrumSec, React2Shell 취약점으로 AWS 환경 최초 침투&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;2026년 2월 24일 ~ 3월 초&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Redshift, VPC DB, Secrets Manager 데이터 유출 (2.04GB)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;2026년 3월 3일&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;FulcrumSec, BreachForums에 매니페스토 및 유출 데이터 공개&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;2026년 3월 3일&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;LexisNexis, BleepingComputer에 침해 사실 확인&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;2026년 3월 4일&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;LexisNexis, 공식 성명 발표 - 사고 봉쇄 완료, 서비스 영향 없음 확인&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. 대응 방안&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3.1 인터넷 노출 애플리케이션 즉시 패치&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 사고의 출발점은 &lt;b&gt;알려진 취약점(React2Shell)이 오랜 기간 패치되지 않은 것&lt;/b&gt;이었습니다. 공개 취약점 데이터베이스(NVD, CVE)와 벤더 보안 공지를 지속적으로 모니터링하고, 인터넷에 노출된 모든 애플리케이션에 대해 신속한 패치를 적용해야 합니다. 특히 컨테이너 기반 환경에서는 베이스 이미지와 애플리케이션 의존성 모두에 대한 취약점 스캔을 자동화하는 것이 중요합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3.2 ECS 태스크 역할 최소 권한 원칙 적용&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 사고에서 &lt;b&gt;단일 ECS 태스크 역할이 AWS 계정 전체 시크릿에 대한 읽기 권한&lt;/b&gt;을 보유하고 있었다는 점은 설계 오류입니다. 각 ECS 태스크에는 해당 태스크가 실제로 필요로 하는 시크릿에만 접근을 허용하는 별도의 역할을 부여해야 하며 IAM 정책의 리소스(Resource) 필드를 * 대신 특정 ARN으로 제한해야 합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3.3 AWS Secrets Manager 자격증명 교체 및 접근 감사&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;탈취된 53개의 시크릿이 &lt;b&gt;평문으로 저장&lt;/b&gt;되어 있었다는 점은 자격증명 관리 체계의 부재를 보여줍니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;자동 교체 활성화&lt;/b&gt;: AWS Secrets Manager의 자동 교체 기능을 사용하면 키가 유출되더라도 짧은 유효 기간 내에 무력화됩니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;시크릿 접근 감사&lt;/b&gt;: CloudTrail과 연동하여 모든 GetSecretValue 호출을 로깅하고, 이상 행위 발생 시 즉시 알림을 받도록 설정합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;참고 자료&lt;/h2&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;The Register&lt;/b&gt; - LexisNexis Legal &amp;amp; Professional confirms data breach&lt;br /&gt;&lt;a href=&quot;https://www.theregister.com/2026/03/04/lexisnexis_legal_professional_confirms_data/&quot;&gt;https://www.theregister.com/2026/03/04/lexisnexis_legal_professional_confirms_data/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;BleepingComputer&lt;/b&gt; - LexisNexis confirms data breach as hackers leak stolen files&lt;br /&gt;&lt;a href=&quot;https://www.bleepingcomputer.com/news/security/lexisnexis-confirms-data-breach-as-hackers-leak-stolen-files/&quot;&gt;https://www.bleepingcomputer.com/news/security/lexisnexis-confirms-data-breach-as-hackers-leak-stolen-files/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Rescana&lt;/b&gt; - LexisNexis AWS Data Breach 2026: React2Shell Exploit Exposes Legacy Data in Cloud Hack&lt;br /&gt;&lt;a href=&quot;https://www.rescana.com/post/lexisnexis-aws-data-breach-2026-react2shell-exploit-exposes-legacy-data-in-cloud-hack&quot;&gt;https://www.rescana.com/post/lexisnexis-aws-data-breach-2026-react2shell-exploit-exposes-legacy-data-in-cloud-hack&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Cybernews&lt;/b&gt; - Hackers claim LexisNexis breach exposing 400K users, including federal judges&lt;br /&gt;&lt;a href=&quot;https://cybernews.com/security/lexisnexis-breach-400k-users-gov-accounts-aws/&quot;&gt;https://cybernews.com/security/lexisnexis-breach-400k-users-gov-accounts-aws/&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;</description>
      <category>AWS</category>
      <category>AWS 사고 사례 분석</category>
      <author>lhywk</author>
      <guid isPermaLink="true">https://lhywk.tistory.com/111</guid>
      <comments>https://lhywk.tistory.com/111#entry111comment</comments>
      <pubDate>Wed, 20 May 2026 03:03:12 +0900</pubDate>
    </item>
    <item>
      <title>AWS Security Hub</title>
      <link>https://lhywk.tistory.com/110</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;들어가며&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;소규모 아키텍처에서는 CloudWatch Alarm + SNS로 이상 징후를 이메일로 받는 구조가 충분히 효과적입니다. 하지만 계정 수가 늘고, 서비스가 다양해지고, 컴플라이언스 요건이 생기는 &lt;b&gt;중대규모 환경&lt;/b&gt;에서는 근본적인 질문이 생깁니다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;GuardDuty, Inspector, Macie, Config, Access Analyzer&amp;hellip; 각각 콘솔을 따로 봐야 하나? 이 findings들을 어떻게 한 곳에서 관리하지?&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 답이 바로 &lt;b&gt;AWS Security Hub&lt;/b&gt;입니다. 이 글에서는 Security Hub의 개념부터 최신 진화 방향, 멀티 계정 아키텍처, 실전 자동화까지 체계적으로 정리합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. Security Hub가 무엇인지, 먼저 정확히 이해하자&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1.1 탄생 배경: &quot;보안 시그널이 너무 분산되어 있다&quot;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS에는 목적별 보안 서비스가 많습니다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;서비스&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;역할&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;Amazon GuardDuty&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;위협 탐지 (비정상 API 호출, 네트워크 이상 등)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;Amazon Inspector&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;취약점 관리 (EC2 CVE, ECR 이미지 스캔)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;Amazon Macie&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;민감 데이터 탐지 (S3 내 PII 등)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;IAM Access Analyzer&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;외부에 노출된 리소스 탐지&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;AWS Config&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;리소스 구성 변경 추적 및 규정 준수 평가&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 서비스가 개별 콘솔에서 findings를 생성합니다. 10개 계정, 5개 리전 환경이라면 모니터링 포인트가 기하급수적으로 늘어납니다. 이 문제를 해결하기 위해 Security Hub가 만들어졌습니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1.2 Security Hub의 핵심 역할 3가지&lt;/h4&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;[분산된 보안 서비스들]          [Security Hub]           [대응]
GuardDuty  ────────────┐
Inspector  ────────────┤──&amp;rarr;  집계 + 정규화  ──&amp;rarr;  우선순위 기반 대응
Macie      ────────────┤     상관관계 분석        EventBridge 자동화
Config     ────────────┤     통합 가시성          SIEM/SOAR 연동
3rd-party  ────────────┘&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 통합 집계&lt;/b&gt;: 모든 findings를 ASFF(AWS Security Finding Format)로 정규화&lt;br /&gt;&lt;b&gt;2. 보안 상태 평가&lt;/b&gt;: CIS, PCI DSS, NIST 등 컴플라이언스 기준으로 자동 점검&lt;br /&gt;&lt;b&gt;3. 자동화 연동&lt;/b&gt;: EventBridge를 통한 자동 remediation 트리거&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1.3 ASFF (AWS Security Finding Format)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Security Hub가 강력한 이유 중 하나는 &lt;b&gt;모든 finding을 단일 포맷으로 정규화&lt;/b&gt;한다는 점입니다.&lt;/p&gt;
&lt;pre class=&quot;nimrod&quot;&gt;&lt;code&gt;{
  &quot;SchemaVersion&quot;: &quot;2018-10-08&quot;,
  &quot;Id&quot;: &quot;account-id/region/finding-id&quot;,
  &quot;ProductArn&quot;: &quot;arn:aws:securityhub:ap-northeast-2::product/aws/guardduty&quot;,
  &quot;GeneratorId&quot;: &quot;arn:aws:guardduty:...&quot;,
  &quot;AwsAccountId&quot;: &quot;123456789012&quot;,
  &quot;Types&quot;: [&quot;TTPs/Initial Access/UnauthorizedAccess&quot;],
  &quot;Severity&quot;: {
    &quot;Label&quot;: &quot;HIGH&quot;,
    &quot;Normalized&quot;: 70
  },
  &quot;Resources&quot;: [...],
  &quot;Compliance&quot;: {...}
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GuardDuty finding이든, Inspector finding이든, 써드파티 SIEM finding이든 모두 동일한 스키마로 처리됩니다. 별도 파싱 로직 없이 단일 쿼리로 전체 보안 이벤트를 조회할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. Security Hub의 진화: CSPM &amp;rarr; Unified Security Solution&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2025년 기준으로 Security Hub는 단순한 findings 집계 도구를 넘어 대규모 전환을 거쳤습니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2.1 브랜드 분리: Security Hub CSPM vs. Security Hub (통합 솔루션)&lt;/h4&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;구분&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;내용&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;Security Hub CSPM&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;기존 Security Hub의 핵심 기능 &amp;mdash; 보안 표준 점검, findings 집계, 컴플라이언스 평가&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;AWS Security Hub (통합)&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;CSPM + GuardDuty + Inspector + Macie를 하나의 콘솔에서 통합 운영. 신호 간 자동 상관관계 분석 추가&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쉽게 말하면, &lt;b&gt;Security Hub CSPM은 이제 더 큰 Security Hub 통합 솔루션의 일부&lt;/b&gt;가 되었습니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2.2 핵심 신기능: Near Real-Time Risk Analytics&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존에는 GuardDuty finding과 Inspector finding이 각각 따로 존재했습니다. 이제는 Security Hub가 이 신호들을 &lt;b&gt;자동으로 상관관계 분석&lt;/b&gt;하여 하나의 actionable insight로 만들어줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;예시 시나리오&lt;/b&gt;:&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;[기존 방식]
GuardDuty: &quot;EC2 인스턴스에서 비정상 API 호출 탐지&quot; (별도 콘솔)
Inspector:  &quot;동일 EC2에 CVE-2024-XXXX 취약점 존재&quot; (별도 콘솔)
Macie:      &quot;연결된 S3 버킷에 PII 데이터 존재&quot; (별도 콘솔)
&amp;rarr; 수동 상관관계 분석 필요, 우선순위 판단 어려움

[Security Hub 통합 방식 (2025~)]
Security Hub: &quot;CRITICAL &amp;mdash; 외부 노출된 취약한 EC2가 민감 데이터에 접근 중&quot;
&amp;rarr; 자동 상관관계 분석 &amp;rarr; 즉시 우선순위화 &amp;rarr; EventBridge 자동화 트리거&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2.3 2026년 3월 최신 업데이트: CloudWatch 통합&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2026년 3월 31일 발표된 신기능으로, &lt;b&gt;Security Hub CSPM findings를 CloudWatch Logs로 직접 수집&lt;/b&gt;할 수 있게 되었습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;ASFF 및 OCSF(Open Cybersecurity Schema Framework) 포맷 지원&lt;/li&gt;
&lt;li&gt;CloudWatch Logs Insights로 finding 쿼리 가능&lt;/li&gt;
&lt;li&gt;조직 전체 또는 특정 계정에 자동 활성화 가능&lt;/li&gt;
&lt;li&gt;S3 Tables 연동으로 장기 분석 지원&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. 멀티 계정 아키텍처: Security Hub를 제대로 설계하는 방법&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Security Hub를 제대로 쓰려면 &lt;b&gt;멀티 계정 + 멀티 리전 설계&lt;/b&gt;를 이해해야 합니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3.1 전체 계정 구조&lt;/h4&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;Management Account (루트)
├── Security Account &amp;larr; Security Hub 위임 관리자 (Delegated Admin)
│     ├── 전 계정 findings 집계 뷰
│     ├── 보안 표준 중앙 설정
│     └── EventBridge &amp;rarr; Lambda 자동화
├── Log Archive Account
│     └── CloudTrail, VPC Flow Logs, Security Hub findings 장기 저장
├── Production Account
│     └── Security Hub 멤버 (findings 생성)
├── Staging Account
│     └── Security Hub 멤버
└── Development Account
      └── Security Hub 멤버&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3.2 핵심 설정: Delegated Administrator&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Management Account에서 Security Account를 Security Hub 위임 관리자로 지정합니다.&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;# Management Account에서 실행
aws organizations enable-aws-service-access \
  --service-principal securityhub.amazonaws.com

aws securityhub enable-organization-admin-account \
  --admin-account-id &amp;lt;security-account-id&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위임 관리자로 지정하면:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Management Account 자체는 보안 운영에서 분리 (최소 권한 원칙)&lt;/li&gt;
&lt;li&gt;Security Account에서 전 멤버 계정의 findings를 통합 조회&lt;/li&gt;
&lt;li&gt;신규 계정 생성 시 자동으로 Security Hub 활성화&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3.3 Cross-Region Aggregation: 리전 통합&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Security Hub는 &lt;b&gt;리전 단위 서비스&lt;/b&gt;입니다. 멀티 리전 환경이라면 반드시 집계 리전(Aggregation Region)을 설정해야 합니다.&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;[ap-northeast-2 (서울)] &amp;larr; Aggregation Region (집계 리전)
      &amp;uarr;
[us-east-1]  [ap-southeast-1]  [eu-west-1]
(Linked Regions)

모든 findings가 서울 리전으로 실시간 동기화
&amp;rarr; 단일 콘솔에서 전 리전 보안 현황 조회
&amp;rarr; EventBridge도 서울 리전 하나만 구독하면 됨&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;설정 방법&lt;/b&gt; (Security Hub 관리자 계정, 집계 리전에서):&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;aws securityhub create-finding-aggregator \
  --region-linking-mode ALL_REGIONS \
  --region ap-northeast-2&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3.4 Central Configuration Policy: 표준 일괄 적용&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Security Hub CSPM에서 중요한 개념입니다. Security Account에서 보안 표준과 설정을 &lt;b&gt;조직 전체에 일괄 적용&lt;/b&gt;할 수 있습니다.&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;Security Account (Delegated Admin)
└── Central Configuration Policy
      ├── 활성화 범위: 전체 OU 또는 특정 계정
      ├── 활성화 리전: 전체 또는 지정
      ├── 적용 표준: AWS FSBP (필수), CIS v3.0, PCI DSS v4.0
      └── 신규 계정: 자동 적용&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 하면 새 계정이 생성될 때 자동으로 Security Hub가 활성화되고 표준이 적용됩니다. 수동으로 각 계정마다 설정할 필요가 없습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4. Security Standards: 어떤 표준을 활성화해야 하나?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Security Hub CSPM은 리소스를 여러 보안 표준(Security Standards)에 따라 자동 평가합니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;4.1 지원 표준 목록&lt;/h4&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;표준&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;설명&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;권장 환경&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;AWS Foundational Security Best Practices (FSBP)&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;AWS가 자체 개발한 기준. 273개 이상의 controls&lt;/td&gt;
&lt;td&gt;모든 환경 필수&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;CIS AWS Foundations Benchmark v3.0&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;독립 기관 CIS의 AWS 보안 기준&lt;/td&gt;
&lt;td&gt;금융, 공공기관&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;PCI DSS v4.0&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;카드 결제 데이터 보안 표준&lt;/td&gt;
&lt;td&gt;핀테크, 커머스&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;NIST SP 800-53 Rev. 5&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;미국 정부 보안 프레임워크&lt;/td&gt;
&lt;td&gt;공공, 규제 산업&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;ISO 27001:2022&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;국제 정보보안 관리 표준&lt;/td&gt;
&lt;td&gt;글로벌 서비스&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;4.2 Security Score: 우선순위 판단 기준&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 표준에 대해 Security Hub는 &lt;b&gt;Security Score (0~100점)&lt;/b&gt;를 계산합니다.&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;Security Score = 통과한 Controls 수 / 전체 활성 Controls 수 &amp;times; 100

예시:
- 전체 활성 controls: 200개
- 통과(PASSED): 160개
- 실패(FAILED): 40개
- Score: 80점&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;점수는 멀티 계정, 멀티 리전 환경에서 집계 리전 기준으로 전체 통합 점수를 보여줍니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;4.3 실전 팁: 표준 활성화 시 노이즈 관리&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음 Security Hub를 활성화하면 findings가 수백 개 쏟아집니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;노이즈를 줄이는 핵심 전략:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 환경별 표준 분리 적용&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;less&quot;&gt;&lt;code&gt;Production OU  &amp;rarr; AWS FSBP + CIS v3.0 + PCI DSS (엄격)
Development OU &amp;rarr; AWS FSBP만 적용 (기본)
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. Automation Rules로 알려진 허용 항목 suppress&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;// 예: Dev 계정의 특정 S3 버킷 Public Access 경고 suppress
{
  &quot;RuleName&quot;: &quot;suppress-dev-public-bucket&quot;,
  &quot;Criteria&quot;: {
    &quot;AwsAccountId&quot;: [&quot;dev-account-id&quot;],
    &quot;ResourceId&quot;: [&quot;arn:aws:s3:::my-public-static-assets&quot;]
  },
  &quot;Actions&quot;: [{
    &quot;Type&quot;: &quot;FINDING_FIELDS_UPDATE&quot;,
    &quot;FindingFieldsUpdate&quot;: {
      &quot;Workflow&quot;: {&quot;Status&quot;: &quot;SUPPRESSED&quot;},
      &quot;Note&quot;: {&quot;Text&quot;: &quot;Intentionally public CDN bucket&quot;, &quot;UpdatedBy&quot;: &quot;security-team&quot;}
    }
  }]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. Severity 기반 필터링&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;properties&quot;&gt;&lt;code&gt;CRITICAL &amp;rarr; 즉시 대응 필요 (자동화 고려)
HIGH     &amp;rarr; 24시간 내 대응
MEDIUM   &amp;rarr; 7일 내 대응
LOW      &amp;rarr; 스프린트 단위 정리
INFO     &amp;rarr; 참고용, suppress 검토
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;5. Automation: EventBridge 연동으로 자동 대응 구현&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Security Hub의 진짜 가치는 &lt;b&gt;탐지 &amp;rarr; 자동 대응 루프&lt;/b&gt;를 구현할 수 있다는 점입니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;5.1 기본 자동화 아키텍처&lt;/h4&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;Security Hub Finding 발생
         &amp;darr;
   EventBridge Rule
   (Finding 조건 매칭)
         &amp;darr;
    ┌────┴────┐
    &amp;darr;         &amp;darr;
 Lambda     SNS
(자동 수정)  (알림)
    &amp;darr;
Finding 상태 업데이트
(WORKFLOW_STATUS: RESOLVED)&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;5.2 실전 EventBridge Rule 예시&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;예시 1: S3 퍼블릭 접근 자동 차단&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;// EventBridge Rule Pattern
{
  &quot;source&quot;: [&quot;aws.securityhub&quot;],
  &quot;detail-type&quot;: [&quot;Security Hub Findings - Imported&quot;],
  &quot;detail&quot;: {
    &quot;findings&quot;: {
      &quot;Severity&quot;: {&quot;Label&quot;: [&quot;CRITICAL&quot;, &quot;HIGH&quot;]},
      &quot;Types&quot;: [&quot;Software and Configuration Checks/AWS Security Best Practices/S3.2&quot;],
      &quot;Workflow&quot;: {&quot;Status&quot;: [&quot;NEW&quot;]}
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;python&quot;&gt;&lt;code&gt;# Lambda 자동 수정 코드
import boto3

def lambda_handler(event, context):
    s3 = boto3.client('s3')
    finding = event['detail']['findings'][0]
    
    bucket_name = finding['Resources'][0]['Id'].split(':::')[1]
    
    # Public Access Block 강제 적용
    s3.put_public_access_block(
        Bucket=bucket_name,
        PublicAccessBlockConfiguration={
            'BlockPublicAcls': True,
            'IgnorePublicAcls': True,
            'BlockPublicPolicy': True,
            'RestrictPublicBuckets': True
        }
    )
    
    # Finding 상태 업데이트
    hub = boto3.client('securityhub')
    hub.batch_update_findings(
        FindingIdentifiers=[{
            'Id': finding['Id'],
            'ProductArn': finding['ProductArn']
        }],
        Workflow={'Status': 'RESOLVED'},
        Note={'Text': 'Auto-remediated by Lambda', 'UpdatedBy': 'auto-remediation'}
    )
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;예시 2: Security Group 0.0.0.0/0 인바운드 규칙 자동 제거&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;prolog&quot;&gt;&lt;code&gt;def lambda_handler(event, context):
    ec2 = boto3.client('ec2')
    finding = event['detail']['findings'][0]
    
    sg_id = finding['Resources'][0]['Id'].split('/')[-1]
    
    # 위험한 규칙 탐지 및 제거
    sg = ec2.describe_security_groups(GroupIds=[sg_id])['SecurityGroups'][0]
    
    for permission in sg['IpPermissions']:
        for ip_range in permission.get('IpRanges', []):
            if ip_range.get('CidrIp') == '0.0.0.0/0':
                ec2.revoke_security_group_ingress(
                    GroupId=sg_id,
                    IpPermissions=[permission]
                )
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;5.3 Automation Rules (코드 없이 Finding 조작)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2023년 이후 추가된 기능으로, &lt;b&gt;Lambda 없이 콘솔에서&lt;/b&gt; finding을 자동으로 업데이트할 수 있습니다.&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;Automation Rule 사용 사례:
① 특정 계정의 LOW findings &amp;rarr; 자동 SUPPRESSED
② Critical finding &amp;rarr; 심각도 레이블 변경 + 담당자 주석 추가
③ 특정 리소스 태그 기반으로 workflow status 자동 업데이트&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Lambda 연동이 필요한 실제 remediation과 달리, &lt;b&gt;finding 메타데이터 조작&lt;/b&gt;은 Automation Rules로 간단하게 처리할 수 있습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;6. 아키텍처에서의 Security Hub 포지셔닝&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Security Account 중심 멀티 계정 구조에 Security Hub를 어떻게 연결할지 정리합니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;6.1 보안 탐지 흐름 전체 그림&lt;/h4&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;Production / Staging / Development Account (Member)
├── GuardDuty Finding    ──┐
├── Inspector Finding    ──┤──&amp;rarr; Security Hub CSPM (Security Account)
├── Macie Finding        ──┤         &amp;darr;
├── Access Analyzer      ──┘    상관관계 분석 &amp;amp; 우선순위화
└── Config NON_COMPLIANT ──&amp;rarr;         &amp;darr;
                               EventBridge Rule (Security Account)
                                     &amp;darr;
                    ┌────────────────┼────────────────┐
                    &amp;darr;                &amp;darr;                &amp;darr;
                 Lambda           SNS Topic        SIEM/SOAR
              (자동 수정)      (보안담당자 알림)    (외부 연동)
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;7. 비용 구조: 예측 가능하게 관리하기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Security Hub는 활성화 자체는 무료 트라이얼(30일) 이후 과금됩니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;7.1 Security Hub CSPM 과금 구조&lt;/h4&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;과금 항목&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;기준&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;보안 검사(Security Checks)&lt;/td&gt;
&lt;td&gt;계정당, 리전당 검사 수&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Finding 수집(Finding Ingestion)&lt;/td&gt;
&lt;td&gt;수신한 finding 건수&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Automation Rules&lt;/td&gt;
&lt;td&gt;규칙 평가 건수&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;실전 비용 최적화 팁&lt;/b&gt;:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Security Hub 통합 솔루션(GA, 2025년 12월~)은 GuardDuty, Inspector, Macie 요금을 통합 청구하여 &lt;b&gt;비용 예측성 향상&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;Dev 계정에는 표준 수를 최소화하여 검사 수 줄이기&lt;/li&gt;
&lt;li&gt;불필요한 써드파티 finding 수집 비활성화 (downstream 연동 확인 후)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;참고 자료&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.aws.amazon.com/securityhub/latest/userguide/what-is-securityhub.html&quot;&gt;AWS Security Hub 공식 문서&lt;/a&gt; (2026년 3월 갱신)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://aws.amazon.com/blogs/aws/aws-security-hub-now-generally-available-with-near-real-time-analytics-and-risk-prioritization/&quot;&gt;AWS Security Hub - GA 발표 (re:Invent 2025)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://aws.amazon.com/blogs/security/aws-security-hub-is-expanding-to-unify-security-operations-across-multicloud-environments/&quot;&gt;Security Hub 멀티클라우드 확장 계획&lt;/a&gt; (2026년 3월)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://aws.amazon.com/about-aws/whats-new/2026/03/amazon-cloudwatch-securityhub-findings/&quot;&gt;CloudWatch + Security Hub 통합 발표&lt;/a&gt; (2026년 3월)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://aws.github.io/aws-security-services-best-practices/guides/security-hub/&quot;&gt;AWS Security Hub CSPM Best Practices (GitHub)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://aws.amazon.com/blogs/aws/aws-reinforce-roundup-2025-top-announcements/&quot;&gt;AWS re:Inforce 2025 보안 발표 총정리&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.aws.amazon.com/securityhub/latest/userguide/securityhub-cloudwatch-events.html&quot;&gt;EventBridge 자동 대응 공식 문서&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>AWS</category>
      <category>security hub</category>
      <author>lhywk</author>
      <guid isPermaLink="true">https://lhywk.tistory.com/110</guid>
      <comments>https://lhywk.tistory.com/110#entry110comment</comments>
      <pubDate>Mon, 11 May 2026 14:42:45 +0900</pubDate>
    </item>
    <item>
      <title>ERGO의 이벤트 기반 보안 자동 대응 아키텍처 분석</title>
      <link>https://lhywk.tistory.com/109</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 개요&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ERGO는 독일과 유럽의 주요 보험 그룹 중 하나입니다. 산하의 ERGO Technology &amp;amp; Services S.A.(ET&amp;amp;S)는 디지털 전환과 복잡한 IT 시스템 구축을 담당하며 AWS 기반의 멀티 계정 클라우드 환경을 운영하고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클라우드 전환 초기 ERGO는 &lt;b&gt;CIS AWS Foundations Benchmark Standard&lt;/b&gt;를 보안 컴플라이언스의 핵심 지표로 채택했습니다. 초기 측정 결과 보안 태세에 상당한 개선 여지가 있었고 다음과 같은 과제가 있었습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;다수의 AWS 계정에서 발생하는 보안 이벤트를 &lt;b&gt;스케일에 맞게&lt;/b&gt; 관리해야 함&lt;/li&gt;
&lt;li&gt;보안 이벤트 대응과 교정을 &lt;b&gt;중앙에서 실시간에 가깝게&lt;/b&gt; 처리해야 함&lt;/li&gt;
&lt;li&gt;각 프로젝트 계정에 직접 접근하지 않고 책임 분리를 유지해야 함&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 아키텍처는 위 세 가지 요구 사항을 모두 만족하는 &lt;b&gt;완전한 서버리스 이벤트 기반 보안 자동 대응 시스템입니다&lt;/b&gt;. 최종적으로 CIS 컴플라이언스를 약 &lt;b&gt;95%&lt;/b&gt; 수준으로 끌어올렸으며 클라우드 보안팀의 지속적인 플랫폼 유지 부담을 크게 줄였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. 아키텍처 분석&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;951&quot; data-origin-height=&quot;707&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/NAxF9/dJMcaiXwnCL/ibdBlW7MUHUTI1Fdzw74Uk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/NAxF9/dJMcaiXwnCL/ibdBlW7MUHUTI1Fdzw74Uk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/NAxF9/dJMcaiXwnCL/ibdBlW7MUHUTI1Fdzw74Uk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNAxF9%2FdJMcaiXwnCL%2FibdBlW7MUHUTI1Fdzw74Uk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;752&quot; height=&quot;559&quot; data-origin-width=&quot;951&quot; data-origin-height=&quot;707&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2.1 핵심 계정 구조&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ERGO는 AWS Organizations를 사용해 멀티 계정 환경을 중앙 관리합니다. 보안 아키텍처는 &lt;b&gt;세 가지 계정 유형&lt;/b&gt;으로 역할을 명확히 분리합니다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 17.907%;&quot;&gt;&lt;b&gt;계정 유형&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 30.9302%;&quot;&gt;&lt;b&gt;역할&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 51.1628%;&quot;&gt;&lt;b&gt;주요 서비스&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 17.907%;&quot;&gt;&lt;b&gt;Security Account&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 30.9302%;&quot;&gt;보안 이벤트 집계 및 워크플로 오케스트레이션&lt;/td&gt;
&lt;td style=&quot;width: 51.1628%;&quot;&gt;Security Hub (Admin), CloudWatch, Step Functions, Proxy Lambda&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 17.907%;&quot;&gt;&lt;b&gt;Service Account&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 30.9302%;&quot;&gt;실제 교정 액션 실행&lt;/td&gt;
&lt;td style=&quot;width: 51.1628%;&quot;&gt;Remediation Lambda, IAM Cross-Account Role&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 17.907%;&quot;&gt;&lt;b&gt;Project Account&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 30.9302%;&quot;&gt;워크로드가 실행되는 멤버 계정&lt;/td&gt;
&lt;td style=&quot;width: 51.1628%;&quot;&gt;Security Hub (Member), GuardDuty&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 구조는 &lt;b&gt;역할 분리의 핵심 원칙&lt;/b&gt;을 실현합니다. Security Account는 감지와 오케스트레이션만 담당하고 실제 리소스에 대한 액션은 반드시 Service Account를 통해서만 수행됩니다. Project Account에는 어떤 자동화 코드도 직접 배포되지 않습니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2.2 데이터 흐름 단계별 분석&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아키텍처의 전체 데이터 흐름은 8단계로 구성됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 보안 이벤트 수집&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 Project Account에서 실행 중인 AWS Security Hub가 보안 탐지 결과(Finding)를 생성한다. Amazon GuardDuty가 VPC Flow Logs, CloudTrail, DNS 쿼리 로그 등을 분석해 이상 행동을 탐지하면 이 결과가 Security Hub로 전송됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS Organizations와 Security Hub의 통합을 통해 Security Account가 Security Hub 관리자 계정으로 지정됩니다. 모든 Project Account는 자동으로 멤버 계정으로 등록되어 자신의 Finding을 Security Account의 Security Hub로 전송합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. 이벤트 집계 및 CloudWatch 전달&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Security Account의 Security Hub는 모든 멤버 계정의 Finding을 집계합니다. Security Hub는 Amazon CloudWatch와 통합되어 모든 보안 이벤트를 CloudWatch Events로 전송합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. 1차 필터링 - CloudWatch Events Rules&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CloudWatch Events Rules를 통한 &lt;b&gt;1차 필터링&lt;/b&gt;이 수행됩니다. 이벤트 패턴 매칭을 통해 ERGO가 집중하고자 하는 이벤트 유형을 추려냅니다. 이 규칙에 매칭된 이벤트는 Step Functions 상태 머신의 트리거가 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;AWS Step Functions: 여러 AWS 서비스를 순서대로 연결해 하나의 워크플로로 만들어주는 서버리스 오케스트레이션 서비스. 각 단계를 시각적으로 정의하고 조건 분기, 재시도, 에러 처리를 워크플로 수준에서 통합 관리할 수 있습니다. Lambda를 단독으로 쓰면 각 함수마다 에러 처리 코드를 넣어야 하지만 Step Functions를 쓰면 그 로직을 워크플로 정의에서 한 번에 처리할 수 있습니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;4. 2차 필터링 및 오케스트레이션 - AWS Step Functions&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS Step Functions는 이 아키텍처의 &lt;b&gt;두뇌&lt;/b&gt; 역할을 합니다. CloudWatch Rules보다 더 세밀한 2차 필터링을 수행하며 이벤트 유형에 따라 두 가지 처리 경로로 분기합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;경로 A (Suppress):&lt;/b&gt; Project Account에 직접 접근할 필요 없이 억제가 가능한 이벤트 -&amp;gt; Archival Lambda 호출&lt;/li&gt;
&lt;li&gt;&lt;b&gt;경로 B (Remediate):&lt;/b&gt; Project Account에서 교정 액션이 필요한 이벤트 -&amp;gt; Proxy Lambda 호출&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Step Functions를 선택한 결정적 이유는 &lt;b&gt;에러 처리의 중앙화입니다&lt;/b&gt;. 실제 운영 중 Archival Lambda 함수가 Security Hub API Rate Throttling으로 인해 간헐적으로 실패하는 문제가 발생했습니다. ERGO는 다음 대안들을 검토했습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;AWS SDK 자동 재시도 -&amp;gt; Rate Limit 상황에서 충분하지 않음&lt;/li&gt;
&lt;li&gt;Lambda 예약 동시성 제한 -&amp;gt; Archival 함수 스로틀링&lt;/li&gt;
&lt;li&gt;이벤트 배치 처리 -&amp;gt; 단일 API 호출로 여러 파라미터 처리&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최종적으로 Step Functions의 &lt;b&gt;&quot;retry on error&quot; 메커니즘&lt;/b&gt;을 활용하는 방식을 선택했습니다. 이를 통해 각 Lambda 함수에 개별적으로 에러 처리 로직을 구현하지 않고도 워크플로 수준에서 일관된 에러 처리가 가능해졌습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;5. 교정 요청 전달 - Proxy Lambda&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Project Account에서 교정이 필요한 이벤트의 경우 Step Functions는 Security Account 내의 &lt;b&gt;Proxy Lambda&lt;/b&gt;를 호출합니다. Proxy Lambda는 다음 정보를 인자로 받습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;실행할 Remediation 함수 이름 및 버전&lt;/li&gt;
&lt;li&gt;대상 Project Account ID&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Proxy Lambda의 역할은 Security Account와 Service Account 사이의 &lt;b&gt;크로스 계정 브릿지입니다&lt;/b&gt;. Security Account의 Step Functions는 다른 계정의 Lambda를 직접 호출할 수 없으므로 동일 Security Account 내 Proxy Lambda가 이 역할을 대신합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;6. 크로스 계정 교정 실행 - Remediation Lambda&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Proxy Lambda는 Service Account의 &lt;b&gt;Remediation Lambda&lt;/b&gt;를 호출합니다. Remediation Lambda는 IAM의 &lt;b&gt;AssumeRole&lt;/b&gt;을 사용해 각 Project Account에서 교정 액션을 수행할 수 있는 권한을 위임받습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 사용되는 IAM 역할은 조직 레벨 역할로 모든 Project Account에 배포되어 있으며 교정 수행에 필요한 최소한의 권한만을 갖습니다. IAM 퍼미션, VPC 리소스 조작 등 다양한 교정 액션이 이 함수를 통해 실행됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;7. 교정 액션 수행&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이벤트 유형에 따라 해당 Project Account에서 구체적인 교정 액션이 실행됩니다. CIS Benchmark 기준에 따른 대표적인 교정 액션의 예는 다음과 같습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;과도하게 열린 보안 그룹 규칙 제거&lt;/li&gt;
&lt;li&gt;MFA가 비활성화된 IAM 루트 계정 알림&lt;/li&gt;
&lt;li&gt;암호화되지 않은 S3 버킷에 서버 사이드 암호화 적용&lt;/li&gt;
&lt;li&gt;CloudTrail 로깅 재활성화&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;8. 실행 결과 반환&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Remediation Lambda는 교정 결과를 Proxy Lambda로 반환하고 이는 다시 Step Functions 상태 머신으로 전달되어 워크플로를 완료합니다. 교정에 실패한 케이스는 예외 상황으로 분류되어 수동 처리됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2.3 주요 설계 결정 포인트&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;서버리스 완전 관리형 아키텍처&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 아키텍처는 EC2, ECS 등 관리형 서버를 전혀 사용하지 않습니다. Lambda, Step Functions, CloudWatch 모두 완전 관리형 서버리스 서비스입니다. 이는 보안팀이 인프라 유지보수가 아닌 보안 정책 개선에 집중할 수 있게 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;계층적 이중 필터링 구조&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CloudWatch Events Rules(1차)와 Step Functions 워크플로(2차)로 이어지는 이중 필터링 구조는 이벤트 처리의 정밀도를 높입니다. 1차에서는 대분류, 2차에서는 교정 액션과의 매핑이라는 역할 분담이 명확합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Proxy Lambda 패턴을 통한 크로스 계정 통합&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Step Functions에서 다른 계정의 Lambda를 직접 호출하는 대신 동일 계정의 Proxy Lambda를 경유하는 패턴은 크로스 계정 권한 관리의 복잡성을 줄입니다. Service Account의 Remediation Lambda에 대한 접근 권한을 Proxy Lambda에만 부여하면 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;조직 레벨 IAM 역할을 통한 확장성&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 Project Account에 표준화된 조직 레벨 IAM 역할을 배포함으로써 새로운 프로젝트 계정이 AWS Organizations에 추가될 때마다 자동으로 교정 기능이 적용됩니다. 개별 계정별 커스텀 설정이 필요하지 않습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. 추가하면 좋을 보안 요소&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3.1 Amazon SNS를 통한 교정 실패 알림&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원문에서도 &quot;실패한 교정은 예외적으로 수동 처리한다&quot;고 명시하고 있기 때문에 Step Functions의 실패 분기에 &lt;b&gt;Amazon SNS&lt;/b&gt;를 연결해 교정 실패 시 보안팀에게 즉시 통보할 수 있습니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3.2 SQS Dead Letter Queue를 통한 이벤트 유실 방지&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Lambda 실행이 반복 실패할 경우 해당 보안 이벤트 자체가 사라집니다. &lt;b&gt;Amazon SQS DLQ&lt;/b&gt;를 Lambda 함수에 설정하면 처리에 실패한 이벤트를 보존해 원인 분석과 재처리가 가능합니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;참고자료&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;How ERGO Implemented an Event-driven Security Remediation Architecture on AWS -&amp;nbsp;&lt;b&gt;&lt;a href=&quot;https://aws.amazon.com/ko/blogs/architecture/how-ergo-implemented-an-event-driven-security-remediation-architecture-on-aws/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://aws.amazon.com/ko/blogs/architecture/how-ergo-implemented-an-event-driven-security-remediation-architecture-on-aws/&lt;/a&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>AWS</category>
      <category>AWS 보안 아키텍처 분석</category>
      <author>lhywk</author>
      <guid isPermaLink="true">https://lhywk.tistory.com/109</guid>
      <comments>https://lhywk.tistory.com/109#entry109comment</comments>
      <pubDate>Sat, 9 May 2026 23:09:48 +0900</pubDate>
    </item>
    <item>
      <title>AWS Organizations + SCP</title>
      <link>https://lhywk.tistory.com/108</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 &lt;b&gt;계정 자체를 어떻게 구조화하고 통제할 것인가&lt;/b&gt;를 다룰 차례입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;계정이 2~3개일 때는 수동으로 관리해도 됩니다. 그런데 계정이 10개, 20개, 50개로 늘어나면 얘기가 달라집니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;개발자가 실수로 프로덕션 계정에서 비용이 많이 드는 GPU 인스턴스를 켜놨습니다&lt;/li&gt;
&lt;li&gt;보안 팀 모르게 누군가 특정 계정에서 CloudTrail을 꺼버렸습니다&lt;/li&gt;
&lt;li&gt;데이터 규정 준수상 특정 리전에서만 리소스를 생성해야 하는데, 다른 리전에도 생겨버렸습니다&lt;/li&gt;
&lt;li&gt;새로 입사한 개발자가 어떤 계정에서 무엇을 할 수 있는지 기준이 없습니다&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 문제들을 한꺼번에 해결하는 것이 &lt;b&gt;AWS Organizations&lt;/b&gt;이고, 그 핵심 통제 도구가 SCP(Service Control Policy)입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 글에서 다루는 것:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;AWS Organizations의 구조와 왜 다중 계정이 모범 사례인가&lt;/li&gt;
&lt;li&gt;SCP의 동작 원리와 IAM Policy와의 결정적 차이&lt;/li&gt;
&lt;li&gt;OU 설계 전략 &amp;mdash; 실무에서 쓰이는 패턴&lt;/li&gt;
&lt;li&gt;SCP 작성 전략과 실전 예제&lt;/li&gt;
&lt;li&gt;IAM Access Analyzer로 권한을 지속적으로 검토하는 방법&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. 왜 다중 계정이 모범 사례인가?&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS 계정을 하나만 사용하는 것은 마치 &lt;b&gt;회사 직원 전체가 하나의 Linux 서버를 root 계정으로 공유하는 것&lt;/b&gt;과 같습니다. 편하긴 하지만 위험이 집중됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다중 계정 전략이 권장되는 이유는 크게 네 가지입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;① 폭발 반경(Blast Radius) 제한&lt;/b&gt; 어떤 계정에서 보안 사고가 나도, 다른 계정의 리소스는 영향을 받지 않습니다. 개발 계정이 해킹되어도 프로덕션 데이터는 안전합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;② 자연스러운 결제 경계&lt;/b&gt; 계정별로 비용이 독립적으로 추적됩니다. 개발/스테이징/프로덕션 각각 얼마가 드는지 Consolidated Billing으로 한눈에 보면서도, 계정별 책임이 명확합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;③ 리소스 격리&lt;/b&gt; 서비스 할당량(Quota)이 계정 단위로 관리되므로, 하나의 워크로드가 할당량을 모두 소진해도 다른 계정은 영향을 받지 않습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;④ 거버넌스 단순화&lt;/b&gt; SCP로 계정/OU 단위의 가드레일을 설정하면, 계정 내부의 IAM 설정이 어떻게 되어있든 관계없이 조직 전체 정책을 강제할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. AWS Organizations 구조&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2-1. 핵심 개념&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Organization(조직)&lt;/b&gt; : 중앙에서 관리할 수 있으며 최상단에 루트가 있고, 그 아래에는 조직 단위가 중첩된 트리형 계층 구조로 구성할 수 있는 AWS 계정의 모음입니다. 조직은 무료로 사용할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;관리 계정(Management Account)&lt;/b&gt; : 조직을 생성하는 데 사용하는 AWS 계정입니다. 이 계정에서 조직 내 다른 계정을 생성하거나 초대하고, OU를 구성하고, SCP를 적용합니다. 이전에는 &quot;마스터 계정(Master Account)&quot;이라고 불렸습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;중요:&lt;/b&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt; 관리 계정은 SCP의 영향을 받지 않습니다. SCP는 멤버 계정에만 적용됩니다. 따라서 관리 계정에는 워크로드를 배포하지 않는 것이 강력히 권장됩니다. 관리 계정의 역할은 Organizations 자체의 관리에 집중되어야 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;멤버 계정(Member Account)&lt;/b&gt; : 조직의 나머지 계정들입니다. 관리 계정에서 직접 생성하거나, 기존 계정을 초대할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;루트(Root)&lt;/b&gt; : 조직 계층 구조의 최상위 컨테이너입니다. 루트에 SCP를 연결하면 조직의 모든 계정에 적용됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;OU(Organizational Unit)&lt;/b&gt; : 조직 내 계정의 논리적 그룹화입니다. OU는 다른 OU를 포함할 수 있어 계층 구조를 만들 수 있습니다. OU를 최대 5단계까지 중첩할 수 있으며, OU에 SCP를 연결하면 해당 OU의 모든 하위 계정과 하위 OU에 상속됩니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2-2. 정책 상속 원리&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SCP는 &lt;b&gt;계층 구조를 타고 상속&lt;/b&gt;됩니다. 이것이 OU 설계의 핵심입니다.&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;루트 (Root)
├── SCP: DenyLeaveOrganization
│
├── OU: Security
│   ├── SCP: SecurityReadOnly
│   └── 계정: Log Archive
│   └── 계정: Security Tooling
│
├── OU: Workloads
│   ├── SCP: DenyExpensiveInstances
│   │
│   ├── OU: Prod
│   │   ├── SCP: DenyDeleteCloudTrail, DenyPublicS3
│   │   └── 계정: Prod-App1
│   │   └── 계정: Prod-App2
│   │
│   └── OU: Dev
│       ├── SCP: DenyProdServices
│       └── 계정: Dev-App1
│       └── 계정: Dev-App2&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 구조에서 Prod-App1 계정이 받는 SCP는 &lt;b&gt;루트 SCP + Workloads OU SCP + Prod OU SCP&lt;/b&gt; 세 가지를 모두 상속받습니다. 위로 올라갈수록 더 많은 제약이 누적됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. SCP(Service Control Policy)&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3-1. SCP란?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SCP는 조직의 권한을 관리하는 데 사용할 수 있는 조직 정책 유형입니다. SCP는 조직 내 모든 IAM 사용자 및 IAM 역할에 대해 사용 가능한 최대 권한을 중앙에서 제어합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2편에서 다룬 &lt;b&gt;Permission Boundary&lt;/b&gt;가 IAM 엔터티(User/Role) 단위의 상한선이라면, SCP는 &lt;b&gt;AWS 계정 전체 단위&lt;/b&gt;의 상한선입니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3-2. SCP의 결정적 특성 &amp;mdash; 권한을 부여하지 않는다&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SCP에 대해 가장 많이 오해하는 부분이 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;SCP는 어떠한 권한도 부여하지 않습니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SCP가 &quot;Effect&quot;: &quot;Allow&quot;를 포함하더라도 그것은 &quot;이 범위 안에서는 IAM 정책이 Allow를 줄 수 있다&quot;는 의미이지, SCP가 직접 권한을 주는 것이 아닙니다. 실제 권한은 여전히 IAM 정책이 부여합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 권한 = IAM Policy가 허용하는 것 &amp;cap; SCP가 허용하는 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 두 가지가 모두 Allow해야만 실제로 허용됩니다. 어느 하나라도 Deny하거나, 어느 하나에서 Allow가 없으면 거부됩니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3-3. SCP vs IAM Policy 비교&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;항목 IAM Policy SCP&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;항목&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;IAM Policy&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;SCP&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;적용 대상&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;IAM User/Group/Role&lt;/td&gt;
&lt;td&gt;계정 전체 (멤버 계정의 모든 IAM 엔터티)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;관리 위치&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;각 계정 내부&lt;/td&gt;
&lt;td&gt;Organizations 관리 계정&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;권한 부여 여부&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;직접 부여 가능&lt;/td&gt;
&lt;td&gt;&lt;b&gt;부여 불가, 상한선만 설정&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;Root User 제한&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;불가&lt;/td&gt;
&lt;td&gt;&lt;b&gt;가능 (루트 포함 모든 엔터티)&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;관리 계정 적용&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;해당&lt;/td&gt;
&lt;td&gt;&lt;b&gt;적용 안 됨&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;서비스 연결 역할 제한&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;가능&lt;/td&gt;
&lt;td&gt;&lt;b&gt;불가&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;상속&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;없음&lt;/td&gt;
&lt;td&gt;계층 구조 상속&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;중요한 차이:&lt;/b&gt; IAM Policy는 Root User를 제한할 수 없지만, SCP는 멤버 계정의 Root User에도 적용됩니다. (단, 관리 계정은 예외)&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3-4. SCP 작동 방식: 허용 목록 vs 거부 목록&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SCP를 작성하는 전략이 두 가지 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;전략 1: 허용 목록(Allow List)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본적으로 모든 것을 차단하고, 허용할 것만 명시합니다.&lt;/p&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;{
  &quot;Version&quot;: &quot;2012-10-17&quot;,
  &quot;Statement&quot;: [
    {
      &quot;Effect&quot;: &quot;Allow&quot;,
      &quot;Action&quot;: [
        &quot;ec2:*&quot;,
        &quot;s3:*&quot;,
        &quot;rds:*&quot;,
        &quot;lambda:*&quot;,
        &quot;iam:*&quot;
      ],
      &quot;Resource&quot;: &quot;*&quot;
    }
  ]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 SCP만 있으면, 명시된 서비스 외에는 전부 차단됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;장점: 허용된 것만 쓸 수 있어 매우 엄격한 제어 가능 단점: 새로운 서비스를 사용하려면 매번 SCP를 수정해야 함. 잘못 설정하면 운영이 중단될 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;전략 2: 거부 목록(Deny List) &amp;mdash; 실무에서 더 일반적&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본적으로 기존 FullAWSAccess SCP로 모든 것을 허용하고, 금지할 것만 Deny로 명시합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS는 기본적으로 모든 루트, OU, 계정에 FullAWSAccess SCP를 연결합니다. 그 위에 Deny를 추가하는 방식입니다.&lt;/p&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;{
  &quot;Version&quot;: &quot;2012-10-17&quot;,
  &quot;Statement&quot;: [
    {
      &quot;Sid&quot;: &quot;DenyExpensiveInstances&quot;,
      &quot;Effect&quot;: &quot;Deny&quot;,
      &quot;Action&quot;: &quot;ec2:RunInstances&quot;,
      &quot;Resource&quot;: &quot;arn:aws:ec2:*:*:instance/*&quot;,
      &quot;Condition&quot;: {
        &quot;StringNotLike&quot;: {
          &quot;ec2:InstanceType&quot;: [
            &quot;t3.*&quot;,
            &quot;t3a.*&quot;,
            &quot;m5.*&quot;,
            &quot;c5.*&quot;
          ]
        }
      }
    }
  ]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;장점: 기존 운영에 영향 최소화, 점진적으로 가드레일 추가 가능 단점: Deny가 누락되면 허용될 수 있음&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3-5. SCP의 제한사항 &amp;mdash; 반드시 알아야 할 것들&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;제한 1: 관리 계정에는 적용 안 됨&lt;/b&gt; SCP는 멤버 계정에만 적용됩니다. 관리 계정의 IAM 엔터티는 SCP의 영향을 받지 않습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;제한 2: 서비스 연결 역할(Service-Linked Role)에는 적용 안 됨&lt;/b&gt; AWSServiceRoleFor* 형태의 서비스 연결 역할은 SCP로 제한할 수 없습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;제한 3: 리소스 기반 정책에는 직접 영향 안 줌&lt;/b&gt; SCP는 계정 내 IAM 엔터티에 적용됩니다. 다른 계정의 사용자가 리소스 기반 정책(S3 버킷 정책 등)으로 접근하는 경우, 그 외부 사용자에게는 SCP가 적용되지 않습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;제한 4: SCP 크기 제한&lt;/b&gt; 각 SCP는 최대 5,120바이트입니다. 복잡한 정책은 여러 SCP로 분리해야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4. OU 설계 전략&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;OU를 설계할 때 가장 중요한 원칙이 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;OU는 회사 조직도를 따르는 게 아니라, 적용할 제어 정책이 같은 계정끼리 묶어야 합니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어, &quot;개발팀 계정&quot;과 &quot;마케팅팀 계정&quot;을 팀 기준으로 묶는 것이 아니라, &quot;프로덕션 환경 계정&quot;과 &quot;비프로덕션 환경 계정&quot;으로 묶어야 SCP를 효율적으로 적용할 수 있습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4-1. AWS 권장 기본 OU 구조&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS는 다음과 같은 기본 OU 구조를 권장합니다.&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;Root
├── Security OU
│   ├── Log Archive 계정     (모든 계정의 CloudTrail/Config 로그 집중)
│   └── Security Tooling 계정 (GuardDuty, Security Hub 중앙 관리)
│
├── Infrastructure OU
│   ├── Network 계정         (Transit Gateway, VPC, Route53 등)
│   └── Shared Services 계정 (공유 AD, 공유 ECR 등)
│
├── Workloads OU
│   ├── Prod OU
│   │   └── App1-Prod, App2-Prod ...
│   └── SDLC OU (비프로덕션)
│       └── App1-Dev, App1-Staging ...
│
├── Sandbox OU              (개발자 자유 실험 계정, 강한 제한 없음)
│
└── Management OU (선택)    (관리 도구 계정)&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4-2. 각 OU의 역할과 SCP&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Security OU:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;목적: 보안 서비스 집중 관리, 감사 로그 보관&lt;/li&gt;
&lt;li&gt;적용 SCP: 읽기 전용 제한 (로그 삭제 방지), 로그 아카이브 계정은 외부 접근 최소화&lt;/li&gt;
&lt;li&gt;특이사항: 보안 팀만 접근 가능, 일반 개발자 접근 차단&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Infrastructure OU:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;목적: 네트워킹, 공유 서비스&lt;/li&gt;
&lt;li&gt;적용 SCP: 네트워크 관련 서비스만 허용&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Workloads &amp;gt; Prod OU:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;목적: 프로덕션 환경 격리&lt;/li&gt;
&lt;li&gt;적용 SCP:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;CloudTrail 비활성화 방지&lt;/li&gt;
&lt;li&gt;S3 퍼블릭 액세스 허용 방지&lt;/li&gt;
&lt;li&gt;루트 사용자 활동 차단&lt;/li&gt;
&lt;li&gt;특정 리전 외 리소스 생성 방지&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Workloads &amp;gt; SDLC OU:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;목적: 개발/스테이징 환경&lt;/li&gt;
&lt;li&gt;적용 SCP: 비용 관련 제한 (고가 인스턴스 차단), 프로덕션 데이터 접근 차단&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Sandbox OU:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;목적: 개발자 자유 실험, 학습&lt;/li&gt;
&lt;li&gt;적용 SCP: 비용 상한 (특정 인스턴스 차단, 특정 리전 제한), 데이터 유출 방지&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4-3. 실무 OU 설계 시 주의사항&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;계정은 하나의 OU에만 속할 수 있습니다.&lt;/b&gt; 계정을 여러 OU에 중복 배치할 수 없습니다. 따라서 제어 정책의 교집합이 필요한 경우, OU 상속 계층을 잘 활용해야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;OU 이동 시 SCP가 즉시 변경됩니다.&lt;/b&gt; 계정을 다른 OU로 옮기면 SCP가 즉시 재계산됩니다. 프로덕션 계정을 잘못된 OU로 옮기면 운영이 중단될 수 있습니다. 반드시 테스트 후 이동하세요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;너무 깊게 중첩하지 마세요.&lt;/b&gt; 최대 5단계까지 중첩 가능하지만, 3단계 이상으로 깊어지면 &quot;이 계정에 어떤 SCP가 적용되는지&quot; 파악하기 어려워집니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;5. 실전 SCP 예제&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;5-1. 특정 리전 외 리소스 생성 방지&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;규정 준수(Compliance) 요건으로 특정 리전에서만 리소스를 생성해야 하는 경우입니다.&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;{
  &quot;Version&quot;: &quot;2012-10-17&quot;,
  &quot;Statement&quot;: [
    {
      &quot;Sid&quot;: &quot;DenyOutsideApNortheast2&quot;,
      &quot;Effect&quot;: &quot;Deny&quot;,
      &quot;NotAction&quot;: [
        &quot;iam:*&quot;,
        &quot;organizations:*&quot;,
        &quot;route53:*&quot;,
        &quot;budgets:*&quot;,
        &quot;waf:*&quot;,
        &quot;cloudfront:*&quot;,
        &quot;sts:*&quot;,
        &quot;support:*&quot;,
        &quot;health:*&quot;,
        &quot;s3:GetBucketLocation&quot;,
        &quot;s3:ListAllMyBuckets&quot;
      ],
      &quot;Resource&quot;: &quot;*&quot;,
      &quot;Condition&quot;: {
        &quot;StringNotEquals&quot;: {
          &quot;aws:RequestedRegion&quot;: [
            &quot;ap-northeast-2&quot;,
            &quot;us-east-1&quot;
          ]
        }
      }
    }
  ]
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;주의:&lt;/b&gt; NotAction을 사용해서 글로벌 서비스(IAM, CloudFront, Route53 등)는 제외해야 합니다. 이들은 리전 없이 동작하기 때문에 리전 제한에서 예외처리가 필요합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;5-2. CloudTrail 비활성화 방지&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 프로덕션 계정에서 CloudTrail을 끄거나 삭제하는 것을 방지합니다.&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;{
  &quot;Version&quot;: &quot;2012-10-17&quot;,
  &quot;Statement&quot;: [
    {
      &quot;Sid&quot;: &quot;DenyCloudTrailDisable&quot;,
      &quot;Effect&quot;: &quot;Deny&quot;,
      &quot;Action&quot;: [
        &quot;cloudtrail:DeleteTrail&quot;,
        &quot;cloudtrail:StopLogging&quot;,
        &quot;cloudtrail:UpdateTrail&quot;
      ],
      &quot;Resource&quot;: &quot;*&quot;
    }
  ]
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;5-3. S3 퍼블릭 액세스 허용 방지&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로덕션 계정에서 S3 버킷을 실수로 퍼블릭으로 열어놓는 것을 방지합니다.&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;{
  &quot;Version&quot;: &quot;2012-10-17&quot;,
  &quot;Statement&quot;: [
    {
      &quot;Sid&quot;: &quot;DenyS3PublicAccess&quot;,
      &quot;Effect&quot;: &quot;Deny&quot;,
      &quot;Action&quot;: [
        &quot;s3:PutBucketPublicAccessBlock&quot;,
        &quot;s3:DeletePublicAccessBlock&quot;
      ],
      &quot;Resource&quot;: &quot;*&quot;,
      &quot;Condition&quot;: {
        &quot;StringEquals&quot;: {
          &quot;s3:PublicAccessBlockConfiguration/BlockPublicAcls&quot;: &quot;false&quot;
        }
      }
    },
    {
      &quot;Sid&quot;: &quot;DenyPublicBucketPolicy&quot;,
      &quot;Effect&quot;: &quot;Deny&quot;,
      &quot;Action&quot;: &quot;s3:PutBucketPolicy&quot;,
      &quot;Resource&quot;: &quot;*&quot;,
      &quot;Condition&quot;: {
        &quot;Bool&quot;: {
          &quot;s3:PolicyIsPublic&quot;: &quot;true&quot;
        }
      }
    }
  ]
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;5-4. 고비용 인스턴스 차단 (개발 환경)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발/샌드박스 계정에서 GPU나 대형 인스턴스 사용을 방지합니다.&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;{
  &quot;Version&quot;: &quot;2012-10-17&quot;,
  &quot;Statement&quot;: [
    {
      &quot;Sid&quot;: &quot;DenyExpensiveEC2&quot;,
      &quot;Effect&quot;: &quot;Deny&quot;,
      &quot;Action&quot;: &quot;ec2:RunInstances&quot;,
      &quot;Resource&quot;: &quot;arn:aws:ec2:*:*:instance/*&quot;,
      &quot;Condition&quot;: {
        &quot;StringNotLike&quot;: {
          &quot;ec2:InstanceType&quot;: [
            &quot;t2.*&quot;,
            &quot;t3.*&quot;,
            &quot;t3a.*&quot;,
            &quot;m5.*&quot;,
            &quot;m5a.*&quot;,
            &quot;c5.*&quot;,
            &quot;r5.*&quot;
          ]
        }
      }
    }
  ]
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;5-5. 계정이 Organizations를 탈퇴하지 못하도록 방지&lt;/h3&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;{
  &quot;Version&quot;: &quot;2012-10-17&quot;,
  &quot;Statement&quot;: [
    {
      &quot;Sid&quot;: &quot;DenyLeaveOrganization&quot;,
      &quot;Effect&quot;: &quot;Deny&quot;,
      &quot;Action&quot;: &quot;organizations:LeaveOrganization&quot;,
      &quot;Resource&quot;: &quot;*&quot;
    }
  ]
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 SCP를 루트에 연결하면, 모든 멤버 계정이 Organizations를 임의로 탈퇴할 수 없습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;5-6. 보안 서비스 비활성화 방지 (루트 적용)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GuardDuty, Security Hub, Config 등 핵심 보안 서비스를 끄지 못하도록 합니다.&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;{
  &quot;Version&quot;: &quot;2012-10-17&quot;,
  &quot;Statement&quot;: [
    {
      &quot;Sid&quot;: &quot;DenyDisableSecurityServices&quot;,
      &quot;Effect&quot;: &quot;Deny&quot;,
      &quot;Action&quot;: [
        &quot;guardduty:DeleteDetector&quot;,
        &quot;guardduty:DisassociateFromMasterAccount&quot;,
        &quot;guardduty:StopMonitoringMembers&quot;,
        &quot;securityhub:DisableSecurityHub&quot;,
        &quot;config:DeleteConfigurationRecorder&quot;,
        &quot;config:StopConfigurationRecorder&quot;
      ],
      &quot;Resource&quot;: &quot;*&quot;
    }
  ]
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;6. SCP가 IAM Policy를 어떻게 제한하는가 &amp;mdash; 실습&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 실습은 SCP가 AdministratorAccess 권한을 가진 IAM 사용자도 제한할 수 있음을 직접 확인합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;실습 준비&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;AWS Organizations가 활성화된 관리 계정&lt;/li&gt;
&lt;li&gt;멤버 계정 1개 (테스트용)&lt;/li&gt;
&lt;li&gt;멤버 계정에 AdministratorAccess 권한의 IAM User 또는 Role&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Step 1: 테스트용 SCP 생성&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;관리 계정에서:&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;Organizations 콘솔 &amp;rarr; 정책 &amp;rarr; 서비스 제어 정책
&amp;rarr; 정책 생성

이름: DenyEC2-Test
설명: EC2 접근을 완전히 차단하는 테스트 SCP

JSON 편집:&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;{
  &quot;Version&quot;: &quot;2012-10-17&quot;,
  &quot;Statement&quot;: [
    {
      &quot;Sid&quot;: &quot;DenyEC2ForTest&quot;,
      &quot;Effect&quot;: &quot;Deny&quot;,
      &quot;Action&quot;: &quot;ec2:*&quot;,
      &quot;Resource&quot;: &quot;*&quot;
    }
  ]
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Step 2: SCP를 멤버 계정에 연결&lt;/h3&gt;
&lt;pre class=&quot;cmake&quot;&gt;&lt;code&gt;Organizations 콘솔 &amp;rarr; AWS 계정 &amp;rarr; 멤버 계정 선택
&amp;rarr; 정책 &amp;rarr; 서비스 제어 정책 &amp;rarr; 연결
&amp;rarr; DenyEC2-Test 선택 &amp;rarr; 정책 연결
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Step 3: 멤버 계정에서 EC2 접근 시도&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;멤버 계정의 AdministratorAccess IAM User로 로그인 후:&lt;/p&gt;
&lt;pre class=&quot;pgsql&quot;&gt;&lt;code&gt;# EC2 인스턴스 목록 조회 시도
aws ec2 describe-instances --region ap-northeast-2

# 예상 결과:
# An error occurred (UnauthorizedAccess) when calling the
# DescribeInstances operation: You are not authorized to perform
# this operation.
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;AdministratorAccess가 있음에도 EC2가 완전히 차단됩니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IAM Policy Simulator에서도 확인:&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;Policy Simulator &amp;rarr; 멤버 계정의 AdministratorAccess IAM User 선택
&amp;rarr; EC2 서비스 &amp;rarr; DescribeInstances
&amp;rarr; [Run Simulation]
결과: denied by Organizations SCP
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Step 4: SCP 예외 처리 &amp;mdash; 특정 Role은 허용&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실무에서는 특정 역할(예: 보안팀, SRE)은 예외로 EC2에 접근해야 하는 경우가 있습니다. Condition의 ArnNotLike로 예외를 만들 수 있습니다.&lt;/p&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;{
  &quot;Version&quot;: &quot;2012-10-17&quot;,
  &quot;Statement&quot;: [
    {
      &quot;Sid&quot;: &quot;DenyEC2ExceptSRE&quot;,
      &quot;Effect&quot;: &quot;Deny&quot;,
      &quot;Action&quot;: &quot;ec2:*&quot;,
      &quot;Resource&quot;: &quot;*&quot;,
      &quot;Condition&quot;: {
        &quot;ArnNotLike&quot;: {
          &quot;aws:PrincipalArn&quot;: [
            &quot;arn:aws:iam::*:role/SRERole&quot;,
            &quot;arn:aws:iam::*:role/SecurityAdminRole&quot;
          ]
        }
      }
    }
  ]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SRERole과 SecurityAdminRole을 가진 사람은 EC2 접근 가능, 나머지는 차단됩니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Step 5: 정리&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실습이 끝나면 SCP를 반드시 분리하세요:&lt;/p&gt;
&lt;pre class=&quot;cmake&quot;&gt;&lt;code&gt;Organizations 콘솔 &amp;rarr; 멤버 계정 &amp;rarr; 정책
&amp;rarr; DenyEC2-Test &amp;rarr; 분리(Detach)
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;7. IAM Access Analyzer&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;7-1. Access Analyzer가 필요한 이유&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;권한을 주는 것은 쉽지만, 시간이 지나면서 &lt;b&gt;의도치 않게 과도해진 권한&lt;/b&gt;이 쌓입니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;6개월 전에 프로젝트용으로 만든 IAM Role이 지금도 AdministratorAccess를 갖고 있음&lt;/li&gt;
&lt;li&gt;S3 버킷이 실수로 퍼블릭으로 열려 있었는데 아무도 몰랐음&lt;/li&gt;
&lt;li&gt;테스트용 Lambda 함수의 역할이 삭제되지 않고 계속 존재함&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IAM Access Analyzer는 이런 문제를 &lt;b&gt;지속적으로 탐지하고 알려주는 서비스&lt;/b&gt;입니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;7-2. Access Analyzer의 세 가지 분석 유형&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;① 외부 액세스 분석기 (External Access Analyzer) &amp;mdash; 무료&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;신뢰 영역(Trust Zone, 보통 하나의 계정 또는 Organizations) 외부에서 접근할 수 있는 리소스를 탐지합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;분석 대상:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;S3 버킷 (버킷 정책, ACL)&lt;/li&gt;
&lt;li&gt;IAM Role (신뢰 정책)&lt;/li&gt;
&lt;li&gt;KMS 키&lt;/li&gt;
&lt;li&gt;Lambda 함수/계층&lt;/li&gt;
&lt;li&gt;SQS 대기열&lt;/li&gt;
&lt;li&gt;Secrets Manager 비밀&lt;/li&gt;
&lt;li&gt;ECR 리포지토리&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시 결과:&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;S3 버킷 'prod-data-bucket'이 공개적으로 읽기 가능합니다
IAM Role 'AnalyticsRole'이 외부 계정 999999999 에서 AssumeRole 가능합니다&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;② 미사용 액세스 분석기 (Unused Access Analyzer) &amp;mdash; 유료 ($0.2/IAM엔터티/월)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제로 사용되지 않는 권한, 자격 증명, 역할을 탐지합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시 결과:&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;IAM Role 'OldProjectRole' &amp;mdash; 180일 이상 사용되지 않음
IAM User 'alice' &amp;mdash; S3 권한이 부여됐지만 S3를 한 번도 사용하지 않음 (90일)
Access Key AKIA... &amp;mdash; 60일 이상 미사용&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;③ 정책 검증 (Policy Validation) &amp;mdash; 무료&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;새 정책을 작성하거나 저장할 때 100개 이상의 보안 모범 사례 체크를 수행합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시 경고:&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;이 정책은 와일드카드 액션(*) 을 사용합니다. 최소 권한을 위해 구체적인 액션을 지정하세요
이 정책의 리소스 ARN 형식이 잘못되었습니다&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;7-3. 신뢰 영역(Trust Zone) 설정&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;분석기를 만들 때 &lt;b&gt;신뢰 영역&lt;/b&gt;을 설정합니다. 이 영역 밖에서의 접근이 &quot;외부 접근&quot;으로 분류됩니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;계정 수준 분석기&lt;/b&gt;: 해당 계정 외부 = 외부 접근&lt;/li&gt;
&lt;li&gt;&lt;b&gt;조직 수준 분석기&lt;/b&gt;: Organizations 외부 = 외부 접근 (같은 조직 내 계정 간 접근은 내부로 간주)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대부분의 기업은 Organizations 전체를 신뢰 영역으로 설정하고, 조직 외부에서 접근 가능한 리소스를 모니터링합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;7-4. 실습: Access Analyzer 설정 및 결과 확인&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Step 1: 외부 액세스 분석기 생성&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;IAM 콘솔 &amp;rarr; Access Analyzer &amp;rarr; 분석기 생성

이름: external-access-analyzer
유형: 외부 액세스 분석기
신뢰 영역: AWS 계정 (단일 계정) 또는 조직 선택

&amp;rarr; 분석기 생성&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생성 직후부터 분석이 시작되며 수 분 내에 결과가 나타납니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Step 2: 결과 확인 및 처리&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;elixir&quot;&gt;&lt;code&gt;Access Analyzer &amp;rarr; 활성 결과(Active Findings)

예시 결과:
┌─────────────────────────────────────────────────────┐
│ 리소스: arn:aws:s3:::my-test-bucket                 │
│ 액세스 유형: Public                                 │
│ 원인: 버킷 정책이 모든 보안 주체에게 읽기 허용      │
│ 상태: Active                                       │
└─────────────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과에 대해 취할 수 있는 조치:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;아카이브(Archive)&lt;/b&gt;: 의도된 공개 접근이면 아카이브 (이후 변경 시 재활성화)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;해결(Resolve)&lt;/b&gt;: 버킷 정책을 수정하여 실제로 문제를 해결&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Step 3: CLI로 결과 조회&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;# 분석기 목록 조회
aws accessanalyzer list-analyzers

# 활성 결과 조회
aws accessanalyzer list-findings \
  --analyzer-arn &quot;arn:aws:accessanalyzer:ap-northeast-2:ACCOUNT_ID:analyzer/external-access-analyzer&quot; \
  --filter '{&quot;status&quot;: {&quot;eq&quot;: [&quot;ACTIVE&quot;]}}'

# 결과를 JSON으로 출력하여 보안 팀 리포트 생성
aws accessanalyzer list-findings \
  --analyzer-arn &quot;arn:aws:accessanalyzer:...&quot; \
  --query 'findings[*].{Resource:resource,Type:resourceType,Status:status}' \
  --output table&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Step 4: 미사용 액세스 분석기 생성 (유료)&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;Access Analyzer &amp;rarr; 분석기 생성

이름: unused-access-analyzer
유형: 미사용 액세스 분석기
미사용 액세스 기간: 90일 (이 기간 이상 미사용 시 결과 생성)
범위: 계정 또는 조직&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;90일 동안 사용되지 않은 역할, 사용자, 액세스 키 목록이 생성됩니다. 이를 주기적으로 검토하고 불필요한 권한을 제거합니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;8. Organizations + SCP + Identity Center 통합 뷰&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금까지 배운 것들이 어떻게 연결되는지 정리합니다.&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;AWS Organizations (계정 구조 및 거버넌스)
    │
    ├── SCP (계정 단위 최대 권한 상한선)
    │       &amp;darr; 상속
    │   루트 &amp;rarr; OU &amp;rarr; 계정
    │
    ├── IAM Identity Center (SSO 접근)
    │       &amp;darr;
    │   Permission Set &amp;rarr; IAM Role (각 계정에 자동 생성)
    │       &amp;darr;
    │   사용자가 해당 Role 수임 &amp;rarr; SCP 범위 내에서만 작업 가능
    │
    └── IAM Access Analyzer (권한 지속 모니터링)
            &amp;darr;
        외부 접근 탐지, 미사용 권한 탐지&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최종 권한 결정 공식:&lt;/p&gt;
&lt;pre class=&quot;crmsh&quot;&gt;&lt;code&gt;실제 허용 = (IAM Policy가 Allow) &amp;cap; (SCP가 Allow) &amp;cap; (Permission Boundary가 Allow)
단, 어디서든 Explicit Deny가 있으면 무조건 DENY
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;AWS Organizations:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;다중 계정을 중앙에서 관리하는 서비스&lt;/li&gt;
&lt;li&gt;관리 계정 + 멤버 계정 + OU 계층 구조&lt;/li&gt;
&lt;li&gt;관리 계정에 워크로드 배포 금지&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;SCP:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;계정 단위의 최대 권한 상한선 &amp;mdash; 권한을 부여하지 않고 제한만 함&lt;/li&gt;
&lt;li&gt;루트 &amp;rarr; OU &amp;rarr; 계정 순으로 상속&lt;/li&gt;
&lt;li&gt;IAM Policy와 교집합이 실제 유효 권한&lt;/li&gt;
&lt;li&gt;관리 계정, 서비스 연결 역할에는 미적용&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;OU 설계:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;조직도가 아닌, 같은 제어 정책이 필요한 계정끼리 묶기&lt;/li&gt;
&lt;li&gt;Security / Infrastructure / Workloads(Prod + SDLC) / Sandbox 기본 구조&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;IAM Access Analyzer:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;외부 접근 분석기: 의도치 않게 열린 리소스 탐지 (무료)&lt;/li&gt;
&lt;li&gt;미사용 액세스 분석기: 오래된 권한, 미사용 역할 탐지 (유료)&lt;/li&gt;
&lt;li&gt;정책 검증: 새 정책 작성 시 모범 사례 체크 (무료)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;참고 자료&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.aws.amazon.com/ko_kr/organizations/latest/userguide/orgs_getting-started_concepts.html&quot;&gt;AWS 공식 문서: AWS Organizations 개념&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.aws.amazon.com/ko_kr/organizations/latest/userguide/orgs_manage_policies_scps.html&quot;&gt;AWS 공식 문서: 서비스 제어 정책(SCP)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.aws.amazon.com/ko_kr/organizations/latest/userguide/orgs_manage_policies_scps_examples.html&quot;&gt;AWS 공식 문서: SCP 예제&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.aws.amazon.com/ko_kr/organizations/latest/userguide/orgs_manage_ous_best_practices.html&quot;&gt;AWS 공식 문서: OU 관리 모범 사례&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.aws.amazon.com/ko_kr/IAM/latest/UserGuide/access-analyzer-concepts.html&quot;&gt;AWS 공식 문서: IAM Access Analyzer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://repost.aws/ko/knowledge-center/iam-policy-service-control-policy&quot;&gt;AWS re:Post: IAM 정책과 SCP의 상호작용 방식&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://towardsthecloud.com/blog/aws-scp-service-control-policies&quot;&gt;Towards the Cloud: SCP 완전 구현 가이드&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>AWS</category>
      <category>AWS Organizations</category>
      <category>OU</category>
      <category>scp</category>
      <author>lhywk</author>
      <guid isPermaLink="true">https://lhywk.tistory.com/108</guid>
      <comments>https://lhywk.tistory.com/108#entry108comment</comments>
      <pubDate>Sat, 2 May 2026 12:57:30 +0900</pubDate>
    </item>
    <item>
      <title>IAM Identity Center</title>
      <link>https://lhywk.tistory.com/107</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;개발 계정, 스테이징 계정, 프로덕션 계정, 보안 계정, 로깅 계정 &amp;mdash; AWS Organizations를 잘 쓰는 기업이라면 계정이 수십 개입니다. 각 계정마다 Federation을 따로 설정하고, IAM Role을 따로 만들고, 사용자를 따로 관리한다면 운영 비용이 폭발합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;AWS IAM Identity Center&lt;/b&gt;는 이 문제를 해결하기 위해 만들어진 서비스입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&quot;계정 하나에 로그인하면, 권한이 있는 모든 계정에 클릭 한 번으로 전환&quot;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이것이 IAM Identity Center가 해결하는 핵심 문제입니다.&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. IAM Identity Center란?&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1-1. 이름의 역사&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IAM Identity Center는 2022년 7월 이전까지 &lt;b&gt;AWS Single Sign-On(AWS SSO)&lt;/b&gt; 이라고 불렸습니다. 기능이 크게 확장되면서 이름이 바뀌었지만, API 네임스페이스(sso, identitystore)는 하위 호환성을 위해 그대로 유지됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문서나 블로그에서 &quot;AWS SSO&quot;를 보더라도 IAM Identity Center와 같은 서비스입니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1-2. IAM Identity Center가 해결하는 문제&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;기존 방식의 문제점:&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;계정 A (개발)      &amp;rarr; IAM User alice_dev / 별도 비밀번호
계정 B (스테이징)  &amp;rarr; IAM User alice_stg / 또 다른 비밀번호
계정 C (프로덕션)  &amp;rarr; IAM User alice_prod / 또 다른 비밀번호&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 방식은:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;계정마다 별도 IAM User 관리 필요&lt;/li&gt;
&lt;li&gt;퇴사 시 모든 계정에서 일일이 비활성화해야 함&lt;/li&gt;
&lt;li&gt;MFA도 계정마다 따로 설정&lt;/li&gt;
&lt;li&gt;CloudTrail 로그에 IAMUser:alice_prod 처럼 계정별 다른 identity로 기록 &amp;rarr; 추적 어려움&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;IAM Identity Center 방식:&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;회사 IdP (Okta / Azure AD / AWS 내부 디렉터리)
    &amp;darr; 한 번 로그인
IAM Identity Center
    &amp;darr; 클릭 한 번으로
계정 A (개발)     &amp;rarr; 자동 임시 자격 증명 발급
계정 B (스테이징) &amp;rarr; 자동 임시 자격 증명 발급
계정 C (프로덕션) &amp;rarr; 자동 임시 자격 증명 발급&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;퇴사 시 IdP에서 계정 하나만 비활성화하면 모든 AWS 계정 접근이 차단됩니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1-3. IAM Identity Center vs 직접 IAM Federation&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IAM 직접 Federation(SAML/OIDC)과 비교하면:&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;항목&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;직접 IAM Federation&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;IAM Identity Center&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;설정 복잡도&lt;/td&gt;
&lt;td&gt;계정마다 별도 설정&lt;/td&gt;
&lt;td&gt;한 번 설정, 전체 계정 적용&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;다중 계정&lt;/td&gt;
&lt;td&gt;어려움 (각 계정 개별 설정)&lt;/td&gt;
&lt;td&gt;핵심 기능 (다중 계정 통합)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Permission 관리&lt;/td&gt;
&lt;td&gt;계정마다 IAM Role 직접 설정&lt;/td&gt;
&lt;td&gt;Permission Set 중앙 관리&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CLI 지원&lt;/td&gt;
&lt;td&gt;복잡한 AssumeRole 설정&lt;/td&gt;
&lt;td&gt;aws sso login 명령어 하나&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;감사&lt;/td&gt;
&lt;td&gt;계정별 분산&lt;/td&gt;
&lt;td&gt;IAM Identity Center 중앙 통합&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AWS 권장 방향&lt;/td&gt;
&lt;td&gt;단순 환경&lt;/td&gt;
&lt;td&gt;&lt;b&gt;다중 계정 환경의 표준&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. IAM Identity Center의 핵심 구성 요소&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2-1. 자격 증명 소스 (Identity Source)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IAM Identity Center는 사용자를 직접 관리하지 않습니다. &lt;b&gt;외부의 자격 증명 소스에서 사용자를 가져옵니다.&lt;/b&gt; 세 가지 옵션이 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;옵션 1: IAM Identity Center 내부 디렉터리 (기본값)&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;IAM Identity Center 자체에 사용자/그룹을 직접 생성&lt;/li&gt;
&lt;li&gt;외부 IdP가 없는 스타트업이나 소규모 팀에 적합&lt;/li&gt;
&lt;li&gt;가장 빠르게 시작할 수 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;옵션 2: Active Directory (AWS Managed AD 또는 AD Connector)&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;AD와 연동&lt;/li&gt;
&lt;li&gt;기업 AD 그룹이 IAM Identity Center 그룹으로 동기화됨&lt;/li&gt;
&lt;li&gt;온프레미스 AD 사용자가 AWS에 SSO 접근 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;옵션 3: 외부 IdP (Okta, Azure AD, Google Workspace 등)&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;SAML 2.0으로 인증 연결&lt;/li&gt;
&lt;li&gt;SCIM으로 사용자/그룹 자동 동기화&lt;/li&gt;
&lt;li&gt;대부분의 기업이 선호하는 방식&lt;b&gt;&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;중요한 특성:&lt;/b&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt; 외부 IdP를 자격 증명 소스로 사용할 때, IAM Identity Center는 사용자의 &lt;/span&gt;&lt;b&gt;비밀번호나 MFA 디바이스를 저장하지 않습니다&lt;/b&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;. 인증은 여전히 외부 IdP가 담당하고, IAM Identity Center는 권한 부여를 담당합니다. 사용자 이름과 그룹 멤버십 같은 속성의 동기화된 복사본만 보관합니다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2-2. Permission Set (권한 세트)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Permission Set은 &lt;b&gt;IAM Identity Center의 핵심 개념&lt;/b&gt;입니다. IAM Role의 템플릿이라고 생각하면 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공식 정의: 권한 세트는 하나 이상의 IAM 정책 컬렉션을 정의하는 템플릿으로, 조직의 사용자 및 그룹에 대한 AWS 계정 액세스 할당을 간소화합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Permission Set을 계정에 할당하면, 해당 계정에 &lt;b&gt;자동으로 IAM Role이 생성됩니다.&lt;/b&gt; 사용자가 그 계정에 접속하면 이 Role을 자동으로 수임(AssumeRole)하는 방식입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Permission Set의 구성:&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;Permission Set: &quot;Developer&quot;
├── AWS 관리형 정책: PowerUserAccess
├── 고객 관리형 정책: CompanyDevPolicy
├── 인라인 정책: (선택 사항)
└── Permission Boundary: (선택 사항)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Permission Set의 핵심 특성:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;계정마다 IAM Role을 직접 만들 필요가 없음&lt;/li&gt;
&lt;li&gt;Permission Set 하나를 수십 개의 계정에 동시에 적용 가능&lt;/li&gt;
&lt;li&gt;Permission Set을 수정하면, 연결된 모든 계정의 IAM Role이 자동 업데이트&lt;/li&gt;
&lt;li&gt;세션 기간 설정 가능 (기본 1시간, 최대 12시간)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2-3. 계정 할당 (Account Assignment)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;할당(Assignment)은 &lt;b&gt;&quot;누가, 어떤 계정에, 어떤 Permission Set으로 접근 가능한가&quot;&lt;/b&gt; 를 정의합니다.&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;[Alice] + [개발 계정] + [Developer Permission Set] &amp;rarr; Alice는 개발 계정에 Developer로 접근 가능
[Alice] + [프로덕션 계정] + [ReadOnly Permission Set] &amp;rarr; Alice는 프로덕션 계정에 ReadOnly로만 접근 가능
[DB팀 그룹] + [모든 계정] + [DBA Permission Set] &amp;rarr; DB팀 전원이 모든 계정에 DBA 권한으로 접근 가능&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그룹에 할당하면 그룹 멤버십 변경으로 권한이 자동 조정됩니다. 신입 사원이 &quot;개발팀&quot; 그룹에 추가되는 순간 개발 계정 접근 권한이 자동으로 부여됩니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2-4. AWS 액세스 포털 (Access Portal)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용자가 실제로 접속하는 웹 인터페이스입니다. 주소는 https://[조직별 서브도메인].awsapps.com/start 형태입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로그인하면:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;접근 권한이 있는 모든 AWS 계정 목록&lt;/li&gt;
&lt;li&gt;각 계정별 사용 가능한 Permission Set (역할)&lt;/li&gt;
&lt;li&gt;클릭 한 번으로 해당 계정의 AWS 콘솔 접속&lt;/li&gt;
&lt;li&gt;임시 자격 증명 (CLI/SDK용) 복사&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1440&quot; data-origin-height=&quot;1060&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lpbsq/dJMcafmaFG9/SQWPtuvoZn35zLyEGJGClk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lpbsq/dJMcafmaFG9/SQWPtuvoZn35zLyEGJGClk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lpbsq/dJMcafmaFG9/SQWPtuvoZn35zLyEGJGClk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Flpbsq%2FdJMcafmaFG9%2FSQWPtuvoZn35zLyEGJGClk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1440&quot; height=&quot;1060&quot; data-origin-width=&quot;1440&quot; data-origin-height=&quot;1060&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. IAM Identity Center의 내부 동작 원리&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3-1. 로그인부터 AWS 콘솔 접속까지&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;표면적으로는 &quot;로그인하고 계정 클릭&quot;이지만, 내부에서는 다음이 일어납니다.&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;사용자 &amp;rarr; Access Portal 접속
   &amp;darr;
IdP 인증 (Okta/Azure AD/내부 디렉터리)
   &amp;darr;
IAM Identity Center: 세션 토큰 발급 (포털 세션, 기본 8시간)
   &amp;darr;
사용자가 계정 + Permission Set 선택
   &amp;darr;
IAM Identity Center &amp;rarr; STS AssumeRole 내부 호출
   &amp;darr;
해당 계정에 자동 생성된 IAM Role 수임
   &amp;darr;
단기 자격 증명 반환 (기본 1시간)
   &amp;darr;
AWS 콘솔 세션 시작 / CLI 임시 자격 증명 사용&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3-2. 두 가지 세션의 구분&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IAM Identity Center에는 두 종류의 세션이 있습니다. 이 구분을 이해하지 못하면 &quot;왜 1시간마다 다시 로그인해야 하지?&quot;라는 혼란이 생깁니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;① 포털 세션 (Access Portal Session)&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Access Portal(awsapps.com/start)에 로그인한 세션&lt;/li&gt;
&lt;li&gt;기본 8시간, 최대 90일까지 설정 가능&lt;/li&gt;
&lt;li&gt;이 세션이 유효한 동안 재인증 없이 계정을 전환할 수 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;② 권한 세트 세션 (Permission Set Session)&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;특정 계정 + Permission Set으로 발급된 임시 자격 증명 세션&lt;/li&gt;
&lt;li&gt;기본 1시간, 최대 12시간&lt;/li&gt;
&lt;li&gt;이 세션이 만료되면 포털에서 다시 클릭해야 함 (포털 재로그인은 불필요)&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;포털 세션 (8시간) ──────────────────────────────────────────────&amp;rarr;
                 권한세트 세션(1h)  권한세트 세션(1h)  권한세트 세션(1h) ...
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CLI를 사용할 때는 토큰 자동 갱신이 지원됩니다. IAM Identity Center의 액세스 토큰은 매시간 확인되며 새로 고침 토큰을 사용하여 자동으로 새로 고쳐집니다. 포털 세션이 유효한 동안 CLI는 자동으로 자격 증명을 갱신합니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4. 외부 IdP 연동 &amp;mdash; SAML + SCIM&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4-1. SAML과 SCIM의 역할 분리&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;외부 IdP(Okta, Azure AD 등)와 연동할 때 두 가지 프로토콜이 함께 사용됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;SAML 2.0 &amp;rarr; 인증(Authentication)&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;사용자가 누구인지 확인하는 역할&lt;/li&gt;
&lt;li&gt;IdP가 SAML Assertion을 발급 &amp;rarr; IAM Identity Center가 사용자 인증&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;SCIM 2.0 &amp;rarr; 프로비저닝(Provisioning)&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;사용자/그룹 정보를 자동 동기화하는 역할&lt;/li&gt;
&lt;li&gt;IdP에서 SCIM 프로토콜로 IAM Identity Center로 사용자 정보를 실시간 푸시&lt;/li&gt;
&lt;li&gt;사용자 생성/수정/삭제, 그룹 멤버십 변경이 자동 반영&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SAML만 쓰고 SCIM이 없으면 어떻게 될까요? IAM Identity Center는 인증은 할 수 있지만, &lt;b&gt;누가 어떤 그룹에 속하는지 알 수 없습니다.&lt;/b&gt; SAML 프로토콜 자체는 사용자/그룹 정보를 조회하는 기능을 제공하지 않기 때문에, IAM Identity Center에 미리 사용자와 그룹을 수동으로 프로비저닝하거나, SCIM을 통해 자동화해야 합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4-2. SCIM 동작 방식&lt;/h3&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;Okta (IdP)
   │
   │ 사용자 추가/수정/삭제 발생
   │
   ├─ SCIM API POST/PUT/DELETE
   &amp;darr;
IAM Identity Center SCIM 엔드포인트
   https://scim.us-east-1.amazonaws.com/[인스턴스ID]/scim/v2
   │
   ├─ 사용자 동기화
   ├─ 그룹 동기화
   └─ 멤버십 동기화&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SCIM으로 동기화되는 것:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;사용자 이름(username), 이메일, 이름, 부서 등 속성&lt;/li&gt;
&lt;li&gt;그룹 및 그룹 멤버십&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SCIM으로 동기화되지 않는 것:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;비밀번호 (인증은 여전히 IdP가 담당)&lt;/li&gt;
&lt;li&gt;MFA 디바이스&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4-3. 지원하는 외부 IdP&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IdP SAML 지원 SCIM 지원 AWS 공식 통합 가이드&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;IdP&lt;/td&gt;
&lt;td&gt;SAML 지원&amp;nbsp;&lt;/td&gt;
&lt;td&gt;SCIM 지원&lt;/td&gt;
&lt;td&gt;AWS 공식 통합 가이드&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Okta&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Microsoft Entra ID (Azure AD)&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Google Workspace&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅ (제한적)&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OneLogin&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PingFederate&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;JumpCloud&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Active Directory (직접)&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;AD 동기화&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1440&quot; data-origin-height=&quot;840&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cvUtYP/dJMcahYzrFx/QxbSdn5gvHqIFTMwaQCmGK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cvUtYP/dJMcahYzrFx/QxbSdn5gvHqIFTMwaQCmGK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cvUtYP/dJMcahYzrFx/QxbSdn5gvHqIFTMwaQCmGK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcvUtYP%2FdJMcahYzrFx%2FQxbSdn5gvHqIFTMwaQCmGK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1440&quot; height=&quot;840&quot; data-origin-width=&quot;1440&quot; data-origin-height=&quot;840&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;5. Permission Set 설계 전략&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Permission Set 설계는 IAM Identity Center에서 가장 중요한 의사결정 중 하나입니다. 잘못 설계하면 관리가 복잡해지고, 잘 설계하면 수십 개 계정을 몇 개의 Permission Set으로 깔끔하게 관리할 수 있습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;5-1. 직무 기반 (Job Function) 설계&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 일반적이고 권장되는 방식입니다. &lt;b&gt;업무 역할에 맞춰 Permission Set을 설계&lt;/b&gt;합니다.&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;Permission Sets:
├── AdministratorAccess   &amp;rarr; DevOps/인프라팀 관리자
├── PowerUserAccess       &amp;rarr; 개발자 (IAM 관리 제외)
├── ReadOnlyAccess        &amp;rarr; 뷰어, 감사, BI팀
├── DatabaseAdmin         &amp;rarr; DB 관리자 (RDS, DynamoDB 등)
├── SecurityAudit         &amp;rarr; 보안팀 감사용
├── BillingAdmin          &amp;rarr; 재무팀 (Cost Explorer, Budgets)
└── NetworkAdmin          &amp;rarr; 네트워크팀 (VPC, Route53 등)&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;5-2. 환경별 권한 차등&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;같은 사람에게 환경마다 다른 권한 레벨&lt;/b&gt;을 부여하는 패턴입니다.&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;[개발자 Alice]
├── 개발 계정     &amp;rarr; PowerUserAccess (자유롭게 개발)
├── 스테이징 계정 &amp;rarr; ReadOnlyAccess + 특정 서비스 배포 권한
└── 프로덕션 계정 &amp;rarr; ReadOnlyAccess (읽기 전용, 배포는 CI/CD로만)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 패턴이 중요한 이유: 개발자가 실수로 프로덕션을 건드리는 것을 구조적으로 방지합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;5-3. Permission Set에 Permission Boundary 적용&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Permission Set에도 2편에서 다룬 &lt;b&gt;Permission Boundary&lt;/b&gt;를 적용할 수 있습니다. 이를 통해 개발자가 실수로 IAM 권한을 확장하더라도, Boundary 범위를 벗어나지 못하도록 안전망을 추가할 수 있습니다.&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;Permission Set: Developer
├── 정책: PowerUserAccess
└── Permission Boundary: DeveloperBoundaryPolicy
    (IAM 변경, Billing 접근 등 차단)&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;5-4. 계정 수에 따른 할당 전략&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;소규모 (계정 5개 이하):&lt;/b&gt; 개별 계정에 직접 할당 &lt;b&gt;중규모 (계정 10~50개):&lt;/b&gt; 계정 태그나 OU 단위로 그룹 할당 &lt;b&gt;대규모 (계정 50개 이상):&lt;/b&gt; Infrastructure as Code(Terraform, CDK)로 할당 자동화&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;6. AWS CLI에서 IAM Identity Center 사용하기&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;6-1. 왜 CLI 설정이 중요한가&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IAM Identity Center를 사용하면 Access Key를 발급할 필요가 없습니다. 대신 aws sso login 명령으로 브라우저 인증을 거쳐 임시 자격 증명을 자동으로 받아옵니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 방식의 장점:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Access Key 유출 위험 없음&lt;/li&gt;
&lt;li&gt;자동 만료 + 자동 갱신&lt;/li&gt;
&lt;li&gt;여러 계정/역할을 프로파일로 쉽게 전환&lt;/li&gt;
&lt;li&gt;MFA가 브라우저 로그인에서 이미 처리됨&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;6-2. CLI 설정 방법&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;방법 1: 대화형 설정 (처음 설정할 때)&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;aws configure sso

SSO session name (Recommended): company-sso
SSO start URL [None]: https://d-1234567890.awsapps.com/start
SSO region [None]: ap-northeast-2
SSO registration scopes [sso:account:access]: (Enter)

# 브라우저가 열리며 로그인 진행
# 로그인 후 CLI로 돌아오면 계정 목록이 표시됨

# 사용할 계정/역할 선택
The only AWS account available to you is: 123456789012
Using the account ID 123456789012
The only role available to you is: Developer
Using the role name &quot;Developer&quot;

# 프로파일 이름 설정
CLI default client Region [ap-northeast-2]: ap-northeast-2
CLI default output format [None]: json
CLI profile name [Developer-123456789012]: dev-developer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;방법 2: ~/.aws/config 직접 편집&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;# ~/.aws/config

# SSO 세션 정의 (공통)
[sso-session company]
sso_start_url = https://d-1234567890.awsapps.com/start
sso_region = ap-northeast-2
sso_registration_scopes = sso:account:access

# 개발 계정 - Developer 역할
[profile dev-developer]
sso_session = company
sso_account_id = 111111111111
sso_role_name = Developer
region = ap-northeast-2
output = json

# 스테이징 계정 - ReadOnly 역할
[profile stg-readonly]
sso_session = company
sso_account_id = 222222222222
sso_role_name = ReadOnly
region = ap-northeast-2
output = json

# 프로덕션 계정 - ReadOnly 역할
[profile prod-readonly]
sso_session = company
sso_account_id = 333333333333
sso_role_name = ReadOnly
region = ap-northeast-2
output = json

# 프로덕션 계정 - Administrator (긴급 사용)
[profile prod-admin]
sso_session = company
sso_account_id = 333333333333
sso_role_name = AdministratorAccess
region = ap-northeast-2
output = json&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;방법 3: 로그인 및 사용&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;# SSO 로그인 (브라우저 열림, 한 번만 하면 세션 동안 유효)
aws sso login --sso-session company

# 개발 계정에서 작업
aws s3 ls --profile dev-developer
aws ec2 describe-instances --profile dev-developer

# 프로덕션은 ReadOnly
aws s3 ls --profile prod-readonly
aws ec2 terminate-instances ... --profile prod-readonly
# &amp;rarr; 권한 없음 오류 (의도된 동작)

# 현재 어떤 자격 증명인지 확인
aws sts get-caller-identity --profile dev-developer

# 로그아웃
aws sso logout&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;6-3. 자동 자격 증명 갱신&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IAM Identity Center CLI 설정의 큰 장점 중 하나는 &lt;b&gt;자동 자격 증명 갱신&lt;/b&gt;입니다. 포털 세션이 유효한 동안 AWS CLI와 SDK는 자격 증명이 만료되기 전에 자동으로 새로운 자격 증명을 갱신합니다. 덕분에 오래 실행되는 스크립트나 배치 작업 중 자격 증명이 만료되어 실패하는 상황을 방지할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인증 토큰 캐시는 ~/.aws/sso/cache/ 디렉터리에 저장됩니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;7. 실습: IAM Identity Center 설정부터 CLI 사용까지&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;전제 조건:&lt;/b&gt;&lt;span style=&quot;color: #333333; font-size: 16px; letter-spacing: 0px;&quot;&gt; AWS Organizations가 활성화되어 있어야 합니다. (관리 계정에서 IAM Identity Center를 활성화합니다)&lt;/span&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Step 1: IAM Identity Center 활성화&lt;/h3&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;IAM Identity Center 콘솔 &amp;rarr; [Enable] 클릭

&amp;rarr; 조직 인스턴스 선택 (권장, Organizations 관리 계정에 배포)
&amp;rarr; 활성화 완료 (몇 초 이내)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;활성화 후 &lt;b&gt;AWS 액세스 포털 URL&lt;/b&gt; 확인:&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;설정 &amp;rarr; AWS 액세스 포털 URL:
https://d-1234567890.awsapps.com/start&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 URL을 직원들에게 공유합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Step 2: 내부 디렉터리로 사용자/그룹 생성 (외부 IdP가 없는 경우)&lt;/h3&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;IAM Identity Center &amp;rarr; 사용자 &amp;rarr; 사용자 추가

사용자 이름: alice
이름: Alice Kim
이메일: alice@example.com
&amp;rarr; 사용자 추가

# 비밀번호 설정 이메일이 alice@example.com으로 발송됨&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;IAM Identity Center &amp;rarr; 그룹 &amp;rarr; 그룹 생성

그룹 이름: Developers
설명: 개발팀 멤버
&amp;rarr; 그룹 생성 &amp;rarr; alice 추가&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Step 3: Permission Set 생성&lt;/h3&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;IAM Identity Center &amp;rarr; 권한 세트 &amp;rarr; 권한 세트 생성

[타입 선택]
사전 정의된 권한 세트 &amp;rarr; PowerUserAccess 선택
(또는 사용자 지정으로 직접 정책 구성)

[세부 정보]
권한 세트 이름: Developer
설명: 개발자용 - IAM 관리 제외 전체 서비스
세션 기간: 4시간

&amp;rarr; 생성&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;고급 설정 (추가 정책 연결):&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;권한 세트 &amp;rarr; Developer &amp;rarr; 편집
&amp;rarr; AWS 관리형 정책 추가: 필요한 경우 추가
&amp;rarr; 고객 관리형 정책 추가: 사내 커스텀 정책
&amp;rarr; 권한 경계 설정: DeveloperBoundary (선택)&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Step 4: 계정에 할당&lt;/h3&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;IAM Identity Center &amp;rarr; AWS 계정 &amp;rarr; [계정 선택]
&amp;rarr; 사용자 및 그룹 할당

[계정: 개발 계정 (111111111111)]
&amp;rarr; 그룹 할당: Developers
&amp;rarr; 권한 세트: Developer
&amp;rarr; 할당

# 자동으로 개발 계정에 IAM Role이 생성됨
# Role 이름: AWSReservedSSO_Developer_[고유ID]&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Step 5: 사용자 입장에서 로그인&lt;/h3&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;1. https://d-1234567890.awsapps.com/start 접속
2. alice / 비밀번호 로그인 (MFA 설정 권장)
3. 화면에 접근 가능한 계정 목록 표시:
   ┌─────────────────────────────────┐
   │ 개발 계정 (111111111111)        │
   │ Developer                [접속] │
   │ [자격 증명 복사]                │
   └─────────────────────────────────┘
4. [접속] 클릭 &amp;rarr; 개발 계정 AWS 콘솔로 이동&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Step 6: CLI 설정 및 사용&lt;/h3&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;# AWS CLI v2 설치 확인
aws --version
# aws-cli/2.x.x 이상이어야 함 (v1은 SSO 지원 제한적)

# 대화형 SSO 설정
aws configure sso

SSO session name: mycompany
SSO start URL: https://d-1234567890.awsapps.com/start
SSO region: ap-northeast-2

# 브라우저에서 로그인 완료 후
# 계정 및 역할 선택 &amp;rarr; 프로파일 이름 입력
CLI profile name: dev

# 사용
aws sso login --sso-session mycompany
aws s3 ls --profile dev
aws sts get-caller-identity --profile dev&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;예상 출력:&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;{
    &quot;UserId&quot;: &quot;AROA...:alice&quot;,
    &quot;Account&quot;: &quot;111111111111&quot;,
    &quot;Arn&quot;: &quot;arn:aws:sts::111111111111:assumed-role/AWSReservedSSO_Developer_xxxx/alice&quot;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;alice라는 사용자 이름이 CloudTrail 로그에도 기록됩니다. 여러 계정을 쓰더라도 동일한 identity로 추적 가능합니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;8. 외부 IdP 연동 실습 &amp;mdash; Okta 또는 Azure AD&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;8-1. Azure AD (Microsoft Entra ID) 연동 개요&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;전체 설정 흐름:&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;[1단계: Azure 포털]
Enterprise Applications &amp;rarr; AWS IAM Identity Center 앱 추가
&amp;rarr; SSO 설정 (SAML) &amp;rarr; 페더레이션 메타데이터 XML 다운로드

[2단계: IAM Identity Center 콘솔]
설정 &amp;rarr; ID 소스 변경 &amp;rarr; 외부 ID 제공업체
&amp;rarr; Azure AD 메타데이터 XML 업로드
&amp;rarr; IAM Identity Center 메타데이터 다운로드 &amp;rarr; Azure에 업로드

[3단계: SCIM 설정]
IAM Identity Center &amp;rarr; 설정 &amp;rarr; 자동 프로비저닝 활성화
&amp;rarr; SCIM 엔드포인트 URL + 액세스 토큰 복사
&amp;rarr; Azure AD 프로비저닝 탭에서 입력

[4단계: 사용자/그룹 Azure에서 할당]
Azure AD &amp;rarr; IAM Identity Center 앱 &amp;rarr; 사용자/그룹 할당
&amp;rarr; 자동으로 IAM Identity Center에 동기화됨
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;8-2. SCIM 자동 프로비저닝 핵심 명령&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IAM Identity Center 콘솔에서 SCIM을 활성화합니다:&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;IAM Identity Center &amp;rarr; 설정 &amp;rarr; 자동 프로비저닝
&amp;rarr; [활성화] 클릭

인바운드 자동 프로비저닝 정보:
SCIM 엔드포인트: https://scim.ap-northeast-2.amazonaws.com/[ID]/scim/v2/
액세스 토큰: [토큰 표시] &amp;larr; 이 값을 반드시 복사해두세요 (이후 재확인 불가)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;주의:&lt;/b&gt; SCIM 액세스 토큰은 생성 시 한 번만 전체 값을 볼 수 있습니다. 이 토큰을 외부 IdP의 SCIM 설정에 입력합니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;9. 운영 시 고려사항&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;9-1. 퇴사자 처리 자동화&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IAM Identity Center의 가장 큰 보안 이점은 &lt;b&gt;퇴사자 처리 자동화&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SCIM이 설정된 경우:&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;1. HR에서 Okta/Azure AD 계정 비활성화
   &amp;darr;
2. SCIM이 IAM Identity Center에 사용자 비활성화 신호 전달
   &amp;darr;
3. IAM Identity Center가 사용자의 모든 활성 세션 즉시 종료
   &amp;darr;
4. 모든 AWS 계정 접근 차단 (자동, 즉시)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 과정이 수동이라면 사람이 수십 개의 계정에서 직접 하나씩 비활성화해야 하는데, 현실적으로 누락이 생기고 그 틈이 보안 위험이 됩니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;9-2. MFA 정책&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;내부 디렉터리 사용 시:&lt;/b&gt; IAM Identity Center에서 직접 MFA 정책을 설정합니다.&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;IAM Identity Center &amp;rarr; 설정 &amp;rarr; MFA
&amp;rarr; MFA 적용: 모든 사용자에게 필수
&amp;rarr; 허용 인증 방법: 인증 앱, 보안 키 (Passkey)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;외부 IdP 사용 시:&lt;/b&gt; MFA는 외부 IdP(Okta, Azure AD 등)에서 관리합니다. IAM Identity Center는 별도 MFA 설정이 필요 없습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;9-3. 감사 (CloudTrail 통합)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IAM Identity Center를 통한 모든 접근은 CloudTrail에 &lt;b&gt;사용자 이름 포함&lt;/b&gt; 기록됩니다.&lt;/p&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;{
  &quot;eventName&quot;: &quot;AssumeRoleWithSAML&quot;,
  &quot;userIdentity&quot;: {
    &quot;type&quot;: &quot;SAMLUser&quot;,
    &quot;principalId&quot;: &quot;...:alice@company.com&quot;,
    &quot;arn&quot;: &quot;arn:aws:sts::111111111111:assumed-role/AWSReservedSSO_Developer_xxx/alice@company.com&quot;
  },
  &quot;requestParameters&quot;: {
    &quot;roleArn&quot;: &quot;arn:aws:iam::111111111111:role/AWSReservedSSO_Developer_xxx&quot;,
    &quot;durationSeconds&quot;: 3600
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;alice@company.com이 무엇을 했는지 모든 계정에서 동일한 형식으로 추적됩니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;IAM Identity Center의 본질:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;다중 계정 환경에서 중앙 집중적 ID 관리와 SSO의 해결책&lt;/li&gt;
&lt;li&gt;계정마다 IAM User를 만들 필요 없음&lt;/li&gt;
&lt;li&gt;외부 IdP와 SAML+SCIM으로 연동하면 완전 자동화&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;핵심 구성 요소:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;자격 증명 소스: 어디서 사용자 정보를 가져오는가&lt;/li&gt;
&lt;li&gt;Permission Set: IAM Role 템플릿, 계정에 자동 Role 생성&lt;/li&gt;
&lt;li&gt;계정 할당: 누가, 어떤 계정에, 어떤 Permission Set으로&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;설계 원칙:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;직무 기반 Permission Set 설계&lt;/li&gt;
&lt;li&gt;환경마다 권한 차등 (개발 &amp;gt; 스테이징 &amp;gt; 프로덕션)&lt;/li&gt;
&lt;li&gt;Administrator는 세션 기간 짧게&lt;/li&gt;
&lt;li&gt;SCIM으로 퇴사자 처리 자동화&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;CLI:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;aws configure sso로 설정&lt;/li&gt;
&lt;li&gt;aws sso login으로 브라우저 인증&lt;/li&gt;
&lt;li&gt;Access Key 없이도 모든 AWS CLI 사용 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;참고 자료&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.aws.amazon.com/ko_kr/singlesignon/latest/userguide/what-is.html&quot;&gt;AWS 공식 문서: IAM Identity Center란?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.aws.amazon.com/ko_kr/singlesignon/latest/userguide/permissionsetsconcept.html&quot;&gt;AWS 공식 문서: Permission Set 개념&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.aws.amazon.com/ko_kr/singlesignon/latest/userguide/manage-your-identity-source-idp.html&quot;&gt;AWS 공식 문서: 외부 ID 제공업체&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.aws.amazon.com/ko_kr/singlesignon/latest/userguide/provision-automatically.html&quot;&gt;AWS 공식 문서: SCIM을 통한 자동 프로비저닝&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.aws.amazon.com/ko_kr/singlesignon/latest/userguide/gs-okta.html&quot;&gt;AWS 공식 문서: Okta와 SAML+SCIM 설정&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.aws.amazon.com/ko_kr/singlesignon/latest/userguide/idp-microsoft-entra.html&quot;&gt;AWS 공식 문서: Azure AD와 SAML+SCIM 설정&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.aws.amazon.com/ko_kr/cli/latest/userguide/cli-configure-sso.html&quot;&gt;AWS 공식 문서: CLI에서 IAM Identity Center 사용&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://aws.amazon.com/ko/iam/identity-center/faqs/&quot;&gt;AWS 공식 문서: IAM Identity Center FAQ&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.cloudquery.io/blog/aws-identity-center-guide&quot;&gt;CloudQuery: AWS IAM Identity Center Complete Guide 2026&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>AWS</category>
      <category>iam identity center</category>
      <category>SSO</category>
      <author>lhywk</author>
      <guid isPermaLink="true">https://lhywk.tistory.com/107</guid>
      <comments>https://lhywk.tistory.com/107#entry107comment</comments>
      <pubDate>Sat, 2 May 2026 12:49:14 +0900</pubDate>
    </item>
    <item>
      <title>Directory Service</title>
      <link>https://lhywk.tistory.com/106</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;이번 글에서는 &lt;b&gt;AWS Directory Service&lt;/b&gt;를 파고듭니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Directory Service는 AWS 계정 관리 시리즈에서 다소 독특한 위치에 있습니다. IAM이나 STS는 AWS 자체의 자격 증명 시스템인 반면, Directory Service는 &lt;b&gt;기업이 이미 수십 년간 써온 인증 체계 &amp;mdash; Active Directory &amp;mdash; 를 AWS에 가져오거나 연결하는 다리&lt;/b&gt; 역할을 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 글에서 다루는 핵심 질문들:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Active Directory가 정확히 무엇이고, 왜 기업에서 이것을 쓰는가?&lt;/li&gt;
&lt;li&gt;AWS Directory Service의 세 가지 옵션은 언제 무엇을 선택해야 하는가?&lt;/li&gt;
&lt;li&gt;온프레미스 AD와 AWS를 연동할 때 실제로 어떤 일이 일어나는가?&lt;/li&gt;
&lt;li&gt;EC2 인스턴스를 도메인에 가입(Domain Join)시키면 무엇이 달라지는가?&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. Active Directory란 무엇인가? &amp;mdash; 기업 인증의 근간&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1-1. 디렉터리 서비스의 역할&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;디렉터리 서비스(Directory Service)는 쉽게 말해 &lt;b&gt;&quot;조직 내 모든 것의 주소록&quot;&lt;/b&gt; 입니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;누가 이 조직의 구성원인가? (사용자 계정)&lt;/li&gt;
&lt;li&gt;어떤 그룹이 있고, 누가 속해 있는가? (그룹 관리)&lt;/li&gt;
&lt;li&gt;어떤 컴퓨터가 네트워크에 있는가? (컴퓨터 계정)&lt;/li&gt;
&lt;li&gt;누가 어떤 리소스에 접근할 수 있는가? (접근 제어)&lt;/li&gt;
&lt;li&gt;어떤 보안 정책이 적용되는가? (GPO - Group Policy Object)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Microsoft의 &lt;b&gt;Active Directory Domain Services(AD DS)&lt;/b&gt; 는 1999년 Windows 2000 Server와 함께 출시된 이후, 전 세계 기업 환경에서 사실상 표준이 되었습니다. 오늘날 대다수의 기업이 임직원 인증을 AD로 처리합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1-2. Active Directory의 핵심 프로토콜&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AD가 실제로 어떻게 동작하는지 이해하려면 두 가지 핵심 프로토콜을 알아야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;① Kerberos &amp;mdash; 현대 AD 인증의 주인공&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Kerberos는 AD 환경에서 사용자 인증을 처리하는 티켓 기반 프로토콜입니다. 1980년대 MIT에서 개발됐으며, 비밀번호를 네트워크로 직접 전송하지 않고 암호화된 티켓을 주고받는 방식으로 동작합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Kerberos 인증 흐름을 단순화하면:&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;1. 사용자가 로그인 시 KDC(Key Distribution Center)에 인증 요청
2. KDC가 TGT(Ticket Granting Ticket) 발급
   &amp;rarr; &quot;이 사람은 인증된 사용자입니다&quot;라는 증명서
3. 사용자가 특정 서비스(예: 파일 서버) 접근 시
   TGT를 KDC에 제시하여 서비스 티켓 요청
4. KDC가 서비스 티켓 발급
5. 사용자가 서비스 티켓으로 서버에 직접 접근&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 방식의 핵심 장점은 SSO(Single Sign-On)입니다. 아침에 한 번 로그인하면, 그 티켓으로 모든 AD 연동 서비스에 추가 로그인 없이 접근합니다. 파일 서버, 이메일 서버, ERP 시스템 &amp;mdash; 모두 같은 회사 계정으로.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;② LDAP &amp;mdash; AD의 데이터 검색 프로토콜&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LDAP(Lightweight Directory Access Protocol)는 디렉터리에서 &lt;b&gt;정보를 읽고 쓰는&lt;/b&gt; 프로토콜입니다. 사용자 목록 조회, 그룹 멤버십 확인, 사용자 속성 검색 등에 사용됩니다.&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;LDAP 쿼리 예시:
&quot;mail 속성이 alice@company.com인 사용자를 찾아라&quot;
&amp;rarr; DC=company,DC=com 하위에서 (mail=alice@company.com) 검색

결과:
cn=Alice Kim
sAMAccountName=alice
memberOf=CN=Developers,OU=Groups,DC=company,DC=com
mail=alice@company.com&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;많은 애플리케이션(Jenkins, GitLab, Jira, 이메일 서버 등)이 &quot;LDAP 인증&quot;을 지원한다고 할 때, 바로 이 프로토콜로 AD에서 사용자를 조회해 인증을 처리합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1-3. AD의 계층 구조&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AD는 조직을 논리적으로 표현하기 위해 계층 구조를 사용합니다.&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;Forest (포리스트): company.com
└── Tree (트리): company.com
    ├── Domain (도메인): company.com
    │   ├── OU (조직 단위): Employees
    │   │   ├── OU: Engineering
    │   │   │   ├── User: alice (Engineer)
    │   │   │   └── User: bob (Engineer)
    │   │   └── OU: HR
    │   │       └── User: charlie (HR Manager)
    │   ├── OU: Computers
    │   │   ├── Computer: WORKSTATION-01
    │   │   └── Computer: SERVER-PROD-01
    │   └── OU: Groups
    │       ├── Group: Developers
    │       └── Group: Admins
    └── Child Domain: us.company.com (자회사/지역 도메인)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 구조에서 중요한 개념들:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Domain(도메인)&lt;/b&gt;: 인증과 정책의 기본 단위. company.com이 하나의 도메인&lt;/li&gt;
&lt;li&gt;&lt;b&gt;OU(Organizational Unit)&lt;/b&gt;: 도메인 내의 논리적 컨테이너. 부서/팀 단위로 GPO 적용&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Forest(포리스트)&lt;/b&gt;: 여러 도메인의 최상위 컨테이너. 보안 경계&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Trust(신뢰 관계)&lt;/b&gt;: 서로 다른 도메인/포리스트 간 인증을 허용하는 관계&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1-4. Group Policy Object (GPO)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GPO는 AD에서 &lt;b&gt;정책을 일괄 적용&lt;/b&gt;하는 강력한 도구입니다. 도메인이나 OU에 GPO를 연결하면, 그 범위 안의 모든 컴퓨터와 사용자에게 자동으로 정책이 적용됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GPO로 할 수 있는 것들:&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;정책&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;예시 내용&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;비밀번호 정책&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;최소 12자, 대문자+숫자+특수문자 포함&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;화면 잠금&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;15분 비활성 시 자동 잠금&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;소프트웨어 배포&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;도메인 가입 PC에 Anti-virus 자동 설치&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;방화벽 규칙&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;특정 포트 차단 일괄 적용&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;USB 드라이브 차단&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;특정 OU 내 PC에서 외장 저장장치 비활성화&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;EC2 Windows 인스턴스를 AD에 조인(Domain Join)하면 이 GPO가 클라우드 인스턴스에도 자동으로 적용됩니다. 온프레미스 서버와 동일한 보안 정책을 유지할 수 있어, 규정 준수(Compliance) 요건을 충족하기가 훨씬 쉬워집니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. AWS Directory Service 세 가지 옵션&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS는 세 가지 방식으로 디렉터리 서비스를 제공합니다. 이 셋은 목적이 완전히 다르므로, 상황에 따라 올바른 것을 선택해야 합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2-1. AWS Managed Microsoft AD&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;정의:&lt;/b&gt; AWS가 완전 관리하는 &lt;b&gt;진짜 Microsoft Active Directory&lt;/b&gt;입니다. Windows Server 2019 기반의 실제 AD DS가 AWS 클라우드에서 실행되며, AWS가 도메인 컨트롤러의 패치, 백업, 복구를 담당합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;핵심 특성:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;AWS 관리형 Microsoft AD는 클라우드에서 AWS가 관리하는 실제 Microsoft Windows Server Active Directory로 구동됩니다&lt;/li&gt;
&lt;li&gt;기본적으로 &lt;b&gt;서로 다른 가용 영역(AZ)에 최소 2개의 도메인 컨트롤러&lt;/b&gt;를 배포해 고가용성을 보장합니다&lt;/li&gt;
&lt;li&gt;도메인 컨트롤러에 직접 RDP, SSH, Telnet으로 접근할 수 없습니다. AWS가 관리하는 영역이기 때문입니다&lt;/li&gt;
&lt;li&gt;온프레미스 AD와 &lt;b&gt;Trust Relationship&lt;/b&gt;을 구성해 하이브리드 환경을 만들 수 있습니다&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;에디션:&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;에디션&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;디렉터리 객체 수&amp;nbsp;&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;주요 대상&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;Standard&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;최대 약 30,000개&lt;/td&gt;
&lt;td&gt;중소기업&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;Enterprise&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;최대 약 500,000개&lt;/td&gt;
&lt;td&gt;대기업&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;Hybrid&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;기존 온프레미스 AD 확장&lt;/td&gt;
&lt;td&gt;하이브리드 인프라&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;지원하는 AWS 서비스:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Amazon EC2 (도메인 조인, GPO 적용)&lt;/li&gt;
&lt;li&gt;Amazon RDS for SQL Server (Windows 인증)&lt;/li&gt;
&lt;li&gt;Amazon WorkSpaces, AppStream 2.0&lt;/li&gt;
&lt;li&gt;Amazon FSx for Windows File Server&lt;/li&gt;
&lt;li&gt;AWS IAM Identity Center (AD를 자격 증명 소스로)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;언제 선택하나:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;5,000명 이상의 사용자&lt;/li&gt;
&lt;li&gt;온프레미스 AD와 Trust 관계가 필요할 때&lt;/li&gt;
&lt;li&gt;RDS SQL Server를 AD 인증으로 사용해야 할 때&lt;/li&gt;
&lt;li&gt;AWS에서 완전히 새로운 AD 도메인을 구축할 때&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2-2. AD Connector&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;정의:&lt;/b&gt; AD Connector는 프록시입니다. 클라우드에 별도 디렉터리를 만들지 않고, 기존 온프레미스 AD를 향해 인증 요청을 &lt;b&gt;중계&lt;/b&gt;합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;핵심 특성:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;AD Connector는 클라우드에 어떠한 정보도 캐싱하지 않고 디렉터리 요청을 온프레미스 Microsoft Active Directory로 프록시합니다&lt;/li&gt;
&lt;li&gt;사용자 자격 증명이 AWS에 저장되지 않음 &amp;mdash; 온프레미스 AD가 &lt;b&gt;Single Source of Truth&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;AD Connector는 RDS SQL Server와 호환되지 않습니다&lt;/li&gt;
&lt;li&gt;온프레미스 네트워크와의 연결이 끊기면 인증이 불가능합니다 (VPN/Direct Connect 필수)&lt;/li&gt;
&lt;li&gt;기존 RADIUS 기반 MFA 인프라에 연결해 MFA를 활성화할 수 있습니다&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;AD Connector의 필수 전제 조건:&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;온프레미스 DC &amp;larr; VPN 또는 Direct Connect &amp;rarr; AD Connector (VPC 내)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;연결이 반드시 있어야 합니다. 연결이 없으면 AD Connector는 아무것도 할 수 없습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;언제 선택하나:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이미 온프레미스 AD가 있고, 그것을 그대로 사용하고 싶을 때&lt;/li&gt;
&lt;li&gt;AWS에 사용자 데이터를 저장하고 싶지 않을 때 (데이터 주권/규정 준수)&lt;/li&gt;
&lt;li&gt;EC2 Windows 인스턴스를 온프레미스 도메인에 조인하고 싶을 때&lt;/li&gt;
&lt;li&gt;WorkSpaces, WorkDocs, WorkMail 등을 기존 AD로 인증하고 싶을 때&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2-3. Simple AD&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;정의:&lt;/b&gt; Simple AD는 Samba 4 기반의 독립 실행형 Microsoft Active Directory 호환 디렉터리입니다. 클라우드에서 독립적으로 동작하며, 작고 비용 효율적인 솔루션입니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;핵심 특성:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Simple AD는 최대 5,000명의 사용자를 지원하는 저비용, 소규모 디렉터리로 기본 Active Directory 호환성을 제공합니다&lt;/li&gt;
&lt;li&gt;진짜 Microsoft AD가 아닌 &lt;b&gt;Samba 4 구현체&lt;/b&gt;이므로 고급 기능이 없습니다&lt;/li&gt;
&lt;li&gt;지원하지 않는 기능: MFA, Trust 관계, DNS 동적 업데이트, 스키마 확장, LDAPS, FSMO 역할 전달&lt;/li&gt;
&lt;li&gt;RDS SQL Server 미지원&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;언제 선택하나:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;소규모 팀(5,000명 이하)&lt;/li&gt;
&lt;li&gt;기본적인 사용자/그룹 관리, EC2 도메인 조인만 필요&lt;/li&gt;
&lt;li&gt;비용을 최소화하고 싶을 때&lt;/li&gt;
&lt;li&gt;온프레미스 AD가 없는 스타트업이나 테스트 환경&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2-4. 세 가지 비교 표&lt;/h3&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;항목&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt; AWS Managed Microsoft AD &lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt; AD Connector &lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt; Simple AD &lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;실제 AD 여부&lt;/td&gt;
&lt;td&gt;✅ 진짜 MS AD&lt;/td&gt;
&lt;td&gt;❌ 프록시&lt;/td&gt;
&lt;td&gt;⚠️ Samba 4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;사용자 데이터 저장 위치&lt;/td&gt;
&lt;td&gt;AWS&lt;/td&gt;
&lt;td&gt;온프레미스&lt;/td&gt;
&lt;td&gt;AWS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;최대 사용자 수&lt;/td&gt;
&lt;td&gt;~500,000&lt;/td&gt;
&lt;td&gt;제한 없음&lt;/td&gt;
&lt;td&gt;~5,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;온프레미스 AD 필요&lt;/td&gt;
&lt;td&gt;선택&lt;/td&gt;
&lt;td&gt;&lt;b&gt;필수&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;불필요&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Trust 관계&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MFA 지원&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅ (RADIUS)&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RDS SQL Server&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;FSx for Windows&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;VPN/Direct Connect&lt;/td&gt;
&lt;td&gt;선택&lt;/td&gt;
&lt;td&gt;&lt;b&gt;필수&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;불필요&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;비용&lt;/td&gt;
&lt;td&gt;높음&lt;/td&gt;
&lt;td&gt;중간&lt;/td&gt;
&lt;td&gt;낮음&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1440&quot; data-origin-height=&quot;1000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d3GbYo/dJMcafsUCvq/cZfK3xhq4fhCPcoVtEHqck/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d3GbYo/dJMcafsUCvq/cZfK3xhq4fhCPcoVtEHqck/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d3GbYo/dJMcafsUCvq/cZfK3xhq4fhCPcoVtEHqck/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd3GbYo%2FdJMcafsUCvq%2FcZfK3xhq4fhCPcoVtEHqck%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1440&quot; height=&quot;1000&quot; data-origin-width=&quot;1440&quot; data-origin-height=&quot;1000&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. Trust Relationship &amp;mdash; 두 AD 도메인을 연결하는 신뢰&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Trust Relationship은 &lt;b&gt;서로 다른 AD 도메인(또는 포리스트) 간의 인증 신뢰 협약&lt;/b&gt;입니다. Trust가 맺어지면, 한쪽 도메인의 사용자가 상대 도메인의 리소스에 접근할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1440&quot; data-origin-height=&quot;920&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bBIZvK/dJMcadu2zlu/GRkAz1zuemycLAlsk69UVk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bBIZvK/dJMcadu2zlu/GRkAz1zuemycLAlsk69UVk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bBIZvK/dJMcadu2zlu/GRkAz1zuemycLAlsk69UVk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbBIZvK%2FdJMcadu2zlu%2FGRkAz1zuemycLAlsk69UVk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1440&quot; height=&quot;920&quot; data-origin-width=&quot;1440&quot; data-origin-height=&quot;920&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3-1. Trust의 방향&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;단방향 Trust (One-Way Trust):&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;온프레미스 AD (corp.local) &amp;rarr; AWS Managed AD (aws.corp.local)
     신뢰함(Trusts)               신뢰받음(Trusted)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 경우 aws.corp.local의 사용자가 corp.local의 리소스에 접근할 수 있지만, 반대는 불가합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;양방향 Trust (Two-Way Trust):&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;온프레미스 AD (corp.local) &amp;harr; AWS Managed AD (aws.corp.local)
     서로 신뢰함&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;양쪽 도메인 사용자 모두 상대방 리소스에 접근 가능합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3-2. Trust의 종류&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;External Trust (외부 신뢰):&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;두 도메인 간의 직접 1:1 신뢰&lt;/li&gt;
&lt;li&gt;비전이적(Non-transitive): A&amp;harr;B, B&amp;harr;C 신뢰가 있어도 A&amp;rarr;C 자동 허용 없음&lt;/li&gt;
&lt;li&gt;NTLM 인증 사용 (Kerberos 부분 가능)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Forest Trust (포리스트 신뢰):&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;두 포리스트 전체 간의 신뢰&lt;/li&gt;
&lt;li&gt;Forest Trust는 두 포리스트 간의 리소스 공유에 사용되며, Kerberos와 완전히 호환되는 선호하는 트러스트 모델입니다&lt;/li&gt;
&lt;li&gt;전이적(Transitive): A&amp;harr;B Forest Trust가 있으면 A 내 모든 도메인이 B 내 모든 도메인과 신뢰&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실무 권장: 가능하면 Forest Trust를 사용하세요. Kerberos SSO가 완전히 동작하며, External Trust보다 관리가 단순합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3-3. AWS Managed AD와 온프레미스 AD Trust 구성 흐름&lt;/h3&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;1. AWS Managed Microsoft AD 생성
2. 온프레미스 AD와 AWS 간 네트워크 연결 (VPN 또는 Direct Connect)
3. DNS 포워딩 설정
   - 온프레미스 DNS &amp;rarr; AWS 도메인(aws.corp.local) 쿼리를 AWS로 포워딩
   - AWS Route 53 Resolver &amp;rarr; 온프레미스 도메인(corp.local) 쿼리를 온프레미스로 포워딩
4. 온프레미스 AD에서 Trust 생성 (먼저 생성해야 함)
5. AWS Managed AD에서 Trust 생성
6. Trust 검증&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;중요: Trust를 생성할 때 온프레미스 도메인에서 먼저 Trust를 생성한 다음, AWS Managed Microsoft AD에서 Trust를 생성해야 합니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4. Domain Join &amp;mdash; EC2 인스턴스를 AD에 연결하기&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4-1. Domain Join이란?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;EC2 Windows 인스턴스를 AD 도메인에 가입(Join)시키면, 그 인스턴스는 AD의 구성원이 됩니다. 이후부터:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;AD 사용자 계정으로 RDP 로그인 가능 (로컬 계정 불필요)&lt;/li&gt;
&lt;li&gt;GPO 자동 적용 (보안 정책, 소프트웨어 배포 등)&lt;/li&gt;
&lt;li&gt;AD 그룹 기반 접근 제어 가능&lt;/li&gt;
&lt;li&gt;Kerberos SSO 지원&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기업 환경에서 &quot;EC2에서 Windows 서버를 운영한다&quot;면, 대부분 도메인에 조인해서 중앙 집중적으로 관리합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4-2. 도메인 조인 방법 비교&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;방법 1: 콘솔 / 수동 조인&lt;/b&gt; EC2 시작 시 또는 이미 실행 중인 인스턴스에 RDP 접속 후 Windows의 &quot;도메인 가입&quot; 기능을 직접 사용합니다. 소규모 환경이나 테스트 용도에 적합합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;방법 2: EC2 Launch Wizard (자동 조인)&lt;/b&gt; EC2 인스턴스를 시작할 때 &quot;도메인 조인 디렉터리&quot;를 선택하면, 인스턴스가 부팅되면서 자동으로 도메인에 가입됩니다. AWS Systems Manager SSM Agent가 이 과정을 처리합니다.&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;EC2 콘솔 &amp;rarr; 인스턴스 시작 &amp;rarr; 고급 세부 정보
&amp;rarr; 도메인 조인 디렉터리: [생성한 Directory ID 선택]
&amp;rarr; IAM 인스턴스 프로파일: [SSM 권한이 있는 Role 선택]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;방법 3: SSM Automation (대규모 자동화)&lt;/b&gt; AWS Systems Manager의 AWS-JoinDirectoryServiceDomain 자동화 문서를 사용하면 기존 인스턴스를 도메인에 대량으로 조인할 수 있습니다.&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;aws ssm start-automation-execution \
  --document-name &quot;AWS-JoinDirectoryServiceDomain&quot; \
  --parameters \
    directoryId=d-xxxxxxxx,\
    directoryName=corp.example.com,\
    instanceIds=i-1234567890abcdef0&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4-3. Domain Join 후 실제 변화&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;도메인 조인 전후를 비교하면:&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;[조인 전]
- 로컬 계정(Administrator)으로만 RDP 로그인 가능
- 보안 정책을 인스턴스마다 개별 설정
- 중앙 집중 관리 불가

[조인 후]
- AD 사용자 계정(CORP\alice)으로 RDP 로그인 가능
- GPO 자동 적용 (비밀번호 정책, 화면 잠금, 방화벽 등)
- AD 그룹(CORP\Admins)을 로컬 Administrators 그룹에 추가해 권한 위임 가능
- RSAT 도구로 중앙에서 관리 가능&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;5. AWS Managed Microsoft AD와 IAM Identity Center 연동&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS Managed Microsoft AD의 가장 강력한 활용은 &lt;b&gt;IAM Identity Center와 연동&lt;/b&gt;하는 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 조합이 갖추어지면:&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;직원 &amp;rarr; 회사 AD 계정으로 로그인
     &amp;rarr; IAM Identity Center가 AD를 자격 증명 소스로 사용
     &amp;rarr; Permission Set(IAM Role 묶음) 매핑
     &amp;rarr; 여러 AWS 계정에 SSO 접근
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 직원이 &lt;b&gt;회사 LDAP/AD 계정 하나로 모든 AWS 계정에 SSO 접근&lt;/b&gt;합니다. AD 계정이 비활성화되면 자동으로 AWS 접근도 차단됩니다.&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;6. 실습: AWS Managed Microsoft AD 생성 및 EC2 Domain Join&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 실습은 AWS Managed Microsoft AD를 생성하고, EC2 Windows 인스턴스를 도메인에 가입시켜 AD 계정으로 RDP 로그인하는 것까지 구현합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;비용 주의:&lt;/b&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt; AWS Managed Microsoft AD는 시간당 과금됩니다. Standard Edition 기준 약 &lt;/span&gt;&lt;b&gt;$0.05/도메인컨트롤러/시간&lt;/b&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt; (최소 2개 DC). 실습 후 반드시 삭제하세요. 30일 무료 체험(1,500 DC 시간)을 활용할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;실습 환경 구성&lt;/h3&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;[실습 구성]
VPC: 10.0.0.0/16
  ├── 퍼블릭 서브넷 1 (ap-northeast-2a): 10.0.1.0/24 &amp;rarr; EC2 인스턴스
  ├── 프라이빗 서브넷 1 (ap-northeast-2a): 10.0.10.0/24 &amp;rarr; AD DC
  └── 프라이빗 서브넷 2 (ap-northeast-2c): 10.0.20.0/24 &amp;rarr; AD DC (이중화)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Step 1: VPC 및 서브넷 준비&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실습용 VPC가 없다면 먼저 생성합니다:&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;VPC 콘솔 &amp;rarr; VPC 생성
&amp;rarr; VPC 설정: VPC 및 기타 (VPC + 서브넷 자동 생성)
&amp;rarr; IPv4 CIDR: 10.0.0.0/16
&amp;rarr; 가용 영역 수: 2
&amp;rarr; 퍼블릭 서브넷 수: 2 (EC2 접근용)
&amp;rarr; 프라이빗 서브넷 수: 2 (AD DC용)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Step 2: AWS Managed Microsoft AD 생성&lt;/h3&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;Directory Service 콘솔 &amp;rarr; 디렉터리 설정 &amp;rarr; 디렉터리 유형 선택
&amp;rarr; AWS Managed Microsoft AD 선택 &amp;rarr; 다음

[디렉터리 정보]
에디션: Standard
DNS 이름: corp.example.com        &amp;larr; 조직에 맞게 설정
NetBIOS 이름: CORP
관리자 비밀번호: [복잡한 비밀번호 설정]  &amp;larr; 반드시 기록해두기

[네트워킹]
VPC: [위에서 만든 VPC 선택]
서브넷: [프라이빗 서브넷 2개 선택 &amp;mdash; 서로 다른 AZ]

&amp;rarr; 검토 및 생성
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생성 완료 후 확인해야 할 것들:&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;# Directory ID 확인 (d-xxxxxxxxxx 형태)
aws ds describe-directories --query 'DirectoryDescriptions[*].{ID:DirectoryId,Name:Name,Status:Stage}'

# DNS 주소 확인 (두 개의 IP)
aws ds describe-directories \
  --directory-ids d-xxxxxxxxxx \
  --query 'DirectoryDescriptions[0].DnsIpAddrs'&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Step 3: EC2 Domain Join용 IAM Role 생성&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;도메인 조인 자동화를 위해 EC2에 연결할 IAM Role이 필요합니다:&lt;/p&gt;
&lt;pre class=&quot;crmsh&quot;&gt;&lt;code&gt;IAM 콘솔 &amp;rarr; Roles &amp;rarr; Create role
&amp;rarr; EC2 서비스 선택
&amp;rarr; 정책 추가:
   - AmazonSSMManagedInstanceCore (SSM 에이전트 통신)
   - AmazonSSMDirectoryServiceAccess (도메인 조인 자동화)
&amp;rarr; Role name: EC2-DomainJoin-Role
&amp;rarr; Create role
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Step 4: AD 사용자 생성 (관리 EC2 인스턴스 사용)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS Managed Microsoft AD를 관리하는 방법은 두 가지입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;방법 A (최신 방식): Directory Service Data API 직접 사용&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;dsconfig&quot;&gt;&lt;code&gt;# 사용자 생성
aws ds-data create-user \
  --directory-id d-xxxxxxxxxx \
  --sam-account-name testuser \
  --given-name Test \
  --surname User \
  --password &quot;TestP@ssw0rd!&quot;

# 그룹 생성
aws ds-data create-group \
  --directory-id d-xxxxxxxxxx \
  --sam-account-name Developers

# 그룹에 사용자 추가
aws ds-data add-group-member \
  --directory-id d-xxxxxxxxxx \
  --group-sam-account-name Developers \
  --member-sam-account-name testuser
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;방법 B (전통적 방식): RSAT 도구 사용&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AD 도메인에 조인된 Windows EC2 인스턴스에 RSAT(Remote Server Administration Tools)를 설치하고, Active Directory Users and Computers(ADUC) GUI로 관리합니다.&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;# Windows EC2에서 RSAT 설치
Install-WindowsFeature -Name RSAT-AD-Tools

# AD Users and Computers 열기
dsa.msc&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Step 5: EC2 Windows 인스턴스 생성 및 도메인 조인&lt;/h3&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;EC2 콘솔 &amp;rarr; 인스턴스 시작

[AMI 선택]
Windows Server 2022 Base 선택

[인스턴스 유형]
t3.medium (Windows는 최소 이 크기 권장)

[고급 세부 정보]
IAM 인스턴스 프로파일: EC2-DomainJoin-Role
도메인 조인 디렉터리: corp.example.com [생성한 디렉터리 선택]

[보안 그룹]
RDP (3389): 내 IP에서만 허용&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인스턴스가 시작되면서 자동으로 도메인에 조인됩니다. &lt;b&gt;약 5~10분&lt;/b&gt; 소요됩니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Step 6: AD 계정으로 RDP 로그인 확인&lt;/h3&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;1. EC2 콘솔 &amp;rarr; 인스턴스 선택 &amp;rarr; 연결 &amp;rarr; RDP 클라이언트
2. 비밀번호 가져오기 (키 페어 사용)
3. RDP 로그인 화면에서:
   사용자 이름: CORP\testuser  &amp;larr; 도메인\사용자 형식
   비밀번호: TestP@ssw0rd!
4. 로그인 성공 확인
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로그인 성공 후 PowerShell에서 확인:&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;# 도메인 가입 여부 확인
(Get-WmiObject Win32_ComputerSystem).Domain
# 출력: corp.example.com

# 현재 로그인 사용자 확인
whoami
# 출력: corp\testuser

# AD 그룹 멤버십 확인
whoami /groups | findstr CORP&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;7. 실습: AD Connector 설정 (개념 실습)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AD Connector는 온프레미스 AD가 있어야 하므로, 이 실습에서는 실제 온프레미스 AD 대신 EC2에 Self-managed AD를 구성하여 연결하는 시나리오로 진행합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;AD Connector의 필수 전제 조건&lt;/h3&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;1. 온프레미스(또는 EC2 Self-managed) AD가 준비되어 있어야 함
2. VPN 또는 Direct Connect로 AWS VPC와 연결되어 있어야 함
3. AD Connector 서비스 계정 (비관리자 계정, 특정 권한만 부여)
   - Users, Groups, Computers 읽기 권한
   - 컴퓨터 도메인 가입 권한
4. 방화벽 규칙 (AD Connector &amp;rarr; 온프레미스 DC):
   - TCP/UDP 88  (Kerberos)
   - TCP/UDP 389 (LDAP)
   - TCP 636     (LDAPS)
   - TCP/UDP 445 (SMB)
   - TCP/UDP 464 (Kerberos Password Change)&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;AD Connector 생성&lt;/h3&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;Directory Service 콘솔 &amp;rarr; 디렉터리 설정
&amp;rarr; AD Connector 선택 &amp;rarr; 다음

[디렉터리 정보]
DNS 이름: corp.onprem.local
NetBIOS 이름: CORP

[연결 정보]
VPC: [선택]
서브넷: [두 개의 서브넷 선택]
DNS IP 주소:
  10.0.100.10  &amp;larr; 온프레미스 DC 1의 IP
  10.0.100.11  &amp;larr; 온프레미스 DC 2의 IP (이중화)
서비스 계정 사용자 이름: svc-ad-connector
서비스 계정 암호: [서비스 계정 비밀번호]&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;8. 아키텍처 패턴: 언제 무엇을 선택할까&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;패턴 1: 스타트업 / 클라우드 네이티브&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AD가 없는 신규 조직이라면 대부분 &lt;b&gt;AWS Managed Microsoft AD는 불필요&lt;/b&gt;합니다. 대신 IAM + IAM Identity Center로 충분합니다. Windows 워크로드가 많아지면 그때 Simple AD나 Managed AD를 검토하세요.&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;추천: IAM Identity Center (IdP 없이) + IAM User/Role
이유: 복잡성 최소화, 비용 절감
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;패턴 2: 기업 &amp;mdash; 온프레미스 AD 있음, 클라우드로 일부 이전&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존 AD를 유지하면서 AWS를 사용하는 가장 일반적인 엔터프라이즈 패턴입니다.&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;추천: AD Connector
이유:
  - 온프레미스 AD가 Single Source of Truth 유지
  - 사용자 자격 증명이 AWS에 저장되지 않음
  - 이미 있는 인프라를 최대 활용
  - 단, VPN/Direct Connect 연결 필수, RDS SQL Server 불가
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;패턴 3: 기업 &amp;mdash; 온프레미스 AD와 AWS를 독립적으로 운영하되 신뢰 관계 필요&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS에서 새로운 AD 도메인을 운영하면서, 온프레미스 AD 사용자도 AWS 리소스에 접근이 가능해야 하는 경우입니다.&lt;/p&gt;
&lt;pre class=&quot;markdown&quot;&gt;&lt;code&gt;추천: AWS Managed Microsoft AD + Trust Relationship
이유:
  - AWS AD가 독립적으로 운영 (온프레미스 연결 단절 시에도 동작)
  - Trust로 온프레미스 사용자 접근 허용
  - RDS SQL Server, FSx 등 모든 AWS 서비스 지원
  - 단, 비용이 가장 높음
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;패턴 4: 대규모 기업 &amp;mdash; 완전한 하이브리드 ID&lt;/h3&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;추천: AWS Managed Microsoft AD (Hybrid Edition) + IAM Identity Center
이유:
  - AWS Managed AD가 온프레미스 AD 포리스트의 일부로 편입
  - IAM Identity Center를 통해 수십 개의 AWS 계정에 SSO
  - 전사적 단일 자격 증명 체계
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Active Directory의 본질:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;LDAP(디렉터리 검색) + Kerberos(인증) + GPO(정책)의 조합&lt;/li&gt;
&lt;li&gt;기업 환경에서 인증의 Single Source of Truth&lt;/li&gt;
&lt;li&gt;OU 계층 구조로 조직을 논리적으로 표현&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;AWS Directory Service 선택 기준:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;온프레미스 AD 없음 + 소규모 &amp;rarr; Simple AD (또는 IAM만으로 충분)&lt;/li&gt;
&lt;li&gt;온프레미스 AD 있음 + 그대로 활용 &amp;rarr; AD Connector (VPN/DX 필수)&lt;/li&gt;
&lt;li&gt;클라우드 AD 독립 운영 + 풀 기능 &amp;rarr; AWS Managed Microsoft AD&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Trust Relationship:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;서로 다른 AD 도메인/포리스트 간 인증 허용&lt;/li&gt;
&lt;li&gt;Forest Trust가 External Trust보다 선호됨 (Kerberos 완전 지원)&lt;/li&gt;
&lt;li&gt;온프레미스 AD에서 먼저 Trust 생성 후 AWS 측에서 생성&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Domain Join:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;EC2 인스턴스를 AD에 연결해 중앙 집중적 관리&lt;/li&gt;
&lt;li&gt;콘솔 자동 조인, SSM Automation, 수동 조인 세 가지 방법&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;참고 자료&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.aws.amazon.com/ko_kr/directoryservice/latest/admin-guide/what_is.html&quot;&gt;AWS 공식 문서: AWS Directory Service란?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.aws.amazon.com/directoryservice/latest/admin-guide/simple_ad_best_practices.html&quot;&gt;AWS 공식 문서: Simple AD 모범 사례&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.aws.amazon.com/directoryservice/latest/admin-guide/ad_connector_best_practices.html&quot;&gt;AWS 공식 문서: AD Connector 모범 사례&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.aws.amazon.com/directoryservice/latest/admin-guide/ms_ad_setup_trust.html&quot;&gt;AWS 공식 문서: 온프레미스 AD와 신뢰 관계 생성&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://aws.amazon.com/blogs/security/everything-you-wanted-to-know-about-trusts-with-aws-managed-microsoft-ad/&quot;&gt;AWS 블로그: Trust with AWS Managed Microsoft AD에 대해 알고 싶은 모든 것&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://aws.amazon.com/ko/directoryservice/features/&quot;&gt;AWS 공식 문서: AWS Directory Service 기능&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://tutorialsdojo.com/aws-directory-service/&quot;&gt;Tutorials Dojo: AWS Directory Service Cheat Sheet&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>AWS</category>
      <category>AWS Active Directory</category>
      <author>lhywk</author>
      <guid isPermaLink="true">https://lhywk.tistory.com/106</guid>
      <comments>https://lhywk.tistory.com/106#entry106comment</comments>
      <pubDate>Sat, 2 May 2026 12:40:35 +0900</pubDate>
    </item>
    <item>
      <title>IAM Federation + OIDC</title>
      <link>https://lhywk.tistory.com/105</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;페더레이션이라는 단어가 낯설 수 있지만, 개념 자체는 간단합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&quot;AWS 외부에 이미 존재하는 자격 증명 시스템을 AWS에서도 그대로 신뢰해 사용하는 것&quot;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러분이 이미 경험한 사례가 있습니다. 어떤 사이트에 &quot;Google 계정으로 로그인&quot;하면, 그 사이트는 여러분의 Google 비밀번호를 모릅니다. Google이 &quot;이 사람 진짜 맞아요&quot;라고 보증해주는 것입니다. AWS Federation도 동일한 원리입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 글에서 다루는 내용:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;OIDC Federation&lt;/b&gt;: GitHub Actions &amp;rarr; AWS 배포를 Access Key 없이 구현&lt;/li&gt;
&lt;li&gt;&lt;b&gt;SAML 2.0 Federation&lt;/b&gt;: 기업 Active Directory 계정으로 AWS 콘솔 로그인&lt;/li&gt;
&lt;li&gt;두 방식의 동작 원리와 신뢰 정책 구조&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히 &lt;b&gt;&quot;GitHub Actions에서 AWS 배포할 때 Access Key를 GitHub Secrets에 저장하는 것&quot;&lt;/b&gt; 은 매우 흔하지만 보안상 좋지 않은 방법입니다. OIDC로 이를 완전히 없애는 방법을 학습합니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. Federation이란?&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1-1. 왜 Federation이 필요한가?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;조직이 커지면 다음과 같은 문제가 생깁니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;문제 1: IAM User 관리 폭발&lt;/b&gt; 100명 직원이 있다면 100개의 IAM User가 필요합니다. 직원이 퇴사하면 즉시 삭제해야 하고, 비밀번호 정책도 따로 관리해야 합니다. 이미 Active Directory나 Google Workspace 같은 Identity Provider(IdP)가 있는 기업은 이 작업이 이중 관리입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;문제 2: CI/CD 파이프라인의 Access Key 관리&lt;/b&gt; GitHub Actions, GitLab CI, Jenkins 등에서 AWS를 배포할 때 Access Key를 저장해두게 됩니다. 이 키가 유출되면 재앙입니다. 키 로테이션도 번거롭고, 여러 파이프라인에 퍼져 있으면 어디에 저장했는지도 파악하기 어렵습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;해결책: Federation&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;외부 자격 증명 시스템(GitHub, Google, Active Directory 등)과 AWS 사이에 신뢰 관계를 맺어, 외부에서 인증된 사용자/시스템이 &lt;b&gt;임시 자격 증명&lt;/b&gt;으로 AWS에 접근하게 합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1-2. AWS가 지원하는 Federation 방식&lt;/h3&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;방식&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;사용 프로토콜&lt;/td&gt;
&lt;td&gt;주요 사용 사례&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;OIDC Federation&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;OpenID Connect (JWT 기반)&lt;/td&gt;
&lt;td&gt;GitHub Actions, Kubernetes, 모바일 앱&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;SAML 2.0 Federation&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;SAML (XML 기반)&lt;/td&gt;
&lt;td&gt;기업 AD, Okta, Azure AD, Google Workspace&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;Web Identity&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;OIDC의 하위 개념&lt;/td&gt;
&lt;td&gt;Amazon/Facebook/Google 소셜 로그인&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS는 이 두 프로토콜을 모두 지원하며, 공통적으로 &lt;b&gt;STS AssumeRole&lt;/b&gt;을 통해 임시 자격 증명을 발급합니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. OIDC Federation&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2-1. OpenID Connect란?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;OpenID Connect(OIDC)는 OAuth 2.0 위에 만들어진 &lt;b&gt;인증 레이어&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;OIDC의 핵심은 JWT입니다. IdP가 발급하는 JWT에는 누가 인증받았는지, 언제, 어느 앱을 위해 발급됐는지 등의 정보가 암호화되어 담겨 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JWT의 구조:&lt;/p&gt;
&lt;pre class=&quot;avrasm&quot;&gt;&lt;code&gt;Header.Payload.Signature

Header: 알고리즘 정보 ({&quot;alg&quot;: &quot;RS256&quot;})
Payload: 클레임 정보 ({
  &quot;sub&quot;: &quot;repo:my-org/my-repo:ref:refs/heads/main&quot;,
  &quot;aud&quot;: &quot;sts.amazonaws.com&quot;,
  &quot;iss&quot;: &quot;https://token.actions.githubusercontent.com&quot;,
  &quot;exp&quot;: 1711234567
})
Signature: Header + Payload를 IdP의 개인 키로 서명
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS STS는 이 JWT를 IdP의 공개 키로 검증한 뒤, 신뢰 정책 조건을 확인하고 임시 자격 증명을 발급합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2-2. OIDC Federation 동작 원리&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;핵심 흐름은 이렇습니다:&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;1. 외부 시스템이 IdP에 인증 요청
2. IdP가 JWT 토큰 발급
3. JWT를 AWS STS에 제출 (AssumeRoleWithWebIdentity)
4. STS가 JWT 서명 검증 + 신뢰 정책 확인
5. STS가 임시 자격 증명 반환
6. 임시 자격 증명으로 AWS 리소스 접근&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1440&quot; data-origin-height=&quot;1040&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lweX4/dJMcadojhVQ/YPsoqIuJrci0jQCSzO771k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lweX4/dJMcadojhVQ/YPsoqIuJrci0jQCSzO771k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lweX4/dJMcadojhVQ/YPsoqIuJrci0jQCSzO771k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlweX4%2FdJMcadojhVQ%2FYPsoqIuJrci0jQCSzO771k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1440&quot; height=&quot;1040&quot; data-origin-width=&quot;1440&quot; data-origin-height=&quot;1040&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2-3. IAM OIDC Identity Provider 등록&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;OIDC Federation을 사용하기 전에, AWS 계정에 IdP를 등록해야 합니다. 이것이 &quot;이 OIDC 발급자를 신뢰하겠다&quot;는 선언입니다.&lt;/p&gt;
&lt;pre class=&quot;dsconfig&quot;&gt;&lt;code&gt;# GitHub Actions OIDC Provider 등록 (CLI)
aws iam create-open-id-connect-provider \
  --url &quot;https://token.actions.githubusercontent.com&quot; \
  --client-id-list &quot;sts.amazonaws.com&quot; \
  --thumbprint-list &quot;6938fd4d98bab03faadb97b34396831e3780aea1&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;참고: Google, Facebook, Amazon Cognito는 AWS에 이미 내장된 OIDC Provider이므로 별도 등록이 필요 없습니다. 그 외의 Provider(GitHub, Kubernetes 등)는 위처럼 직접 등록해야 합니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. GitHub Actions + OIDC - 실무 핵심 사례&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3-1. 왜 OIDC가 Access Key보다 좋은가?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;기존 방식 (Access Key 사용):&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;# .github/workflows/deploy.yml (나쁜 예)
- name: Configure AWS credentials
  uses: aws-actions/configure-aws-credentials@v4
  with:
    aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
    aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
    aws-region: ap-northeast-2&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문제점:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Access Key가 GitHub Secrets에 영구 저장됨&lt;/li&gt;
&lt;li&gt;키 유출 시 즉시 AWS 전체 위험&lt;/li&gt;
&lt;li&gt;키 로테이션이 번거로움 (여러 레포지토리에 분산됐다면 더더욱)&lt;/li&gt;
&lt;li&gt;직원 퇴사 시 어느 곳에 키가 쓰이는지 파악 어려움&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;OIDC 방식:&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;# .github/workflows/deploy.yml (올바른 예)
- name: Configure AWS credentials
  uses: aws-actions/configure-aws-credentials@v4
  with:
    role-to-assume: arn:aws:iam::123456789012:role/GitHubActionsDeployRole
    aws-region: ap-northeast-2&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;장점:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Access Key 자체가 없음&lt;/b&gt; &amp;mdash; 저장할 키가 없으니 유출될 키도 없음&lt;/li&gt;
&lt;li&gt;각 Job 실행마다 새 임시 토큰 발급, Job 종료 시 자동 만료&lt;/li&gt;
&lt;li&gt;특정 레포지토리/브랜치/환경에만 허용하도록 세밀하게 제어 가능&lt;/li&gt;
&lt;li&gt;키 로테이션 불필요&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3-2. GitHub Actions OIDC 설정 방법&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Step 1: IAM에 GitHub OIDC Provider 등록&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;콘솔:&lt;/p&gt;
&lt;pre class=&quot;groovy&quot;&gt;&lt;code&gt;IAM &amp;rarr; Identity providers &amp;rarr; Add provider
&amp;rarr; Provider type: OpenID Connect
&amp;rarr; Provider URL: https://token.actions.githubusercontent.com
&amp;rarr; Audience: sts.amazonaws.com
&amp;rarr; Add provider
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CLI:&lt;/p&gt;
&lt;pre class=&quot;dsconfig&quot;&gt;&lt;code&gt;aws iam create-open-id-connect-provider \
  --url &quot;https://token.actions.githubusercontent.com&quot; \
  --client-id-list &quot;sts.amazonaws.com&quot; \
  --thumbprint-list &quot;6938fd4d98bab03faadb97b34396831e3780aea1&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Step 2: IAM Role 생성 (신뢰 정책 설정)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특정 레포지토리 + 특정 브랜치만 허용하는 신뢰 정책:&lt;/p&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;{
  &quot;Version&quot;: &quot;2012-10-17&quot;,
  &quot;Statement&quot;: [
    {
      &quot;Effect&quot;: &quot;Allow&quot;,
      &quot;Principal&quot;: {
        &quot;Federated&quot;: &quot;arn:aws:iam::123456789012:oidc-provider/token.actions.githubusercontent.com&quot;
      },
      &quot;Action&quot;: &quot;sts:AssumeRoleWithWebIdentity&quot;,
      &quot;Condition&quot;: {
        &quot;StringEquals&quot;: {
          &quot;token.actions.githubusercontent.com:aud&quot;: &quot;sts.amazonaws.com&quot;
        },
        &quot;StringLike&quot;: {
          &quot;token.actions.githubusercontent.com:sub&quot;: &quot;repo:my-org/my-repo:ref:refs/heads/main&quot;
        }
      }
    }
  ]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Condition 설명:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;aud: 이 토큰이 sts.amazonaws.com을 위해 발급됐는지 확인 (필수)&lt;/li&gt;
&lt;li&gt;sub: 어느 레포지토리/브랜치/환경에서 발급된 토큰인지 제한&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;보안 경고:&lt;/b&gt; sub 조건을 반드시 설정하세요. 없으면 GitHub의 모든 레포지토리에서 이 Role을 수임할 수 있어 심각한 보안 위험이 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;sub 클레임 패턴 예시:&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;목적&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;sub 패턴&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;main 브랜치만&lt;/td&gt;
&lt;td&gt;repo:org/repo:ref:refs/heads/main&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;모든 브랜치&lt;/td&gt;
&lt;td&gt;repo:org/repo:*&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;특정 환경(Environment)&lt;/td&gt;
&lt;td&gt;repo:org/repo:environment:production&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PR만&lt;/td&gt;
&lt;td&gt;repo:org/repo:pull_request&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;특정 태그&lt;/td&gt;
&lt;td&gt;repo:org/repo:ref:refs/tags/v*&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Step 3: Role에 배포에 필요한 권한 추가&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;aws iam attach-role-policy \
  --role-name GitHubActionsDeployRole \
  --policy-arn arn:aws:iam::aws:policy/AmazonS3FullAccess&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최소 권한 원칙에 따라 실제로 필요한 서비스와 액션만 부여하세요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Step 4: GitHub Actions Workflow 설정&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;# .github/workflows/deploy.yml
name: Deploy to AWS

on:
  push:
    branches: [main]

permissions:
  id-token: write   # OIDC 토큰 요청 권한 필수
  contents: read

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Configure AWS Credentials (OIDC)
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: arn:aws:iam::123456789012:role/GitHubActionsDeployRole
          aws-region: ap-northeast-2

      - name: Verify identity
        run: aws sts get-caller-identity

      - name: Deploy to S3
        run: |
          aws s3 sync ./dist s3://my-app-bucket --delete

      - name: Invalidate CloudFront
        run: |
          aws cloudfront create-invalidation \
            --distribution-id EDFDVBD6EXAMPLE \
            --paths &quot;/*&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3-3. 환경(Environment)별 Role 분리 전략&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로덕션과 스테이징을 분리하려면, GitHub Environments와 OIDC를 조합합니다.&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;# 스테이징 배포 job
deploy-staging:
  environment: staging
  steps:
    - uses: aws-actions/configure-aws-credentials@v4
      with:
        role-to-assume: arn:aws:iam::111111111:role/GitHubActions-Staging
        # sub: &quot;repo:org/repo:environment:staging&quot;

# 프로덕션 배포 job (승인 필요)
deploy-production:
  environment: production   # GitHub에서 승인자 지정 가능
  steps:
    - uses: aws-actions/configure-aws-credentials@v4
      with:
        role-to-assume: arn:aws:iam::999999999:role/GitHubActions-Production
        # sub: &quot;repo:org/repo:environment:production&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;신뢰 정책에서 각 환경마다 다른 sub 조건:&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;&quot;StringEquals&quot;: {
  &quot;token.actions.githubusercontent.com:sub&quot;:
    &quot;repo:my-org/my-repo:environment:production&quot;
}&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4. SAML 2.0 Federation&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4-1. SAML이란?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SAML(Security Assertion Markup Language)은 기업 환경에서 오랫동안 사용해온 &lt;b&gt;XML 기반 SSO 표준&lt;/b&gt;입니다. 주로 기업 IdP(Active Directory, Okta, Azure AD 등)와 연동할 때 사용합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;OIDC가 JWT를 사용한다면, SAML은 &lt;b&gt;XML Assertion&lt;/b&gt;을 사용합니다. 내용은 비슷하지만 포맷이 다릅니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;주요 SAML IdP:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Microsoft Active Directory Federation Services (ADFS)&lt;/li&gt;
&lt;li&gt;Azure Active Directory (Azure AD / Entra ID)&lt;/li&gt;
&lt;li&gt;Okta&lt;/li&gt;
&lt;li&gt;Google Workspace&lt;/li&gt;
&lt;li&gt;Shibboleth&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4-2. SAML Federation 동작 원리&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SAML Federation으로 AWS 콘솔에 로그인하는 흐름:&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;1. 직원이 회사 포털/IdP 접속
2. IdP가 Active Directory 등으로 사용자 인증
3. IdP가 SAML Assertion(XML) 생성
   - 누가 인증받았는지
   - 어떤 AWS Role을 허용하는지
4. SAML Assertion을 AWS Sign-In 엔드포인트로 전달
5. AWS가 Assertion 검증 + STS AssumeRoleWithSAML 호출
6. 임시 자격 증명으로 AWS 콘솔 세션 생성
7. 직원이 바로 AWS 콘솔에 로그인 완료&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1440&quot; data-origin-height=&quot;960&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dJeTOS/dJMcaad6aMb/oiRIfgkZuPgUzI27Ef5cJk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dJeTOS/dJMcaad6aMb/oiRIfgkZuPgUzI27Ef5cJk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dJeTOS/dJMcaad6aMb/oiRIfgkZuPgUzI27Ef5cJk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdJeTOS%2FdJMcaad6aMb%2FoiRIfgkZuPgUzI27Ef5cJk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1440&quot; height=&quot;960&quot; data-origin-width=&quot;1440&quot; data-origin-height=&quot;960&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;직원 입장에서는 &lt;b&gt;회사 계정 하나로 AWS 콘솔에 바로 들어갑니다.&lt;/b&gt; IAM User 비밀번호를 따로 기억할 필요가 없습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4-3. SAML Federation 핵심 구성 요소&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;① IAM SAML Identity Provider 등록&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;dsconfig&quot;&gt;&lt;code&gt;# IdP 메타데이터 XML 파일로 등록
aws iam create-saml-provider \
  --name &quot;CompanyActiveDirectory&quot; \
  --saml-metadata-document file://idp-metadata.xml
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;② IAM Role의 신뢰 정책&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SAML Federation용 신뢰 정책은 OIDC와 구조가 유사하지만, Action이 sts:AssumeRoleWithSAML이고 Principal이 SAML Provider ARN을 가리킵니다:&lt;/p&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;{
  &quot;Version&quot;: &quot;2012-10-17&quot;,
  &quot;Statement&quot;: [
    {
      &quot;Effect&quot;: &quot;Allow&quot;,
      &quot;Principal&quot;: {
        &quot;Federated&quot;: &quot;arn:aws:iam::123456789012:saml-provider/CompanyActiveDirectory&quot;
      },
      &quot;Action&quot;: &quot;sts:AssumeRoleWithSAML&quot;,
      &quot;Condition&quot;: {
        &quot;StringEquals&quot;: {
          &quot;SAML:aud&quot;: &quot;https://signin.aws.amazon.com/saml&quot;
        }
      }
    }
  ]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;③ SAML Assertion의 역할 매핑&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IdP는 SAML Assertion 안에 사용자가 어떤 AWS Role을 사용해야 하는지를 포함시켜 전달합니다. 여러 Role이 있다면 사용자가 로그인 시 Role을 선택할 수 있습니다.&lt;/p&gt;
&lt;pre class=&quot;http&quot;&gt;&lt;code&gt;
  
    arn:aws:iam::123456789012:role/SAML-Admin,
    arn:aws:iam::123456789012:saml-provider/CompanyAD
  

&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;④ 역할 그룹 매핑 전략&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실무에서는 AD 그룹을 AWS Role에 매핑합니다:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Active Directory 그룹 AWS IAM Role 권한 수준&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;AWS-Admins&lt;/td&gt;
&lt;td&gt;SAML-Admin&lt;/td&gt;
&lt;td&gt;AdministratorAccess&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AWS-Developers&lt;/td&gt;
&lt;td&gt;SAML-Developer&lt;/td&gt;
&lt;td&gt;PowerUserAccess&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AWS-ReadOnly&lt;/td&gt;
&lt;td&gt;SAML-ReadOnly&lt;/td&gt;
&lt;td&gt;ReadOnlyAccess&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AWS-Finance&lt;/td&gt;
&lt;td&gt;SAML-Finance&lt;/td&gt;
&lt;td&gt;Billing 접근만&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;5. OIDC vs SAML 비교&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;비교 항목 OIDC SAML 2.0&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;비교 항목&amp;nbsp;&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;OIDC&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;SAML 2.0&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;토큰 형식&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;JWT (JSON)&lt;/td&gt;
&lt;td&gt;XML Assertion&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;주요 사용처&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;CI/CD, 모바일, 웹앱&lt;/td&gt;
&lt;td&gt;기업 SSO, AD 연동&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;설정 복잡도&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;상대적으로 간단&lt;/td&gt;
&lt;td&gt;다소 복잡 (XML 기반)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;STS API&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;AssumeRoleWithWebIdentity&lt;/td&gt;
&lt;td&gt;AssumeRoleWithSAML&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;세션 유효 기간&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;기본 1시간&lt;/td&gt;
&lt;td&gt;최대 12시간&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;대표 IdP&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;GitHub, Google, Cognito&lt;/td&gt;
&lt;td&gt;Okta, ADFS, Azure AD&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;언제 뭘 쓰나:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;기업 직원이 AWS 콘솔/CLI에 접근 &amp;rarr; &lt;b&gt;SAML&lt;/b&gt; (또는 IAM Identity Center)&lt;/li&gt;
&lt;li&gt;GitHub Actions / GitLab CI 등 CI/CD &amp;rarr; &lt;b&gt;OIDC&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;Kubernetes 파드가 AWS 접근 &amp;rarr; &lt;b&gt;OIDC&lt;/b&gt; (EKS IRSA)&lt;/li&gt;
&lt;li&gt;모바일/웹 앱 사용자가 AWS 접근 &amp;rarr; &lt;b&gt;OIDC + Cognito&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;6. 실습: GitHub Actions OIDC 설정&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 실습은 Access Key 없이 GitHub Actions에서 AWS S3에 파일을 업로드하는 것을 구현합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;실습 준비&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;GitHub 계정과 레포지토리&lt;/li&gt;
&lt;li&gt;AWS 계정 (IAM 관리 권한)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Step 1: AWS에 GitHub OIDC Provider 등록&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;콘솔:&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;IAM &amp;rarr; Identity providers &amp;rarr; Add provider
Provider type: OpenID Connect
Provider URL: https://token.actions.githubusercontent.com
&amp;rarr; [Get thumbprint] 클릭
Audience: sts.amazonaws.com
&amp;rarr; Add provider&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;CLI:&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;aws iam create-open-id-connect-provider \
  --url &quot;https://token.actions.githubusercontent.com&quot; \
  --client-id-list &quot;sts.amazonaws.com&quot; \
  --thumbprint-list &quot;6938fd4d98bab03faadb97b34396831e3780aea1&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Step 2: IAM Role 생성&lt;/h3&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;# 신뢰 정책 파일 생성
cat &amp;gt; github-trust-policy.json &amp;lt;&amp;lt; 'EOF'
{
  &quot;Version&quot;: &quot;2012-10-17&quot;,
  &quot;Statement&quot;: [
    {
      &quot;Effect&quot;: &quot;Allow&quot;,
      &quot;Principal&quot;: {
        &quot;Federated&quot;: &quot;arn:aws:iam::ACCOUNT_ID:oidc-provider/token.actions.githubusercontent.com&quot;
      },
      &quot;Action&quot;: &quot;sts:AssumeRoleWithWebIdentity&quot;,
      &quot;Condition&quot;: {
        &quot;StringEquals&quot;: {
          &quot;token.actions.githubusercontent.com:aud&quot;: &quot;sts.amazonaws.com&quot;
        },
        &quot;StringLike&quot;: {
          &quot;token.actions.githubusercontent.com:sub&quot;: &quot;repo:YOUR_ORG/YOUR_REPO:*&quot;
        }
      }
    }
  ]
}
EOF

# ACCOUNT_ID와 레포지토리 정보 교체
sed -i 's/ACCOUNT_ID/실제계정ID/g' github-trust-policy.json
sed -i 's/YOUR_ORG\/YOUR_REPO/실제조직\/실제레포/g' github-trust-policy.json

# Role 생성
aws iam create-role \
  --role-name GitHubActionsDeployRole \
  --assume-role-policy-document file://github-trust-policy.json

# S3 권한 부여 (테스트용)
aws iam attach-role-policy \
  --role-name GitHubActionsDeployRole \
  --policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Step 3: GitHub Workflow 파일 작성&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;레포지토리에 .github/workflows/aws-oidc-test.yml 파일 생성:&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;name: AWS OIDC Test

on:
  push:
    branches: [main]
  workflow_dispatch:   # 수동 실행도 허용

permissions:
  id-token: write   # OIDC 토큰 발급에 필수
  contents: read

jobs:
  test-aws-access:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Configure AWS Credentials via OIDC
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: arn:aws:iam::ACCOUNT_ID:role/GitHubActionsDeployRole
          aws-region: ap-northeast-2

      - name: Verify AWS Identity
        run: |
          echo &quot;=== 현재 자격 증명 확인 ===&quot;
          aws sts get-caller-identity

      - name: List S3 Buckets
        run: |
          echo &quot;=== S3 버킷 목록 ===&quot;
          aws s3 ls

      - name: Try EC2 (should fail - no permission)
        run: |
          echo &quot;=== EC2 접근 시도 (실패 예상) ===&quot;
          aws ec2 describe-instances || echo &quot;EC2 접근 거부됨 (예상된 결과)&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Step 4: 실행 및 결과 확인&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GitHub에서 Actions 탭 &amp;rarr; 워크플로우 실행&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;결과:&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;=== 현재 자격 증명 확인 ===
{
    &quot;UserId&quot;: &quot;AROA...:GitHubActionsDeployRole&quot;,
    &quot;Account&quot;: &quot;123456789012&quot;,
    &quot;Arn&quot;: &quot;arn:aws:sts::123456789012:assumed-role/GitHubActionsDeployRole/...&quot;
}
=== S3 버킷 목록 ===
2025-01-15 10:30:00 my-app-bucket
...
=== EC2 접근 시도 (실패 예상) ===
EC2 접근 거부됨 (예상된 결과)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;get-caller-identity 결과에서 Role 이름이 보이면 OIDC 인증 성공입니다. Access Key를 한 번도 사용하지 않았습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Step 5: sub 클레임 제한 확인&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보안 확인을 위해, 다른 브랜치에서의 접근이 차단되는지 테스트합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;신뢰 정책의 sub를 main 브랜치만으로 수정:&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;&quot;StringEquals&quot;: {
  &quot;token.actions.githubusercontent.com:sub&quot;:
    &quot;repo:YOUR_ORG/YOUR_REPO:ref:refs/heads/main&quot;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다른 브랜치에서 동일 workflow를 실행하면:&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;Error: Not authorized to perform sts:AssumeRoleWithWebIdentity&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이처럼 특정 브랜치/환경만 허용할 수 있습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;7. EKS IRSA &amp;mdash; Kubernetes에서의 OIDC&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS EKS(Elastic Kubernetes Service)에서도 동일한 OIDC 원리를 활용합니다. 이것을 IRSA(IAM Roles for Service Accounts)라고 부릅니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쿠버네티스 파드가 S3나 DynamoDB에 접근할 때, Access Key를 환경변수에 넣는 대신 Service Account에 IAM Role을 연결합니다.&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;# Kubernetes Service Account에 IAM Role 연결
apiVersion: v1
kind: ServiceAccount
metadata:
  name: my-app-sa
  namespace: default
  annotations:
    eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/MyPodRole&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IAM Role의 신뢰 정책:&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;{
  &quot;Effect&quot;: &quot;Allow&quot;,
  &quot;Principal&quot;: {
    &quot;Federated&quot;: &quot;arn:aws:iam::ACCOUNT_ID:oidc-provider/oidc.eks.ap-northeast-2.amazonaws.com/id/CLUSTER_ID&quot;
  },
  &quot;Action&quot;: &quot;sts:AssumeRoleWithWebIdentity&quot;,
  &quot;Condition&quot;: {
    &quot;StringEquals&quot;: {
      &quot;oidc.eks.ap-northeast-2.amazonaws.com/id/CLUSTER_ID:sub&quot;:
        &quot;system:serviceaccount:default:my-app-sa&quot;
    }
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 설정하면 파드 내 애플리케이션은 SDK가 자동으로 OIDC 토큰을 교환해 IAM Role 자격 증명을 받아옵니다. EC2 Instance Profile과 동일한 개발자 경험을 Kubernetes에서도 구현합니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;9. Federation 설계 모범 사례&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;원칙 1: Condition은 항상 최대한 좁게&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;1c&quot;&gt;&lt;code&gt;// 나쁜 예: 너무 넓음
&quot;StringLike&quot;: {&quot;token.actions.githubusercontent.com:sub&quot;: &quot;*&quot;}

// 좋은 예: 특정 레포지토리, 특정 환경만
&quot;StringEquals&quot;: {
  &quot;token.actions.githubusercontent.com:sub&quot;:
    &quot;repo:my-org/my-repo:environment:production&quot;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;원칙 2: 환경별 Role 분리&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;crmsh&quot;&gt;&lt;code&gt;GitHubActions-Dev-Role    &amp;rarr; 개발 계정
GitHubActions-Staging-Role &amp;rarr; 스테이징 계정
GitHubActions-Prod-Role   &amp;rarr; 프로덕션 계정 (승인 필요)
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;원칙 3: 최소 권한&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;pgsql&quot;&gt;&lt;code&gt;배포 Role에는 실제 배포에 필요한 서비스(S3, ECR, ECS 등)만
읽기 전용 Role과 배포 Role을 분리
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;원칙 4: CloudTrail로 Federation 로그인 모니터링&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;properties&quot;&gt;&lt;code&gt;# SAML Federation 로그인 이벤트 확인
aws cloudtrail lookup-events \
  --lookup-attributes AttributeKey=EventName,AttributeValue=AssumeRoleWithSAML

# OIDC 이벤트 확인
aws cloudtrail lookup-events \
  --lookup-attributes AttributeKey=EventName,AttributeValue=AssumeRoleWithWebIdentity
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;10. 마치며&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Federation의 핵심:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;AWS 외부의 자격 증명 시스템을 AWS에서 신뢰하는 것&lt;/li&gt;
&lt;li&gt;외부 인증 후 STS가 임시 자격 증명을 발급&lt;/li&gt;
&lt;li&gt;IAM User를 만들지 않아도 됨&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;OIDC:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;JWT 기반, GitHub Actions/K8s/모바일 앱에 적합&lt;/li&gt;
&lt;li&gt;AssumeRoleWithWebIdentity 사용&lt;/li&gt;
&lt;li&gt;신뢰 정책 Condition에 반드시 aud + sub 모두 설정&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;SAML:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;XML 기반, 기업 AD/Okta/Azure AD 연동에 적합&lt;/li&gt;
&lt;li&gt;AssumeRoleWithSAML 사용&lt;/li&gt;
&lt;li&gt;AD 그룹 &amp;rarr; IAM Role 매핑으로 대규모 조직 관리&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;가장 중요한 실천 사항:&lt;/b&gt; GitHub Actions에서 AWS_ACCESS_KEY_ID를 Secrets에 저장하는 방식을 즉시 OIDC로 교체하세요. 설정은 30분이면 충분하고, 보안은 크게 향상됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;참고 자료&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.aws.amazon.com/ko_kr/IAM/latest/UserGuide/id_roles_providers.html&quot;&gt;AWS 공식 문서: ID 공급자 및 페더레이션&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_oidc.html&quot;&gt;AWS 공식 문서: IAM에서 OIDC IdP 생성&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://aws.amazon.com/blogs/security/use-iam-roles-to-connect-github-actions-to-actions-in-aws/&quot;&gt;AWS 블로그: GitHub Actions에서 IAM Role로 AWS 접근&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/configuring-openid-connect-in-amazon-web-services&quot;&gt;GitHub 공식 문서: OIDC in Amazon Web Services&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_saml.html&quot;&gt;AWS 공식 문서: SAML 2.0 Federation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://aws.amazon.com/ko/blogs/korea/how-to-use-trust-policies-with-iam-roles/&quot;&gt;AWS 블로그: IAM 역할에서 신뢰 정책 사용 방법&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.aws.amazon.com/ko_kr/eks/latest/userguide/iam-roles-for-service-accounts-technical-overview.html&quot;&gt;AWS 공식 문서: EKS IRSA 기술 개요&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>AWS</category>
      <category>IAM Federation</category>
      <category>OIDC</category>
      <author>lhywk</author>
      <guid isPermaLink="true">https://lhywk.tistory.com/105</guid>
      <comments>https://lhywk.tistory.com/105#entry105comment</comments>
      <pubDate>Sat, 2 May 2026 12:31:59 +0900</pubDate>
    </item>
    <item>
      <title>Bybit / Safe{Wallet} 사고 사례 분석</title>
      <link>https://lhywk.tistory.com/104</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 개요&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;662&quot; data-origin-height=&quot;362&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bS4PuY/dJMcacwbgmM/mUmsvDtMIChjPlq020qfbk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bS4PuY/dJMcacwbgmM/mUmsvDtMIChjPlq020qfbk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bS4PuY/dJMcacwbgmM/mUmsvDtMIChjPlq020qfbk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbS4PuY%2FdJMcacwbgmM%2FmUmsvDtMIChjPlq020qfbk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;561&quot; height=&quot;307&quot; data-origin-width=&quot;662&quot; data-origin-height=&quot;362&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;사건 배경&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2025년 2월 21일 세계 최대 규모의 암호화폐 거래소 중 하나인 Bybit에서 역대 최대 규모의 암호화폐 해킹 사건이 발생하였습니다. 이 사건으로 약 401,000 ETH, 미화 약 15억 달러(한화 약 2조 원) 상당의 자산이 탈취되었으며 Web3 역사상 단일 사건으로는 전례 없는 피해 규모를 기록하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Bybit의 콜드 월렛은 멀티시그 방식의 스마트 컨트랙트 지갑 플랫폼인 &lt;b&gt;Safe{Wallet}&lt;/b&gt;(구 Gnosis Safe)으로 보호되고 있었습니다. 멀티시그 방식은 복수의 승인자가 트랜잭션에 서명해야만 실행되는 구조로 이론적으로는 매우 견고한 보안 체계입니다. 그러나 공격자는 스마트 컨트랙트 자체를 공격하지 않고 &lt;b&gt;Safe{Wallet}의 프론트엔드 인터페이스를 공급망 공격&lt;/b&gt;&amp;nbsp;방식으로 침해함으로써 이 보안 체계를 우회하였습니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;공격 주체&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;미국 연방수사국(FBI)은 이 공격의 배후로 &lt;b&gt;북한 국가 지원 해킹 그룹 TraderTraitor&lt;/b&gt;를 공식 지목하였습니다. TraderTraitor는 Jade Sleet, PUKCHONG, UNC4899, Slow Pisces 등의 별칭으로도 알려져 있으며 광범위한 Lazarus Group의 하위 조직으로 분류됩니다. Mandiant(Google Cloud 소속)도 독자적인 포렌식 조사를 통해 동일 결론에 도달하였습니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;피해 현황 요약&lt;/h4&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;항목&lt;/td&gt;
&lt;td&gt;내용&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;피해 발생일&lt;/td&gt;
&lt;td&gt;2025년 2월 21일&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;피해 금액&lt;/td&gt;
&lt;td&gt;약 15억 달러 (401,000 ETH)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;공격 벡터&lt;/td&gt;
&lt;td&gt;Safe{Wallet} AWS S3 버킷 내 악성 JavaScript 삽입&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;공격 주체&lt;/td&gt;
&lt;td&gt;TraderTraitor (Lazarus Group 하위 조직, 북한 국가 지원)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;피해 대상&lt;/td&gt;
&lt;td&gt;Bybit ETH 콜드 월렛&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;조사 기관&lt;/td&gt;
&lt;td&gt;Sygnia, Google Cloud Mandiant, FBI&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. 공격 분석&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2.1 공격 타임라인&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 사건은 약 &lt;b&gt;19일에 걸친 치밀하게 계획된 다단계 공격&lt;/b&gt;이었습니다.&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;2025-02-04  Safe{Wallet} 개발자(Developer1) macOS 노트북 최초 침해
2025-02-05  탈취한 AWS 세션 토큰으로 Safe{Wallet} AWS 인프라 최초 접근
2025-02-05 ~ 02-17  AWS 인프라 내부 정찰 및 횡적 이동
2025-02-19  Safe{Wallet} AWS S3 버킷 내 JavaScript 악성 코드 삽입 (15:29:25 UTC)
2025-02-21  Bybit ETH 콜드 월렛 &amp;rarr; 웜 월렛 트랜잭션 실행 시도
            악성 코드 활성화 및 트랜잭션 조작 (14:13:35 UTC)
            공격자, 콜드 월렛 스마트 컨트랙트 소유권 탈취 및 전액 인출
            악성 코드 제거 및 정상 JavaScript 재업로드 (~14:15 UTC)
2025-02-25  Sygnia의 중간 조사 보고서 Bybit에 전달
2025-03-06  Safe{Wallet}, Mandiant 조사 결과 공개 및 TraderTraitor 공식 귀속&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2.2 초기 침투: 소셜 엔지니어링을 통한 개발자 노트북 감염&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공격의 출발점은 Safe{Wallet}의 내부 개발자 한 명이었습니다. Safe{Wallet} 조사 결과에 따르면 &lt;b&gt;2025년 2월 4일&lt;/b&gt;&amp;nbsp;해당 개발자(이하 Developer1)는 Apple macOS 노트북에서 &lt;b&gt;MC-Based-Stock-Invest-Simulator-main&lt;/b&gt;이라는 이름의 Docker 프로젝트를 다운로드하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 Docker 프로젝트는 소셜 엔지니어링 공격의 일환으로 배포된 악성 패키지로 실행 시 getstockprice[.]com 이라는 도메인과 통신하였습니다. 해당 도메인은 프로젝트 다운로드 이틀 전에 Namecheap을 통해 등록된 신규 도메인이었습니다. Mandiant는 TraderTraitor가 과거에도 주식 시뮬레이터 테마의 Docker 프로젝트를 유사한 공격에 활용한 선례가 있다고 확인하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Developer1은 Safe{Wallet} 내에서 AWS 인프라에 대한 높은 수준의 접근 권한을 보유한 소수의 인원 중 한 명이었으며 이것이 공격자가 이 개발자를 표적으로 삼은 핵심 이유였습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2.3 AWS 세션 토큰 탈취 및 MFA 우회&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;노트북 감염에 성공한 공격자는 다음 단계로 &lt;b&gt;AWS 인프라 침투&lt;/b&gt;를 시도하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공격자는 가장 먼저 자신들의 MFA 기기를 Developer1의 AWS 계정에 등록하려 시도하였으나 이는 실패하였습니다. 이에 따라 더 정교한 방법으로 전환하여 &lt;b&gt;감염된 노트북에서 Developer1의 활성 AWS 세션 토큰을 직접 탈취&lt;/b&gt;하는 방식을 택하였습니다. 이를 통해 MFA 인증 체계 자체를 우회하는 데 성공하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공격자의 AWS 접근 행위는 &lt;b&gt;ExpressVPN IP 주소&lt;/b&gt;를 통해 이루어졌으며 User-Agent 문자열에 distrib#kali.2024가 포함되어 있어 Kali Linux 기반 공격 환경이 사용되었음을 나타냈습니다. 또한 공격자는 &lt;b&gt;Developer1의 실제 근무 시간대에 맞추어 활동&lt;/b&gt;하여 정상적인 접근처럼 보이도록 위장하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후 2월 5일부터 2월 17일까지 약 2주 동안 공격자는 Safe{Wallet}의 AWS 환경 내부에서 광범위한 &lt;b&gt;정찰&lt;/b&gt;을 수행하였으며, IAM 역할 및 클라우드 자산 구성을 파악하였습니다. 조사를 마친 후 공격자는 자신이 설치한 악성 코드를 삭제하고 Bash 히스토리를 지워 흔적을 은폐하였습니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2.4 공급망 공격: AWS S3 버킷 내 악성 JavaScript 삽입&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2025년 2월 19일 15:29:25 UTC 공격자는 Safe{Wallet}의 웹 프론트엔드를 제공하는 &lt;b&gt;AWS S3 버킷에 악성 JavaScript 코드를 삽입&lt;/b&gt;하였습니다. 독립 보안 분석 기관인 Verichains는 공개 웹 아카이브 스냅샷을 통해 이 삽입 시각을 정확히 특정하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;악성 코드의 핵심 특징은 다음과 같습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;표적 선별적 활성화:&lt;/b&gt; 악성 코드는 Bybit의 콜드 월렛 컨트랙트 주소를 명시적으로 감지하도록 설계되어 &lt;b&gt;오직 Bybit의 트랜잭션이 시도될 때만 동작&lt;/b&gt;하였습니다. 다른 Safe{Wallet} 이용자들은 정상적인 인터페이스를 경험하였습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;UI 위조:&lt;/b&gt; 악성 JavaScript는 서명자에게 보여지는 트랜잭션 세부 정보를 실시간으로 조작하였습니다. 서명자들의 화면에는 정상적인 트랜잭션처럼 보였지만 실제로 블록체인에 전송되는 데이터는 공격자가 조작한 것이었습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;흔적 은폐:&lt;/b&gt; Bybit의 악성 트랜잭션이 실행된 직후 약 2분 이내에 공격자는 S3 버킷에 정상 JavaScript를 재업로드하여 악성 코드를 즉시 제거하였습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2.5 트랜잭션 조작 및 스마트 컨트랙트 탈취&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2025년 2월 21일 Bybit의 서명자들은 콜드 월렛에서 웜 월렛으로의 &lt;b&gt;일상적인 내부 이체&lt;/b&gt; 트랜잭션을 실행하려 하였습니다. Bybit CEO Ben Zhou를 포함한 서명자들은 Safe{Wallet} 웹 인터페이스에서 정상적인 트랜잭션을 확인하고 서명을 진행하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러나 공격자가 삽입한 악성 JavaScript는 서명자들이 인지하지 못한 채로 트랜잭션의 실제 내용을 다음과 같이 바꿔치기하였습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;정상 트랜잭션:&lt;/b&gt; 콜드 월렛 -&amp;gt; 웜 월렛 ETH 이체&lt;/li&gt;
&lt;li&gt;&lt;b&gt;조작된 트랜잭션:&lt;/b&gt; Bybit 콜드 월렛 스마트 컨트랙트의 &lt;b&gt;구현체를 공격자가 미리 배포한 악성 컨트랙트로 교체&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 조작의 핵심은 이더리움 스마트 컨트랙트의 &lt;b&gt;delegatecall&lt;/b&gt; 기능을 악용한 것이었습니다. delegatecall은 한 컨트랙트가 다른 컨트랙트의 코드를 자신의 스토리지 컨텍스트에서 실행할 수 있게 해주는 기능입니다. 공격자는 서명자들이 자신도 모르게 월렛의 컨트랙트 로직 자체를 악성 버전으로 교체하도록 유도하였으며 이를 통해 멀티시그 승인 없이도 임의의 금액을 인출할 수 있는 sweepETH(), sweepERC20() 함수가 포함된 악성 컨트랙트가 Bybit 콜드 월렛을 완전히 장악하게 되었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 Safe{Wallet}은 당시 &lt;b&gt;SRI&lt;/b&gt; 해시 검증을 구현하지 않았고 별도의 실시간 프론트엔드 변조 탐지 메커니즘도 부재하였습니다. EIP-712 서명 표준 역시 중첩된 스마트 컨트랙트 연산을 사람이 읽을 수 있는 형태로 표시하는 데 한계가 있어, 서명자들이 자신이 무엇에 서명하는지 실질적으로 검증하기 어려운 구조였습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2.6 자금 세탁 및 추적&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;탈취된 ETH는 이후 조직화된 방식으로 세탁되었습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;탈취 직후 다수의 중간 지갑으로 분산&lt;/li&gt;
&lt;li&gt;THORChain 등 탈중앙화 크로스체인 브릿지를 통해 BTC 및 기타 암호화폐로 전환&lt;/li&gt;
&lt;li&gt;6954개 이상의 지갑으로 분산 보관&lt;/li&gt;
&lt;li&gt;ZachXBT의 온체인 분석을 통해 Lazarus Group과의 연관성이 최종 확인&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;조사 기관들의 추적에 따르면 약 77%의 자금은 일정 기간 추적이 가능하였으며 20%는 추적이 불가능한 상태로 전환되었고 3%는 동결 조치되었습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. 대응 방안&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 사건은 크게 세 가지 지점에서 보안 실패가 발생하였습니다. 1. &lt;b&gt;개발자 엔드포인트 침해 -&amp;gt; 2. AWS 세션 토큰 탈취 -&amp;gt; 3. S3 프론트엔드 변조.&lt;/b&gt; 각 단계에서 실질적으로 적용 가능한 대응 방안을 아래에 정리하였습니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3.1 높은 권한을 가진 개발자 계정의 엔드포인트 보호&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 공격은 AWS 고권한 개발자의 맥북 한 대를 장악하는 것에서 시작되었습니다. Developer1이 미확인 Docker 프로젝트를 실행한 것이 전체 침해의 출발점이었습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;외부 소프트웨어 실행 통제:&lt;/b&gt; AWS 등 인프라에 접근 권한을 가진 개발자는 미검증 오픈소스 프로젝트, 특히 Docker 이미지나 Python 스크립트를 업무 환경에서 직접 실행하는 것을 사내 정책으로 금지하여야 합니다. TraderTraitor는 이 수법을 Bybit 이전에도 반복적으로 사용하였습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;FIDO2 기반 MFA 적용:&lt;/b&gt; 이번 사건에서 공격자는 세션 토큰을 탈취하여 기존 MFA를 완전히 우회하였습니다. TOTP(시간 기반 OTP) 방식은 세션 탈취에 무력하므로 하드웨어 키 기반의 FIDO2 인증으로 전환하여야 합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3.2 AWS 세션 토큰 탈취 대응&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공격자는 감염된 맥북에서 활성 AWS 세션 토큰을 추출하여 MFA 없이 Safe{Wallet}의 AWS 환경에 접근하였습니다. ExpressVPN을 통해 접속하면서 개발자의 근무 시간대에 맞춰 활동하였기 때문에 상당 기간 탐지를 피하였습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;세션 토큰 수명 단축:&lt;/b&gt; AWS IAM에서 임시 자격증명의 세션 지속 시간을 업무상 필요한 최소값으로 설정하여야 합니다. 세션이 짧을수록 탈취된 토큰의 유효 기간도 줄어듭니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;비정상 접근 실시간 탐지:&lt;/b&gt; AWS CloudTrail과 GuardDuty를 연동하여 기존과 다른 IP 대역, 알려진 VPN/프록시 IP, 비정상적인 시간대의 API 호출에 대한 실시간 알림을 설정하여야 합니다. 이번 사건에서 공격자가 사용한 ExpressVPN IP와 Kali Linux User-Agent는 충분히 탐지 가능한 이상 징후였습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;최소 권한 원칙 적용:&lt;/b&gt; S3 버킷에 대한 쓰기 권한은 배포 파이프라인 전용 서비스 계정으로만 제한하고, 개발자 개인 계정에는 읽기 권한만 부여하여야 합니다. Developer1의 계정이 S3 오브젝트를 직접 수정할 수 있었던 것이 피해를 가능하게 한 직접적인 원인이었습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3.3 S3 프론트엔드 코드 변조 탐지 및 차단&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Safe{Wallet}은 JavaScript 파일이 S3에 무단으로 수정되었음을 실시간으로 탐지하는 체계가 없었습니다. 악성 코드는 이틀간 서빙되었고, 아무도 눈치채지 못하였습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;SRI 해시 적용:&lt;/b&gt; 프론트엔드 HTML에서 로드하는 JavaScript 파일에 integrity 해시를 명시하면 파일 내용이 변조되었을 때 브라우저가 자동으로 실행을 차단합니다. 이번 사건에서 SRI가 적용되어 있었다면 악성 JavaScript는 브라우저 수준에서 차단되었을 것입니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;S3 객체 변경 알림 구성:&lt;/b&gt; S3 버킷 이벤트 알림 또는 CloudTrail + EventBridge를 통해 프론트엔드 파일이 변경될 때마다 즉각적인 알림이 발송되도록 구성하여야 합니다. 배포 파이프라인 외의 경로로 S3 객체가 수정되는 것은 명백한 이상 징후입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;참고 자료&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;The Hacker News - Safe{Wallet} Confirms North Korean TraderTraitor Hackers - &lt;a href=&quot;https://thehackernews.com/2025/03/safewallet-confirms-north-korean.html&quot;&gt;https://thehackernews.com/2025/03/safewallet-confirms-north-korean.html&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;The Hacker News - Bybit Hack Traced to Safe{Wallet} Supply Chain Attack - &lt;a href=&quot;https://thehackernews.com/2025/02/bybit-hack-traced-to-safewallet-supply.html&quot;&gt;https://thehackernews.com/2025/02/bybit-hack-traced-to-safewallet-supply.html&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Cryptopolitan - Safe Wallet Update on Bybit Hack - &lt;a href=&quot;https://www.cryptopolitan.com/safe-wallet-releases-update-on-bybit-hack/&quot;&gt;https://www.cryptopolitan.com/safe-wallet-releases-update-on-bybit-hack/&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PANews - Safe{Wallet} Forensic Investigation Report - &lt;a href=&quot;https://www.panewslab.com/en/articles/nqhu2v42&quot;&gt;https://www.panewslab.com/en/articles/nqhu2v42&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;NCC Group - In-Depth Technical Analysis of the Bybit Hack - &lt;a href=&quot;https://www.nccgroup.com/research/in-depth-technical-analysis-of-the-bybit-hack/&quot;&gt;https://www.nccgroup.com/research/in-depth-technical-analysis-of-the-bybit-hack/&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>AWS</category>
      <category>AWS 침해사고 사례 분석</category>
      <author>lhywk</author>
      <guid isPermaLink="true">https://lhywk.tistory.com/104</guid>
      <comments>https://lhywk.tistory.com/104#entry104comment</comments>
      <pubDate>Wed, 29 Apr 2026 02:22:38 +0900</pubDate>
    </item>
    <item>
      <title>OLX Europe의 봇 방어 아키텍처 분석</title>
      <link>https://lhywk.tistory.com/103</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 개요&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;OLX Europe은 매월 3억 명 이상이 이용하는 글로벌 중고 거래 플랫폼으로 32개 이상의 국가에서 서비스를 운영하고 있습니다. 이 규모의 플랫폼은 자연스럽게 다양한 악성 봇의 표적이 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;OLX가 직면한 주요 위협은 크게 세 가지였습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;콘텐츠 스크래핑&lt;/b&gt;: 경쟁 사이트가 OLX의 상품 정보를 자동으로 수집하여 자사 플랫폼에 활용&lt;/li&gt;
&lt;li&gt;&lt;b&gt;DDoS 공격&lt;/b&gt;: 서비스 가용성을 위협하는 대규모 분산 서비스 거부 공격&lt;/li&gt;
&lt;li&gt;&lt;b&gt;계정 탈취(Account Takeover, ATO)&lt;/b&gt;: 자동화된 브루트포스를 통한 사용자 계정 침해&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;계정이 탈취될 경우 공격자는 OLX 마켓플레이스에서 가짜 상품을 판매하는 등 사기 행위를 벌일 수 있어 사용자 신뢰를 핵심 가치로 삼는 OLX에게 심각한 비즈니스 리스크로 작용했습니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;전환 배경 및 목표&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존에 OLX는 외부 벤더의 봇 보호 솔루션을 사용하고 있었으나 비용이 높고 가시성과 제어 유연성이 부족하다는 한계가 있었습니다. CDN 마이그레이션 기회를 활용해 AWS 기반의 인하우스 엣지 보안 솔루션을 직접 구축하기로 결정했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;구축 목표&lt;/b&gt;는 다음과 같았습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;중앙 집중식 보안 거버넌스 구현 (다수의 AWS 계정 및 리전 관리)&lt;/li&gt;
&lt;li&gt;룰 업데이트 및 차단 이유 파악 등 운영 단순화&lt;/li&gt;
&lt;li&gt;기존 CDN 계약 만료 전 무중단 전환&lt;/li&gt;
&lt;li&gt;CDN 및 봇 보호 비용 50% 절감&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과적으로 OLX는 &lt;b&gt;3개월 만에&lt;/b&gt; 월 2,400억 건의 요청을 처리하는 엣지 보안 솔루션을 성공적으로 구축하였고 관련 비용을 50% 절감하는 성과를 달성했습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. 아키텍처 분석&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;OLX의 엣지 보안 아키텍처는 크게 세 개의 레이어로 구성됩니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;WAF 기반 보호 기반 구축&amp;nbsp;&lt;/li&gt;
&lt;li&gt;WAF 로그를 활용한 가시성 확보&amp;nbsp;&lt;/li&gt;
&lt;li&gt;자동화된 봇 탐지 및 차단&amp;nbsp;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1281&quot; data-origin-height=&quot;688&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sGNBx/dJMcai337Hk/OceUL08V141Gply3MZo3Lk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sGNBx/dJMcai337Hk/OceUL08V141Gply3MZo3Lk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sGNBx/dJMcai337Hk/OceUL08V141Gply3MZo3Lk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsGNBx%2FdJMcai337Hk%2FOceUL08V141Gply3MZo3Lk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1281&quot; height=&quot;688&quot; data-origin-width=&quot;1281&quot; data-origin-height=&quot;688&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2-1. AWS WAF + AWS Firewall Manager&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;AWS WAF 규칙 구성&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;OLX는 공개 엔드포인트에 AWS WAF를 적용하여 애플리케이션 계층(L7)에서 악성 요청을 차단합니다. 보호 정책은 두 가지 레이어로 구성됩니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;AWS Managed Rules&lt;/b&gt;: SQL Injection, XSS 등 일반적인 웹 위협에 대한 표준 기준선 보호&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Custom Rules&lt;/b&gt;: IP 매칭 기반의 자체 커스텀 규칙 추가 적용&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;중앙 집중식 규칙 관리 (GitOps 방식)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다수의 AWS 계정과 리전에 WAF 규칙을 일관되게 적용하기 위해 OLX는 GitOps 기반의 중앙화된 규칙 관리 체계를 도입했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;규칙 저장소 구조&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;754&quot; data-origin-height=&quot;1118&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ceuKeQ/dJMcafGmM1Y/PEI5CyGeikBruc9qtRVrb1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ceuKeQ/dJMcafGmM1Y/PEI5CyGeikBruc9qtRVrb1/img.png&quot; data-alt=&quot;OLX의 AWS WAF 규칙 저장소&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ceuKeQ/dJMcafGmM1Y/PEI5CyGeikBruc9qtRVrb1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FceuKeQ%2FdJMcafGmM1Y%2FPEI5CyGeikBruc9qtRVrb1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;469&quot; height=&quot;695&quot; data-origin-width=&quot;754&quot; data-origin-height=&quot;1118&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;OLX의 AWS WAF 규칙 저장소&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 WAF 규칙은 &lt;b&gt;AWS WAF JSON 포맷&lt;/b&gt;으로 개별 파일로 관리됩니다. 보안 엔지니어가 규칙 파일을 추가하거나 수정한 뒤 Git에 커밋하면 &lt;b&gt;CI/CD 파이프라인&lt;/b&gt;이 자동으로 트리거되어 다음 단계를 수행합니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;규칙 파일 통합 및 CloudFormation 템플릿 생성&lt;/li&gt;
&lt;li&gt;중앙 AWS 계정에 Firewall Manager WAF 정책 배포&lt;/li&gt;
&lt;li&gt;Firewall Manager가 각 AWS 계정의 CloudFront 리소스에 WAF WebACL 자동 배포&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;AWS Firewall Manager의 역할&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS Firewall Manager는 이 아키텍처의 핵심 거버넌스 레이어입니다. 중앙 관리자 계정 하나로 전체 AWS 조직의 WAF 규칙을 제어하며 신규 계정이나 리소스가 추가되더라도 보안 정책이 자동으로 적용됩니다. OLX는 Firewall Manager를 통해 WAF 로그 수집도 중앙에서 자동으로 활성화합니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2-2. 가시성 확보: WAF 로그 파이프라인&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;OLX는 하루 &lt;b&gt;400GB&lt;/b&gt;에 달하는 WAF 로그를 두 가지 경로로 이원화하여 처리합니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Amazon Kinesis Data Firehose&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Amazon Kinesis Data Firehose(현재 명칭: Amazon Data Firehose)는 스트리밍 데이터를 수집하여 실시간으로 원하는 목적지에 전달하는 &lt;b&gt;완전 관리형 서비스&lt;/b&gt;입니다. 서버 프로비저닝이나 인프라 관리 없이 데이터 양에 따라 자동으로 스케일링되며 초 단위로 데이터를 전송합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS WAF는 Kinesis Data Firehose와 네이티브 통합을 지원합니다. WAF WebACL에서 로깅을 활성화하면 AWS WAF가 검사하는 &lt;b&gt;모든 HTTP/S 요청&lt;/b&gt;에 대한 로그(요청 헤더, 발신 IP, 매칭된 규칙 등)를 지정된 Firehose 스트림으로 실시간 전송합니다. 단 스트림 이름은 반드시 aws-waf-logs-로 시작해야 합니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;로그 흐름 구조&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1440&quot; data-origin-height=&quot;1160&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5zxnx/dJMcaaLO7SJ/Qaph9nrDpt3mxSBkE7EOQK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5zxnx/dJMcaaLO7SJ/Qaph9nrDpt3mxSBkE7EOQK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5zxnx/dJMcaaLO7SJ/Qaph9nrDpt3mxSBkE7EOQK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5zxnx%2FdJMcaaLO7SJ%2FQaph9nrDpt3mxSBkE7EOQK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;529&quot; height=&quot;426&quot; data-origin-width=&quot;1440&quot; data-origin-height=&quot;1160&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Kinesis Data Firehose의 변환 기능을 활용하여 &lt;b&gt;허용 로그를 필터링&lt;/b&gt;한 것입니다. 차단 및 카운트 로그만 OpenSearch로 전송함으로써 비용을 절감하고 조회 성능을 높였습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Amazon S3&lt;/b&gt;: 전체 로그 아카이빙 및 Amazon Athena를 통한 비정기적 심층 분석&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Amazon OpenSearch&lt;/b&gt;: 차단, 카운트 로그만 수집하여 고객지원 엔지니어의 빠른 조회 지원&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Amazon OpenSearch Service&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Amazon OpenSearch Service는 대규모 데이터를 &lt;b&gt;밀리초 단위로 검색하고 분석&lt;/b&gt;할 수 있는 AWS의 완전 관리형 검색, 분석 엔진 서비스입니다. 원래는 오픈소스 검색 엔진인 Elasticsearch를 기반으로 한 Amazon Elasticsearch Service였으나 2021년 라이선스 정책 변경으로 AWS가 Elasticsearch 7.10을 기반으로 오픈소스 포크 프로젝트인 &lt;b&gt;OpenSearch&lt;/b&gt;를 만들었고 서비스 이름도 Amazon OpenSearch Service로 변경되었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;OpenSearch는 실시간 전문 검색이 가능한 데이터베이스에 가깝습니다. 데이터가 들어오는 즉시 인덱싱하여 IP 주소, User-Agent, 차단 규칙 이름 등 어떤 필드로든 수초 안에 검색 결과를 반환합니다. 또한 내장된 OpenSearch Dashboards(구 Kibana)를 통해 차단 현황, 공격 IP 분포, 시간별 트래픽 패턴 등을 시각화한 대시보드를 별도 도구 없이 구성할 수 있습니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;고객 지원 챗봇 (Slack 연동)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;OLX는 &lt;b&gt;Slack 챗봇&lt;/b&gt;을 자체 구축하여 고객지원팀이 별도의 AWS 콘솔 접근 없이 Slack에서 직접 특정 요청의 차단 이유를 조회할 수 있도록 했습니다. Amazon CloudFront가 각 요청에 부여하는 고유한 request-id가 WAF 로그와 HTTP 응답 헤더 양쪽에 포함되므로 고객 티켓 처리 속도를 크게 향상시킬 수 있었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 &lt;b&gt;카운트 모드 로그&lt;/b&gt;를 분석함으로써 특정 규칙을 실제 차단 모드로 전환하기 전에 운영 환경에서의 영향도를 사전에 파악할 수 있습니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2-3. 봇 탐지 자동화&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;OLX 봇 탐지 시스템의 핵심은 &lt;b&gt;EC2 인스턴스에서 동작하는 위협 분석 로직&lt;/b&gt;으로 세 가지 소스에서 위협 데이터를 주기적으로 수집합니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;위협 데이터 소스&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. AWS WAF Rate Limiting&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS WAF의 기본 레이트 기반 규칙은 5분 이내에 임계치(최소 100회) 이상의 요청을 보낸 IP를 임시 차단하지만 임계치 아래로 내려가면 차단이 해제됩니다. OLX는 AWS WAF API를 통해 이 차단 IP 목록을 주기적으로 수집하고 &lt;b&gt;더 긴 기간 동안 차단을 유지&lt;/b&gt;하여 적응형 봇의 재진입을 차단합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. Amazon Cognito Advanced Security&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Amazon Cognito의 Advanced Security는 로그인 요청의 다양한 속성(사용 디바이스, 접속 위치, IP 주소 등)을 분석하여 위험 점수를 부여합니다. OLX는 Cognito Events를 Lambda 함수로 소비하여 &lt;b&gt;고위험 이벤트&lt;/b&gt;를 Amazon OpenSearch 클러스터로 전송하고 봇 탐지 파이프라인에 통합합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. New Relic (클라이언트 사이드 행동 분석)&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;New Relic을 통해 수집된 클라이언트 사이드 모니터링 데이터를 분석하여 정상 사용자와 다른 &lt;b&gt;비정상적인 내비게이션 패턴&lt;/b&gt;을 가진 의심 IP를 식별합니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;위협 레벨별 자동 대응&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오탐을 줄이기 위해 OLX는 위협 수준에 따른 &lt;b&gt;3단계 대응 모드&lt;/b&gt;를 도입했습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1237&quot; data-origin-height=&quot;836&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Tqbnk/dJMcabjGncS/IgWWxS5zpBilhCDzzr5sUK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Tqbnk/dJMcabjGncS/IgWWxS5zpBilhCDzzr5sUK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Tqbnk/dJMcabjGncS/IgWWxS5zpBilhCDzzr5sUK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTqbnk%2FdJMcabjGncS%2FIgWWxS5zpBilhCDzzr5sUK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;597&quot; height=&quot;403&quot; data-origin-width=&quot;1237&quot; data-origin-height=&quot;836&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;봇 IP가 탐지되고 차단 결정이 내려지면 자동화 로직이 &lt;b&gt;중앙 Git 규칙 저장소에 커밋&lt;/b&gt;하고 CI/CD 파이프라인이 트리거되어 몇 분 내에 차단이 실제 WAF에 반영됩니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS 마이그레이션 1주일 후 OLX는 초당 약 70만 건에 달하는 대규모 DDoS 공격을 받았습니다. 구축된 봇 탐지 시스템을 통해 공격자 IP를 신속하게 탐지하고 차단하여 서비스를 방어했습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. 추가하면 좋을 보안 요소&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 아키텍처는 강력한 엣지 보안을 제공하지만 다음의 보안 요소를 추가하면 보호 수준을 더욱 높일 수 있습니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3-1. AWS Shield Advanced 통합&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 아키텍처는 AWS WAF 레이트 리미팅으로 DDoS 대응을 수행하지만 &lt;b&gt;AWS Shield Advanced&lt;/b&gt;를 통합하면 L3/L4 계층 DDoS에 대한 전문적인 방어와 AWS DDoS 대응 팀(DRT)의 24/7 지원을 받을 수 있습니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3-2. AWS WAF Bot Control 관리형 규칙 그룹 적용&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 봇 탐지는 자체 구축한 EC2 기반 로직에 의존합니다. &lt;b&gt;AWS WAF Bot Control&lt;/b&gt; 관리형 규칙 그룹을 추가하면 AWS가 지속적으로 업데이트하는 봇 시그니처 데이터베이스를 활용하여 Selenium, Headless Chrome 등 일반적인 자동화 도구를 별도의 커스텀 로직 없이 탐지하고 차단할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3-3. AWS WAF Fraud Control - Account Takeover Prevention (ATP) 보완 검토&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 계정 탈취 대응은 Amazon Cognito Advanced Security를 통해 이루어지고 있습니다. &lt;b&gt;AWS WAF ATP(Account Takeover Prevention)&lt;/b&gt; 관리형 규칙 그룹은 다크웹에서 수집된 유출 자격증명 데이터베이스를 실시간으로 검사하고 로그인 실패율을 IP 및 세션 단위로 집계하여 차단하는 기능을 제공합니다. 단 ATP는 현재 Amazon Cognito User Pool에는 직접 적용이 불가능하며 CloudFront 배포 앞단에서의 로그인 엔드포인트 보호에 적용 가능합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;참고자료&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://aws.amazon.com/ko/blogs/architecture/field-notes-how-olx-europe-fights-millions-of-bots-with-aws/&quot;&gt;Field Notes: How OLX Europe Fights Millions of Bots with AWS&lt;/a&gt; - AWS Architecture Blog&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>AWS</category>
      <category>AWS 보안 아키텍처 분석</category>
      <author>lhywk</author>
      <guid isPermaLink="true">https://lhywk.tistory.com/103</guid>
      <comments>https://lhywk.tistory.com/103#entry103comment</comments>
      <pubDate>Thu, 23 Apr 2026 15:55:18 +0900</pubDate>
    </item>
    <item>
      <title>Twilio TaskRouter JS SDK 사고 사례 분석</title>
      <link>https://lhywk.tistory.com/102</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 개요&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1326&quot; data-origin-height=&quot;847&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DMr9y/dJMcaf7krpI/okWfLkKvppOTECzCvKXQx1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DMr9y/dJMcaf7krpI/okWfLkKvppOTECzCvKXQx1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DMr9y/dJMcaf7krpI/okWfLkKvppOTECzCvKXQx1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDMr9y%2FdJMcaf7krpI%2FokWfLkKvppOTECzCvKXQx1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;383&quot; data-origin-width=&quot;1326&quot; data-origin-height=&quot;847&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1.1 사고 배경&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Twilio는 개발자들이 음성, 영상, 메시지, 인증 기능을 애플리케이션에 손쉽게 통합할 수 있도록 지원하는 클라우드 커뮤니케이션 플랫폼(CPaaS) 기업입니다. Twitter, Netflix, Uber, Airbnb, Spotify, Shopify 등 전 세계 40,000개 이상의 기업이 Twilio의 API를 사용하고 있으며 5백만 명 이상의 개발자가 플랫폼을 활용하고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2020년 7월 19일 Twilio의 &lt;b&gt;TaskRouter JS SDK&lt;/b&gt;가 공격자에 의해 악성 코드로 변조되는 사건이 발생했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;TaskRouter JS SDK&lt;/b&gt;란 Twilio가 제공하는 JavaScript 라이브러리로 한 마디로 &lt;b&gt;&quot;콜센터 자동 배분 시스템을 웹에서 쉽게 구현할 수 있게 해주는 도구&quot;&lt;/b&gt;입니다. 예를 들어 고객이 쇼핑몰에 문의 전화를 했을 때 단순 문의는 신입 상담원에게, 환불 문제는 숙련 상담원에게, VIP 고객은 전담팀으로 자동 연결하는 로직을 개발자가 손쉽게 구현할 수 있도록 지원합니다. 구체적으로는 고객 요청의 자동 배정, 상담원 상태 관리, 속성 기반 라우팅 규칙 설정, 실시간 대기열 모니터링 등의 기능을 제공합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 라이브러리는 웹 페이지에 &amp;lt;script&amp;gt; 태그로 직접 로드하는 방식으로 사용되기 때문에 S3 버킷에 저장된 파일이 변조되면 해당 라이브러리를 사용하는 모든 고객 웹 앱에 악성 코드가 그대로 실행되는 구조였습니다. 이것이 이번 사고가 공급망 공격으로 분류되는 핵심 이유입니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1.2 사고 타임라인&lt;/h4&gt;
&lt;div&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt; 시각 &lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;사건 &lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;2015년&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;해당 S3 버킷 경로 추가. 초기에는 퍼블릭 쓰기 권한 없음&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;2015년 (5개월 후)&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;빌드 시스템 문제 해결을 위해 퍼블릭 쓰기 권한 설정. 이후 초기화 누락&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;2020년 7월 19일 13:12&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;공격자가 TOR 네트워크를 통해 변조된 taskrouter.min.js 업로드&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;2020년 7월 19일 21:20&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Twilio 보안팀에 변조 알림 접수&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;2020년 7월 19일 22:30&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;악성 SDK 제거 및 정상 버전으로 교체, S3 버킷 잠금 조치&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;2020년 7월 20일 22:30&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;CDN 캐시 만료 완료 (최대 24시간)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;2020년 7월 22일&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Twilio, 공식 인시던트 리포트 공개&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1.3 영향 범위&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;직접 영향&lt;/b&gt;: TaskRouter JS SDK &lt;b&gt;v1.20&lt;/b&gt; 단일 버전&lt;/li&gt;
&lt;li&gt;&lt;b&gt;노출 시간&lt;/b&gt;: 약 8~10시간 (CDN 캐시 포함 시 최대 24시간)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;영향 제외&lt;/b&gt;: Twilio Flex 고객 (별도 SDK 사용, 공개 사이트에서 로드하지 않음)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;고객 데이터 접근&lt;/b&gt;: 증거 없음&lt;/li&gt;
&lt;li&gt;&lt;b&gt;내부 시스템 침해&lt;/b&gt;: 없음&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. 공격 분석&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2.1 초기 침투: AWS S3 버킷 Misconfigured Access Policy&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 사고의 근본 원인은 &lt;b&gt;AWS S3 버킷의 Misconfigured Access Policy&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Twilio는 twiliocdn.com 도메인을 통해 퍼블릭 콘텐츠를 제공하기 위한 S3 버킷을 운영하고 있었습니다. 이 버킷에는 Programmable Chat, Programmable Video, Twilio Client, Twilio TaskRouter 등의 클라이언트 측 JavaScript SDK가 저장되어 있었습니다. 해당 파일들은 CloudFlare CDN을 통해 사용자에게 제공되지만 S3 버킷에 직접 접근하는 것도 가능한 구조였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;잘못된 설정이 만들어진 것은&lt;/b&gt;&amp;nbsp;다음과 같습니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;2015년 TaskRouter SDK 경로가 S3 버킷에 추가될 당시에는 퍼블릭 쓰기 권한이 부여되지 않았습니다.&lt;/li&gt;
&lt;li&gt;5개월 후 빌드 시스템 트러블슈팅 과정에서 해당 경로의 퍼블릭 쓰기 권한이 활성화되었습니다.&lt;/li&gt;
&lt;li&gt;문제 해결 후 쓰기 권한을 원래 상태로 되돌리지 않아 약 &lt;b&gt;5년간&lt;/b&gt; 인터넷상 누구든지 해당 경로에 읽기/쓰기가 가능한 상태가 지속되었습니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1256&quot; data-origin-height=&quot;559&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mvmBl/dJMcag6f7Ql/KTLuY6bm6aKYWLLjo7Dnjk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mvmBl/dJMcag6f7Ql/KTLuY6bm6aKYWLLjo7Dnjk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mvmBl/dJMcag6f7Ql/KTLuY6bm6aKYWLLjo7Dnjk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmvmBl%2FdJMcag6f7Ql%2FKTLuY6bm6aKYWLLjo7Dnjk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;642&quot; height=&quot;286&quot; data-origin-width=&quot;1256&quot; data-origin-height=&quot;559&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Principal이 모든 사용자로 설정되어 있으며 s3:GetObject뿐 아니라 s3:PutObject까지 허용되어 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 설정 오류는 당시 Twilio 내부 보안 감사에서도 발견되지 않았으며 사고 이후 전체 S3 버킷 감사를 통해 유사한 잘못된 쓰기 권한 설정을 가진 버킷이 추가로 발견되기도 했습니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2.2 공격: Magecart 그룹의 자동화된 S3 스캐닝&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1440&quot; data-origin-height=&quot;1736&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/TXlzp/dJMcaiQuSGJ/4vxPDxBHrEPK4yxTk5puYk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/TXlzp/dJMcaiQuSGJ/4vxPDxBHrEPK4yxTk5puYk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/TXlzp/dJMcaiQuSGJ/4vxPDxBHrEPK4yxTk5puYk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTXlzp%2FdJMcaiQuSGJ%2F4vxPDxBHrEPK4yxTk5puYk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;610&quot; height=&quot;735&quot; data-origin-width=&quot;1440&quot; data-origin-height=&quot;1736&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 공격은 &lt;b&gt;Magecart&lt;/b&gt;로 알려진 공격 그룹의 전형적인 수법과 일치합니다. Magecart는 전자상거래 사이트에서 신용카드 정보 등 민감한 금융 데이터를 탈취하기 위해 웹 스키밍(Web Skimming) 기법을 사용하는 여러 해킹 그룹을 포괄하는 용어입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;웹 스키밍&lt;/b&gt;은 &lt;span style=&quot;background-color: #ffffff; color: #0a0a0a; text-align: start;&quot;&gt;전자상거래 사이트의 결제 페이지에 악성 스크립트를 주입해 사용자의 신용카드 정보와 개인정보를 실시간으로 탈취하는 사이버 범죄입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;공격 단계는 다음과 같습니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 자동화 스캐닝&lt;/b&gt;: 공격자는 인터넷상에 노출된 잘못 설정된 S3 버킷을 자동으로 스캔합니다. AWS S3 버킷은 기본적으로 보안이 설정되어 있지만 관리자가 퍼블릭 쓰기 권한을 허용하면 누구나 파일을 덮어쓸 수 있게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. JavaScript 파일 탐색&lt;/b&gt;: 잘못 설정된 버킷을 발견하면 공격자는 해당 버킷 내의 모든 .js 파일을 탐색합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. 악성 코드 삽입&lt;/b&gt;: JavaScript 파일을 다운로드한 후 파일 끝에 악성 코드를 추가하고 버킷에 재업로드합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 사고에서 주입된 코드는 다음과 같이 동작했습니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;bash&quot; style=&quot;color: #14181f;&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;악성 코드 &amp;rarr; hxxps://gold.platinumus[.]top/track/awswrite?q=dmn 로 HTTP GET 요청
         &amp;rarr; 반환된 URL로 리다이렉트
         &amp;rarr; 브라우저 뒤로 가기 버튼 차단
         &amp;rarr; 모바일 기기 관련 데이터 수집 시도&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공격자는 TOR 익명화 네트워크를 통해 접속하여 추적을 어렵게 했습니다. RiskIQ의 연구에 따르면 jqueryapi1oad라고도 불리는 이 악성 리다이렉터는 Hookads 멀버타이징 캠페인과 연관되어 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;멀버타이징이란 Malicious(악성)와 Advertising(광고)의 합성어로 사용자 몰래 광고를 강제로 띄우거나 광고 수익을 가로채는 행위를 말합니다. Hookads 캠페인은 2019년 4월부터 활동해 온 광고 사기 네트워크입니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2.3 공급망 공격으로서의 의미&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 사고는 단순한 단일 기업 해킹을 넘어 &lt;b&gt;소프트웨어 공급망 공격&lt;/b&gt;의 특성을 지닙니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현대 웹 애플리케이션은 서드파티 스크립트와 오픈소스 라이브러리를 광범위하게 활용합니다. Twilio처럼 수만 개의 기업이 사용하는 SDK가 침해될 경우 공격자는 단 하나의 공급자를 공략함으로써 그 공급자에 의존하는 수많은 하위 기업과 사용자에게 간접적으로 피해를 입힐 수 있습니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2.4 탐지 지연과 CDN 캐싱 문제&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 사고에서 중요한 것 중 하나는&amp;nbsp;&lt;b&gt;탐지 지연&lt;/b&gt;입니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;악성 파일이 업로드된 시각: 13:12&lt;/li&gt;
&lt;li&gt;Twilio가 알림을 받은 시각: 21:20&lt;/li&gt;
&lt;li&gt;정상 파일로 교체 완료: 22:30&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;약 &lt;b&gt;8시간&lt;/b&gt; 동안 악성 SDK가 서비스되었으며 CDN에 캐시된 버전은 최대 &lt;b&gt;24시간&lt;/b&gt; 더 사용자에게 노출될 수 있었습니다. 이는 클라우드 스토리지 변경에 대한 실시간 모니터링 부재가 얼마나 큰 위험을 가져오는지를 보여줍니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. 대응 방안&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3.1 즉각적 사고 대응&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Twilio는 사고 발생 후 다음과 같이 대응했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;단기 대응 조치&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;변조된 SDK 리포트 접수 후 &lt;b&gt;15분 이내&lt;/b&gt;에 보안팀 소집&lt;/li&gt;
&lt;li&gt;알림 접수 약 &lt;b&gt;1시간 후&lt;/b&gt; 정상 버전 SDK로 교체 및 S3 버킷 퍼블릭 접근 잠금&lt;/li&gt;
&lt;li&gt;전체 AWS S3 버킷 감사 실시: 잘못된 쓰기 설정을 가진 추가 버킷 발견 및 조치&lt;/li&gt;
&lt;li&gt;동일한 방식으로 침해될 수 있는 다른 SDK 확인 (추가 피해 없음 확인)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;고객 대응&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;2020년 7월 19일 13:12 ~ 7월 20일 22:30 사이에 TaskRouter JS SDK v1.20을 다운로드한 고객에게 즉시 재다운로드 권고&lt;/li&gt;
&lt;li&gt;CDN에서 동적으로 로드하는 애플리케이션은 자동으로 정상 버전으로 교체됨&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;무결성 검증 방법 제공&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Twilio는 고객이 보유한 SDK의 무결성을 검증할 수 있도록 명령어를 안내했습니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;bash&quot; style=&quot;color: #14181f;&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;# taskrouter.min.js 무결성 검증
shasum -a 256 taskrouter.min.js&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3.2 개선 방안&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;AWS S3 버킷 보안 강화&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;S3 퍼블릭 액세스 차단 활성화&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS는 계정 및 버킷 수준에서 퍼블릭 액세스를 차단하는 기능을 제공합니다. 퍼블릭 콘텐츠를 서비스하더라도 S3 버킷에 직접 퍼블릭 쓰기 접근을 허용할 필요는 없습니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;bash&quot; style=&quot;color: #14181f;&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;{
  &quot;BlockPublicAcls&quot;: true,      // 새로운 퍼블릭 ACL 추가 차단
  &quot;IgnorePublicAcls&quot;: true,     // 기존에 열려있던 퍼블릭 ACL 무력화
  &quot;BlockPublicPolicy&quot;: true,    // 퍼블릭 버킷 정책 추가 차단
  &quot;RestrictPublicBuckets&quot;: true // 기존 퍼블릭 버킷 정책 무력화
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4개를 모두 true로 설정하는 것이 AWS 보안 권고사항이며 Twilio 사고처럼 실수로 열린 권한이 장기간 방치되는 상황을 원천 차단할 수 있습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;최소 권한 원칙 적용&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;버킷 정책과 IAM 정책을 통해 쓰기 권한은 필요한 특정 사용자, 역할, 또는 서비스에만 부여해야 합니다. Twilio는 사고 이후 S3 버킷에 대한 직접 접근을 제한하고 알려진 CDN을 통해서만 콘텐츠를 제공하는 방식으로 전환하기로 했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;버킷 정책 변경 모니터링&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS CloudTrail을 통해 S3 버킷 정책 변경, 퍼블릭 접근 설정 변경 등의 이벤트를 실시간으로 모니터링하고, 비정상적인 권한 변경 시 즉시 알람을 발생시켜야 합니다. AWS Config 규칙을 활용하면 s3-bucket-public-write-prohibited 등의 컴플라이언스 규칙을 자동으로 감사할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CloudTrail 로그에는 sourceIPAddress(요청 IP), userIdentity(IAM 계정 정보), userAgent(사용 클라이언트) 필드가 포함되어 있어 &lt;b&gt;내부 수정과 외부 침입을 구분&lt;/b&gt;할 수 있습니다. 내부 수정이라면 회사 IP와 IAM 계정 정보가 기록되지만 이번 Twilio 사고처럼 외부 공격이라면 TOR 출구 노드 IP와 익명 클라이언트 정보가 찍히게 됩니다. 따라서 알 수 없는 IP나 IAM 외부의 접근으로 파일이 수정되는 이벤트에 대해 즉각 알람을 설정하는 것이 중요합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;버킷 버저닝 활성화&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;S3 버킷에 버저닝을 활성화하면 파일이 악의적으로 덮어쓰여지더라도 이전 버전으로 빠르게 롤백할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;S3 오브젝트 잠금(Object Lock) 활성화&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;탐지보다 한 단계 앞선 예방 조치로 S3 오브젝트 잠금 기능을 활성화하면 파일 자체를 덮어쓰거나 삭제하지 못하도록 원천 차단할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;배포 파이프라인 통제&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;S3에 직접 파일을 업로드하는 것을 막고 CI/CD 파이프라인을 통해서만 파일이 배포되도록 강제하는 것도 예방책입니다. 파이프라인 외부에서 이루어지는 모든 직접 업로드를 차단하면 공격자가 퍼블릭 쓰기 권한을 획득하더라도 실제 파일 변조로 이어지기 어렵습니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;파일 변경 탐지 및 모니터링&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;실시간 파일 무결성 모니터링&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서비스 중인 JavaScript 파일에 대한 정기적인 해시 비교 및 변경 탐지 시스템이 필요합니다. 이번 사고에서 Twilio는 파일 변조 후 약 8시간이 지나서야 알림을 받았으며 이는 모니터링 체계의 부재를 의미합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;CDN 로그 분석&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CDN 접근 로그를 분석하여 비정상적인 파일 업로드나 갑작스러운 트래픽 패턴 변화를 탐지해야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;보안 설정 감사 프로세스&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;잘못된 설정이 5년 동안 발견되지 않았다는 점은 정기적인 클라우드 보안 감사의 필요성을 강조합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;정기 S3 버킷 권한 감사&lt;/b&gt;: 모든 S3 버킷의 퍼블릭 접근 설정, ACL, 버킷 정책을 주기적으로 검토합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;임시 권한 변경 이력 관리&lt;/b&gt;: 트러블슈팅 등 운영 목적으로 임시 권한을 부여한 경우 작업 완료 후 반드시 원복하는 프로세스와 티켓 시스템을 운영합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;AWS Security Hub, Prowler 등 자동화 도구 활용&lt;/b&gt;: 클라우드 환경의 보안 설정 오류를 자동으로 탐지하는 도구를 도입합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;참고 자료&lt;/b&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Twilio, &quot;Incident Report: TaskRouter JS SDK Security Incident - July 19, 2020,&quot; Twilio Blog, July 22, 2020. &lt;a href=&quot;https://www.twilio.com/en-us/blog/company/communications/incident-report-taskrouter-js-sdk-july-2020&quot;&gt;https://www.twilio.com/en-us/blog/company/communications/incident-report-taskrouter-js-sdk-july-2020&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Ionut Ilascu, &quot;Twilio exposes SDK, attackers inject it with malvertising code,&quot; BleepingComputer, July 22, 2020. &lt;a href=&quot;https://www.bleepingcomputer.com/news/security/twilio-exposes-sdk-attackers-inject-it-with-malvertising-code/&quot;&gt;https://www.bleepingcomputer.com/news/security/twilio-exposes-sdk-attackers-inject-it-with-malvertising-code/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Kelly Sheridan, &quot;Twilio Security Incident Shows Danger of Misconfigured S3 Buckets,&quot; Dark Reading, July 23, 2020. &lt;a href=&quot;https://www.darkreading.com/cloud-security/twilio-security-incident-shows-danger-of-misconfigured-s3-buckets&quot;&gt;https://www.darkreading.com/cloud-security/twilio-security-incident-shows-danger-of-misconfigured-s3-buckets&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Imperva, &quot;What Is Magecart | Attack Examples &amp;amp; Prevention Techniques.&quot; &lt;a href=&quot;https://www.imperva.com/learn/application-security/magecart/&quot;&gt;https://www.imperva.com/learn/application-security/magecart/&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;</description>
      <category>AWS</category>
      <category>AWS 침해사고 사례 분석</category>
      <author>lhywk</author>
      <guid isPermaLink="true">https://lhywk.tistory.com/102</guid>
      <comments>https://lhywk.tistory.com/102#entry102comment</comments>
      <pubDate>Fri, 17 Apr 2026 14:55:30 +0900</pubDate>
    </item>
  </channel>
</rss>