13년차의 서버실

서버, 인프라, 홈랩 기술 블로그

[태그:] OIDC

  • [Cloud] OIDC와 SSO를 활용한 사내 인증 시스템 통합 전략 분석

    [Cloud] OIDC와 SSO를 활용한 사내 인증 시스템 통합 전략 분석

    안녕하세요, 13년차의 서버실 주인장입니다. 오늘은 인프라 엔지니어라면 한 번쯤은 고민하고, 또 삽질하게 되는 주제, 바로 OIDC(OpenID Connect)와 SSO(Single Sign-On)를 활용한 사내 인증 시스템 통합 전략에 대해 이야기해보려고 합니다. 사내에 시스템이 한두 개가 아닐 텐데, 매번 다른 아이디와 비밀번호로 로그인하는 게 여간 귀찮은 일이 아니죠. 저도 처음엔 ‘그냥 다 개별적으로 관리하면 되지 뭐’라고 안일하게 생각했었는데, 시스템이 늘어날수록 사용자들의 불만이 폭주하더라고요. ‘로그인만 수십 번 하는 것 같다’는 피드백을 들었을 때는 정말 등골이 오싹했었습니다. 😱

    이런 불편함을 해소하고 보안 강화는 물론, 사용자 경험 개선까지 동시에 잡을 수 있는 방법이 바로 SSO, 그리고 그 핵심에 있는 OIDC입니다. 저도 저희 회사 시스템들을 OIDC 기반으로 통합하면서 정말 많은 삽질을 했거든요. 오늘은 그 경험을 바탕으로 OIDC와 SSO가 무엇인지, 어떻게 통합해야 하는지, 그리고 어떤 문제들을 만날 수 있는지 솔직하게 풀어보겠습니다.

    OIDC SSO 사내 인증 시스템 통합 아키텍처 다이어그램

    OIDC와 SSO를 활용한 사내 인증 시스템 통합의 전체 아키텍처 다이어그램입니다. 사용자가 SSO 포털을 통해 OIDC Provider에 인증하고, 여러 서비스에 접근하는 흐름을 한눈에 볼 수 있습니다.

    SSO와 OIDC, 이 둘은 대체 뭘까요?

    먼저 핵심 개념들을 쉽고 명확하게 정리해 볼게요. 저도 처음엔 OAuth랑 OIDC가 뭐가 다른지 헷갈려서 엄청 찾아봤거든요. 간단히 정리해볼게요.

    SSO (Single Sign-On): 한 번의 로그인으로 만사형통!

    SSO(Single Sign-On, 싱글 사인온)는 말 그대로 한 번의 인증(로그인)으로 여러 개의 서로 다른 애플리케이션이나 서비스에 접근할 수 있도록 해주는 인증 방식입니다. 예를 들어, 회사 포털에 한 번 로그인하면 그룹웨어, 메신저, 인사 시스템 등 모든 사내 시스템에 추가 로그인 없이 바로 접근할 수 있는 거죠. 사용자 입장에서는 정말 편리하고, 관리자 입장에서는 사용자 계정 관리가 훨씬 수월해집니다. 💡

    OAuth 2.0 (Open Authorization): 권한 위임의 대명사

    OAuth 2.0(Open Authorization)은 인증(Authentication) 프로토콜이 아닙니다. 정확히는 권한 위임(Authorization Delegation)을 위한 프레임워크라고 보시면 됩니다. ‘나’라는 사용자가 ‘서비스 A’에게 ‘서비스 B’에 있는 내 정보에 접근할 수 있는 권한을 위임할 때 사용됩니다. “카카오톡으로 로그인”이나 “구글로 로그인” 버튼을 눌렀을 때, 서비스 제공자가 내 개인 정보에 접근할 권한을 얻는 과정이 바로 OAuth 2.0을 통해 이루어집니다. 중요한 건, OAuth 2.0은 ‘누가 로그인했는지(인증)’보다는 ‘무엇에 접근할 수 있는지(권한)’에 초점을 맞춘다는 거죠.

    OIDC (OpenID Connect): OAuth 2.0 위에서 동작하는 인증 프로토콜

    드디어 오늘의 주인공, OIDC(OpenID Connect)입니다. OIDC는 OAuth 2.0 프레임워크 위에서 동작하는 인증(Authentication) 계층입니다. OAuth 2.0이 권한 위임에 집중했다면, OIDC는 ‘로그인한 사용자가 누구인지’를 확인하는 데 집중합니다. 사용자 정보를 담은 ID Token(아이디 토큰)을 발행하여, 클라이언트 애플리케이션이 사용자를 식별하고 인증할 수 있도록 해줍니다. 즉, OAuth 2.0은 “문 열어줄 권한”을 주고, OIDC는 “문 열고 들어온 사람이 누구인지 신분증 확인”까지 해준다고 생각하시면 쉽습니다.

    OAuth 2.0 vs OIDC 비교

    특징 OAuth 2.0 OIDC (OpenID Connect)
    목적 권한 위임 (Authorization) 사용자 인증 (Authentication)
    기반 기술 인증/인가를 위한 프레임워크 OAuth 2.0 위에 구축된 프로토콜
    주요 토큰 Access Token (접근 토큰) ID Token (아이디 토큰), Access Token
    제공 정보 자원 접근 권한 사용자 신원 정보 (이름, 이메일 등)
    활용 예시 타사 앱에서 내 Google Drive 접근 Google, Kakao로 웹사이트 로그인

    OIDC는 OAuth 2.0의 유연한 구조를 활용하면서도, 표준화된 방식으로 사용자 인증 정보를 제공한다는 점에서 큰 장점이 있습니다.

    OIDC 기반 SSO, 실전 구현 삽질기

    자, 이제 개념은 잡혔으니 실제로 어떻게 사내 시스템에 OIDC SSO 통합을 적용했는지 이야기해 볼까요? 저는 주로 Keycloak 같은 오픈소스 OIDC Provider를 활용하는 편입니다. 홈랩에서도 자주 써봤거든요. 여기서는 OIDC Provider(Keycloak 등)가 이미 구축되어 있고, 우리가 만든 서비스(Client Application)에 연동하는 과정을 중심으로 설명하겠습니다.

    1단계: OIDC Provider에 클라이언트 등록

    가장 먼저 할 일은 OIDC Provider에 우리 서비스(Client Application)를 클라이언트(Client)로 등록하는 겁니다. 이때 몇 가지 중요한 정보를 입력해야 해요.

    • Client ID (클라이언트 ID): 우리 서비스를 식별하는 고유한 ID입니다.
    • Client Secret (클라이언트 시크릿): 클라이언트의 비밀 키로, 보안상 매우 중요합니다. 절대 외부에 노출되면 안 돼요!
    • Redirect URI (리다이렉트 URI): 인증이 성공했을 때 OIDC Provider가 사용자 에이전트(브라우저)를 다시 보낼 URL입니다. 이 URL은 정확해야 합니다. 제가 초반에 제일 삽질 많이 했던 부분이 이 리다이렉트 URI 오타나 불일치였어요. ⚠️
    • Scope (스코프): 클라이언트가 사용자 정보 중 어떤 항목에 접근할 권한을 요청할지 정의합니다. 최소한 openid 스코프는 필수입니다. 보통 profile, email 등도 함께 요청하죠.
    OIDC Provider 클라이언트 등록 설정 화면

    OIDC Provider(예: Keycloak)에 새로운 클라이언트를 등록하는 설정 화면입니다. Client ID, Client Secret, Redirect URI, Scope 등을 정확히 입력해야 합니다. 특히 Redirect URI는 오타 없이 정확하게 입력하는 것이 중요합니다.

    2단계: 서비스 애플리케이션에 OIDC 클라이언트 연동

    이제 우리 서비스 애플리케이션에서 OIDC Provider와 통신할 차례입니다. 저는 웹 서비스 앞단에 Nginx를 두고 OIDC 모듈을 연동하거나, 직접 애플리케이션 코드에 OIDC 클라이언트 라이브러리를 사용하는 방식을 선호합니다. 여기서는 Nginx를 이용한 간단한 연동 예시와 함께, OIDC 플로우의 핵심을 보여드릴게요.

    Nginx OIDC 모듈을 사용한 연동 예시

    Nginx를 리버스 프록시(Reverse Proxy)로 사용하고, nginx-auth-oidc 같은 모듈을 활용하면 애플리케이션 코드 수정 없이도 OIDC 인증을 붙일 수 있습니다. 정말 편리하더라고요.

    
    # nginx.conf 예시 (http 블록 내 server 블록)
    
    server {
        listen 80;
        server_name your.service.com;
    
        # OIDC 설정 블록
        location / {
            # OIDC Provider의 Well-Known Configuration 엔드포인트
            # 예: https://idp.example.com/auth/realms/your-realm/.well-known/openid-configuration
            auth_request /_oauth2_proxy_auth; # 이 경로는 실제 인증 프록시 엔드포인트와 맞춰야 합니다.
            error_page 401 = /_oauth2_proxy_auth; # 401 에러 발생 시 인증 프록시로 리다이렉트
    
            # 인증이 성공하면 애플리케이션으로 트래픽 전달
            proxy_pass http://your_backend_service;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
        }
    
        # OIDC 인증 프록시 설정 (이 부분은 실제 OIDC 모듈 설정에 따라 달라질 수 있습니다)
        location = /_oauth2_proxy_auth {
            internal; # 외부에서 직접 접근 불가
            proxy_pass http://localhost:PORT/auth; # 실제 OIDC 인증 프록시 서버 주소
            proxy_pass_request_body off;
            proxy_set_header Content-Length "";
            proxy_set_header X-Original-URI $request_uri;
            # 여기에 OIDC Client ID, Secret, Redirect URI 등의 환경 변수나 설정 파일 경로 지정
            # 예: proxy_set_header X-OIDC-Client-ID "your_client_id";
            # proxy_set_header X-OIDC-Client-Secret "your_client_secret";
            # proxy_set_header X-OIDC-Redirect-URI "https://your.service.com/oauth2/callback";
        }
    
        # OIDC 콜백 엔드포인트
        location = /oauth2/callback {
            proxy_pass http://localhost:PORT/callback; # OIDC 인증 프록시 콜백 엔드포인트
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
        }
    }
    

    위 Nginx 설정은 개념적인 예시이며, 실제 nginx-auth-oidc 모듈이나 oauth2_proxy 같은 솔루션을 사용할 경우 설정 방식이 조금 다를 수 있습니다. 핵심은 사용자가 보호된 리소스에 접근하려 할 때, Nginx가 이를 가로채 OIDC Provider로 인증을 위임하고, 인증이 완료되면 원래 요청을 백엔드 서비스로 전달하는 흐름입니다.

    OIDC 플로우 간략 설명 (Authorization Code Flow 기준)

    1. 사용자가 보호된 리소스(예: your.service.com/dashboard)에 접근합니다.
    2. 서비스 애플리케이션(또는 Nginx 프록시)은 사용자가 인증되지 않았음을 감지하고, OIDC Provider의 Authorization Endpoint(인가 엔드포인트)로 사용자를 리다이렉트합니다. 이때 Client ID, Redirect URI, Scope 등을 쿼리 파라미터로 넘깁니다.
    3. 사용자는 OIDC Provider 로그인 페이지에서 아이디/비밀번호를 입력하여 인증합니다.
    4. 인증 성공 시, OIDC Provider는 미리 등록된 Redirect URI로 Authorization Code(인가 코드)를 포함하여 사용자를 다시 우리 서비스로 리다이렉트합니다.
    5. 우리 서비스는 받은 Authorization Code를 이용해 OIDC Provider의 Token Endpoint(토큰 엔드포인트)로 Access Token과 ID Token을 요청합니다. 이때 Client Secret도 함께 전송하여 클라이언트의 신원을 증명합니다.
    6. OIDC Provider는 Access Token과 ID Token을 발급해줍니다.
    7. 우리 서비스는 ID Token을 검증하여 사용자 신원을 확인하고, Access Token을 사용하여 필요한 경우 사용자 정보(Userinfo Endpoint)를 추가로 조회하거나, 다른 리소스에 접근할 수 있습니다.
    8. 사용자는 이제 서비스에 로그인된 상태가 됩니다. 🎉

    주의사항과 트러블슈팅: 삽질은 나의 힘!

    이런 시스템 통합 작업은 늘 예상치 못한 문제의 연속이더라고요. 제가 겪었던 대표적인 삽질 경험과 해결책을 공유합니다.

    • ⚠️ Redirect URI 불일치: OIDC Provider에 등록된 Redirect URI와 실제 요청하는 URI가 단 한 글자라도 다르면 인증 플로우가 진행되지 않습니다. 심지어 http와 https, 마지막 슬래시 / 유무까지 정확히 일치해야 합니다.

      해결책: OIDC Provider 설정 화면과 애플리케이션 코드/설정 파일을 꼼꼼히 대조하고, 브라우저 개발자 도구(F12)의 네트워크 탭에서 실제 리다이렉트되는 URL을 확인하며 디버깅하세요.

      
              # curl 명령어로 .well-known/openid-configuration 확인하여 정확한 endpoint 정보 파악
              curl -s https://idp.example.com/auth/realms/your-realm/.well-known/openid-configuration | jq .
              

      이 명령어를 통해 OIDC Provider가 제공하는 정확한 엔드포인트와 정보들을 확인할 수 있습니다. 특히 authorization_endpoint, token_endpoint, jwks_uri 등을 잘 봐야 합니다.

    • ⚠️ Scope/Claim 누락: 필요한 사용자 정보(예: 이메일, 이름)가 ID Token이나 Userinfo Endpoint에서 넘어오지 않을 때가 있습니다. 이는 보통 클라이언트 등록 시 요청하는 Scope(스코프)가 부족하거나, OIDC Provider에서 해당 Claim(클레임)을 발행하도록 설정되지 않았기 때문입니다.

      해결책: 클라이언트 등록 시 openid profile email 등 필요한 스코프를 모두 요청했는지 확인하고, OIDC Provider의 사용자 속성(User Attributes) 또는 클레임 매핑 설정을 확인하세요.

    • ⚠️ Token 검증 실패: ID Token의 Signature(서명) 검증에 실패하거나, 유효 기간(exp 클레임)이 만료된 토큰을 사용하는 경우가 있습니다. 이는 주로 OIDC Provider의 JWKS(JSON Web Key Set) 엔드포인트 설정 오류, 서버 시간 동기화 문제, 또는 토큰 캐싱 문제에서 발생합니다.

      해결책: OIDC Provider의 JWKS URI가 정확한지 확인하고, 애플리케이션 서버의 시간이 NTP 등으로 정확하게 동기화되어 있는지 확인하세요. 토큰을 캐싱한다면 만료 시간을 고려해야 합니다.

    • ⚠️ Client Secret 노출 위험: Client Secret은 정말 중요합니다. 절대 하드코딩하거나 Git 저장소에 올리면 안 돼요.

      해결책: 환경 변수(Environment Variable), HashiCorp Vault 같은 Secrets Management 솔루션, 또는 Kubernetes Secret 등을 활용하여 안전하게 관리해야 합니다.

      
              # 환경 변수로 Client Secret 설정 예시 (애플리케이션 실행 시)
              export OIDC_CLIENT_SECRET="your_very_secret_key"
              python your_app.py
              

      이런 방식으로 서버 시작 시에만 접근하도록 하는 것이 안전합니다.

    검증 및 결과 확인: 드디어 로그인 성공!

    위의 삽질들을 거쳐서 드디어 OIDC 기반 SSO가 정상적으로 동작하는 것을 확인했습니다. 보통 다음과 같은 방법으로 검증합니다.

    1. 서비스 접근 및 로그인 시도: 웹 브라우저로 서비스 URL에 접속했을 때, OIDC Provider의 로그인 페이지로 정확히 리다이렉트되는지 확인합니다.
    2. 로그인 후 서비스 접근: 로그인 성공 후, 서비스의 메인 페이지나 보호된 리소스에 정상적으로 접근되는지 확인합니다.
    3. ID Token 및 Access Token 내용 확인: 개발자 도구 또는 애플리케이션 로그를 통해 발급된 ID Token(JWT 형식)을 jwt.io 같은 사이트에서 디코딩하여, 사용자 정보(sub, name, email 등)가 올바르게 포함되어 있는지 확인합니다. Access Token은 불투명할 수 있지만, OIDC Provider의 Userinfo Endpoint를 통해 사용자 정보를 가져올 때 사용됩니다.
    4. 세션 관리 확인: 한 번 로그인하면 다른 사내 시스템(OIDC Client로 등록된)에 추가 로그인 없이 접근되는지 확인합니다.
    OIDC SSO 로그인 성공 및 JWT 토큰 디코딩 결과 화면

    OIDC 기반 SSO 로그인 성공 후, 사용자 정보가 표시되는 웹 애플리케이션 대시보드와 JWT 토큰 디코딩 결과 화면입니다. 토큰에 담긴 사용자 정보가 정확한지 확인하는 과정이 중요합니다.

    마무리: OIDC SSO, 선택이 아닌 필수

    OIDC와 SSO를 사내 시스템에 통합하는 과정은 결코 쉽지 않습니다. 저도 수많은 시행착오와 삽질을 거쳤고, 밤샘 디버깅도 여러 번 했거든요. 하지만 고생 끝에 낙이 온다고, 제대로 구축된 OIDC 기반 SSO는 사용자 경험 개선, 보안 강화, 그리고 중앙 집중식 계정 관리라는 세 마리 토끼를 동시에 잡을 수 있게 해줍니다.

    OIDC 기반 SSO 통합의 주요 장점

    장점 설명
    사용자 경험 개선 한 번 로그인으로 여러 시스템 접근, 로그인 피로도 감소
    보안 강화 중앙 집중식 인증으로 보안 정책 일관성 유지, 2FA(다단계 인증) 적용 용이
    관리 효율성 증대 계정 생성/삭제/관리의 단일화, 감사(Audit) 용이
    표준화된 프로토콜 다양한 서비스 및 솔루션과의 호환성 보장

    이러한 장점들은 OIDC 기반 SSO가 단순한 편의 기능을 넘어, 현대 IT 인프라에서 필수적인 요소가 되었음을 보여줍니다.

    OIDC SSO 통합 주요 장점 인포그래픽

    OIDC 기반 SSO의 주요 장점을 요약한 인포그래픽입니다. 사용자 경험 개선부터 보안 강화, 관리 효율성 증대까지 다양한 이점을 명확하게 보여줍니다.

    만약 여러분의 사내 시스템이 아직도 각자도생의 길을 걷고 있다면, 지금 바로 OIDC 기반 SSO 통합을 진지하게 고민해 보시길 강력히 권해드립니다. 처음엔 어렵겠지만, 장기적으로는 훨씬 더 견고하고 효율적인 인프라를 만들 수 있을 거예요. 다음번에는 OIDC와 연동하여 RBAC(Role-Based Access Control, 역할 기반 접근 제어)를 어떻게 구현하는지에 대한 경험담을 풀어볼까 합니다. 궁금하신 점이 있다면 언제든 댓글 남겨주세요! 😉

  • [Infra] SSO 로그인 장애 발생 시 디버깅 체크리스트와 해결 전략

    [Infra] SSO 로그인 장애 발생 시 디버깅 체크리스트와 해결 전략

    [Infra] SSO 로그인 장애 발생 시 디버깅 체크리스트와 해결 전략

    운영 중인 서비스에서 갑자기 로그인이 안 되기 시작하면, 특히 SSO 로그인 장애 해결 이슈는 생각보다 훨씬 까다롭게 번진다. 사용자 입장에서는 그냥 “로그인이 안 된다”로 끝나지만, 운영자 입장에서는 IdP(Identity Provider, 인증 제공자), SP(Service Provider, 서비스 제공자), 브라우저 쿠키, 리버스 프록시(reverse proxy, 역방향 프록시), 시간 동기화까지 전부 의심해야 하거든요. 저도 처음엔 이게 뭔가 싶었는데, 실제로 장애 대응을 몇 번 해보니까 결국 핵심은 감으로 때려 맞추는 게 아니라 체크리스트 기반으로 좁혀가는 것이더라고요. 이번 글에서는 제가 현장에서 자주 쓰는 SSO 디버깅 순서와 IDP 문제 해결 전략을 정리해보겠다.

    사용자, 브라우저, 서비스 제공자, 인증 제공자 사이에서 어디서 실패하는지 한눈에 파악하는 구조도입니다.

    1. 왜 SSO 로그인 장애는 빨리 커질까요?

    SSO(Single Sign-On, 통합 로그인)는 쉽게 말해 한 번 인증하면 여러 서비스에 연동되는 구조입니다. 평소에는 정말 편합니다. 그런데 장애가 나면 영향 범위도 같이 커집니다. 한 서비스만 막히는 게 아니라, 회사 포털, 내부 위키, VPN, 협업 도구까지 줄줄이 막힐 수 있거든요.

    실제로 써보니까 SSO 장애는 보통 아래 네 가지 패턴으로 나뉘더라고요.

    • 리다이렉트(redirect, 재전송) 루프: 로그인 페이지로 계속 돌아감
    • 인증 오류: 잘못된 Assertion, invalid token, audience mismatch 같은 오류
    • 세션 문제: 로그인 직후 다시 로그아웃되거나 세션이 안 붙음
    • 환경 문제: DNS, TLS 인증서, 프록시 헤더, 서버 시간 차이

    여기서 중요한 포인트! SSO는 애플리케이션만 봐서는 잘 안 풀립니다. 브라우저 – 네트워크 – 애플리케이션 – IdP를 한 묶음으로 봐야 합니다.

    2. SSO 로그인 흐름 이해하기: 구조를 먼저 머릿속에 그려보세요

    저도 처음엔 로그만 뒤졌었는데, 사실 그 전에 흐름부터 정리해야 하더라고요. 쉽게 말해 사용자가 보호된 페이지에 접근하면 SP가 “너 인증 필요해”라고 판단하고 IdP로 보냅니다. 사용자가 IdP에서 로그인하면, IdP는 SAML Assertion(사설명서 같은 인증 응답)이나 OIDC Token(JSON 기반 토큰)을 SP로 돌려보냅니다. 그다음 SP가 검증하고 세션을 발급하면 끝입니다.

    항목 SAML OIDC
    주요 데이터 XML Assertion ID Token, Access Token
    전송 방식 브라우저 리다이렉트, POST Authorization Code Flow 등
    운영 중 자주 보는 문제 서명, ACS URL, NameID 불일치 redirect_uri, issuer, nonce, scope 오류
    확인 포인트 메타데이터, 인증서, 시간 클라이언트 설정, 토큰 클레임

    이 흐름을 기준으로 보면 SSO 로그인 장애 지점이 꽤 명확해집니다. 브라우저가 못 가는지, IdP가 거절하는지, SP가 응답을 못 읽는지 구분이 되거든요.

    3. SSO 로그인 장애 해결 체크리스트: 제가 가장 먼저 보는 순서

    이 부분은 진짜 실전입니다. 삽질 좀 했습니다 ㅎㅎ 그래서 지금은 무조건 아래 순서로 봅니다.

    1. 사용자 증상 수집: 전원 장애인지, 특정 사용자만 그런지, 특정 브라우저만 그런지 확인합니다.
    2. 최근 변경사항 확인: 인증서 교체, 프록시 설정 변경, 도메인 변경, 쿠키 정책 수정이 있었는지 봅니다.
    3. 브라우저 개발자 도구 확인: Network 탭에서 302, 400, 401, 403 흐름을 추적합니다.
    4. 애플리케이션 로그 확인: assertion invalid, token verification failed, audience mismatch 같은 문자열을 찾습니다.
    5. IdP 로그 확인: 정책 차단인지, 앱 설정 mismatch인지 확인합니다.
    6. 시간 동기화 점검: NTP(Network Time Protocol, 시간 동기화) 오차가 몇 분만 나도 실패합니다.
    7. 프록시/로드밸런서 헤더 확인: X-Forwarded-Proto, Host 헤더가 꼬이면 redirect_uri가 달라집니다.

    운영 서버에서 빠르게 볼 때는 이런 식으로 확인합니다.

    # 애플리케이션 로그에서 인증 관련 에러만 추리기
    journalctl -u myapp -n 300 | egrep -i "saml|oidc|oauth|token|assertion|redirect|issuer|audience|nonce|session"
    
    # NTP 동기화 상태 확인
    chronyc tracking
    chronyc sources -v
    
    # 리다이렉트와 응답 헤더 확인
    curl -k -I https://service.example.com/login
    curl -k -L -v https://service.example.com/login
    
    # 인증서 만료일 확인
    openssl s_client -connect service.example.com:443 -servername service.example.com </dev/null | openssl x509 -noout -dates -issuer -subject

    직접 해보니 여기서 절반은 걸러집니다. 특히 최근 변경사항과 시간 동기화는 생각보다 자주 원인이 됩니다.

    4. 실전 구현: 로그와 설정으로 원인 좁히기

    4-1. OIDC 설정 점검 포인트

    OIDC(OpenID Connect, OpenID 기반 인증 확장)를 쓰는 서비스라면 클라이언트 설정이 맞는지부터 보셔야 합니다. redirect_uri 하나만 달라도 바로 로그인 실패가 납니다.

    auth:
      oidc:
        issuer: "https://idp.example.com/realms/main"
        client_id: "internal-portal"
        client_secret: "REDACTED"
        redirect_uri: "https://portal.example.com/oauth/callback"
        scopes:
          - openid
          - profile
          - email

    여기서 제가 실제로 자주 본 문제는 세 가지였습니다.

    • issuer 불일치: 트레일링 슬래시 하나 차이로 검증 실패
    • redirect_uri 불일치: 프록시 뒤에 있어서 http로 인식됨
    • scope 누락: email, profile이 없어 사용자 매핑 실패

    4-2. SAML 설정 점검 포인트

    SAML은 XML 기반이라 더 고전적인 대신, 장애가 나면 더 난감할 때가 있습니다. 처음엔 에러 메시지도 불친절해서 헷갈렸는데, 결국 볼 건 비슷합니다.

    saml:
      entity_id: "https://service.example.com/saml/metadata"
      acs_url: "https://service.example.com/saml/acs"
      idp_metadata_url: "https://idp.example.com/metadata"
      want_assertions_signed: true
      want_response_signed: true

    ACS URL(Assertion Consumer Service URL, 인증 응답 수신 주소), Entity ID, 서명용 인증서가 안 맞으면 거의 바로 터집니다.

    SSO 로그인 장애 해결에 필요한 OIDC와 SAML 설정 비교 이미지

    실무에서 자주 확인하는 issuer, redirect URI, ACS URL, Entity ID 같은 핵심 항목을 비교해 보여주는 이미지입니다.

    5. ⚠️ 자주 만나는 장애 패턴과 해결 전략

    이제부터는 제가 장애 대응하면서 반복해서 본 케이스들입니다. 여기서 시간 많이 씁니다.

    5-1. 무한 리다이렉트가 걸릴 때

    브라우저에서 로그인 후 다시 로그인 페이지로 돌아오면 보통 세션이 저장되지 않았거나, 콜백 URL 계산이 틀린 경우가 많습니다.

    • 쿠키의 SameSite 속성 확인
    • Secure 쿠키인데 HTTPS 종료 지점이 꼬이지 않았는지 확인
    • X-Forwarded-Proto, X-Forwarded-Host 헤더 전달 확인
    • 애플리케이션의 external URL 설정 확인

    저는 예전에 로드밸런서에서 HTTPS를 종료하고 백엔드로 HTTP를 넘기는 구조에서 이걸 크게 겪었습니다. 앱은 자꾸 자기 주소를 http로 계산하고, IdP에는 https로 등록되어 있으니 매번 검증이 틀어지더라고요.

    5-2. token expired 또는 not yet valid

    이건 거의 시간 문제입니다. 서버 두 대 중 한 대만 시간이 어긋나도 간헐 장애처럼 보입니다. 그래서 모든 인증 노드는 반드시 같은 시간 기준을 써야 합니다.

    timedatectl status
    chronyc tracking
    # 컨테이너 환경이라면 호스트 시간도 같이 확인

    5-3. 특정 사용자만 실패할 때

    이 경우는 그룹 매핑(group mapping), 이메일 클레임(claim), NameID 형식, 역할(role) 동기화 문제일 때가 많습니다. 즉, 시스템 전체 장애가 아니라 속성(attribute) 매핑 문제일 수 있습니다.

    5-4. 인증서는 멀쩡한데 서명 검증이 실패할 때

    이건 IdP 메타데이터가 갱신됐는데 SP가 예전 인증서를 계속 들고 있을 때 자주 봅니다. 메타데이터 캐시를 갱신하거나, 인증서를 다시 가져오면 풀리는 경우가 많습니다.

    6. 검증 절차: 수정 후에는 이렇게 확인합니다

    SSO 로그인 장애 조치가 끝났다고 바로 종료하면 안 됩니다. 저도 예전에 한 사용자만 테스트하고 끝냈다가, 다른 브라우저에서 다시 터진 적이 있었습니다. 그래서 수정 후 검증은 아래처럼 분리해서 합니다.

    1. 신규 세션 테스트: 시크릿 모드에서 처음부터 로그인
    2. 기존 세션 테스트: 로그인 상태 유지, 로그아웃 후 재로그인
    3. 권한별 테스트: 일반 사용자, 관리자, 외부 사용자 계정
    4. 브라우저별 테스트: Chrome, Edge, Safari 등
    5. 로그 검증: 에러가 사라졌는지, 경고만 남았는지 확인
    # 최근 10분간 에러 로그 재확인
    journalctl -u myapp --since "10 minutes ago" | egrep -i "error|warn|saml|oidc|oauth|token|assertion"
    
    # 헬스체크 응답 확인
    curl -k https://service.example.com/health
    
    # 로그인 후 콜백 응답 코드 확인 예시
    curl -k -I https://portal.example.com/oauth/callback
    SSO 로그인 장애 해결 후 정상 동작을 확인하는 결과 대시보드 이미지

    장애 조치 이후 정상 로그인과 에러 감소 추이를 함께 보여주는 검증 결과 이미지입니다.

    이렇게 해두면 단순히 “된다”가 아니라, 왜 해결됐는지까지 남길 수 있습니다. 이게 다음 장애 때 큰 차이를 만듭니다. 드디어 됐다! 싶은 순간이 오더라고요.

    7. 빠르게 보는 SSO 디버깅 체크리스트

    운영 중 급할 때 바로 볼 수 있게 요약하면 이렇습니다.

    체크 항목 무엇을 볼까 의심 원인
    브라우저 Network 302/400/401/403 흐름 redirect_uri, 쿠키, 프록시
    애플리케이션 로그 issuer, audience, nonce, assertion 설정 불일치, 서명 오류
    IdP 로그 정책 차단, 매핑 실패 사용자 속성, 그룹, 앱 정책
    시간 동기화 NTP 상태 token expired, not yet valid
    TLS/인증서 만료일, 체인 신뢰 실패, 메타데이터 불일치

    SSO 로그인 장애 해결을 할 때 중요한 건 도구보다 순서입니다. 순서만 잡히면 장애 대응 시간이 확 줄어듭니다.

    8. 정리와 다음 단계

    오늘 정리한 내용은 결국 하나로 모입니다. SSO 디버깅은 인증 서버만 보지 말고, 사용자 요청이 지나가는 전 구간을 따라가야 한다는 점입니다. 저도 처음엔 앱 로그만 붙잡고 있었는데, 실제로는 프록시 헤더 하나 때문에 반나절을 날린 적도 있었거든요. 그런 삽질을 몇 번 하고 나니, 이제는 무조건 체크리스트로 갑니다.

    혹시 지금 인증 오류나 로그인 실패 때문에 급하게 보고 계시다면, 먼저 최근 변경사항과 시간 동기화부터 보세요. 그다음 브라우저 리다이렉트 흐름, 애플리케이션 로그, IdP 로그 순으로 좁혀가면 됩니다. 이 흐름만 익숙해져도 IDP 문제 해결 속도가 꽤 빨라집니다.

    다음 글에서는 Keycloak, Okta 같은 실존 IdP 제품에서 공통적으로 확인할 수 있는 로그 포인트와, Kubernetes(쿠버네티스) Ingress(인그레스, 외부 트래픽 진입점) 뒤에서 SSO가 꼬일 때의 대응법도 다뤄볼 예정입니다. 이전 글에서 다뤘던 리버스 프록시 헤더 정리 글도 함께 보시면 더 이해가 잘 되실 겁니다.

    SSO 로그인 장애 해결 체크리스트 요약 인포그래픽

    장애 대응 순서, 주요 원인, 확인 명령어를 한 장으로 요약한 인포그래픽 이미지입니다.

    9. 자주 묻는 질문

    Q1. 로그인 실패가 특정 브라우저에서만 발생하면 어디를 봐야 하나요?

    쿠키 정책, 캐시, 확장 프로그램, 서드파티 쿠키 차단 설정부터 보시면 됩니다. 특히 SameSite 정책은 브라우저별 체감이 다를 수 있습니다.

    Q2. IdP는 정상인데 서비스만 로그인 안 되면요?

    SP 쪽 redirect_uri, ACS URL, issuer, audience 설정을 다시 보셔야 합니다. 대부분은 설정 불일치입니다.

    Q3. 장애 재발 방지는 어떻게 하시나요?

    설정 변경 전후 diff 관리, 메타데이터 만료 모니터링, NTP 상태 점검, synthetic login test(합성 로그인 테스트) 자동화를 추천드립니다. 이거 진짜 편하더라고요.

  • [Cloud] Okta, Keycloak, Auth0: 클라우드 SSO 솔루션 비교 분석

    [Cloud] Okta, Keycloak, Auth0: 클라우드 SSO 솔루션 비교 분석

    [인증] 클라우드 SSO 비교: Okta, Keycloak, Auth0 분석

    SSO 체계를 도입해야 할 때가 꼭 옵니다. SaaS가 늘어나고, 사내 앱도 많아지고, 외부 파트너 계정까지 붙기 시작하면 로그인 관리가 금방 복잡해지거든요. 저도 홈랩과 실무 환경에서 IdP(Identity Provider, 사용자 신원을 확인해 주는 주체) 구성을 여러 번 갈아엎어 봤는데, 처음엔 이게 뭔가 싶었습니다. 그냥 로그인 하나 붙이는 일 같았는데, 막상 들어가 보면 프로토콜 선택, 운영 책임, 확장 방식, 감사 로그까지 다 엮여 있더라고요.

    이번 글은 Okta, Keycloak, Auth0를 놓고, 어떤 팀에 어떤 선택이 맞는지 경험 기반으로 정리한 글입니다. 제품 소개를 나열하기보다는, 실제로 SSO 솔루션 선택할 때 어디를 봐야 하는지에 초점을 맞췄습니다. 특히 B2E(Business to Employee, 임직원용), B2B(Business to Business, 파트너 연동), 내부 서비스 인증 통합을 고민하는 분들께 도움이 될 겁니다.

    클라우드 SSO 비교를 위한 전체 아키텍처 개요 이미지

    Okta, Keycloak, Auth0가 사용자, 애플리케이션, 외부 IdP 사이에서 어떻게 배치되는지 한눈에 보여주는 개요 이미지입니다.

    1. 클라우드 SSO 비교 전에 먼저 이해할 핵심 개념

    쉽게 말해 SSO(Single Sign-On, 한 번 로그인으로 여러 서비스 이용)는 중앙 인증 허브를 두는 방식입니다. 사용자는 각 서비스마다 비밀번호를 넣는 대신, 중앙의 IdP에서 한 번 인증하고 나머지 서비스는 그 결과를 신뢰합니다.

    • IdP(Identity Provider): 사용자를 인증하는 주체입니다. Okta, Keycloak, Auth0가 여기에 들어갑니다.
    • SP(Service Provider): 실제 서비스 앱입니다. 사내 포털, Grafana, Jenkins, Slack 같은 대상이 여기에 들어갑니다.
    • OIDC(OpenID Connect, OAuth 2.0 기반 인증 표준): 요즘 웹앱, 모바일앱에 가장 많이 붙습니다.
    • SAML(Security Assertion Markup Language, XML 기반 기업용 연동 표준): 오래된 엔터프라이즈 SaaS나 기업 연동에서 여전히 많이 보입니다.
    • SCIM(System for Cross-domain Identity Management, 계정 프로비저닝 표준): 로그인만이 아니라 계정 생성/비활성화 자동화까지 다룰 때 중요합니다.

    여기서 중요한 포인트가 하나 있습니다. SSO는 로그인 화면 예쁘게 만드는 기술이 아니라 운영 모델을 정하는 일입니다. 누가 계정을 만들고, 누가 권한을 회수하고, 누가 장애를 책임질지까지 같이 결정됩니다.

    2. Okta, Keycloak, Auth0를 보는 기준

    제가 직접 PoC(Proof of Concept, 개념 검증)를 돌릴 때는 기능 목록보다 아래 기준을 먼저 봅니다. 실제로 써보니까 제품 설명서보다 이 기준이 훨씬 덜 헷갈리더라고요.

    1. 운영 주체: SaaS로 맡길지, 직접 운영할지
    2. 주요 사용자군: 임직원 중심인지, 고객 서비스 중심인지
    3. 프로토콜 적합성: OIDC 위주인지, SAML 연동이 많은지
    4. 프로비저닝: 계정 생성/회수 자동화가 중요한지
    5. 커스터마이징: 로그인 흐름, 토큰 클레임, 브랜딩, 확장 포인트가 필요한지
    6. 장애 허용도: 인증 장애가 났을 때 내부 팀이 감당 가능한지

    특히 인프라 팀 입장에서는 기능이 많으냐보다 누가 밤에 깨느냐가 더 중요합니다. SaaS형은 편하지만 제품 철학에 맞춰야 하고, 자체 운영형은 유연하지만 운영 부담이 따라옵니다.

    3. 제품별 성격 요약: IdP 비교 관점에서 보면

    항목 Okta Keycloak Auth0
    기본 성격 클라우드 기반 IAM/SSO 플랫폼 오픈소스 IAM 개발자 친화적 클라우드 ID 플랫폼
    운영 방식 주로 SaaS 직접 구축/운영 주로 SaaS
    강한 영역 임직원 접근 통제, SaaS 연동, 중앙 관리 자체 통제, 커스터마이징, 비용 구조 유연성 애플리케이션 로그인, 고객/파트너 인증 흐름
    적합한 팀 운영 자동화와 거버넌스를 중시하는 조직 플랫폼 통제권이 필요한 엔지니어링 팀 개발 속도와 로그인 UX가 중요한 제품 팀
    표준 지원 관점 OIDC, SAML 등 엔터프라이즈 연동에 강점 OIDC, SAML 기반 표준 지향 OIDC 중심, 엔터프라이즈 연결 옵션 제공
    주의할 점 구성 범위가 넓어 초기 설계가 중요 고가용성, 백업, 업그레이드 책임이 내부에 있음 요구사항이 복잡해질수록 설계 규율이 필요

    Okta는 임직원용 접근 제어와 다양한 SaaS 연동을 중앙에서 다루려는 조직에 잘 맞습니다. 관리 콘솔과 정책 기반 운영이 강점이라, 인프라 팀이 계정 라이프사이클과 MFA(Multi-Factor Authentication, 다중 인증) 정책을 통합하려 할 때 매력이 큽니다.

    Keycloak은 오픈소스 기반이라 통제권이 큽니다. Realm(리얼름, 독립된 인증 도메인), Client(클라이언트, 연동 애플리케이션), Role(역할) 구조를 이해하면 상당히 유연하게 구성할 수 있습니다. 대신 직접 운영하는 순간부터는 인증 서버도 결국 또 하나의 핵심 인프라가 됩니다. 저도 처음엔 무료니까 좋겠네 하고 시작했다가, 백업/복구 설계에서 삽질 좀 했습니다 ㅎㅎ

    Auth0는 개발자 관점에서 접근하기 편한 편입니다. 애플리케이션 로그인 흐름, Universal Login(통합 로그인 화면), 외부 엔터프라이즈 연결 같은 시나리오를 빠르게 붙이기 좋습니다. 참고로 Auth0는 2021년 Okta에 인수되었지만, 제품 선택 관점에서는 여전히 별도 성격으로 보는 게 실무에선 편합니다.

    4. 어떤 상황에서 무엇을 고를까: SSO 솔루션 선택 가이드

    Okta가 잘 맞는 경우

    • 사내 SaaS 수가 많고 중앙 접근 제어가 필요할 때
    • HR 시스템과 계정 라이프사이클을 맞추고 싶을 때
    • 감사 로그, 정책, 관리자 역할 분리가 중요한 조직일 때

    Keycloak이 잘 맞는 경우

    • 자체 호스팅이 가능하고 운영 역량이 있는 팀일 때
    • 내부 서비스, 홈랩, 사설망 환경까지 폭넓게 통합해야 할 때
    • 벤더 종속성보다 표준 기반 제어권이 더 중요할 때

    Auth0가 잘 맞는 경우

    • 제품팀이 빠르게 로그인 체계를 붙여야 할 때
    • 고객/파트너 인증 흐름을 앱 중심으로 설계할 때
    • OIDC 기반 애플리케이션 통합과 브랜딩 경험이 중요할 때

    실제로는 이렇게 정리하면 편합니다. 기업 내부 접근 통합이면 Okta 쪽이 먼저 검토되고, 직접 운영 가능한 플랫폼 팀이면 Keycloak이 강하게 들어오고, 애플리케이션 로그인 제품화가 핵심이면 Auth0가 자연스럽게 후보가 됩니다.

    5. 실전 구현: 같은 기준으로 세 제품을 검증하는 방법

    비교 글만 읽고 끝내면 감이 잘 안 옵니다. 제가 추천하는 방법은 세 제품을 모두 같은 체크리스트로 보는 겁니다. 핵심은 OIDC Discovery(OpenID Connect 디스커버리, 인증 메타데이터 자동 조회), 토큰 발급, 클레임 매핑, 로그 확인입니다.

    1. 테스트용 애플리케이션 하나를 준비합니다.
    2. OIDC issuer(발급자 URL)를 기준으로 메타데이터를 조회합니다.
    3. 리다이렉트 로그인 후 ID Token, Access Token 구조를 확인합니다.
    4. 로그아웃과 세션 만료 동작을 검증합니다.
    5. 그룹/역할 클레임이 앱까지 제대로 전달되는지 확인합니다.

    Keycloak은 홈랩에서 바로 띄워 보기 좋습니다. 아래처럼 로컬 테스트를 시작할 수 있습니다.

    docker run --name keycloak-dev \
      -p 8080:8080 \
      -e KEYCLOAK_ADMIN=admin \
      -e KEYCLOAK_ADMIN_PASSWORD=admin \
      quay.io/keycloak/keycloak:latest start-dev

    테스트가 올라오면 OIDC 메타데이터를 바로 확인합니다.

    curl -s http://localhost:8080/realms/master/.well-known/openid-configuration

    Okta나 Auth0는 로컬 컨테이너 대신 테넌트 기준으로 issuer URL을 확인하면 됩니다. 아래처럼 포맷만 맞춰 두고 비교하면 꽤 수월합니다.

    curl -s https://YOUR_OKTA_DOMAIN/.well-known/openid-configuration
    curl -s https://YOUR_AUTH0_DOMAIN/.well-known/openid-configuration

    앱 설정은 대체로 이런 항목들을 공통으로 봅니다.

    sso:
      provider: oidc
      issuer: https://example.com/
      client_id: example-client-id
      client_secret: example-client-secret
      redirect_uri: https://app.example.com/callback
      scopes:
        - openid
        - profile
        - email

    여기서 제가 꼭 보는 건 issuer, redirect URI, scope 세 가지입니다. 이 셋 중 하나만 어긋나도 로그인은 되는데 세션이 안 잡히거나, 토큰 검증이 실패하거나, 사용자 정보가 비어 버리거든요.

    클라우드 SSO 비교에서 OIDC 설정 흐름을 보여주는 이미지

    클라이언트 설정값, 리다이렉트 URI, 토큰 발급 흐름을 한 번에 보여주는 실전 구성 이미지입니다.

    6. ⚠️ 실제 많이 막히는 포인트와 트러블슈팅

    여기는 진짜 중요합니다. 기능 비교보다 장애 포인트를 먼저 알아두면 시간이 많이 절약됩니다.

    1) Redirect URI 불일치

    가장 흔합니다. 브라우저에서는 그럴듯하게 보이는데 인증 서버는 아주 엄격하게 비교합니다. 슬래시 하나, 포트 하나 달라도 실패합니다. 저도 처음엔 앱 버그인 줄 알고 한참 헤맸는데, 결국 콜백 URL 오타였던 적이 많았습니다.

    2) SAML과 OIDC를 섞어 생각함

    기존 SaaS는 SAML만 받고, 신규 내부 앱은 OIDC가 더 자연스러운 경우가 많습니다. 이걸 한 제품 안에서 모두 다룰 수 있는지가 중요합니다. 특히 엔터프라이즈 연동에서는 프로토콜 혼재를 전제로 설계해야 합니다.

    3) 그룹/역할 클레임 설계 부족

    로그인까진 되는데 권한이 안 맞는 경우가 있습니다. 사용자 인증(Authentication, 본인 확인)과 인가(Authorization, 권한 부여)는 다른 문제거든요. 토큰에 어떤 클레임을 넣을지, 앱이 그걸 어떻게 읽을지 초기에 정해야 합니다.

    4) 자체 운영형의 고가용성 착시

    Keycloak은 잘 돌아갈 때 정말 편합니다. 근데 여기서 방심하면 안 됩니다. DB(Database, 데이터베이스) 백업, 세션 저장소, 인증서 갱신, 업그레이드 검증, 모니터링을 다 챙겨야 합니다. “로그인 서버 하나쯤이야” 하고 가볍게 보면 나중에 제일 무거운 서비스가 되더라고요.

    5) SaaS형의 정책 복잡도

    Okta나 Auth0는 관리형이라 편하지만, 반대로 조직 정책이 복잡하면 설계를 대충 하면 안 됩니다. 애플리케이션별 로그인 정책, 외부 IdP 연결, MFA 예외 규칙, 관리자 권한 분리를 먼저 정리해 두는 게 좋습니다.

    7. 검증 결과: 운영자 시선에서 정리한 결론

    제가 직접 해보니 세 제품은 “누가 더 좋다”가 아니라 “어떤 운영 모델에 맞느냐”로 갈립니다.

    • Okta: 임직원용 SSO와 중앙 정책 관리가 핵심인 조직에 안정적인 선택지입니다.
    • Keycloak: 인프라 팀이 직접 통제하고 표준 기반으로 확장하려는 환경에 잘 맞습니다.
    • Auth0: 제품팀이 빠르게 로그인 경험을 구현하고 외부 연결을 확장하려는 경우 강점이 있습니다.

    간단한 판단표로 보면 이렇습니다.

    질문 우선 검토 후보
    사내 앱과 SaaS를 한 번에 묶고 싶은가? Okta
    직접 운영해도 괜찮고 통제권이 더 중요한가? Keycloak
    고객/파트너 로그인 경험이 제품 경쟁력과 연결되는가? Auth0
    표준 기반 연동을 실험하며 내부 플랫폼을 키우고 싶은가? Keycloak 또는 Okta
    클라우드 SSO 비교 검증 결과를 보여주는 대시보드 이미지

    OIDC 메타데이터 확인, 토큰 검증, 권한 클레임 확인이 완료된 상태를 보여주는 검증 결과 이미지입니다.

    이 단계까지 오면 이제 비교가 감으로 되는 게 아니라, 운영 부담과 목표에 맞춘 선택으로 바뀝니다. 이거 진짜 편하더라고요. 제품 마케팅 문구에 덜 흔들리게 됩니다.

    8. 자주 묻는 질문과 마무리

    Q1. 세 제품 모두 SSO 용도로 쓸 수 있나요?

    네. 다만 접근 방식이 다릅니다. Keycloak은 오픈소스 기반 자체 운영, Okta와 Auth0는 클라우드 중심 운영에 더 가깝습니다.

    Q2. 내부 직원용과 외부 고객용을 같은 제품으로 가야 하나요?

    반드시 그럴 필요는 없습니다. 조직 구조와 운영 책임이 다르면 분리하는 쪽이 더 깔끔할 때도 많습니다.

    Q3. 처음 PoC는 무엇부터 확인하면 되나요?

    OIDC 로그인, 그룹/역할 클레임, 로그아웃, 감사 로그, 계정 비활성화 반영까지 보시면 됩니다. 로그인 성공 화면만 보고 끝내면 나중에 꼭 다시 보게 됩니다.

    정리해보면, 이번 클라우드 SSO 비교의 핵심은 기능표가 아니라 운영 모델입니다. Okta, Keycloak, Auth0 모두 실존하는 강한 도구지만, 팀의 성숙도와 목표가 다르면 정답도 달라집니다. 저도 처음엔 기능이 많은 쪽이 답인 줄 알았는데, 실제로 써보니까 누가 운영하고 어디까지 자동화할지가 훨씬 중요했습니다.

    다음 글에서는 Keycloak으로 홈랩 SSO 붙이기를 단계별로 다뤄볼 예정입니다. 이전 글에서 다룬 Reverse Proxy(리버스 프록시, 앞단 트래픽 제어)와 함께 보시면 흐름이 더 잘 잡히실 겁니다.

    Okta Keycloak Auth0 클라우드 SSO 비교 요약 인포그래픽

    운영 방식, 추천 시나리오, 선택 기준을 한 장으로 요약한 비교 인포그래픽 이미지입니다.

  • [Cloud] GitHub Actions OIDC로 AWS 인증하기: 보안 강화 및 자격 증명 관리

    [Cloud] GitHub Actions OIDC로 AWS 인증하기: 보안 강화 및 자격 증명 관리

    GitHub Actions에서 AWS 인증, 아직도 IAM Access Key 쓰시나요?

    안녕하세요, 13년차 인프라 엔지니어이자 서버실 주인장입니다. 지난 몇 년간 수많은 CI/CD 파이프라인(Continuous Integration/Continuous Delivery Pipeline)을 구축하고 관리해왔는데, GitHub Actions와 AWS를 연동해서 사용하는 경우가 정말 많았거든요. 처음에는 저도 많은 분들처럼 AWS IAM(Identity and Access Management) 사용자의 Access Key와 Secret Key를 GitHub Secrets에 넣어 사용했습니다. 편리하긴 했죠. 근데 이게 뭔가 찜찜하더라고요.

    Access Key는 말 그대로 영구적인 자격 증명(Long-lived Credentials)이라 탈취 위험이 늘 존재하고, 정기적으로 Key를 교체(Rotation)해야 하는 관리 부담도 만만치 않았습니다. 만약 여러 레포지토리에서 같은 키를 쓴다면 더더욱 골치 아파지고요. 혹시 이런 경험 있으신가요? 저도 처음엔 이 방식밖에 없나 싶었는데, 다행히 더 안전하고 효율적인 방법이 등장했습니다. 바로 GitHub Actions OIDC(OpenID Connect)를 활용한 AWS 인증입니다! 오늘은 이 OIDC를 이용해 GitHub Actions에서 AWS에 안전하게 접근하는 방법을 제 경험을 바탕으로 자세히 알려드릴게요. CI/CD 파이프라인의 보안을 한 단계 끌어올리는 중요한 포인트가 될 겁니다.

    GitHub Actions OIDC를 이용한 AWS 인증의 전체적인 아키텍처 다이어그램입니다. GitHub Actions가 OIDC Provider 역할을 하고, AWS IAM이 이를 신뢰하여 임시 자격 증명을 발급하는 과정을 보여줍니다.

    OIDC(OpenID Connect)와 워크로드 아이덴티티(Workload Identity)가 뭔가요?

    본격적인 설정에 들어가기 전에, OIDC와 워크로드 아이덴티티라는 개념을 잠시 짚고 넘어가면 좋습니다. 복잡하게 들릴 수 있지만, 쉽게 말해볼게요.

    • OIDC (OpenID Connect, 오픈아이디 커넥트): OAuth 2.0 위에 구축된 인증(Authentication) 프로토콜입니다. 사용자(혹은 서비스)가 어떤 Identity Provider(신원 제공자)에게 “나 누구야”라고 인증받으면, Identity Provider는 ID Token이라는 걸 발급해줍니다. 이 토큰 안에는 “이 사람이 누구고, 어떤 방식으로 인증했는지” 같은 정보가 담겨있죠. AWS의 경우, GitHub Actions가 Identity Provider 역할을 하고, AWS IAM이 이 ID Token을 신뢰하는 Relying Party(의존 당사자)가 되는 겁니다.
    • 워크로드 아이덴티티 (Workload Identity): CI/CD 파이프라인의 워크로드(Workload)나 컨테이너처럼 사람이 아닌 시스템에 신원(Identity)을 부여하는 개념입니다. 기존의 Access Key 방식처럼 영구적인 자격 증명을 주지 않고, 필요할 때만 임시 자격 증명(Temporary Credentials)을 발급받아 사용하는 방식이에요. 이렇게 하면 자격 증명 탈취 위험을 최소화하고, 키 관리 부담을 없앨 수 있습니다.

    결론적으로, GitHub Actions OIDC를 사용하면 GitHub Actions 워크플로우가 직접 Access Key 없이 AWS에 “나 GitHub Actions의 이 레포지토리, 이 브랜치에서 실행된 애야!”라고 증명하고, AWS는 이 신원을 확인한 후 특정 권한을 가진 임시 자격 증명을 주는 방식이라고 이해하시면 됩니다. 진짜 편하고 안전하더라고요!

    GitHub Actions OIDC로 AWS 인증 설정 단계별 가이드

    자, 이제 실제로 GitHub Actions OIDC를 이용해 AWS에 인증하는 방법을 단계별로 따라해 볼까요? 제가 직접 해보니 몇 가지 포인트만 잘 기억하면 어렵지 않게 설정할 수 있었습니다.

    1단계: AWS IAM Identity Provider 생성하기

    가장 먼저 AWS IAM에서 GitHub Actions를 신뢰할 수 있는 OIDC Identity Provider로 등록해야 합니다. AWS 콘솔에서 진행하는 것이 가장 직관적입니다.

    1. AWS 콘솔에 로그인 후 IAM 서비스로 이동합니다.
    2. 왼쪽 탐색 메뉴에서 Access management (액세스 관리) > Identity Providers (자격 증명 공급자)를 클릭합니다.
    3. Add provider (공급자 추가) 버튼을 클릭합니다.
    4. Provider type (공급자 유형)으로 OpenID Connect를 선택합니다.
    5. Provider URL (공급자 URL)에 <code>https://token.actions.githubusercontent.com 을 입력합니다.
    6. Get thumbprint (지문 가져오기) 버튼을 클릭하여 서버 인증서 지문을 자동으로 가져옵니다.
    7. Audience (대상)에는 sts.amazonaws.com 을 입력하고 Add provider (공급자 추가)를 클릭하여 완료합니다.

    💡 팁: sts.amazonaws.com은 AWS Security Token Service의 기본 대상입니다. 다른 용도로 특정 서비스에만 OIDC를 사용한다면 해당 서비스의 Audience를 사용할 수도 있습니다.

    AWS IAM 콘솔에서 OIDC Identity Provider를 생성하는 화면입니다. Provider URL과 Audience를 정확히 입력하는 것이 중요합니다.

    2단계: AWS IAM Role 생성하기

    이제 이 OIDC Identity Provider를 통해 GitHub Actions가 임시 자격 증명을 요청할 수 있는 IAM Role을 생성해야 합니다. 이 역할에는 GitHub Actions가 AWS에서 수행할 작업에 대한 권한을 부여하게 됩니다.

    1. IAM 콘솔에서 Access management (액세스 관리) > Roles (역할)로 이동합니다.
    2. Create role (역할 생성) 버튼을 클릭합니다.
    3. Select type of trusted entity (신뢰할 수 있는 개체 유형 선택)에서 Custom trust policy (사용자 지정 신뢰 정책)를 선택합니다.
    4. 다음과 같이 신뢰 정책을 작성합니다. 여기서 StringEquals 조건이 핵심입니다!
    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Principal": {
            "Federated": "arn:aws:iam::YOUR_AWS_ACCOUNT_ID:oidc-provider/token.actions.githubusercontent.com"
          },
          "Action": "sts:AssumeRoleWithWebIdentity",
          "Condition": {
            "StringEquals": {
              "token.actions.githubusercontent.com:aud": "sts.amazonaws.com",
              "token.actions.githubusercontent.com:sub": "repo:YOUR_GITHUB_ORG/YOUR_GITHUB_REPO:ref:refs/heads/main"
            }
          }
        }
      ]
    }

    ⚠️ 주의사항:

    • YOUR_AWS_ACCOUNT_ID: 여러분의 AWS 계정 ID로 교체해야 합니다.
    • YOUR_GITHUB_ORG/YOUR_GITHUB_REPO: GitHub 조직(Organization) 이름과 레포지토리(Repository) 이름으로 교체해야 합니다.
    • ref:refs/heads/main: 이 부분은 특정 브랜치(Branch)에서만 역할 가정을 허용하겠다는 의미입니다. *를 사용하여 모든 브랜치를 허용할 수도 있지만, 보안을 위해 특정 브랜치를 지정하는 것을 권장합니다. 예를 들어, 특정 태그(tag)에서만 허용하려면 ref:refs/tags/v*와 같이 설정할 수 있습니다.
    1. 정책 검토 후 다음 단계로 넘어갑니다.
    2. 이 역할에 필요한 Permissions (권한)을 부여합니다. 예를 들어 S3 버킷에 파일을 업로드해야 한다면 AmazonS3FullAccess 대신 필요한 최소한의 권한(Least Privilege)을 부여하는 것이 좋습니다. 저는 테스트를 위해 AmazonS3ReadOnlyAccess를 잠시 붙여봤습니다.
    3. 역할 이름을 지정하고(예: GitHubActionsOIDC-S3AccessRole) 역할을 생성합니다.

    3단계: GitHub Actions Workflow 설정하기

    마지막으로 GitHub Actions 워크플로우 YAML 파일에 OIDC를 통한 AWS 인증 로직을 추가합니다. configure-aws-credentials 액션을 사용하면 아주 쉽게 설정할 수 있습니다.

    name: Deploy to AWS S3 via OIDC
    
    on:
      push:
        branches:
          - main
    
    permissions:
      id-token: write # OIDC ID Token을 요청하기 위해 필수
      contents: read # 레포지토리 코드 읽기 권한
    
    jobs:
      deploy:
        runs-on: ubuntu-latest
        steps:
          - name: Checkout code
            uses: actions/checkout@v4
    
          - name: Configure AWS Credentials with OIDC
            uses: aws-actions/configure-aws-credentials@v4
            with:
              role-to-assume: arn:aws:iam::YOUR_AWS_ACCOUNT_ID:role/GitHubActionsOIDC-S3AccessRole # 2단계에서 생성한 역할 ARN
              aws-region: ap-northeast-2 # 여러분의 AWS 리전
              # role-session-name: optional-session-name # (선택 사항)
    
          - name: List S3 buckets (for verification)
            run: aws s3 ls

    ⚠️ 여기서 중요한 포인트! permissions: id-token: write 설정은 반드시 필요합니다. 이 권한이 없으면 GitHub Actions가 OIDC ID Token을 생성할 수 없어 AWS 인증이 실패합니다. 처음엔 이걸 몰라서 삽질 좀 했습니다 ㅎㅎ

    삽질 경험: “AccessDenied” 에러의 늪에서 벗어나기 ⚠️

    제가 처음 GitHub Actions OIDC를 설정하면서 가장 많이 겪었던 문제는 다름 아닌 “AccessDenied” 에러였습니다. 워크플로우 로그를 보면 An error occurred (AccessDenied) when calling the AssumeRoleWithWebIdentity operation: Not authorized to perform sts:AssumeRoleWithWebIdentity 이런 메시지가 뜨더라고요. 진짜 답답했죠.

    주요 원인은 대부분 IAM Role의 Trust Policy (신뢰 정책) 조건 문제였습니다. 제가 겪었던 실수와 해결 방법은 다음과 같습니다.

    • Audience 불일치: IAM Identity Provider를 생성할 때 Audience를 sts.amazonaws.com으로 설정했는데, IAM Role Trust Policy의 "token.actions.githubusercontent.com:aud" 조건에도 정확히 "sts.amazonaws.com"이 들어가야 합니다. 한 글자라도 다르면 인증이 실패합니다.
    • sub 조건 오류: 가장 흔한 실수입니다. "token.actions.githubusercontent.com:sub" 조건에 지정된 GitHub 레포지토리, 브랜치 정보가 정확해야 합니다. 예를 들어, repo:YOUR_GITHUB_ORG/YOUR_GITHUB_REPO:ref:refs/heads/main 에서 오타가 있거나, 워크플로우가 실행되는 브랜치와 다르면 에러가 발생합니다. 저는 처음에 main 브랜치로 설정해놓고 develop 브랜치에서 테스트하다가 한참을 헤맸습니다.
    • permissions: id-token: write 누락: GitHub Actions 워크플로우 자체에 OIDC 토큰을 생성할 권한이 없어서 생기는 문제입니다. 이 한 줄 때문에 몇 시간을 날린 적도 있어요. 꼭 확인하세요!
    • AWS 계정 ID 또는 역할 ARN 오타: 기본적인 실수지만, 의외로 자주 발생합니다. ARN을 복사 붙여넣기 할 때 다시 한번 확인하는 습관을 들이세요.

    문제가 발생하면 AWS CloudTrail 로그를 확인하는 것이 가장 좋습니다. AssumeRoleWithWebIdentity 호출이 실패한 이유가 자세히 기록되어 있으니 꼭 살펴보세요. 삽질 끝에 드디어 성공했을 때의 그 쾌감이란! 진짜 이 맛에 엔지니어 하는 것 같아요.

    드디어 성공! OIDC로 안전하게 AWS 리소스 접근하기 🎉

    위에 설명드린 대로 모든 설정을 마치고 GitHub Actions 워크플로우를 실행하면, 아래와 같이 성공적으로 AWS 리소스에 접근하는 모습을 볼 수 있습니다.

    GitHub Actions 워크플로우가 성공적으로 AWS CLI 명령어를 실행하여 S3 버킷 목록을 가져오는 로그입니다. OIDC 기반 인증이 정상적으로 작동했음을 보여줍니다.

    워크플로우 로그를 보면 aws s3 ls 명령어가 문제없이 실행되고, S3 버킷 목록이 출력되는 것을 확인할 수 있습니다. 이제 더 이상 GitHub Secrets에 Access Key를 저장할 필요가 없어졌습니다! 🎉

    이 방식의 가장 큰 장점은 바로 단기 자격 증명(Short-lived Credentials)이라는 점입니다. GitHub Actions 워크플로우가 실행될 때만 임시 자격 증명을 발급받아 사용하고, 워크플로우가 끝나면 만료되죠. 덕분에 키 탈취로 인한 보안 위험이 현저히 줄어들고, 키 교체 주기를 관리할 필요도 없어졌습니다. 관리적인 측면에서도 엄청난 이득이라고 생각해요.

    OIDC, CI/CD 보안의 새로운 표준이 되다

    오늘은 GitHub Actions OIDC를 이용해 AWS에 안전하게 인증하는 방법을 자세히 알아봤습니다. 제가 직접 경험하며 얻은 삽질 경험과 해결 과정도 솔직하게 공유해 드렸는데요. 이 방식은 단순히 편리함을 넘어 CI/CD 파이프라인의 보안을 근본적으로 강화하는 핵심 기술이라고 생각합니다.

    기존의 Access Key 방식과 OIDC를 활용한 AWS 인증 방식의 주요 특징을 비교한 표입니다. 보안성, 관리 용이성 등 여러 측면에서 OIDC의 장점을 한눈에 보여줍니다.

    핵심 장점을 다시 정리해볼까요?

    • 보안 강화: 영구적인 Access Key 없이 임시 자격 증명 사용으로 탈취 위험 최소화.
    • 관리 용이성: Access Key 생성, 배포, 교체 등의 관리 부담 해소.
    • 정교한 권한 제어: 특정 레포지토리, 특정 브랜치, 특정 태그에서만 AWS 리소스 접근 허용 가능.
    • 감사 추적 용이: CloudTrail을 통해 어떤 GitHub Actions 워크플로우가 어떤 역할로 AWS에 접근했는지 명확하게 추적 가능.

    저도 홈랩에서 다양한 CI/CD 환경을 구성하면서 OIDC의 강력함을 몸소 체험하고 있습니다. 앞으로는 OIDC 기반의 워크로드 아이덴티티가 CI/CD 보안의 표준으로 자리매김할 것이라고 확신합니다. 혹시 아직 Access Key를 사용하고 계시다면, 이번 기회에 OIDC로 전환해 보시는 것을 강력히 추천합니다! 처음엔 조금 낯설 수 있지만, 한번 설정해두면 정말 든든하거든요.

    다음 글에서는 AWS S3에 정적 웹사이트를 배포하는 과정을 GitHub Actions OIDC와 함께 자동화하는 방법에 대해 다뤄볼까 합니다. 기대해주세요! 그럼 다음 글에서 만나요! 👋