Cloud Connector: 아키텍처

GitLab Cloud Connector은 여러 GitLab 배치, 인스턴스 및 셀에서 공통으로 액세스하는 방법입니다. 현재 Cloud Connector는 전용 서비스가 아니라 인증 및 통합과 관련한 방식을 표준화하는 API 및 코드의 모음입니다.

이 페이지는 Cloud Connector의 일반적인 아키텍처를 다루며, 주요 개발자 문서에 대한 보완 자료로 사용됩니다.

용어

Cloud Connector의 구성 요소 및 메커니즘을 설명할 때, 다음 용어를 사용합니다:

  • GitLab Rails: 주요 GitLab 애플리케이션
  • GitLab.com: GitLab Inc.가 운영하는 멀티 테넌트 GitLab SaaS 배포
  • Dedicated: GitLab Inc.가 운영하는 단일 테넌트 GitLab SaaS 배포
  • Self-managed: 고객이 운영하는 GitLab 인스턴스로, 사설 클라우드에 배포될 수 있음
  • GitLab instance: 위에서 언급된 모든 것
  • Backend service: GitLab 인스턴스가 호출하여 Cloud Connector 기능 중 하나인 기능을 제공하는 GitLab이 운영하는 웹 서비스. AI 게이트웨이가 그 예시 중 하나입니다.
  • CustomersDot: 고객이 GitLab 구독을 관리하는 데 사용하는 GitLab Customers Portal
  • OIDC: OpenID Connect, 식별 공급자 및 인증/인가를 구현하기 위한 오픈 표준. JWT 발행자는 JWT 검증기를 위해 키를 게시하기 위한 OIDC 호환 디스커버리 엔드포인트를 제공합니다.
  • JWT: JSON Web Token, 암호화된 토큰 형식의 식별 데이터를 인코딩하고 전송하기 위한 오픈 표준. 이 토큰은 GitLab 인스턴스 또는 사용자와 백엔드 서비스 간의 요청을 인가하는 데 사용됩니다. GitLab 인스턴스 또는 사용자 중 어느 쪽에든 범위를 설정할 수 있습니다.
  • JWT 발행자: JWT를 발행하기 위한 GitLab이 운영하는 웹 서비스. OAuth 사양에서는 이를 Authorization Server로 참조하며 해당 토큰을 유효성 검사하기 위한 공개 키를 제공하는 엔드포인트를 제공합니다. GitLab.com, CustomersDot 및 AI Gateway는 모두 JWT 발행자입니다.
  • JWT 검증기: GitLab 인스턴스가 JWT를 전달하는 백엔드 서비스의 요청을 유효성 검사하는 백엔드 서비스. OAuth 사양에서는 이를 Resource Server로 참조하며 JWT 발행자로부터 얻은 공개 키를 사용하여 유효성을 검사합니다. AI Gateway가 그 예시 중 하나입니다.
  • IJWT: 인스턴스 JSON Web Token으로, GitLab 인스턴스용으로 생성된 JWT
  • UJWT: 사용자 JSON Web Token으로, 인스턴스용 JWT보다 수명이 짧고 더 적은 권한이 있는 GitLab 사용자용으로 생성된 JWT
  • JWKS: JSON Web Key Set, JWT를 유효성 검사하기 위한 암호화 키를 인코딩하는 오픈 표준
  • Unit primitives: 권한/액세스 범위 제어에 사용되는 논리적 기능
  • Add-On: 번들로 묶여 함께 판매되는 단위 기본 요소의 그룹 예: code_suggestionsduo_chatDUO_PRO 추가 기능에 함께 묶여 판매되는 2개의 UP입니다.

해결해야 할 문제

대부분의 GitLab 기능은 배포 위치에 상관없이 GitLab 인스턴스에서 직접 제공될 수 있습니다. 그러나 일부 기능은 3rd party 업체와의 통합이 필요하거나 GitLab.com 외부에서 운영하기가 어려운 경우가 있습니다. 이는 자체 관리 및 전용 고객에게 문제가 될 수 있는데, 왜냐하면 이러한 기능에 쉽게 액세스할 수 없기 때문입니다.

Cloud Connector는 다음과 같은 방법으로 이 문제를 해결합니다:

  • GitLab Rails로부터 기능을 이동시켜 GitLab이 운영하는 서비스에 제공하여 고객이 수동으로 구성하고 운영하는 수고를 덜어줍니다.
  • Cloud Connector 기능의 단일 글로벌 진입점을 제공하여 cloud.gitlab.com에서 백엔드 서비스에 액세스합니다.
  • 인스턴스 라이선스 및 요금 청구 데이터를 액세스 권한에 연결하여 GitLab 인스턴스가 GitLab Inc.가 운영하는 백엔드 서비스에 호스팅된 기능을 사용할 수 있도록 합니다.

Cloud Connector 구성 요소

기술적으로, Cloud Connector는 다음과 같은 구성 요소로 구성됩니다:

  1. 글로벌 로드 밸런서. Cloudflare에서 cloud.gitlab.com에 호스트되며, 모든 AI와 같은 Cloud Connector 기능으로의 모든 트래픽은 이 호스트를 통해 들어가야 합니다. 로드 밸런서는 경로 접두어에 따라 라우팅 결정을 내립니다. 예를 들어
    1. 로드 밸런서는 /prefix를 백엔드 서비스에 매핑합니다.
    2. 클라이언트는 cloud.gitlab.com/prefix/path를 요청합니다.
    3. 로드 밸런서는 /prefix를 제거하고 /path를 백엔드 서비스로 라우팅합니다.
  2. IJWT 발행자로서 GitLab.com 및 CustomersDot을 선출. 우리는 GitLab Inc.만이 액세스할 수 있는 개인 키로 이러한 배포를 구성합니다. 이러한 키를 사용하여 GitLab Rails 인스턴스가 연결된 서비스 백엔드로의 요청을 위해 암호화된 IJWT를 발행합니다. 공개 검증 키는 OIDC 디스커버리 API 엔드포인트를 사용하여 게시됩니다.
  3. UJWT 발행자 및 검증기로서 AI Gateway를 선출. 앞서 언급한 IJWT 발행자와 유사하지만 사용자용 토큰을 발행하는 데 목적으로 사용됩니다. AI Gateway는 자체 검증기이므로 검증 키는 OIDC 디스커버리 API 엔드포인트에 게시되지 않습니다.
  4. Backend 서비스를 IJWT 검증기로 선출. 백엔드 서비스는 정기적으로 GitLab.com이나 CustomersDot과 동기화하여 요청에 첨부된 서비스 토큰의 서명을 유효성 검사하는 데 사용되는 공개 키를 얻습니다. 백엔드 서비스는 서명 유효성 및 토큰이 본문에 포함할 수 있는 요구사항에 따라 요청을 수락하거나 거부할 수 있습니다.
  5. 위의 내용과 통합하기 위한 API 프로그래밍. 우리는 GitLab Rails 애플리케이션과 백엔드 서비스 간의 통신을 구현하기 쉽도록 Ruby에서 필요한 인터페이스를 제공하려고 합니다. 이는 계속 변화하고 있으며, 이를 개선하기 위해 Cloud Connector 추상화 에픽에 이슈를 등록합니다.

다음 다이어그램은 이러한 구성 요소가 상호 작용하는 방식을 보여줍니다:

액세스 제어

백엔드 서비스로의 요청을 하는 경우 두 가지 수준의 액세스 제어가 있습니다.

  1. 인스턴스 액세스. 특정 SM/Dedicated 인스턴스에 대한 액세스 권한은 고객의 클라우드 라이선스 요금 상태에 대한 IJWT를 발급함으로써 이루어집니다. 이 토큰은 매일 CustomersDot에서 GitLab 인스턴스로 동기화되어 인스턴스의 로컬 데이터베이스에 저장됩니다. GitLab.com의 경우, 이 단계가 필요하지 않으며, 대신 각 요청에 대해 단명한 토큰을 발급합니다. 이러한 토큰은 JWT로 구현되며 발급자에 의해 암호적으로 서명됩니다.
  2. 사용자 액세스. 우리는 현재 모든 최종 사용자 요청이 해당 GitLab 인스턴스를 최소한 한 번 통과하도록 예상합니다. 특정 요청(예: 코드 완성)의 경우 사용자가 백엔드 서비스로 직접 요청을 보낼 수 있도록 백엔드 범위의 UJWT를 사용합니다. 이 토큰은 인스턴스 토큰보다 수명과 액세스가 제한적입니다. 사용자 토큰을 얻으려면 사용자는 먼저 해당 GitLab 인스턴스를 통해 토큰을 요청해야 합니다. 따라서 사용자 수준의 인증 및 권한 부여는 REST 또는 GraphQL API 요청과 마찬가지로 OAuth 또는 개인 액세스 토큰을 사용하여 처리됩니다.

인스턴스 액세스용으로 발급된 JWT에는 다음과 같은 클레임이 포함됩니다(무한하게 완성된 것은 아님, 변경될 수 있음):

  • aud: 청중(audience). 이것은 백엔드 서비스의 이름입니다(예: gitlab-ai-gateway).
  • sub: 제목(subject). 이것은 토큰이 발급된 GitLab 인스턴스의 UUID입니다(예: 8f6e4253-58ce-42b9-869c-97f5c2287ad2).
  • iss: 발급자 URL. https://gitlab.com 또는 https://customers.gitlab.com중 하나입니다.
  • exp: 토큰의 만료 시간(UNIX 타임스탬프). 현재는 GitLab.com의 경우 1시간이며, SM/Dedicated의 경우 3일입니다.
  • nbf: 이 토큰을 사용할 수 없는 시간(UNIX 타임스탬프), 이것은 토큰이 발급된 시간보다 5초 전으로 설정됩니다.
  • iat: 토큰이 발급된 시간(UNIX 타임스탬프), 이것은 토큰이 발급된 시간으로 설정됩니다.
  • jti: JWT ID, 무작위로 생성된 UUID로 설정됩니다(예: 0099dd6c-b66e-4787-8ae2-c451d86025ae).
  • gitlab_realm: Self-Managed 및 GitLab.com에서 요청을 구분하는 문자열입니다. 이것은 Customers Portal에 의해 발급된 경우 self-managed이며, GitLab.com에 의해 발급된 경우 saas입니다.
  • scopes: 이 토큰이 유효한 기능을 정의하는 액세스 스코프 목록입니다. 우리는 이를 GitLab 티어 및 추가 기능이 GitLab 티어 및 애드온으로 묶이는 결정과 같은 결정을 바탕으로 얻습니다.

사용자 액세스용으로 발급되는 JWT에는 다음과 같은 클레임이 포함됩니다(무한하게 완성된 것은 아님, 변경될 수 있음):

  • aud: 청중(audience). 이것은 백엔드 서비스의 이름입니다(gitlab-ai-gateway).
  • sub: 제목(subject). 이것은 토큰이 발급된 GitLab 사용자의 전역적으로 고유한 익명 사용자 ID 해시입니다(예: W2HPShrOch8RMah8ZWsjrXtAXo+stqKsNX0exQ1rsQQ=).
  • iss: 발급자(gitlab-ai-gateway).
  • exp: 토큰의 만료 시간(UNIX 타임스탬프). 현재는 발급된 시간으로부터 1시간입니다.
  • nbf: 이 토큰을 사용할 수 없는 시간(UNIX 타임스탬프), 이것은 토큰이 발급된 시간으로 설정됩니다.
  • iat: 토큰이 발급된 시간(UNIX 타임스탬프), 이것은 토큰이 발급된 시간으로 설정됩니다.
  • jti: JWT ID, 무작위로 생성된 UUID로 설정됩니다(예: 0099dd6c-b66e-4787-8ae2-c451d86025ae).
  • gitlab_realm: Self-Managed 및 GitLab.com에서 요청을 구분하는 문자열. self-managed 또는 saas 중 하나입니다.
  • scopes: 이 토큰이 유효한 기능을 정의하는 액세스 스코프 목록입니다. 우리는 이를 GitLab 티어 및 애드온과 같은 기능이 사용자 토큰을 통해 액세스할 수 있는지 여부를 결정하는 결정을 바탕으로 얻습니다.

JWKS(JWK Set)는 토큰 유효성 검사기가 토큰의 서명을 확인하는데 사용하는 공개 키를 포함합니다. 현재 모든 백엔드 서비스는 다음을 수행해야 합니다:

  • GitLab.com 및 CustomersDot에서 JWKS를 정기적으로 새로고침하여 키 회전이 서비스 중단 없이 쉽게 정기적으로 발생할 수 있도록 합니다.
  • 각 요청에 대해 JWT의 서명 검사 및 액세스 스코프 확인을 수행합니다.

다음 플로우 차트는 사용자가 클라우드 커넥터 기능(예: AI 챗봇과 대화)을 사용할 때 GitLab.com 및 Dedicated/self-managed 배포에서 무슨 일이 발생하는지 이해하는 데 도움이 될 것입니다.

GitLab.com

GitLab.com 배포는 특별한 신뢰를 즐기기 때문에 모든 클라우드 커넥터 기능에 대한 요청에 대해 자체 서명하고 IJWT를 생성할 수 있는 장점이 있어서 흐름을 크게 단순화할 수 있습니다:

sequenceDiagram autonumber participant U as User participant GL as GitLab.com participant SB as Backend service Note over U,SB: 최종 사용자 흐름 U->>GL: GitLab 인스턴스 인증 GL-->>U: PAT 또는 쿠키 U->>GL: 클라우드 커넥터 기능 사용 GL->>GL: 쿠키 또는 PAT로 인증/인가 수행 GL->>GL: 사용자가 기능 사용을 허용받았는지 확인 GL->>GL: 서명된 IJWT 생성 GL->>SB: IJWT를 사용한 기능 요청 SB->>GL: 공개 서명 키 검색(필요한 경우) GL-->>SB: JWKS SB->>SB: 키로 IJWT 유효성 확인 SB-->>GL: 기능 페이로드

GitLab Dedicated/Self-Managed

Dedicated 및 Self-Managed 인스턴스의 주요 문제는 신뢰 위임입니다: 우리는 개별 Self-Managed 인스턴스를 신뢰할 수 없으며 토큰을 발행할 수 없지만, CustomersDot가 GitLab Inc.에서 제어하고 있는 인스턴스가 자신을 정기적으로 인증하도록 허용함으로써 신뢰를 위임할 수 있습니다. GitLab Dedicated 인스턴스를 우리가 제어하지만, 클라우드 커넥터 관점에서 현재 이를 “self-managed”로 간주합니다.

GitLab.com과의 주된 차이점은 고객 인스턴스가 정기적으로 동기화하여 GitLab 백엔드 서비스에 액세스하는 데 필요한 데이터를 가져오고 유지하는 CustomersDot 액터의 추가입니다.

sequenceDiagram autonumber participant U as User participant GL as SM/Dedicated GitLab participant CD as CustomersDot participant SB as Backend service Note over GL,CD: 백그라운드: 액세스 데이터 동기화 loop cron job GL->>CD: 라이선스 키 전송 CD->>CD: 라이선스 키로 고객 구독 확인 CD->>CD: IJWT 생성 및 서명 CD-->>GL: Cloud Connector 액세스 데이터 + IJWT GL->>GL: DB에 액세스 데이터 + IJWT 저장 end Note over U,SB: 최종 사용자 흐름 U->>GL: GitLab 인스턴스 인증 GL-->>U: PAT 또는 쿠키 U->>GL: 클라우드 커넥터 기능 사용 GL->>GL: 쿠키 또는 PAT로 인증/인가 수행 GL->>GL: 사용자 허용 여부 확인 GL->>GL: DB에서 IJWT 로드 GL->>SB: IJWT를 사용한 기능 요청 SB->>CD: 공개 서명 키 검색(필요한 경우) CD-->>SB: JWKS SB->>SB: 키로 IJWT 유효성 확인 SB-->>GL: 기능 페이로드

클라우드 커넥터 액세스 데이터는 인스턴스의 로컬 데이터베이스에 저장된 구조화된 JSON 데이터입니다. IJWT 위에 완전히 출시된 서비스인지 또는 베타 단계인지를 포함한 추가 정보를 포함하며, 이 정보는 우리가 제어하지 않는 Self-Managed 인스턴스의 업그레이드 주기 때문에 변경될 수 있는 데이터를 동기화하고 일부 GitLab 기능에 원격으로 액세스하도록 허용하는 데 특히 유용합니다.

AI 게이트웨이

AI 게이트웨이는 사용자가 AI 게이트웨이와 직접 통신하도록 의도된 UJWT를 발급할 수 있습니다. 즉, 먼저 GitLab 인스턴스에 전화를 걸지 않아도 됩니다. 이는 IJWT를 사용하는 것에 추가됩니다. UJWT를 요청할 수 있는 것은 GitLab 인스턴스뿐이며, 이는 IJWT로 요청을 보내는 것으로 이루어집니다. AI 게이트웨이는 그런 다음 인스턴스가 사용자에게 전달할 수 있는 짧은 수명을 가진 UJWT를 반환합니다. 클라이언트는 이 UJWT를 사용하여 AI 게이트웨이와 직접 통신할 수 있습니다.

sequenceDiagram autonumber participant U as 사용자 participant GL as SM/Dedicated GitLab 또는 GitLab.com participant AIGW as AI 게이트웨이 U->>GL: GitLab 인스턴스로 승인 GL-->>U: PAT 또는 Cookie loop 초기 요청, UJWT가 만료된 경우에만 시간별로 수행됩니다. U->>GL: UJWT 요청 GL->>GL: Cookie 또는 PAT로 인증 수행 GL->>GL: 사용 권한이 있는지 확인 Note over GL: 단계 6은 SM/Dedicated GitLab와 GitLab.com에서 다릅니다 GL->>GL: SM/Dedicated GitLab: DB에서 IJWT 로드<br/>GitLab.com: 서명된 IJWT 생성 GL->>AIGW: IJWT로 UJWT 요청 AIGW->>AIGW: 키로 IJWT 유효성 검사 AIGW->>AIGW: UJWT 생성 AIGW-->>GL: UJWT GL-->>U: UJWT end U->>AIGW: UJWT로 특징 요청 AIGW->>U: 특징 페이로드

참조