# Google Cloud Spanner

![google spanner.png](https://assets.relyanceuat.xyz/images/docs/42791748953869/42791748950797.png)
Google Cloud Spanner is a fully managed, scalable, relational database service for regional and global application data.

Relyance AI integrates with Google Cloud Spanner to discover and classify personal and sensitive data across your Spanner databases. Through this integration, Relyance AI can scan your database schemas, tables, and data to provide visibility into what sensitive information exists and where it flows within your organization.

### What You’ll Need

To integrate Google Cloud Spanner with Relyance AI, you will need:

- **GCP Console access** with permissions to:
    - Create service accounts
    - Grant IAM roles and permissions
    - View Spanner instances and databases
- **A Google Cloud project** with active Spanner instances
- **Admin or Owner role** on your GCP project (or equivalent permissions)

### In Google Cloud Platform

This section covers the steps you'll complete in the Google Cloud Console to grant Relyance AI secure access to your Spanner instances.

#### **Step 1: Create a Service Account**

1. Navigate to **IAM & Admin**→ **Service Accounts** in the Google Cloud Console.
2. Click **+ CREATE SERVICE ACCOUNT**.
3. Enter the service account details:
    - **Service account name**: Follow the naming convention rely-`<tenant_name>`-int-`<suffix>`
        - Example: rely-dataeng-int or rely-aisec-int-surendra
    - **Service account ID**: Will auto-populate based on the name
    - **Service account description**: Service account for Relyance AI Spanner integration
4. Click **CREATE AND CONTINUE**.
5. Skip the optional permissions step (you'll configure this in the next step).
6. Click **DONE**.

Copy the full service account email (e.g., rely-dataeng-int@your-project-id.iam.gserviceaccount.com

). You'll need this in later steps.

**Reference Documentation:**

- [Creating and managing service accounts](https://cloud.google.com/iam/docs/service-accounts-create)

#### **Step 2: Assign Required Permissions**

Grant the service account the permissions needed to scan your Spanner databases and discover assets.

1. In the Google Cloud Console, navigate to **Spanner**→ **Instances**.
2. Select the Spanner instance you want Relyance AI to access.
3. Click the **PERMISSIONS** tab.
4. Click **GRANT ACCESS**.
5. In the "New principals" field, enter the service account email you created in Step 1: rely-`<tenant_name>`-int-`<suffix>`@`<your-project-id>`.iam.gserviceaccount.com
6. In the "Select a role" dropdown, choose **Cloud Spanner Database Reader** ( roles/spanner.databaseReader ).
7. Add a second role, **Cloud Spanner Viewer** ( roles/spanner.viewer ).
8. Click **SAVE**.

Both roles are needed. Relyance uses these eight permissions, and Database Reader
covers seven of them:

| Permission | Used for | Granted by |
| --- | --- | --- |
| `spanner.instances.get` | reading the instance's configuration | Database Reader |
| `spanner.databases.list` | **discovering which databases exist in the instance** | **Viewer only** |
| `spanner.databases.get` | reading a database's schema | Database Reader |
| `spanner.databases.read`, `spanner.databases.select` | reading rows to classify them | Database Reader |
| `spanner.sessions.create`, `sessions.get`, `sessions.delete` | the sessions those reads run in | Database Reader |

`spanner.databases.list` is the one Database Reader does not carry, which is why
Viewer is added alongside it — granting Database Reader on its own leaves the
connection able to read databases it cannot enumerate.

**Reference Documentation:**

- [Granting access to Spanner resources](https://cloud.google.com/spanner/docs/grant-permissions)
- [Cloud Spanner roles](https://cloud.google.com/spanner/docs/iam#roles)

#### **Step 3: Configure Service Account Impersonation**

Allow Relyance AI's platform service account to impersonate your service account.

1. Navigate to **IAM & Admin**→ **Service Accounts**.
2. Find and click on the service account you created in Step 1.
3. Click the **PERMISSIONS** tab.
4. Click **GRANT ACCESS** under "View by Principals".
5. In the "Add principals" drawer:
    - **New principals**: `<tenant-name>-gcp-integrations@relyance-prod.iam.gserviceaccount.com`
    - **Select a role**: **Workload Identity User** ( roles/iam.workloadIdentityUser )
6. Click **SAVE**.

This grants Relyance AI's service account permission to impersonate your service account, enabling secure, credential-free access to your Spanner databases without sharing private keys.

**Reference Documentation:**

- [Service account impersonation](https://cloud.google.com/iam/docs/service-account-overview#impersonation)
- [Workload Identity User role](https://cloud.google.com/iam/docs/understanding-roles#iam.workloadIdentityUser)

### In the Relyance AI Application

1. Login to your Relyance account.
2. Navigate to the **Settings** menu in the bottom left-hand side.
3. Select **Integrations**.
4. Find the **Google Cloud Spanner** integration card and click it to open its connections.
5. On the **Authentication** step, pick the method under **Authentication Method**.
6. Under **Connection → Authentication Step**, select **Service Account** as your authentication method. (Spanner has only this one; there is no Direct Connection option to look for.)
7. Enter your connection details:
    - **Your Service Account Email**: the service account email you created in Step 1: rely-`<tenant_name>`-int-`<suffix>`@`<your-project-id>`.iam.gserviceaccount.com
    - **Project ID**: your Google Cloud project ID (e.g. acme-production-12345).
8. **Config Options** is required, and it is where the instance to scan is named. `instance_id` is what points the scan at a Spanner instance; the deny lists narrow it further:

    ```json
    [
      {
        "instance_id": "",
        "deny_list_databases": ["your_dataset_name"],
        "deny_list_tables": []
      }
    ]
    ```
9. Click **Authenticate**.
10. You should see a success indicator on the integrations page showing the connection is active.

### Verify the connection is really working

1. **A failure at Authenticate** is the impersonation grant from Step 3.
   `Workload Identity User` must be on the service account itself — its
   **Principals with access** tab — not on the project. A project-level grant looks
   right in the IAM list and does not work.
2. **Connected but no databases discovered.** This is `spanner.databases.list`,
   which **Cloud Spanner Database Reader does not include**. Add **Cloud Spanner
   Viewer** as described above.
3. **Databases discovered but nothing classified.** The roles were granted on the
   wrong scope — they have to be on the instance (or the project containing it),
   and a grant on a single database leaves the rest unreadable.
4. **Fewer databases or tables than expected.** **Config Options** is the scope, and
   it is deny-based: anything in `deny_list_databases` or `deny_list_tables` is
   skipped. The default value shipped in the field denies a database literally named
   `your_dataset_name`, so clear it if you pasted the example as-is.

<!-- terraform-examples:begin (generated from the integration catalog; do not hand-edit) -->

## Manage this integration with Terraform

Connections for this integration can be managed as code with the [Relyance Terraform provider](https://registry.terraform.io/providers/Relyance/relyance/latest). Non-secret fields go in `auth.params`; secret fields go in `auth.secrets_wo`, which is write-only — never stored in Terraform state. Rotate secrets by bumping `auth.secrets_wo_version`.

```hcl
resource "relyance_integration_connection" "gcloud_spanner" {
  vendor = "gcloud_spanner"
  name   = "<your connection name>"

  auth = {
    method = "service-account"
    params = {
      config_options = jsonencode([
        {
          deny_list_databases = [
            "your_dataset_name"
          ]
          deny_list_tables = []
          instance_id = ""
        }
      ])
    }
    # Secret fields are write-only: sent to Relyance, never stored in state.
    secrets_wo = {
      service_account_email = var.gcloud_spanner_service_account_email
      project_id_scan = var.gcloud_spanner_project_id_scan
    }
    secrets_wo_version = 1
  }

  scans = { "data-inspection" = { enabled = true } }
}
```

<!-- terraform-examples:end -->
