인포레터에서 최신 DevOps 트렌드를 격주로 만나보세요!
작업 부하 ID 및 GCP 작업 부하 ID 연합(JWT) 구성
디자인 파트너십
우리는 Teleport Workload Identity의 미래를 함께 만들어 나갈 디자인 파트너를 적극적으로 찾고 있으며, 귀하의 피드백을 듣고 싶습니다.
Teleport 작업 부하 ID는 JWT 형식의 유연한 단기 ID를 발급합니다.
GCP 작업 부하 ID 연합을 사용하면 이러한 JWT를 사용하여 GCP 서비스에 인증할 수 있습니다.
이는 기계가 장기 자격 증명 없이 GCP 서비스에 안전하게 인증해야 하는 경우에 유용할 수 있습니다.
기계는 공유 비밀을 사용하지 않고도 우리 위임된 조인 방법 중 하나를 사용하여 Teleport로 인증할 수 있습니다.
이 가이드에서는 Teleport 작업 부하 ID와 GCP를 구성하여 작업 부하가 GCP Cloud Storage API에 인증하고 버킷에 콘텐츠를 업로드할 수 있도록 합니다.
작동 방식
이 구현은 Teleport 애플리케이션 서비스를 사용하여 GCP API를 보호하는 것과 몇 가지 방법에서 다릅니다:
- GCP에 대한 요청은 Teleport 프록시 서비스를 통해 프록시되지 않으므로 대기 시간이 줄어들지만, 이러한 요청은 Teleport의 감사 로그에 기록되지 않기 때문에 가시성이 줄어듭니다.
- 작업 부하 ID는 커맨드 라인 도구를 포함한 모든 GCP 클라이언트와 함께 작동하지만, 그들의 SDK와도 함께 작동합니다.
- Teleport 애플리케이션 서비스를 사용하여 GCP에 접근하는 것은 머신 ID와 함께 작동하지 않으므로 머신이 AWS에 인증해야 할 때 사용할 수 없습니다.
전제 조건
-
실행 중인 Teleport 클러스터 버전 17.0.0-dev 이상. Teleport를 시작하려면 가입하여 무료 평가판을 이용하거나 데모 환경 설정 방법을 확인하십시오.
-
tctl
관리자 도구와tsh
클라이언트 도구.tctl
및tsh
다운로드 방법에 대한 지침은 설치를 방문하십시오.
- 연결이 가능한지 확인하기 위해
tsh login
으로 로그인한 다음, 현재 자격 증명을 사용하여tctl
명령어를 실행할 수 있는지 확인하십시오. 예를 들어:클러스터에 연결할 수 있고tsh login --proxy=teleport.example.com --user=email@example.comtctl status클러스터 teleport.example.com
버전 17.0.0-dev
CA 핀 sha256:abdc1245efgh5678abdc1245efgh5678abdc1245efgh5678abdc1245efgh5678
tctl status
명령어를 실행할 수 있다면, 현재 자격 증명을 사용하여 워크스테이션에서 후속tctl
명령어를 실행할 수 있습니다.
자신의 Teleport 클러스터를 호스팅하는 경우, Teleport Auth Service를 호스팅하는 컴퓨터에서 전체 권한으로tctl
명령어를 실행할 수도 있습니다. tbot
은 Teleport 작업 부하 ID에 접근해야 하는 작업 부하가 실행될 호스트에 이미 설치되고 구성되어 있어야 합니다. 자세한 내용은 배포 가이드를 참조하십시오.
Teleport 작업 부하 ID로 JWT SVID를 발급하기 위해서는 최소 버전 16.4.3이 필요합니다.
SPIFFE ID 구조 결정
Teleport 작업 부하 ID 내에서 모든 ID는 SPIFFE ID를 사용하여 표현됩니다. 이는 해당 ID가 대표하는 엔터티를 고유하게 식별하는 URI입니다. 스킴은 항상 spiffe://
이며, 호스트는 Teleport 클러스터의 이름이 됩니다. 이 URI의 경로 구조는 귀하의 선택입니다.
이 가이드의 목적을 위해, 우리는 spiffe://example.teleport.sh/svc/example-service
SPIFFE ID에 GCP 접근을 부여할 것입니다.
이미 Teleport 작업 부하 ID를 배포했다면 SPIFFE ID 구조가 이미 설정되어 있을 것입니다. 배포하지 않았다면 SPIFFE ID의 구조를 결정해야 합니다.
Teleport 작업 부하 ID를 GCP 작업 부하 ID 연합과 함께만 사용하는 경우, 허용된 GCP 서비스 계정을 명시적으로 지정하도록 SPIFFE ID를 구조화할 수 있습니다. 그러나 종종 SPIFFE ID를 사용할 작업 부하나 사람의 이름을 지정하는 것이 더 의미가 있습니다. 추가 조언은 모범 사례 안내서를 참조하십시오.
1/4단계. GCP 구성
GCP 작업 부하 ID 연합을 처음 구성하려면 몇 가지 단계가 필요합니다. 이전에 Teleport 클러스터에 대해 GCP 작업 부하 ID 연합을 구성한 경우 일부 단계는 필요하지 않을 수 있습니다.
작업 부하 ID 풀 및 OIDC 공급자 생성
먼저, GCP 내에서 작업 부하 ID 풀 및 이 풀 내의 OIDC 공급자를 생성해야 합니다. 작업 부하 ID 풀은 외부 작업 부하 ID가 GCP 내에서 어떻게 표현되는지를 관리하는 엔터티입니다.
공급자는 외부 ID가 풀에 인증되는 방식을 구성합니다. Teleport 작업 부하 ID가 OIDC 호환 JWT-SVID를 발급하므로 OIDC 공급자 유형을 사용합니다.
풀을 구성할 때, 식별할 이름을 선택해야 합니다. 이 이름은 작업 부하 ID의 원본을 고유하게 식별해야 합니다. Teleport 클러스터의 이름을 따서 이름을 지정하는 것이 좋습니다. 이 예에서는 workload-id-pool
이라고 부릅니다.
공급자를 구성할 때, 발급자 URI를 지정해야 합니다. 이는 Teleport 프록시 서비스의 공개 주소와 경로 /workload-identity
가 추가된 것입니다. OIDC 연합이 작동하려면 GCP가 Teleport 프록시 서비스에 접근할 수 있어야 합니다.
또한 "속성 매핑"을 지정합니다. 이는 GCP가 JWT 내에서 ID를 어떻게 메핑할지를 결정합니다. SVID를 사용하므로 JWT 내에서 sub
클레임을 google.subject
속성에 매핑하여 작업 부하의 SPIFFE ID를 사용하여 GCP에서 권한 결정을 내릴 수 있도록 합니다.
data "google_project" "project" {}
resource "google_iam_workload_identity_pool" "workload_identity" {
workload_identity_pool_id = "workload-id-pool"
}
resource "google_iam_workload_identity_pool_provider" "workload_identity_oidc" {
workload_identity_pool_id = google_iam_workload_identity_pool.workload_identity.workload_identity_pool_id
workload_identity_pool_provider_id = "workload-id-oidc"
attribute_mapping = {
// Maps the `sub` claim within the JWT to the `google.subject` attribute.
// This will allow it to be used to make Authz decisions in GCP.
"google.subject" = "assertion.sub"
}
oidc {
// Replace example.teleport.sh with the hostname of your Proxy Service's
// public address.
issuer_uri = "https://example.teleport.sh/workload-identity"
}
}
gcloud
CLI를 사용하여 작업 부하 ID 풀을 생성합니다:
Replace "workload-id-pool" with a meaningful, unique name.
gcloud iam workload-identity-pools create workload-id-pool \ --location="global"
gcloud
CLI를 사용하여 작업 부하 ID 공급자를 생성합니다:
Replace "workload-id-pool" with the name of the pool you just created and
"workload-id-oidc" with a meaningful, unique name.
gcloud iam workload-identity-pools providers create-oidc workload-id-oidc \ --location="global" \ # This should match the name of the pool you just created.--workload-identity-pool="workload-id-pool" \ # Replace example.teleport.sh with the hostname of your Proxy Service's # public address. --issuer-uri="https://example.teleport.sh/workload-identity" \ # Maps the `sub` claim within the JWT to the `google.subject` attribute. # This will allow it to be used to make Authz decisions in GCP. --attribute-mapping="google.subject=assertion.sub"
GCP 스토리지 버킷 및 RBAC 생성
이 가이드의 목적을 위해 작업 부하에 GCP 스토리지 버킷에 대한 액세스를 부여할 것입니다. 필요한 경우 이 단계를 변경하여 원하는 GCP 내 다른 서비스에 대한 액세스를 부여할 수 있습니다.
작업 부하가 서비스 계정을 가정하지 않고 리소스에 직접 액세스할 수 있도록 할 것입니다.
이를 위해, 이미 구성한 속성 매핑에 기반한 작업 부하 신원 연합 풀에서 생성된 주체를 사용합니다. 이 주체는 IAM 정책에서 직접 사용되어 작업 부하 신원에 대한 권한을 부여할 수 있습니다. 주체는 GCP 프로젝트 번호, 작업 부하 신원 풀의 이름 및 SPIFFE ID를 포함합니다. 형식은 다음과 같습니다:
principal://iam.googleapis.com/projects/$PROJECT_NUMBER/locations/global/workloadIdentityPools/$POOL_NAME/subject/$SPIFFE_ID
작업 부하가 서비스 계정을 가정할 수 있는 능력을 부여하는 것도 가능합니다. 이 가이드에서는 다루지 않지만, 필요한 권한으로 이미 생성된 서비스 계정을 사용하도록 작업 부하를 허용해야 하는 시나리오에서 유용할 수 있습니다.
resource "google_storage_bucket" "demo" {
// 의미 있는 고유 이름으로 교체하세요.
name = "example"
location = "EU"
force_destroy = true
uniform_bucket_level_access = true
}
locals {
// 버킷에 액세스할 작업 부하의 SPIFFE ID로 교체하세요.
allow_spiffe_id = "spiffe://example.teleport.sh/svc/example-service"
}
resource "google_storage_bucket_iam_binding" "binding" {
bucket = google_storage_bucket.demo.name
role = "roles/storage.admin"
members = [
"principal://iam.googleapis.com/projects/${data.google_project.project.number}/locations/global/workloadIdentityPools/${google_iam_workload_identity_pool.leaf_cluster.workload_identity_pool_id}/subject/${local.allow_spiffe_id}",
]
}
gcloud
CLI를 사용하여 스토리지 버킷을 생성합니다:
"example"를 의미 있는 고유 이름으로 교체하세요.
gcloud storage buckets create gs://example \ --location=EU \ --uniform-bucket-level-access
gcloud
CLI를 사용하여 작업 부하에 버킷에 대한 액세스를 부여합니다:
ROLE="roles/storage.admin"PROJECT_NUMBER를 GCP 프로젝트 번호로 교체하세요.
PROJECT_NUMBER="123456789000"POOL_ID를 생성한 작업 부하 신원 풀의 ID로 교체하세요.
POOL_ID="workload-id-pool"SPIFFE_ID를 버킷에 액세스할 작업 부하의 SPIFFE ID로 교체하세요.
SPIFFE_ID="spiffe://example.teleport.sh/svc/example-service"MEMBER="principal://iam.googleapis.com/projects/${PROJECT_NUMBER}/locations/global/workloadIdentityPools/${POOL_ID}/subject/${SPIFFE_ID}"gcloud storage buckets add-iam-policy-binding gs://example --member=$MEMBER --role=$ROLE
2/4단계. Teleport RBAC 구성
이제 선택한 SPIFFE ID를 포함하는 JWT가 발급될 수 있도록 Teleport를 구성해야 합니다.
다음 내용을 포함하여 role.yaml
을 생성합니다:
kind: role
version: v6
metadata:
name: my-workload-gcp
spec:
allow:
spiffe:
- path: /svc/example-service
다음을 교체하세요:
my-workload-gcp
를 역할에 대한 설명적인 이름으로 교체하세요./svc/example-service
를 선택한 SPIFFE ID의 경로 부분으로 교체하세요.
다음 명령어를 사용하여 이 역할을 Teleport 클러스터에 적용합니다:
tctl create -f role.yaml
이제 이 역할을 봇에 할당해야 합니다:
tctl bots update my-bot --add-roles my-workload-gcp
3/4단계. 작업 부하 ID JWT 발급
이제 tbot
을 구성하여 작업 부하에 대한 단기 JWT SVID를 발급하고 갱신합니다. JWT는 디스크에 파일로 기록되며, 이후 GCP 클라이언트 및 SDK가 이 파일을 읽도록 구성할 수 있습니다.
이를 구성하기 전에 JWT SVID에서 요청할 올바른 대상을 결정해야 합니다. 이는 방금 생성한 작업 부하 ID 연합 구성에 특정하며 세 가지 구성 요소를 포함합니다:
- GCP 프로젝트의 프로젝트 번호
- GCP에 구성된 작업 부하 ID 연합 풀의 이름
- GCP에 구성된 작업 부하 ID 연합 공급자의 이름
다음 형식을 가집니다: https://iam.googleapis.com/projects/$PROJECT_NUMBER/locations/global/workloadIdentityPools/$POOL_NAME/providers/$PROVIDER_NAME
.
이미 배포된 tbot
서비스를 가져와 SPIFFE SVID를 발급하도록 다음을 tbot
구성 파일에 추가합니다:
outputs:
- type: spiffe-svid
destination:
type: directory
path: /opt/workload-identity
svid:
path: /svc/example-service
jwts:
- audience: https://iam.googleapis.com/projects/123456789000/locations/global/workloadIdentityPools/workload-id-pool/providers/workload-id-oidc
file_name: gcp-jwt
다음 항목을 교체합니다:
123456789000
을 귀하의 GCP 프로젝트 번호로.workload-id-pool
을 귀하의 작업 부하 ID 연합 풀의 이름으로.workload-id-oidc
을 귀하의 작업 부하 ID 연합 공급자의 이름으로.
새 구성을 적용하기 위해 tbot
서비스를 재시작합니다. /opt/workload-identity/gcp-jwt
경로에 JWT가 포함된 파일이 생성된 것을 확인할 수 있습니다.
4/4단계. GCP CLI 및 SDK 구성
마지막으로, GCP CLI 및 SDK가 작업 부하 ID를 사용하여 인증하도록 구성하는 구성 파일을 생성해야 합니다. 이 구성 파일은 tbot
이 작성하는 JWT 파일의 경로를 지정하며, 사용할 작업 부하 ID 연합 풀 및 공급자를 지정합니다.
다음 명령어를 사용하여 gcloud
CLI로 이 구성 파일을 생성할 수 있습니다:
gcloud iam workload-identity-pools create-cred-config \ projects/123456789000/locations/global/workloadIdentityPools/workload-id-pool/providers/workload-id-oidc \ --output-file=gcp-workload-identity.json \ --credential-source-file=/opt/workload-identity/gcp-jwt \ --credential-source-type=text
다음 항목을 교체합니다:
123456789000
을 귀하의 GCP 프로젝트 번호로.workload-id-pool
을 귀하의 작업 부하 ID 연합 풀의 이름으로.workload-id-oidc
을 귀하의 작업 부하 ID 연합 공급자의 이름으로./opt/workload-identity/gcp-jwt
을tbot
이 작성하는 JWT 파일의 경로로.
명령어를 실행하면 현재 디렉토리에 gcp-workload-identity.json
이라는 파일이 생성됩니다.
gcloud
CLI
작업 부하 ID를 사용하여 인증하도록 gcloud
CLI를 구성하려면, gcloud auth login
명령어를 사용하고 방금 생성한 구성 파일의 경로를 지정합니다:
gcloud auth login --cred-file gcp-workload-identity.json
이제 GCP 저장소 API에 인증을 테스트할 수 있습니다. 버킷에 업로드할 파일을 생성합니다:
echo "Hello, World!" > hello.txt
이제 gcloud
CLI를 사용하여 이 파일을 귀하의 버킷에 업로드합니다:
gcloud storage cp hello.txt gs://example
모든 것이 올바르게 구성되었다면, 귀하는 이 파일이 귀하의 버킷에 업로드된 것을 확인할 수 있습니다. GCP의 감사 로그를 검사하면 요청이 작업 부하 ID를 사용하여 인증되었음을 나타내고 요청을 생성한 작업의 SPIFFE ID를 지정합니다.
GCP SDKs
GCP SDKs를 Workload Identity를 사용하여 인증하도록 구성하려면, 방금 생성한 구성 파일의 경로로 GOOGLE_APPLICATION_CREDENTIALS
환경 변수를 설정해야 합니다:
export GOOGLE_APPLICATION_CREDENTIALS=gcp-workload-identity.json
다음 단계
- GCP Workload Identity Federation documentation: Workload Identity Federation에 대한 공식 GCP 문서입니다.
- Workload Identity Overview: Teleport Workload Identity 개요입니다.
- JWT SVID Overview: Teleport Workload Identity에 의해 발급된 JWT SVIDs 개요입니다.
- Best Practices: 운영 환경에서 Workload Identity를 사용하는 모범 사례입니다.
- configuration reference를 읽고 사용 가능한 모든 구성 옵션을 탐색하십시오.