클라우드 커넥터

GitLab 클라우드 커넥터는 여러 GitLab 배포, 인스턴스 및 셀에서 공통으로 사용되는 서비스에 액세스하는 방법입니다. 현재 클라우드 커넥터는 전용 서비스가 아니라 오히려 클라우드 기반 서비스를 GitLab 인스턴스와 통합할 때 인증 및 기타 항목에 대한 접근 방식을 표준화하는 API 및 코드의 모음입니다. 이 페이지의 목표는 클라우드 커넥터를 사용하여 GitLab Rails를 서비스에 연결하는 방법을 설명하는 것입니다.

클라우드 커넥터에 대한 자세한 내용은 아키텍처 페이지를 참조하세요. 또한, 문서 전체에서 사용되는 용어 디렉터리은 여기를 참조하세요.

자습서: 클라우드 커넥터를 사용하여 기능 연결

GitLab Rails 인스턴스는 클라우드 커넥터 서비스 액세스 토큰을 사용하여 백엔드 서비스에 액세스합니다. 이 토큰은 GitLab Rails 애플리케이션에서 제공되며 해당 백엔드 서비스 및 해당 서비스의 기능에 대한 정보를 보유하고 있습니다.

다음 섹션에서는 클라우드 커넥터를 통해 기존에 구축되거나 새로이 구축된 백엔드 서비스의 기능을 노출하는 데 필요한 단계를 다룹니다.

기존 서비스에 기능 연결

기존 백엔드 서비스의 기능을 클라우드 커넥터에 연결하려면:

  1. GitLab Rails 단계를 완료하세요.
  2. CustomersDot 단계를 완료하세요.
  3. 백엔드 서비스 단계를 완료하세요.

GitLab Rails

  1. CloudConnector::AvailableServices.find_by_name(:feature_name).access_token(user_or_namespace)를 호출하고 이 토큰을 Authorization HTTP 헤더 필드에 포함하세요.

GitLab.com에서는 제공된 리소스에 따라 스코프가 달라지는 토큰을 자체 발급합니다.

  • 사용자의 경우: 스코프는 사용자의 시트 할당에 기반합니다.
  • 네임스페이스의 경우: 스코프는 해당 네임스페이스의 구매 애드온에 기반합니다.
  • 기능이 free_access?인 경우(애드온 구매가 필요하지 않은 경우): 토큰에는 해당 기능에 대한 모든 사용 가능한 스코프가 포함됩니다.

Self-Managed형의 경우 항상 ::CloudConnector::ServiceAccessToken 인스턴스 토큰을 반환합니다.

백엔드 서비스는 이 토큰 및 해당 토큰이 전달하는 스코프를 수신할 때 확인해야 합니다. 사용 사례에 따라 토큰에 추가 클레임을 포함해야 하는 경우 extra_claims 인수로 이를 전달할 수 있습니다. 여기에 전달된 스코프 및 다른 클레임은 GitLab.com에서 자체 발급된 토큰에만 포함됩니다. Self-Managed형 인스턴스에 대한 사용자 정의 클레임 처리 방법을 보려면 CustomersDot을 참조하세요.

  1. 요청이 백엔드 서비스로 필요한 헤더를 보냈는지 확인하세요.

    이러한 헤더는 다음과 같습니다:

    • X-Gitlab-Instance-Id: 전역적으로 고유한 인스턴스 ID 문자열.
    • X-Gitlab-Global-User-Id: 전역적으로 고유한 익명 사용자 ID 문자열.
    • X-Gitlab-Realm: saas, Self-Managed 중 하나.
    • Authorization: 단계 1의 access_token 메서드에서 얻은 JWT의 Bearer 토큰으로 인코딩된 Base64.

    이러한 헤더 중 일부는 API::Helpers::CloudConnector#cloud_connector_headers 메서드의 결과를 페이로드에 Merge함으로써 주입할 수 있습니다.

다음 예제는 :new_feature라는 기능에 대한 요청입니다. 여기서는 백엔드 서비스가 foo로 호출되고 이미 https://cloud.gitlab.com/foo에서 도달 가능하다고 가정합니다. 또한 백엔드 서비스가 /new_feature_endpoint 엔드포인트를 사용하여 기능을 노출한다고 가정합니다. 이를 통해 클라이언트는 https://cloud.gitlab.com/foo/new_feature_endpoint에서 기능에 액세스할 수 있습니다.

include API::Helpers::CloudConnector

new_feature = ::CloudConnector::AvailableServices.find_by_name(:new_feature)

# (Optional) 필요한 경우 무료 액세스 케이스를 별도로 처리하세요
if new_feature.free_access?
  # ...
  return
end

# 사용자에게 할당된 시트, 애드온 구매 여부에 따라 해당 기능을 사용할 수 있는지 확인하세요
return unauthorized! unless new_feature.allowed_for?(current_user)

# 토큰 획득
token = new_feature.access_token(current_user)

Gitlab::HTTP.post(
  "https://cloud.gitlab.com/foo/new_feature_endpoint",
  headers: {
      'Authorization' => "Bearer #{token}",
    }.merge(cloud_connector_headers(current_user))
)
note
access_token에 전달하는 인수(user 또는 namespace, extra_claims)는 GitLab.com에서 발급된 토큰에만 적용됩니다. Self-Managed형 GitLab 인스턴스에서는 토큰이 데이터베이스에서 그대로 읽히고 결코 수정되지 않습니다.

CustomersDot

이 단계는 Self-Managed형 및 GitLab Dedicated 배포용으로 기능이 작동하도록 필요합니다.

CustomersDot은 인스턴스가 어떤 액세스 권한을 가지고 있는지에 대한 권한을 관리합니다. 이 정보는 인스턴스의 서비스 토큰에 저장됩니다.

범위에 바인드된 새 기능을 추가하려면:

  1. cloud_connector.yml을 업데이트하세요.
    • 서비스에 새로운 서비스를 추가하여 시작합니다. 서비스 토큰에 범위로 포함될 기능 이름부터 시작합니다.

    백엔드는 대상 백엔드 서비스이며 토큰 수신자가 될 것입니다.

    service_start_time은 해당 기능에 대한 결제가 필요한 마감일입니다.

    min_gitlab_version은 인스턴스가 액세스를 받기 위해 필요한 최소한의 GitLab 버전입니다(마감일 전).

    min_gitlab_version_for_beta은 인스턴스가 액세스를 받기 위해 필요한 최소한의 GitLab 베타 버전입니다(마감일 전).

    bundled_with는 서비스 액세스를 얻기 위해 필요한 애드온 번들입니다.

예:

defaults: &defaults
  services:
    new_feature_scope:
      service_start_time: 2024-02-15 00:00:00 UTC
      min_gitlab_version: '16.8'
      bundled_with: 'duo_pro'
  1. 선택 사항: 토큰을 사용하는 백엔드 서비스가 추가 클레임이 필요한 경우 현재 우리는 그에 대한 인터페이스가 없으므로 #g_cloud_connector(Slack, 내부 전용)에 문의하세요.

백엔드 서비스

GitLab Rails는 Self-Managed형 및 전용 인스턴스에서 사용할 수 없는 기능을 제공하기 위해 백엔드 서비스를 호출합니다. GitLab Rails에서 이를 호출할 수 있도록하려면 엔드포인트를 노출해야 합니다. 백엔드 서비스는 Authorization 헤더에서 GitLab Rails가 보낸 각 JWT를 확인해야 합니다.

이 섹션의 예제는 AI GatewayFastAPI 프레임워크를 기반으로 합니다.

  1. 서비스에 엔드포인트를 생성하세요.

    @router.post("/new_feature_endpoint")
    async def feature_name(
        request: Request,
        payload: CompletionRequest
    ):
        return Response(
         id="id",
         created=int(time()),
         extra="Feature"
     )
    
  2. 엔드포인트가 호출자가 올바른 스코프 액세스를 갖고 있는지 확인하세요:

    @router.post("/new_feature_endpoint")
    @requires("new_feature_scope")
    async def feature_name(
    ...
    

새로운 백엔드 서비스를 클라우드 커넥터에 연결

이미 클라우드 커넥터 기능으로 액세스할 수 없는 새로운 백엔드 서비스를 통합하려면:

  1. JWT 유효성 검사 설정.
  2. cloud.gitlab.com에서 사용 가능하게 만드세요.

JWT 검증 설정

백엔드 서비스 섹션에 언급된대로 이미 Cloud Connector를 사용하는 서비스는 각 서비스가 GitLab 인스턴스에서 보낸 JWT를 확인해야 합니다.

이를 수행하려면 백엔드 서비스는 다음을 수행해야 합니다.

  1. JSON 웹 키 세트(JWKS)를 유지.
  2. 이 세트에 있는 키로 JWT를 검증하세요(#validate-jwts-with-jwks).

이러한 메커니즘에 대한 자세한 설명은 아키텍처: 액세스 제어를 참조하세요.

JWKS 및 JWT 인증을 처리하는 기존 소프트웨어 라이브러리를 사용하는 것을 강력히 권장합니다. 예시로는 다음이 있습니다.

토큰 검증을 위해 JWKS 유지

JWT는 토큰 관할자에 의해 암호적으로 서명되어 처음으로 발급됩니다. 그런 다음 GitLab 인스턴스는 요청에 대해 JWT를 첨부합니다.

JWT 서비스 액세스 토큰을 유효성 검사하려면 백엔드 서비스는 먼저 해당 토큰를 서명하는 개인 키에 해당하는 공개 유효성 검사 키가 들어 있는 JWKS를 가져와야 합니다. GitLab.com 및 CustomersDot은 모두 토큰을 발행하므로 백엔드 서비스는 두 곳에서 JWKS를 가져와야 합니다.

JWKS를 가져오려면 GitLab.com 및 CustomersDot에 의해 노출된 OIDC 디스커버리 엔드포인트를 사용하세요. 이러한 토큰 관할자 각각에 대해:

  1. GET /.well-known/openid-configuration

    예시 응답:

    {
      "issuer": "https://customers.gitlab.com/",
      "jwks_uri": "https://customers.gitlab.com/oauth/discovery/keys",
      "id_token_signing_alg_values_supported": [
        "RS256"
      ]
    }
    
  2. GET <jwks_uri>

    예시 응답:

    {
      "keys": [
        {
          "kty": "RSA",
          "n": "sGy_cbsSmZ_Y4XV80eK_ICmz46XkyWVf6O667-mhDcN5FcSfPW7gqhyn7s052fWrZYmJJZ4PPyh6ZzZ_gZAaQM7Oe2VrpbFdCeJW0duR51MZj52FwShLfi-NOBz2GH9XuUsRBKnXt7wwKQTabH4WW7XL23Hi0eDjc9dyQmsr2-AbH05yVsrgvEYSsWiCGEgobPgNc51DwBoIcsJ-kFN591aO_qAkbpf1j7yAuAVG7TUxaditQhyZKkourPXXyx1R-u0Lx9UJyAV8ySqFxq3XDE_pg6ZuJ7M0zS0XnGI82g3Js5zAughrQyJMhKd8j5c8UfSGxhRBQh58QNl3UwoMjQ",
          "e": "AQAB",
          "kid": "ZoObkdsnUfqW_C_EfXp9DM6LUdzl0R-eXj6Hrb2lrNU",
          "use": "sig",
          "alg": "RS256"
        }
      ]
    }
    
  3. 응답을 캐시합니다. 캐시의 유효 기간은 하루입니다.

이 방식으로 얻은 키는 해당 토큰 관할자가 발행한 JWT를 유효성 검사하는 데 사용할 수 있습니다. 이 작업은 사용하는 프로그래밍 언어와 라이브러리에 따라 다르며, 일반적인 지침은 JSON 웹 키 세트 찾기에서 찾을 수 있습니다. 백엔드 서비스는 두 토큰 관할자로부터의 응답을 단일 캐시된 결과 집합으로 Merge할 수 있습니다.

JWKS로 JWT 유효성 검사

JWT를 유효성 검사하려면:

  1. HTTP Authorization 헤더에서 토큰 문자열을 읽습니다.
  2. 앞서 얻은 JWKS 및 JWT 라이브러리 객체를 사용하여 유효성을 확인하세요.

토큰을 유효성 검사할 때 다음 사항을 확인하세요.

  1. 토큰 서명이 올바른지 확인하세요.
  2. aud 클레임이 백엔드 서비스와 동일하거나 해당하는지 확인하세요(이 필드는 문자열 또는 배열일 수 있음).
  3. iss 클레임이 해당 키의 발급자 URL과 일치하는지 확인하세요.
  4. scopes 클레임이 요청된 엔드포인트에서 노출하는 기능을 포함하는지 확인하세요(자세한 내용은 백엔드 서비스를 참조).

새로운 Cloud Connector 경로 추가

모든 Cloud Connector 기능은 경로 접두어를 기반으로 요청을 백엔드 서비스로 라우팅하는 글로벌 로드 밸런서인 cloud.gitlab.com을 통해 액세스해야 합니다. 예를 들어, AI 기능은 cloud.gitlab.com/ai/<AI-specific-path>에서 요청해야 합니다. 그런 다음 로드 밸런서는 <AI-specific-path>를 AI 게이트웨이로 라우팅합니다.

새로운 백엔드 서비스를 Cloud Connector에 연결하려면 새로운 경로 접두어를 요청하여 서비스로 라우팅해야 합니다. 예를 들어, foo-service를 연결하는 경우 cloud.gitlab.com/foofoo-service로 라우팅하는 새 경로를 추가해야 합니다.

새로운 경로를 추가하려면 프로덕션 인프라 구성에 액세스해야 합니다. 새 경로가 필요한 경우 gitlab-org/gitlab 이슈 트래커에서 이슈를 열고 Cloud Connector 그룹에 할당하세요.

테스트

AI 게이트웨이를 백엔드 서비스로 사용하는 end-to-end 통합 설정 예시는 여기에서 찾을 수 있습니다.