Autenticação programática

Nesta página, você verá como se autenticar em um recurso protegido pelo Identity-Aware Proxy (IAP) usando uma conta de usuário ou de conta de serviço.

  • A conta de usuário pertence a um usuário individual. Ela é usada na autenticação quando o aplicativo precisa acessar recursos protegidos pelo IAP em nome de um usuário. Para mais informações, consulte Contas de usuário.

  • A conta de serviço pertence a um aplicativo, e não a um usuário individual. Ela é usada na autenticação quando você quer permitir que um aplicativo acesse seus recursos protegidos pelo IAP. Para mais informações, consulte Contas de serviço.

Antes de começar

Antes de começar, você precisará de:

  • Um aplicativo protegido pelo IAP a que você quer se conectar de maneira programática usando uma conta de desenvolvedor, conta de serviço ou credenciais de apps para dispositivos móveis.

Como autenticar uma conta de usuário

É possível ativar o acesso do usuário ao seu app a partir de um app para computador ou dispositivo móvel para permitir que um programa interaja com um recurso protegido pelo IAP.

Como autenticar usando um app para dispositivos móveis

  1. Crie ou use um ID do cliente OAuth 2.0 no seu app para dispositivos móveis. Para usar um ID do cliente OAuth 2.0, siga as etapas em Como compartilhar clientes OAuth.
  2. Autorize o ID do cliente OAuth para acesso programático ao app.
  3. Receba um token de ID para o ID do cliente protegido pelo IAP.
  4. Inclua o token de ID em um cabeçalho Authorization: Bearer para fazer a solicitação autenticada ao recurso protegido pelo IAP.

Como autenticar usando um app para computador

Esta seção descreve como autenticar uma conta de usuário de uma linha de comando de um desktop.

  1. Para permitir que os desenvolvedores acessem o aplicativo pela linha de comando, crie um ID de cliente OAuth 2.0 para computador ou compartilhe um ID de cliente OAuth para computador.
  2. Autorize o ID do cliente OAuth para acesso programático ao app.

Como fazer login no aplicativo

Cada desenvolvedor que quiser acessar um app protegido pelo IAP terá que fazer login primeiro. É possível empacotar o processo em um script, por exemplo, usando a gcloud CLI. Veja abaixo um exemplo que usa a curl para fazer login e gerar um token que pode ser usado para acessar o aplicativo:

  1. Faça login na sua conta que tem acesso ao recurso do Google Cloud.
  2. Inicie um servidor local que possa transmitir as solicitações recebidas.
        $ nc -k -l 4444
        
    OBSERVAÇÃO: o comando usa o utilitário NetCat. Use o utilitário que preferir.
  3. Acesse o seguinte URI, em que DESKTOP_CLIENT_ID é o ID do cliente do app para computador:
    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
  4. Na saída do servidor local, procure os parâmetros da solicitação. Você verá algo parecido com isto: GET /?code=$CODE&scope=email%20openid%20https://www.googleapis.com/auth/userinfo.email&hd=google.com&prompt=consent HTTP/1.1 copie o CODE para substituir AUTH_CODE abaixo com o ID do cliente e a chave secreta do app para computador:

    curl --verbose \
          --data client_id=DESKTOP_CLIENT_ID \
          --data client_secret=DESKTOP_CLIENT_SECRET \
          --data code=AUTH_CODE \
          --data redirect_uri=http://localhost:4444 \
          --data grant_type=authorization_code \
          https://oauth2.googleapis.com/token

    Esse código retorna um objeto JSON com um campo id_token, que pode ser usado para acessar o aplicativo.

Como acessar o aplicativo

Para acessar o app, use o id_token da seguinte maneira:

curl --verbose --header 'Authorization: Bearer ID_TOKEN' URL

Token de atualização

Use o token de atualização gerado durante o fluxo de login para receber novos tokens de ID. Isso é útil quando o token de ID original expira. Cada token de ID é válido por cerca de uma hora, período em que você pode fazer várias solicitações para um app específico.

A seguir, apresentamos um exemplo que usa curl para utilizar o token de atualização e receber um novo token de ID. No exemplo a seguir, REFRESH_TOKEN é o token do fluxo de login. DESKTOP_CLIENT_ID e DESKTOP_CLIENT_SECRET são os mesmos usados no fluxo de login:

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

Esse código retorna um objeto JSON com um novo campo id_token, que pode ser usado para acessar o app.

Como autenticar uma conta de serviço

É possível usar um JWT da conta de serviço ou um token do OpenID Connect (OIDC) para autenticar uma conta de serviço com um recurso protegido pelo IAP. A tabela a seguir descreve algumas das diferenças entre os diferentes tokens de autenticação e os recursos deles.

Recursos do Authentication JWT da conta de serviço Token do OpenID Connect
Suporte ao acesso baseado no contexto
Requisito de ID do cliente OAuth 2.0
Escopo do token URL do recurso protegido pelo IAP ID do cliente OAuth 2.0

Como autenticar com um JWT de conta de serviço

A autenticação de uma conta de serviço usando um JWT abrange as seguintes etapas principais:

  1. Conceda à conta de serviço que fez a chamada o papel de Criador de token da conta de serviço (roles/iam.serviceAccountTokenCreator).

    O papel dá permissão aos principais para criar credenciais de curta duração, como JWTs.

  2. Crie um JWT para o recurso protegido pelo IAP.

  3. Assine o JWT usando a chave privada da conta de serviço.

Como criar o JWT

O JWT criado deve ter um payload semelhante ao seguinte exemplo:

{
  "iss": SERVICE_ACCOUNT_EMAIL_ADDRESS,
  "sub": SERVICE_ACCOUNT_EMAIL_ADDRESS,
  "aud": TARGET_URL,
  "iat": IAT,
  "exp": EXP,
}
  • Nos campos iss e sub, especifique o endereço de e-mail da conta de serviço. Ela pode ser encontrada no campo client_email do arquivo JSON da conta de serviço ou transmitida. Formato típico: service-account@PROJECT_ID.iam.gserviceaccount.com

  • No campo aud, especifique o URL do recurso protegido pelo IAP.

  • No campo iat, especifique o horário da época Unix atual e, para o campo exp, especifique um horário até 3.600 segundos depois. Define quando o JWT expira.

Assinar o JWT

É possível usar um dos seguintes métodos para assinar o JWT:

  • Use a API IAM credentials para assinar um JWT sem precisar de acesso direto a uma chave privada.
  • Use um arquivo de chave de credenciais locais para assinar o JWT localmente.

Como assinar o JWT usando a API Service Account Credentials do IAM

Use a API IAM Service Account Credentials para assinar um JWT de conta de serviço. O método busca a chave privada associada à sua conta de serviço e a usa para assinar o payload do JWT. Isso permite a assinatura de um JWT sem acesso direto a uma chave privada.

Para se autenticar no IAP, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.

gcloud

  1. Execute o seguinte comando para preparar uma solicitação com o payload do 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
    
  2. Use o seguinte comando da Google Cloud CLI para assinar o payload em request.json:

    gcloud iam service-accounts sign-jwt --iam-account=SERVICE_ACCOUNT_EMAIL_ADDRESS claim.json output.jwt
    

    Quando a solicitação é bem-sucedida, output.jwt contém um JWT assinado.

  3. Use o JWT para acessar seu recurso protegido pelo IAP.

Python

import datetime
import json

import google.auth
from google.cloud import iam_credentials_v1
import jwt

def generate_jwt_payload(service_account_email: str, resource_url: str) -> str:
  """Generates JWT payload for service account.

  The resource url provided must be the same as the url of the IAP secured resource.

  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:
    A signed-jwt that can be used to access IAP protected applications.
    Access the application with the JWT in the Authorization Header.
    curl --verbose --header 'Authorization: Bearer SIGNED_JWT' URL
  """
  iat = datetime.datetime.now(tz=datetime.timezone.utc)
  exp = iat + 3600
  return json.dumps({
      'iss': service_account_email,
      'sub': service_account_email,
      'aud': resource_url,
      'iat': iat,
      'exp': exp,
  })

def sign_jwt(target_sa: str, resource_url: str) -> str:
  """Signs JWT payload using ADC and IAM credentials API.

  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:
    A signed-jwt that can be used to access IAP protected apps.
  """
  source_credentials, _ = google.auth.default()
  iam_client = iam_credentials_v1.IAMCredentialsClient(credentials=source_credentials)
  return iam_client.sign_jwt(
      name=iam_client.service_account_path('-', target_sa),
      payload=generate_jwt_payload(target_sa, resource_url),
  ).signed_jwt

Quando a solicitação é bem-sucedida, o script retorna um JWT assinado. Use o JWT para acessar seu recurso protegido pelo IAP.

curl

  1. Execute o seguinte comando para preparar uma solicitação com o payload do JWT:

    cat << EOF > request.json
    {
      "payload": JWT_PAYLOAD
    }
    EOF
    
  2. Assine o JWT usando a API Service Account Credentials do IAM:

    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"

    Quando a solicitação é bem-sucedida, um JWT assinado aparece na resposta.

  3. Use o JWT para acessar seu recurso protegido pelo IAP.

Como assinar o JWT de um arquivo de chave de credencial local

Os JWTs são assinados usando a chave privada da conta de serviço.

Se você tiver um arquivo de chave da conta de serviço, o JWT poderá ser assinado localmente.

O script envia um cabeçalho JWT junto com o payload. Para o campo kid no cabeçalho, use o ID da chave privada da conta de serviço, que está no campo private_key_id do arquivo JSON da credencial da conta de serviço. A chave também é usada para assinar o JWT.

Python

import time
import jwt
import json

def generate_jwt_payload(service_account_email, resource_url):
  """Generates JWT payload for service account.

  The resource url provided must be the same as the url of the IAP secured resource.

  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:
    A signed-jwt that can be used to access IAP protected applications.
    Access the application with the JWT in the Authorization Header.
    curl --verbose --header 'Authorization: Bearer SIGNED_JWT' URL
  """
  iat = datetime.datetime.now(tz=datetime.timezone.utc)
  exp = iat + 3600
  return json.dumps({
      'iss': service_account_email,
      'sub': service_account_email,
      'aud': resource_url,
      'iat': iat,
      'exp': exp,
  })

def sign_jwt_with_key_file(credential_key_file_path, resource_url):
  """Signs JWT payload using local service account credential key file.

  Args:
    credential_key_file_path (str): Path to the downloaded JSON credentials of the service
      account the JWT is being created for.
    resource_url (str): Scope of JWT token, This is the url of the IAP protected application.
  Returns:
    A service account JWT created with a downloaded private key.
  """
  with open(credential_key_file_path, 'r') as credential_key_file:
      key_data = json.load(credential_key_file)

  PRIVATE_KEY_ID_FROM_JSON = key_data["private_key_id"]
  PRIVATE_KEY_FROM_JSON = key_data["private_key"]
  SERVICE_ACCOUNT_EMAIL = key_data["client_email"]

  # Sign JWT with private key and store key id in the header
  additional_headers = {'kid': PRIVATE_KEY_ID_FROM_JSON}
  payload = generate_jwt_payload(service_account_email=SERVICE_ACCOUNT_EMAIL, resource_url=resource_url)

  signed_jwt = jwt.encode(
      payload,
      PRIVATE_KEY_FROM_JSON,
      headers=additional_headers,
      algorithm='RS256',
  )
  return signed_jwt

O resultado é um JWT assinado.

Como acessar o aplicativo

Em todos os casos, para acessar o app, use o signed-jwt da seguinte maneira:

curl --verbose --header 'Authorization: Bearer SIGNED_JWT' URL

Como autenticar com um token OIDC

  1. Crie ou use um ID do cliente OAuth 2.0. Para usar um ID do cliente OAuth 2.0, siga as etapas em Como compartilhar clientes OAuth.
  2. Autorize o ID do cliente OAuth para acesso programático ao app.

Você também precisa adicionar a conta de serviço à lista de acesso do projeto protegido pelo IAP. Os exemplos de código a seguir mostram como receber um token OIDC. Inclua o token em um cabeçalho Authorization: Bearer para fazer a solicitação de autenticação ao recurso protegido pelo IAP.

Como conseguir um token OIDC para a conta de serviço padrão

Se você quiser receber um token OIDC para a conta de serviço padrão do Compute Engine, App Engine ou Cloud Run, use o exemplo de código a seguir para gerar o token e acessar um recurso protegido pelo IAP:

C#


using Google.Apis.Auth.OAuth2;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading;
using System.Threading.Tasks;

public class IAPClient
{
    /// <summary>
    /// Makes a request to a IAP secured application by first obtaining
    /// an OIDC token.
    /// </summary>
    /// <param name="iapClientId">The client ID observed on 
    /// https://console.cloud.google.com/apis/credentials. </param>
    /// <param name="uri">HTTP URI to fetch.</param>
    /// <param name="cancellationToken">The token to propagate operation cancel notifications.</param>
    /// <returns>The HTTP response message.</returns>
    public async Task<HttpResponseMessage> InvokeRequestAsync(
        string iapClientId, string uri, CancellationToken cancellationToken = default)
    {
        // Get the OidcToken.
        // You only need to do this once in your application
        // as long as you can keep a reference to the returned OidcToken.
        OidcToken oidcToken = await GetOidcTokenAsync(iapClientId, cancellationToken);

        // Before making an HTTP request, always obtain the string token from the OIDC token,
        // the OIDC token will refresh the string token if it expires.
        string token = await oidcToken.GetAccessTokenAsync(cancellationToken);

        // Include the OIDC token in an Authorization: Bearer header to 
        // IAP-secured resource
        // Note: Normally you would use an HttpClientFactory to build the httpClient.
        // For simplicity we are building the HttpClient directly.
        using HttpClient httpClient = new HttpClient();
        httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
        return await httpClient.GetAsync(uri, cancellationToken);
    }

    /// <summary>
    /// Obtains an OIDC token for authentication an IAP request.
    /// </summary>
    /// <param name="iapClientId">The client ID observed on 
    /// https://console.cloud.google.com/apis/credentials. </param>
    /// <param name="cancellationToken">The token to propagate operation cancel notifications.</param>
    /// <returns>The HTTP response message.</returns>
    public async Task<OidcToken> GetOidcTokenAsync(string iapClientId, CancellationToken cancellationToken)
    {
        // Obtain the application default credentials.
        GoogleCredential credential = await GoogleCredential.GetApplicationDefaultAsync(cancellationToken);

        // Request an OIDC token for the Cloud IAP-secured client ID.
       return await credential.GetOidcTokenAsync(OidcTokenOptions.FromTargetAudience(iapClientId), cancellationToken);
    }
}

Go

Para se autenticar no IAP, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.

import (
	"context"
	"fmt"
	"io"
	"net/http"

	"google.golang.org/api/idtoken"
)

// makeIAPRequest makes a request to an application protected by Identity-Aware
// Proxy with the given audience.
func makeIAPRequest(w io.Writer, request *http.Request, audience string) error {
	// request, err := http.NewRequest("GET", "http://example.com", nil)
	// audience := "IAP_CLIENT_ID.apps.googleusercontent.com"
	ctx := context.Background()

	// client is a http.Client that automatically adds an "Authorization" header
	// to any requests made.
	client, err := idtoken.NewClient(ctx, audience)
	if err != nil {
		return fmt.Errorf("idtoken.NewClient: %w", err)
	}

	response, err := client.Do(request)
	if err != nil {
		return fmt.Errorf("client.Do: %w", err)
	}
	defer response.Body.Close()
	if _, err := io.Copy(w, response.Body); err != nil {
		return fmt.Errorf("io.Copy: %w", err)
	}

	return nil
}

Java


import com.google.api.client.http.HttpRequest;
import com.google.api.client.http.HttpRequestInitializer;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.auth.http.HttpCredentialsAdapter;
import com.google.auth.oauth2.GoogleCredentials;
import com.google.auth.oauth2.IdTokenCredentials;
import com.google.auth.oauth2.IdTokenProvider;
import com.google.common.base.Preconditions;
import java.io.IOException;
import java.util.Collections;

public class BuildIapRequest {
  private static final String IAM_SCOPE = "https://www.googleapis.com/auth/iam";

  private static final HttpTransport httpTransport = new NetHttpTransport();

  private BuildIapRequest() {}

  private static IdTokenProvider getIdTokenProvider() throws IOException {
    GoogleCredentials credentials =
        GoogleCredentials.getApplicationDefault().createScoped(Collections.singleton(IAM_SCOPE));

    Preconditions.checkNotNull(credentials, "Expected to load credentials");
    Preconditions.checkState(
        credentials instanceof IdTokenProvider,
        String.format(
            "Expected credentials that can provide id tokens, got %s instead",
            credentials.getClass().getName()));

    return (IdTokenProvider) credentials;
  }

  /**
   * Clone request and add an IAP Bearer Authorization header with ID Token.
   *
   * @param request Request to add authorization header
   * @param iapClientId OAuth 2.0 client ID for IAP protected resource
   * @return Clone of request with Bearer style authorization header with ID Token.
   * @throws IOException exception creating ID Token
   */
  public static HttpRequest buildIapRequest(HttpRequest request, String iapClientId)
      throws IOException {

    IdTokenProvider idTokenProvider = getIdTokenProvider();
    IdTokenCredentials credentials =
        IdTokenCredentials.newBuilder()
            .setIdTokenProvider(idTokenProvider)
            .setTargetAudience(iapClientId)
            .build();

    HttpRequestInitializer httpRequestInitializer = new HttpCredentialsAdapter(credentials);

    return httpTransport
        .createRequestFactory(httpRequestInitializer)
        .buildRequest(request.getRequestMethod(), request.getUrl(), request.getContent());
  }
}

Node.js

/**
 * TODO(developer): Uncomment these variables before running the sample.
 */
// const url = 'https://some.iap.url';
// const targetAudience = 'IAP_CLIENT_ID.apps.googleusercontent.com';

const {GoogleAuth} = require('google-auth-library');
const auth = new GoogleAuth();

async function request() {
  console.info(`request IAP ${url} with target audience ${targetAudience}`);
  const client = await auth.getIdTokenClient(targetAudience);
  const res = await client.request({url});
  console.info(res.data);
}

request().catch(err => {
  console.error(err.message);
  process.exitCode = 1;
});

PHP

Para se autenticar no IAP, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.

namespace Google\Cloud\Samples\Iap;

# Imports Auth libraries and Guzzle HTTP libraries.
use Google\Auth\ApplicationDefaultCredentials;
use GuzzleHttp\Client;
use GuzzleHttp\HandlerStack;

/**
 * Make a request to an application protected by Identity-Aware Proxy.
 *
 * @param string $url The Identity-Aware Proxy-protected URL to fetch.
 * @param string $clientId The client ID used by Identity-Aware Proxy.
 */
function make_iap_request($url, $clientId)
{
    // create middleware, using the client ID as the target audience for IAP
    $middleware = ApplicationDefaultCredentials::getIdTokenMiddleware($clientId);
    $stack = HandlerStack::create();
    $stack->push($middleware);

    // create the HTTP client
    $client = new Client([
        'handler' => $stack,
        'auth' => 'google_auth'
    ]);

    // make the request
    $response = $client->get($url);
    print('Printing out response body:');
    print($response->getBody());
}

Python

Para se autenticar no IAP, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.

from google.auth.transport.requests import Request
from google.oauth2 import id_token
import requests


def make_iap_request(url, client_id, method="GET", **kwargs):
    """Makes a request to an application protected by Identity-Aware Proxy.

    Args:
      url: The Identity-Aware Proxy-protected URL to fetch.
      client_id: The client ID used by Identity-Aware Proxy.
      method: The request method to use
              ('GET', 'OPTIONS', 'HEAD', 'POST', 'PUT', 'PATCH', 'DELETE')
      **kwargs: Any of the parameters defined for the request function:
                https://github.com/requests/requests/blob/master/requests/api.py
                If no timeout is provided, it is set to 90 by default.

    Returns:
      The page body, or raises an exception if the page couldn't be retrieved.
    """
    # Set the default timeout, if missing
    if "timeout" not in kwargs:
        kwargs["timeout"] = 90

    # Obtain an OpenID Connect (OIDC) token from metadata server or using service
    # account.
    open_id_connect_token = id_token.fetch_id_token(Request(), client_id)

    # Fetch the Identity-Aware Proxy-protected URL, including an
    # Authorization header containing "Bearer " followed by a
    # Google-issued OpenID Connect token for the service account.
    resp = requests.request(
        method,
        url,
        headers={"Authorization": "Bearer {}".format(open_id_connect_token)},
        **kwargs
    )
    if resp.status_code == 403:
        raise Exception(
            "Service account does not have permission to "
            "access the IAP-protected application."
        )
    elif resp.status_code != 200:
        raise Exception(
            "Bad response from application: {!r} / {!r} / {!r}".format(
                resp.status_code, resp.headers, resp.text
            )
        )
    else:
        return resp.text

Ruby

Para se autenticar no IAP, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.

# url = "The Identity-Aware Proxy-protected URL to fetch"
# client_id = "The client ID used by Identity-Aware Proxy"
require "googleauth"
require "faraday"

# The client ID as the target audience for IAP
id_token_creds = Google::Auth::Credentials.default target_audience: client_id

headers = {}
id_token_creds.client.apply! headers

resp = Faraday.get url, nil, headers

if resp.status == 200
  puts "X-Goog-Iap-Jwt-Assertion:"
  puts resp.body
else
  puts "Error requesting IAP"
  puts resp.status
  puts resp.headers
end

Como conseguir um token OIDC de um arquivo de chave de conta de serviço local

Se você tiver um arquivo de chave da conta de serviço, poderá adaptar as amostras de código anteriores para fornecer o arquivo de chave da conta de serviço.

Bash

  #!/usr/bin/env bash
  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}"

    local iam_scope="https://www.googleapis.com/auth/iam"
    local oauth_token_uri="https://www.googleapis.com/oauth2/v4/token"

    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')"
    local issued_at="$(date +%s)"
    local expires_at="$((issued_at + 600))"
    local header="{'alg':'RS256','typ':'JWT','kid':'${private_key_id}'}"
    local header_base64="$(echo "${header}" | base64)"
    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)"
    local signature_base64="$(printf %s "${header_base64}.${payload_base64}" | openssl dgst -binary -sha256 -sign <(printf '%s\n' "${private_key}")  | base64)"
    local assertion="${header_base64}.${payload_base64}.${signature_base64}"
    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)"
    local bearer_id_token="$(echo "${token_payload}" | jq -r '.id_token')"
    echo "${bearer_id_token}"
  }

  main(){
    # TODO: Replace the following variables:
    SERVICE_ACCOUNT_KEY="service_account_key_file_path"
    IAP_CLIENT_ID="iap_client_id"
    URL="application_url"

    # Obtain the ID token.
    ID_TOKEN=$(get_token "${SERVICE_ACCOUNT_KEY}" "${IAP_CLIENT_ID}")
    # Access the application with the ID token.
    curl --header "Authorization: Bearer ${ID_TOKEN}" "${URL}"
  }

  main "$@"

Como conseguir um token OIDC em todos os outros casos

Em todos os outros casos, use a API IAM credentials para gerar um token OIDC representando uma conta de serviço de destino antes de acessar um recurso protegido pelo IAP. Esse processo envolve as seguintes etapas:

  1. Forneça a conta de serviço de chamada (a conta de serviço associada ao código que está recebendo o token de ID) com o papel Criador de token do OpenID Connect Identity (roles/iam.serviceAccountOpenIdTokenCreator).

    Isso permite que a conta de serviço de chamada represente a conta de serviço de destino.

  2. Use as credenciais fornecidas pela conta de serviço de chamada para chamar o método generateIdToken na conta de serviço de destino.

    Defina o campo audience como o ID do cliente.

Para instruções passo a passo, consulte Criar um token de ID.

Como autenticar usando o cabeçalho Proxy-Authorization

Caso seu aplicativo use o cabeçalho de solicitação Authorization, inclua o token de ID em um cabeçalho Proxy-Authorization: Bearer. Se um token de ID válido for encontrado em um cabeçalho Proxy-Authorization, o IAP autorizará a solicitação com ele. Depois de autorizar a solicitação, o IAP transmite o cabeçalho Authorization para o aplicativo sem processar o conteúdo.

Se nenhum token de ID válido for encontrado no cabeçalho Proxy-Authorization, o IAP continuará processando o cabeçalho Authorization e removerá o cabeçalho Proxy-Authorization antes de transmitir a solicitação ao aplicativo.

A seguir