このドキュメントでは、Identity-Aware Proxy(IAP)で保護されたリソースをユーザー アカウントまたはサービス アカウントから認証する方法について説明します。
プログラムによるアクセスとは、コマンドライン ツール、サービス間呼び出し、モバイルアプリなどのブラウザ以外のクライアントから IAP で保護されたアプリケーションを呼び出すことを指します。ユースケースによっては、ユーザー認証情報またはサービス認証情報を使用して IAP の認証を行う必要があります。
ユーザー アカウントは、個々のユーザーに属します。ユーザーの代わりにアプリケーションが IAP で保護されたリソースにアクセスする必要がある場合、ユーザー アカウントを認証します。詳しくは、ユーザー アカウントをご覧ください。
- サービス アカウントは、個々のユーザーではなくアプリケーションを表します。アプリケーションから IAP で保護されたリソースにアクセスできるようにする場合、サービス アカウントを認証します。詳細については、サービス アカウントをご覧ください。
IAP は、プログラムによるアクセスに対して次のタイプの認証情報をサポートしています。
OAuth 2.0 ID トークン - Google が発行した、人間ユーザーまたはサービス アカウント用のトークン。オーディエンス クレームが IAP アプリケーションのリソース ID に設定されています。
サービス アカウント署名付き JWT - サービス アカウントの自己署名または Google 発行の JWT トークン。
これらの認証情報を、リクエストの Authorization または Proxy-Authorization HTTP ヘッダーに含めて IAP に送信します。
始める前に
デベロッパー アカウント、サービス アカウント、またはモバイルアプリの認証情報を使用してプログラムでアクセスするアプリケーションがあることを確認します。
1 つ以上の OAuth 2.0 クライアントを作成するには、プログラムによるアクセスをご覧ください。
ユーザー アカウントを認証する
デスクトップ アプリまたはモバイルアプリからアプリケーションへのユーザー アクセスを有効にして、プログラムが IAP で保護されたリソースを操作できるようにすることができます。
モバイルアプリから認証する
モバイルアプリ用の OAuth 2.0 クライアント ID を作成するか、既存の OAuth 2.0 クライアント ID を使用します。既存の OAuth 2.0 クライアント ID を使用するには、OAuth クライアントを共有する方法の手順に沿って操作します。アプリケーションへのプログラムによるアクセスのために、OAuth クライアント ID を許可リストに追加します。
IAP で保護されたリソースの OAuth 2.0 クライアント ID の ID トークンを取得します。
Android: Google ログイン API を使用して、OpenID Connect(OIDC)トークンをリクエストします。
requestIdTokenクライアント ID を、接続先のリソースのクライアント ID に設定します。iOS: Google ログインを使用して ID トークンを取得します。
Authorization: Bearerヘッダーに ID トークンを含めて、IAP で保護されたリソースに対して認証済みリクエストを送信します。
デスクトップ アプリから認証する
このセクションでは、デスクトップ コマンドラインからユーザー アカウントを認証する方法について説明します。
デベロッパーがコマンドラインからアプリケーションにアクセスできるようにするには、デスクトップ OAuth 2.0 クライアント ID を作成するか、既存のデスクトップ OAuth クライアント ID を共有します。
アプリケーションのプログラムによるアクセスの許可リストに OAuth ID を追加します。
アプリケーションにログインする
各デベロッパーは、IAP で保護されたアプリにアクセスするためにログインする必要があります。gcloud CLI を使用するなどの方法で、プロセスをスクリプトにパッケージ化できます。次の例では、curl を使用してログインし、アプリケーションにアクセスするために使用できるトークンを生成します。
Google Cloud リソースにアクセスできるアカウントにログインします。
受信リクエストをエコーできるローカル サーバーを起動します。
# Example using Netcat (http://netcat.sourceforge.net/) nc -k -l 4444下記の URI に移動します。
DESKTOP_CLIENT_IDは、[デスクトップ アプリ] のクライアント ID です。https://accounts.google.com/o/oauth2/v2/auth?client_id=DESKTOP_CLIENT_ID&response_type=code&scope=openid%20email&access_type=offline&redirect_uri=http://localhost:4444&cred_ref=trueローカル サーバーの出力で、リクエスト パラメータを探します。
GET /?code=CODE&scope=email%20openid%20https://www.googleapis.com/auth/userinfo.email&hd=google.com&prompt=consent HTTP/1.1CODE 値をコピーして、次のコマンドの CODE を、デスクトップ アプリのクライアント ID とシークレットに置き換えます。
curl --verbose \ --data client_id=DESKTOP_CLIENT_ID \ --data client_secret=DESKTOP_CLIENT_SECRET \ --data code=CODE \ --data redirect_uri=http://localhost:4444 \ --data grant_type=authorization_code \ https://oauth2.googleapis.com/tokenこのコマンドは、
id_tokenフィールドとaccess_tokenフィールドを含む JSON オブジェクトを返します。どちらのトークンを使用してもアプリケーションにアクセスできます。
アプリケーションにアクセスする
アプリにアクセスするには、Authorization: Bearer ヘッダーに id_token または access_token を含めます。
curl --verbose --header 'Authorization: Bearer TOKEN' URL
更新トークン
ログインフロー中に生成された更新トークンを使用して、新しい ID トークンとアクセス トークンを取得できます。これは、元のトークンが期限切れになった際に役立ちます。各トークンは約 1 時間有効です。その間、特定のアプリに対して複数のリクエストを行うことができます。
次の例では、curl を使用して更新トークンを使用し、新しい ID トークンとアクセス トークンを取得します。この例では、REFRESH_TOKEN はログインフローで生成したトークンです。DESKTOP_CLIENT_ID と DESKTOP_CLIENT_SECRET は、ログインフローで使用したものと同じです。
curl --verbose \
--data client_id=DESKTOP_CLIENT_ID \
--data client_secret=DESKTOP_CLIENT_SECRET \
--data refresh_token=REFRESH_TOKEN \
--data grant_type=refresh_token \
https://oauth2.googleapis.com/token
このコマンドは、アプリにアクセスするために使用できる新しい id_token フィールドを含む JSON オブジェクトを返します。
サービス アカウントを認証する
サービス アカウント JWT、OpenID Connect(OIDC)トークン、または OAuth 2.0 アクセス トークンを使用して、IAP で保護されたリソースでサービス アカウントを認証できます。次の表に、さまざまな認証トークンとその機能の違いの概要を示します。
| 認証機能 | サービス アカウント JWT | OpenID Connect トークン | OAuth 2.0 アクセス トークン |
|---|---|---|---|
| コンテキストアウェア アクセスのサポート | |||
| OAuth 2.0 クライアント ID の要件 | |||
| トークンのスコープ | IAP で保護されたリソースの URL | OAuth 2.0 クライアント ID | openid と https://www.googleapis.com/auth/userinfo.email |
サービス アカウントの JWT で認証する
IAP は、Google ID、Identity Platform、Workforce Identity 連携で構成されたアプリケーションのサービス アカウント JWT 認証をサポートしています。JWT を使用してサービス アカウントを認証する手順は次のとおりです。
呼び出し元のサービス アカウントにサービス アカウント トークン作成者のロール(
roles/iam.serviceAccountTokenCreator)を付与します。このロールは、JWT などの有効期間の短い認証情報を作成する権限をプリンシパルに付与します。
IAP で保護されたリソースの JWT を作成します。
サービス アカウントの秘密鍵を使用して JWT に署名します。
JWT を作成する
作成された JWT のペイロードは、次の例のようになります。
{
"iss": SERVICE_ACCOUNT_EMAIL_ADDRESS,
"sub": SERVICE_ACCOUNT_EMAIL_ADDRESS,
"aud": TARGET_URL,
"iat": IAT,
"exp": EXP,
}
issフィールドとsubフィールドに、サービス アカウントのメールアドレスを指定します。メールアドレスは、サービス アカウントの JSON ファイルのclient_emailフィールドにあります。または、入力として指定されます。一般的な形式:service-account@PROJECT_ID.audフィールドには、IAP で保護されたリソースの正確な URL またはパス ワイルドカード(/*)を含む URL を指定します(例:https://example.com/、https://example.com/*)。audフィールドに正確な URL が含まれている JWT は、その特定の URL にのみアクセスできます。audフィールドにパス ワイルドカード(/*)を含む JWT は、末尾の*を除いたaud文字列が先頭に付加されたすべての URL にアクセスできます。iatフィールドには現在の Unix エポック時間を指定し、expフィールドには 3,600 秒以内の時間を指定します。これは、JWT の有効期限を定義します。
JWT に署名する
JWT に署名するには、次のいずれかの方法を使用します。
IAM Credentials API を使用して、秘密鍵に直接アクセスすることなく JWT に署名します。
ローカル認証情報キーファイルを使用して、JWT にローカルで署名します。
IAM Service Account Credentials API を使用して JWT に署名する
IAM Service Account Credentials API を使用して、サービス アカウントの JWT に署名します。このメソッドは、サービス アカウントに関連付けられた秘密鍵を取得し、それを使用して JWT ペイロードに署名します。これにより、秘密鍵に直接アクセスせずに JWT に署名できます。
IAP への認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証を設定するをご覧ください。
gcloud
次のコマンドを実行して、JWT ペイロードを含むリクエストを準備します。
cat > claim.json << EOM { "iss": "SERVICE_ACCOUNT_EMAIL_ADDRESS", "sub": "SERVICE_ACCOUNT_EMAIL_ADDRESS", "aud": "TARGET_URL", "iat": $(date +%s), "exp": $((`date +%s` + 3600)) } EOM次の Google Cloud CLI コマンドを使用して、
claim.jsonのペイロードに署名します。gcloud iam service-accounts sign-jwt --iam-account="SERVICE_ACCOUNT_EMAIL_ADDRESS" claim.json output.jwtリクエストが成功すると、
output.jwtには、IAP で保護されたリソースへのアクセスに使用できる署名付き JWT が含まれます。
Python
import datetime
import json
import google.auth
from google.cloud import iam_credentials_v1
def generate_jwt_payload(service_account_email: str, resource_url: str) -> str:
"""Generates JWT payload for service account.
Creates a properly formatted JWT payload with standard claims (iss, sub,
aud, iat, exp) needed for IAP authentication.
Args:
service_account_email (str): Specifies the service account that the
JWT is created for.
resource_url (str): Specifies the scope of the JWT, the URL that the
JWT will be allowed to access.
Returns:
str: JSON string containing the JWT payload with properly formatted
claims.
"""
# Create current time and expiration time (1 hour later) in UTC
iat = datetime.datetime.now(tz=datetime.timezone.utc)
exp = iat + datetime.timedelta(seconds=3600)
# Convert datetime objects to numeric timestamps (seconds since epoch)
# as required by JWT standard (RFC 7519)
payload = {
"iss": service_account_email,
"sub": service_account_email,
"aud": resource_url,
"iat": int(iat.timestamp()),
"exp": int(exp.timestamp()),
}
return json.dumps(payload)
def sign_jwt(target_sa: str, resource_url: str) -> str:
"""Signs JWT payload using ADC and IAM credentials API.
Uses Google Cloud's IAM Credentials API to sign a JWT. This requires the
caller to have iap.webServiceVersions.accessViaIap permission on the
target service account.
Args:
target_sa (str): Service Account JWT is being created for.
iap.webServiceVersions.accessViaIap permission is required.
resource_url (str): Audience of the JWT and scope of the JWT token.
This is the URL of the IAP-secured application.
Returns:
str: A signed JWT that can be used to access IAP-secured applications.
Use in Authorization header as: 'Bearer <signed_jwt>'
"""
# Get default credentials from environment or application credentials
source_credentials, project_id = google.auth.default()
# Initialize IAM credentials client with source credentials
iam_client = iam_credentials_v1.IAMCredentialsClient(credentials=source_credentials)
# Generate the service account resource name.
# Project should always be "-".
# Replacing the wildcard character with a project ID is invalid.
name = iam_client.service_account_path("-", target_sa)
# Create and sign the JWT payload
payload = generate_jwt_payload(target_sa, resource_url)
# Sign the JWT using the IAM credentials API
response = iam_client.sign_jwt(name=name, payload=payload)
return response.signed_jwt
curl
次のコマンドを実行して、JWT ペイロードを含むリクエストを準備します。
cat << EOF > request.json { "payload": JWT_PAYLOAD } EOFIAM を使用して JWT に署名する
Service Account Credentials API:
curl -X POST \ -H "Authorization: Bearer $(gcloud auth print-access-token)" \ -H "Content-Type: application/json; charset=utf-8" \ -d @request.json \ "https://iamcredentials./v1/projects/-/serviceAccounts/SERVICE_ACCOUNT_EMAIL_ADDRESS:signJwt"リクエストが成功すると、レスポンスで署名付き JWT が返されます。
JWT を使用して、IAP で保護されたリソースにアクセスします。
ローカルの認証情報キーファイルから JWT に署名する
JWT は、サービス アカウントの秘密鍵を使用して署名されます。
サービス アカウント キー ファイルがある場合は、JWT にローカルで署名できます。
JWT にローカルで署名する場合は、ペイロードに JWT ヘッダーを含めます。ヘッダーの kid フィールドには、サービス アカウントの秘密鍵 ID を使用します。これは、サービス アカウントの認証情報 JSON ファイルの private_key_id フィールドにあります。ファイル内の秘密鍵は、JWT の署名に使用されます。
アプリケーションにアクセスする
アプリケーションにアクセスするには、署名付き JWT を Authorization ヘッダーに含めます。
curl --verbose --header 'Authorization: Bearer SIGNED_JWT' URL
サービス アカウントの OIDC トークンで認証する
サービス アカウントの OIDC トークンを使用して認証するには、次の操作を行います。
新しい OIDC クライアント ID を作成するか、既存の ID を使用します。
新しい OAuth 2.0 クライアント ID を作成するには、次の操作を行います。
Google Auth を使用するようにアプリケーションを登録していることを確認します(まだ登録していない場合)。
Google Auth Platform ページに移動します。
プロジェクトが選択されていない場合は、プロジェクトを作成するよう求められます。
[Create Client] をクリックします。
適切なアプリケーションの種類を選択し、必要な追加情報を入力します。
選択したクライアント タイプに必要な情報を入力します。クライアントを作成するには、[作成] をクリックします。
既存の OAuth 2.0 クライアント ID を使用する: OAuth クライアントを共有する方法の手順に沿って操作します。
アプリケーションのプログラムによるアクセスの許可リストに OAuth ID を追加します。
デフォルトのサービス アカウントが、IAP で保護されたプロジェクトのアクセスリストに追加されていることを確認します。
IAP で保護されたリソースにリクエストを送信する場合は、Authorization ヘッダーにトークンを含める必要があります。Authorization: 'Bearer OIDC_TOKEN'
次のコードサンプルは、OIDC トークンを取得する方法を示しています。
デフォルトのサービス アカウントの OIDC トークンを取得する
Compute Engine、App Engine、Cloud Run のデフォルトのサービス アカウント用 OIDC トークンを取得するには、以下のコードサンプルを参照して、IAP で保護されたリソースにアクセスするためのトークンを生成します。
C#
IAP への認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証を設定するをご覧ください。
Go
IAP への認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証の設定をご覧ください。
Java
IAP への認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証の設定をご覧ください。
Node.js
IAP への認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証の設定をご覧ください。
PHP
IAP への認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証の設定をご覧ください。
Python
IAP への認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証の設定をご覧ください。
Ruby
IAP への認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証の設定をご覧ください。
ローカルのサービス アカウント キー ファイルから OIDC トークンを取得する
サービス アカウント キーファイルを使用して OIDC トークンを生成するには、キーファイルを使用して JWT アサーションを作成して署名し、そのアサーションを ID トークンと交換します。次の Bash スクリプトは、このプロセスを示しています。
Bash
#!/usr/bin/env bash
#
# Example script that generates an OIDC token using a service account key file and uses it to access an IAP-secured resource.
set -euo pipefail
get_token() {
# Get the bearer token in exchange for the service account credentials
local service_account_key_file_path="${1}"
local iap_client_id="${2}"
# Define the scope and token endpoint
local iam_scope="https://www.googleapis.com/auth/iam"
local oauth_token_uri="https://www.googleapis.com/oauth2/v4/token"
# Extract data from service account key file
local private_key_id="$(cat "${service_account_key_file_path}" | jq -r '.private_key_id')"
local client_email="$(cat "${service_account_key_file_path}" | jq -r '.client_email')"
local private_key="$(cat "${service_account_key_file_path}" | jq -r '.private_key')"
# Set token timestamps (current time and expiration 10 minutes later)
local issued_at="$(date +%s)"
local expires_at="$((issued_at + 600))"
# Create JWT header and payload
local header="{'alg':'RS256','typ':'JWT','kid':'${private_key_id}'}"
local header_base64="$(echo "${header}" | base64 | tr -d '\n')"
local payload="{'iss':'${client_email}','aud':'${oauth_token_uri}','exp':${expires_at},'iat':${issued_at},'sub':'${client_email}','target_audience':'${iap_client_id}'}"
local payload_base64="$(echo "${payload}" | base64 | tr -d '\n')"
# Create JWT signature using the private key
local signature_base64="$(printf %s "${header_base64}.${payload_base64}" | openssl dgst -binary -sha256 -sign <(printf '%s\n' "${private_key}") | base64 | tr -d '\n')"
local assertion="${header_base64}.${payload_base64}.${signature_base64}"
# Exchange the signed JWT assertion for an ID token
local token_payload="$(curl -s \
--data-urlencode "grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer" \
--data-urlencode "assertion=${assertion}" \
https://www.googleapis.com/oauth2/v4/token)"
# Extract just the ID token from the response
local bearer_id_token="$(echo "${token_payload}" | jq -r '.id_token')"
echo "${bearer_id_token}"
}
main() {
# Check if required arguments are provided
if [[ $# -lt 3 ]]; then
echo "Usage: $0 <service_account_key_file.json> <iap_client_id> <url>"
exit 1
fi
# Assign parameters to variables
SERVICE_ACCOUNT_KEY="$1"
IAP_CLIENT_ID="$2"
URL="$3"
# Generate the ID token
echo "Generating token..."
ID_TOKEN=$(get_token "${SERVICE_ACCOUNT_KEY}" "${IAP_CLIENT_ID}")
# Access the IAP-secured resource with the token
echo "Accessing: ${URL}"
curl --header "Authorization: Bearer ${ID_TOKEN}" "${URL}"
}
# Run the main function with all provided arguments
main "$@"
このスクリプトは、次の手順を実行します。
JSON キーファイルからサービス アカウント キー情報を抽出します。
ターゲット オーディエンスとして IAP クライアント ID を含む、必要なフィールドを含む JWT を作成します。
サービス アカウントの秘密鍵を使用して JWT に署名する
Google の OAuth サービスを介して、この JWT を OIDC トークンと交換します。
生成されたトークンを使用して、IAP で保護されたリソースに認証済みリクエストを送信します。
このスクリプトを使用するには:
ファイル(
get_iap_token.shなど)に保存します。実行可能にする:
chmod +x get_iap_token.sh次の 3 つのパラメータを指定して実行します。
./get_iap_token.sh service-account-key.json \ OAUTH_CLIENT_ID \ URLここで
service-account-key.jsonは、ダウンロードしたサービス アカウント キーファイルです。OAUTH_CLIENT_ID は、IAP で保護されたリソースの OAuth クライアント ID です。
URL は、アクセスする URL です。
サービス アカウントの権限借用を使用して OIDC トークンを取得する
上記以外の場合は、IAP で保護されたリソースにアクセスする直前に IAM 認証情報 API を使用し、ターゲット サービス アカウントになりすまして OIDC トークンを生成します。このプロセスには、次のステップが含まれます。
呼び出し側のサービス アカウント(ID トークンを取得するコードに関連付けられたサービス アカウント)に、サービス アカウントの OpenID Connect ID トークン作成者ロール(
roles/iam.serviceAccountOpenIdTokenCreator)を付与します。これにより、呼び出し元のサービス アカウントが、ターゲット サービス アカウントの権限を借用できるようになります。
呼び出し側のサービス アカウントが提供する認証情報を使用して、ターゲット サービス アカウントの generateIdToken メソッドを呼び出します。
audienceフィールドにクライアント ID を設定します。
手順については、ID トークンを作成するをご覧ください。
サービス アカウントのアクセス トークンで認証する
openid スコープと https://www.googleapis.com/auth/userinfo.email(email)スコープの両方を含む OAuth 2.0 アクセス トークンを使用して、IAP で保護されたリソースに対してサービス アカウントを認証できます。
サービス アカウントが IAP で保護されたリソースのアクセスリストに追加されていることを確認します。
openidスコープとhttps://www.googleapis.com/auth/userinfo.emailスコープを使用して、サービス アカウントの OAuth 2.0 アクセス トークンを生成します。たとえば、gcloud CLI でサービス アカウントの権限を借用してアクセス トークンを生成するには、次のコマンドを実行します。
gcloud auth print-access-token \ --impersonate-service-account=SERVICE_ACCOUNT_EMAIL_ADDRESS \ --scopes=openid,https://www.googleapis.com/auth/userinfo.emailSERVICE_ACCOUNT_EMAIL_ADDRESSは、サービス アカウントのメールアドレスに置き換えます。IAM Service Account Credentials API の
generateAccessTokenメソッドを呼び出し、scopeフィールドに"openid"と"https://www.googleapis.com/auth/userinfo.email"を指定することもできます。詳細については、有効期間の短いアクセス トークンを作成するをご覧ください。IAP で保護されたリソースを呼び出すときに、
Authorization: Bearerヘッダーにアクセス トークンを含めます。curl --verbose \ --header 'Authorization: Bearer ACCESS_TOKEN' \ URL次のように置き換えます。
ACCESS_TOKEN: サービス アカウントの OAuth 2.0 アクセス トークンURL: IAP で保護されたリソースの URL
Proxy-Authorization ヘッダーから認証する
アプリケーションで Authorization リクエスト ヘッダーを使用している場合は、代わりに Proxy-Authorization: Bearer ヘッダーに ID トークン、アクセス トークン、またはサービス アカウント JWT を含めることができます。Proxy-Authorization ヘッダーに有効な認証情報が見つかった場合、IAP はその認証情報を使用してリクエストを認可します。リクエストを認可した後、IAP はコンテンツを処理せずに Authorization ヘッダーをアプリケーションに渡します。
Proxy-Authorization ヘッダーに有効な認証情報が見つからない場合、IAP は Authorization ヘッダーの処理を続行し、Proxy-Authorization ヘッダーを削除してからリクエストをアプリケーションに渡します。
アプリケーションにアクセスする
Proxy-Authorization ヘッダーを使用してアプリケーションにアクセスするには、次のコマンドを実行します。
curl --verbose --header 'Proxy-Authorization: Bearer SIGNED_JWT' URL
次のステップ
- Authorization: 署名なしトークン の詳細を確認する。
- Android 向けログインまたは iOS 向けログインをお試しください。