Google Chat 사용자 ID를 이메일로 변환: 최소 권한 방식

발행: (2025년 12월 24일 오전 03:43 GMT+9)
7 min read
원문: Dev.to

Source: Dev.to

Google Workspace Developers profile image
Justin Poehnelt

Google Chat 봇을 만든 적이 있다면, 이 문제에 부딪혔을 가능성이 높습니다: Chat API가 사용자 ID(예: users/1154…)가 포함된 membership event를 보내지만, 이메일 필드를 전혀 포함하지 않습니다. 비즈니스 로직에서는 보통 그 이메일 주소가 필요합니다.

  • People API를 시도해 볼 수 있지만, 서비스 계정에 연락처가 없기 때문에 빈 필드를 반환합니다.
  • Admin SDK는 작동하지만, 기본 서비스‑account 호출은 관리자 권한이 없어서 403 Forbidden을 반환합니다.
  • Domain‑Wide Delegation (DwD)을 사용하면 봇이 관리자를 가장할 수 있지만, 봇에게 모든 사용자를 가장할 권한을 부여하는 것은 마치 견과류를 깨기 위해 대형 해머를 사용하는 느낌입니다.

더 나은 방법이 있습니다. 서비스 계정에 읽기 전용 사용자 지정 관리자 역할을 직접 할당하면, 전체 도메인 접근 권한을 부여하지 않고도 이메일을 안전하게 조회할 수 있습니다.

Source:

전략

DwD를 사용해 서비스 계정이 관리자를 가장 하게 하는 대신, 서비스 계정을 자체적으로 관리자로 만들되—맞춤 역할을 사용해 읽기 전용 관리자만 부여합니다.

서비스 계정에 할당된 읽기 전용 사용자 맞춤 역할
서비스 계정에 할당된 읽기 전용 사용자 맞춤 역할.

1. 맞춤 역할 만들기

  1. Google Admin ConsoleRolesCreate a custom role를 엽니다.
  2. 이름을 지정합니다(예: Read Users).
  3. 하나의 권한을 추가합니다: Admin API Privileges > Users > Read.
  4. 역할을 저장합니다.
    맞춤 역할에 대해 자세히 알아보기.

2. 역할 할당

새로 만든 맞춤 역할을 서비스 계정의 이메일 주소(예: my-bot@my-project.iam.gserviceaccount.com)에 직접 할당합니다.

3. 로컬 개발

Domain‑Wide Delegation(서비스 계정이 사용자를 가장하는 방식) 대신 IAM 서비스 계정 가장(서비스 계정 as 로 실행)을 사용해 로컬에서 스크립트를 실행합니다. 이렇게 하면 로컬 환경에 키가 필요하지 않게 됩니다.

해결책

Google Cloud에서 프로덕션 환경에서는 일반적으로 Application Default Credentials (ADC) 를 사용합니다. ADC는 서비스 계정으로 인증합니다. 서비스 계정 자체가 이제 관리자 권한을 가지고 있기 때문에 추가적인 위임 로직이 필요하지 않으며, API 호출이 바로 동작합니다.

로컬 테스트에서는 장기 저장 JSON 키를 피하기 위해 Service Account Impersonation 을 사용해 일시적으로 봇으로 동작합니다.

Bash 스크립트 – 로컬 테스트 흐름

#!/bin/bash
# -------------------------------------------------
# Prerequisites
# -------------------------------------------------
# 1. In Google Cloud IAM, grant your user the role
#    "Service Account Token Creator" on the service account.
# 2. In Google Workspace, create a custom admin role with
#    "Admin API Privileges > Users > Read" and assign it
#    to the service‑account email.
# -------------------------------------------------
# Configuration
# -------------------------------------------------
# Replace with the ID from the Chat API
TARGET_USER_ID="115429828439139643037"
SERVICE_ACCOUNT="your-bot@your-project.iam.gserviceaccount.com"

echo "Generating impersonated access token for $SERVICE_ACCOUNT..."

# 1️⃣ Generate an access token for the service account.
#    We request the admin.directory.user.readonly scope.
ACCESS_TOKEN=$(gcloud auth print-access-token \
    --impersonate-service-account="$SERVICE_ACCOUNT" \
    --scopes="https://www.googleapis.com/auth/admin.directory.user.readonly")

if [[ -z "$ACCESS_TOKEN" ]]; then
    echo "Error: Failed to generate impersonated token."
    exit 1
fi

# 2️⃣ Query Admin SDK
echo "Querying Admin SDK for User ID: $TARGET_USER_ID..."
RESPONSE=$(curl -fs -X GET \
    -H "Authorization: Bearer $ACCESS_TOKEN" \
    -H "Content-Type: application/json" \
    "https://admin.googleapis.com/admin/directory/v1/users/${TARGET_USER_ID}?projection=basic")

# 3️⃣ Parse the output
EMAIL=$(echo "$RESPONSE" | jq -r '.primaryEmail')
echo "Resolved email: $EMAIL"

참고: --scopes 플래그가 예상대로 동작하지 않을 수 있으며 impersonated_account 유형에서는 무시된다는 경고는 gcloud CLI에서 위임을 사용할 때 알려진 특성입니다. 아래 토큰 페이로드에서 요청한 스코프가 여전히 포함되어 있고 API 호출이 성공함을 확인할 수 있습니다.

예시 액세스‑토큰 페이로드

{
  "issued_to": "108111659397065155772",
  "audience": "108111659397065155772",
  "user_id": "108111659397065155772",
  "scope": "https://www.googleapis.com/auth/userinfo.email openid https://www.googleapis.com/auth/admin.directory.user.readonly",
  "expires_in": 3599,
  "email": "admin-read-test@list-user-emails-test.iam.gserviceaccount.com",
  "verified_email": true,
  "access_type": "online"
}

쿼리 결과

------------------------------------
Success! Resolved to: justin@example.com
------------------------------------

Beyond Email Resolution

서비스 계정이 자체적으로 작동하기 때문에 ID를 해결하는 것에만 제한되지 않습니다. Users > Read 권한을 부여하면 다음도 할 수 있습니다:

  • Admin SDK를 사용하여 Search Users 수행
  • 조직 단위 나열

모두 슈퍼 관리자가 아니어도 되며 도메인‑와이드 위임이 필요하지 않습니다.

왜 이것이 더 좋은가

  • 키 없음 – 장기간 유효한 JSON 키 파일을 노트북에 다운로드할 필요가 없습니다.
  • 감사 로그 – 관리 감사 로그에 서비스 계정이 읽기 작업을 수행한 것으로 표시되며, 위임된 슈퍼 관리자가 아닙니다.
  • 최소 권한 – 봇은 사용자만 읽을 수 있습니다. 계정을 삭제하거나 비밀번호를 재설정하거나 Gmail을 읽는 등 도메인‑와이드 위임 범위와 관련된 일반적인 위험을 초래하지 않습니다.

이 접근 방식은 보안 팀을 만족시키면서도 봇이 정상적으로 작동하도록 합니다.


Resolving Google Chat User IDs to Emails: The Least Privilege Way © 2025 by Justin Poehnelt is licensed under CC BY‑SA 4.0.

Back to Blog

관련 글

더 보기 »

고트래픽 Node.js API 최적화 전략

Node.js의 이벤트‑드리븐 아키텍처를 활용하세요. I/O 작업을 논블로킹으로 유지하고, 블로킹 코드 대신 async/await 또는 promises를 사용합니다. javascript // Use async…