Documentation

GCP Cloud Connector Deployment Guide

Deploy the Trusted Signatures Cloud Function on Google Cloud Platform with console, gcloud, Terraform, or Deployment Manager workflows.

  • Cloud Function deployment
  • Service account IAM
  • Cloud Storage mode support

GCP proof

Use Cloud Functions and Cloud Storage for project-level speed, scale, and IAM control

The documented GCP pattern uses Cloud Functions for execution, direct or Cloud Storage modes for document handling, and Google Cloud IAM controls for a customer-managed sealing workflow.

Trust & Standards

32 MB

speed path

Direct mode handles base64 PDF requests up to about 32 MB for a simple single-request integration path.

Gen2

scale model

The connector runs as a second-generation Cloud Function and can shift large-file workflows to Cloud Storage mode.

IAM

security controls

Invoker bindings, dedicated service accounts, and bucket-scoped roles keep runtime and document access tightly scoped.

SHA-256

data boundary

Only the PDF digest is sent to Trusted Signatures while source and sealed files remain in your GCP project.

Deployment Guide

This guide covers multiple ways to deploy the GCP Cloud Connector to Google Cloud Platform.

Prerequisites

  • Google Cloud Project with billing enabled
  • Cloud Functions API enabled
  • Cloud Storage API enabled (for Storage Mode)
  • Built gcf-package.zip file (run npm run build)

For Storage Mode support, create a custom service account:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# Create service account
gcloud iam service-accounts create pdf-sealer-function \
  --display-name="PDF Sealer Function" \
  --description="Service account for PDF Sealer Cloud Function"

# Grant Cloud Storage permissions
export SERVICE_ACCOUNT_EMAIL="pdf-sealer-function@PROJECT_ID.iam.gserviceaccount.com"

# For reading from source buckets
gcloud projects add-iam-policy-binding PROJECT_ID \
  --member="serviceAccount:$SERVICE_ACCOUNT_EMAIL" \
  --role="roles/storage.objectViewer"

# For writing to destination buckets
gcloud projects add-iam-policy-binding PROJECT_ID \
  --member="serviceAccount:$SERVICE_ACCOUNT_EMAIL" \
  --role="roles/storage.objectCreator"

Note: See Cloud Storage setup for detailed Cloud Storage configuration.

GCP Console Deployment

Step 1: Enable Cloud Functions API

  1. Go to GCP Console
  2. Navigate to APIs & ServicesLibrary
  3. Search for “Cloud Functions API”
  4. Click Enable

Step 2: Create Cloud Function

  1. Go to Cloud Functions in GCP Console
  2. Click Create Function
  3. Configure:
    • Function name: pdf-sealer-gateway
    • Region: Choose your region
    • Trigger type: HTTP
    • Authentication: Allow unauthenticated invocations (or configure as needed)
  4. Click Save then Next

Step 3: Upload Code

  1. In the Code section:
    • Runtime: Node.js 22
    • Entry point: pdfSealer
    • Source code: ZIP upload
  2. Click Browse and select gcf-package.zip
  3. Click Upload

Step 4: Configure Function

  1. Expand Runtime, build, connections and security settings
  2. Set:
    • Memory allocated: 512 MB (increase for large PDFs in Direct Mode)
    • Timeout: 60 seconds (increase for large files)
    • Maximum instances: Set as needed
    • Service account: Use custom service account for Storage Mode
  3. Click Deploy

Step 5: Test

Wait for deployment to complete, then:

1
curl https://REGION-PROJECT_ID.cloudfunctions.net/pdf-sealer-gateway/health

gcloud CLI Deployment

Prerequisites

Install and configure gcloud CLI:

1
2
3
4
5
6
7
8
9
# Install gcloud CLI
# https://cloud.google.com/sdk/docs/install

# Initialize and authenticate
gcloud init
gcloud auth login

# Set project
gcloud config set project PROJECT_ID

Deploy Function

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# Deploy with default service account (Direct Mode only)
gcloud functions deploy pdf-sealer-gateway \
  --gen2 \
  --runtime=nodejs22 \
  --region=us-central1 \
  --source=gcf-package.zip \
  --entry-point=pdfSealer \
  --trigger-http \
  --allow-unauthenticated \
  --memory=512MB \
  --timeout=60s

# Deploy with custom service account (Storage Mode support)
gcloud functions deploy pdf-sealer-gateway \
  --gen2 \
  --runtime=nodejs22 \
  --region=us-central1 \
  --source=gcf-package.zip \
  --entry-point=pdfSealer \
  --trigger-http \
  --allow-unauthenticated \
  --service-account=pdf-sealer-function@PROJECT_ID.iam.gserviceaccount.com \
  --memory=512MB \
  --timeout=60s

# Get the function URL
gcloud functions describe pdf-sealer-gateway \
  --gen2 \
  --region=us-central1 \
  --format='value(serviceConfig.uri)'

Update Existing Function

1
2
3
4
5
6
gcloud functions deploy pdf-sealer-gateway \
  --gen2 \
  --runtime=nodejs22 \
  --region=us-central1 \
  --source=gcf-package.zip \
  --entry-point=pdfSealer

Terraform Deployment

Create main.tf:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
terraform {
  required_providers {
    google = {
      source  = "hashicorp/google"
      version = "~> 5.0"
    }
  }
}

provider "google" {
  project = var.project_id
  region  = var.region
}

variable "project_id" {
  description = "GCP Project ID"
  type        = string
}

variable "region" {
  description = "GCP Region"
  type        = string
  default     = "us-central1"
}

# Storage bucket for function source
resource "google_storage_bucket" "function_bucket" {
  name     = "${var.project_id}-gcf-source"
  location = var.region
}

# Upload function source
resource "google_storage_bucket_object" "function_zip" {
  name   = "gcf-package-${filemd5("gcf-package.zip")}.zip"
  bucket = google_storage_bucket.function_bucket.name
  source = "gcf-package.zip"
}

# Cloud Function (2nd gen)
resource "google_cloudfunctions2_function" "pdf_sealer" {
  name     = "pdf-sealer-gateway"
  location = var.region

  build_config {
    runtime     = "nodejs22"
    entry_point = "pdfSealer"
    source {
      storage_source {
        bucket = google_storage_bucket.function_bucket.name
        object = google_storage_bucket_object.function_zip.name
      }
    }
  }

  service_config {
    max_instance_count    = 10
    available_memory      = "512M"
    timeout_seconds       = 60
    service_account_email = "pdf-sealer-function@${var.project_id}.iam.gserviceaccount.com"
  }
}

# IAM policy for public access (optional)
resource "google_cloudfunctions2_function_iam_member" "invoker" {
  project        = google_cloudfunctions2_function.pdf_sealer.project
  location       = google_cloudfunctions2_function.pdf_sealer.location
  cloud_function = google_cloudfunctions2_function.pdf_sealer.name
  role           = "roles/cloudfunctions.invoker"
  member         = "allUsers"
}

output "function_uri" {
  value = google_cloudfunctions2_function.pdf_sealer.service_config[0].uri
}

Deploy:

1
2
terraform init
terraform apply -var="project_id=YOUR_PROJECT_ID"

Deployment Manager

Create function.yaml:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
resources:
- name: pdf-sealer-gateway
  type: gcp-types/cloudfunctions-v2:projects.locations.functions
  properties:
    parent: projects/PROJECT_ID/locations/us-central1
    functionId: pdf-sealer-gateway
    buildConfig:
      runtime: nodejs22
      entryPoint: pdfSealer
      source:
        storageSource:
          bucket: YOUR_BUCKET
          object: gcf-package.zip
    serviceConfig:
      availableMemory: 512M
      timeoutSeconds: 60
      maxInstanceCount: 10
      serviceAccountEmail: pdf-sealer-function@PROJECT_ID.iam.gserviceaccount.com

- name: pdf-sealer-invoker
  type: gcp-types/cloudfunctions-v2:projects.locations.functions.setIamPolicy
  properties:
    resource: $(ref.pdf-sealer-gateway.name)
    policy:
      bindings:
      - role: roles/cloudfunctions.invoker
        members:
        - allUsers

Deploy:

1
2
gcloud deployment-manager deployments create pdf-sealer-deployment \
  --config function.yaml

Authentication Options

Public Access (No Auth)

1
2
3
4
5
gcloud functions add-iam-policy-binding pdf-sealer-gateway \
  --gen2 \
  --region=us-central1 \
  --member="allUsers" \
  --role="roles/cloudfunctions.invoker"

Authenticated Access

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# Remove public access
gcloud functions remove-iam-policy-binding pdf-sealer-gateway \
  --gen2 \
  --region=us-central1 \
  --member="allUsers" \
  --role="roles/cloudfunctions.invoker"

# Grant access to specific service account
gcloud functions add-iam-policy-binding pdf-sealer-gateway \
  --gen2 \
  --region=us-central1 \
  --member="serviceAccount:SERVICE_ACCOUNT@PROJECT_ID.iam.gserviceaccount.com" \
  --role="roles/cloudfunctions.invoker"

Invoke with Authentication

1
2
3
4
5
6
# Get ID token
TOKEN=$(gcloud auth print-identity-token)

# Call function
curl -H "Authorization: Bearer $TOKEN" \
  https://REGION-PROJECT_ID.cloudfunctions.net/pdf-sealer-gateway/health

Monitoring

Cloud Logging

View function logs:

1
2
3
4
gcloud functions logs read pdf-sealer-gateway \
  --gen2 \
  --region=us-central1 \
  --limit=50

Or in GCP Console:

  1. Go to Cloud Functions
  2. Click on your function
  3. Go to Logs tab

Cloud Monitoring

View metrics:

  1. Go to Cloud Monitoring
  2. Navigate to Metrics Explorer
  3. Select resource type: Cloud Function
  4. Select your function

Key metrics:

  • Execution count
  • Execution times
  • Memory usage
  • Error rate

VPC Configuration (Optional)

Connect function to VPC:

1
2
3
4
5
6
7
gcloud functions deploy pdf-sealer-gateway \
  --gen2 \
  --runtime=nodejs22 \
  --region=us-central1 \
  --source=gcf-package.zip \
  --entry-point=pdfSealer \
  --vpc-connector=projects/PROJECT_ID/locations/REGION/connectors/CONNECTOR_NAME

Testing Deployment

Test Health Endpoint

1
curl https://REGION-PROJECT_ID.cloudfunctions.net/pdf-sealer-gateway/health

Test Direct Mode

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# Create a small test PDF (base64)
echo "test pdf content" | base64 > test_pdf_b64.txt
PDF_B64=$(cat test_pdf_b64.txt)

curl -X POST https://REGION-PROJECT_ID.cloudfunctions.net/pdf-sealer-gateway/seal \
  -H "Content-Type: application/json" \
  -d "{
    \"pdfBuffer\": \"$PDF_B64\",
    \"apiKey\": \"your-hex-api-key\",
    \"apiKeyId\": \"your-key-id\",
    \"tsaTimestamp\": true,
    \"includeLtv\": true
  }"

Test Storage Mode

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# Upload test file to Cloud Storage
echo "test pdf content" > test.pdf
gsutil cp test.pdf gs://your-test-bucket/test.pdf

# Test storage mode
curl -X POST https://REGION-PROJECT_ID.cloudfunctions.net/pdf-sealer-gateway/seal \
  -H "Content-Type: application/json" \
  -d '{
    "sourceBucket": "your-test-bucket",
    "sourceKey": "test.pdf",
    "destinationBucket": "your-test-bucket",
    "destinationKey": "sealed-test.pdf",
    "apiKey": "your-hex-api-key",
    "apiKeyId": "your-key-id",
    "tsaTimestamp": true,
    "includeLtv": true
  }'

Troubleshooting

Deployment Fails

  • Check Cloud Functions API is enabled
  • Verify IAM permissions
  • Check function logs for errors
  • Ensure gcf-package.zip is properly built

Function Timeout

  • Increase timeout setting (max 540 seconds for 2nd gen)
  • Check network connectivity to Trusted Signatures API
  • For large PDFs, consider using Storage Mode

Memory Issues

  • Increase memory allocation (especially for Direct Mode)
  • Monitor memory usage in Cloud Monitoring
  • Use Storage Mode for large PDFs to reduce memory usage

403 Forbidden

  • Check IAM permissions
  • Verify authentication configuration
  • Ensure invoker role is granted
  • For Storage Mode: verify service account has Cloud Storage permissions

Storage Mode Issues

  • Verify service account has storage.objectViewer and storage.objectCreator roles
  • Check bucket names and file paths are correct
  • Ensure buckets exist and are accessible
  • Verify function is deployed with correct service account

400 Bad Request

  • Check request format (cannot specify both modes)
  • Verify all required fields are present
  • For Direct Mode: check PDF size limit (~32MB)
  • Validate API key format (hex-encoded)

Cost Optimization

Minimize Cold Starts

  • Set minimum instances (costs more but reduces latency)
  • Use 2nd gen functions (faster cold starts)

Right-size Resources

  • Direct Mode: Start with 512 MB, increase for large PDFs (PDF size × 4)
  • Storage Mode: 512 MB sufficient for most use cases
  • Monitor actual usage and adjust
  • Set appropriate timeout (don’t use max if not needed)

Control Scaling

  • Set maximum instances to control costs
  • Use concurrency settings appropriately

Security Best Practices

Network Security

  • Use VPC connector for private network access
  • Configure firewall rules appropriately
  • Use Private Google Access if needed

IAM Security

  • Use least privilege principle
  • Avoid public access if not needed
  • Use service accounts for authentication
  • Regularly audit IAM policies

Function Security

  • Keep runtime updated
  • Monitor for vulnerabilities
  • Use Secret Manager for Trusted Signatures API keys (recommended)
  • Enable Cloud Armor for DDoS protection
  • Use custom service accounts with minimal permissions
  • For Storage Mode: restrict bucket access to specific service accounts

Need architectural review?

Book a technical walkthrough

For enterprise rollout, we can review trust model, controls, and integration patterns with your team.