> ## Documentation Index
> Fetch the complete documentation index at: https://docs.formal.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# GCP

> How to proxy Google Cloud APIs through the Formal Connector with GCP Resources

## Overview

A GCP Resource represents a Google Cloud API, such as Cloud Storage at `storage.googleapis.com`. The Connector proxies it with its HTTP engine. It adds the Google API service, method, and custom action to policy input and logs.

<Note>
  A GCP Resource is different from a
  [GCP Cloud Account](/docs/guides/integrations/clouds/gcp), which lets Formal
  discover Resources and write logs in your Google Cloud project.
</Note>

## Create a GCP Resource

<Tabs>
  <Tab title="Control Plane">
    Go to [Resources](https://app.formal.ai/resources) and click **Create Resource**. Set **Technology** to **GCP**. Set **Hostname** to the API hostname, such as `storage.googleapis.com`. The **Port** defaults to `443`.
  </Tab>

  <Tab title="Terraform">
    ```hcl theme={"languages":{"custom":["/languages/cel.json","/languages/rego.json"]}}
    resource "formal_resource" "gcs_api" {
      name       = "gcs-api"
      technology = "gcp"
      hostname   = "storage.googleapis.com"
      port       = 443
    }
    ```
  </Tab>
</Tabs>

Create one Resource for each Google API hostname you want to govern.

## Authentication

By default, clients send their own Google credentials, such as an OAuth access token in the `Authorization` header. The Connector forwards them unchanged.

To inject a credential instead, add a [Native User](/docs/guides/core-concepts/resources/native-users) with one of the HTTP credential types: **HTTP Bearer**, **HTTP Basic**, **API Key (Header)**, or **API Key (Query)**. See [HTTP authentication](/docs/guides/core-concepts/resources/http#authentication).

<Warning>
  The Control Plane also lists **GCP IAM** for GCP Resources. Connectors don't
  support that credential type for this technology yet, and requests that
  select it fail.
</Warning>

## Connect to a GCP Resource

<Tabs>
  <Tab title="Formal Endpoint">
    With [Transparent Mode](/docs/guides/client-apps/desktop-app#transparent-mode), the Formal Endpoint recognizes Google API traffic. Add a [network rule](/docs/guides/network-rules) that forwards traffic for your Formal Resources to the Connector:

    ```cel theme={"languages":{"custom":["/languages/cel.json","/languages/rego.json"]}}
    {
      "condition": {
        "pre_tcp": true,
        "pre_tls": resource.name != "",
        "post_tls": true
      },
      "outputs": {
        "forward_to_connector": true,
        "resource_name": resource.name
      }
    }
    ```

    Clients keep calling `*.googleapis.com`. They must trust the Endpoint's certificate authority, so tools that ship their own CA bundle need it added to their configuration.
  </Tab>

  <Tab title="Connector hostname">
    Send requests to `https://<resource-name>.<connector-hostname>`, as for [HTTP Resources](/docs/guides/core-concepts/resources/http#multiple-resources). This needs wildcard DNS and a wildcard TLS certificate for the Connector hostname. Point your client's API endpoint for that service at this address.
  </Tab>
</Tabs>

**Verify:** Make a request, then open [Logs](https://app.formal.ai/logs) and filter on `resource.technology:gcp`.

## Policy Evaluation

GCP Resources support the same stages and actions as [HTTP Resources](/docs/guides/core-concepts/resources/http#policy-evaluation). Policies also receive `input.gcp.api`:

| Field | Description |
| - | - |
| `input.gcp.api.host` | Host the client sent the request to |
| `input.gcp.api.service` | Google API service, such as `storage` for `storage.googleapis.com` |
| `input.gcp.api.method` | HTTP method |
| `input.gcp.api.custom_action` | Custom method from the last path segment, such as `setIamPolicy` in `/v1/projects/my-project:setIamPolicy` |

Logs record the same values under `request.http.gcp.api`.

<Note>
  `host` and `service` come from the request's `Host` header. When a client
  calls the Connector hostname, or the Endpoint forwards the request to the
  Connector, `host` is the Connector address and `service` is empty. In those
  cases, match on `input.http.hostname` or `input.resource.name`, which hold
  the Resource's upstream hostname and name.
</Note>

### Example: Block IAM Policy Changes

```rego theme={"languages":{"custom":["/languages/cel.json","/languages/rego.json"]}}
package formal.v2

import future.keywords.if

request := {
  "action": "block",
  "type": "block_with_custom_message",
  "message": "Change IAM policies through Terraform"
} if {
  input.resource.technology == "gcp"
  input.gcp.api.custom_action == "setIamPolicy"
}
```

## Next Steps

<CardGroup cols={2}>
  <Card title="HTTP" icon="globe" href="/docs/guides/core-concepts/resources/http">
    Learn how HTTP-based Resources work
  </Card>

  <Card title="Network Rules" icon="filter" href="/docs/guides/network-rules">
    Choose which traffic the Endpoint intercepts
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.