Scopri come richiamare le funzioni Cloud Run autenticate

1. Introduzione

Panoramica

Cloud Run Functions è una soluzione di calcolo leggera che consente agli sviluppatori di creare funzioni autonome a uso specifico, che possono essere attivate utilizzando HTTPS o rispondere a CloudEvents senza la necessità di gestire un ambiente server o di runtime. Scopri di più su Cloud Run Functions in nostro post del blog.

Esistono due approcci principali per controllare le chiamate a Cloud Run Functions: proteggere l'accesso in base all'identità e proteggere l'accesso utilizzando i controlli dell'accesso basati sulla rete. Questo codelab si concentra sul primo approccio e ti guida attraverso 3 scenari per proteggere l'accesso in base all'identità per richiamare una funzione:

  1. Utilizza il token di identità gcloud per richiamare una funzione a scopo di sviluppo e test locali
  2. Simula l'identità di un account di servizio durante lo sviluppo e il test in locale per utilizzare le stesse credenziali della produzione
  3. Utilizza le librerie client di Google per gestire l'autenticazione alle API Google Cloud, ad esempio quando un servizio deve richiamare una funzione

Cosa imparerai a fare

  • Come configurare l'autenticazione su una funzione Cloud Run e verificare che sia stata configurata correttamente
  • Richiamare una funzione autenticata da un ambiente di sviluppo locale fornendo il token per la tua identità gcloud
  • Come creare un account di servizio e concedergli il ruolo appropriato per richiamare una funzione
  • Come simulare l'identità di un servizio da un ambiente di sviluppo locale che dispone dei ruoli appropriati per richiamare una funzione

2. Configurazione e requisiti

Prerequisiti

Attiva Cloud Shell

  1. Nella console Cloud, fai clic su Attiva Cloud Shell d1264ca30785e435.png.

84688aa223b1c3a2.png

Se è la prima volta che avvii Cloud Shell, viene visualizzata una schermata intermedia che ne descrive le funzionalità. Se è stata visualizzata una schermata intermedia, fai clic su Continua.

d95252b003979716.png

Bastano pochi istanti per eseguire il provisioning e connettersi a Cloud Shell.

7833d5e1c5d18f54.png

Questa macchina virtuale è caricata con tutti gli strumenti per sviluppatori necessari. Offre una home directory permanente da 5 GB e viene eseguita in Google Cloud, migliorando notevolmente le prestazioni e l'autenticazione della rete. Gran parte del lavoro per questo codelab, se non tutto, può essere svolto con un browser.

Una volta eseguita la connessione a Cloud Shell, dovresti vedere che il tuo account è autenticato e il progetto è impostato sul tuo ID progetto.

  1. Esegui questo comando in Cloud Shell per verificare che l'account sia autenticato:
gcloud auth list

Output comando

 Credentialed Accounts
ACTIVE  ACCOUNT
*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. Esegui questo comando in Cloud Shell per verificare che il comando gcloud conosca il tuo progetto:
gcloud config list project

Output comando

[core]
project = <PROJECT_ID>

In caso contrario, puoi impostarlo con questo comando:

gcloud config set project <PROJECT_ID>

Output comando

Updated property [core/project].

3. Creare e testare una funzione Cloud Run autenticata

Se è richiesta l'autenticazione, l'entità che richiama la funzione deve disporre del ruolo Invoker di Cloud Run; in caso contrario, la funzione restituirà un errore 403 Forbidden. Questo codelab mostra come concedere i ruoli Invoker appropriati a un'entità.

Configurare le variabili di ambiente locali per semplificare i comandi gcloud

Innanzitutto, crea alcune variabili di ambiente per migliorare la leggibilità dei comandi gcloud utilizzati in questo codelab.

REGION=us-central1
PROJECT_ID=$(gcloud config get-value project)

Creare il codice sorgente della funzione

Sebbene questo codelab utilizzi Node.js, puoi utilizzare qualsiasi runtime supportato dalle librerie client di autenticazione di Google.

Innanzitutto, crea una directory e spostati al suo interno.

mkdir auth-function-codelab && cd $_

Quindi, crea il file package.json.

touch package.json

echo '{
  "dependencies": {
    "@google-cloud/functions-framework": "^3.0.0"
  }
}
' > package.json

Poi, crea il file sorgente index.js.

touch index.js

echo 'const functions = require("@google-cloud/functions-framework");

functions.http("helloWorld", (req, res) => {
 res.send(`Hello ${req.query.name || req.body.name || "World"}!`);
});' > index.js

Creare la funzione autenticata

Ecco i passaggi per creare una funzione autenticata per il runtime nodejs20. Tuttavia, puoi utilizzare qualsiasi runtime supportato dalle librerie client di autenticazione di Google.

FUNCTION_NAME=authenticated-function-codelab
ENTRY_POINT=helloWorld

Per eseguire il deployment di una funzione Cloud Run direttamente su Cloud Run, esegui questo comando:

gcloud beta run deploy $FUNCTION_NAME \
      --source . \
      --function helloWorld \
      --region $REGION \
      --no-allow-unauthenticated

e poi puoi salvare l'URL della funzione come variabile di ambiente da utilizzare in un secondo momento.

FUNCTION_URL="$(gcloud run services describe $FUNCTION_NAME --region $REGION --format 'value(status.url)')"

Se preferisci eseguire il deployment come Cloud Functions (2nd gen), utilizza questo comando:

gcloud functions deploy nodejs-http-function \
  --gen2 \
  --runtime=nodejs20 \
  --region=$REGION \
  --source=. \
  --entry-point=helloWorld \
  --trigger-http \
  --no-allow-unauthenticated

e poi puoi salvare l'URL della funzione come variabile di ambiente da utilizzare in un secondo momento.

FUNCTION_URL="$(gcloud functions describe $FUNCTION_NAME --gen2 --region us-central1 --format='get(serviceConfig.uri)')"

Verificare che la funzione richieda l'autenticazione tentando di richiamarla come chiamante anonimo

Richiama la funzione senza autenticazione per verificare di ricevere l'errore 403 previsto.

Da una riga di comando, esegui questo comando curl:

curl -i $FUNCTION_URL

Vedrai il seguente risultato:

<html><head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<title>403 Forbidden</title>
</head>
<body text=#000000 bgcolor=#ffffff>
<h1>Error: Forbidden</h1>
<h2>Your client does not have permission to get URL <code>/</code> from this server.</h2>
<h2></h2>
</body></html>

Ora puoi esaminare 3 scenari in cui puoi richiamare la funzione fornendo l'autenticazione.

4. Scenario 1: utilizza il token di identità gcloud

Come sviluppatore, vorrai un modo per testare la tua funzione mentre la sviluppi in locale. In questa sezione, eseguirai un test rapido per verificare che la funzione sia autenticata correttamente utilizzando la tua identità.

Verifica di aver eseguito l'autenticazione utilizzando gcloud eseguendo questo comando:

gcloud auth list

Dovresti vedere un asterisco accanto alla tua identità attiva, ad esempio:

Credentialed Accounts
ACTIVE  ACCOUNT

*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`

Puoi trovare ulteriori informazioni sulla configurazione di gcloud init e gcloud auth login nella documentazione.

Poi, richiama la funzione e trasmetti il token di identità.

curl $FUNCTION_URL -H "Authorization: bearer $(gcloud auth print-identity-token)"

Ora vedrai il risultato:

Hello World!

Risoluzione dei problemi

Se ricevi un errore 403 Forbidden, assicurati che la tua identità abbia il ruolo Invoker di Cloud Run. Puoi utilizzare la console IAM per verificare i ruoli assegnati a un'entità.

Sebbene l'utilizzo del tuo token di identità sia un modo rapido per testare la tua funzione durante lo sviluppo, il chiamante della tua funzione autenticata avrà bisogno dei ruoli appropriati; in caso contrario, il chiamante riceverà un errore 403 Forbidden.

Ti consigliamo di seguire il principio del privilegio minimo limitando il numero di identità e account di servizio che hanno ruoli per richiamare la funzione. Nello scenario successivo, imparerai a creare un nuovo account di servizio e a concedergli i ruoli appropriati per richiamare la funzione.

5. Scenario 2: simulare l'identità di un service account

In questo scenario, simulerai l'identità (ovvero assumerai le autorizzazioni di) un account di servizio per richiamare una funzione durante lo sviluppo e il test in locale. Simulando l'identità di un account di servizio, puoi testare la tua funzione con le stesse credenziali della produzione.

In questo modo, non solo verificherai i ruoli, ma seguirai anche il principio del privilegio minimo non dovendo concedere il ruolo Invoker di Cloud Functions ad altre identità solo a scopo di test locali.

Ai fini di questo codelab, creerai un nuovo account di servizio che ha solo i ruoli per richiamare la funzione che hai creato in questo codelab.

Creare un nuovo account di servizio

Innanzitutto, crea un paio di variabili di ambiente aggiuntive per rappresentare gli account di servizio utilizzati nei comandi gcloud.

SERVICE_ACCOUNT_NAME="invoke-functions-codelab"
SERVICE_ACCOUNT_ADDRESS=$SERVICE_ACCOUNT_NAME@$PROJECT_ID.iam.gserviceaccount.com

Poi, crea l'account di servizio.

gcloud iam service-accounts create $SERVICE_ACCOUNT_NAME \
  --display-name="Cloud Run function Authentication codelab"

E concedi il ruolo Invoker di Cloud Run all'account di servizio:

gcloud run services add-iam-policy-binding $FUNCTION_NAME \
  --region=us-central1  \
  --member serviceAccount:$SERVICE_ACCOUNT_ADDRESS \
  --role='roles/run.invoker'

Richiamare la funzione rappresentando l'account di servizio

Per farlo, simulerai l'identità del service account appena creato ottenendo il relativo token ID.

Aggiungere i ruoli richiesti per la rappresentazione

Per simulare l'identità di un account di servizio, il tuo account utente deve disporre del ruolo Creatore token account di servizio (roles/iam.serviceAccountTokenCreator) per generare un token ID per l'account di servizio.

Puoi eseguire questi comandi per concedere questo ruolo al tuo account utente attivo:

ACCOUNT_EMAIL=$(gcloud auth list --filter=status:ACTIVE --format="value(account)")

gcloud iam service-accounts add-iam-policy-binding $SERVICE_ACCOUNT_ADDRESS  \
  --member user:$ACCOUNT_EMAIL \
  --role='roles/iam.serviceAccountTokenCreator'

Utilizzare il token ID dell'account di servizio

Attendi qualche minuto affinché le autorizzazioni vengano propagate. Ora puoi richiamare la funzione passando il token ID dell'account di servizio.

curl $FUNCTION_URL -H "Authorization: bearer $(gcloud auth print-identity-token --impersonate-service-account $SERVICE_ACCOUNT_ADDRESS)" 

E vedrai quanto segue:

WARNING: This command is using service account impersonation. All API calls will be executed as [invoke-functions-codelab@<project-id>.iam.gserviceaccount.com].

Hello World!

6. Scenario 3: utilizzare le librerie client di Google

Per quest'ultima parte del codelab, eseguirai un piccolo servizio in locale per generare un token ID per un account di servizio e poi chiamerai la funzione a livello di programmazione utilizzando le librerie client di autenticazione di Google e le Credenziali predefinite dell'applicazione (ADC). Puoi scoprire di più sulle librerie client di Google nella sezione Descrizione delle librerie client della documentazione.

L'utilizzo di ADC è particolarmente importante quando vuoi scrivere e testare la tua funzione in locale (ad es. sul laptop, in Cloud Shell e così via) interagendo con altre risorse Google Cloud (ad es. Cloud Storage, API Cloud Vision e così via). In questo esempio, vedrai come fare in modo che un servizio richiami un'altra funzione che richiede l'autenticazione. Per ulteriori informazioni su ADC e sullo sviluppo locale, consulta il post del blog Come sviluppare e testare le funzioni Cloud Functions in locale | Blog di Google Cloud

Eseguire il comando gcloud per rappresentare un account di servizio

ADC trova automaticamente le credenziali in base all'ambiente dell'applicazione e le utilizza per l'autenticazione alle API Cloud. Il flag –impersonate-service-account ti consente di simulare l'identità di un service account utilizzando la sua identità per l'autenticazione alle API Cloud.

Per simulare l'identità di un account di servizio, puoi eseguire questo comando:

gcloud auth application-default login --impersonate-service-account=$SERVICE_ACCOUNT_ADDRESS

Ora stai eseguendo i comandi gcloud come service account, anziché come identità.

Creare ed eseguire un servizio per richiamare una funzione autenticata

Ogni runtime ha la propria libreria client di autenticazione di Google che puoi installare. Questo codelab ti guida nella creazione e nell'esecuzione di un'app Node.js in locale.

Ecco i passaggi per Node.js:

  1. Crea una nuova directory
mkdir local-dev && cd $_
  1. Crea una nuova app Node.js
npm init -y
  1. Installa la libreria client di autenticazione di Google
npm install google-auth-library
  1. Crea un file index.js
  2. Recupera l'URL della tua funzione Cloud Run, che aggiungerai al codice nel passaggio successivo.
echo $FUNCTION_URL
  1. Aggiungi il seguente codice a index.js. Assicurati di modificare la variabile targetAudience con l'URL della funzione Cloud Run.

index.js

// Cloud Functions uses your function's url as the `targetAudience` value

const targetAudience = '<YOUR-CLOUD-RUN-FUNCTION-URL>';

// For Cloud Functions, endpoint(`url`) and `targetAudience` should be equal

const url = targetAudience;

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

async function request() {
    console.info(`request ${url} with target audience ${targetAudience}`);

    // this call retrieves the ID token for the impersonated service account
    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;
});
  1. Esegui l'app
node index.js

Dovresti vedere il risultato "Hello World!".

Risoluzione dei problemi

Se viene visualizzato un errore Permission ‘iam.serviceAccounts.getOpenIdToken' denied on resource (or it may not exist)., attendi qualche minuto affinché il ruolo Creatore token account di servizio venga propagato.

Se hai ricevuto l'errore Cannot fetch ID token in this environment, use GCE or set the GOOGLE_APPLICATION_CREDENTIALS variabile di ambiente to a service account credentials JSON file, potresti aver dimenticato di eseguire il comando

gcloud auth application-default login --impersonate-service-account=$SERVICE_ACCOUNT_ADDRESS

7. Complimenti!

Complimenti per aver completato il codelab.

Ti consigliamo di consultare la documentazione su come proteggere Cloud Run Functions.

Ti consigliamo anche questo post del blog su sviluppo locale con Cloud Run Functions per scoprire come sviluppare e testare la tua funzione Cloud Run nel tuo ambiente di sviluppo locale.

Argomenti trattati

  • Come configurare l'autenticazione su una funzione Cloud Run e verificare che sia stata configurata correttamente
  • Richiamare una funzione autenticata da un ambiente di sviluppo locale fornendo il token per la tua identità gcloud
  • Come creare un account di servizio e concedergli il ruolo appropriato per richiamare una funzione
  • Come simulare l'identità di un servizio da un ambiente di sviluppo locale che dispone dei ruoli appropriati per richiamare una funzione

8. Libera spazio

Per evitare addebiti involontari (ad esempio, se questa funzione Cloud Functions viene richiamata inavvertitamente più volte di quanto consentito dalla quota mensile di chiamate di Cloud Run Functions nel livello senza costi), puoi eliminare la funzione Cloud Functions o il progetto creato nel passaggio 2.

Per interrompere la rappresentazione dell'account di servizio, puoi accedere di nuovo utilizzando la tua identità:

gcloud auth application-default login

Per eliminare la funzione Cloud Run, vai alla console Cloud Run Functions all'indirizzo https://console.cloud.google.com/functions/. Assicurati che il progetto creato nel passaggio 2 sia il progetto attualmente selezionato.

Seleziona la my-authenticated-function di cui hai eseguito il deployment in precedenza. Poi premi Elimina.

Se scegli di eliminare l'intero progetto, puoi andare all'indirizzo https://console.cloud.google.com/cloud-resource-manager, selezionare il progetto creato nel passaggio 2 e scegliere Elimina. Se elimini il progetto, dovrai modificare i progetti in Cloud SDK. Puoi visualizzare l'elenco di tutti i progetti disponibili eseguendo gcloud projects list.