このドキュメントでは、IAP で保護されたリソースをユーザー アカウントまたはサービス アカウントから認証する方法について説明します。
プログラムによるアクセスは、ブラウザ以外のクライアントから IAP で保護されたアプリケーションを呼び出すシナリオです。これには、コマンドライン ツール、サービス間呼び出し、モバイル アプリケーションが含まれます。ユースケースに応じて、ユーザー認証情報またはサービス認証情報を使用して IAP の認証を行うことができます。
- ユーザー アカウントは、個々のユーザーに属します。ユーザーの代わりにアプリケーションが IAP で保護されたリソースにアクセスする必要がある場合、ユーザー アカウントを認証します。詳しくは、ユーザー アカウントをご覧ください。 
- サービス アカウントは、個々のユーザーではなくアプリケーションを表します。アプリケーションから IAP で保護されたリソースにアクセスできるようにする場合、サービス アカウントを認証します。詳細については、サービス アカウントをご覧ください。 
IAP は、プログラムによるアクセスに対して次のタイプの認証情報をサポートしています。
- OAuth 2.0 ID トークン - 対象クレームが IAP アプリケーションのリソース ID に設定された、人間ユーザーまたはサービス アカウント用の Google 発行のトークン。
- サービス アカウントの署名付き JWT - サービス アカウントの自己署名または Google 発行の JWT トークン。
これらの認証情報を Authorization または Proxy-Authorization HTTP ヘッダーで IAP に渡します。
始める前に
始める前に、デベロッパー アカウント、サービス アカウント、モバイルアプリの認証情報を使用してプログラムで接続する、IAP で保護されたアプリケーションが必要です。
ユーザー アカウントを認証する
デスクトップまたはモバイルアプリからアプリへのユーザー アクセスを有効にすると、プログラムから IAP で保護されたリソースを操作できます。
モバイルアプリから認証する
- モバイルアプリ用の OAuth 2.0 クライアント ID を作成するか、既存の ID を使用します。既存の OAuth 2.0 クライアント ID を使用するには、OAuth クライアントを共有する方法の手順に沿って操作します。アプリケーションのプログラムによるアクセスの許可リストに OAuth クライアント ID を追加します。
- IAP で保護されたクライアント ID の ID トークンを取得します。- Android: Google Sign-In API を使用して OpenID Connect(OIDC)トークンをリクエストします。requestIdTokenクライアント ID を接続先のリソースのクライアント ID に設定します。
- iOS: Google ログインを使用して ID トークンを取得します。
 
- Android: Google Sign-In API を使用して OpenID Connect(OIDC)トークンをリクエストします。
- 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.1
- コードの値をコピーし、次のコマンドの - AUTH_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フィールドを含む JSON オブジェクトを返します。
アプリケーションにアクセスする
アプリにアクセスするには、id_token を使用します。
curl --verbose --header 'Authorization: Bearer ID_TOKEN' URL
更新トークン
ログインフローで生成された更新トークンを使用して、新しい ID トークンを取得できます。これは、元の ID トークンが期限切れになった際に役立ちます。各 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)トークンを使用して、IAP で保護されたリソースに対してサービス アカウントを認証できます。次の表に、さまざまな認証トークンとその機能の違いを示します。
| 認証機能 | サービス アカウントの JWT | OpenID Connect トークン | 
|---|---|---|
| コンテキストアウェア アクセスのサポート | ||
| OAuth 2.0 クライアント ID の要件 | ||
| トークン スコープ | IAP で保護されたリソースの URL | OAuth 2.0 クライアント ID | 
サービス アカウント JWT で認証する
IAP は、Google ID、Identity Platform、Workforce Identity Federation で構成されたアプリケーションのサービス アカウント 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.iam.gserviceaccount.com
- audフィールドには、IAP で保護されたリソースの URL を指定します。
- iatフィールドには現在の Unix エポック時間を指定し、- expフィールドには 3,600 秒以内の時間を指定します。これにより、JWT の有効期限が定義されます。
JWT に署名する
次のいずれかの方法で JWT に署名できます。
- IAM 認証情報 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 service account JWT is created for.
        resource_url (str): Specifies 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 protected application.
    Returns:
        str: A signed JWT that can be used to access IAP protected apps.
            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 } EOF
- IAM を使用して 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.googleapis.com/v1/projects/-/serviceAccounts/SERVICE_ACCOUNT_EMAIL_ADDRESS:signJwt"- リクエストが成功すると、署名付きの JWT がレスポンスで返されます。 
- JWT を使用して、IAP で保護されたリソースにアクセスします。 
ローカルの認証情報鍵ファイルから JWT に署名する
JWT は、サービス アカウントの秘密鍵を使用して署名されます。
サービス アカウント キーファイルがある場合は、JWT にローカルで署名できます。
JWT にローカルで署名する場合は、ペイロードとともに JWT ヘッダーを含めます。ヘッダーの kid フィールドには、サービス アカウントの秘密鍵 ID を使用します。これは、サービス アカウント認証情報の JSON ファイルの private_key_id フィールドにあります。ファイル内の秘密鍵は、JWT の署名に使用されます。
アプリケーションにアクセスする
いずれの場合も、アプリにアクセスするには signed-jwt を使用します。
curl --verbose --header 'Authorization: Bearer SIGNED_JWT' URL
OIDC トークンで認証する
- OAuth 2.0 クライアント ID を作成するか、既存の ID を使用します。既存の 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 トークンを作成するをご覧ください。
Proxy-Authorization ヘッダーからの認証
アプリケーションが Authorization リクエスト ヘッダーを使用する場合は、代わりに Proxy-Authorization: Bearer ヘッダーに ID トークンを含めることができます。有効な ID トークンが Proxy-Authorization ヘッダーで見つかった場合、IAP はそのトークンを使用してリクエストを承認します。リクエストを承認すると、IAP はコンテンツを処理せずに Authorization ヘッダーをアプリケーションに渡します。
Proxy-Authorization ヘッダーに有効な ID トークンが見つからない場合、IAP は Authorization ヘッダーの処理を続行し、Proxy-Authorization ヘッダーを削除してから、リクエストをアプリケーションに渡します。
次のステップ
- Authorization: Bearer トークンの詳細を確認する。
- Android 用のログインまたは iOS 用のログインを試す。