mirror of
https://github.com/crewAIInc/crewAI.git
synced 2026-07-03 06:08:15 +00:00
274 lines
17 KiB
Plaintext
274 lines
17 KiB
Plaintext
---
|
|
title: GCP Workload Identity Federation
|
|
description: 로테이션 인식, 자격 증명 없는 시크릿 액세스를 위해 Workload Identity Federation을 통해 Google Cloud Secret Manager를 구성합니다
|
|
sidebarTitle: Workload Identity 사용
|
|
icon: "id-badge"
|
|
---
|
|
|
|
## 개요
|
|
|
|
이 가이드는 **Workload Identity Federation**을 사용하여 Google Cloud Secret Manager를 시크릿 공급자로 구성합니다: CrewAI Platform이 단기 OIDC 토큰을 발급하고, Security Token Service를 통해 이를 Google Cloud 자격 증명과 교환하여 시크릿을 읽습니다 — 장기 서비스 계정 키를 어디에도 저장하지 않습니다.
|
|
|
|
<Note>
|
|
**이 경로를 선택하는 이유:** 시크릿은 자동화 실행 시점에 해석되므로, **로테이션된 값이 재배포 없이 다음 kickoff에 전파됩니다**. 정적 자격 증명만 필요하다면 더 간단한 [GCP — 서비스 계정 키](/ko/enterprise/features/secrets-manager/gcp) 가이드를 참조하세요.
|
|
</Note>
|
|
|
|
### 런타임 동작 방식
|
|
|
|
1. 배포 워커가 CrewAI Platform에서 새 OIDC JWT를 요청합니다.
|
|
2. 워커가 아래에서 설정한 Workload Identity Pool Provider를 참조하여 [Security Token Service](https://cloud.google.com/iam/docs/reference/sts/rest)를 통해 JWT를 federated Google 자격 증명과 교환합니다.
|
|
3. 워커가 federated 자격 증명을 직접 사용하여 시크릿을 읽기 위해 `secretmanager.googleapis.com:accessSecretVersion`을 호출합니다(federated 주체가 `roles/secretmanager.secretAccessor`를 보유함 — 4단계 참조).
|
|
4. 가져온 값이 해당 자동화 kickoff의 환경 변수 값으로 주입됩니다.
|
|
|
|
OIDC 주체 토큰은 매 kickoff마다 재발급을 피하기 위해 약 1시간 동안 캐시됩니다. 시크릿 값은 OIDC 캐시 상태와 관계없이 매 kickoff마다 새로 가져오며, 이것이 이 경로를 로테이션 인식으로 만드는 요소입니다.
|
|
|
|
## 사전 준비 사항
|
|
|
|
<Note>
|
|
시작하기 전에 다음을 준비하세요:
|
|
|
|
- 자동화 파드 이미지에 CrewAI 런타임 버전 `1.14.5` 이상이 포함되어야 합니다.
|
|
- **Secret Manager API**, **Security Token Service API**, **IAM Credentials API**가 활성화된 Google Cloud 프로젝트. 콘솔에서 또는 다음을 통해 활성화하세요:
|
|
|
|
```bash
|
|
gcloud services enable secretmanager.googleapis.com sts.googleapis.com iamcredentials.googleapis.com \
|
|
--project=<YOUR_PROJECT_ID>
|
|
```
|
|
|
|
- Workload Identity Pool, IAM 역할, 서비스 계정, (필요한 경우) 시크릿을 생성할 프로젝트 권한.
|
|
- 사용자가 `workload_identity_configs: manage` 및 `secret_providers: manage` 권한을 가진 CrewAI Platform 조직. [권한 (RBAC)](/ko/enterprise/features/secrets-manager/usage#permissions-rbac)을 참조하세요.
|
|
- **CrewAI Platform 설치가 Google Cloud에서 HTTPS를 통해 접근 가능해야 합니다.** GCP STS가 토큰 검증 중 OIDC 디스커버리 문서와 JWKS를 가져올 수 있어야 합니다. 플랫폼 관리자에게 호스트가 인터넷에서 접근 가능한지 확인하세요.
|
|
</Note>
|
|
|
|
## 1단계 — CrewAI Platform OIDC 발급자 URL 찾기
|
|
|
|
CrewAI Platform 설치는 `https://<your-platform-host>/.well-known/openid-configuration`에서 OpenID Connect 디스커버리 문서를 게시합니다. 여기의 `issuer` 필드는 Google이 신뢰할 수 있는 OIDC 공급자로 등록할 URL입니다.
|
|
|
|
브라우저에서 URL을 엽니다:
|
|
|
|
```
|
|
https://<your-platform-host>/.well-known/openid-configuration
|
|
```
|
|
|
|
다음을 포함하는 JSON이 보일 것입니다:
|
|
|
|
```json
|
|
{
|
|
"issuer": "https://<your-platform-host>",
|
|
"jwks_uri": "https://<your-platform-host>/oauth2/jwks",
|
|
...
|
|
}
|
|
```
|
|
|
|
`issuer`의 정확한 값을 기록하세요 — 3단계에서 사용합니다.
|
|
|
|
<Tip>
|
|
URL이 404 또는 503을 반환하면 플랫폼 관리자에게 문의하세요. OIDC 발급자는 설치 시점에 개인 서명 키가 구성되어 있어야 합니다. `OIDC_PRIVATE_KEY` 및 `OIDC_ISSUER` 구성에 대한 내용은 플랫폼 설치 가이드를 참조하세요.
|
|
</Tip>
|
|
|
|
## 2단계 — Workload Identity Pool 생성
|
|
|
|
Workload Identity Pool은 신뢰할 수 있는 외부 ID를 위한 Google Cloud 측 컨테이너입니다. 이 풀 내부에 CrewAI Platform을 공급자로 등록합니다.
|
|
|
|
```bash
|
|
gcloud iam workload-identity-pools create crewai-pool \
|
|
--project=<YOUR_PROJECT_ID> \
|
|
--location=global \
|
|
--display-name="CrewAI Platform"
|
|
```
|
|
|
|
또는 [Workload Identity Pools 콘솔](https://console.cloud.google.com/iam-admin/workload-identity-pools)에서 **Create Pool**을 클릭합니다.
|
|
|
|
{/* SCREENSHOT: GCP "Create Workload Identity Pool" form with name "crewai-pool" → /images/secrets-manager/gcp-wi/01-create-pool.png */}
|
|
|
|
## 3단계 — CrewAI Platform을 풀에 OIDC 공급자로 추가
|
|
|
|
```bash
|
|
gcloud iam workload-identity-pools providers create-oidc crewai-provider \
|
|
--project=<YOUR_PROJECT_ID> \
|
|
--location=global \
|
|
--workload-identity-pool=crewai-pool \
|
|
--display-name="CrewAI Platform OIDC" \
|
|
--issuer-uri="https://<your-platform-host>" \
|
|
--attribute-mapping="google.subject=assertion.sub,attribute.organization=assertion.organization_id" \
|
|
--attribute-condition="assertion.organization_id != ''"
|
|
```
|
|
|
|
`--attribute-mapping`은 JWT 클레임을 Google 속성으로 매핑하는 방법을 Google에 알려줍니다:
|
|
- `google.subject`는 주체 식별자입니다 — JWT의 `sub` 클레임에 매핑하며, CrewAI Platform은 이를 `organization:<uuid>`로 설정합니다.
|
|
- `attribute.organization`은 사용자 정의 속성입니다 — JWT의 `organization_id` 클레임에 매핑하여 나중에 IAM 바인딩에서 참조할 수 있습니다.
|
|
|
|
`--attribute-condition`은 `organization_id` 클레임이 없는 토큰을 거부하는 심층 방어 검사입니다.
|
|
|
|
**Provider 리소스 이름**을 가져옵니다(audience 및 IAM 바인딩에 필요):
|
|
|
|
```bash
|
|
gcloud iam workload-identity-pools providers describe crewai-provider \
|
|
--project=<YOUR_PROJECT_ID> \
|
|
--location=global \
|
|
--workload-identity-pool=crewai-pool \
|
|
--format="value(name)"
|
|
```
|
|
|
|
출력은 다음과 같습니다:
|
|
|
|
```
|
|
projects/<PROJECT_NUMBER>/locations/global/workloadIdentityPools/crewai-pool/providers/crewai-provider
|
|
```
|
|
|
|
이것이 6단계에서 CrewAI Platform의 **Workload Identity Provider** 값입니다. CrewAI Platform은 토큰을 발급할 때 OIDC audience를 `//iam.googleapis.com/<this-resource-name>`으로 자동으로 계산합니다.
|
|
|
|
{/* SCREENSHOT: "Add provider to pool" form with OIDC selected, issuer URI, audience defaults, attribute mapping → /images/secrets-manager/gcp-wi/02-add-oidc-provider.png */}
|
|
|
|
## 4단계 — Federated 주체에 Secret Manager 액세스 부여
|
|
|
|
프로젝트 범위에서 두 Secret Manager 역할을 모두 federated 주체에 바인딩합니다 — 한 역할은 환경 변수 폼의 Secret Name 자동 완성을 활성화하고, 다른 역할은 자동화 kickoff 시점에 시크릿 값을 읽을 수 있게 합니다. 기능이 처음부터 끝까지 작동하려면 두 역할 모두 필요합니다.
|
|
|
|
```bash
|
|
PRINCIPAL_SET="principalSet://iam.googleapis.com/projects/<PROJECT_NUMBER>/locations/global/workloadIdentityPools/crewai-pool/attribute.organization/<YOUR_CREWAI_ORG_UUID>"
|
|
|
|
# Secret Name 자동 완성에 필요 (secretmanager.secrets.list 호출)
|
|
gcloud projects add-iam-policy-binding <YOUR_PROJECT_ID> \
|
|
--member="$PRINCIPAL_SET" \
|
|
--role="roles/secretmanager.viewer"
|
|
|
|
# kickoff 시점에 시크릿 값을 읽는 데 필요
|
|
gcloud projects add-iam-policy-binding <YOUR_PROJECT_ID> \
|
|
--member="$PRINCIPAL_SET" \
|
|
--role="roles/secretmanager.secretAccessor"
|
|
```
|
|
|
|
`<PROJECT_NUMBER>`를 숫자 프로젝트 번호(`gcloud projects describe <YOUR_PROJECT_ID> --format='value(projectNumber)'`)로, `<YOUR_CREWAI_ORG_UUID>`를 시크릿을 읽을 수 있도록 허용할 CrewAI Platform 조직의 UUID로 교체합니다. 조직 UUID는 플랫폼 UI의 조직 설정 페이지나 API를 통해 찾을 수 있습니다. 이는 federation을 특정 CrewAI 조직으로 범위 지정합니다 — 해당 조직의 자동화를 위해 발급된 토큰만 수락됩니다.
|
|
|
|
또는 Google Cloud 콘솔을 통해:
|
|
|
|
1. 프로젝트의 **IAM & Admin** → **IAM**을 엽니다.
|
|
2. **GRANT ACCESS**를 클릭합니다.
|
|
3. **New principals:** 전체 `principalSet://...attribute.organization/<YOUR_CREWAI_ORG_UUID>` 문자열을 붙여 넣습니다.
|
|
4. 역할 **Secret Manager Viewer** (`roles/secretmanager.viewer`)를 할당합니다.
|
|
5. **SAVE**를 클릭합니다.
|
|
6. **GRANT ACCESS**를 다시 클릭하고 **Secret Manager Secret Accessor** (`roles/secretmanager.secretAccessor`) 역할로 반복합니다.
|
|
|
|
<Tip>
|
|
**조직별 격리.** `principalSet://...attribute.organization/<UUID>` 패턴은 특정 조직의 토큰에 대한 액세스를 제한합니다. 하나의 Google Cloud 프로젝트를 여러 CrewAI 조직이 공유하는 경우, 각 조직에 대해 올바른 UUID로 두 바인딩을 모두 반복하거나 — 격리가 필요하지 않으면 덜 제한적인 attribute condition을 사용하세요.
|
|
</Tip>
|
|
|
|
<Tip>
|
|
**시크릿별로 `secretAccessor` 범위 지정 (선택 사항).** `roles/secretmanager.secretAccessor`를 프로젝트 전체로 부여하고 싶지 않으면, 위의 두 번째 바인딩을 생략하고 대신 시크릿별로 바인딩합니다:
|
|
|
|
```bash
|
|
gcloud secrets add-iam-policy-binding <SECRET_NAME> \
|
|
--member="$PRINCIPAL_SET" \
|
|
--role="roles/secretmanager.secretAccessor" \
|
|
--project=<YOUR_PROJECT_ID>
|
|
```
|
|
|
|
어느 쪽이든 `roles/secretmanager.viewer`는 프로젝트 범위로 유지하세요 — `secretmanager.secrets.list`(자동 완성이 의존)는 시크릿별로 부여할 수 없습니다.
|
|
</Tip>
|
|
|
|
## 5단계 — GCP에 최소 하나의 시크릿 생성
|
|
|
|
테스트할 시크릿이 아직 없다면 `gcloud` CLI를 통해 하나 만듭니다:
|
|
|
|
```bash
|
|
echo -n "hello from gcp" | gcloud secrets create crewai-test-keyword \
|
|
--data-file=- \
|
|
--project=<YOUR_PROJECT_ID> \
|
|
--replication-policy=automatic
|
|
```
|
|
|
|
또는 [Secret Manager 콘솔](https://console.cloud.google.com/security/secret-manager)을 통해:
|
|
|
|
1. GCP 프로젝트에서 **Secret Manager**를 엽니다.
|
|
2. **+ CREATE SECRET**을 클릭합니다.
|
|
3. **Name:** `crewai-test-keyword`. **Secret value:** 값을 붙여 넣습니다.
|
|
4. **CREATE SECRET**을 클릭합니다.
|
|
|
|
## 6단계 — CrewAI Platform에 Workload Identity 구성 추가
|
|
|
|
CrewAI Platform에서 **Settings** → **Workload Identity**로 이동하여 **Add Workload Identity Config**를 클릭합니다.
|
|
|
|
폼을 작성합니다:
|
|
|
|
- **Name:** 설명적인 이름(예: `gcp-prod`).
|
|
- **Cloud Provider:** `GCP`.
|
|
- **Workload Identity Provider:** 3단계의 provider 리소스 이름(예: `projects/<PROJECT_NUMBER>/locations/global/workloadIdentityPools/crewai-pool/providers/crewai-provider`).
|
|
- (선택) GCP 기반 시크릿 자격 증명을 생성할 때 이것이 기본 WI 구성으로 선택되길 원한다면 **Default Configuration**을 토글합니다.
|
|
|
|
**Create**를 클릭합니다.
|
|
|
|
{/* SCREENSHOT: "Add Workload Identity Config" form with GCP and provider resource name → /images/secrets-manager/gcp-wi/03-amp-add-wi-config-gcp.png */}
|
|
{/* SCREENSHOT: Workload Identity list showing both AWS and GCP rows → /images/secrets-manager/gcp-wi/04-amp-wi-list-with-gcp.png */}
|
|
|
|
## 7단계 — WI 구성에 바인딩된 Secret Provider Credential 추가
|
|
|
|
**Settings** → **Secret Provider Credentials**로 이동하여 **Add Credential**을 클릭합니다.
|
|
|
|
폼을 작성합니다:
|
|
|
|
- **Name:** 설명적인 이름(예: `gcp-prod-wi`).
|
|
- **Provider:** `Google Cloud Secret Manager`.
|
|
- **Authentication Method:** `Workload Identity`.
|
|
- **Workload Identity Configuration:** 6단계에서 만든 구성을 선택합니다.
|
|
- **Project ID:** GCP 프로젝트 ID(시크릿을 소유한 동일한 프로젝트).
|
|
- (선택) **Set as default credential for this provider**를 체크합니다.
|
|
|
|
Workload Identity 아래에서는 폼이 **Project ID**만 요청합니다 — **Service Account JSON** 필드는 이 경로에 적용되지 않으므로 의도적으로 숨겨집니다. federated ID는 연결된 WI 구성에서 가져옵니다.
|
|
|
|
**Create**를 클릭합니다.
|
|
|
|
{/* SCREENSHOT: "Add Secret Provider Credential" form with GCP + Workload Identity + WI config dropdown → /images/secrets-manager/gcp-wi/05-amp-add-credential-gcp-wi.png */}
|
|
|
|
## 8단계 — 연결 테스트
|
|
|
|
자격 증명을 저장한 후 **Test Connection**을 클릭합니다. Workload Identity 자격 증명의 경우 OIDC 핸드셰이크를 검증합니다: CrewAI Platform이 JWT를 발급하고, Security Token Service를 통해 federated Google 액세스 토큰과 교환합니다. 녹색 결과는 federation 바인딩이 정상임을 의미합니다.
|
|
|
|
성공적인 Test Connection은 Workload Identity Pool, OIDC 공급자, attribute mapping, attribute condition이 모두 올바르게 연결되었음을 증명합니다. Secret Manager IAM이 올바르다는 것을 증명하지는 **않습니다** — `secretmanager.secrets.list`와 `secretmanager.versions.access`는 Secret Name 자동 완성이 로드되거나 환경 변수가 kickoff에 해석될 때 별도로 수행됩니다. 핸드셰이크 실패 모드는 [문제 해결](#troubleshooting)을 참조하세요.
|
|
|
|
## 9단계 — 환경 변수에서 시크릿 참조
|
|
|
|
다른 Secrets Manager 기반 환경 변수와 마찬가지로 자동화에서 시크릿을 참조합니다. 폼 필드와 동작은 [Secrets Manager 사용하기](/ko/enterprise/features/secrets-manager/usage#referencing-secrets-in-environment-variables)를 참조하세요.
|
|
|
|
## 10단계 — 로테이션 확인
|
|
|
|
배포가 실행 중인 상태에서 새 버전을 추가하여 GCP의 시크릿을 로테이션합니다(Secret Manager는 기본적으로 항상 최신 활성화 버전을 읽음):
|
|
|
|
```bash
|
|
echo -n "rotated value" | gcloud secrets versions add crewai-test-keyword \
|
|
--data-file=- \
|
|
--project=<YOUR_PROJECT_ID>
|
|
```
|
|
|
|
새 자동화 kickoff를 트리거합니다. kickoff의 환경은 `"rotated value"`를 볼 것입니다 — 재배포, 워커 재시작, TTL 대기 없음.
|
|
|
|
워커 로그에서 확인하려면 다음을 찾으세요:
|
|
|
|
```
|
|
Workload identity config '<id>' (gcp): N secret(s) resolved
|
|
```
|
|
|
|
이 줄은 모든 kickoff에 나타나며 GCP에 대한 새로운 `accessSecretVersion` 호출을 의미합니다.
|
|
|
|
## 문제 해결
|
|
|
|
| 증상 | 가능한 원인 |
|
|
|---|---|
|
|
| Test Connection이 핸드셰이크 오류로 실패함 | STS 토큰 교환이 거부되었습니다. Workload Identity Pool이 존재하는지, OIDC provider의 발급자가 플랫폼의 `issuer` 값과 일치하는지, attribute condition이 JWT의 클레임을 수락하는지 확인하세요. 플랫폼의 OIDC 디스커버리 URL이 공용 인터넷을 통해 GCP에서 접근 가능한지 확인하세요. |
|
|
| `Could not refresh access token: invalid_target` | audience 클레임이 Workload Identity Provider의 예상 audience와 일치하지 않습니다. CrewAI Platform이 audience를 자동으로 설정합니다. 사용자 정의한 경우 `//iam.googleapis.com/<provider-resource-name>`과 일치하는지 확인하세요. |
|
|
| `Failed to fetch JWKS from issuer` | GCP STS가 CrewAI Platform 호스트에 도달할 수 없습니다. 호스트가 인터넷에서 접근 가능하고 `/.well-known/openid-configuration`이 200을 반환하는지 확인하세요. |
|
|
| `Attribute condition rejected token` | OIDC provider의 attribute condition(3단계)이 `organization_id`를 요구합니다. CrewAI Platform은 항상 이 클레임을 설정하므로 보통 잘못 구성된 풀/공급자를 의미합니다. provider의 attribute condition을 다시 확인하세요. |
|
|
| Secret Name 자동 완성에 `PERMISSION_DENIED: secretmanager.secrets.list` 표시 | federated 주체에 프로젝트 범위의 `roles/secretmanager.viewer`가 없습니다. `secretmanager.secrets.list` 권한은 프로젝트 범위에서만 가능하며 시크릿별로 부여할 수 없습니다. 4단계를 참조하세요. |
|
|
| Test Connection은 통과하지만 kickoff가 시크릿을 해석하지 못함 | WI 바인딩은 정상이지만 실패한 시크릿에 `secretmanager.versions.access`가 없습니다. `roles/secretmanager.secretAccessor`(프로젝트 범위 또는 4단계에서 그렇게 범위 지정한 경우 시크릿별)를 감사하세요. |
|
|
| 다음 kickoff에서 로테이션된 값이 적용되지 않음 | 자동화의 환경 변수가 Workload Identity 기반 자격 증명을 참조하는지 확인하세요(정적 키 자격 증명이 아님). 정적 경로는 배포 이미지에 값을 박습니다. |
|
|
|
|
### 참고 링크
|
|
|
|
- GCP: [Workload Identity Federation overview](https://cloud.google.com/iam/docs/workload-identity-federation)
|
|
- GCP: [Configure Workload Identity Federation with OIDC](https://cloud.google.com/iam/docs/workload-identity-federation-with-other-providers)
|
|
- GCP: [Secret Manager IAM roles](https://cloud.google.com/secret-manager/docs/access-control)
|
|
|
|
## 다음 단계
|
|
|
|
- [환경 변수에서 시크릿 사용 및 권한 관리](/ko/enterprise/features/secrets-manager/usage)
|
|
- 다중 클라우드의 경우 [AWS Workload Identity (OIDC Federation)](/ko/enterprise/features/secrets-manager/aws-workload-identity) 및 [Azure Workload Identity Federation](/ko/enterprise/features/secrets-manager/azure-workload-identity)도 참조하세요.
|