Documentation

GCP Cloud Connector API Reference

API reference for direct PDF sealing and Cloud Storage workflows through the Trusted Signatures Cloud Function on GCP.

  • Direct mode up to about 32 MB
  • Cloud Storage mode
  • SHA-256 digest only

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.

API Reference

The GCP Cloud Connector provides businesses with a scalable, cost-effective API on their Google Cloud infrastructure to seal even the most sensitive documents. By deploying the connector in their own project, customers have assurance that none of the information in the documents can be intercepted or modified. Only an SHA-256 digest of the PDF is sent to Trusted Signatures for signing; no other data about the document exits the customer’s infrastructure.

The connector supports two modes:

  • Direct Mode: PDF sent as base64 in request body (up to ~32MB)
  • Storage Mode: PDF stored in Cloud Storage buckets (no size limit)

Base URL

Your Cloud Function URL:

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

Architecture Overview

Endpoints

Health Check

Check if the Cloud Function is operational.

1
GET /health

Response:

1
2
3
{
  "status": "ok"
}

Status Codes:

  • 200 - Function is healthy

Seal PDF Document

Digitally seal a PDF document with Trusted Signatures using either direct mode or Cloud Storage mode.

1
2
POST /seal
Content-Type: application/json

Direct Mode (Base64)

For PDFs up to ~32MB. PDF is sent directly in the request body.

Request Body:

1
2
3
4
5
6
7
8
{
  "pdfBuffer": "<base64-encoded-pdf>",
  "apiKey": "<hex-encoded-api-key>",
  "apiKeyId": "your-api-key-id",
  "tsaTimestamp": true,
  "includeLtv": true,
  "limitChanges": "no-changes"
}

Response:

1
2
3
{
  "sealedPdf": "<base64-encoded-sealed-pdf>"
}

Storage Mode (Cloud Storage)

For PDFs of any size. PDF is stored in Cloud Storage buckets.

Request Body:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
{
  "sourceBucket": "your-source-bucket",
  "sourceKey": "path/to/document.pdf",
  "destinationBucket": "your-destination-bucket",
  "destinationKey": "path/to/sealed-document.pdf",
  "apiKey": "<hex-encoded-api-key>",
  "apiKeyId": "your-api-key-id",
  "tsaTimestamp": true,
  "includeLtv": true,
  "limitChanges": "no-changes"
}

Response:

1
2
3
4
5
6
{
  "sealedPdfLocation": {
    "bucket": "your-destination-bucket",
    "key": "path/to/sealed-document.pdf"
  }
}

Parameters

Common Parameters:

ParameterTypeRequiredDescription
apiKeystringYesHex-encoded API key from Trusted Signatures
apiKeyIdstringYesYour API key identifier
tsaTimestampbooleanYesInclude timestamp authority signature
includeLtvbooleanYesInclude Long Term Validation data
limitChangesstringNoPDF modification restrictions

Direct Mode Parameters:

ParameterTypeRequiredDescription
pdfBufferstringYesBase64-encoded PDF document (max ~32MB)

Storage Mode Parameters:

ParameterTypeRequiredDescription
sourceBucketstringYesCloud Storage bucket containing source PDF
sourceKeystringYesCloud Storage key (path) to source PDF
destinationBucketstringYesCloud Storage bucket for sealed PDF
destinationKeystringYesCloud Storage key (path) for sealed PDF

Important:

  • You cannot specify both modes in the same request
  • You must specify exactly one mode (direct or storage)
  • Use unique sourceKey and destinationKey values for concurrent invocations to avoid conflicts
  • The source and destination buckets may be the same or different buckets

limitChanges Options:

  • "no-changes" - No modifications allowed (default)
  • "allow-forms" - Allow form filling only
  • "allow-comments" - Allow comments and annotations

Status Codes:

  • 200 - PDF successfully sealed
  • 400 - Invalid request (missing fields, both modes specified, size limit exceeded)
  • 403 - Access denied to Cloud Storage
  • 404 - Source PDF not found in Cloud Storage
  • 500 - Sealing operation failed

Error Response:

1
2
3
{
  "error": "Error message description"
}

Usage Examples

JavaScript/Node.js - Direct Mode

 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
const fs = require("fs");

async function sealPdfDirect() {
  const pdfBuffer = fs.readFileSync("document.pdf");
  const apiKeyHex = "your-hex-api-key";

  const response = await fetch(
    "https://REGION-PROJECT_ID.cloudfunctions.net/pdf-sealer-gateway/seal",
    {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        pdfBuffer: pdfBuffer.toString("base64"),
        apiKey: apiKeyHex,
        apiKeyId: "your-key-id",
        tsaTimestamp: true,
        includeLtv: true,
        limitChanges: "no-changes",
      }),
    }
  );

  const result = await response.json();
  const sealedPdf = Buffer.from(result.sealedPdf, "base64");
  fs.writeFileSync("sealed-document.pdf", sealedPdf);
}

sealPdfDirect().catch(console.error);

JavaScript/Node.js - Storage Mode

 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
const { Storage } = require("@google-cloud/storage");
const fs = require("fs");

async function sealPdfStorage() {
  const storage = new Storage();
  const apiKeyHex = "your-hex-api-key";

  const sourceBucket = "your-source-bucket";
  const sourceKey = "uploads/document.pdf";
  const destinationBucket = "your-destination-bucket";
  const destinationKey = "sealed/sealed-document.pdf";

  // Upload PDF to Cloud Storage
  await storage.bucket(sourceBucket).upload("document.pdf", {
    destination: sourceKey,
    metadata: {
      contentType: "application/pdf",
    },
  });

  // Invoke Cloud Function
  const response = await fetch(
    "https://REGION-PROJECT_ID.cloudfunctions.net/pdf-sealer-gateway/seal",
    {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        sourceBucket: sourceBucket,
        sourceKey: sourceKey,
        destinationBucket: destinationBucket,
        destinationKey: destinationKey,
        apiKey: apiKeyHex,
        apiKeyId: "your-key-id",
        tsaTimestamp: true,
        includeLtv: true,
        limitChanges: "no-changes",
      }),
    }
  );

  const result = await response.json();
  console.log("PDF sealed successfully!");
  console.log("Sealed PDF location:", result.sealedPdfLocation);

  // Download sealed PDF
  await storage
    .bucket(result.sealedPdfLocation.bucket)
    .file(result.sealedPdfLocation.key)
    .download({ destination: "sealed-document.pdf" });

  // Optional: Clean up temporary files
  await storage.bucket(sourceBucket).file(sourceKey).delete();
  await storage.bucket(destinationBucket).file(destinationKey).delete();
}

sealPdfStorage().catch(console.error);

Python - Direct Mode

 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
import requests
import base64

def seal_pdf_direct():
    with open('document.pdf', 'rb') as f:
        pdf_data = base64.b64encode(f.read()).decode()

    api_key_hex = 'your-hex-api-key'

    response = requests.post(
        'https://REGION-PROJECT_ID.cloudfunctions.net/pdf-sealer-gateway/seal',
        json={
            'pdfBuffer': pdf_data,
            'apiKey': api_key_hex,
            'apiKeyId': 'your-key-id',
            'tsaTimestamp': True,
            'includeLtv': True,
            'limitChanges': 'no-changes'
        }
    )

    result = response.json()
    sealed_pdf = base64.b64decode(result['sealedPdf'])

    with open('sealed-document.pdf', 'wb') as f:
        f.write(sealed_pdf)

if __name__ == '__main__':
    seal_pdf_direct()

Python - Storage Mode

 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
import requests
from google.cloud import storage

def seal_pdf_storage():
    client = storage.Client()
    api_key_hex = 'your-hex-api-key'

    source_bucket = 'your-source-bucket'
    source_key = 'uploads/document.pdf'
    dest_bucket = 'your-destination-bucket'
    dest_key = 'sealed/sealed-document.pdf'

    # Upload PDF to Cloud Storage
    bucket = client.bucket(source_bucket)
    blob = bucket.blob(source_key)
    blob.upload_from_filename('document.pdf', content_type='application/pdf')

    # Invoke Cloud Function
    response = requests.post(
        'https://REGION-PROJECT_ID.cloudfunctions.net/pdf-sealer-gateway/seal',
        json={
            'sourceBucket': source_bucket,
            'sourceKey': source_key,
            'destinationBucket': dest_bucket,
            'destinationKey': dest_key,
            'apiKey': api_key_hex,
            'apiKeyId': 'your-key-id',
            'tsaTimestamp': True,
            'includeLtv': True,
            'limitChanges': 'no-changes'
        }
    )

    result = response.json()
    print('PDF sealed successfully!')
    print('Sealed PDF location:', result['sealedPdfLocation'])

    # Download sealed PDF
    dest_bucket_obj = client.bucket(result['sealedPdfLocation']['bucket'])
    sealed_blob = dest_bucket_obj.blob(result['sealedPdfLocation']['key'])
    sealed_blob.download_to_filename('sealed-document.pdf')

    # Optional: Clean up temporary files
    blob.delete()
    sealed_blob.delete()

if __name__ == '__main__':
    seal_pdf_storage()

cURL - Direct Mode

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# Prepare base64 encoded PDF and hex API key
PDF_B64=$(base64 -i document.pdf)
API_KEY_HEX="your-hex-api-key"

# Seal the PDF
curl -X POST https://REGION-PROJECT_ID.cloudfunctions.net/pdf-sealer-gateway/seal \
  -H "Content-Type: application/json" \
  -d "{
    \"pdfBuffer\": \"$PDF_B64\",
    \"apiKey\": \"$API_KEY_HEX\",
    \"apiKeyId\": \"your-key-id\",
    \"tsaTimestamp\": true,
    \"includeLtv\": true,
    \"limitChanges\": \"no-changes\"
  }" | jq -r '.sealedPdf' | base64 -d > sealed-document.pdf

cURL - Storage Mode

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# Upload PDF to Cloud Storage
gsutil cp document.pdf gs://your-source-bucket/uploads/document.pdf

# Seal the PDF
curl -X POST https://REGION-PROJECT_ID.cloudfunctions.net/pdf-sealer-gateway/seal \
  -H "Content-Type: application/json" \
  -d '{
    "sourceBucket": "your-source-bucket",
    "sourceKey": "uploads/document.pdf",
    "destinationBucket": "your-destination-bucket",
    "destinationKey": "sealed/sealed-document.pdf",
    "apiKey": "your-hex-api-key",
    "apiKeyId": "your-key-id",
    "tsaTimestamp": true,
    "includeLtv": true,
    "limitChanges": "no-changes"
  }'

# Download sealed PDF
gsutil cp gs://your-destination-bucket/sealed/sealed-document.pdf sealed-document.pdf

# Optional: Clean up temporary files
gsutil rm gs://your-source-bucket/uploads/document.pdf
gsutil rm gs://your-destination-bucket/sealed/sealed-document.pdf

With Authentication

If your function requires authentication:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# Get ID token
TOKEN=$(gcloud auth print-identity-token)

# Call function with authentication
curl -X POST https://REGION-PROJECT_ID.cloudfunctions.net/pdf-sealer-gateway/seal \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d "{
    \"pdfBuffer\": \"$PDF_B64\",
    \"apiKey\": \"$API_KEY_HEX\",
    \"apiKeyId\": \"your-key-id\",
    \"tsaTimestamp\": true,
    \"includeLtv\": true,
    \"limitChanges\": \"no-changes\"
  }"

Rate Limits

Cloud Functions default limits:

  • Concurrent executions: 1000 per region (can be increased)
  • Request rate: No hard limit, scales automatically
  • Request timeout: 60 seconds (configurable up to 540s for 2nd gen)

Configure limits in function settings or via quotas.

Error Handling

400 Bad Request

Invalid mode specification:

1
2
3
{
  "error": "Cannot specify both storage mode (sourceBucket/sourceKey/destinationBucket/destinationKey) and direct mode (pdfBuffer) in the same request"
}
1
2
3
{
  "error": "Must specify either storage mode (sourceBucket, sourceKey, destinationBucket, destinationKey) or direct mode (pdfBuffer)"
}

Missing required fields:

1
2
3
{
  "error": "Missing required fields: apiKey, apiKeyId, tsaTimestamp, includeLtv"
}

Size limit exceeded (Direct Mode):

1
2
3
{
  "error": "PDF size (45.2 MB) exceeds direct mode limit (31.97 MB). Use Cloud Storage mode for larger files."
}

Solution: Verify request format and use appropriate mode for your PDF size.

403 Forbidden

Cloud Storage access denied:

1
2
3
{
  "error": "Access denied to source: gs://bucket/key. Check Cloud Function service account permissions."
}
1
2
3
{
  "error": "Access denied to destination: gs://bucket/key. Check Cloud Function service account permissions."
}

Solution: Verify Cloud Function service account has required Cloud Storage IAM roles.

404 Not Found

Source PDF not found:

1
2
3
{
  "error": "Source PDF not found: gs://bucket/key"
}

Solution: Verify the source bucket and key exist and are accessible.

500 Internal Server Error

Sealing operation failed:

1
2
3
{
  "error": "Sealing operation failed: [specific error]"
}

Common causes:

  • Invalid API key or credentials
  • Malformed PDF document
  • Network connectivity issues
  • Trusted Signatures API unavailable
  • Cloud Storage service errors

Solution: Check Cloud Logging for detailed error information.

503 Service Unavailable

Function temporarily unavailable:

Common causes:

  • Cold start taking too long
  • Function scaling up
  • Temporary GCP issue

Solution: Retry the request with exponential backoff.

CORS Support

The function includes CORS headers for cross-origin requests:

  • Access-Control-Allow-Origin: *
  • Access-Control-Allow-Methods: GET, POST
  • Access-Control-Allow-Headers: Content-Type

Preflight OPTIONS requests are handled automatically.

Security

HTTPS Only

All Cloud Functions URLs use HTTPS by default.

Authentication Options

Configure in function settings:

  • No authentication - Public access
  • Require authentication - IAM-based access control
  • Service account - Machine-to-machine authentication

Data Handling

  • PDF documents are processed in memory only
  • No data is persisted by the Cloud Function
  • API keys are transmitted securely via HTTPS

Monitoring

Cloud Logging

View function logs:

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

Cloud Monitoring

Monitor function metrics:

  • Execution count
  • Execution time
  • Memory usage
  • Error rate
  • Active instances

Access via GCP Console → Cloud Monitoring → Metrics Explorer

Performance

Mode Selection

Direct Mode:

  • Best for: PDFs < 10MB, low latency requirements
  • Pros: Single request, no Cloud Storage setup needed
  • Cons: 32MB size limit, higher memory usage, slower for large files

Storage Mode:

  • Best for: Large PDFs, high-volume processing, existing Cloud Storage workflows
  • Pros: No size limit, better memory efficiency, parallel processing
  • Cons: Requires Cloud Storage setup, additional latency for upload/download

Cold Starts

  • First invocation may take 2-5 seconds
  • Subsequent invocations are faster (warm starts)
  • Set minimum instances to reduce cold starts (increases cost)

Memory Allocation

Direct Mode:

  • Rule of thumb: PDF size × 4 = minimum memory needed
  • For 10MB PDF: allocate at least 512MB
  • For 25MB PDF: allocate at least 1GB

Storage Mode:

  • More memory efficient (streaming from Cloud Storage)
  • 512MB sufficient for most use cases
  • Scale up for very large PDFs (>100MB)

Optimization Tips

  • Use Storage Mode for files >10MB
  • Keep function code minimal (already optimized via bundling)
  • Use appropriate memory allocation based on mode
  • Set reasonable timeout values (up to 540s for 2nd gen)
  • Monitor and adjust based on actual usage
  • Use regional buckets in same region as function

Best Practices

Security

  • API Keys: Store Trusted Signatures API credentials in Google Secret Manager
  • IAM: Use custom service accounts with minimal required permissions
  • Network: Consider VPC deployment for enhanced security
  • Monitoring: Set up alerts for unusual usage patterns
  • Data: Only SHA-256 digest transmitted to Trusted Signatures (PDFs stay in your environment)

Performance

  • Mode Selection: Use Storage Mode for files >10MB
  • Memory: Allocate appropriate memory based on PDF size and mode
  • Regions: Deploy function and buckets in same region
  • Lifecycle: Use Cloud Storage lifecycle policies for temporary files
  • Monitoring: Track function performance and costs

Error Handling

  • Implement proper error handling in your code
  • Log errors for debugging
  • Set up monitoring and alerts
  • Use exponential backoff for retries

Licensing

This Cloud Functions Gateway requires a valid Trusted Signatures Container Gateway license for production use. Usage is only permitted under the terms and conditions at https://trusted-signatures.com/terms/

Support

For technical support or questions:

Need architectural review?

Book a technical walkthrough

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