사전 페더레이션
개념

페더레이션

gabury1고친 사람 github-actions[bot]

페더레이션은 한 조직이 확인한 사용자를 다른 조직의 서비스가 믿고 들여보내게 해 줍니다. 회사 계정 하나로 회사 밖 업무 서비스에 로그인하는 것이 그 예입니다. 바깥 서비스는 비밀번호 대신 회사가 서명해 보낸 확인서만 검사합니다. 다른 분야에서는 같은 낱말이 따로 도는 시스템 여럿을 잇는 방식을 가리킵니다.

쉽고 빠른 이해

페더레이션은 다른 조직이 확인한 사용자를 믿고 들여보내는 약속입니다. 회사 계정 하나로 회사 밖 메일 서비스와 문서 서비스에 들어가는 것이 그 예입니다.

이 약속이 없으면 직원은 서비스마다 계정을 따로 만들어야 합니다. 퇴사자가 생기면 관리자가 서비스마다 들어가 계정을 하나씩 지워야 합니다. 빠뜨린 계정은 퇴사 뒤에도 살아 있습니다.

순서는 이렇습니다.

  1. 회사와 서비스가 서로를 미리 등록해 둡니다
  2. 직원이 서비스에 들어가려 하면 서비스가 회사 로그인 화면으로 보냅니다
  3. 회사가 직원을 확인한 뒤 서명한 확인서를 들려 돌려보냅니다
  4. 서비스는 서명을 검사한 뒤 직원을 들여보냅니다

대가는 로그인이 회사 한 곳에 묶인다는 것입니다. 회사 로그인이 멈추면 어느 서비스에도 새로 들어갈 수 없습니다. 회사 계정 하나가 털리면 그 계정이 닿는 서비스가 전부 열립니다.

상세

도서관 여러 곳이 협약을 맺었다고 합시다. 협약 도서관의 회원증을 가진 사람은 다른 도서관에서 새로 가입하지 않고 책을 빌립니다. 빌려주는 도서관은 그 사람을 다시 심사하지 않습니다. 회원증을 내준 도서관의 심사를 믿기로 미리 약속해 두었기 때문입니다.

이 절은 회사 계정으로 회사 밖 서비스에 로그인하는 장면을 따라갑니다.

조직마다 계정을 따로 둘 때의 곤란

회사 하나가 회사 밖 업무 서비스를 여럿 쓴다고 합시다. 메일 서비스, 일정 서비스, 문서 서비스 같은 것들입니다. 서비스마다 제 계정과 비밀번호를 따로 받습니다.

직원 한 명이 들어오면 관리자는 서비스마다 계정을 만듭니다. 직원이 나가면 그 계정을 전부 지워야 합니다. 하나라도 빠뜨리면 퇴사한 사람이 그 서비스에 계속 들어올 수 있습니다.

직원 쪽도 곤란합니다. 비밀번호가 여러 개가 되면 같은 비밀번호를 돌려 쓰기 쉽습니다. 그러면 한 서비스에서 새어 나간 비밀번호로 나머지 서비스까지 열립니다.

해법은 사용자를 확인하는 일을 회사 한 곳에 모으는 것입니다. 바깥 서비스는 회사가 확인한 결과를 믿고 받습니다. 조직의 경계를 넘어 이렇게 확인을 맡기고 믿는 약속을 페더레이션이라고 부릅니다. 우리말로는 연합 인증이라고도 씁니다.

federation 은 영어로 연방을 뜻합니다. 연방의 주들은 저마다 자치를 지킵니다. 그러면서도 한 나라로 묶입니다.

페더레이션도 모양이 같습니다. 조직마다 제 계정은 스스로 관리합니다. 확인 결과만 서로 믿습니다.

누가 누구를 믿나

페더레이션에는 세 쪽이 등장합니다. 로그인하려는 사용자, 사용자를 확인해 주는 쪽, 그 확인을 믿는 쪽입니다.

사용자를 확인해 주는 쪽이 신원 제공자입니다. 영어로 Identity Provider 라서 IdP 라고 줄여 씁니다. 신원 제공자는 직원 계정과 비밀번호를 쥐고 있습니다. 회사가 직접 운영하기도 합니다. 회사가 고른 로그인 전문 서비스에 맡기기도 합니다.

확인을 믿는 쪽이 신뢰 당사자입니다. 사용자가 쓰려는 바깥 서비스가 이쪽입니다. 규격에 따라 서비스 제공자(SP, Service Provider)라고도 부릅니다. 두 이름은 같은 역할을 가리킵니다.

신원 제공자가 신뢰 당사자에게 건네는 확인서가 단언입니다. 단언에는 누가 언제 로그인했는지와 어느 서비스 앞으로 보내는 것인지가 적힙니다. 도서관 비유의 회원증이 이것입니다.

신원 제공자는 단언에 서명을 붙여 보냅니다. 서명은 신원 제공자만 만들 수 있는 표식입니다. 중간에 누가 단언 내용을 고치면 서명이 맞지 않아 들킵니다.

서명에는 짝을 이루는 키 두 개를 씁니다. 신원 제공자는 자기만 가진 개인 키로 서명을 만듭니다. 신뢰 당사자는 미리 받아 둔 공개 키로 그 서명이 맞는지 검사합니다. 공개 키는 남에게 알려도 괜찮은 키입니다.

한 조직이 제 계정과 규칙으로 관리하는 범위를 보안 도메인이라고 합니다. 페더레이션은 이 범위가 서로 다른 조직 사이에 맺는 약속입니다. 한 회사 안의 시스템끼리 로그인을 나누는 것과는 이 점이 다릅니다.

아래 그림은 신원 제공자 하나에 신뢰 당사자 여럿이 매달린 모양입니다.

flowchart TD
    subgraph 회사["회사의 보안 도메인"]
        A["직원 계정"] --> I["신원 제공자"]
    end
    I -->|서명한 단언| S1["메일 서비스"]
    I -->|서명한 단언| S2["일정 서비스"]
    I -->|서명한 단언| S3["문서 서비스"]

직원 계정은 회사의 보안 도메인 안에만 있습니다. 바깥의 세 서비스는 계정을 갖지 않고 서명된 단언만 받습니다.

믿음을 미리 세워 두는 등록

신뢰 당사자는 아무 신원 제공자의 단언이나 믿지 않습니다. 신원 제공자도 아무 서비스에나 단언을 보내지 않습니다. 두 쪽은 로그인이 일어나기 전에 서로를 등록해 둡니다.

등록 때 주고받는 것은 대개 아래 넷입니다. 식별자는 각자를 가리키는 고유한 이름입니다.

건네는 쪽 무엇을 어디에 쓰나
신원 제공자 자기 식별자 단언의 발급자가 맞는지 맞춰 봅니다
신원 제공자 서명 검사용 공개 키 단언의 서명을 검사합니다
신뢰 당사자 자기 식별자 단언이 이 서비스 앞으로 온 것인지 맞춰 봅니다
신뢰 당사자 로그인 뒤 돌아올 주소 단언을 이 주소로만 보냅니다

표의 마지막 줄은 단언이 엉뚱한 곳으로 새는 것을 막습니다. 로그인 요청에 적힌 돌아갈 주소가 등록된 주소와 다르면 신원 제공자는 단언을 보내지 않습니다. 공격자가 주소를 자기 서버로 바꿔 끼워도 단언을 가로챌 수 없습니다.

조직이 많아지면 둘씩 짝을 지어 등록하기가 버겁습니다. 이럴 때는 여러 조직이 중앙 목록 하나에 등록 정보를 올려 두고 서로 믿기도 합니다. 대학들이 연구용 서비스를 함께 쓸 때 이런 연합을 꾸립니다.

로그인 한 번이 지나가는 길

직원이 회사 밖 메일 서비스에 처음 들어가는 경우를 따라갑니다. 사용자를 다른 서비스로 보내는 일은 리다이렉트로 합니다. 리다이렉트는 서버가 브라우저에게 다른 주소로 가라고 돌려보내는 응답입니다.

sequenceDiagram
    participant 사용자
    participant 신뢰당사자 as 신뢰 당사자
    participant 신원제공자 as 신원 제공자
    사용자->>신뢰당사자: 들어가려 한다
    신뢰당사자-->>사용자: 신원 제공자로 돌려보낸다
    사용자->>신원제공자: 회사 계정과 비밀번호로 로그인한다
    신원제공자-->>사용자: 서명한 단언을 들려 돌려보낸다
    사용자->>신뢰당사자: 단언을 전한다
    Note over 신뢰당사자: 단언을 검사한다
    신뢰당사자-->>사용자: 들여보낸다

그림에서 비밀번호는 신원 제공자에게만 갑니다. 신뢰 당사자가 받는 것은 서명된 단언 하나입니다. 그래서 바깥 서비스는 비밀번호를 보관할 책임을 지지 않습니다.

검사를 통과하면 신뢰 당사자는 자기 세션을 만듭니다. 세션은 로그인한 사용자를 다음 요청에서도 알아보려고 서버가 쥐는 기록입니다. 그 뒤의 요청은 이 세션으로 처리합니다. 요청마다 신원 제공자에게 다시 묻지 않습니다.

직원이 이어서 일정 서비스에 들어가면 같은 길을 다시 탑니다. 이번에는 신원 제공자에 로그인 세션이 이미 있습니다. 신원 제공자는 비밀번호를 묻지 않고 바로 단언을 내줍니다.

한 번의 로그인으로 여러 서비스에 들어가는 이 경험이 싱글 사인온(SSO, Single Sign-On)입니다. 페더레이션은 조직 사이에 믿음을 세우는 약속입니다. 싱글 사인온은 그 약속 위에서 사용자가 겪는 결과입니다. 한 회사 안에서만 도는 싱글 사인온도 있으므로 둘이 늘 같이 다니지는 않습니다.

「다른 계정으로 로그인」 버튼을 단 서비스도 같은 구도입니다. 이때 신원 제공자는 회사가 아니라 사용자가 이미 계정을 가진 큰 인터넷 서비스입니다. 이런 로그인을 소셜 로그인이라고 부릅니다.

단언에서 맞춰 보는 칸

신뢰 당사자는 단언을 받자마자 믿지 않습니다. 몇 칸을 맞춰 본 뒤에 믿습니다. 하나라도 빠뜨리면 그 틈으로 남의 단언이 통과합니다.

칸 맞춰 보는 것 빠뜨리면 생기는 일
서명 등록해 둔 공개 키로 검사되나 누구나 단언을 지어내 로그인합니다
발급자 믿기로 등록한 신원 제공자인가 다른 신원 제공자의 단언이 통과합니다
받는 쪽 내 식별자가 적혔나 다른 서비스 앞으로 간 단언을 내게 내밉니다
유효 기간 기한이 안 지났나 오래전에 빼낸 단언으로 들어옵니다

놓치기 쉬운 것은 받는 쪽 칸입니다. 같은 신원 제공자를 쓰는 다른 서비스가 받은 단언도 서명은 맞습니다. 받는 쪽에 내 식별자가 적혀 있어야 그 단언이 나에게 온 것입니다.

단언의 생김새는 웹 로그인 규격 OpenID Connect 로 봅니다. 이 규격은 아래 「페더레이션을 실어 나르는 규격」에서 자세히 다룹니다.

OpenID Connect 에서는 단언을 ID 토큰(ID Token)이라고 부릅니다. ID 토큰은 JSON(JavaScript Object Notation) 문서입니다. 아래는 그 내용 일부입니다.

오른쪽 주석은 위 표의 칸 이름입니다. 표의 첫 칸인 서명은 이 내용 바깥에 따로 붙습니다. 마지막 두 줄은 표의 칸이 아니라 사용자를 알려 주는 값입니다.

JavaScript
{
  "iss": "https://idp.example", // 발급자
  "aud": "mail-app",            // 받는 쪽
  "exp": 1767225600,            // 유효 기간
  "sub": "u-4821",              // 사용자
  "email": "[email protected]"   // 이메일
}

필드 이름은 영어 낱말의 줄임입니다. iss 는 issuer(발급자), aud 는 audience(받는 쪽), exp 는 expiration(만료), sub 는 subject(주체)입니다.

신뢰 당사자는 발급자와 sub 를 한 쌍으로 묶어 자기 회원을 찾습니다. sub 는 신원 제공자가 사용자에게 붙인 번호입니다. 발급자가 다르면 같은 값이 다른 사람일 수 있습니다. 이메일은 회원을 찾는 열쇠로 쓰기 어렵습니다. 사용자가 이메일을 바꾸면 같은 사람이 다른 값으로 들어오기 때문입니다.

넘겨받은 신원으로 권한 정하기

단언에는 사용자 정보도 실립니다. 이메일, 이름, 부서 같은 값입니다. 이 값 하나하나를 클레임이라고 부릅니다. 규격에 따라 속성이라고도 부릅니다.

사용자가 누구인지 확인하는 일이 인증입니다. 그 사용자에게 무엇을 허락할지 정하는 일이 인가입니다. 페더레이션으로 넘기는 것은 인증입니다.

인가는 여전히 신뢰 당사자가 합니다. 부서 클레임이 재무팀인 사용자에게만 결재 화면을 여는 식입니다. 신원 제공자는 사실을 적어 보냅니다. 문을 열지는 신뢰 당사자가 그 사실을 보고 정합니다.

처음 들어온 사용자는 신뢰 당사자에 회원 기록이 없습니다. 이때 단언의 클레임으로 회원 기록을 바로 만드는 방식을 흔히 씁니다. 관리자가 서비스마다 계정을 미리 만들 필요가 없어집니다.

페더레이션을 실어 나르는 규격

페더레이션은 약속의 이름이지 규격 하나의 이름이 아닙니다. 약속을 실제 메시지로 옮기는 규격이 여럿 있습니다. 흔히 만나는 것은 둘입니다.

SAML(Security Assertion Markup Language)은 단언을 XML(eXtensible Markup Language) 문서로 보내는 규격입니다. 기업이 사내 계정으로 바깥 업무 서비스에 들어가게 할 때 오래 써 왔습니다.

OpenID Connect 는 OAuth(Open Authorization) 위에 로그인을 얹은 규격입니다. OAuth 는 사용자가 허락한 만큼 앱이 사용자 대신 다른 서비스를 부르게 해 주는 규격입니다. OAuth 만으로는 사용자가 누구인지 알 수 없습니다. 그 빈칸을 OpenID Connect 의 ID 토큰이 채웁니다.

규격 단언 단언 형식 흔히 만나는 곳
SAML SAML 단언 XML 사내 계정으로 들어가는 기업용 서비스
OpenID Connect ID 토큰 JSON 소셜 로그인 · 웹과 모바일 앱

두 규격은 역할 이름도 다르게 부릅니다. SAML 은 신뢰 당사자를 서비스 제공자라고 부릅니다. OpenID Connect 는 신뢰 당사자라는 이름을 그대로 씁니다.

로그인을 한 곳에 맡기는 대가

페더레이션은 확인을 한 곳에 모읍니다. 그래서 그 한 곳에 생기는 일이 연결된 서비스 전부에 번집니다.

첫째는 가용성입니다. 신원 제공자가 멈추면 연결된 어느 서비스에도 새로 로그인할 수 없습니다. 이미 세션을 받은 사용자는 그 세션이 끝날 때까지 씁니다.

둘째는 피해 범위입니다. 회사 계정 하나가 털리면 그 계정이 닿는 서비스가 전부 열립니다. 신원 제공자의 개인 키가 새면 공격자가 아무 사용자의 단언이나 만들어 냅니다.

그래서 신원 제공자 쪽 로그인은 더 단단히 막습니다. 비밀번호 뒤에 휴대폰 확인을 한 번 더 받는 식입니다. 이렇게 확인을 둘 이상 거는 것을 다중 인증이라고 부릅니다.

셋째는 끊는 일이 두 군데로 갈린다는 것입니다. 신원 제공자의 세션과 신뢰 당사자의 세션은 따로 삽니다. 신원 제공자에서 계정을 막아도 신뢰 당사자에 이미 만든 세션은 남습니다. 둘을 함께 끊으려면 로그아웃과 계정 삭제를 서로 알리는 절차를 더 붙여야 합니다.

넷째는 사생활입니다. 모든 로그인이 신원 제공자를 거칩니다. 그래서 신원 제공자는 사용자가 언제 어느 서비스에 들어갔는지를 전부 봅니다.

다른 분야의 페더레이션

페더레이션은 로그인 밖에서도 쓰는 낱말입니다. 분야마다 잇는 대상은 다릅니다. 모양은 같습니다. 독립된 시스템 여럿이 따로 운영됩니다. 그리고 약속한 규칙으로 서로 이어집니다.

아래 표의 GraphQL 은 클라이언트가 받고 싶은 필드를 골라 묻는 질의 언어입니다. GraphQL 서버는 주고받을 수 있는 필드 목록을 미리 정해 둡니다.

표의 마지막 줄 쿠버네티스는 컨테이너 여럿을 서버 묶음 위에 배치하고 관리하는 도구입니다. 회사는 이런 서버 묶음을 여럿 두기도 합니다.

분야 이어지는 것 이어서 얻는 것
로그인 조직마다 있는 계정 체계 계정 하나로 여러 조직의 서비스에 들어갑니다
데이터베이스 떨어진 데이터베이스 여럿 쿼리 하나로 여러 곳의 데이터를 읽습니다
GraphQL 팀마다 만든 GraphQL 서버 한 주소에서 합쳐진 필드 목록을 봅니다
소셜 네트워크 운영자가 다른 서버 여럿 다른 서버의 사용자와 글을 주고받습니다
쿠버네티스 쿠버네티스가 관리하는 서버 묶음 여럿 여러 묶음을 한 곳에서 다룹니다

이 문서가 다룬 것은 표 첫 줄의 로그인 페더레이션입니다. 나머지 줄은 각 분야의 항목이 받습니다.

관련 항목

페더레이션에 참여하는 역할

신원 제공자 · 신뢰 당사자 · 서비스 제공자 · 인가 서버 · 사용자 에이전트 · 보안 도메인

페더레이션에서 오가는 증표

단언 · SAML 단언 · ID 토큰 · JWT · 클레임 · 액세스 토큰 · 전자 서명

페더레이션을 실어 나르는 규격

SAML · OpenID Connect · OAuth 2.0 · WS-Federation · SCIM

페더레이션 위에서 사용자가 겪는 로그인 방식

싱글 사인온 · 소셜 로그인 · 싱글 로그아웃 · 세션 · 리다이렉트

페더레이션이 나누어 맡기는 보안 개념

인증 · 인가 · 인증과 인가 · 신원 관리 · 다중 인증 · 공개 키 · 개인 키

페더레이션을 노리는 공격

재전송 공격 · 토큰 탈취 · 피싱 · XML 서명 래핑 · 골든 SAML

같은 이름을 쓰는 다른 분야의 페더레이션

데이터 페더레이션 · GraphQL 페더레이션 · 연합우주 · ActivityPub · 쿠버네티스 페더레이션

다른 이름: federation · Federation · identity federation · federated identity · 아이덴티티 페더레이션 · 신원 페더레이션 · 연합 인증 · 신원 연합