docs: migrate Secrets Manager / Workload Identity from replicated-config (#5874)

This commit is contained in:
Heitor Carvalho
2026-05-21 14:23:42 -03:00
committed by GitHub
parent 56b6594669
commit 6d712a3686
37 changed files with 8308 additions and 4 deletions

View File

@@ -0,0 +1,321 @@
---
title: AWS Workload Identity (OIDC Federation)
description: 로테이션 인식, 자격 증명 없는 시크릿 액세스를 위해 Workload Identity를 통해 AWS Secrets Manager를 구성합니다
sidebarTitle: Workload Identity 사용
icon: "id-badge"
---
## 개요
이 가이드는 **Workload Identity Federation**을 사용하여 AWS Secrets Manager를 시크릿 공급자로 구성합니다: CrewAI Platform이 단기 OIDC 토큰을 발급하고, STS를 통해 이를 AWS 자격 증명과 교환하여 시크릿을 읽습니다 — 장기 AWS 액세스 키를 어디에도 저장하지 않습니다.
<Note>
**이 경로를 선택하는 이유:** 시크릿은 자동화 실행 시점에 해석되므로, **로테이션된 값이 재배포 없이 다음 kickoff에 전파됩니다**. 정적 자격 증명만 필요하고 로테이션 전파에 신경 쓰지 않는다면, 더 간단한 [AWS — 정적 키 / AssumeRole](/ko/enterprise/features/secrets-manager/aws) 가이드를 참조하세요.
</Note>
### 런타임 동작 방식
1. 배포 워커가 CrewAI Platform에서 새 OIDC JWT를 요청합니다.
2. 워커가 JWT를 제시하여 아래에서 설정한 IAM 역할에 대해 `sts:AssumeRoleWithWebIdentity`를 호출합니다.
3. AWS STS가 CrewAI Platform의 공개 OIDC 발급자에 대해 JWT를 검증한 다음(따라서 플랫폼 설치가 AWS에서 접근 가능해야 함), 단기 AWS 자격 증명을 반환합니다.
4. 워커가 해당 자격 증명을 사용하여 `secretsmanager:GetSecretValue`를 호출합니다.
5. 가져온 값이 해당 자동화 kickoff의 환경 변수 값으로 주입됩니다.
OIDC 주체 토큰은 매 kickoff마다 재발급을 피하기 위해 약 1시간 동안 캐시됩니다. 시크릿 값은 OIDC 캐시 상태와 관계없이 매 kickoff마다 새로 가져오며, 이것이 이 경로를 로테이션 인식으로 만드는 요소입니다.
## 사전 준비 사항
<Note>
시작하기 전에 다음을 준비하세요:
- 자동화 파드 이미지에 CrewAI 런타임 버전 `1.14.5` 이상이 포함되어야 합니다.
- IAM OIDC 공급자, IAM 역할, IAM 정책을 생성할 권한이 있는 AWS 계정.
- 시크릿이 위치한(또는 위치할) AWS 리전(예: `us-east-1`).
- 사용자가 `workload_identity_configs: manage` 및 `secret_providers: manage` 권한을 가진 CrewAI Platform 조직. [권한 (RBAC)](/ko/enterprise/features/secrets-manager/usage#permissions-rbac)을 참조하세요.
- **CrewAI 조직 UUID.** CrewAI Platform의 조직 설정 페이지에서 찾을 수 있습니다 — 3단계의 신뢰 정책이 IAM 역할을 이 특정 조직에 바인딩합니다.
- **CrewAI Platform 설치가 AWS에서 HTTPS를 통해 접근 가능해야 합니다.** AWS STS가 토큰 검증 중 OIDC 디스커버리 문서와 JWKS를 가져올 수 있어야 합니다. 플랫폼 관리자에게 호스트가 인터넷에서 접근 가능한지(또는 AWS가 VPC 피어링/동등한 방법을 통해 네트워크에 도달할 수 있는지) 확인하세요.
</Note>
## 1단계 — CrewAI Platform OIDC 발급자 URL 찾기
CrewAI Platform 설치는 `https://<your-platform-host>/.well-known/openid-configuration`에서 OpenID Connect 디스커버리 문서를 게시합니다. 해당 문서의 `issuer` 필드는 AWS가 신뢰할 수 있는 OIDC 공급자로 등록할 URL입니다.
브라우저에서 URL을 엽니다(`<your-platform-host>`를 실제 호스트 이름으로 교체, 예: `app.crewai.com`):
```
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단계 — CrewAI Platform을 IAM OIDC ID 공급자로 등록
[IAM → Identity providers 콘솔](https://console.aws.amazon.com/iam/home#/identity_providers)을 열고 **Add provider**를 클릭합니다.
- **Provider type:** OpenID Connect.
- **Provider URL:** 1단계의 `issuer` 값(예: `https://app.crewai.com`).
- **Audience:** `sts.amazonaws.com`
**Add provider**를 클릭합니다.
또는 CLI를 통해:
```bash
aws iam create-open-id-connect-provider \
--url "https://<your-platform-host>" \
--client-id-list "sts.amazonaws.com" \
--thumbprint-list "$(echo | openssl s_client -servername <your-platform-host> -connect <your-platform-host>:443 2>/dev/null | openssl x509 -fingerprint -noout -sha1 | cut -d= -f2 | tr -d ':')"
```
출력에서 **OpenIDConnectProviderArn**(또는 콘솔에서 공급자의 ARN)을 복사합니다. 3단계에서 사용합니다.
<Note>
AWS는 실제로 STS WebIdentity 호출의 thumbprint를 검증하지 않습니다 — 검증 시점에 항상 JWKS를 다시 가져옵니다 — 그러나 API에서 해당 필드가 존재해야 합니다.
</Note>
{/* SCREENSHOT: AWS IAM "Add identity provider" form filled with the Platform issuer URL and audience sts.amazonaws.com → /images/secrets-manager/aws-wi/01-add-oidc-provider.png */}
{/* SCREENSHOT: Provider detail page showing the provider's ARN → /images/secrets-manager/aws-wi/02-oidc-provider-arn.png */}
## 3단계 — IAM 역할 생성
`trust-policy.json`으로 저장하고, `<YOUR_ACCOUNT_ID>`, `<your-platform-host>`(발급자 호스트로 `https://` 또는 `http://` **없음**, 예: `app.crewai.com`), `<YOUR_CREWAI_ORG_UUID>`(사전 준비 사항에서)를 교체합니다:
```json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::<YOUR_ACCOUNT_ID>:oidc-provider/<your-platform-host>"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"<your-platform-host>:aud": "sts.amazonaws.com",
"<your-platform-host>:sub": "organization:<YOUR_CREWAI_ORG_UUID>"
}
}
}
]
}
```
역할을 생성합니다:
```bash
aws iam create-role \
--role-name crewai-secrets-reader \
--assume-role-policy-document file://trust-policy.json
```
출력에서 **Role Arn**을 복사합니다 — 이것이 `aws_role_arn`입니다. 6단계에서 CrewAI Platform에 붙여 넣습니다.
<Tip>
두 조건은 신뢰를 정확하게 범위 지정합니다: `aud`는 AWS STS audience를 가진 토큰으로만 가정을 제한하고, `sub`는 federation을 특정 CrewAI 조직으로 범위 지정합니다 — 해당 조직의 자동화를 위해 발급된 토큰만 수락됩니다. CrewAI Platform은 항상 AWS workload identity 토큰에 두 클레임을 모두 설정합니다.
</Tip>
{/* SCREENSHOT: IAM "Create role" with Web Identity trust type, federated provider selector pointing at the CrewAI Platform OIDC provider → /images/secrets-manager/aws-wi/03-create-role-trust.png */}
## 4단계 — Secrets Manager + KMS 액세스용 IAM 정책 생성 및 연결
`secrets-policy.json`으로 저장하고 자리 표시자를 계정 ID, 리전, 시크릿 이름 접두사, 그리고 해당 시크릿을 암호화하는 KMS 키 ARN으로 교체합니다:
```json
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "SecretsManagerListForUI",
"Effect": "Allow",
"Action": "secretsmanager:ListSecrets",
"Resource": "*"
},
{
"Sid": "SecretsManagerRead",
"Effect": "Allow",
"Action": [
"secretsmanager:GetSecretValue"
],
"Resource": "arn:aws:secretsmanager:<REGION>:<YOUR_ACCOUNT_ID>:secret:<SECRET_NAME_PREFIX>-*"
},
{
"Sid": "KMSDecrypt",
"Effect": "Allow",
"Action": [
"kms:Decrypt"
],
"Resource": "arn:aws:kms:<REGION>:<YOUR_ACCOUNT_ID>:key/<KMS_KEY_ID>"
}
]
}
```
`SecretsManagerListForUI`는 환경 변수 폼의 **Secret Name 자동 완성**과 자격 증명의 **Test Connection** 버튼을 지원합니다. `secretsmanager:ListSecrets`는 `Resource: "*"`만 허용합니다 — IAM 계층에서 계정 범위로 제한됩니다.
CLI(인라인 정책, 가장 간단함) 또는 콘솔 UI를 사용하여 역할에 정책을 연결합니다. 많은 역할에서 동일한 권한을 재사용하는 환경의 경우 재사용 가능한 명명된 정책을 위해 **Managed policy** 탭을 사용하세요.
<Tabs>
<Tab title="인라인 정책 (CLI)">
```bash
aws iam put-role-policy \
--role-name crewai-secrets-reader \
--policy-name SecretsManagerRead \
--policy-document file://secrets-policy.json
```
이는 정책을 **인라인**으로 역할에 연결합니다. 인라인 정책은 역할에 연결되어 있으며 다른 역할에서 재사용할 수 없습니다.
</Tab>
<Tab title="관리형 정책 (CLI, 재사용 가능)">
```bash
POLICY_ARN=$(aws iam create-policy \
--policy-name CrewAISecretsReader \
--policy-document file://secrets-policy.json \
--query 'Policy.Arn' --output text)
aws iam attach-role-policy \
--role-name crewai-secrets-reader \
--policy-arn "$POLICY_ARN"
```
관리형 정책은 여러 역할에 연결할 수 있는 독립형 IAM 리소스입니다.
</Tab>
<Tab title="콘솔 (UI)">
1. [IAM → Roles 콘솔](https://console.aws.amazon.com/iam/home#/roles)을 열고 **crewai-secrets-reader**를 선택합니다.
2. **Permissions** 탭에서 **Add permissions** → **Create inline policy**를 클릭합니다.
3. **JSON** 편집기로 전환하고 `secrets-policy.json`의 내용을 붙여 넣습니다.
4. **Next**를 클릭하고 정책 이름(예: `SecretsManagerRead`)을 지정한 다음 **Create policy**를 클릭합니다.
대신 재사용 가능한 관리형 정책을 만들려면 **IAM → Policies → Create policy**를 사용한 다음, 역할의 **Permissions** 탭에서 역할에 연결합니다.
{/* SCREENSHOT: IAM Role detail → Permissions → Create inline policy with JSON editor → /images/secrets-manager/aws-wi/03b-attach-inline-policy.png */}
</Tab>
</Tabs>
## 5단계 — AWS에 최소 하나의 시크릿 생성
테스트할 시크릿이 아직 없다면 지금 하나 만드세요:
```bash
aws secretsmanager create-secret \
--region <REGION> \
--name crewai-test-keyword \
--secret-string "hello from aws"
```
또는 [AWS Secrets Manager 콘솔](https://console.aws.amazon.com/secretsmanager/) → **Store a new secret**을 통해 만듭니다.
{/* SCREENSHOT: AWS Secrets Manager "Store a new secret" page with a sample value → /images/secrets-manager/aws-wi/04-create-secret.png */}
## 6단계 — CrewAI Platform에 Workload Identity 구성 추가
CrewAI Platform에서 **Settings** → **Workload Identity**로 이동하여 **Add Workload Identity Config**를 클릭합니다.
{/* SCREENSHOT: Sidebar highlighting Settings → Workload Identity → /images/secrets-manager/aws-wi/05-amp-settings-wi-nav.png */}
{/* SCREENSHOT: Empty state of Workload Identity page with "Add Workload Identity Config" button → /images/secrets-manager/aws-wi/06-amp-wi-empty-state.png */}
폼을 작성합니다:
- **Name:** 설명적인 이름(예: `aws-prod`).
- **Cloud Provider:** `AWS`.
- **AWS Role ARN:** 3단계의 **Role Arn**.
- **AWS Region:** 시크릿이 위치한 리전(예: `us-east-1`).
- (선택) AWS 기반 시크릿 자격 증명을 생성할 때 이 WI 구성을 기본으로 선택하려면 **Set as default for AWS**를 체크합니다.
**Create**를 클릭합니다.
{/* SCREENSHOT: "Add Workload Identity Config" form with AWS, role ARN, and region filled in → /images/secrets-manager/aws-wi/07-amp-add-wi-config-aws.png */}
{/* SCREENSHOT: Workload Identity list showing the new AWS row with "(default)" badge if applicable → /images/secrets-manager/aws-wi/08-amp-wi-list-with-aws.png */}
## 7단계 — WI 구성에 바인딩된 Secret Provider Credential 추가
**Settings** → **Secret Provider Credentials**로 이동하여 **Add Credential**을 클릭합니다.
폼을 작성합니다:
- **Name:** 설명적인 이름(예: `aws-prod-wi`).
- **Provider:** `AWS Secrets Manager`.
- **Authentication Method:** `Workload Identity`(정적 키 / AssumeRole 대신).
- **Workload Identity Configuration:** 6단계에서 만든 구성을 선택합니다(예: `aws-prod`).
- (선택) **Set as default credential for this provider**를 체크합니다.
Workload Identity 아래에서는 폼이 **AWS Region**만 요청합니다 — 정적 자격 증명 필드(Access Key ID, Secret Access Key, Role ARN, External ID)는 이 경로에 적용되지 않으므로 의도적으로 숨겨집니다. 역할 ARN은 연결된 WI 구성에서 가져옵니다.
**Create**를 클릭합니다.
{/* SCREENSHOT: "Add Secret Provider Credential" form with AWS + Workload Identity + WI config dropdown selected → /images/secrets-manager/aws-wi/09-amp-add-credential-aws-wi.png */}
## 8단계 — 연결 테스트
자격 증명을 저장한 후 **Test Connection**을 클릭합니다. Workload Identity 자격 증명의 경우 OIDC 핸드셰이크를 검증합니다: CrewAI Platform이 JWT를 발급하고, `sts:AssumeRoleWithWebIdentity`를 통해 AWS STS와 교환한 다음, 결과로 받은 자격 증명이 가정된 역할에 대해 `sts:GetCallerIdentity`를 호출할 수 있는지 확인합니다. 녹색 결과는 federation 바인딩이 정상임을 의미합니다.
성공적인 Test Connection은 신뢰 정책, OIDC 공급자 등록, audience 조건이 모두 올바르게 연결되었음을 증명합니다. 시크릿별 IAM이 올바르다는 것을 증명하지는 **않습니다** — 특정 시크릿 ARN에 대한 `secretsmanager:GetSecretValue`는 환경 변수가 kickoff에 해석될 때 별도로 수행됩니다. 핸드셰이크 실패 모드는 [문제 해결](#troubleshooting)을 참조하세요.
## 9단계 — 환경 변수에서 시크릿 참조
이제 다른 Secrets Manager 기반 환경 변수와 마찬가지로 자동화에서 시크릿을 참조합니다. 폼 필드와 동작은 [Secrets Manager 사용하기](/ko/enterprise/features/secrets-manager/usage#referencing-secrets-in-environment-variables)를 참조하세요.
WI 기반과 정적 키 기반 환경 변수의 유일한 차이는 시크릿이 **언제** 읽히는지입니다:
- **WI 기반:** 모든 자동화 kickoff에서 시크릿 값을 새로 읽습니다.
- **정적 키 기반:** 배포 시점에 시크릿 값을 읽고 배포 이미지에 박힙니다.
## 10단계 — 로테이션 확인
배포가 실행 중인 상태에서 AWS의 시크릿을 로테이션합니다:
```bash
aws secretsmanager update-secret \
--region <REGION> \
--secret-id crewai-test-keyword \
--secret-string "rotated value"
```
새 자동화 kickoff를 트리거합니다. kickoff의 환경은 `"rotated value"`를 볼 것입니다 — 재배포, 워커 재시작, TTL 대기 없음.
로그에서 확인하려면(워커에 액세스할 수 있는 경우) 다음을 찾으세요:
```
Workload identity config '<id>' (aws): N secret(s) resolved
```
이 줄은 모든 kickoff에 나타나며 AWS에 대한 새로운 `GetSecretValue` 호출을 의미합니다.
## 문제 해결
| 증상 | 가능한 원인 |
|---|---|
| Test Connection이 핸드셰이크 오류로 실패함 | `sts:AssumeRoleWithWebIdentity` 호출이 거부되었습니다. 신뢰 정책의 federated principal ARN이 `oidc-provider/<your-platform-host>`(호스트로 `https://` 또는 `http://` **없음**, 후행 슬래시 없음)를 참조하는지, audience 조건이 정확히 `sts.amazonaws.com`인지, `sub` 조건이 CrewAI 조직 UUID와 일치하는지, 플랫폼의 OIDC 디스커버리 URL이 공용 인터넷을 통해 AWS에서 접근 가능한지 확인하세요. |
| `InvalidIdentityToken: Couldn't retrieve verification key from your identity provider` | AWS STS가 CrewAI Platform 호스트에 도달하여 JWKS를 가져올 수 없습니다. 호스트가 AWS에서 인터넷에 접근 가능한지, OIDC 디스커버리 URL이 200을 반환하는지, JWKS 엔드포인트가 접근 가능한지 확인하세요. |
| `AccessDenied: Not authorized to perform sts:AssumeRoleWithWebIdentity` | 신뢰 정책 불일치. 3단계를 다시 확인하세요: federated principal ARN은 `oidc-provider/<your-platform-host>`(호스트로 `https://` 또는 `http://` **없음**, 후행 슬래시 없음)를 포함해야 하고, audience 조건은 정확히 `sts.amazonaws.com`이어야 하며, `sub` 조건은 `organization:<YOUR_CREWAI_ORG_UUID>`와 같아야 합니다. |
| Secret Name 자동 완성에 `AccessDenied: secretsmanager:ListSecrets` 표시 | 역할에 `Resource: "*"`를 가진 `secretsmanager:ListSecrets`가 없습니다. 4단계의 `SecretsManagerListForUI` 문을 추가하세요. |
| Test Connection은 통과하지만 kickoff가 시크릿을 해석하지 못함 | WI 바인딩은 정상이지만 실패한 시크릿에 리소스 범위 IAM이 없습니다. 해당 시크릿의 ARN과 KMS 키에 대한 역할의 `secretsmanager:GetSecretValue` 및 `kms:Decrypt` 권한을 감사하세요. |
| `RegionDisabledException` / 시크릿을 찾을 수 없음 | Workload Identity Config의 리전이 시크릿이 위치한 곳과 일치하지 않습니다. 6단계를 다시 확인하세요. |
| 다음 kickoff에서 로테이션된 값이 적용되지 않음 | 자동화의 환경 변수가 Workload Identity 기반 자격 증명을 참조하는지 확인하세요(정적 키 자격 증명이 아님). 정적 경로는 배포 이미지에 값을 박습니다. |
### 참고 링크
- AWS: [Creating OpenID Connect (OIDC) identity providers](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_oidc.html)
- AWS: [Configuring a role for OpenID Connect federation](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_oidc_relying-party.html)
- AWS: [STS:AssumeRoleWithWebIdentity API reference](https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRoleWithWebIdentity.html)
## 다음 단계
- [환경 변수에서 시크릿 사용 및 권한 관리](/ko/enterprise/features/secrets-manager/usage)
- 다중 클라우드의 경우 [GCP Workload Identity Federation](/ko/enterprise/features/secrets-manager/gcp-workload-identity) 및 [Azure Workload Identity Federation](/ko/enterprise/features/secrets-manager/azure-workload-identity)도 참조하세요.

View File

@@ -0,0 +1,295 @@
---
title: AWS Secrets Manager (정적 자격 증명)
description: 정적 액세스 키 또는 AssumeRole을 사용하여 AWS Secrets Manager를 CrewAI Platform의 시크릿 공급자로 구성합니다
sidebarTitle: 정적 자격 증명 사용
icon: "key"
---
## 개요
이 가이드는 **정적 자격 증명**(액세스 키, 선택적으로 AssumeRole 포함)을 사용하여 AWS Secrets Manager를 CrewAI Platform 조직의 시크릿 공급자로 구성하는 방법을 안내합니다. 완료되면 CrewAI Platform이 AWS 계정에 저장된 시크릿을 읽고 런타임에 환경 변수 값으로 주입할 수 있습니다.
<Note>
이 가이드는 **정적 자격 증명** 경로를 다룹니다 — 시크릿은 배포 시점에 해석되고 배포 이미지에 박힙니다. 로테이션된 값은 재배포가 필요합니다. 매 자동화 kickoff마다 업데이트되는 로테이션 인식 시크릿을 원하면(재배포 없음), [AWS Workload Identity (OIDC Federation)](/ko/enterprise/features/secrets-manager/aws-workload-identity)을 참조하세요.
</Note>
<Note>
이 가이드는 AWS 측 구성과 CrewAI Platform의 자격 증명 설정을 다룹니다. 환경 변수에서 시크릿을 참조하려면 [Secrets Manager 사용하기](/ko/enterprise/features/secrets-manager/usage)를 참조하세요.
</Note>
## 사전 준비 사항
<Note>
시작하기 전에 다음을 준비하세요:
- IAM 사용자, 고객 관리형 정책, 그리고 (선택적으로) IAM 역할을 생성할 수 있는 권한이 있는 AWS 계정.
- 시크릿이 위치한(또는 위치할) AWS 리전(예: `us-east-1`).
- 사용자가 `secret_providers: manage` 권한을 가진 CrewAI Platform 조직. [권한 (RBAC)](/ko/enterprise/features/secrets-manager/usage#permissions-rbac)을 참조하세요.
</Note>
## 인증 방법 선택
CrewAI Platform은 AWS Secrets Manager에 인증하는 두 가지 방법을 지원합니다. 시작하기 전에 하나를 선택하세요 — 아래 단계는 선택한 방법에 따라 다릅니다.
| 방법 | 사용 시기 | 트레이드오프 |
|---|---|---|
| **정적 액세스 키** | 시작 단계, 단일 계정 배포 | 가장 간단한 설정; 액세스 키를 수동으로 로테이션해야 함 |
| **AssumeRole** | 교차 계정, 프로덕션 강화 | 단기 자격 증명; External ID 지원; 추가 IAM 역할 필요 |
이 가이드의 나머지 부분은 단계 3-5에서 탭을 사용하므로 선택한 경로에 맞는 단계를 따를 수 있습니다.
## 1단계 — IAM 사용자 생성
[IAM 콘솔](https://console.aws.amazon.com/iam/)을 열고 **Users**로 이동한 다음 **Create user**를 클릭합니다.
- 권장 이름: `crewai-secrets-reader`.
- **Provide user access to the AWS Management Console**은 선택하지 마세요 — 이 주체는 사람이 아닌 CrewAI Platform이 프로그래밍 방식으로 사용합니다.
- **Next**를 클릭합니다.
**Set permissions** 페이지에서 기본 선택을 유지합니다. 정책은 3단계에서 연결합니다.
**Next**를 클릭하고 검토한 다음 **Create user**를 클릭합니다.
자세한 내용은 AWS 문서를 참조하세요: [Create an IAM user in your AWS account](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users_create.html).
{/* SCREENSHOT: AWS IAM "Create user" form filled with name "crewai-secrets-reader" → /images/secrets-manager/aws/01-create-iam-user.png */}
## 2단계 — IAM 정책 생성
CrewAI Platform은 AWS Secrets Manager에 대한 읽기 전용 액세스와 KMS를 통해 시크릿을 복호화할 수 있는 권한이 필요합니다. 다음 JSON으로 고객 관리형 정책을 생성하세요.
IAM 콘솔에서 **Policies**로 이동한 다음 **Create policy**를 클릭합니다.
**JSON** 탭을 선택하고 내용을 다음으로 바꿉니다:
```json
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "SecretsManagerRead",
"Effect": "Allow",
"Action": [
"secretsmanager:ListSecrets",
"secretsmanager:GetSecretValue",
"secretsmanager:DescribeSecret"
],
"Resource": "*"
},
{
"Sid": "KMSDecrypt",
"Effect": "Allow",
"Action": [
"kms:DescribeKey",
"kms:Decrypt"
],
"Resource": "*"
}
]
}
```
**Next**를 클릭한 다음 **Review and create** 페이지에서:
- **Policy name:** `CrewAISecretsManagerRead`
- **Description (optional):** `Read-only access to AWS Secrets Manager for CrewAI Platform`
**Create policy**를 클릭합니다.
<Tip>
위 정책은 간소화를 위해 `Resource`에 `*`를 부여합니다. 프로덕션에서는 `Resource`를 CrewAI Platform이 액세스해야 하는 특정 시크릿의 ARN으로 좁히고, `kms:Decrypt`를 해당 시크릿을 암호화하는 특정 KMS 키 ARN으로 좁히세요. [AWS의 최소 권한 지침](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_create-console.html)을 참조하세요.
</Tip>
{/* SCREENSHOT: AWS IAM "Create policy" → JSON tab with the policy above pasted → /images/secrets-manager/aws/02-create-policy-json-editor.png */}
{/* SCREENSHOT: AWS IAM "Review and create policy" page with name "CrewAISecretsManagerRead" → /images/secrets-manager/aws/03-policy-review-and-create.png */}
## 3단계 — 정책 연결
<Tabs>
<Tab title="정적 액세스 키">
1. IAM 콘솔에서 **Users**로 이동하여 1단계에서 만든 사용자를 클릭합니다.
2. **Permissions** 탭에서 **Add permissions** → **Attach policies directly**를 클릭합니다.
3. `CrewAISecretsManagerRead`를 검색하고 선택한 다음 **Next**를 클릭합니다.
4. **Add permissions**를 클릭합니다.
{/* SCREENSHOT: "Add permissions" → "Attach policies directly" with CrewAISecretsManagerRead selected → /images/secrets-manager/aws/04a-attach-policy-to-user.png */}
</Tab>
<Tab title="AssumeRole">
AssumeRole의 경우 정책은 (사용자가 아닌) 별도의 IAM **역할**에 연결됩니다. 1단계의 사용자는 해당 역할에 대해 `sts:AssumeRole`을 호출할 권한만 필요합니다.
**역할 생성:**
1. IAM 콘솔에서 **Roles**로 이동하여 **Create role**을 클릭합니다.
2. **Trusted entity type:** AWS account. **This account**를 선택합니다(또는 교차 계정 설정의 경우 **Another AWS account**를 선택하고 1단계 IAM 사용자를 호스팅하는 AWS 계정 ID를 입력합니다).
3. (권장) **Require external ID**를 체크하고 직접 생성한 값을 입력합니다 — 이는 5단계에서 CrewAI Platform에 붙여 넣을 공유 시크릿입니다.
4. **Next**를 클릭합니다.
5. `CrewAISecretsManagerRead` 정책을 연결합니다.
6. **Next**를 클릭하고 역할 이름을 `CrewAISecretsManagerRole`로 지정한 다음 **Create role**을 클릭합니다.
**IAM 사용자가 역할을 맡을 수 있도록 허용:**
1. 방금 만든 역할을 열고 **ARN**을 복사합니다.
2. IAM 콘솔에서 **Users**로 이동하여 1단계 사용자를 클릭한 다음 **Permissions** 탭에서 **Add permissions** → **Create inline policy**를 클릭합니다.
3. **JSON** 탭에서 다음을 붙여 넣습니다(`ROLE_ARN_FROM_ABOVE`를 교체):
```json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "ROLE_ARN_FROM_ABOVE"
}
]
}
```
4. 정책 이름을 `CrewAIAssumeSecretsRole`로 지정하고 **Create policy**를 클릭합니다.
{/* SCREENSHOT: IAM "Create role" trust policy step with External ID checkbox enabled → /images/secrets-manager/aws/04b-create-role-trust-policy.png */}
{/* SCREENSHOT: Inline sts:AssumeRole policy attached to the IAM user → /images/secrets-manager/aws/04c-attach-assumerole-on-user.png */}
</Tab>
</Tabs>
## 4단계 — 자격 증명 가져오기
<Tabs>
<Tab title="정적 액세스 키">
1. IAM 콘솔에서 1단계 사용자를 엽니다.
2. **Security credentials** 탭을 클릭합니다.
3. **Access keys** 아래에서 **Create access key**를 클릭합니다.
4. 사용 사례로 **Application running outside AWS**(또는 **Other**)를 선택합니다. **Next**를 클릭합니다.
5. (선택) 설명 태그를 추가합니다. **Create access key**를 클릭합니다.
6. **Show**를 클릭하여 시크릿 액세스 키를 표시한 다음 **Access key ID**와 **Secret access key**를 모두 복사하거나 **Download .csv file**을 클릭합니다.
<Warning>
시크릿 액세스 키는 한 번만 표시됩니다. 복사하지 않고 이 페이지를 닫으면 키를 삭제하고 새 키를 만들어야 합니다.
</Warning>
자세한 내용은 AWS 문서를 참조하세요: [Manage access keys for IAM users](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html).
{/* SCREENSHOT: Access key use-case selector ("Application running outside AWS") → /images/secrets-manager/aws/05a-create-access-key-use-case.png */}
{/* SCREENSHOT: "Retrieve access keys" page with Show/Download buttons → /images/secrets-manager/aws/06a-retrieve-access-keys.png */}
</Tab>
<Tab title="AssumeRole">
AssumeRole을 사용하더라도 CrewAI Platform은 여전히 IAM 사용자에 대한 액세스 키가 필요합니다 — `sts:AssumeRole` 호출을 수행하기 위한 호출 신원으로 해당 키를 사용합니다.
1. 위의 **정적 액세스 키** 탭에서 설명한 대로 사용자에 대한 액세스 키를 생성합니다.
2. 3단계에서 만든 역할을 열고 다음을 복사합니다:
- **Role ARN** (역할 요약에서).
- 구성한 **External ID** (있는 경우) — 3단계에서 직접 설정했으므로 가지고 있는지 확인하세요.
{/* SCREENSHOT: IAM role detail page showing Role ARN → /images/secrets-manager/aws/05b-role-arn-detail.png */}
</Tab>
</Tabs>
## 5단계 — CrewAI Platform에 자격 증명 추가
CrewAI Platform에서 **Settings** → **Secret Provider Credentials**로 이동하여 **Add Credential**을 클릭합니다.
{/* SCREENSHOT: Sidebar/nav highlighting Settings → Secret Provider Credentials → /images/secrets-manager/usage/01-amp-settings-nav.png */}
{/* SCREENSHOT: Empty state of Secret Provider Credentials page with "Add Credential" button → /images/secrets-manager/usage/02-amp-credentials-empty-state.png */}
<Tabs>
<Tab title="정적 액세스 키">
폼을 작성합니다:
- **Name:** 설명적인 이름(예: `aws-prod`).
- **Provider:** `AWS Secrets Manager`.
- **Region:** 시크릿이 위치한 AWS 리전(예: `us-east-1`). 읽으려는 시크릿의 리전과 일치해야 합니다.
- **Access Key ID:** 4단계의 값.
- **Secret Access Key:** 4단계의 값.
- (선택) **Set as default credential for this provider**를 체크합니다. 기본 자격 증명은 자격 증명을 명시적으로 지정하지 않고 AWS 시크릿을 참조하는 환경 변수에서 사용됩니다.
**Role ARN**과 **External ID**는 비워둡니다.
**Create**를 클릭합니다.
{/* SCREENSHOT: "Add Secret Provider Credential" form with AWS + static access keys filled in → /images/secrets-manager/usage/03a-amp-add-credential-form-aws-static.png */}
</Tab>
<Tab title="AssumeRole">
폼을 작성합니다:
- **Name:** 설명적인 이름(예: `aws-prod-assumerole`).
- **Provider:** `AWS Secrets Manager`.
- **Region:** 시크릿이 위치한 AWS 리전.
- **Access Key ID:** 4단계의 IAM 사용자 액세스 키(STS 호출에 사용).
- **Secret Access Key:** 4단계의 IAM 사용자 시크릿 액세스 키.
- **Role ARN:** 4단계에서 복사한 Role ARN.
- **External ID:** 역할의 신뢰 정책에 설정한 External ID(없으면 생략).
- (선택) **Set as default credential for this provider**를 체크합니다.
**Create**를 클릭합니다.
{/* SCREENSHOT: "Add Secret Provider Credential" form with AWS + AssumeRole fields filled in → /images/secrets-manager/usage/03b-amp-add-credential-form-aws-assumerole.png */}
</Tab>
</Tabs>
<Note>
**두 모드의 런타임 동작:**
- **정적 액세스 키**만 사용하는 경우, CrewAI Platform은 제공된 키를 사용하여 AWS Secrets Manager를 직접 호출합니다.
- **Role ARN**이 설정된 경우, CrewAI Platform은 먼저 제공된 액세스 키(구성된 경우 External ID 포함)로 `sts:AssumeRole`을 호출한 다음, STS가 반환한 단기 자격 증명을 사용하여 시크릿을 읽습니다.
</Note>
{/* SCREENSHOT: Credentials list showing the new AWS row, with "(default)" badge if applicable → /images/secrets-manager/usage/04-amp-credential-created.png */}
## 6단계 — AWS에 최소 하나의 시크릿 생성
AWS Secrets Manager에 시크릿이 아직 없다면, 7단계에서 연결을 확인할 수 있도록 지금 하나 만드세요.
[AWS Secrets Manager 콘솔](https://console.aws.amazon.com/secretsmanager/)에서 **Store a new secret**을 클릭합니다.
- **Secret type:** **Other type of secret**을 선택합니다.
- **Key/value pairs** — 다음 중 하나:
- 하나 이상의 키/값 쌍 입력(구조화된 시크릿에 권장), 또는
- 단일 문자열 값을 위해 **Plaintext** 탭 사용.
- **Encryption key:** 특정 KMS 키 요구 사항이 없으면 `aws/secretsmanager`(AWS 관리형 키)를 사용합니다.
**Next**를 클릭한 다음 입력합니다:
- **Secret name:** 고유한 이름(예: `crewai/openai-api-key`).
- **Description (optional):** 시크릿 용도에 대한 간단한 메모.
로테이션 및 검토 단계를 통해 **Next**를 클릭한 다음 **Store**를 클릭합니다.
<Note>
**JSON 키 참조 구문.** 여러 키/값 쌍(JSON 객체)이 있는 시크릿을 저장하는 경우, CrewAI Platform은 환경 변수 참조에서 `secret-name#json_key` 구문을 사용하여 특정 필드를 추출할 수 있습니다. 예를 들어, `{"username": "...", "password": "..."}`가 있는 `database-credentials`라는 시크릿은 `database-credentials#password`로 참조할 수 있습니다. 자세한 내용은 [Secrets Manager 사용하기](/ko/enterprise/features/secrets-manager/usage#referencing-secrets-in-environment-variables)를 참조하세요.
</Note>
자세한 내용은 AWS 문서를 참조하세요: [Create an AWS Secrets Manager secret](https://docs.aws.amazon.com/secretsmanager/latest/userguide/create_secret.html).
{/* SCREENSHOT: AWS Secrets Manager "Choose secret type" page → /images/secrets-manager/aws/07-create-secret-store-type.png */}
{/* SCREENSHOT: AWS Secrets Manager "Configure secret" page with name and description → /images/secrets-manager/aws/08-create-secret-name.png */}
## 7단계 — 연결 테스트
CrewAI Platform으로 돌아가 **Secret Provider Credentials** 페이지에서 방금 만든 자격 증명을 찾고 **Test Connection**을 클릭합니다.
성공 토스트는 CrewAI Platform이 AWS에 인증하고 계정의 시크릿을 읽을 수 있음을 확인합니다.
{/* SCREENSHOT: Success toast after clicking "Test Connection" → /images/secrets-manager/usage/05-amp-test-connection-success.png */}
테스트가 실패하면 가장 일반적인 원인을 확인하세요:
| 증상 | 가능한 원인 |
|---|---|
| `secretsmanager:ListSecrets`에서 `AccessDenied` | 정책이 연결되지 않았거나 잘못된 사용자입니다. 3단계를 다시 확인하세요. |
| `kms:Decrypt`에서 `AccessDenied` | `KMSDecrypt` 문이 누락되었거나, 시크릿이 `Resource: "*"`로 다루지 않는 고객 관리형 KMS 키를 사용합니다. |
| `InvalidClientTokenId` / `SignatureDoesNotMatch` | 잘못된 액세스 키 ID 또는 시크릿 액세스 키입니다. 4단계와 5단계를 다시 확인하세요. |
| `RegionDisabledException` / 시크릿을 찾을 수 없음 | 자격 증명의 **Region**이 시크릿이 실제로 위치한 곳과 일치하지 않습니다. |
| `sts:AssumeRole`에서 `AccessDenied` (AssumeRole만 해당) | IAM 사용자에 인라인 `sts:AssumeRole` 정책이 없거나, 역할의 신뢰 정책이 이 주체를 허용하지 않거나, External ID가 일치하지 않습니다. |
| IAM 사용자 생성 직후 테스트는 통과하지만 다음 번에는 실패함 | IAM 자격 증명이 전역적으로 전파되는 데 1-2분 정도 걸릴 수 있습니다. 다시 시도하세요. |
## 다음 단계
이제 AWS가 연결되었으므로 [Secrets Manager 사용하기](/ko/enterprise/features/secrets-manager/usage)로 이동하여 다음을 수행하세요:
- 조직 멤버에게 Secrets Manager를 사용(또는 관리)할 수 있는 적절한 권한을 부여합니다.
- CrewAI Platform 환경 변수에서 AWS 시크릿을 참조합니다.
재배포 없이 전파되는 **로테이션 인식** 시크릿을 원한다면 [AWS Workload Identity (OIDC Federation)](/ko/enterprise/features/secrets-manager/aws-workload-identity)으로 전환하세요 — 동일한 시크릿 저장소, 정적 자격 증명 없음, kickoff마다 시크릿을 가져옵니다.

View File

@@ -0,0 +1,275 @@
---
title: Azure Workload Identity Federation
description: 로테이션 인식, 자격 증명 없는 시크릿 액세스를 위해 Microsoft Entra Workload Identity Federation을 통해 Azure Key Vault를 구성합니다
sidebarTitle: Workload Identity 사용
icon: "id-badge"
---
## 개요
이 가이드는 **Microsoft Entra Workload Identity Federation**을 사용하여 Azure Key Vault를 시크릿 공급자로 구성합니다: CrewAI Platform이 단기 OIDC 토큰을 발급하고, Microsoft identity platform을 통해 이를 Entra 액세스 토큰과 교환하여 시크릿을 읽습니다 — 클라이언트 시크릿을 어디에도 저장하지 않습니다.
<Note>
**이 경로를 선택하는 이유:** 시크릿은 자동화 실행 시점에 해석되므로, **로테이션된 값이 재배포 없이 다음 kickoff에 전파됩니다**. 정적 자격 증명만 필요하다면 더 간단한 [Azure Key Vault — 클라이언트 시크릿](/ko/enterprise/features/secrets-manager/azure) 가이드를 참조하세요.
</Note>
### 런타임 동작 방식
1. 배포 워커가 CrewAI Platform에서 새 OIDC JWT를 요청합니다.
2. 워커가 `https://login.microsoftonline.com/<tenant>/oauth2/v2.0/token`에서 JWT를 `client_assertion`(`urn:ietf:params:oauth:client-assertion-type:jwt-bearer`)으로 Microsoft Entra에 제시하며, JWT의 발급자 + 주체와 일치하는 **Federated Identity Credential**을 가진 App Registration을 참조합니다.
3. Entra가 플랫폼의 OIDC 디스커버리 문서와 JWKS에 대해 JWT를 검증한 다음, `https://vault.azure.net/.default`로 범위가 지정된 단기 액세스 토큰을 반환합니다.
4. 워커가 Azure Key Vault를 호출하여 시크릿을 읽습니다.
5. 가져온 값이 해당 자동화 kickoff의 환경 변수 값으로 주입됩니다.
OIDC 주체 토큰은 매 kickoff마다 재발급을 피하기 위해 약 1시간 동안 캐시됩니다. 시크릿 값은 OIDC 캐시 상태와 관계없이 매 kickoff마다 새로 가져오며, 이것이 이 경로를 로테이션 인식으로 만드는 요소입니다.
## 사전 준비 사항
<Note>
시작하기 전에 다음을 준비하세요:
- 자동화 파드 이미지에 CrewAI 런타임 버전 `1.14.5` 이상이 포함되어야 합니다.
- 관리할 수 있는 Azure 구독과 Microsoft Entra 테넌트.
- App Registration을 생성하고 Federated Identity Credential을 추가할 테넌트 권한.
- 권한 부여에 **Azure RBAC**를 사용하는 Key Vault(레거시 액세스 정책 모델이 아님).
- 사용자가 `workload_identity_configs: manage` 및 `secret_providers: manage` 권한을 가진 CrewAI Platform 조직. [권한 (RBAC)](/ko/enterprise/features/secrets-manager/usage#permissions-rbac)을 참조하세요.
- **CrewAI Platform 설치가 Microsoft Entra에서 HTTPS를 통해 접근 가능해야 합니다.** Entra가 토큰 검증 중 OIDC 디스커버리 문서와 JWKS를 가져올 수 있어야 합니다. 플랫폼 관리자에게 호스트가 인터넷에서 접근 가능한지 확인하세요.
</Note>
## 1단계 — CrewAI Platform OIDC 발급자 URL 찾기
CrewAI Platform 설치는 `https://<your-platform-host>/.well-known/openid-configuration`에서 OpenID Connect 디스커버리 문서를 게시합니다. 여기의 `issuer` 필드는 Microsoft Entra가 신뢰할 수 있는 federation 발급자로 등록할 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단계 — App Registration 생성
[Microsoft Entra 포털](https://entra.microsoft.com)에서 **App registrations**로 이동하여 **New registration**을 클릭합니다.
- **Name:** `crewai-secrets-reader`
- **Supported account types:** `Accounts in this organizational directory only (Single tenant)`.
- **Redirect URI**는 비워둡니다.
**Register**를 클릭합니다. App의 개요 블레이드에서 **Application (client) ID**와 **Directory (tenant) ID**를 기록하세요 — 6단계에서 사용합니다.
{/* SCREENSHOT: Azure portal "Register an application" form with name "crewai-secrets-reader" → /images/secrets-manager/azure-wi/01-register-app.png */}
## 3단계 — Federated Identity Credential 추가
Federated Identity Credential은 Microsoft Entra에 다음을 알려줍니다: *이 발급자가 발급한 JWT를 신뢰하라, 이 주체로, 이 App Registration에 대한 client assertion으로 제시될 때.*
App Registration에서 **Certificates & secrets** → **Federated credentials** → **Add credential**로 이동합니다.
- **Federated credential scenario:** `Other issuer`.
- **Issuer:** 1단계의 CrewAI Platform 발급자 URL(예: `https://<your-platform-host>`).
- **Subject identifier:** `organization:<YOUR_CREWAI_ORG_UUID>` — 정확히 JWT의 `sub` 클레임 값. CrewAI Platform의 조직 설정에서 조직 UUID를 찾으세요. 이는 federation을 특정 CrewAI 조직으로 범위 지정합니다 — 해당 조직의 자동화를 위해 발급된 토큰만 수락됩니다.
- **Name:** 설명적인 레이블(예: `crewai-org-prod`).
- **Audience:** `api://AzureADTokenExchange`. 이는 Microsoft Entra가 federated 자격 증명에 요구하는 고정 audience이며 CrewAI Platform이 JWT의 `aud` 클레임에 설정하는 값입니다.
**Add**를 클릭합니다.
<Tip>
**조직별 격리.** 주체 식별자(`organization:<UUID>`)는 federated 자격 증명을 특정 CrewAI 조직의 토큰으로 제한합니다. 여러 CrewAI 조직이 하나의 App Registration을 공유해야 하는 경우, 조직당 하나의 Federated Identity Credential을 추가하세요(각각 조직의 UUID 사용).
</Tip>
자세한 내용은 Microsoft 문서를 참조하세요: [Configure a federated identity credential on an app](https://learn.microsoft.com/en-us/entra/workload-id/workload-identity-federation-create-trust).
{/* SCREENSHOT: "Add credential" panel with scenario = "Other issuer", issuer URL, subject "organization:<uuid>", audience "api://AzureADTokenExchange" → /images/secrets-manager/azure-wi/02-add-federated-credential.png */}
## 4단계 — App Registration에 Key Vault 액세스 부여
대상 볼트에서 App Registration에 **Key Vault Secrets User**를 부여합니다 — 정적 자격 증명 경로에서 사용할 것과 동일한 역할입니다. 볼트 전체(더 간단함) 또는 시크릿별(최소 권한)을 사용하세요.
<Tabs>
<Tab title="볼트 전체 (더 간단함)">
```bash
az role assignment create \
--assignee <APPLICATION_CLIENT_ID> \
--role "Key Vault Secrets User" \
--scope $(az keyvault show --name <VAULT_NAME> --query id -o tsv)
```
볼트 전체 범위는 CrewAI Platform의 환경 변수 폼에 있는 **Secret Name 자동 완성**이 의존하는 `secrets/list` 권한을 부여합니다. 자동 완성이 작동하길 원한다면 이 탭을 선택하세요.
{/* SCREENSHOT: Key Vault "Add role assignment" panel with "Key Vault Secrets User" and the App Registration selected → /images/secrets-manager/azure-wi/03-grant-vault-rbac.png */}
</Tab>
<Tab title="시크릿별 (최소 권한)">
```bash
az role assignment create \
--assignee <APPLICATION_CLIENT_ID> \
--role "Key Vault Secrets User" \
--scope $(az keyvault secret show --vault-name <VAULT_NAME> --name <SECRET_NAME> --query id -o tsv)
```
시크릿별 바인딩은 CrewAI Platform의 환경 변수 폼에 있는 **Secret Name 자동 완성**을 비활성화합니다(자동 완성은 볼트 범위에서만 가능한 `secrets/list`가 필요합니다). 대신 전체 시크릿 이름을 입력하세요.
{/* SCREENSHOT: Per-secret IAM panel with the App Registration assigned **Key Vault Secrets User** at the secret resource scope → /images/secrets-manager/azure-wi/04-per-secret-rbac.png */}
</Tab>
<Tab title="포털 (UI)">
**볼트 전체** 할당:
1. Azure 포털에서 Key Vault를 엽니다.
2. **Access control (IAM)** → **Add** → **Add role assignment**를 클릭합니다.
3. 역할 **Key Vault Secrets User**를 선택하고 → **Next**를 클릭합니다.
4. **Select members**를 클릭하고 App Registration `crewai-secrets-reader`를 검색한 다음 **Select**를 클릭합니다.
5. **Review + assign**을 클릭합니다.
**시크릿별** 할당의 경우 동일한 흐름을 사용하지만 **Objects** → **Secrets** → 시크릿 선택 → 자체 **Access control (IAM)** 패널에서 시작합니다. 시크릿별 바인딩은 자동 완성을 비활성화합니다(위의 시크릿별 탭 참조).
</Tab>
</Tabs>
## 5단계 — Key Vault에 최소 하나의 시크릿 생성
테스트할 시크릿이 아직 없다면 Azure CLI를 통해 하나 만듭니다:
```bash
az keyvault secret set \
--vault-name <VAULT_NAME> \
--name openai-api-key \
--value "sk-your-actual-key"
```
또는 Azure 포털을 통해:
1. Key Vault를 열고 **Objects** → **Secrets**로 이동합니다.
2. **Generate/Import**를 클릭합니다.
3. **Upload options:** `Manual`. **Name:** 시크릿 이름(예: `openai-api-key`). **Secret value:** 값을 붙여 넣습니다.
4. **Create**를 클릭합니다.
<Note>
**시크릿 이름 규칙.** Azure Key Vault 시크릿 이름에는 밑줄을 포함할 수 없습니다. CrewAI Platform은 Azure를 호출할 때 밑줄을 하이픈으로 자동으로 변환하므로(예: `db_password`는 `db-password`로 전송됨), 밑줄 스타일 환경 변수 이름을 유지할 수 있습니다 — 그러나 Key Vault의 기본 시크릿은 하이픈을 사용해야 합니다.
</Note>
## 6단계 — CrewAI Platform에 Workload Identity 구성 추가
CrewAI Platform에서 **Settings** → **Workload Identity**로 이동하여 **Add Workload Identity Config**를 클릭합니다.
폼을 작성합니다:
- **Name:** 설명적인 이름(예: `azure-prod`).
- **Cloud Provider:** `Azure`.
- **Tenant ID:** 2단계의 Microsoft Entra **Directory (tenant) ID**.
- **Client ID:** 2단계의 App Registration **Application (client) ID**.
- (선택) Azure 기반 시크릿 자격 증명을 생성할 때 이것이 기본 WI 구성으로 선택되길 원한다면 **Set as default for Azure**를 체크합니다.
**Audience**는 `api://AzureADTokenExchange`로 고정되어 있습니다 — Microsoft Entra는 federated 자격 증명에 대해 이 정확한 audience를 요구하므로 폼에 Audience 필드가 표시되지 않습니다.
**Create**를 클릭합니다.
{/* SCREENSHOT: "Add Workload Identity Config" form with Azure, tenant ID, client ID populated → /images/secrets-manager/azure-wi/05-amp-add-wi-config-azure.png */}
{/* SCREENSHOT: Workload Identity list showing AWS, GCP, and Azure rows → /images/secrets-manager/azure-wi/06-amp-wi-list-with-azure.png */}
## 7단계 — WI 구성에 바인딩된 Secret Provider Credential 추가
**Settings** → **Secret Provider Credentials**로 이동하여 **Add Credential**을 클릭합니다.
폼을 작성합니다:
- **Name:** 설명적인 이름(예: `azure-prod-wi`).
- **Provider:** `Azure Key Vault`.
- **Authentication Method:** `Workload Identity`.
- **Workload Identity Configuration:** 6단계에서 만든 구성을 선택합니다.
- **Key Vault URL:** 볼트의 DNS 호스트 이름(예: `https://my-vault.vault.azure.net`).
- (선택) **Set as default credential for this provider**를 체크합니다.
Workload Identity 아래에서는 폼이 **Key Vault URL**만 요청합니다 — 정적 자격 증명 필드(Tenant ID, Client ID, Client Secret)는 이 경로에 적용되지 않으므로 의도적으로 숨겨집니다. tenant + client는 연결된 WI 구성에서 가져옵니다.
**Create**를 클릭합니다.
<Tip>
**하나의 App Registration, 여러 볼트.** Key Vault URL은 WI 구성이 아닌 자격 증명에 있습니다. 따라서 하나의 App Registration(과 하나의 WI 구성)이 여러 Key Vault를 서비스할 수 있습니다 — 동일한 WI 구성에 연결된 볼트당 하나의 Secret Provider Credential을 만드세요.
</Tip>
{/* SCREENSHOT: "Add Secret Provider Credential" form with Azure + Workload Identity + WI config dropdown + vault URL → /images/secrets-manager/azure-wi/07-amp-add-credential-azure-wi.png */}
## 8단계 — 연결 테스트
자격 증명을 저장한 후 **Test Connection**을 클릭합니다. Workload Identity 자격 증명의 경우 OIDC 핸드셰이크를 검증합니다: CrewAI Platform이 JWT를 발급하고, federated `client_assertion`으로 Microsoft Entra에 제시한 다음, Entra가 볼트 범위 액세스 토큰을 반환하는지 확인합니다. 녹색 결과는 federation 바인딩이 정상임을 의미합니다.
성공적인 Test Connection은 Federated Identity Credential의 발급자, 주체, audience가 모두 일치하고 App Registration이 접근 가능함을 증명합니다. 시크릿별 Key Vault RBAC가 올바르다는 것을 증명하지는 **않습니다** — 특정 시크릿에 대한 `getSecret`은 환경 변수가 kickoff에 해석될 때 별도로 수행됩니다. 핸드셰이크 실패 모드는 [문제 해결](#troubleshooting)을 참조하세요.
## 9단계 — 환경 변수에서 시크릿 참조
다른 Secrets Manager 기반 환경 변수와 마찬가지로 자동화에서 시크릿을 참조합니다. 폼 필드와 동작은 [Secrets Manager 사용하기](/ko/enterprise/features/secrets-manager/usage#referencing-secrets-in-environment-variables)를 참조하세요.
## 10단계 — 로테이션 확인
배포가 실행 중인 상태에서 Key Vault의 시크릿을 로테이션합니다:
```bash
az keyvault secret set \
--vault-name <VAULT_NAME> \
--name openai-api-key \
--value "rotated value"
```
새 자동화 kickoff를 트리거합니다. kickoff의 환경은 `"rotated value"`를 볼 것입니다 — 재배포, 워커 재시작, TTL 대기 없음.
워커 로그에서 확인하려면 다음을 찾으세요:
```
Workload identity config '<id>' (azure): N secret(s) resolved
```
이 줄은 모든 kickoff에 나타나며 Azure Key Vault에 대한 새로운 `getSecret` 호출을 의미합니다.
엔드 투 엔드 fingerprint 기반 검증은 [로테이션 엔드 투 엔드 검증](/ko/enterprise/features/secrets-manager/verify-rotation)을 참조하세요.
## 문제 해결
| 증상 | 가능한 원인 |
|---|---|
| Test Connection이 핸드셰이크 오류로 실패함 | federated `client_assertion`이 Microsoft Entra에 의해 거부되었습니다. Federated Identity Credential의 **Issuer**가 플랫폼의 `issuer` 값과 정확히 일치하는지, **Subject**가 `organization:<your-org-uuid>`(JWT의 `sub` 클레임과 일치)인지, **Audience**가 `api://AzureADTokenExchange`인지, 플랫폼의 OIDC 디스커버리 URL이 공용 인터넷을 통해 Entra에서 접근 가능한지 확인하세요. |
| `AADSTS70021: No matching federated identity record found for presented assertion` | Federated Identity Credential의 **Issuer** + **Subject** + **Audience**가 모두 JWT와 정확히 일치하지 않습니다. 3단계를 다시 확인하세요: 주체는 `organization:<your-org-uuid>`(JWT의 `sub` 클레임과 일치)여야 하고, audience는 `api://AzureADTokenExchange`여야 합니다. |
| `AADSTS700024: Client assertion is not within its valid time range` | CrewAI Platform 호스트의 시계가 실제 시간과 크게 다릅니다. 호스트의 NTP를 확인하세요. |
| `AADSTS50013: Assertion failed signature validation` | Microsoft Entra가 JWT의 서명을 확인할 수 없습니다. `https://<your-platform-host>/oauth2/jwks`가 공용 인터넷에서 접근 가능하고 유효한 JWKS를 제공하는지 확인하세요. |
| Secret Name 자동 완성에 `Forbidden — does not have permission to perform action 'Microsoft.KeyVault/vaults/secrets/.../list'` 표시 | App Registration의 **Key Vault Secrets User** 역할이 단일 시크릿으로 범위 지정되어 있습니다. `list` 데이터 플레인 액션이 허용되도록 볼트 범위에서 역할을 부여하세요. 4단계를 참조하세요. |
| Test Connection은 통과하지만 kickoff가 시크릿을 해석하지 못함 | WI 바인딩은 정상이지만 실패한 시크릿에 시크릿별 Key Vault RBAC가 없습니다. 해당 특정 시크릿에 대한 **Key Vault Secrets User**를 감사하거나(또는 역할 할당을 볼트 범위로 확장). |
| `Forbidden — request was not authorized` (레거시 액세스 정책을 사용하는 볼트) | 볼트가 Azure RBAC로 전환되지 않았습니다. 볼트의 **Access configuration**에서 권한 모델을 **Azure role-based access control**로 설정하고 4단계의 역할을 다시 부여하세요. |
| `azure_vault_url is required for Azure secret resolution` (워커 로그) | Secret Provider Credential에 **Key Vault URL**이 없습니다. 7단계를 다시 확인하세요. |
| 다음 kickoff에서 로테이션된 값이 적용되지 않음 | 자동화의 환경 변수가 Workload Identity 기반 자격 증명을 참조하는지 확인하세요(정적 키 자격 증명이 아님). 정적 경로는 배포 이미지에 값을 박습니다. |
### 참고 링크
- Microsoft: [Microsoft Entra Workload Identity Federation overview](https://learn.microsoft.com/en-us/entra/workload-id/workload-identity-federation)
- Microsoft: [Configure a federated identity credential on an app](https://learn.microsoft.com/en-us/entra/workload-id/workload-identity-federation-create-trust)
- Microsoft: [Azure Key Vault RBAC guide](https://learn.microsoft.com/en-us/azure/key-vault/general/rbac-guide)
## 다음 단계
- [환경 변수에서 시크릿 사용 및 권한 관리](/ko/enterprise/features/secrets-manager/usage)
- 다중 클라우드의 경우 AWS 동등 설정은 [AWS Workload Identity (OIDC Federation)](/ko/enterprise/features/secrets-manager/aws-workload-identity)에, GCP 동등 설정은 [GCP Workload Identity Federation](/ko/enterprise/features/secrets-manager/gcp-workload-identity)에 있습니다.
## 스크린샷 참조
위의 자리 표시자는 다음에 매핑됩니다:
- `01-register-app.png` — `crewai-secrets-reader`로 채워진 Azure 포털 "Register an application" 폼.
- `02-add-federated-credential.png` — App Registration → Certificates & secrets → Federated credentials → Add credential, **Other issuer**, 플랫폼 발급자 URL, 주체 `organization:<uuid>`, audience `api://AzureADTokenExchange`.
- `03-grant-vault-rbac.png` — Key Vault → Access control (IAM) → Add role assignment, **Key Vault Secrets User**와 App Registration이 선택됨.
- `04-per-secret-rbac.png` — 동일한 폼이지만 단일 시크릿의 IAM 범위에서(대체 최소 권한 경로).
- `05-amp-add-wi-config-azure.png` — Cloud Provider = Azure, Tenant ID, Client ID가 채워진 CrewAI Platform "Add Workload Identity Config" 폼.
- `06-amp-wi-list-with-azure.png` — 생성 후 Workload Identity 목록 페이지, AWS, GCP 및 새 Azure 구성 행 표시.
- `07-amp-add-credential-azure-wi.png` — Provider = Azure Key Vault, Auth = Workload Identity, WI 구성 선택, Key Vault URL이 채워진 "Add Secret Provider Credential" 폼.

View File

@@ -0,0 +1,196 @@
---
title: Azure Key Vault
description: Azure Key Vault를 CrewAI Platform의 시크릿 공급자로 처음부터 끝까지 구성합니다
sidebarTitle: 정적 자격 증명 사용
icon: "key"
---
## 개요
이 가이드는 **클라이언트 시크릿이 있는 Microsoft Entra App Registration**을 사용하여 Azure Key Vault를 CrewAI Platform 조직의 시크릿 공급자로 구성하는 방법을 안내합니다. 완료되면 CrewAI Platform이 Azure Key Vault에 저장된 시크릿을 읽고 런타임에 환경 변수 값으로 주입할 수 있습니다.
<Note>
이 가이드는 **정적 자격 증명** 경로를 다룹니다 — 시크릿은 배포 시점에 해석되고 배포 이미지에 박힙니다. 로테이션된 값은 재배포가 필요합니다. 매 자동화 kickoff마다 업데이트되는 로테이션 인식 시크릿을 원한다면 [Azure Workload Identity Federation](/ko/enterprise/features/secrets-manager/azure-workload-identity)을 참조하세요.
</Note>
<Note>
이 가이드는 Azure 측 구성과 CrewAI Platform의 자격 증명 설정을 다룹니다. 환경 변수에서 시크릿을 참조하려면 [Secrets Manager 사용하기](/ko/enterprise/features/secrets-manager/usage)를 참조하세요.
</Note>
## 사전 준비 사항
<Note>
시작하기 전에 다음을 준비하세요:
- Microsoft Entra에서 App Registration을 생성하고 Key Vault 리소스에 역할 할당을 부여할 권한이 있는 Azure 구독.
- 권한 부여에 **Azure RBAC**를 사용하는 Key Vault(레거시 액세스 정책 모델이 아님). 볼트가 여전히 액세스 정책을 사용하는 경우, 볼트의 **Access configuration** 블레이드에서 RBAC로 전환하세요.
- 사용자가 `secret_providers: manage` 권한을 가진 CrewAI Platform 조직. [권한 (RBAC)](/ko/enterprise/features/secrets-manager/usage#permissions-rbac)을 참조하세요.
</Note>
## 1단계 — App Registration 생성
App Registration은 CrewAI Platform이 인증할 Microsoft Entra 측 ID입니다.
[Microsoft Entra 포털](https://entra.microsoft.com)에서 **App registrations**로 이동하여 **New registration**을 클릭합니다.
- **Name:** `crewai-secrets-reader`
- **Supported account types:** `Accounts in this organizational directory only (Single tenant)`.
- **Redirect URI**는 비워둡니다.
**Register**를 클릭합니다. App의 개요 블레이드에서 **Application (client) ID**와 **Directory (tenant) ID**를 기록하세요 — 4단계에서 둘 다 CrewAI Platform에 붙여 넣습니다.
자세한 내용은 Microsoft 문서를 참조하세요: [Register an application with the Microsoft identity platform](https://learn.microsoft.com/en-us/entra/identity-platform/quickstart-register-app).
{/* SCREENSHOT: Azure "Register an application" form with name "crewai-secrets-reader" → /images/secrets-manager/azure/01-register-app.png */}
## 2단계 — 클라이언트 시크릿 생성
App Registration에서 **Certificates & secrets** → **Client secrets** → **New client secret**으로 이동합니다.
- **Description:** `crewai-platform`
- **Expires:** 로테이션 정책과 일치하는 기간을 선택합니다(Microsoft은 이를 24개월로 제한).
**Add**를 클릭합니다. **Value** 열을 즉시 복사하세요 — 페이지를 떠난 후에는 다시 표시할 수 없습니다.
<Warning>
클라이언트 시크릿은 장기 정적 자격 증명입니다. 값을 안전하게 저장하고(패스워드 매니저나 자체 시크릿 저장소에) 만료 전에 로테이션하세요. 정적 자격 증명을 완전히 제거하려면 대신 [Azure Workload Identity Federation](/ko/enterprise/features/secrets-manager/azure-workload-identity)을 사용하세요.
</Warning>
{/* SCREENSHOT: "Client secrets" tab with the new secret row and the "Value" column highlighted → /images/secrets-manager/azure/02-create-client-secret.png */}
## 3단계 — App Registration에 Key Vault 액세스 부여
CrewAI Platform은 Key Vault의 시크릿에 대한 읽기 액세스가 필요합니다. 두 가지 범위 중 하나를 사용하세요 — 간소화를 위한 **볼트 전체** 또는 최소 권한을 위한 **시크릿별**.
<Tabs>
<Tab title="볼트 전체 (더 간단함)">
[Key Vault 콘솔](https://portal.azure.com/#view/HubsExtension/BrowseResource/resourceType/Microsoft.KeyVault%2Fvaults)에서 대상 볼트를 열고 **Access control (IAM)** → **Add** → **Add role assignment**로 이동합니다.
- **Role:** **Key Vault Secrets User**
- **Assign access to:** User, group, or service principal
- **Members:** App Registration(`crewai-secrets-reader`)을 검색하고 선택합니다.
**Review + assign**을 클릭합니다.
또는 Azure CLI를 통해:
```bash
az role assignment create \
--assignee <APPLICATION_CLIENT_ID> \
--role "Key Vault Secrets User" \
--scope $(az keyvault show --name <VAULT_NAME> --query id -o tsv)
```
{/* SCREENSHOT: Key Vault "Add role assignment" panel with "Key Vault Secrets User" and the App Registration selected → /images/secrets-manager/azure/03-grant-vault-rbac.png */}
</Tab>
<Tab title="시크릿별 (최소 권한)">
개별 시크릿 수준에서 역할을 부여합니다. CrewAI Platform이 액세스해야 하는 각 시크릿에 대해 반복합니다:
```bash
az role assignment create \
--assignee <APPLICATION_CLIENT_ID> \
--role "Key Vault Secrets User" \
--scope $(az keyvault secret show --vault-name <VAULT_NAME> --name <SECRET_NAME> --query id -o tsv)
```
{/* SCREENSHOT: Per-secret "Access control (IAM)" panel showing role assignment scoped to one secret → /images/secrets-manager/azure/04-per-secret-rbac.png */}
</Tab>
</Tabs>
<Tip>
**Key Vault Secrets User** 역할은 시크릿 값 읽기를 허용하지만 볼트의 모든 시크릿을 나열하는 것은 허용하지 않습니다. CrewAI Platform의 시크릿 이름 자동 완성도 `list`를 호출합니다 — 해당 권한은 볼트 범위에서는 역할에 포함되지만, 시크릿별 범위에서는 **포함되지 않습니다**. 시크릿별 바인딩의 경우 자동 완성이 시크릿을 제안하지 않으므로 대신 전체 시크릿 이름을 입력하세요.
</Tip>
## 4단계 — CrewAI Platform에 자격 증명 추가
CrewAI Platform에서 **Settings** → **Secret Provider Credentials**로 이동하여 **Add Credential**을 클릭합니다.
{/* SCREENSHOT: Sidebar/nav highlighting Settings → Secret Provider Credentials → /images/secrets-manager/usage/01-amp-settings-nav.png */}
폼을 작성합니다:
- **Name:** 설명적인 이름(예: `azure-prod`).
- **Provider:** `Azure Key Vault`.
- **Key Vault URL:** 볼트의 DNS 호스트 이름(예: `https://my-vault.vault.azure.net`).
- **Tenant ID:** 1단계의 Microsoft Entra **Directory (tenant) ID**.
- **Client ID:** 1단계의 App Registration **Application (client) ID**.
- **Client Secret:** 2단계에서 복사한 **Value**.
- (선택) **Set as default credential for this provider**를 체크합니다. 기본 자격 증명은 자격 증명을 명시적으로 지정하지 않고 Azure 시크릿을 참조하는 환경 변수에서 사용됩니다.
**Create**를 클릭합니다.
{/* SCREENSHOT: "Add Secret Provider Credential" form with Azure fields filled in → /images/secrets-manager/azure/05-amp-add-credential-form-azure.png */}
## 5단계 — Azure Key Vault에 최소 하나의 시크릿 생성
Key Vault에 시크릿이 아직 없다면, 6단계에서 연결을 확인할 수 있도록 지금 하나 만드세요.
Key Vault 콘솔에서 **Objects** → **Secrets** → **Generate/Import**로 이동합니다.
- **Upload options:** `Manual`
- **Name:** 예: `openai-api-key`
- **Secret value:** 시크릿 값을 붙여 넣습니다
- 나머지는 기본값으로 둡니다.
**Create**를 클릭합니다.
또는 Azure CLI를 통해:
```bash
az keyvault secret set \
--vault-name <VAULT_NAME> \
--name openai-api-key \
--value "sk-your-actual-key"
```
<Note>
**시크릿 이름 규칙.** Azure Key Vault 시크릿 이름에는 밑줄을 포함할 수 없습니다. CrewAI Platform은 Azure를 호출할 때 밑줄을 하이픈으로 자동으로 변환하므로(예: `db_password`는 `db-password`로 전송됨), 밑줄 스타일 환경 변수 이름을 유지할 수 있습니다 — 그러나 Key Vault의 기본 시크릿은 하이픈을 사용해야 합니다.
</Note>
<Note>
**JSON 키 참조 구문.** Key Vault는 시크릿 값을 불투명한 문자열로 취급합니다. 시크릿 값이 JSON 객체인 경우, CrewAI Platform은 `secret-name#json_key` 구문(예: `database-credentials#password`)을 사용하여 단일 필드를 추출할 수 있습니다. 자세한 내용은 [Secrets Manager 사용하기](/ko/enterprise/features/secrets-manager/usage#referencing-secrets-in-environment-variables)를 참조하세요.
</Note>
자세한 내용은 Microsoft 문서를 참조하세요: [Set and retrieve a secret](https://learn.microsoft.com/en-us/azure/key-vault/secrets/quick-create-cli).
{/* SCREENSHOT: Azure Key Vault "Create a secret" form with name and value → /images/secrets-manager/azure/06-create-secret.png */}
## 6단계 — 연결 테스트
CrewAI Platform으로 돌아가 **Secret Provider Credentials** 페이지에서 방금 만든 자격 증명을 찾고 **Test Connection**을 클릭합니다.
성공 토스트는 CrewAI Platform이 Microsoft Entra에 인증하고 볼트의 시크릿을 읽을 수 있음을 확인합니다.
{/* SCREENSHOT: Success toast after clicking "Test Connection" on the Azure credential → /images/secrets-manager/azure/07-test-connection-success.png */}
테스트가 실패하면 가장 일반적인 원인을 확인하세요:
| 증상 | 가능한 원인 |
|---|---|
| `AADSTS7000215: Invalid client secret provided` | 붙여 넣은 **Client Secret**이 잘못되었거나 만료되었습니다. 시크릿을 다시 생성하고(2단계) 자격 증명을 업데이트하세요. |
| `AADSTS700016: Application not found in the directory` | **Tenant ID** 또는 **Client ID**가 App Registration과 일치하지 않습니다. 4단계를 다시 확인하세요. |
| `Forbidden — caller does not have permission` | App Registration에 볼트(또는 시크릿별) **Key Vault Secrets User** 역할이 없습니다. 3단계를 다시 확인하세요. |
| `Vault not found` / DNS 오류 | **Key Vault URL**이 잘못되었거나, 볼트에 공용 액세스를 차단하는 프라이빗 엔드포인트가 있습니다. 호스트가 `curl https://<vault-name>.vault.azure.net/secrets?api-version=7.4`에 응답하는지 확인하세요. |
| `Forbidden — request was not authorized` (레거시 액세스 정책을 사용하는 볼트) | 볼트가 Azure RBAC로 전환되지 않았습니다. 볼트의 **Access configuration**에서 권한 모델을 **Azure role-based access control**로 설정하고 3단계의 역할을 다시 부여하세요. |
## 다음 단계
이제 Azure Key Vault가 연결되었으므로 [Secrets Manager 사용하기](/ko/enterprise/features/secrets-manager/usage)로 이동하여 다음을 수행하세요:
- 조직 멤버에게 Secrets Manager를 사용(또는 관리)할 수 있는 적절한 권한을 부여합니다.
- CrewAI Platform 환경 변수에서 Azure 시크릿을 참조합니다.
재배포 없이 전파되는 **로테이션 인식** 시크릿을 원한다면 [Azure Workload Identity Federation](/ko/enterprise/features/secrets-manager/azure-workload-identity)으로 전환하세요 — 동일한 볼트, 로테이션할 클라이언트 시크릿 없음, kickoff마다 시크릿을 가져옵니다.
## 스크린샷 참조
위의 자리 표시자는 다음에 매핑됩니다:
- `01-register-app.png` — `crewai-secrets-reader`로 채워진 Azure 포털 "Register an application" 폼.
- `02-create-client-secret.png` — App Registration → Certificates & secrets → Client secrets, 새로 생성된 시크릿 행이 표시됨(마스킹되기 전 Value 열 강조).
- `03-grant-vault-rbac.png` — Key Vault → Access control (IAM) → Add role assignment, **Key Vault Secrets User**가 선택되고 App Registration이 멤버로 선택됨.
- `04-per-secret-rbac.png` — 동일한 패널이지만 단일 시크릿 리소스로 범위 지정됨(대체 최소 권한 경로).
- `05-amp-add-credential-form-azure.png` — CrewAI Platform "Add Secret Provider Credential" 폼: Provider = Azure Key Vault, 다섯 필드 모두 채워짐.
- `06-create-secret.png` — `openai-api-key`와 붙여 넣은 값이 있는 Azure Key Vault "Create a secret" 패널.
- `07-test-connection-success.png` — 자격 증명에서 **Test Connection**을 클릭한 후의 CrewAI Platform 성공 토스트 / 행 상태.

View File

@@ -0,0 +1,273 @@
---
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)도 참조하세요.

View File

@@ -0,0 +1,189 @@
---
title: Google Cloud Secret Manager
description: Google Cloud Secret Manager를 CrewAI Platform의 시크릿 공급자로 처음부터 끝까지 구성합니다
sidebarTitle: 정적 자격 증명 사용
icon: "key"
---
## 개요
이 가이드는 **서비스 계정 자격 증명**을 사용하여 Google Cloud Secret Manager를 CrewAI Platform 조직의 시크릿 공급자로 구성하는 방법을 안내합니다. 완료되면 CrewAI Platform이 Google Cloud 프로젝트에 저장된 시크릿을 읽고 런타임에 환경 변수 값으로 주입할 수 있습니다.
<Note>
이 가이드는 **정적 자격 증명** 경로를 다룹니다 — 시크릿은 배포 시점에 해석되고 배포 이미지에 박힙니다. 로테이션된 값은 재배포가 필요합니다. 매 자동화 kickoff마다 업데이트되는 로테이션 인식 시크릿을 원한다면 [GCP Workload Identity Federation](/ko/enterprise/features/secrets-manager/gcp-workload-identity)을 참조하세요.
</Note>
<Note>
이 가이드는 GCP 측 구성과 CrewAI Platform의 자격 증명 설정을 다룹니다. 환경 변수에서 시크릿을 참조하려면 [Secrets Manager 사용하기](/ko/enterprise/features/secrets-manager/usage)를 참조하세요.
</Note>
## 사전 준비 사항
<Note>
시작하기 전에 다음을 준비하세요:
- **Secret Manager API**가 활성화된 Google Cloud 프로젝트. [APIs & Services 콘솔](https://console.cloud.google.com/apis/library/secretmanager.googleapis.com)에서 또는 `gcloud`를 통해 활성화하세요:
```bash
gcloud services enable secretmanager.googleapis.com --project=YOUR_PROJECT_ID
```
- 서비스 계정 생성, IAM 역할 부여, (필요한 경우) 시크릿 생성에 대한 프로젝트 권한.
- 사용자가 `secret_providers: manage` 권한을 가진 CrewAI Platform 조직. [권한 (RBAC)](/ko/enterprise/features/secrets-manager/usage#permissions-rbac)을 참조하세요.
</Note>
## 1단계 — 서비스 계정 생성
서비스 계정은 CrewAI Platform이 인증할 GCP 측 ID입니다.
[IAM & Admin → Service Accounts 콘솔](https://console.cloud.google.com/iam-admin/serviceaccounts)에서 **Create Service Account**를 클릭합니다.
- **Service account name:** `crewai-secrets-reader`
- **Service account ID:** 이름에서 자동으로 채워짐(예: `crewai-secrets-reader@YOUR_PROJECT_ID.iam.gserviceaccount.com`)
- **Description (optional):** "Read-only access to Secret Manager for CrewAI Platform"
**Create and Continue**를 클릭합니다. 이 화면에서 선택적 권한 부여는 건너뜁니다 — 역할은 2단계에서 연결합니다. **Done**을 클릭합니다.
자세한 내용은 GCP 문서를 참조하세요: [Create service accounts](https://cloud.google.com/iam/docs/service-accounts-create).
{/* SCREENSHOT: GCP "Create service account" form with name "crewai-secrets-reader" → /images/secrets-manager/gcp/01-create-service-account.png */}
## 2단계 — Secret Manager 액세스 부여
CrewAI Platform은 프로젝트의 시크릿을 나열하고 읽을 수 있는 권한이 필요합니다. 두 가지 범위 중 하나를 사용하세요 — 간소화를 위한 **프로젝트 전체** 또는 최소 권한을 위한 **시크릿별**.
<Tabs>
<Tab title="프로젝트 전체 (더 간단함)">
[IAM 콘솔](https://console.cloud.google.com/iam-admin/iam)에서 **Grant Access**를 클릭하고:
- **New principals:** 1단계 서비스 계정의 이메일.
- **Role:** **Secret Manager Secret Accessor** (`roles/secretmanager.secretAccessor`).
**Save**를 클릭합니다.
또는 `gcloud`를 통해:
```bash
gcloud projects add-iam-policy-binding YOUR_PROJECT_ID \
--member="serviceAccount:crewai-secrets-reader@YOUR_PROJECT_ID.iam.gserviceaccount.com" \
--role="roles/secretmanager.secretAccessor"
```
{/* SCREENSHOT: GCP IAM "Grant access" panel with the service account and Secret Manager Secret Accessor role → /images/secrets-manager/gcp/02-iam-grant-access.png */}
</Tab>
<Tab title="시크릿별 (최소 권한)">
CrewAI Platform이 액세스해야 하는 특정 시크릿에만 역할을 부여합니다. 각 시크릿에 대해 반복합니다:
```bash
gcloud secrets add-iam-policy-binding YOUR_SECRET_NAME \
--member="serviceAccount:crewai-secrets-reader@YOUR_PROJECT_ID.iam.gserviceaccount.com" \
--role="roles/secretmanager.secretAccessor" \
--project=YOUR_PROJECT_ID
```
또는 콘솔에서: [Secret Manager](https://console.cloud.google.com/security/secret-manager)에서 각 시크릿을 열고, 오른쪽 패널의 **Permissions**를 클릭한 다음 서비스 계정에 **Secret Manager Secret Accessor**를 부여합니다.
{/* SCREENSHOT: Per-secret "Permissions" panel in Secret Manager with the service account granted accessor role → /images/secrets-manager/gcp/03-per-secret-permissions.png */}
</Tab>
</Tabs>
<Tip>
`roles/secretmanager.secretAccessor` 역할은 시크릿 값에 대한 읽기 전용 액세스를 부여합니다. CrewAI Platform은 또한 환경 변수 폼의 자동 완성 경험을 위해 `secretmanager.secrets.list`를 호출합니다 — 해당 권한은 프로젝트 범위에서는 역할에 포함되지만, 시크릿별 범위에서는 **포함되지 않습니다**. 시크릿별 바인딩의 경우 자동 완성이 시크릿을 제안하지 않으므로 전체 시크릿 이름을 입력해야 합니다.
</Tip>
## 3단계 — 서비스 계정 키 생성
[IAM & Admin → Service Accounts 콘솔](https://console.cloud.google.com/iam-admin/serviceaccounts)에서 1단계의 서비스 계정을 엽니다.
- **Keys** 탭을 클릭합니다.
- **Add Key** → **Create new key**를 클릭합니다.
- **Key type:** JSON.
- **Create**를 클릭합니다. 브라우저가 JSON 파일을 다운로드합니다 — 안전하게 보관하세요. 다시 다운로드할 수 없습니다.
또는 `gcloud`를 통해:
```bash
gcloud iam service-accounts keys create ./crewai-secrets-reader.json \
--iam-account=crewai-secrets-reader@YOUR_PROJECT_ID.iam.gserviceaccount.com
```
<Warning>
서비스 계정 키는 장기 정적 자격 증명입니다. 안전하게 저장하고(패스워드 매니저나 자체 시크릿 저장소에) 정기적으로 로테이션하세요. 정적 자격 증명을 완전히 제거하려면 대신 [GCP Workload Identity Federation](/ko/enterprise/features/secrets-manager/gcp-workload-identity)을 사용하세요.
</Warning>
{/* SCREENSHOT: Service account "Keys" tab with the "Create new key" → JSON option → /images/secrets-manager/gcp/04-create-service-account-key.png */}
## 4단계 — CrewAI Platform에 자격 증명 추가
CrewAI Platform에서 **Settings** → **Secret Provider Credentials**로 이동하여 **Add Credential**을 클릭합니다.
{/* SCREENSHOT: Sidebar/nav highlighting Settings → Secret Provider Credentials → /images/secrets-manager/usage/01-amp-settings-nav.png */}
폼을 작성합니다:
- **Name:** 설명적인 이름(예: `gcp-prod`).
- **Provider:** `Google Cloud Secret Manager`.
- **Project ID:** GCP 프로젝트 ID(예: `my-crewai-prod`).
- **Service Account JSON:** 3단계에서 다운로드한 JSON 파일의 전체 내용을 붙여 넣습니다.
- (선택) **Set as default credential for this provider**를 체크합니다. 기본 자격 증명은 자격 증명을 명시적으로 지정하지 않고 GCP 시크릿을 참조하는 환경 변수에서 사용됩니다.
**Create**를 클릭합니다.
{/* SCREENSHOT: "Add Secret Provider Credential" form with GCP fields filled in → /images/secrets-manager/gcp/05-amp-add-credential-form-gcp.png */}
## 5단계 — GCP에 최소 하나의 시크릿 생성
GCP Secret Manager에 시크릿이 아직 없다면, 6단계에서 연결을 확인할 수 있도록 지금 하나 만드세요.
[Secret Manager 콘솔](https://console.cloud.google.com/security/secret-manager)에서 **Create secret**을 클릭합니다.
- **Name:** 고유한 이름(예: `openai-api-key`).
- **Secret value:** 원시 값을 붙여 넣거나 파일을 업로드합니다.
- 특정 요구 사항이 없으면 로테이션, 복제 및 기타 설정을 기본값으로 둡니다.
**Create secret**을 클릭합니다.
또는 `gcloud`를 통해:
```bash
echo -n "sk-your-actual-key" | gcloud secrets create openai-api-key \
--data-file=- \
--project=YOUR_PROJECT_ID \
--replication-policy=automatic
```
<Note>
**JSON 키 참조 구문.** GCP Secret Manager는 시크릿 값을 불투명한 blob으로 취급합니다. 시크릿 값이 JSON 문자열인 경우, CrewAI Platform은 `secret-name#json_key` 구문(예: `database-credentials#password`)을 사용하여 단일 필드를 추출할 수 있습니다. 자세한 내용은 [Secrets Manager 사용하기](/ko/enterprise/features/secrets-manager/usage#referencing-secrets-in-environment-variables)를 참조하세요.
</Note>
자세한 내용은 GCP 문서를 참조하세요: [Create a secret](https://cloud.google.com/secret-manager/docs/create-secret-quickstart).
{/* SCREENSHOT: GCP "Create secret" form with name and value → /images/secrets-manager/gcp/06-create-secret.png */}
## 6단계 — 연결 테스트
CrewAI Platform으로 돌아가 **Secret Provider Credentials** 페이지에서 방금 만든 자격 증명을 찾고 **Test Connection**을 클릭합니다.
성공 토스트는 CrewAI Platform이 GCP에 인증하고 프로젝트의 시크릿을 읽을 수 있음을 확인합니다.
{/* SCREENSHOT: Success toast after clicking "Test Connection" on the GCP credential → /images/secrets-manager/gcp/07-test-connection-success.png */}
테스트가 실패하면 가장 일반적인 원인을 확인하세요:
| 증상 | 가능한 원인 |
|---|---|
| 시크릿 나열 시 `PERMISSION_DENIED` | 서비스 계정에 `roles/secretmanager.secretAccessor`가 없거나, 시크릿별로 범위를 지정했습니다(`list`가 부여되지 않음). 2단계를 다시 확인하세요. |
| `secretmanager.secrets.access`에서 `PERMISSION_DENIED` | 위와 동일하지만 특정 시크릿에 대한 것입니다. 해당 시크릿에 서비스 계정이 accessor 역할을 갖고 있는지 확인하세요. |
| `unauthorized_client` / `invalid_grant` | 붙여 넣은 서비스 계정 JSON이 유효하지 않거나, 만료되었거나, 삭제된 서비스 계정용입니다. 키를 다시 만들고(3단계) 다시 붙여 넣으세요. |
| `Project ID does not match` | CrewAI Platform의 Project ID 필드가 서비스 계정/시크릿을 소유한 프로젝트와 일치하지 않습니다. 4단계를 다시 확인하세요. |
| `API not enabled` | 프로젝트에 Secret Manager API가 활성화되어 있지 않습니다. 사전 준비 사항을 참조하세요. |
## 다음 단계
이제 GCP가 연결되었으므로 [Secrets Manager 사용하기](/ko/enterprise/features/secrets-manager/usage)로 이동하여 다음을 수행하세요:
- 조직 멤버에게 Secrets Manager를 사용(또는 관리)할 수 있는 적절한 권한을 부여합니다.
- CrewAI Platform 환경 변수에서 GCP 시크릿을 참조합니다.
재배포 없이 전파되는 **로테이션 인식** 시크릿을 원한다면 [GCP Workload Identity Federation](/ko/enterprise/features/secrets-manager/gcp-workload-identity)으로 전환하세요 — 동일한 시크릿 저장소, 정적 자격 증명 없음, kickoff마다 시크릿을 가져옵니다.

View File

@@ -0,0 +1,96 @@
---
title: Secrets Manager 개요
description: 외부 시크릿 저장소를 CrewAI Platform에 연결하고 환경 변수에서 관리되는 시크릿을 참조합니다
sidebarTitle: 개요
icon: "book-open"
---
## 개요
Secrets Manager 기능은 조직에서 외부 시크릿 저장소(AWS Secrets Manager, Google Cloud Secret Manager 또는 Azure Key Vault)를 연결하고, 자동화(Automation) 및 Crew의 환경 변수에서 해당 시크릿을 직접 참조할 수 있게 해줍니다. 플랫폼에 평문 값을 붙여 넣는 대신, 각 공급자별로 자격 증명 한 세트만 저장하고 시크릿을 이름으로 참조합니다.
이를 통해 얻는 이점은 다음과 같습니다:
- **중앙 집중식 저장** — CrewAI Platform 설정을 편집하는 대신 공급자에서 시크릿을 관리합니다. CrewAI Platform은 시크릿 값의 평문 사본을 보관하지 않습니다.
- **노출 감소** — 민감한 값이 CrewAI Platform 설정에 평문으로 존재하지 않습니다.
- **클라우드 네이티브 감사 가능성** — 공급자의 감사 로그에 모든 시크릿 읽기 작업이 기록됩니다.
<Note>
Secrets Manager(정적 자격 증명 및 Workload Identity 경로 모두)는 자동화 파드 이미지에 CrewAI 런타임 버전 `1.14.5` 이상이 필요합니다.
</Note>
## 두 가지 경로: 정적 자격 증명 vs Workload Identity
CrewAI Platform을 클라우드의 시크릿 저장소에 연결하는 방법은 두 가지가 있습니다. **로테이션 동작 방식에서 큰 차이가 있으므로**, 시크릿이 얼마나 자주 로테이션되는지와 보안 정책의 엄격함에 따라 선택하세요.
| 항목 | 정적 자격 증명 | Workload Identity (OIDC Federation) |
|---|---|---|
| **인증** | 장기 액세스 키 / 서비스 계정 JSON을 CrewAI Platform에 저장 | 워커 프로세스마다 발급되는 단기 토큰; 어디에도 정적 자격 증명을 저장하지 않음 |
| **로테이션 전파** | 배포 시점에 해석되어 **배포 컨테이너 이미지에 박힘** — 로테이션된 값을 반영하려면 재배포 필요 | **자동화 실행 시점**에 해석됨 — 로테이션된 값이 재배포 없이 다음 kickoff에 전파됨 |
| **설정 노력** | 더 적음 — 키 붙여 넣기 / 서비스 계정 JSON 업로드 | 더 많음 — CrewAI Platform을 클라우드에 OIDC 공급자로 등록하고 신뢰 정책 구성 |
| **적합한 용도** | 시작 단계, 드물게 로테이션되는 시크릿, 단일 계정 배포 | 프로덕션, 자주 로테이션되는 시크릿, 장기 자격 증명을 금지하는 규정 준수 환경 |
<Note>
**두 경로 모두 환경 변수에서 시크릿을 참조하는 동일한 UI 흐름을 사용합니다**([Secrets Manager 사용하기](/ko/enterprise/features/secrets-manager/usage) 참조). 차이점은 전적으로 플랫폼이 클라우드에 어떻게 인증하고 언제 시크릿 값을 읽는지에 있습니다.
</Note>
### 설정 가이드 선택
| 공급자 | 정적 자격 증명 | Workload Identity |
|---|---|---|
| AWS Secrets Manager | [AWS — 정적 키 / AssumeRole](/ko/enterprise/features/secrets-manager/aws) | [AWS — Workload Identity (OIDC)](/ko/enterprise/features/secrets-manager/aws-workload-identity) |
| Google Cloud Secret Manager | [GCP — 서비스 계정 키](/ko/enterprise/features/secrets-manager/gcp) | [GCP — Workload Identity Federation](/ko/enterprise/features/secrets-manager/gcp-workload-identity) |
| Azure Key Vault | [Azure — 클라이언트 시크릿](/ko/enterprise/features/secrets-manager/azure) | [Azure — Workload Identity Federation](/ko/enterprise/features/secrets-manager/azure-workload-identity) |
<Note>
Secrets Manager 및 Workload Identity UI는 현재 CrewAI Platform에서 **Beta**로 표시되어 있습니다.
</Note>
## 동작 방식
Secrets Manager 설정은 클라우드 공급자와 CrewAI Platform 양쪽 모두에서 작업하는 3단계 흐름입니다:
1. **관리자가 공급자 자격 증명을 구성합니다.** 이는 클라우드 측 작업이며 — 선택한 경로(정적 자격 증명 또는 Workload Identity)에 따라 작업이 다릅니다. 공급자별 가이드에서 처음부터 끝까지 다룹니다.
2. **관리자(또는 권한이 부여된 멤버)가 환경 변수에서 시크릿을 참조합니다.** Environment Variables 페이지에서 공급자 자격 증명을 선택하고 시크릿 이름을 선택합니다. [Secrets Manager 사용하기](/ko/enterprise/features/secrets-manager/usage#referencing-secrets-in-environment-variables)를 참조하세요.
3. **자동화가 런타임에 해석된 값을 받습니다.** Crew 또는 자동화가 실행될 때, CrewAI Platform이 공급자에서 시크릿을 가져와 환경 변수 값으로 주입합니다. Workload Identity의 경우 이 가져오기는 매 kickoff마다 수행됩니다(로테이션 인식). 정적 자격 증명의 경우 이 가져오기는 배포 시점에 수행되고 값이 배포 이미지에 박힙니다.
## 가시성 및 범위
<Note>
WI 기반 환경 변수는 평문 환경 변수와 동일한 할당 모델을 따릅니다: 자동화는 명시적으로 할당된 WI 기반 변수만 해석합니다. 해당 자동화의 Environment Variables 페이지에서 WI 기반 변수를 자동화에 할당하세요; 조직 수준 또는 Studio 프로젝트에 정의된 변수는 할당하기 전까지 kickoff에서 해석되지 않습니다.
</Note>
<Note>
시크릿 가져오기 단계는 매 kickoff마다 실행되지만, 배포에 WI 기반 환경 변수가 할당되어 있을 때만 실제로 작업을 수행합니다. 할당된 변수 각각에 대해, 런타임은 매 crew, flow, training, test, 또는 checkpoint-restore kickoff마다 클라우드 공급자에서 값을 해석하여 프로세스 환경에 기록합니다. 할당된 변수가 없으면 이 단계는 no-op입니다. 그렇지 않은 경우, 비용은 할당된 변수 수에 비례합니다: kickoff당 약간의 추가 지연 시간과 변수당 하나의 클라우드 측 audit log 항목.
</Note>
<Warning>
Workload Identity *구성* 수준에서는 오늘날에도 여전히 조직 전체에 적용됩니다. 조직 내 모든 자동화는 조직이 등록한 모든 Workload Identity 구성을 기반으로 부트스트랩되며, 오늘날에는 특정 Workload Identity 구성을 특정 자동화에 바인딩할 수 없습니다. 자동화별 Workload Identity 범위 지정은 로드맵에 있습니다. 그때까지는 조직 내 모든 자동화가 사용해도 되는 Workload Identity 구성만 등록하세요.
</Warning>
## 권한
Secrets Manager 접근을 제어하는 두 가지 CrewAI Platform 기능:
- `secret_providers` — 공급자 자격 증명을 보거나 관리할 수 있는 사람을 제어합니다.
- `environment_variables` — 시크릿을 참조하는 환경 변수를 포함하여 환경 변수를 생성하고 편집할 수 있는 사람을 제어합니다.
세 번째 기능은 Workload Identity 설정을 제어합니다:
- `workload_identity_configs` — Workload Identity 구성을 보거나 관리할 수 있는 사람을 제어합니다. Workload Identity 경로를 사용하는 경우에만 필요합니다.
소유자(Owner)는 항상 전체 접근 권한을 가집니다. 멤버는 기본적으로 `secret_providers` 또는 `workload_identity_configs`에 대한 접근 권한을 **받지 않으며**, 사용자 정의 역할을 통해 권한을 명시적으로 부여받아야 합니다. 전체 매트릭스와 단계별 지침은 [권한 (RBAC)](/ko/enterprise/features/secrets-manager/usage#permissions-rbac)을 참조하세요.
## 다음 단계
원하는 경로를 선택하세요:
- **정적 자격 증명** (더 간단함, 로테이션 시 재배포 필요):
- [AWS Secrets Manager 구성](/ko/enterprise/features/secrets-manager/aws)
- [Google Cloud Secret Manager 구성](/ko/enterprise/features/secrets-manager/gcp)
- [Azure Key Vault 구성](/ko/enterprise/features/secrets-manager/azure)
- **Workload Identity** (로테이션 인식, 재배포 불필요):
- [AWS Workload Identity 구성](/ko/enterprise/features/secrets-manager/aws-workload-identity)
- [GCP Workload Identity Federation 구성](/ko/enterprise/features/secrets-manager/gcp-workload-identity)
- [Azure Workload Identity Federation 구성](/ko/enterprise/features/secrets-manager/azure-workload-identity)
- 그리고: [환경 변수에서 시크릿을 사용하고 권한 관리하기](/ko/enterprise/features/secrets-manager/usage)

View File

@@ -0,0 +1,137 @@
---
title: Secrets Manager 사용하기
description: CrewAI Platform에서 권한을 관리하고 환경 변수에서 관리되는 시크릿을 참조합니다
sidebarTitle: 사용 및 권한
icon: "list-check"
---
## 개요
이 가이드는 공급자 중립적입니다. 사용자(또는 다른 관리자)가 이미 최소 하나의 Secret Provider Credential을 구성했다고 가정합니다. 원하는 경로에 따라 설정 가이드를 선택하세요:
- 정적 자격 증명: [AWS](/ko/enterprise/features/secrets-manager/aws) · [GCP](/ko/enterprise/features/secrets-manager/gcp)
- Workload Identity (로테이션 인식): [AWS](/ko/enterprise/features/secrets-manager/aws-workload-identity) · [GCP](/ko/enterprise/features/secrets-manager/gcp-workload-identity)
이 가이드를 사용하여 다음을 수행하세요:
- 조직 멤버에게 적절한 권한을 부여합니다.
- 자동화의 환경 변수에서 시크릿을 참조합니다.
- 런타임에서 모든 것이 올바르게 해석되는지 확인합니다.
## 권한 (RBAC)
Secrets Manager를 사용할 때 관련된 세 가지 CrewAI Platform 기능:
- `secret_providers` — **Secret Provider Credentials** 페이지에 대한 접근을 제어합니다.
- `workload_identity_configs` — **Workload Identity** 페이지에 대한 접근을 제어합니다(WI 경로를 사용하는 경우에만 관련됨).
- `environment_variables` — 환경 변수를 생성하거나 편집할 수 있는 사람을 제어합니다.
각 기능에는 두 가지 작업 수준이 있습니다: `read`와 `manage`. `manage`를 부여하면 자동으로 `read`를 포함합니다.
### 부여할 권한
| 목표 | `secret_providers` | `workload_identity_configs` | `environment_variables` |
|---|---|---|---|
| 환경 변수에서 기존 정적 자격 증명 사용 (공급자 편집 불가) | `read` | — | `manage` |
| 정적 자격 증명 생성, 편집 또는 삭제 | `manage` | — | `manage` |
| 환경 변수에서 기존 Workload Identity 기반 자격 증명 사용 | `read` | — | `manage` |
| Workload Identity 구성(및 이를 참조하는 자격 증명) 생성, 편집 또는 삭제 | `manage` | `manage` | `manage` |
<Note>
**소유자(Owner)**는 모든 기능에 대해 자동으로 전체 접근 권한을 가집니다. 기본 **멤버(Member)** 역할은 의도적으로 `secret_providers` 및 `workload_identity_configs`를 제외합니다 — 관리자는 사용자 정의 역할을 통해 멤버에게 명시적으로 옵트인해야 합니다.
</Note>
### 할당 방법
1. CrewAI Platform에서 **Settings** → **Roles**로 이동합니다. 이 페이지에서 새 역할을 생성하고, 각 역할의 권한을 편집하며, 조직의 기존 멤버에게 역할을 할당할 수 있습니다.
{/* SCREENSHOT: Sidebar highlighting Settings → Roles → /images/secrets-manager/usage/06-amp-settings-roles-nav.png */}
{/* SCREENSHOT: Roles list page with "Create Role" button visible → /images/secrets-manager/usage/07-amp-roles-list.png */}
2. **Create Role**을 클릭하여 새 역할을 만들거나, 기존 역할을 열어 권한을 편집합니다.
3. 역할의 권한 편집기에서 위 표에 따라 관련 기능을 토글합니다:
- `secret_providers`: 이 역할이 기존 자격 증명만 사용하면 되는 경우 **read**를 선택하고, 자격 증명을 생성, 편집, 삭제할 수도 있어야 하면 **manage**를 선택합니다.
- `environment_variables`: 역할이 시크릿을 참조하는 환경 변수를 생성할 수 있도록 **manage**를 선택합니다.
{/* SCREENSHOT: Role editor showing the secret_providers feature with read/manage toggles → /images/secrets-manager/usage/08-amp-role-editor-secret-providers-toggles.png */}
{/* SCREENSHOT: Role editor showing environment_variables toggles → /images/secrets-manager/usage/09-amp-role-editor-env-vars-toggles.png */}
4. 역할을 저장합니다.
5. 동일한 Roles 페이지(또는 조직 Members 목록)에서 해당 멤버에게 역할을 할당합니다.
{/* SCREENSHOT: Member assignment screen where the new role is applied to a user → /images/secrets-manager/usage/10-amp-assign-role-to-member.png */}
## 환경 변수에서 시크릿 참조하기
공급자 자격 증명이 존재하고 역할에 적절한 권한이 있으면, 모든 환경 변수에서 관리되는 시크릿을 참조할 수 있습니다.
CrewAI Platform에서 **Environment Variables**로 이동하여 **Add Environment Variables**를 클릭합니다.
{/* SCREENSHOT: Environment Variables empty state with "Add" button → /images/secrets-manager/usage/11-amp-env-vars-empty.png */}
폼을 작성합니다:
- **Key** — 환경 변수의 이름입니다. 문자나 밑줄로 시작해야 하며, 문자, 숫자, 밑줄만 포함해야 합니다. 관례적으로 대문자로 작성합니다(예: `OPENAI_API_KEY`).
- **Value Source** — 값의 출처를 선택합니다:
- **Direct Value** — 직접 입력하는 평문 값입니다. 공급자를 사용하고 싶지 않을 때 사용합니다.
- **Use AWS default** (또는 공급자에 해당하는 항목) — 해당 공급자 유형에서 기본값으로 표시된 자격 증명을 사용합니다.
- **특정 명명된 자격 증명** — 이름으로 자격 증명을 선택합니다. 동일한 공급자에 대해 여러 자격 증명(예: `aws-prod`와 `aws-staging`)이 있고 하나를 명시적으로 선택하려는 경우에 사용합니다.
{/* SCREENSHOT: Env var form with the "Value Source" dropdown open, showing "AWS default" + named credentials → /images/secrets-manager/usage/12-amp-env-var-form-source-selector.png */}
- **Secret Name** — 공급자의 시크릿 이름입니다. 자격 증명이 선택되면 이 필드에서 자동 완성을 제공합니다: 입력을 시작하면 CrewAI Platform이 일치하는 시크릿 이름을 공급자에 쿼리합니다.
구조화된(JSON) 시크릿에서 단일 필드를 추출하려면 `secret-name#json_key` 구문을 사용합니다. 예를 들어, `{"username": "...", "password": "..."}` 값을 가진 시크릿 `database-credentials`가 있다면, `database-credentials#password`로 참조하여 비밀번호만 주입할 수 있습니다.
{/* SCREENSHOT: Env var form with the secret name autocomplete dropdown showing live results → /images/secrets-manager/usage/13-amp-env-var-form-secret-name-autocomplete.png */}
<Note>
**Azure Key Vault 참고:** Azure 시크릿 이름에는 밑줄을 포함할 수 없습니다. CrewAI Platform은 Azure를 호출할 때 `Secret Name` 필드의 밑줄을 자동으로 하이픈으로 변환합니다(예: `db_password`는 `db-password`로 전송됨).
</Note>
**Create**를 클릭하여 변수를 저장합니다.
{/* SCREENSHOT: Env var list with the new variable showing masked value and a "secret" indicator → /images/secrets-manager/usage/14-amp-env-var-created.png */}
<Tip>
기존 환경 변수를 편집할 때 **Value** 필드를 비워두면 현재 값이 유지됩니다. 이는 의도된 동작이며 — 값을 다시 입력하지 않고도 다른 필드(시크릿 이름이나 자격 증명 등)를 변경할 수 있게 해줍니다.
</Tip>
## 작동 여부 검증
엔드 투 엔드 검증 방법:
1. 다른 환경 변수와 동일한 방식으로 자동화, Crew 또는 배포에서 환경 변수를 참조합니다.
2. 자동화를 배포합니다.
3. 실행을 트리거하고 성공적으로 완료되는지 확인합니다.
### 로테이션 동작은 자격 증명 경로에 따라 다릅니다
| 자격 증명 경로 | 시크릿이 읽히는 시점 | 로테이션 시 필요한 작업 |
|---|---|---|
| **정적 자격 증명** (AWS 액세스 키, GCP 서비스 계정 JSON) | **배포 시점** — 값이 배포 이미지에 박힘 | 시크릿 로테이션 후 자동화 재배포 |
| **Workload Identity** (OIDC federation, AWS 또는 GCP) | **모든 자동화 kickoff 시점** — 값을 클라우드에서 새로 가져옴 | 없음 — 로테이션 후 다음 kickoff에서 새 값이 보임 |
<Note>
**로테이션 인식 시크릿이 필요한 경우**(로테이션 시 재배포 없이), Workload Identity 경로를 사용하세요: [AWS WI](/ko/enterprise/features/secrets-manager/aws-workload-identity) 또는 [GCP WI](/ko/enterprise/features/secrets-manager/gcp-workload-identity). 트레이드오프는 초기 설정 노력이 더 많지만(CrewAI Platform을 클라우드에 OIDC 공급자로 등록), 장기적으로는 운영이 더 단순해진다는 점입니다.
</Note>
배포 또는 실행이 시크릿 관련 오류로 실패하면 가장 일반적인 원인을 확인하세요:
| 증상 | 가능한 원인 |
|---|---|
| `no credential found` | 환경 변수가 공급자를 참조하지만 특정 자격 증명이 선택되지 않았고, 해당 공급자 유형에 대한 기본 자격 증명이 설정되어 있지 않습니다. 변수에서 자격 증명을 명시적으로 선택하거나, **Secret Provider Credentials** 페이지에서 자격 증명을 기본값으로 표시하세요. |
| `secret not found` | **Secret Name**의 오타, 또는 자격 증명이 가리키는 공급자 계정/리전에 시크릿이 존재하지 않습니다. 둘 다 다시 확인하세요. |
| 로테이션 후에도 자동화가 이전 값으로 실행됨 (정적 자격 증명 경로) | 이전 값이 배포 컨테이너 이미지에 박혀 있습니다. 로테이션된 값을 가져오려면 자동화를 재배포하세요. 이를 완전히 피하려면 자격 증명을 Workload Identity 경로로 전환하세요. |
| 로테이션 후에도 자동화가 이전 값으로 실행됨 (Workload Identity 경로) | 환경 변수가 WI 기반 자격 증명을 참조하는지 확인하세요(정적 키가 아님). WI를 사용하면 로테이션 후 다음 kickoff에서 새 값이 보여야 합니다. 그렇지 않으면 시크릿이 실제로 클라우드에서 업데이트되었는지 확인하세요(예: `aws secretsmanager get-secret-value`). |
| `JSON key not found` | `secret-name#json_key`를 사용할 때 기본 시크릿은 해당 키를 포함하는 유효한 JSON 객체여야 합니다. 공급자에서 직접 시크릿을 읽어 확인하세요. |
## 다음 단계
- [Secrets Manager 개요로 돌아가기](/ko/enterprise/features/secrets-manager/overview)
- 정적 자격 증명: [AWS](/ko/enterprise/features/secrets-manager/aws) · [GCP](/ko/enterprise/features/secrets-manager/gcp)
- Workload Identity (로테이션 인식): [AWS](/ko/enterprise/features/secrets-manager/aws-workload-identity) · [GCP](/ko/enterprise/features/secrets-manager/gcp-workload-identity)

View File

@@ -0,0 +1,261 @@
---
title: 로테이션 확인
description: 클라우드 공급자에서 로테이션된 시크릿이 재배포 없이 실행 중인 배포에 전파됨을 증명하는 자체 포함된 예제 Crew입니다.
sidebarTitle: 로테이션 확인
icon: "arrows-rotate"
---
## 개요
이 가이드는 **클라우드 공급자에서 로테이션된 시크릿이 바로 다음 자동화 kickoff에서 적용됨**을 검증하는 방법을 보여줍니다 — 재배포 없음, 워커 재시작 없음. Workload Identity 기반 자격 증명([AWS](/ko/enterprise/features/secrets-manager/aws-workload-identity), [GCP](/ko/enterprise/features/secrets-manager/gcp-workload-identity), [Azure](/ko/enterprise/features/secrets-manager/azure-workload-identity))을 구성한 경우에만 관련됩니다. 정적 자격 증명 배포는 로테이션 후 재배포가 필요합니다. 여기에서는 확인할 것이 없습니다.
아래 레시피는 하나의 도구, 하나의 에이전트, 하나의 작업으로 구성된 작은 자체 포함된 Crew를 사용합니다. Crew 프롬프트는 시크릿 값을 절대 참조하지 않으며 — 대신 도구가 `os.environ`에서 이를 읽고 본 것의 SHA-256 fingerprint를 보고합니다. 클라우드 공급자에서 시크릿을 로테이션하고, 다시 kickoff하면 fingerprint가 변경됩니다.
<Note>
원시 값이 아닌 fingerprint를 사용하는 이유? 원시 시크릿을 LLM 출력과 트레이스 로그에 넣는 것은 유출 벡터입니다. fingerprint는 실제 값을 관찰 가능한 곳에 쓰지 않고도 "값이 변경되었다"는 것을 확인하기에 충분합니다.
</Note>
## 사전 준비 사항
이 검증을 실행하기 전에:
- WI 기반 Secret Provider Credential이 구성되어 있어야 합니다([AWS](/ko/enterprise/features/secrets-manager/aws-workload-identity), [GCP](/ko/enterprise/features/secrets-manager/gcp-workload-identity), [Azure](/ko/enterprise/features/secrets-manager/azure-workload-identity)).
- `Secret = true`, 키 `API_KEY`(또는 원하는 이름 — 아래 도구를 일치시키도록 조정)로 클라우드 공급자의 시크릿을 참조하는 배포의 환경 변수.
- 클라우드 공급자에서 시크릿 값을 업데이트할 방법(CLI 액세스 또는 클라우드 콘솔).
- HTTP를 통해 배포를 kickoff할 방법(curl, Postman, 또는 CrewAI Platform의 **Run** 탭).
## 1단계 — 검증 Crew 스캐폴딩
새 Crew 프로젝트를 만듭니다. CrewAI CLI가 구조를 스캐폴딩합니다:
```bash
crewai create crew rotation_verifier --skip_provider
cd rotation_verifier
```
## 2단계 — Credential Echo 도구 추가
`src/rotation_verifier/tools/custom_tool.py`를 시크릿 기반 환경 변수를 읽고 fingerprint를 반환하는 도구로 교체합니다:
```python src/rotation_verifier/tools/credential_echo_tool.py
"""Tool that verifies a runtime-injected secret without leaking the value.
Reads the secret-backed env var (populated by the workload-identity
secrets manager at kickoff time) and returns a stable fingerprint. Never
echo raw credential values into LLM output or logs in production code —
the fingerprint alone is sufficient to confirm rotation worked.
"""
from __future__ import annotations
import hashlib
import os
from crewai.tools import BaseTool
# Match the deployment environment variable's `key` field.
ENV_VAR_NAME = "API_KEY"
class CredentialEchoTool(BaseTool):
name: str = "credential_echo"
description: str = (
"Read the API credential from the worker's environment and return a "
"fingerprint summary. Use this exactly once when asked to verify the "
"current credential. Takes no arguments."
)
def _run(self) -> str:
value = os.environ.get(ENV_VAR_NAME)
if not value:
return (
f"ERROR: {ENV_VAR_NAME} env var is not set. The workload-"
"identity secret fetch did not run, or the deployment is "
"missing the secret-backed env var."
)
fingerprint = hashlib.sha256(value.encode()).hexdigest()[:12]
return f"Authenticated. credential.fingerprint=sha256:{fingerprint}"
```
## 3단계 — 기본 에이전트 및 작업 구성 교체
Crew에는 하나의 에이전트와 하나의 작업이 있습니다 — 둘 다 시크릿 값을 **절대** 언급하지 않는 설명을 가지므로, 작업 키가 로테이션 전반에 걸쳐 안정적으로 유지됩니다.
```yaml src/rotation_verifier/config/agents.yaml
credential_checker:
role: >
Credential Verifier
goal: >
Confirm that the workload-identity-backed secret reached this worker
process and report a fingerprint of the current value.
backstory: >
You are a no-nonsense reliability engineer responsible for verifying
that secrets fetched at runtime via workload identity are present
and fresh. You always use the credential_echo tool exactly once and
report the result verbatim — you never make up values.
```
```yaml src/rotation_verifier/config/tasks.yaml
verify_credential_task:
description: >
Use the credential_echo tool to read the runtime-injected credential
and produce a one-line confirmation. The current year is {current_year}
(use it only in the timestamp; do not transform the credential output).
expected_output: >
A single line in the form:
"[{current_year}] <credential_echo tool's exact output>"
agent: credential_checker
```
## 4단계 — Crew 클래스 연결
```python src/rotation_verifier/crew.py
from crewai import Agent, Crew, Process, Task
from crewai.project import CrewBase, agent, crew, task
from crewai.agents.agent_builder.base_agent import BaseAgent
from rotation_verifier.tools.credential_echo_tool import CredentialEchoTool
@CrewBase
class RotationVerifierCrew():
"""Single-task crew that verifies a workload-identity-backed secret
was successfully fetched at runtime.
Rotate the underlying secret in the cloud provider, kickoff again, and
the credential fingerprint in the agent's report changes — without any
re-deploy, worker restart, or input change. The crew prompt itself
never references the secret value.
"""
agents: list[BaseAgent]
tasks: list[Task]
@agent
def credential_checker(self) -> Agent:
return Agent(
config=self.agents_config["credential_checker"],
tools=[CredentialEchoTool()],
verbose=True,
)
@task
def verify_credential_task(self) -> Task:
return Task(config=self.tasks_config["verify_credential_task"])
@crew
def crew(self) -> Crew:
return Crew(
agents=self.agents,
tasks=self.tasks,
process=Process.sequential,
verbose=True,
)
```
## 5단계 — 배포 및 시크릿 환경 변수 구성
다른 Crew와 마찬가지로 이 Crew를 CrewAI Platform에 배포합니다. 그런 다음 배포의 **Environment Variables** 페이지에서:
- **Key:** `API_KEY` (도구의 `ENV_VAR_NAME`과 일치해야 함)
- **Value Source:** [AWS WI](/ko/enterprise/features/secrets-manager/aws-workload-identity) 또는 [GCP WI](/ko/enterprise/features/secrets-manager/gcp-workload-identity)에서 설정한 WI 기반 자격 증명
- **Secret Name:** 클라우드 공급자의 Secret Manager에 있는 시크릿 이름
{/* SCREENSHOT: Environment Variables form with key=API_KEY, secret-backed value source selected, secret name filled → /images/secrets-manager/verify-rotation/01-env-var-form.png */}
## 6단계 — 첫 번째 Kickoff 실행
`<DEPLOYMENT_AUTH_TOKEN>`과 `<DEPLOYMENT_HOST>`를 배포의 **Run** 탭에 있는 값으로 교체합니다.
```bash
curl -m 60 \
-H "Authorization: Bearer <DEPLOYMENT_AUTH_TOKEN>" \
-H "Content-Type: application/json" \
-X POST https://<DEPLOYMENT_HOST>/kickoff \
-d '{"inputs":{"current_year":"2026"}}'
```
kickoff가 완료되면(몇 초), 에이전트의 출력을 확인합니다. 다음과 같이 표시됩니다:
```
[2026] Authenticated. credential.fingerprint=sha256:004421b993c9
```
fingerprint를 기록합니다. 그 해시는 클라우드 공급자에 현재 있는 어떤 시크릿 값과 고유하게 연결되어 있습니다.
## 7단계 — 클라우드 공급자에서 시크릿 로테이션
<Tabs>
<Tab title="AWS">
```bash
aws secretsmanager update-secret \
--region <REGION> \
--secret-id <SECRET_NAME> \
--secret-string "rotated value"
```
</Tab>
<Tab title="GCP">
새 버전을 추가합니다(Secret Manager는 항상 `latest`를 읽음):
```bash
echo -n "rotated value" | gcloud secrets versions add <SECRET_NAME> \
--data-file=- \
--project=<YOUR_PROJECT_ID>
```
</Tab>
<Tab title="Azure">
```bash
az keyvault secret set \
--vault-name <VAULT_NAME> \
--name <SECRET_NAME> \
--value "rotated value"
```
</Tab>
</Tabs>
## 8단계 — 두 번째 Kickoff 실행 및 비교
```bash
curl -m 60 \
-H "Authorization: Bearer <DEPLOYMENT_AUTH_TOKEN>" \
-H "Content-Type: application/json" \
-X POST https://<DEPLOYMENT_HOST>/kickoff \
-d '{"inputs":{"current_year":"2026"}}'
```
이제 에이전트의 출력은 **다른 fingerprint**를 보여줍니다:
```
[2026] Authenticated. credential.fingerprint=sha256:e2fc89848f72
```
이는 재배포, 워커 재시작 또는 기타 운영자 작업 없이 실행 중인 배포에서 로테이션이 적용되었음을 증명합니다.
## 이것이 검증하는 것 — 그리고 검증하지 않는 것
**검증하는 것:**
- CrewAI Platform에서 WI OIDC 토큰 발급이 작동합니다.
- 클라우드 측 신뢰(AWS의 IAM OIDC 공급자, GCP의 Workload Identity Pool, Azure의 Federated Identity Credential)가 토큰을 수락합니다.
- 클라우드 측 ID(IAM Role / GCP 서비스 계정 / Entra App Registration)가 시크릿을 읽을 수 있는 액세스 권한을 가집니다.
- 시크릿 값이 kickoff 시점에 워커 프로세스의 `os.environ`에 도달합니다.
- 후속 로테이션이 다음 kickoff에 전파됩니다.
**검증하지 않는 것:**
- 실제 프로덕션 Crew가 로테이션을 우아하게 처리하는지 — 예를 들어, 시작 시 환경 변수를 한 번만 읽는 장기 실행 작업은 작업이 끝날 때까지 이전 값을 계속 사용합니다. 적절히 계획하세요: 모듈 임포트 시가 아닌 사용 시점에 시크릿을 읽으세요.
## 왜 프롬프트에서 직접 시크릿을 참조하지 않나요?
더 간단해 보이는 데모는 시크릿 값을 작업 설명에 직접 넣고(예: "`{api_key}`에 대해 조사") 프롬프트를 검사하는 것입니다. **그렇게 하지 마세요.** 두 가지 이유:
1. **LLM 호출 트레이스와 공급자 측 로그에 시크릿이 유출됩니다.** 트레이스 액세스가 있는 모든 사람이 읽을 수 있습니다.
2. **모든 kickoff에서 작업 설명이 변경됩니다.** CrewAI Platform은 설명의 MD5 해시로 작업을 식별합니다. 로테이션되는 값은 kickoff마다 해시가 변경되어 배포 시간 → 런타임 작업 매핑이 깨집니다. 증상: 작업 레코드가 무한정 `pending_run`으로 표시되거나 다중 작업 Crew의 일부 작업만 등록됩니다.
이 가이드의 도구 기반 패턴은 두 문제를 모두 회피합니다: 프롬프트는 정적이고, 도구가 런타임에 환경 변수를 읽으며, 값의 fingerprint만 LLM에 도달합니다.
## 다음 단계
- [Secrets Manager 개요로 돌아가기](/ko/enterprise/features/secrets-manager/overview)
- 검증되면 검증 Crew를 삭제합니다. 실제 Crew는 동일한 패턴을 따라야 합니다: 시크릿은 도구 내부의 `os.environ`을 통해 액세스되며, 절대 프롬프트에 치환되지 않습니다.