---
title: Usa WIF con Google Cloud
url: https://platform.claude.com/docs/es/manage-claude/wif-providers/gcp
description: Federa cargas de trabajo de Google Cloud (Cloud Run, Cloud Functions, App Engine, GCE, GKE) con la Claude API usando tokens de identidad firmados por Google en lugar de claves de API estáticas.
---

Cualquier entorno de cómputo de Google Cloud con acceso al "instance metadata server" (servidor de metadatos de la instancia) puede solicitar un "identity token" (token de identidad) firmado por Google para su "service account" (cuenta de servicio) adjunta. Esto incluye Cloud Run, Cloud Functions, App Engine, Compute Engine (GCE) y GKE con Workload Identity. El emisor del token es `https://accounts.google.com`, y Anthropic puede validarlo directamente mediante el descubrimiento OIDC estándar, sin necesidad de configuración adicional en Google Cloud.

Esta guía muestra cómo registrar el emisor de Google en Anthropic, vincular una cuenta de servicio de Google a una cuenta de servicio de Anthropic y hacer que tu carga de trabajo intercambie su token de identidad por un "access token" (token de acceso) de corta duración para la Claude API.

## Requisitos previos

* Familiaridad con los [conceptos de "Workload Identity Federation" (federación de identidades de cargas de trabajo), o WIF](https://platform.claude.com/docs/es/manage-claude/workload-identity-federation#concepts): cuentas de servicio, "federation issuers" (emisores de federación) y "federation rules" (reglas de federación).
* Un proyecto de Google Cloud con una carga de trabajo que se ejecute en Cloud Run, Cloud Functions, App Engine, Compute Engine o GKE.
* Una cuenta de servicio de Google administrada por el usuario y asociada a esa carga de trabajo (no la cuenta de servicio predeterminada de Compute Engine).
* Permiso para crear cuentas de servicio, emisores de federación y reglas de federación en la Claude Console para tu organización de Anthropic.

## Configura Google Cloud

Google emite tokens de identidad automáticamente para cualquier carga de trabajo que tenga una cuenta de servicio asociada. No hay nada que habilitar del lado de Google más allá de asociar la cuenta de servicio correcta, pero los pasos difieren ligeramente entre el cómputo estándar y GKE.

<Tabs>
  <Tab title="Cloud Run, Cloud Functions, App Engine, GCE">
    Asocia una cuenta de servicio dedicada a tu servicio o instancia:

    ```bash CLI
    gcloud run deploy my-service \
      --service-account inference-worker@my-project.iam.gserviceaccount.com
    ```

    Dentro de la carga de trabajo, el servidor de metadatos devuelve un token de identidad firmado bajo demanda. Solicítalo con el `audience` que planeas registrar del lado de Anthropic e incluye `format=full` para que la respuesta contenga el claim `email`:

    ```text wrap
    GET http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/identity?audience=https://api.anthropic.com&format=full
    Metadata-Flavor: Google
    ```

    O bien, con la CLI de gcloud:

    ```bash CLI
    gcloud auth print-identity-token \
      --audiences="https://api.anthropic.com" \
      --include-email
    ```

    Los equivalentes en los SDK se muestran en [Obtén y usa el token](https://platform.claude.com/docs/es/manage-claude/wif-providers/gcp#acquire-and-use-the-token).

    La carga útil decodificada del token se ve así:

    ```json
    {
      "iss": "https://accounts.google.com",
      "aud": "https://api.anthropic.com",
      "sub": "104892...",
      "azp": "104892...",
      "email": "inference-worker@my-project.iam.gserviceaccount.com",
      "email_verified": true,
      "exp": 1775527120
    }
    ```

    El claim `sub` es el ID único numérico y opaco de la cuenta de servicio de Google. El claim `email` es la dirección legible de la cuenta de servicio. Haz coincidir tanto `sub` como `email` en tu regla de federación.
  </Tab>

  <Tab title="GKE con Workload Identity">
    Habilita [Workload Identity](https://cloud.google.com/kubernetes-engine/docs/how-to/workload-identity) en tu clúster y vincula tu cuenta de servicio de Kubernetes a una cuenta de servicio de Google con la anotación `iam.gke.io/gcp-service-account`:

    ```yaml
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: inference-worker
      namespace: prod
      annotations:
        iam.gke.io/gcp-service-account: inference-worker@my-project.iam.gserviceaccount.com
    ```

    Con esta vinculación establecida, el servidor de metadatos de GKE devuelve un token firmado por Google idéntico al del caso de Cloud Run y GCE: el mismo emisor `https://accounts.google.com`, el mismo claim `email` y la misma URL de obtención. Configura Anthropic exactamente como se indica en la siguiente sección.

    Un token `format=full` de GKE incluye además los claims `google.compute_engine.project_id`, `google.compute_engine.zone` y `google.compute_engine.instance_name`. Puedes hacer referencia a ellos en el comparador `condition` de una regla de federación para limitar el acceso a un clúster o grupo de nodos específico. El comparador usa una expresión CEL como `claims.google.compute_engine.project_id == "my-project"`.

    <Note>
      Si no quieres vincular cuentas de servicio de Kubernetes a cuentas de servicio de Google, los pods de GKE pueden usar en su lugar el propio emisor OIDC del clúster (`https://container.googleapis.com/v1/projects/PROJECT/locations/REGION/clusters/CLUSTER`) con un volumen `serviceAccountToken` proyectado. Esa ruta usa un emisor por clúster en lugar de `accounts.google.com`. Consulta [Usa WIF con Kubernetes](https://platform.claude.com/docs/es/manage-claude/wif-providers/kubernetes) para ver ese patrón.
    </Note>
  </Tab>
</Tabs>

## Configura Anthropic

En la Claude Console, ve a la página [Workload identity](https://platform.claude.com/settings/workload-identity-federation) (`platform.claude.com/settings/workload-identity-federation`), haz clic en **Connect workload** y selecciona el mosaico **Google Cloud**. El asistente te guía para registrar el emisor, crear una cuenta de servicio y crear una regla de federación.

El asistente crea estos recursos por ti. Usa los siguientes valores, ya sea que los ingreses en el asistente o los envíes a la [Admin API](https://platform.claude.com/docs/es/manage-claude/wif-admin-api):

**Emisor de federación:** Google publica su documento de descubrimiento OIDC de forma pública, así que usa el modo de descubrimiento. Este único emisor cubre todas las superficies de Google Cloud: Cloud Run, GCE, Cloud Functions, App Engine y GKE con Workload Identity. Diferencia las cargas de trabajo mediante reglas, no mediante emisores.

```json
{
  "name": "gcp",
  "issuer_url": "https://accounts.google.com",
  "jwks": { "type": "discovery" }
}
```

**Regla de federación:** Haz coincidir tanto el claim `sub` como el claim `email`. `email` es la dirección legible de la cuenta de servicio. `sub` es el ID único numérico de la cuenta de servicio, que Google nunca reutiliza. Fijarlo protege la regla si la cuenta de servicio se elimina y más adelante se crea una nueva con el mismo correo electrónico. Encuentra el ID único con `gcloud iam service-accounts describe SA_EMAIL --format='value(uniqueId)'`.

```json
{
  "name": "gcp-inference-worker",
  "issuer_id": "fdis_...",
  "match": {
    "audience": "https://api.anthropic.com",
    "claims": {
      "sub": "104892101234567890123",
      "email": "inference-worker@my-project.iam.gserviceaccount.com"
    }
  },
  "target": {
    "type": "service_account",
    "service_account_id": "svac_..."
  },
  "workspace_id": "wrkspc_...",
  "oauth_scope": "workspace:developer",
  "token_lifetime_seconds": 600
}
```

## Obtén y usa el token

Dentro de tu carga de trabajo de Google Cloud, obtén el token de identidad del servidor de metadatos, intercámbialo en `POST /v1/oauth/token` y usa el token bearer devuelto para llamar a la Claude API. El SDK de Claude gestiona el intercambio y el ciclo de renovación por ti cuando proporcionas `identity_token_provider` (typescript: `identityTokenProvider`; php: `identityProvider`; csharp: `IdentityTokenProvider`; go: `option.WithFederationTokenProvider`; java: `IdentityTokenConfig`), como se muestra en los siguientes ejemplos. Excepto en Java (consulta el comentario en ese ejemplo), esa opción recibe un proveedor de tokens que devuelve un token de identidad nuevo del servidor de metadatos.

<CodeGroup>
  ```bash cURL
  # Obtén el token de identidad firmado por Google desde el servidor de metadatos
  JWT=$(curl -sS -H "Metadata-Flavor: Google" \
    "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/identity?audience=https://api.anthropic.com&format=full")

  # Intercámbialo por un token de acceso de Anthropic
  RESPONSE=$(curl -sS https://api.anthropic.com/v1/oauth/token \
    -H "content-type: application/json" \
    --data @- <<JSON
  {
    "grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer",
    "assertion": "$JWT",
    "federation_rule_id": "$ANTHROPIC_FEDERATION_RULE_ID",
    "organization_id": "$ANTHROPIC_ORGANIZATION_ID",
    "service_account_id": "$ANTHROPIC_SERVICE_ACCOUNT_ID",
    "workspace_id": "$ANTHROPIC_WORKSPACE_ID"
  }
  JSON
  )
  ACCESS_TOKEN=$(echo "$RESPONSE" | jq -r .access_token)

  # Llama a la API de Claude
  curl -sS https://api.anthropic.com/v1/messages \
    -H "authorization: Bearer $ACCESS_TOKEN" \
    -H "anthropic-version: 2023-06-01" \
    -H "content-type: application/json" \
    -d '{
      "model": "claude-opus-5-5",
      "max_tokens": 1024,
      "messages": [{"role": "user", "content": "Hello from Cloud Run"}]
    }' | jq -r '.content[] | select(.type == "text") | .text'
  ```

  ```python Python
  import os
  import anthropic
  import google.auth.transport.requests
  import google.oauth2.id_token
  from anthropic import WorkloadIdentityCredentials

  AUDIENCE = "https://api.anthropic.com"


  def fetch_google_identity_token() -> str:
      request = google.auth.transport.requests.Request()
      return google.oauth2.id_token.fetch_id_token(request, AUDIENCE)


  client = anthropic.Anthropic(
      credentials=WorkloadIdentityCredentials(
          identity_token_provider=fetch_google_identity_token,
          federation_rule_id=os.environ["ANTHROPIC_FEDERATION_RULE_ID"],
          organization_id=os.environ["ANTHROPIC_ORGANIZATION_ID"],
          service_account_id=os.environ["ANTHROPIC_SERVICE_ACCOUNT_ID"],
          workspace_id=os.environ.get("ANTHROPIC_WORKSPACE_ID"),
      ),
  )

  message = client.messages.create(
      model="claude-opus-5-5",
      max_tokens=1024,
      messages=[{"role": "user", "content": "Hello from Cloud Run"}],
  )
  print(next(block.text for block in message.content if block.type == "text"))
  ```

  ```typescript TypeScript
  import Anthropic from "@anthropic-ai/sdk";
  import { oidcFederationProvider } from "@anthropic-ai/sdk/lib/credentials/oidc-federation";

  const METADATA_URL =
    "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/identity?audience=https://api.anthropic.com&format=full";

  async function fetchGoogleIdentityToken(): Promise<string> {
    const response = await fetch(METADATA_URL, {
      headers: { "Metadata-Flavor": "Google" }
    });
    return response.text();
  }

  const client = new Anthropic({
    credentials: oidcFederationProvider({
      identityTokenProvider: fetchGoogleIdentityToken,
      federationRuleId: process.env.ANTHROPIC_FEDERATION_RULE_ID!,
      organizationId: process.env.ANTHROPIC_ORGANIZATION_ID!,
      serviceAccountId: process.env.ANTHROPIC_SERVICE_ACCOUNT_ID,
      workspaceId: process.env.ANTHROPIC_WORKSPACE_ID,
      baseURL: "https://api.anthropic.com",
      fetch
    })
  });

  const message = await client.messages.create({
    model: "claude-opus-5-5",
    max_tokens: 1024,
    messages: [{ role: "user", content: "Hello from Cloud Run" }]
  });
  for (const block of message.content) {
    if (block.type === "text") {
      console.log(block.text);
    }
  }
  ```

  ```go Go
  const audience = "https://api.anthropic.com"

  googleIDToken := func(ctx context.Context) (string, error) {
  	creds, err := idtoken.NewCredentials(&idtoken.Options{Audience: audience})
  	if err != nil {
  		return "", err
  	}
  	tok, err := creds.Token(ctx)
  	if err != nil {
  		return "", err
  	}
  	return tok.Value, nil
  }

  client := anthropic.NewClient(
  	option.WithFederationTokenProvider(googleIDToken, option.FederationOptions{
  		FederationRuleID: os.Getenv("ANTHROPIC_FEDERATION_RULE_ID"),
  		OrganizationID:   os.Getenv("ANTHROPIC_ORGANIZATION_ID"),
  		ServiceAccountID: os.Getenv("ANTHROPIC_SERVICE_ACCOUNT_ID"),
  		WorkspaceID:      os.Getenv("ANTHROPIC_WORKSPACE_ID"),
  	}),
  )

  message, err := client.Messages.New(context.TODO(), anthropic.MessageNewParams{
  	Model:     anthropic.ModelClaudeOpus5_5,
  	MaxTokens: 1024,
  	Messages: []anthropic.MessageParam{
  		anthropic.NewUserMessage(anthropic.NewTextBlock("Hello from Cloud Run")),
  	},
  })
  if err != nil {
  	panic(err)
  }
  for _, block := range message.Content {
  	if textBlock, ok := block.AsAny().(anthropic.TextBlock); ok {
  		fmt.Println(textBlock.Text)
  		break
  	}
  }
  ```

  ```java Java
  import com.anthropic.config.AuthenticationConfig;
  import com.anthropic.config.AuthenticationType;
  import com.anthropic.config.IdentityTokenConfig;
  import com.anthropic.config.InMemoryProfileConfigProvider;
  import com.anthropic.config.ProfileConfig;
  // ...
  import java.net.URI;
  import java.net.http.HttpClient;
  import java.net.http.HttpRequest;
  import java.net.http.HttpResponse;

  void main() throws Exception {
      HttpClient http = HttpClient.newHttpClient();
      HttpRequest metadataRequest = HttpRequest.newBuilder()
              .uri(URI.create("http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/identity?audience=https://api.anthropic.com&format=full"))
              .header("Metadata-Flavor", "Google")
              .build();

      // El SDK de Java recibe el token en sí o una ruta de archivo, no una función; con
      // source("value"), path(...) contiene el token. El SDK envía ese mismo token
      // en cada renovación del token de acceso de Anthropic, lo cual falla una vez que ha
      // expirado o, si tiene un claim jti, ya se ha usado. Para un proceso de mayor duración,
      // pasa source("file") y escribe un token nuevo en el archivo antes de
      // cada renovación.
      String googleIdentityToken = http.send(metadataRequest, HttpResponse.BodyHandlers.ofString()).body();

      AnthropicClient client = AnthropicOkHttpClient.builder()
              .configurationProvider(InMemoryProfileConfigProvider.of(ProfileConfig.builder()
                      .organizationId(System.getenv("ANTHROPIC_ORGANIZATION_ID"))
                      .workspaceId(System.getenv("ANTHROPIC_WORKSPACE_ID"))
                      .authentication(AuthenticationConfig.builder()
                              .type(AuthenticationType.OIDC_FEDERATION)
                              .federationRuleId(System.getenv("ANTHROPIC_FEDERATION_RULE_ID"))
                              .serviceAccountId(System.getenv("ANTHROPIC_SERVICE_ACCOUNT_ID"))
                              .identityToken(IdentityTokenConfig.builder()
                                      .source("value")
                                      .path(googleIdentityToken)
                                      .build())
                              .build())
                      .build()))
              .build();

      var message = client.messages().create(MessageCreateParams.builder()
              .model(Model.CLAUDE_OPUS_5_5)
              .maxTokens(1024)
              .addUserMessage("Hello from Cloud Run")
              .build());

      IO.println(message.content());
  }
  ```

  ```csharp C#
  using Anthropic.Credentials;
  // ...

  var credentials = new WorkloadIdentityCredentials(new WorkloadIdentityOptions
  {
      FederationRuleId = Environment.GetEnvironmentVariable("ANTHROPIC_FEDERATION_RULE_ID")!,
      OrganizationId = Environment.GetEnvironmentVariable("ANTHROPIC_ORGANIZATION_ID"),
      ServiceAccountId = Environment.GetEnvironmentVariable("ANTHROPIC_SERVICE_ACCOUNT_ID"),
      WorkspaceId = Environment.GetEnvironmentVariable("ANTHROPIC_WORKSPACE_ID"),
      IdentityTokenProvider = new MetadataTokenProvider(),
  });
  using var client = new AnthropicClient(new ClientOptions { Credentials = credentials });

  var message = await client.Messages.Create(new()
  {
      Model = Model.ClaudeOpus5_5,
      MaxTokens = 1024,
      Messages = [new() { Role = Role.User, Content = "Hello from Cloud Run" }],
  });
  foreach (var block in message.Content)
  {
      if (block.Value is TextBlock textBlock)
      {
          Console.WriteLine(textBlock.Text);
      }
  }

  class MetadataTokenProvider : IIdentityTokenProvider
  {
      private const string METADATA_URL =
          "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/identity?audience=https://api.anthropic.com&format=full";

      private static readonly HttpClient httpClient = new()
      {
          DefaultRequestHeaders = { { "Metadata-Flavor", "Google" } },
      };

      public async Task<string> GetIdentityTokenAsync(CancellationToken ct = default)
      {
          return await httpClient.GetStringAsync(METADATA_URL, ct);
      }
  }
  ```

  ```bash CLI
  # Escribe el token de identidad firmado por Google en un archivo que la CLI pueda leer
  ANTHROPIC_IDENTITY_TOKEN_FILE=$(mktemp)
  curl -sS -H "Metadata-Flavor: Google" \
    "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/identity?audience=https://api.anthropic.com&format=full" \
    > "$ANTHROPIC_IDENTITY_TOKEN_FILE"
  export ANTHROPIC_IDENTITY_TOKEN_FILE

  # ANTHROPIC_FEDERATION_RULE_ID, ANTHROPIC_ORGANIZATION_ID,
  # ANTHROPIC_SERVICE_ACCOUNT_ID y ANTHROPIC_WORKSPACE_ID se leen del entorno.
  ant messages create \
    --model claude-opus-5-5 \
    --max-tokens 1024 \
    --message '{role: user, content: "Hello from Cloud Run"}'
  ```

  ```php PHP
  use Anthropic\Client;
  use Anthropic\Lib\Credentials\CredentialResult;
  use Anthropic\Lib\Credentials\IdentityTokenProvider;
  use Anthropic\Lib\Credentials\TokenCache;
  use Anthropic\Lib\Credentials\WorkloadIdentityCredentials;

  const METADATA_URL = 'http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/identity?audience=https://api.anthropic.com&format=full';

  class GoogleIdentityToken implements IdentityTokenProvider
  {
      public function getIdentityToken(): string
      {
          $context = stream_context_create([
              'http' => ['header' => "Metadata-Flavor: Google\r\n"],
          ]);

          return file_get_contents(METADATA_URL, false, $context);
      }
  }

  $credentials = new CredentialResult(
      provider: new TokenCache(new WorkloadIdentityCredentials(
          identityProvider: new GoogleIdentityToken(),
          federationRuleId: getenv('ANTHROPIC_FEDERATION_RULE_ID'),
          organizationId: getenv('ANTHROPIC_ORGANIZATION_ID'),
          serviceAccountId: getenv('ANTHROPIC_SERVICE_ACCOUNT_ID'),
          workspaceId: getenv('ANTHROPIC_WORKSPACE_ID') ?: null,
      )),
  );
  $client = new Client(credentials: $credentials);

  $message = $client->messages->create(
      model: 'claude-opus-5-5',
      maxTokens: 1024,
      messages: [['role' => 'user', 'content' => 'Hello from Cloud Run']],
  );
  $textBlock = array_find($message->content, static fn ($block): bool => $block->type === 'text');
  echo $textBlock->text, PHP_EOL;
  ```

  ```ruby Ruby
  require "anthropic"
  require "net/http"

  METADATA_URL = "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/identity?audience=https://api.anthropic.com&format=full"

  credentials = Anthropic::WorkloadIdentityCredentials.new(
    identity_token_provider: -> { Net::HTTP.get(URI(METADATA_URL), {"Metadata-Flavor" => "Google"}) },
    federation_rule_id: ENV.fetch("ANTHROPIC_FEDERATION_RULE_ID"),
    organization_id: ENV.fetch("ANTHROPIC_ORGANIZATION_ID"),
    service_account_id: ENV.fetch("ANTHROPIC_SERVICE_ACCOUNT_ID"),
    workspace_id: ENV["ANTHROPIC_WORKSPACE_ID"]
  )
  client = Anthropic::Client.new(credentials: credentials)

  message = client.messages.create(
    model: "claude-opus-5-5",
    max_tokens: 1024,
    messages: [{role: "user", content: "Hello from Cloud Run"}]
  )
  puts message.content.find { it.type == :text }.text
  ```
</CodeGroup>

Los tokens de identidad de Google caducan después de aproximadamente una hora. Excepto en Java (consulta el comentario en ese ejemplo), el SDK vuelve a invocar el proveedor de tokens y repite el intercambio automáticamente antes de la caducidad. Para scripts de shell que se ejecutan durante más tiempo que el `expires_in` del token de acceso, renueva con un temporizador y repite el intercambio.

## Verifica la configuración

Desde dentro de tu carga de trabajo, decodifica el token de identidad y confirma que los claims coinciden con tu regla:

```bash cURL
curl -sS -H "Metadata-Flavor: Google" \
  "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/identity?audience=https://api.anthropic.com&format=full" \
  | jq -rR 'split(".")[1] | gsub("-";"+") | gsub("_";"/") | @base64d | fromjson'
```

Comprueba que `iss` sea `https://accounts.google.com`, que `aud` sea `https://api.anthropic.com` y que `email` coincida con el valor de tu regla de federación. Luego ejecuta el intercambio de la sección anterior. Un intercambio exitoso devuelve un `access_token` que comienza con `sk-ant-oat01-` y un valor `expires_in` en segundos. Si el intercambio falla con la respuesta opaca `401` `authentication_error` (mensaje `Authentication failed`), revisa la [página del historial de autenticación](https://platform.claude.com/settings/workload-identity-federation?tab=history) en la Claude Console para ver el motivo del rechazo y consulta [Solucionar un intercambio fallido](https://platform.claude.com/docs/es/manage-claude/wif-reference#troubleshoot-a-failed-exchange); la causa más común del lado de Google Cloud es que falte el claim `email` (solicita el token con `format=full` para que se incluya).

## Limita el alcance de tu regla

<Warning>
  El claim `sub` de Google es el ID único numérico y opaco de la cuenta de servicio y no tiene un prefijo estable. Un `subject_prefix` con un `*` final coincide con cuentas de servicio arbitrarias de todos los proyectos de Google Cloud, y cualquiera de ellas podría obtener un token federado de Anthropic.
</Warning>

Restringe el bloque `match` de la regla al alcance más limitado que se ajuste a tu caso de uso:

* **Haz coincidir `sub` exactamente:** Establece el ID único numérico completo en `claims.sub` y nunca uses `subject_prefix` para tokens de Google.
* **Fija el claim `email`:** Agrega `claims.email` junto con `sub` para que tanto el ID estable como la dirección legible deban coincidir.
* **Fija la audiencia:** Establece `audience` en el valor exacto que solicitas al servidor de metadatos para que se rechacen los tokens emitidos para otros consumidores.
* **Fija el proyecto en GKE:** Para los tokens `format=full`, agrega una `condition` como `claims.google.compute_engine.project_id == "my-project"` para restringir la regla a los nodos de un solo proyecto.

## Próximos pasos

* Lee la página de [Workload Identity Federation](https://platform.claude.com/docs/es/manage-claude/workload-identity-federation) para conocer el modelo de recursos completo y la precedencia de credenciales de los SDK.
* Agrega una regla de federación independiente por entorno (producción, staging) para que puedas revocar una sin afectar a las demás.
