Cloud API
Protector with a REST API on GCP.
This section describes the high-level architecture of Protegrity Cloud API, installation procedures, and performance guidance.
This section focuses on Protegrity specific aspects and should be consumed in conjunction with the corresponding GCP documentation.
This guide may also be used with the Protegrity Enterprise Security Administrator Guide, which explains the mechanism for managing the data security policy.
1 - Overview
Solution overview and features.
Solution Overview
Cloud API Protector on GCP is a cloud-native, serverless product for fine-grained data protection.
This enables the invocation of Protegrity data protection cryptographic methods in cloud-native serverless technology.
The benefits of serverless include rapid auto-scaling, performance, low administrative overhead, and reduced infrastructure
costs compared to a server-based solution.
This product provides a data protection API end-point for clients. The product is designed to scale elastically and
yield reliable query performance under extremely high concurrent loads. During idle use, the serverless product will
scale completely down, providing significant savings in Cloud compute fees.
Protegrity utilizes a data security policy maintained by an Enterprise Security Administrator (ESA), similar to other
Protegrity products. Using a simple REST API interface, authorized users can perform both de-identification (protect)
and re-identification (unprotect) operations on data. A user’s individual capabilities are subject to privileges and
policies defined by the Enterprise Security Administrator.
Analytics on Protected Data
Protegrity’s format and length preserving tokenization scheme make it possible to perform analytics directly on
protected data. Tokens are join-preserving so protected data can be joined across datasets. Often statistical analytics
and machine learning training can be performed without the need to re-identify protected data. However, a user or service
account with authorized security policy privileges may re-identify subsets of data using the Cloud API Protector on GCP
service.
Features
Cloud API Protector on GCP incorporates Protegrity’s patent-pending vaultless tokenization capabilities into
cloud-native serverless technology. Combined with an ESA security policy, the protector provides the following features:
- Role-based access control (RBAC) to protect and unprotect (re-identify) data depending on the user privileges.
- Policy enforcement features of other Protegrity application protectors.
For more information about the available protection options, such as, data types, Tokenization or Encryption types,
or length preserving and non-preserving tokens, refer to Protection Methods Reference.
2 - Architecture
Deployment architecture and connectivity
Deployment Architecture
The Protegrity product should be deployed in the customer’s Cloud account. The product incorporates Protegrity’s vaultless tokenization engine within Google Cloud Functions. The encrypted data security policy from an ESA is deployed periodically as a static resource together with Cloud Function binaries. The policy is decrypted in memory at runtime within the Cloud Function. This architecture allows Protegrity to be highly available and scale very quickly without direct dependency on any other Protegrity services.
The product exposes a remote data protection service. Each network REST request includes a micro-batch of data to process and parameters such as operation and data element. The product applies the ESA security policy including user authorization and returns a corresponding response. Security operations on sensitive data performed by protector can be audited. The product can be configured to send audit logs to ESA via optional component called Log Forwarder.
The security policy is synchronized through another serverless component called the Protegrity Policy Agent. The agent operates on a configurable schedule, fetches the policy from the ESA, performs envelope encryption using Google Key Management Service, and deploys new version of Cloud Function with updated policy. This solution can be configured to automatically provision the static policy or the final step can be performed on-demand by an administrator. There is no downtime for users during this process. Instances provisioned with the function’s previous policy version may continue running (and processing traffic) for several minutes after a deployment has finished.
The following diagram illustrates the high-level architecture.

The following diagram illustrates a reference architecture for synchronizing the security policy from the ESA to the product.

The Protegrity Policy Agent requires network access from GCP to your ESA. Most organizations install the ESA on-premise. Thus, it is recommended to install the Policy Agent in a private subnet with a Cloud VPC using a NAT Gateway to enable this communication through a corporate firewall.
The ESA is a soft appliance that must be installed on a separate server. It is used to create and manage security policies.
For more information about installing the ESA, and creating and managing policies, refer to the Policy Management Guide.
Audit Log Forwarding Architecture
Audit logs are by default sent to Cloud Logging. The Protegrity Product can also be configured to send audit logs to ESA. Such configuration requires deploying Log Forwarder component which is available as part of Protegrity Product deployment bundle. The diagram below shows additional resources deployed with Log Forwarder component.

The log forwarder component includes Pub/Sub service topic and the audit log forwarder function. Pub/Sub service is used to asynchronously send audit records to forwarder function, where similar audit logs are aggregated before sending to ESA. Aggregation rules are described in the Protegrity Log Forwarding guide. When the protector function is configured to send audit logs to log forwarder, audit logs are aggregated on the protector function before sending to Pub/Sub topic. Protector function exposes configuration to control the time it spends aggregating audit logs which is described in the protector function installation section.
The security of audit logs is ensured by using HTTPS connection on each link of the communication between protector function and ESA. Integrity and authenticity of audit logs is additionally checked on log forwarder which verifies individual logs signature. The signature verification is done upon arrival from Pub/Sub topic before applying aggregation. If signature cannot be verified, the log is forwarded as is to ESA where additional signature verification can be configured. Log forwarder function uses basic auth and optional certificate verification to authenticate calls to ESA. Basic auth credentials are stored securely in Secret Manager Service.
To learn more about individual audit log entry structure and purpose of audit logs, refer to Audit Logging section in this document. Installation instruction can be found in the Audit Log Forwarder installation.
The audit log forwarding requires network access from the cloud to the ESA. Most organizations install the ESA on-premise. Therefore, it is recommended that the Log Forwarder Function is installed into a private subnet with a Cloud VPC using a NAT Gateway to enable this communication through a corporate firewall.
Access Control
The Cloud API utilizes access controls provided by the Google Cloud Functions service. The following mechanisms are available for controlling and restricting access to the Cloud API data protection endpoint:
- Google Cloud Identity and Access Management (IAM) access control.
- Google Cloud Network-based access control.
- OpenID Connect. OpenID is a simple identity layer on top of the OAuth 2.0 protocol. Authorization is performed in the Protegrity Cloud Function code.
For more information on Google Cloud Functions security concepts, refer to Securing Cloud Functions
REST API Authentication and Authorization
The Rest API supports built-in authentication and authorization provided by Google Cloud Functions. More information is available in the following Google Cloud Functions documentation.
https://cloud.google.com/functions/docs/securing/authenticating
REST API Policy Authorization
Once the request is authenticated and authorized by the Cloud Function, the Protegrity Cloud API performs the requested security operation based on the policy data element from the payload and the authenticated user.
3 - Installation
Product Installation Guide.
3.1 - Prerequisites
Requirements before installing the protector.
Google Cloud Services
The following table describes the Google Cloud services that may a part of your Protegrity installation.
| Service | Description |
|---|
| Cloud Run Functions | Provides serverless compute for Protegrity protection operations and the ESA integration to fetch policy updates. |
| API Gateway | Provides the end-point and access control (Required for Snowflake only). |
| Key Management Service | Provides cryptographic keys for envelope encryption/decryption of the policy. |
| Secret Manager Service | Stores secrets required during deployment, e.g., ESA credentials. |
| Cloud Storage Service | Storage location for the encrypted ESA policy package. |
| Identity and Access Management | Enforces access policies for deployed resources. |
| Cloud Logging Service | Application and audit logs, performance monitoring, and alerts. |
| Cloud VPC | Required for securing network access to On-Prem or cloud-based ESA. |
| Pub/Sub | Provides a messaging service when forwarding audit logs to ESA is enabled. |
ESA Version Requirements
The Protector and Log Forwarder functions require a security policy from a compatible ESA version.
The table below shows compatibility between different Protector and ESA versions.
| Protector Version | ESA Version |
|---|
| 8.x | 9.0 | 9.1 & 9.2 | 10.0 |
|---|
| 2.x | No | Yes | * | No |
| 3.0.x & 3.1.x | No | No | Yes | No |
| 3.2.x | No | No | Yes | * |
| 4.0.x | No | No | No | Yes |
Legend |
|---|
Yes | Protector was designed to work with this ESA version |
No | Protector will not work with this ESA version |
* | Backward compatible policy download supported: - Data elements and features which are common between this and previous ESA versions will be downloaded
- Data elements and features which are new to this ESA version and do not exist in previous ESA version will not be downloaded
|
Prerequisites
| Requirement | Detail |
|---|
| Protegrity distribution and installation scripts | These artifacts are provided by Protegrity |
| Protegrity ESA 10.0+ | The Cloud VNet must be able to obtain network access to the ESA |
| Google Cloud Account | Recommend creating a new project for Protegrity Serverless |
| Terraform CLI v0.14 or higher | Terraform is used to deploy resources to Google Cloud Account |
Required Skills and Abilities
| Requirements | Description |
|---|
| GCP Cloud Administrator | Run Terraform (or perform steps manually), create/configure a VPC and IAM permissions. |
| Protegrity Administrator | The ESA credentials required to extract the policy for the Policy Agent |
| Network Administrator | Open firewall to access ESA and evaluate Google Cloud network setup |
3.2 - Pre-Configuration
Configuration steps prior product installation.
Google Cloud Project
Identify or create a new Google Cloud Project where the Protegrity solution will be installed. It is recommended to create a new project. This provides greater security controls and avoids conflicts with other applications that might impact regional account limits. An individual with the Owner role will be required for some of the subsequent installations.
Google Project ID: ___________________
Google Project Number: ___________________
Google Cloud Region: ___________________
Key Management Service
The Google Cloud Key Management Service (KMS) provides Protegrity Serverless solution the ability to encrypt and decrypt the Protegrity Security Policy.
To create KMS Key Ring and Asymmetric Encryption Master Key:
Log in to Google Account and select project where Protegrity service will be installed.
Navigate to Security > Key Management.
Select Create key ring.
Specify key ring name. For example, protegrity-policy-keyring.
select Key ring location which corresponds to the region where Protegrity solution will be installed.
Note
A key’s location impacts the performance of protect service.Select Create.
Select CREATE KEY to create encryption key.
Specify key name. For example, protegrity-policy-key.
under Purpose selection, select Asymmetric Decrypt .
Select Key Algorithm. For example, 3072-bit RSA with OAEP Padding and SHA256 digest.
Select Create.
Once the key is created, a screen opens on the key. If the screen does not appear, click on the key name.
Then click on the elipses under Actions that is next to the key version.
Select Copy Resource Name and record the value below, e.g., projects/{project-id}/locations/region/keyRings/{key-ring}/cryptoKeys/{key-name}/cryptoKeyVersions/1
Policy Encryption Key Version Resource Name: ___________________
Google Cloud Storage
Cloud Storage buckets are required for the Gen 2 Cloud Function sources, the Terraform backend, and the deployment of the Protegrity installation artifacts. It is recommended that you create 3 separate buckets to separate files used for different purposes. If you cannot create 3 separate buckets, you may reuse a bucket for multiple purposes.
Create the buckets:
Run the cloud command below to enable the Google Storage Transfer API.
gcloud services enable storagetransfer.googleapis.com
Create the Gen 2 Cloud Function sources bucket. This bucket is not required if you will be deploying to Gen 1 Cloud Functions. The bucket name much match the example below. Replace the <gcp-project-number> and <region> placeholders.
gcf-v2-sources-<gcp-project-number>-<region>
Use the following gcloud command to obtain project number
gcloud projects describe <gcp-project-id> --format='value(projectNumber)'
Create the deployment bucket or reuse an existing bucket. This bucket is used during the installation process to store the Protegrity installation artifacts.
Deployment Bucket Name:___________________
Create the Terraform backend bucket or reuse an existing bucket. This bucket is used by Terraform to store information about your Cloud Protect installation, and will be used if you upgrade to a later version of Cloud Protect in the future.
Terraform Backend Bucket Name:___________________
Note
You may delete the deployment bucket after you’ve completed the installation. A deployment bucket is required for upgrades, but it can be recreated at that time. The Terraform backend files must be retained for upgrading your Cloud Protect deployment in the future.Cloud Functions Service Accounts
Cloud Functions use the service accounts created in this deployment. You can create Service accounts manually or use the Protegrity Terraform installation script to create one. Each service account requires specific permissions, which must be granted through IAM roles. Run the following steps to create service accounts and configure the required IAM access. If you use Terraform scripts, skip these steps.
Agent Function IAM Role
To create Agent Function IAM Role:
Log in to Google Account and select project where Protegrity service will be installed.
Navigate to IAM & Admin > Roles, Select CREATE ROLE.
Specify role name and description.
Select ADD PERMISSIONS.
Select the following permissions:
- cloudkms.cryptoKeyVersions.useToEncrypt
- cloudkms.cryptoKeyVersions.viewPublicKey
- secretmanager.versions.access
- storage.objects.get
- storage.objects.create
- storage.objects.delete
- storage.objects.list
- storage.objects.update
- storage.buckets.get
- cloudfunctions.functions.get
- cloudfunctions.functions.update
- cloudfunctions.functions.sourceCodeGet
- cloudfunctions.functions.sourceCodeSet
- iam.serviceAccounts.actAs
Click Add and then Create.
Alternatively, you can run the following command from the Cloud Shell Terminal.
gcloud iam roles create role-id \
--project=project-id \
--title=role-title \
--description=role-description \
--permissions=cloudkms.cryptoKeyVersions.useToEncrypt,\
cloudkms.cryptoKeyVersions.viewPublicKey,\
secretmanager.versions.access,\
storage.objects.get,\
storage.objects.create,\
storage.objects.delete,\
storage.objects.list,\
storage.objects.update,\
storage.buckets.get,\
cloudfunctions.functions.get,\
cloudfunctions.functions.update,\
cloudfunctions.functions.sourceCodeGet,\
cloudfunctions.functions.sourceCodeSet,\
iam.serviceAccounts.actAs \
--stage=GA
role-id
is the name of the role, such as ptyProtectRole.
project-id
is the name of the project, such as my-project-id.
role-description
is a short description of the role, such as “My custom role description”.
Sample output:
Created role [role-id].
description: role-description
etag: *****************
includedPermissions:
- cloudfunctions.functions.get
- cloudfunctions.functions.sourceCodeGet
- cloudfunctions.functions.sourceCodeSet
- cloudfunctions.functions.update
- cloudkms.cryptoKeyVersions.useToEncrypt
- cloudkms.cryptoKeyVersions.viewPublicKey
- iam.serviceAccounts.actAs
- secretmanager.versions.access
- storage.buckets.get
- storage.objects.create
- storage.objects.delete
- storage.objects.get
- storage.objects.list
- storage.objects.update
name: projects/{project-id}/roles/{role-id}
stage: GA
title: role-title
Agent Service Account
To create Agent Service Account:
Log in to Google Account and select project where Protegrity service will be installed.
Navigate to IAM & Admin > Service Accounts.
Select CREATE SERVICE ACCOUNT.
Specify service account name and description.
Select Create and Continue.
In the next step, click Select Role.
Select Custom and select the role created above .
Click Done.
Once the service account is created, the screen should open on the service account. If the screen does not appear, refresh the page with the service account list and select the service account created.
Record the full email. For example, service-account-name@project-id.iam.gserviceaccount.com
Agent Function Service Account Email: ___________________
Protect Function IAM role
To create Protect Function IAM role:
Log in to Google Account and select project where Protegrity service will be installed.
Navigate to IAM & Admin > Roles, Select CREATE ROLE.
Specify role name and description.
Select ADD PERMISSIONS.
Select the cloudkms.cryptoKeyVersions.useToDecrypt permission.
Click Add and then Create.
Protect Service Account
To create Protect Service Account:
Log in to Google Account and select the project where Protegrity service will be installed.
Navigate to IAM & Admin > Service Accounts.
Select CREATE SERVICE ACCOUNT.
Specify service account name and description.
Select Create and Continue.
In the next step, click Select Role. Then select Custom and select the role created above .
Click Done.
Once the service account is created, the screen should open on the service account. If the screen does not appear, refresh the page with the service account list and select the service account created.
Record the full email. For example, service-account-name@project-id.iam.gserviceaccount.com.
Protect Function Service Account Email: ___________________
3.3 - Protect Service Installation
Product Installation Guide.
Preparation
Ensure that all the steps in pre-configuration are performed.
Log in to the Google Cloud account where Protegrity will be installed.
Select the project.
Ensure that you have access to shell command on your computer or Cloud Shell with Terraform CLI v0.14 or higher installed.
Ensure that the Terraform scripts provided by Protegrity are available on your local computer.
Resources created with Terraform scripts include Protect Cloud Functions Service and other required resources depending on Terraform parameters. If you don’t specify the deployment bucket Terraform parameter, a new storage bucket will also be created. You can optionally choose to create a new service account with custom IAM role.
To install using Terraform:
From the command shell move to directory where you downloaded Protegrity installation bundle.
Unzip the bundle. Verify that the following files are available:
- pty-protect-gcp/
- main.tf
- outputs.tf
- protegrity-cloud-api-gcp-{version}.zip
- README.md
Unzip the protegrity-cloud-protect-gcp-{version}.zip file. Verify that the following files are available:
- pty-protect-gcp/
- main.tf
- outputs.tf
- protegrity-cloud-protect-gcp-{version}.zip
- README.md
Open the main.tf file and update Terraform backend information at the top of the file:
terraform {
backend "gcs" {
bucket = ""
prefix = "protegrity/terraform/pty-protect-gcp/state"
}
}
In the same main.tf file, specify the following Terraform variables: All the values were recorded in Google Cloud Project.
Warning
Google Cloud Function 2nd Generation currently does not support CMEK.
Parameter | Description |
|---|
project_id | The project id recorded in the pre-configuration step |
region | The Region recorded in the pre-configuration step. |
deployment_id | Specify short name to identify deployment. This id will be added to all resources deployed with Terraform. |
deployment_bucket | Use Deployment Bucket Name recorded in pre-configuration or leave empty to create new bucket. |
create_service_account | Leave this as false if you created service account in pre-configuration. Otherwise set to true. |
protect_function_service_account_email | Use Protect Function Service account recorded in pre-configuration or leave empty. |
username_regex | If username_regex is set, the effective policy user will be extracted from the user in the request. |
max_instance_count | GCP Cloud Functions advanced configuration |
available_memory_mb | GCP Cloud Functions advanced configuration |
timeout_seconds | GCP Cloud Functions advanced configuration |
gen2_available_cpu | 2nd Gen Cloud Function advanced configuration |
gen2_container_concurrency | 2nd Gen Cloud Function advanced configuration |
upgrade_step | Set this variable when upgrading to the latest version. |
deploy_api_gateway | Deploys GCP API Gateway proxy for Protect Cloud Function service. |
api_gateway_jwt_issuer | Applicable when deploy_api_gateway = true. Allows setting issuer of JSON Web Token credential used to authenticate calls to API Gateway. Accepts email or URI. |
api_gateway_jwks_uri | Applicable when deploy_api_gateway = true. Allows setting URI of the authentication provider’s public key set to validate the signature of the JSON Web Token. |
labels | You can set this map to include labels for deployed resources. Pay attention to GCP label requirements. For more information, refer to the following link https://cloud.google.com/compute/docs/labeling-resources. For example, only use lowercase and maximum length of 63 characters. |
openid_enabled | When set to true, every request is required to have an Authorization header with the bearer token set to a valid OAuth access token. The following configuration attributes will also be required: OPENID_AUDIENCES, OPENID_ISSUERS, OPENID_METADATA_URL. |
openid_audiences | Applicable when OPENID_ENABLED= “true”. The JWT token must have the “aud” claim and it must match one of the values in this attribute. Can be either one value or comma separated list. |
openid_issuers | Applicable when OPENID_ENABLED= “true”. The JWT token must have the “iss” claim and it must match one of the values in this attribute. Can be either one value or comma separated list. |
openid_metadata_url | Applicable when OPENID_ENABLED= “true”. A URL that points to an OpenID Connect identity provider configuration document, which is also known as OpenID well-known configuration endpoint. |
openid_appid | Applicable when OPENID_ENABLED= “true”. Validates the provided open_appid is listed in the appid claim. If value is empty, appid claim is ignored. Supported Values: ["<appid>", “”] |
authorization | When equals “jwt”, Authorization Header JWT will be required in the Rest API Protect payload. Supported Values: [“jwt”, “”]. When set to “jwt”, any request without Valid JWT in the Authorization header will result in an error from API Gateway: 502 Bad Gateway. *Applies for all configurations of jwt_verify and openid_enabled. |
allow_assume_user | Applicable when authorization = “jwt”. If set to 0, The user from the payload will not be used, and the policy user is the JWT user. Supported Values: [0, 1]. Default Value: 0. *Applies for all configurations of jwt_verify and openid_enabled. |
jwt_user_claim | Applicable when authorization = “jwt”. The JWT payload claim with username. Common claims: name, preferred_username, cognito:username. Default Value: cognito:username. *Applies for all configurations of jwt_verify and openid_enabled. |
service_user | If service_user is set the protect request will use it for the policy user. service_user should be used when the Cloud API should always run as one service_user no matter what user is in the request. service_user will always take priority over any other user in the payload or in the JWT header. *Applies for all configurations of jwt_verify and openid_enabled. |
pty_gcp_jwt_header | When set to true, both Google Cloud access control and Protegrity openid will be supported in two separate headers. This is useful when having access control with GCP IAM (In Authorization header) and the OPENID verification and policy user from JWT in the X-PTY-Authorization header. |
jwt_verify | When set to 1, jwt_secret_base64 is required. Only applicable when authorization is jwt. Supported JWT Algorithm RS256, RS384, RS512. (HS256, HS384, HS512 are supported but not recommended for use). Only applicable when authorization = “jwt” Supported Values: [1, “”] *Applies for all configurations of openid_enabled. |
jwt_secret_base64 | Required when jwt_verify = 1 and Authorization = JWT. The secret must be provided in base64 encoding. It is recommended to only use public key (asymmetric algorithm). applicable when authorization = “jwt” and jwt_verify=1 Supported Values: [<base64 encoded secret key>, “”] |
min_log_level | Minimum log level for log forwarder function. One of off|severe|warning|info|config|all. Defaults to ‘severe’ |
pty_log_output | Audit log output. Accepted values: “”(empty string), “pub_sub”. NoteWhen set to “pub_sub” audit logs will be aggregated and sent to Pub/Sub topic. See Log Forwarder installation section for more details. |
audit_log_flush_interval | Time interval in seconds used to accumulate audit logs before sending to Pub/Sub topic. Default value: 30 Min value: 1 Max value: 900 |
pty_pub_sub_topic | Pub/Sub topic where audit logs will be sent. |
6. Run the following command.
```
terraform init
```
Terraform will download necessary providers.
Run the following command to verify configuration and print out deployment plan.
Run the following command to deploy resources to your account.
Once deployment is complete Terraform will print output variables.
Record the following values:
- protect_function_name: ________________________________
- protect_function_url: __________________________
- api_gateway_managed_service: _____________________________
- api_gateway_protect_service_url: ____________________
- protect_function_resource_name: _______________________
Deploy API Gateway (Optional)
Terraform module provided by Protegrity allows deploying Google API Gateway proxy for the Cloud Protect Service.
To deploy API Gateway:
In the main.tf file set the following Terraform variables.
deploy_api_gateway = true
api_gateway_jwt_issuer = "<service-account>@<google-cloud-project-id>.iam.gserviceaccount.com"
api_gateway_jwks_uri = "https://www.googleapis.com/robot/v1/metadata/x509/<service-account>@<google-cloud-project-id>.iam.gserviceaccount.com"
Below is the brief description of each Terraform variable. You can find more information in the Terraform README file.
Note
The “aud” claim in the JWT must be set to Google API Gateway service name. You can find the API Gateway service name in API Gateway configuration in GCP console under Managed Service label. The service name is of the following format: <deployment-name>-<api-id>.apigateway.<google-cloud-project-id>.cloud.googRun terraform plan.
Run terraform apply.
Wait for the Terraform apply command to complete.
Once Terraform apply completes, it prints out deployment resources information. Record the following information from the Terraform output.
api_gateway_managed_service: ___________________
api_gateway_protect_service_url: ___________________
Follow instructions in the link below to generate JWT token which you can use to authorize request to Protegrity API Gateway endpoint. Use the same service account you configured in section above for api_gateway_jwks_uri.
https://cloud.google.com/iam/docs/create-short-lived-credentials-direct#create-jwt
Note
The method above requires roles/iam.serviceAccountTokenCreator iam role.Record identity token returned in step above:
gcloud_auth_token: ___________________
Run the following CURL command to test API Gateway deployment.
curl -X POST "{api_gateway_protect_service_url}/api/v1/unprotect" \
-H 'Authorization:Bearer {gcloud_auth_token}' \
-d '{
"user": "test",
"data_element":"alpha",
"data": ["UtfVk UHgcD!"]
}'
Verify the following output:
{"encoding":"utf8","results":["hello world!"],"success":true}
Test the Protect Function Installation
Before continuing with next steps, you can verify whether Cloud Functions are installed correctly. This step is optional and can be skipped.
Below you can find example CURL command to test your function.
Before you can execute it, you need to obtain temporary authentication token. Run the gcloud auth login and then gcloud auth print-identity-token commands. The logged in gcloud user must have the cloudfunctions.functions.invoke permission. Record the output of print identity token command.
gcloud_auth_token: _________________
Replace {protect_function_url}; with value recorded in previous step.
Replace {gcloud_auth_token} with value recorded in above step.
Run the following CURL command to test Function deployment.
curl -X POST "{protect_function_url}/pty/v1/unprotect" \
-H 'Authorization:Bearer {gcloud_auth_token}' \
-d '{
"user": "test",
"data_element":"alpha",
"data": ["UtfVk UHgcD!"]
}'
Verify the following output:
{"encoding":"utf8","results":["hello world!"],"success":true}
3.4 - Policy Agent Installation
Install the policy agent.
Policy Agent Function installation is done via Terraform scripts provided by Protegrity. Before running the template, some resources must be created manually.
ESA Server
Policy Agent function requires ESA server running and accessible from Agent Cloud Function on TCP port 8443. Make sure inbound connections on TCP:8443 are allowed for the network where ESA is hosted.
Note down ESA IP address:
ESA IP Address (EsaIpAddress): ___________________
Certificates on ESA
By default, ESA is configured with self-signed certificates, which can only be validated using self-signed CA certificate supplied in Cloud Function Environment variables configuration.
In case ESA is configured with publicly signed certificates, this section can be skipped since the Cloud Function will use public CA to validate ESA certificates.
To obtain self-signed CA certificate from ESA:
Log in to ESA Web UI.
Select Settings > Network > Manage Certificates.
Hover over Server Certificate and click on download icon to download the CA certificate.
After certificate is downloaded, open the PEM file in text editor and replace all new lines with escaped new line: \n.
To escape new lines from command line, use one of the following commands depending on your operating system:
Linux Bash:
awk 'NF {printf "%s\\n",$0;}' ProtegrityCA.pem > output.txt
Windows PowerShell:
(Get-Content '.\ProtegrityCA.pem') -join '\n' | Set-Content 'output.txt'
Record the certificate content with new lines escaped.
ESA CA Server Certificate (EsaCaCert): ___________________
This value will be used to set pty_esa_ca_server_cert Terraform variable in installation section.
For more information about ESA certificate management refer to Certificate Management Guide in ESA documentation.
Identify or Create a new VPC
Google Cloud VPC is used to route traffic from Policy Agent Cloud Function to ESA. If your ESA is in a Google Cloud VPC, it is recommended to create a serverless VPC access and record its name:
google_vpc_access_connector_name: ___________________
If ESA is not on Google Cloud VPC, you can either create one or choose to let Terraform script to create one. The Terraform script will create the following elements:
NAT gateway
To connect to ESA outside the Google Cloud Network
External IP address
Can add it to the allowlist by the firewall in the network environment where ESA is hosted.
Serverless VPC access
Allows connectivity from the Cloud function to the VPC.
Note
These services will incur additional Google Cloud charges.Creating ESA Credentials
Policy Agent Function requires ESA credentials to be provided as one of the two options:
Note
The username and password of the ESA user requires role with DPS Admin and Export Certificates permissions. Security Administrator is one of the predefined roles which contains the above permissions, however for separation of duties it is recommended to create custom role.Secret Manager
Secret Manager is the recommended option for storing ESA credentials.
Create ESA credentials secrets:
Log in to Google Account and select project where Protegrity service will be installed.
Go to Security > Secret Manager.
Select CREATE SECRET.
Specify the Secret Value:
{
"username": "{esa_username}",
"password": "{esa_password}"
}
Select Create Secret.
Once the secret is created, you should see the secret screen opened. If not click on the secret name to see a screen with secret versions.
Click on Actions, next to the secret version you just created.
Select Copy Resource ID and record the full secret version path, For example, projects/{project-id}/secrets/{secret name}/versions/2.
Secret resource id: ___________________
Custom Cloud Function
If you have the skills to write code, you may provide a custom Cloud Function that returns the ESA credentials to the Policy Agent. One use case is when reading the ESA credentials from a third-party password vault.
Create the Cloud Function:
Create a new 2nd gen Cloud Function using any runtime.
The Policy Agent does not provide an input payload.
The Cloud Function must return a response according to the following schema:
response:
type: object
properties:
username: string
password: string
For example,
example output: {"username": "admin", "password": "Password1234"}
Sample GCP Function in Python:
def handler(request):
return {"username": "admin", "password": "password1234"}
Warning
Protegrity does not recommend hardcoding ESA password in the clear.
Grant the Cloud Run Invoker role to the Policy Agent function service account.
Grant the cloudfunctions.functions.get permission to the Policy Agent function service account role.
Record the Function name:
ESA CREDENTIALS FUNCTION NAME: _______________
Agent Terraform scripts provided by Protegrity create a Cloud Function in your Google account. If you don’t specify the deployment bucket Terraform parameter, a new storage bucket will also be created. You can also create the following optional resources by specifying the corresponding parameters:
- Service account with IAM role
- VPC with NAT external IP
- VPC access connector
To install Policy Agent Function through Terraform:
From command shell, move to the directory where you downloaded Protegrity installation bundle.
Unzip the bundle, then unzip the protegrity-agent-gcp-{version}.zip. Verify that the following files are available:
- pty-agent-gcp/
- main.tf
- outputs.tf
- README.md
Open the main.tf file and update Terraform backend information at the top of the file:
terraform {
backend "gcs" {
bucket = ""
prefix = "protegrity/terraform/pty-protect-gcp/state"
}
}
Set the bucket property to Terraform Backend Bucket Name recorded in Google Cloud Storage
Set the prefix property with value unique to your deployment.
In the same main.tf file, specify the following Terraform variables.
| Parameter | Description |
|---|
| project_id | The Project ID recorded in the pre-configuration step |
| region | The Region recorded in the pre-configuration step, for example, us-central1. |
| deployment_id | Specify short name to identify deployment. This id will be added to all resources deployed with Terraform. |
| deployment_bucket | Use Deployment Bucket Name recorded in pre-configuration or leave empty to create new bucket. |
| deployment_bucket_location | Geographical location of deployment bucket, e.g., US, EU, ASIA. |
| deployment_file_directory_path | Path to directory where deployment zip file is located. By default the deployment file should be in the same directory as this main.tf file. |
| policy_download_cron_expression | Cron expression determining how often policy agent function will run to synchronize security policy from ESA. |
| create_service_account | Leave this as false if you created service account in pre-configuration. Otherwise set to true. |
| agent_function_service_account_email | Use Agent Function Service account recorded in pre-configuration or leave empty. |
| create_vpc | Set this to true, if you would like to create VPC with NAT, external IP and vpc access connector, otherwise leave empty. This will be ignored if google_vpc_access_connector_name is specified. |
| google_vpc_access_connector_name | Specify the existing VPC access connector name you identified in earlier step, otherwise leave empty. This setting will disable create_vpc = true. |
| google_vpc_access_connector_full_resource_name | Alternative configuration for VPC access connector. If this parameter is set the google_vpc_access_connector_name will be ignored. Use this parameter, if vpc connector is in different region/project that the one specified for the deployment. |
| labels | You can set this map to include labels for deployed resources. Pay attention to gcp label requirements. More information in: https://cloud.google.com/compute/docs/labeling-resources. For example, only use lowercase and maximum length of 63 characters. |
All the values were recorded in Pre-Configuration and this section’s previous steps.
Provide Policy update Terraform variables. In the same main.tf file, you can specify configuration related to policy update. Any of these variables can be updated at any given time by running the terraform again or directly in the GCP Console. Most of the values were recorded in previous installation steps.
Parameter | Description | Notes |
|---|
pty_esa_ip | ESA IP address or hostname | ESA Server |
pty_esa_ca_server_cert | ESA self-signed CA certificate used by policy Agent Function to ensure ESA is the trusted server. | Recorded in step Certificates on ESA In case ESA is configured with publicly signed certificates, the pty_esa_ca_server_cert configuration will be ignored. |
gcp_esa_credentials_secret_resource_id | ESA username and password (encrypted value by Google Cloud Secrets Manager). For example, projects/{project-id}/secrets/{secret name}/versions/{version} | Creating ESA Credentials |
pty_esa_credentials_function | ESA credentials GCP function resource name. For example, projects/{project-name}/locations/{region}/functions/{esa-credentials-function-name}. | Recorded in step Option 2: Custom Cloud Function ESA CREDENTIALS FUNCTION NAME. Presence of gcp_esa_credentials_secret_resource_id will cause this value to be ignored.
The Policy Agent Function must have network access and IAM permissions to call the ESA Credentials function you have created in Option 2: Custom Cloud Function. |
gcp_kms_key_resource_name | The Key full resource name. For Example, projects/{project-id}/locations/region/keyRings/ {key-ring}/cryptoKeys/{key-name}/cryptoKeyVersions/1 | Key Management Service |
gcp_protect_function_resource_name | List of comma separated Protect function resource names. For Example, projects/{project-id}/ locations/{region}/functions/{function-name1},projects/{project-id}/ locations/{region}/functions/{function-name2} | Use protect_function_resource_name recorded in Protect Service Installation section. |
gcp_policy_retention_storage_bucket | Deployment Bucket Name where the encrypted policy will be written. | You can use deployment bucket recorded in Google Cloud Storage section, or you can specify other existing bucket. |
gcp_policy_version_object_key | Filename of the encrypted policy stored in the Deployment Bucket Name | Default: policy.zip |
retain_policy_versions | Number of policy versions to retain as backup. (e.g. 2 will retain the latest 2 policies and remove older ones). -1 retains all. | Default: 10 |
disable_deploy | This flag can be either 1 or 0. If set to 1, then the agent will not update protector function with the newest policy. Else, the policy will be saved in the cloud storage bucket and deployed to the protector function. WarningAgent deployment requires a deployed Protect or Log Forwarder Cloud Run function when disable_deploy is set | Default: 0 |
log_level | Application and audit logs verbiage level | Default: INFO. Allowed values: DEBUG – the most verbose INFO, WARNING, ERROR – the least verbose |
policy_pull_timeout | Time in seconds to wait for the ESA to send the full policy | Default: 20 |
pty_core_casesensitive | Specifies whether policy usernames should be case sensitive | Default: no. Allowed values: yes, no |
pty_core_emptystring | Override default behavior. Empty string response values are returned as null values. For instance, (un)protect(’’) -> null (un)protect(’’) -> '' | Default: empty. Allowed values: null, empty |
esa_connection_timeout | Time in seconds to wait for the ESA response | Default: 5s |
pty_addipaddressheader | When enabled, agent will send its source IP address in the request header. This configuration works in conjunction with ESA hubcontroller configuration ASSIGN_DATASTORE_USING_NODE_IP (default=false). See Associating ESA Data Store With Cloud Protect Agent for more information. | Default: yes. Allowed values: yes, no |
pty_datastore_key | ESA policy datastore public key fingerprint (64 char long) e.g. 123bff642f621123d845f006c6bfff27737b21299e8a2ef6380aa642e76e89e5. | NoteThis configuration is not applicable for ESA versions lower than 10.2.The export key is the public part of an asymmetric key pair created in a Create KMS Key.
A user with Security Officer permissions adds the public key to the data store in ESA via Policy Management > Data Stores > Export Keys.
The fingerprint can then be copied using the Copy Fingerprint icon next to the key.
Refer to Exporting Keys to Datastore for details. |
pty_sync_datastore | Optional name of the policy datastore to sync with ESA. Refer to ESA documentation for more information on policy datastore sync. | Default: "" |
From local command line or Cloud Shell, change directory to location of the main.tf, for example:
protegrity-agent-gcp-{version}/pty-agent-gcp/
Run terraform init.
Terraform will download necessary providers.
Run terraform plan to verify configuration and print out deployment plan.
Run terraform apply to deploy resources to your account. Once deployment is complete, Terraform will print output variables.
Below is the sample output from successful deployment.
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
Outputs:
agent_function_service_account_email = "pty-agent-test@test.iam.gserviceaccount.com"
deployment_bucket_name = "test-bucket"
nat_ip = 0
policy_agent_function_deployment_object = "pty-agent-test-1.0.1.zip"
policy_agent_function_name = "pty-agent-test"
Test Agent Function Installation
After configuration is complete, you can test the function.
To test and run the Policy Agent Function:
From the Google Cloud console, go to Cloud Run Functions or Cloud Run.
Click on the function you just deployed: pty_agent_{deployment_id}.
Click Test button at the top right section of the screen.
Scroll down to CLI test command.
Copy and run the curl command to trigger the agent. Alternatively, use the option Test in Cloud Shell.
Wait for the function to complete.
Note
The Policy Agent function deploys a new version of the Cloud Protect Function with updated policy. This process may take several minutes. During this time, the previous policy version remains available until the function update is complete.Navigate to the LOGS tab to view agent execution logs.
Alternatively, you may review the logs by navigating to Logging from your Google Console. In the Log Explorer select the All resources dropdown, then Cloud Run Revision > pty-agent-{deployment-id} and apply.
Note
Example logs (most recent first):
Function execution took 23892 ms, finished with status: 'ok'
iap.policy_deployer:INFO:Deleting object [policy_v07-26-2021_21-00-00.zip]
iap.policy_deployer:INFO:Deleting object [policy_v07-26-2021_19-03-23.zip]
iap.policy_deployer:INFO:Removing old function versions in [test-artifacts]. Will retain [1] versions.
iap.policy_deployer:INFO:Updating function [projects/cloud-engineering-315519/locations/us-central1/functions/pty-protect-test] with new deployment artifact [test-artifacts/policy_v07-26-2021_21-00-01.zip] ...
iap.imp_creator:INFO:Uploading encrypted policy data to: [test-artifacts/policy_v07-26-2021_19-03-23.zip]
iap.imp_creator:INFO:Preparing deployment package ...
iap_agent_gcp.cloud_functions_util:INFO:Downloading function deployment package ...
iap.imp_creator:INFO:Encrypting policy package ...
iap.policy_agent:INFO:Preparing new policy deployment ...
iap.policy_agent:WARNING:Current policy deployment has no checksum_mapping metadata:
iap.imp_creator:INFO:Checking current policy version ...
iap.policy_agent:INFO:Current deployment package version: [policy_v07-26-2021_18-51-43.zip].
iap.policy_agent:INFO:Getting current policy metadata ...
iap.imp_creator:INFO:Policy downloaded successfully ...
iap.imp_creator:INFO:PepServer started ...
iap.imp_creator:INFO:Starting PepServer ...
iap.imp_creator:INFO:PepServer configured successfully
iap.imp_creator:INFO:Downloading certificates from ESA ...
iap.imp_creator:INFO:Configuring PepServer ...
iap.policy_agent:INFO:Starting policy agent ...
iap.policy_agent:INFO:Using Secret Manager [GCP_ESA_CREDENTIALS_SECRET_RESOURCE_ID] to retreive ESA credentials.
iap.policy_agent:INFO:PTY_CORE_CASESENSITIVE [no]
iap.policy_agent:INFO:PTY_CORE_EMPTYSTRING [empty]
iap.policy_agent:INFO:RETAIN_POLICY_VERSIONS [1]
iap.policy_agent:INFO:GCP_PROTECT_FUNCTION_RESOURCE_NAME [projects/test/locations/us-central1/functions/pty-protect-test]
iap.policy_agent:INFO:GCP_POLICY_VERSION_OBJECT_KEY [policy.zip]
iap.policy_agent:INFO:GCP_POLICY_RETENTION_STORAGE_BUCKET [test-artifacts]
iap.policy_agent:INFO:GCP_KMS_KEY_RESOURCE_NAME [projects/test/locations/us-central1/keyRings/test-key-ring/cryptoKeys/test-protect-asymmetric/cryptoKeyVersions/1]
iap.policy_agent:INFO:GCP_ESA_CREDENTIALS_SECRET_RESOURCE_ID [projects/1234/secrets/ESA_ADMIN_CREDENTIALS/versions/2]
iap.policy_agent:INFO:PTY_ESA_IP [54.236.107.39]
iap.policy_agent:INFO:POLICY_PULL_TIMEOUT [20]
iap.policy_agent:INFO:DISABLE_DEPLOY [0]
Function execution started
Troubleshooting
Configure additional logging:
Set log_level Terraform variable on the Agent function to DEBUG.
In the GCP Logs Explorer, you can run the query below, replacing placeholders with your deployment id and project name.
resource.type="cloud_run_revision"
resource.labels.service_name=~"pty-agent-<deploymentd-id>"
severity=ERROR OR textPayload=~"\[error\]"
-logName="projects/<gcp-project-id>/logs/run.googleapis.com%2Frequests"
Expand each log entry for more details. Check for jsonPayload > exception to see more detailed error.
Error message | Details |
|---|
iap_agent_gcp.cloud_functions_util.CloudFunctionsApiException: Resource 'projects/<account>/locations/<region>/functions/protegrity-protect-<deployment-id>' was not found
| This error may indicate the following configuration issues:- The function name indicated in setting gcp_protect_function_resource_name has been provided incorrectly, and thus cannot be found.
- disable_deploy has been set, and a dummy function has been entered to work around the gcp_protect_function_resource_name requirement. The Agent deployment requires a deployed Protect or Log Forwarder Cloud Run function to operate.
|
[ERROR] policy_agent:Invalid GCP_PROTECT_FUNCTION_RESOURCE_NAME parameter value. Must be a comma separated list of Lambda Function names or ARNs.
| This error may indicate the following configuration issues:- The setting gcp_protect_function_resource_name is empty. The Agent deployment requires a deployed Protect or Log Forwarder Cloud Run function to operate, this setting may not be left empty.
- The list of function names provided to gcp_protect_function_resource_name contains invalid function name or is not valid csv format.
|
[ERROR] iap_agent_gcp.cloud_functions_util:<HttpError 403 when requesting https://cloudfunctions.googleapis.com/v2/projects/<account>/locations/<region>/functions/pty-protect-<deployment-id>:generateDo
wnloadUrl?alt=json returned "Permission 'cloudfunctions.functions.sourceCodeGet' denied on 'projects/<account>/locations/<region>/functions/<deployment-id>'". Details: "Permission 'cloudfunctions.functions.sourceCodeGet' denied on 'projects/<account>/locations/<region>/functions/pty-protect-<deployment-id>'">
[ERROR] policy_agent:Permission 'cloudfunctions.functions.sourceCodeGet' denied on 'projects/<account>/locations/<region>/functions/pty-protect-<deployment-id>'
...
iap_agent_gcp.cloud_functions_util.CloudFunctionsApiException: Permission 'cloudfunctions.functions.sourceCodeGet' denied on 'projects/<account>/locations/<region>/functions/pty-protect-<deployment-id>'
| Indicates the Agent Cloud Run function’s identity does not have permissions to sourceCodeGet for Protect/Log Forwarder function(s) provided to the gcp_protect_function_resource_name configuration. |
3.5 - Audit Log Forwarder Installation
Install the audit log forwarder.
Audit Log Forwarder installation is done via Terraform scripts provided by Protegrity in the installation bundle.
ESA Audit Store Configuration
ESA server is required as the recipient of audit logs. Verify the information below to ensure ESA is accessible and configured properly.
ESA server running and accessible on TCP port 9200.
Audit Store service is configured and running on ESA. For information related to ESA Audit Store configuration, refer to Audit Store Guide.
Certificates on ESA
By default, ESA is configured with self-signed certificates, which can only be validated using self-signed CA certificate supplied in Log Forwarder configuration.
In case ESA is configured with publicly signed certificates, this section can be skipped since the Log Forwarder will use public CA to validate ESA certificates.
To obtain self-signed CA certificate from ESA:
Download ESA CA certificate from the /etc/ksa/certificates/plug directory of the ESA
After certificate is downloaded, open the PEM file in text editor and replace all new lines with escaped new line: \n.
To escape new lines from command line, use one of the following commands depending on your operating system:
Linux Bash:
awk 'NF {printf "%s\\n",$0;}' CA.pem > output.txt
Windows PowerShell:
(Get-Content '.\CA.pem') -join '\n' | Set-Content 'output.txt'
Record the certificate content with new lines escaped.
ESA CA Server Certificate (EsaCaCert): ___________________
This value will be used to set pty_esa_ca_server_cert Terraform variable in installation section. Install Log Forwarder via Terraform
For more information about ESA certificate management refer to Certificate Management Guide in ESA documentation.
VPC configuration
Similar to Policy Agent Function, log forwarder function requires Google Cloud VPC to route traffic from the function to ESA. Review the VPC configuration steps for agent in section Identify or Create a new VPC. Same VPC connector as the policy agent can be used. Note down VPC connector name:
google_vpc_access_connector_name: ___________________
ESA Authentication
Audit Log Forwarder must authenticate with ESA using certificate-based authentication with client certificate and certificate key.
Download the following certificates from the /etc/ksa/certificates/plug directory of the ESA:
| File Name | Description |
|---|
| client.key | Client certificate key |
| client.pem | Client certificate (PEM) |
Both certificate and certificate key must be converted to single-line values using code similar to the following examples.
Client certificate (client.pem):
$folder = 'C:\Temp'
cd $folder
(Get-Content "$folder\client.pem") -join '\n' | Set-Content "$folder\one-liner-client.pem"
cat "$folder\one-liner-client.pem"
folder="/tmp"
cd "$folder"
awk 'NF {printf "%s\\n",$0}' "client.pem" > "one-liner-client.pem"
cat "one-liner-client.pem"
Client certificate key (client.key):
$folder = 'C:\Temp'
cd $folder
(Get-Content "$folder\client.key") -join '\n' | Set-Content "$folder\one-liner-client.key"
cat "$folder\one-liner-client.key"
folder="/tmp"
cd "$folder"
awk 'NF {printf "%s\\n",$0}' "client.key" > "one-liner-client.key"
cat "one-liner-client.key"
Note
Use single-line certificate and single-line certificate key values below when configuring Log Forwarder.While installing using Terraform template:
- Provide single-line client certificate for pty_esa_client_cert
- Provide ID of the GCP secret containing the single-line certificate key for pty_esa_client_cert_key_secret_id Secret is created in a later step
Audit Log Forwarder Function uses GCP Secret Manager to store ESA Audit Store credentials used during authentication.
For information on how to configure basic and certificate authentication for Audit Store on ESA refer to Audit Store Guide.
Log in to Google Account and select project where Protegrity service will be installed.
Go to Security > Secret Manager.
Select CREATE SECRET.
Specify the Secret Value:
{
"username": "admin",
"password": "{esa_password}"
}
Select Create Secret.
Once the secret is created, you should see the secret screen opened. If not click on the secret name to see a screen with secret versions.
Click on Actions, next to the secret version you just created.
Select Copy Resource ID and record the full secret version path, for example, projects/{project-id}/secrets/{secret name}/versions/2.
ESA Log Forwarder Credentials Secret Name: _________________
Create another secret with single-line contents of ESA client certificate key file
See Certificate Authentication for details on client certificate key
Record the full secret version path, for example, projects/{project-id}/secrets/{secret name}/versions/1.
ESA Log Forwarder Client Certificate Key Secret Name: _________________
Create Log Forwarder Service Account
To create Log Forwarder Service Account:
Log in to Google Account and select the project where Protegrity service will be installed.
Navigate to IAM & Admin > Service Accounts.
Select CREATE SERVICE ACCOUNT.
Specify service account name and description.
Select Create and Continue.
In the next step, click Select Role. Then select the following roles:
- Cloud KMS CryptoKey Decrypter
- Pub/Sub Publisher
- Secret Manager Secret Accessor
Click Done.
Once the service account is created, the screen should open on the service account. If the screen does not appear, refresh the page with the service account list and select the service account created.
Record the full email. For example, service-account-name@project-id.iam.gserviceaccount.com.
Log Forwarder Function Service Account Email: ___________________
Create Service Account For Forwarder Pub/Sub
Pub/Sub service requires Cloud Run Invoker permissions in order to be able to send messages to the Forwarder function.
Log in to Google Account and select the project where Protegrity forwarder will be installed.
Navigate to IAM & Admin > Service Accounts.
Select CREATE SERVICE ACCOUNT.
Specify service account name and description.
Select Create and Continue.
In the next step, click Select Role. Then select Cloud Run Invoker.
Click Done.
Once the service account is created, the screen should open on the service account. If the screen does not appear, refresh the page with the service account list and select the service account created.
Record the full email. For example, service-account-name@project-id.iam.gserviceaccount.com.
Pub/Sub Log Forwarder Service Account Email: ___________________
Preparation
Ensure that all the steps in Google Cloud Project are performed.
Log in to the Google Cloud account where Protegrity will be installed.
Select the project.
Ensure that you have access to shell command on your computer or Cloud Shell with Terraform CLI v0.14 or higher installed.
Ensure that the Terraform scripts provided by Protegrity are available on your local computer.
Resources created with Terraform scripts include Audit Log Forwarder Cloud Functions Service and Pub/Sub topic. If you don’t specify the deployment bucket Terraform parameter, a new storage bucket will also be created. You can optionally choose to create a new service account with custom IAM role.
To install using Terraform:
From the command shell move to directory where you downloaded Protegrity installation bundle.
Unzip the bundle, then unzip the protegrity-gcp-bigquery-{version}.zip. Navigate to pty-log-forwarder-gcp/. Verify that the following files are available:
- pty-log-forwarder-gcp/
- main.tf
- outputs.tf
- protegrity-cloud-api-gcp-{version}.zip
- README.md
Open the main.tf file and update Terraform backend information at the top of the file:
terraform {
backend "gcs" {
bucket = ""
# The bucket/prefix combination must be unique for different deployments
# to avoid conflicting Terraform states and accidental resources destruction.
# prefix = "protegrity-gcp-bigquery/forwarder/<deployment_id>/tf-state"
}
}
Set the bucket property to Terraform Backend Bucket Name recorded in Google Cloud Storage
Set the prefix property with value unique to your deployment.
In the same main.tf file, specify the following Terraform variables: All the values were recorded in Google Cloud Project.
Warning
Google Cloud Function 2nd Generation currently does not support CMEK.| Parameter | Description |
|---|
| project_id | The project id recorded in the pre-configuration step |
| region | The Region recorded in the pre-configuration step. |
| deployment_id | Specify short name to identify deployment. This id will be added to all resources deployed with Terraform. |
| deployment_bucket | Use Deployment Bucket Name recorded in pre-configuration or leave empty to create new bucket. |
| create_service_account | Leave this as false if you created service account in pre-configuration. Otherwise set to true. |
| forwarder_function_service_account_email | Use Forwarder Function Service account recorded in pre-configuration or leave empty. |
| pub_sub_log_forwarder_service_account_email | Service account of the audit log Pub/Sub trigger. The service account must be assigned Cloud Run Invoker (roles/run.invoker) role. |
| create_vpc | If create_vpc flag is set, new vpc will be created together with vpc connector, NAT and external IP Use this flag if you have VPC admin permissions in your Google Account. If you set it to false, you can specify the existing VPC in the google_vpc_access_connector_name parameter. |
| google_vpc_access_connector_name | Use existing VPC connector to associate with Log Forwarder Function. You can specify either the VPC connector name or the full resource name if vpc connector is in different region/project that the one specified for the deployment. You can alternatively set the use google_vpc_access_connector_full_resource_name. Both parameters are optional. Full resource name takes precedence over connector name. |
| log_destination_esa_ip | Ip address of the ESA where Protector logs will be sent to. |
| pty_esa_ca_server_cert | ESA self-signed CA certificate used by log forwarder function to ensure ESA is the trusted server. See documentation for more details. |
| esa_credentials_secret_resource_id | GCP Secret Manager secret id where ESA Fluent Bit logger credentials are stored. |
| pty_esa_client_cert | Single-line ESA client certificate content. See Certificate Authentication for details on client certificate |
| pty_esa_client_cert_key_secret_id | GCP Secret Manager secret id where single-line ESA client certificate key content is stored. See Configure ESA Secrets In GCP Secret Manager for details on client certificate key secret |
| min_log_level | Minimum log level for log forwarder function. Must be one of the following: [off,severe,warning,info,config,all]. |
| esa_tls_disable_cert_verify | Disable certificate verification when connecting to ESA. This is only for dev purposes, should not be used in production environment. |
| esa_connect_timeout | Esa connection timeout in seconds. |
| esa_virtual_host | ESA Virtual Host. |
| audit_log_flush_interval | Time interval in seconds used to accumulate audit logs before sending to ESA. Default value: 10 Min value: 1 Max value: 900 |
| dlq_topic_message_retention_duration | Indicates the minimum duration to retain a message in dead letter queue topic in case log destination server is not available. Value must be decimal number, followed by the letter s (seconds). Cannot be more than 31 days or less than 10 minutes. Default value is 1 day |
| audit_log_dead_letter_topic | This parameter is expected to be used in a separate deployment to replay dead letter queue messages. |
| max_instance_count | GCP Cloud Functions advanced configuration |
| available_memory_mb | GCP Cloud Functions advanced configuration |
| timeout_seconds | GCP Cloud Functions advanced configuration |
| gen2_available_cpu | 2nd Gen Cloud Function advanced configuration |
| gen2_container_concurrency | 2nd Gen Cloud Function advanced configuration |
| upgrade_step | Set this variable when upgrading to the latest version. |
| labels | You can set this map to include labels for deployed resources. Pay attention to GCP label requirements. For more information, refer to the following link https://cloud.google.com/compute/docs/labeling-resources. For example, only use lowercase and maximum length of 63 characters. |
From local command line or Cloud Shell, change directory to location of the main.tf, for example:
pty-log-forwarder-gcp-{version}/pty-log-forwarder-gcp/
Run the following command.
Terraform will download necessary providers.
Run the following command to verify configuration and print out deployment plan.
Run the following command to deploy resources to your account.
Once deployment is complete Terraform will print output variables.
Record the following values:
- forwarder_function_name: ____________________________
- forwarder_function_url: ____________________________
- forwarder_function_resource_name: __________________
Turn on Instance-based billing.
Both Protect and Log Forwarder functions must run for a short period of time after all requests are handled. In order for the GCP Cloud Run service to allow that, the Instance-based billing feature must be enabled for both function deployments.
To enable Instance-based billing:
Log in to Google Account and select the project where Protegrity Cloud Run Function was installed.
Navigate to Cloud Run.
Click on the Cloud Function name.
In Cloud Run revision view, select Edit & deploy new revision.
Scroll down to Billing.
Select Instance-based.
Click DEPLOY.
Repeat the steps for Log Forwarder function.
Test Log Forwarder Function Installation
Before continuing with next steps, you can verify whether Log Forwarder Function is installed correctly. This step is optional and can be skipped.
Below you can find example CURL command to test your function.
Before you can execute it, test if you can obtain temporary authentication token. Run the gcloud auth login and then gcloud auth print-identity-token commands. The logged in gcloud user must have the Cloud Run Invoker permissions. Continue to the next step if the command succeeds and prints the token.
Replace {forwarder_function_url}; with value recorded in previous step.
Run the following CURL command to test Function deployment.
curl {forwarder_function_url} \
-H "Authorization: Bearer $(gcloud auth print-identity-token)" \
-H "Content-Type: application/json" \
-H "ce-id: 123451234512345" \
-H "ce-specversion: 1.0" \
-H "ce-time: 2020-01-02T12:34:56.789Z" \
-H "ce-type: google.cloud.pubsub.topic.v1.messagePublished" \
-H "ce-source: //pubsub.googleapis.com/projects/MY-PROJECT/topics/MY-TOPIC" \
-d '{
"message": {
"data": "'"$(echo '{"additional_info":{"description":"Data unprotect operation was successful.","query_id":"sf-query-id:k6-test-df51a612-4739-4cfb-9fe4-6ec548b70d23"},"client":{},"cnt":4000,"correlationid":"sf-query-id:k6-test-df51a612-4739-4cfb-9fe4-6ec548b70d23","level":"SUCCESS","logtype":"Protection","origin":{"hostname":"localhost","time_utc":1725558586},"process":{"id":1},"protection":{"audit_code":8,"dataelement":"alpha","datastore":"SAMPLE_POLICY","mask_setting":"","operation":"Unprotect","policy_user":"master_user"},"protector":{"core_version":"1.2.2+42.g01eb3.HEAD","family":"cp","pcc_version":"3.4.0.20","vendor":"gcp.snowflake","version":"3.1.0.158"},"signature":{"checksum":"7CE5FFCE9DBE570AAA72D1BB20CD083532EF8FAD3E96E38629EB92E837272D8E","key_id":"676c5178-756d-4363-9"}}' | base64 -w 0)"'",
"attributes": {},
"messageId": "",
"publishTime": "2014-10-02T15:01:23Z",
"orderingKey": ""
}
}'
In GCP Logs Explorer console verify that the following output appears in the logs:
Request finished HTTP/1.1 POST http://pty-forwarder-31-smoke-jf-pfadh7riaq-uc.a.run.app/ - 200 0 - 75.6570ms
Warning
Test steps will only succeed if the Policy Agent has not updated the Log Forwarder policy. Once updated, logs must be signed with your policy, and the sample data blob above will no longer pass the check, resulting in the error below:
[/jenkins/workspace/iaplambda_release_3.1/src/iap/logging/log-aggregator.cpp:66] Failed to aggregate log entry at index 0.
Grant Pub/Sub Publisher Permission to the Protect Function Service Account
Protect function requires permissions to publish audit log messages to Pub/Sub.
Log in to Google Account and select the project where Protegrity service will be installed.
Navigate to IAM & Admin.
Search for protector function service account email recorded in protect service installation step.
Select Edit principal pencil icon.
Select ADD ANOTHER ROLE.
Select Pub/Sub Publisher.
Click Save.
Protect Function Pub/Sub Log Output
Protect function must be configured to output audit logs to Pub/Sub topic.
To configure Protect function audit log output:
Go to Protect function Terraform deployment.
Navigate to pty-protect-gcp/main.tf.
Set Terraform variable pty_log_output=“pub_sub”.
Set Terraform variable pty_pub_sub_topic to log forwarder Pub/Sub topic.
Note
You can obtain the topic resource name from Log Forwarder Terraform output: audit_log_topic.Run terraform apply.
Troubleshooting
Configure additional logging:
Set min_log_level Terraform variable on both Protect function and Log Forwarder function to config.
In the GCP Logs Explorer, you can run the query below, replacing placeholders with your deployment id and project name.
resource.type="cloud_run_revision"
resource.labels.service_name=~"pty-(protect|forwarder)-<deploymentd-id>"
severity=ERROR OR textPayload=~"\[error\]"
-logName="projects/<gcp-project-id>/logs/run.googleapis.com%2Frequests"
Expand each log entry for more details. Check for jsonPayload > exception to see more detailed error.
Error message | Details |
|---|
Pub/Sub configuration error.
| Indicates problems with Pub/Sub service configuration/availability. Expand error log entry and check exception details. For instance: exception: "Grpc.Core.RpcException: Status(StatusCode="InvalidArgument", Detail="Invalid resource name given (name=projects/<todo>/topics/pty-forwarder-<todo>).
Verify that pty_pub_sub_topic Terraform variable is set to correct pub/sub resource name. Verify that Pub/Sub topic exists.
|
Failed to send x/y audit logs to GCP Pub/Sub.
| - This error may be shown as a consequence of Pub/Sub configuration/availability errors.
- Check for pub/sub configuration errors.
- If pub/sub configuration looks correct, this may indicate that cloud function can’t process audit logs fast enough.
- From Protector Function Terraform configuration, try increasing CPU and concurrency.
|
Audit log sink error: Unable to deliver all logs.
opensearch.0: Dropped records: 1/1
[error] [output:opensearch:opensearch.0] HTTP status=401 URI=/_bulk
| - Indicates problems with ESA Audit Store availability/configuration.
- Those errors will usually be displayed together. The third error will have details on what is the status or response from ESA.
- In this example, the HTTP status 401 indicates authentication issue.
|
3.6 -
Prerequisites
| Requirement | Detail |
|---|
| Protegrity distribution and installation scripts | These artifacts are provided by Protegrity |
| Protegrity ESA 10.0+ | The Cloud VNet must be able to obtain network access to the ESA |
| Google Cloud Account | Recommend creating a new project for Protegrity Serverless |
| Terraform CLI v0.14 or higher | Terraform is used to deploy resources to Google Cloud Account |
3.7 -
Required Skills and Abilities
| Requirements | Description |
|---|
| GCP Cloud Administrator | Run Terraform (or perform steps manually), create/configure a VPC and IAM permissions. |
| Protegrity Administrator | The ESA credentials required to extract the policy for the Policy Agent |
| Network Administrator | Open firewall to access ESA and evaluate Google Cloud network setup |
4 - REST API
Reference for Cloud API authorization and specification
The following sections describe key concepts for understanding the REST API.
Base URL: https://{YOUR_REGION}-{YOUR_PROJECT_ID}.cloudfunctions.net/{FUNCTION_NAME}
Substitute:
- YOUR_REGION - is the region where your function is deployed.
- YOUR_PROJECT_ID - is your Google Cloud Platform project ID.
- FUNCTION_NAME - recorded during the Protect function installation name.
4.1 - Policy Users
Protegrity Policy roles defines the unique data access privileges for every member.
Policy Users
Protegrity Policy roles defines the unique data access privileges for every member. The protector function protects the data with the username sent in either the JWT-formatted authorization header, the request body or service user in the environment variables.
The protector function behavior can be set in the cloud function environment variables as described in Install Protect Function via Terraform Scripts
| Authorization/allow_assume_user | 0 | 1 |
|---|
| Empty | User from the request body. / (Throw an error). | User from the request body. |
| JWT | User from JWT payload | User from request body. If not found user from JWT payload. |
Note
The service_user will always take priority over any other user in the payload or in the JWT header.4.2 - JWT Verification
Cloud Protect function can authenticate JWTs with an OpenID endpoint or a stored certificate/secret.
JWT Verification
Cloud Protect function can authenticate JWTs with an OpenID endpoint or a stored certificate/secret.
The protector must be able to reach specified OpenID endpoint to obtain the public key when OpenID settings are enabled. The retrieved key is used to verify the signature. Several additional claims are verified against the configuration provided to the protect function when OpenID is enabled: issuer, audience, appid (optional).
Availability of an OpenID endpoint from the protector may not be feasible or a non-OpenID issuer may be in use. In those cases, a stored certificate/secret may be used to validate the jwt signature by enabling jwt_verify and including a base64 encoded certificate/secret in jwt_secret_base64 configuration. Additional claims are not verified.
Secret
Stored secret verification example using jwt_verify and jwt_secret_base64 configurations:
- Navigate to the cloud function main.tf configuration file, and find the section Parameters applicable when authorization = jwt
- Edit/replace the entries as indicated below, then save and apply the configuration:
Parameter | Value | Notes |
|---|
authorization | JWT |
jwt_verify | 1 | |
jwt_secret_base64 | Secret in base64 encoding. For example, the value of the public key is as follows. -----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC4fkg/JYyN3Skr6RYLiAd/Yhl0
2TE3/HzHSNPnCaRdUakGp9og7oXBMcoadFDjnoSq1sz+gUHnpoO7s2fwkD5Q4OnC
BGD3oKP2A4PlOOWD2B2cVmMqX/vf1nAA/343496jsbfgkh1Q7LTzR0IXfdii0o1U
CbvrVCuaBoyiv4TxWQIDAQAB
-----END PUBLIC KEY-----
This public key will be stored as follows. LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tL
S0KTUlHZk1BMEdDU3FHU0liM0RRRUJBUV
VBQTRHTkFEQ0JpUUtCZ1FDNGZrZy9KWXl
OM1NrcjZSWUxpQWQvWWhsMAoyVEUzL0h6
SFNOUG5DYVJkVWFrR3A5b2c3b1hCTWNvY
WRGRGpub1NxMXN6K2dVSG5wb083czJmd2
tENVE0T25DCkJHRDNvS1AyQTRQbE9PV0Q
yQjJjVm1NcVgvdmYxbkFBLzM0MzQ5Nmpz
YmZna2gxUTdMVHpSMElYZmRpaTBvMVUKQ
2J2clZDdWFCb3lpdjRUeFdRSURBUUFCCi
0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLQ==
| The secret must be in base64. We recommend using RSA public certificates, it is not recommended to keep Hash (symmetric) secrets in the clear. |
OpenID
Verification example using openid_* configuration parameters:
- Navigate to the cloud function main.tf configuration file, and find the section Parameters applicable when openid_enabled = true
- Edit/replace the entries as indicated below, then save and apply the configuration:
| Parameter | Value | Notes |
|---|
| openid_enabled | true | |
| openid_audiences | Audience as it would appear in the aud claim, for example “https://management.azure.com/" | Can be either one value or comma separated list. |
| openid_issuers | Issuer as it would appear in the iss claim, for example “https://sts.windows.net/bca3157d-b8d9-4ca8-a724-1c7e2b96e1ef" | Can be either one value or comma separated list. |
| openid_appid | Appid as it would appear in the appid claim, for example “9ada3e7d-4ec4-48da-9d69-5379b7984fe1” | Optional. If value is “”, appid claim is ignored. When openid_appid is provided, it must match the appid claim of the token. |
4.3 - Authorization Header
Authorization Header
Allowing unauthenticated HTTP function invocation on Google Cloud protector function.
The Protect function will validate the JWT in the Authorization header.
Authenticating for invocation on Google Cloud protector function. All requests to the protector function will need to send the Google JWT in the Authorization header.
When PTY_GCP_JWT_HEADER is not set or it is false the Protect function will validate the JWT in the Authorization header.
When PTY_GCP_JWT_HEADER = true the Protect function will validate the JWT in the X-PTY-Authorization header.
4.4 - Export an OpenAPI Spec
Exporting OpenAPI Spec from GCP
Export an OpenAPI Spec
Once the Cloud API on GCP is installed, you can export the OpenAPI documentation file from:
{base url}/pty/v1/openapi
Authentication and Authorization configurations are enforced on the openapi endpoint URL.
Tip
To get the base url, login to Google Cloud console. Navigate to the Protect Cloud Function details and to the TRIGGER tab.
For testing the REST API, we recommend using a client tool, such as Postman.
4.5 - v1 Specification
Describes the v1 REST API specification
Request
AWS Lambda service limits maximum size of payload to 6 MB. Client applications of Protegrity Cloud API must ensure their payload size is within this limit. This applies to all types of requests described below.
Performs a policy operation such as protect, unprotect, or reprotect.
URI
/v1/protect or /v1/unprotect or /v1/reprotect
Method
POST
Parameters
data: Input data to the policy operation.
data_element: Data element to use for the policy operation.
encoding: Optional, encoding of the data. One of: base64, base64_mime, base64_pem, base64_url, hex, or utf8. Defaults to hex for binary data elements, otherwise defaults to utf8.
external_iv: Optional, external initialization vector.
old_data_element: (reprotect) Data element for unprotecting the input.
old_external_iv: (reprotect) Optional, external initialization vector for the input.
query_id: Optional, identifier for the request.
user: User performing the operation.
Result
Returns the output of the policy operation.
Example 1 - without external IV
{
"encoding": "utf8",
"query_id": "1",
"user": "user1",
"data_element": "Alphanum",
"data":[<data1>,<data2>]
}
Example 2 - with external IV
{
"encoding": "utf8",
"query_id": "1",
"user": "user1",
"data_element": "Alphanum",
"external_iv": "abc123",
"data":[<data1>,<data2>]
}
Example 3 - reprotect
{
"encoding": "utf8",
"query_id": "1",
"user": "user1",
"data_element": "deName",
"old_data_element": "Alphanum",
"data":[<data1>,<data2>]
}
Performs policy operations using different data elements for each data set.
URI
/v1/protect or /v1/unprotect or /v1/reprotect
Method
POST
Parameters
encoding: Optional, encoding of the data. One of: base64, base64_mime, base64_pem, base64_url, hex, or utf8. Defaults to hex for binary data elements, otherwise defaults to utf8.
query_id: Optional, prefix for the request identifier.
user: User performing the operation.
arguments[].data: Input data to the policy operation.
arguments[].data_element: Data element to use for the policy operation.
arguments[].external_iv: Optional, external initialization vector.
arguments[].id: Optional, request identifier.
arguments[].old_data_element: (reprotect) Data element for unprotecting the input.
arguments[].old_external_iv: (reprotect) Optional, external initialization vector for the input.
Note
When multiple data elements are sent in the payload, the Cloud API generates an audit log per argument. The Cloud API appends the argument id, if it exists, to the query_id. For example: query_id.id:{id}. If an argument id is not provided then the index in the argument array is appended to the query_id. For example: query_id.index:{index}.Example 4 - multiple data elements support payload
{
"encoding": "utf8",
"query_id": "query1234",
"user": <policy_user>,
"arguments": [
{
"id": "1",
"external_iv": "<external iv>",
"data_element": "<data element name>",
"data":["<data1>","<data2>"]
},
{
"data_element": <data element name>,
"data":["<data1>","<data2>"]
}
]
}
External IV
The External IV feature provides an additional level of security by allowing different tokenized results across protectors for the same input data and token element, depending on the External IV set on each protector. External IVs must adhere to certain guardrails and not all data elements support External IV. To read more about the Tokenization model with External IV, refer to the External Initialization Vector (IV) chapter in the Protection Methods Reference.
Response
responsePayloadV1:
type: object
properties:
success:
type: bool
error_msg:
type: string
description: When success is false, error_msg is included
results:
type: array
items:
type: string
Example success:
{
"encoding": "utf8",
"results":["str1","str2"],
"success": true
}
If the request was successful, the success flag will always be true.
Example failure:
{
"error_msg": "token expired",
"success": false
}
If the request fails, the success flag will always be false.
Multi Data Elements Support Payload
responsePayloadV2:
type: object
properties:
success:
type: boolean
results:
type: array
items:
type: object
properties:
success:
type: bool
error_msg:
type: string
description: When success is false, error_msg is included
id:
type: string
description: When id is sent in the request payload, id is included in the response
results:
type: array
items:
type: string
Example success:
{
"encoding": "utf8",
"results":[
{
"encoding": "utf8",
"results":["str1","str2"],
"success": true
},
{
"encoding": "utf8",
"results":["str1","str2"],
"success": true
}
],
"success": true
}
If the all the subrequests were successful, the success flag will be true.
Example failure:
{
"results": [
{
"error_msg":
"Protect failed. Data element not found. Refer to audit log for details",
"success": false
},
{
"encoding": "utf8",
"results":["str1","str2"],
"success": true
}
],
"success": false
}
It is possible to have a mix of successful and unsuccessful results. In this case, the global success flag will be false.
4.6 - Legacy Specification
Describes the Legacy REST API specification
Protegrity has multiple products with REST API capabilities, such as Protection Server (out of support), DSG, and the latest product - IAP REST. Each one has its use case. To help you move to cloud-native implementation, Cloud Product REST API supports legacy payload.
Request
Performs a policy operation such as protect, unprotect, or reprotect.
Method
POST
Parameters
dataelementname: (protect/unprotect) Data element to use for the policy operation.
externaliv: (protect/unprotect) Optional, external initialization vector.
newdataelementname: (reprotect) Data element to use for the output.
newexternaliv: (reprotect) Optional, external initialization vector for the output.
olddataelementname: (reprotect) Data element to use for the input.
oldexternaliv: (reprotect) Optional, external initialization vector for the input.
policyusername: User performing the operation.
bulk.id: Optional, identifier for the request.
bulk.data[].content: Input data to the policy operation.
Result
Returns the output of the policy operation.
Example 1 - protect without external IV
{
"protect": {
"policyusername": "user1",
"dataelementname": "Alphanum",
"bulk": {
"id": "1",
"data": [
{
"content": <Data encoded in base64>
}
]
}
}
}
Example 2 - protect with external IV
{
"protect": {
"policyusername": "user1",
"dataelementname": "Alphanum",
"externaliv": "abc123",
"bulk": {
"id": "1",
"data": [
{
"content": <Data encoded in base64>
}
]
}
}
}
Example 3 - unprotect
{
"unprotect": {
"policyusername": "user1",
"dataelementname": "Alphanum",
"bulk": {
"id": "1",
"data": [
{
"content": <Data encoded in base64>
}
]
}
}
}
Example 4 - reprotect
{
"reprotect": {
"policyusername": "user1",
"newdataelementname": "deName",
"olddataelementname": "Alphanum",
"bulk": {
"id": "1",
"data": [
{
"content": <Data encoded in base64>
}
]
}
}
}
Response
Example:
{"protect":{"bulk":{"returntype":"success","data":[{"returntype":"success","message":"Data
protection was successful.","content":"RGZBUFR4ODAzejFwNjQ5TWg0TEFpcFNqbA=="},{"returntype":"success",
"message":"Data protection was successful.","content":"aHNnVVB5QWFDYw=="}]}}}
4.7 - HTTP Status Codes
Explains about the HTTP Status Codes.
HTTP Status Codes
The following table explains the different HTTP Status Codes with their corresponding response.
Status Codes | Response | Description |
|---|
200 | {"results":["<string>","<string>"],
"success": true, "encoding":[hex|utf8]}
| Success protected data is in results and success attribute is true |
400 | {
"error_msg": "<string>",
"success": false
}
| There was an issue in the request, success is false, check error_msg attribute. For more information check the logs |
500 | {"error_msg": "", "success": false }
| Configuration error in the Google Cloud function configuration variables. |
4.8 - SSL Certificates
Reference for SSL Certificate resources in GCP Cloud Run Functions
SSL Certificates
By default, the Google Cloud Functions support HTTPS.
Google Cloud Function HTTPS endpoint have TLS 1.0, TLS 1.1, TLS 1.2 and TLS1.3 enabled.
For more information on HTTPS setting on Google Cloud HTTP Functions, refer to Security levels
4.9 -
OpenID
Verification example using openid_* configuration parameters:
- Navigate to the cloud function main.tf configuration file, and find the section Parameters applicable when openid_enabled = true
- Edit/replace the entries as indicated below, then save and apply the configuration:
| Parameter | Value | Notes |
|---|
| openid_enabled | true | |
| openid_audiences | Audience as it would appear in the aud claim, for example “https://management.azure.com/" | Can be either one value or comma separated list. |
| openid_issuers | Issuer as it would appear in the iss claim, for example “https://sts.windows.net/bca3157d-b8d9-4ca8-a724-1c7e2b96e1ef" | Can be either one value or comma separated list. |
| openid_appid | Appid as it would appear in the appid claim, for example “9ada3e7d-4ec4-48da-9d69-5379b7984fe1” | Optional. If value is “”, appid claim is ignored. When openid_appid is provided, it must match the appid claim of the token. |
4.10 -
Request
Performs a policy operation such as protect, unprotect, or reprotect.
URI
/v1/protect or /v1/unprotect or /v1/reprotect
Method
POST
Parameters
data: Input data to the policy operation.
data_element: Data element to use for the policy operation.
encoding: Optional, encoding of the data. One of: base64, hex, or utf8. Defaults to hex for binary data elements, otherwise defaults to utf8.
external_iv: Optional, external initialization vector.
old_data_element: (reprotect) Data element for unprotecting the input.
old_external_iv: (reprotect) Optional, external initialization vector for the input.
query_id: Optional, identifier for the request.
user: User performing the operation.
Result
Returns the output of the policy operation.
Example 1 - without external IV
{
"encoding": "utf8",
"query_id": "1",
"user": "user1",
"data_element": "Alphanum",
"data":[<data1>,<data2>]
}
Example 2 - with external IV
{
"encoding": "utf8",
"query_id": "1",
"user": "user1",
"data_element": "Alphanum",
"external_iv": "abc123",
"data":[<data1>,<data2>]
}
Example 3 - reprotect
{
"encoding": "utf8",
"query_id": "1",
"user": "user1",
"data_element": "deName",
"old_data_element": "Alphanum",
"data":[<data1>,<data2>]
}
Performs policy operations using different data elements for each data set.
URI
/v1/protect or /v1/unprotect or /v1/reprotect
Method
POST
Parameters
encoding: Optional, encoding of the data. One of: base64, hex, or utf8. Defaults to hex for binary data elements, otherwise defaults to utf8.
query_id: Optional, prefix for the request identifier.
user: User performing the operation.
arguments[].data: Input data to the policy operation.
arguments[].data_element: Data element to use for the policy operation.
arguments[].external_iv: Optional, external initialization vector.
arguments[].id: Optional, request identifier.
arguments[].old_data_element: (reprotect) Data element for unprotecting the input.
arguments[].old_external_iv: (reprotect) Optional, external initialization vector for the input.
Note: When multiple data elements are sent in the payload, the Cloud API generates an audit log per argument. The Cloud API appends the argument id, if it exists, to the query_id. For example: query_id.id:{id}. If an argument id is not provided then the index in the argument array is appended to the query_id. For example: query_id.index:{index}.
Example 4 - multiple data elements support payload
{
"encoding": "utf8",
"query_id": "query1234",
"user": <policy_user>,
"arguments": [
{
"id": "1",
"external_iv": "<external iv>",
"data_element": "<data element name>",
"data":["<data1>","<data2>"]
},
{
"data_element": <data element name>,
"data":["<data1>","<data2>"]
}
]
}
External IV
The External IV feature provides an additional level of security by allowing different tokenized results across protectors for the same input data and token element, depending on the External IV set on each protector. To read more about the Tokenization model with External IV, refer to the External Initialization Vector (IV) in the Protection Methods Reference guide.
4.11 -
Request
Performs a policy operation such as protect, unprotect, or reprotect.
Method
POST
Parameters
dataelementname: (protect/unprotect) Data element to use for the policy operation.
externaliv: (protect/unprotect) Optional, external initialization vector.
newdataelementname: (reprotect) Data element to use for the output.
newexternaliv: (reprotect) Optional, external initialization vector for the output.
olddataelementname: (reprotect) Data element to use for the input.
oldexternaliv: (reprotect) Optional, external initialization vector for the input.
policyusername: User performing the operation.
bulk.id: Optional, identifier for the request.
bulk.data[].content: Input data to the policy operation.
Result
Returns the output of the policy operation.
Example 1 - protect without external IV
{
"protect": {
"policyusername": "user1",
"dataelementname": "Alphanum",
"bulk": {
"id": "1",
"data": [
{
"content": <Data encoded in base64>
}
]
}
}
}
Example 2 - protect with external IV
{
"protect": {
"policyusername": "user1",
"dataelementname": "Alphanum",
"externaliv": "abc123",
"bulk": {
"id": "1",
"data": [
{
"content": <Data encoded in base64>
}
]
}
}
}
Example 3 - unprotect
{
"unprotect": {
"policyusername": "user1",
"dataelementname": "Alphanum",
"bulk": {
"id": "1",
"data": [
{
"content": <Data encoded in base64>
}
]
}
}
}
Example 4 - reprotect
{
"reprotect": {
"policyusername": "user1",
"newdataelementname": "deName",
"olddataelementname": "Alphanum",
"bulk": {
"id": "1",
"data": [
{
"content": <Data encoded in base64>
}
]
}
}
}
4.12 -
Response
responsePayloadV1:
type: object
properties:
success:
type: bool
error_msg:
type: string
description: When success is false, error_msg is included
results:
type: array
items:
type: string
Example success:
{
"encoding": "utf8",
"results":["str1","str2"],
"success": true
}
If the request was successful, the success flag will always be true.
Example failure:
{
"error_msg": "token expired",
"success": false
}
If the request fails, the success flag will always be false.
Multi Data Elements Support Payload
responsePayloadV2:
type: object
properties:
success:
type: boolean
results:
type: array
items:
type: object
properties:
success:
type: bool
error_msg:
type: string
description: When success is false, error_msg is included
id:
type: string
description: When id is sent in the request payload, id is included in the response
results:
type: array
items:
type: string
Example success:
{
"encoding": "utf8",
"results":[
{
"encoding": "utf8",
"results":["str1","str2"],
"success": true
},
{
"encoding": "utf8",
"results":["str1","str2"],
"success": true
}
],
"success": true
}
If the all the subrequests were successful, the success flag will be true.
Example failure:
{
"results": [
{
"error_msg":
"Protect failed. Data element not found. Refer to audit log for details",
"success": false
},
{
"encoding": "utf8",
"results":["str1","str2"],
"success": true
}
],
"success": false
}
It is possible to have a mix of successful and unsuccessful results. In this case, the global success flag will be false.
4.13 -
Response
Example:
{"protect":{"bulk":{"returntype":"success","data":[{"returntype":"success","message":"Data
protection was successful.","content":"RGZBUFR4ODAzejFwNjQ5TWg0TEFpcFNqbA=="},{"returntype":"success",
"message":"Data protection was successful.","content":"aHNnVVB5QWFDYw=="}]}}}
4.14 -
Secret
Stored secret verification example using jwt_verify and jwt_secret_base64 configurations:
- Navigate to the cloud function main.tf configuration file, and find the section Parameters applicable when authorization = jwt
- Edit/replace the entries as indicated below, then save and apply the configuration:
Parameter | Value | Notes |
|---|
authorization | JWT |
jwt_verify | 1 | |
jwt_secret_base64 | Secret in base64 encoding. For example, the value of the public key is as follows. -----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC4fkg/JYyN3Skr6RYLiAd/Yhl0
2TE3/HzHSNPnCaRdUakGp9og7oXBMcoadFDjnoSq1sz+gUHnpoO7s2fwkD5Q4OnC
BGD3oKP2A4PlOOWD2B2cVmMqX/vf1nAA/343496jsbfgkh1Q7LTzR0IXfdii0o1U
CbvrVCuaBoyiv4TxWQIDAQAB
-----END PUBLIC KEY-----
This public key will be stored as follows. LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tL
S0KTUlHZk1BMEdDU3FHU0liM0RRRUJBUV
VBQTRHTkFEQ0JpUUtCZ1FDNGZrZy9KWXl
OM1NrcjZSWUxpQWQvWWhsMAoyVEUzL0h6
SFNOUG5DYVJkVWFrR3A5b2c3b1hCTWNvY
WRGRGpub1NxMXN6K2dVSG5wb083czJmd2
tENVE0T25DCkJHRDNvS1AyQTRQbE9PV0Q
yQjJjVm1NcVgvdmYxbkFBLzM0MzQ5Nmpz
YmZna2gxUTdMVHpSMElYZmRpaTBvMVUKQ
2J2clZDdWFCb3lpdjRUeFdRSURBUUFCCi
0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLQ==
| The secret must be in base64. We recommend using RSA public certificates, it is not recommended to keep Hash (symmetric) secrets in the clear. |
5 - Performance
Performance benchmarks and considerations.
5.1 - Performance Considerations
The following factors may affect performance benchmarks
The following factors may affect performance benchmarks:
- Cold startup: Cloud Function spends additional time on the initial invocation to decrypt and load the policy into memory. This time can vary depending on the policy size. Once the Function is initialized, subsequent “warm executions” should process quickly.
- Size of policy: The size of the policy impacts cold start performance. Larger policies take more time to initialize.
- Cloud Function memory: GCP provides more virtual cores based on the memory configuration. The initial configuration of 2048 MB provides a good tradeoff between performance and cost with the benchmarked policy. Memory can be increased to optimize for your individual cases.
- Number of security operations (protect or unprotect).
- Cloud Function max instances and concurrency quota: The instance limit affects how functions are scaled. By default the limit is not set to allow handling any traffic pattern. The instance limit can be set to prevent abnormally high request levels. Cloud Functions are also subject to maximum quota for concurrent invocations and request rate.
- Size of data element: Operations on larger text consume time.
5.2 - Log Forwarder Performance
Guidance on Log Forwarder Performance settings and considerations.
Log forwarder architecture is optimized to minimize the amount of connections and reduce the overall network bandwidth required to send audit logs to ESA. This is achieved with batching and aggregation taking place on two levels. The first level is in protector function instances, where audit logs from consecutive requests to an instance are batched and aggregated. The second level of batching and aggregation takes place in the log forwarder function before audit logs are forwarded to ESA. This section shows how to configure the deployment to accommodate different patterns of anticipated audit log stream. It also shows how to monitor deployment resources to detect problems before audit records are lost.
Protector Function Terraform configuration:
- audit_log_flush_interval: Determines the minimum amount of time audit logs are aggregated for before they are sent to Pub/Sub topic. Default value is 30 seconds. Changing flush interval may affect the level of aggregation and it will affect the backlog of audit logs buffered in the function. The protector function features multithreaded processing which means that multiple requests can be handled at the same time, which in turn can contribute to large backlog of audit logs waiting to be sent to Pub/Sub. The protector function is hosted on Cloud Run containerized environment where each instance of the function is shut down after specific amount of time when there is no more requests to be handled. If the flush interval is too long, the function might be shut down before all of the audit log backlog is send to Pub/Sub. This can be avoided by lowering the interval value.
Log Forwarder Function Terraform configuration
- audit_log_flush_interval: Determines the minimum amount of time audit logs are aggregated for before they are sent to ESA audit log store. Default value is 10 seconds. Changing flush interval may affect the level of aggregation and it will affect the backlog of audit logs buffered in the function. The forwarder function features multithreaded processing which means that multiple requests can be handled at the same time, which in turn can contribute to large backlog of audit logs waiting to be sent to ESA. The forwarder function is hosted on Cloud Run containerized environment where each instance of the function is shut down after specific amount of time when there is no more requests to be handled. If the flush interval is too long, the function might be shut down before all of the audit log backlog is send to ESA. This can be avoided by lowering the interval value. On the other hand if the interval is too short, forwarder function might end up sending to many requests to ESA, which in some extreme cases may result in messages being sent to dead letter queue.
- gen2_available_cpu: Increasing the Function CPU count allows setting higher concurrency, which in turn allows processing more messages from the Pub/Sub in parallel. The high CPU count will effectively lower the number of forwarder function instances which will lower number of connections to ESA.
- gen2_container_concurrency: See bullet point above.
- audit_log_dead_letter_topic: Dead-letter Pub/Sub topic name. This topic will be used by Log Forwarder in case ESA is temporarily unavailable. Messages from DLQ topic can be re-processed by another instance of Log Forwarder either manually or on schedule once ESA connectivity is restored.
Monitoring Log Forwarder Resources
Protector Function Logs: If protector function is unable to send logs to Pub/Sub, it will log the following message:
Failed to send x/y audit logs to GCP Pub/Sub.
See the description of ‘audit_log_flush_interval’ in the protector function configuration section above to learn about potential mitigation.
Pub/Sub DLQ Topic Metrics: Any positive value in count aggregator on ’topic/message_sizes’ metric indicates that not all audit logs are being delivered to ESA. Review whether connection to ESA is set up in Install Log Forwarder Function via Terraform Scripts
Log Forwarder Function Logs: If log forwarder function is unable to send logs to ESA, it will log the following message:
[/jenkins/workspace/iaplambda_release_3.1/src/iap/logging/fluent-bit-external-sink.cpp:225] opensearch.0: Dropped records: x/y.
See the description of ‘audit_log_flush_interval’ in the log forwarder configuration section above to learn about potential mitigation.
Note
When the error message above occurs, the dropped audit records will be sent to a dead-letter Pub/Sub topic for later manual or automated re-processing.
6 - Audit Logging
Audit log description/formatting
Audit Logging
Audit records and application logs stream to Google Cloud Logging. Cloud Protect uses a JSON format for audit records that is described in the following sections.
You can analyze and alert on audit records using Protegrity ESA or Google Cloud Logging. For more information about forwarding your audit records to ESA, contact Protegrity. For more information about Google Cloud Logging, refer to the Google Cloud Logging overview.
For more information about audit records, refer to the Protegrity Analytics Guide.
Audit record fields
The audit record format has been altered in version 3.1 of the protector to provide more information.
| Field | Description |
|---|
| additional_info.deployment_id | The deployment_id contains the name of the Protect Function. It is automatically set based on the cloud-specific environment variables assigned to the Protect Function. This allows identifying the Cloud Protect deployment responsible for generating audit log. |
| additional_info.cluster | (Optional) Redshift cluster ARN |
| additional_info.description | A human-readable message describing the operation |
| additional_info.query_id | (Optional) Identifies the query that triggered the operation |
| additional_info.request_id | (Optional) AWS Lambda request identifier |
| cnt | Number of operations, may be aggregated |
| correlationid | (Deprecated) Use additional_info instead |
| level | Log severity, one of: SUCCESS, WARNING, ERROR, EXCEPTION |
| logtype | Always “Protection” |
| origin.ip | The private IP address of the compute resource that operates the Protect Function and is responsible for generating the log entry.NoteThe IP address is private, meaning it is used for internal network communication and is not accessible directly from the public internet. When Log Forwarding is enabled the IP address may be aggregated into minimal CIDR blocks. |
| origin.hostname | Hostname of the system that generated the log entry |
| origin.time_utc | UTC timestamp when the log entry was generated |
| protection.audit_code | Audit code of the protect operation; see the log return codes table in the Protegrity Troubleshooting Guide |
| protection.dataelement | Data element used for the policy operation |
| protection.datastore | Name of the data store corresponding to the deployed policy |
| protection.mask_setting | (Optional) Mask setting from policy management |
| protection.operation | Operation type, one of: Protect, Unprotect, Reprotect |
| protection.policy_user | User that performed the operation |
| protector.core_version | Internal core component version |
| protector.family | Always “cp” for Cloud Protect |
| protector.lambda_version | Protector Lambda application version. |
| protector.pcc_version | Internal pcc component version |
| protector.vendor | Identifies the cloud vendor and the database vendor |
| protector.version | Protector version number |
| signature.checksum | Hash value of the signature key ID used to sign the log message when the log is generated |
| signature.key_id | Key used to sign the log message when the log is generated |
The following are sample audit messages:
Protect Success:
{
"additional_info": {
"description": "Data protect operation was successful.",
"query_id": "sf-query-id:01978dbc-0582-d7e4-0000-002a3603a20d",
"request_id": "8476a536-e9f4-11e8-9739-2dfe598c3fcd"
},
"cnt": 4000,
"correlationid": "sf-query-id:01978dbc-0582-d7e4-0000-002a3603a20d",
"logtype": "Protection",
"level": "SUCESS",
"origin": {
"hostname": "localhost",
"time_utc": 1635363966
},
"protection": {
"dataelement": "deAddress",
"operation": "Protect",
"audit_code": 6,
"datastore": "SAMPLE_POLICY",
"policy_user": "test_user"
},
"client": {},
"protector": {
"family": "cp",
"lambda_version": "3.2.10",
"version": "3.2.0",
"vendor": "aws.snowflake",
"pcc_version": "3.4.0.14",
"core_version": "1.2.1+55.g590fe.HEAD"
},
"signature": {
"key_id": "95f5a194-b0a4-4351-a",
"checksum": "B324AF7C56944D91C47847A77C0367C594C0B948E7E75654B889571BD4F60A71"
}
}
User permission denied:
{
"additional_info": {
"description": "The user does not have the appropriate permissions to perform the requested operation."
},
"cnt": 4000,
"correlationid": "sf-query-id:01978dbc-0582-d7e4-0000-002a3603a20d",
"logtype": "Protection",
"level": "ERROR",
"origin": {
"hostname": "localhost",
"time_utc": 1635363966
},
"protection": {
"dataelement": "deAddress",
"operation": "Protect",
"audit_code": 3,
"policy_user": "test_user"
},
"process": {
"id": "1",
"thread_id": "849348352"
},
"client": {},
"protector": {
"family": "IAP Lambda",
"lambda_version": "3.2.10",
"version": "3.2.0",
"vendor": "Cloud Protect",
"pcc_version": "3.3.0.5",
"core_version": "1.1.0"
},
"signature": {
"key_id": "95f5a194-b0a4-4351-a",
"checksum": "A216797C56944D91C47847A77C0367C594C0B948E7E75654B889571BD4F60A71"
}
}
Data element not found:
{
"additional_info": {
"description": "The data element could not be found in the policy in shared memory."
},
"cnt": 4000,
"correlationid": "sf-query-id:01978dbc-0582-d7e4-0000-002a3603a20d",
"logtype": "Protection",
"level": "ERROR",
"origin": {
"hostname": "localhost",
"time_utc": 1635363966
},
"protection": {
"dataelement": "deAddress",
"operation": "Protect",
"audit_code": 2,
"policy_user": "test_user"
},
"process": {
"id": "1",
"thread_id": "849348352"
},
"client": {},
"protector": {
"family": "IAP Lambda",
"lambda_version": "3.2.10",
"version": "3.2.0",
"vendor": "Cloud Protect",
"pcc_version": "3.3.0.5",
"core_version": "1.1.0"
},
"signature": {
"key_id": "95f5a194-b0a4-4351-a",
"checksum": "AF09217C56944D91C47847A77C0367C594C0B948E7E75654B889571BD4F60A71"
}
}
Example Audit Records
The following are sample audit messages:
Protect Success:
{
"additional_info": {
"description": "Data protect operation was successful.",
"query_id": "sf-query-id:01978dbc-0582-d7e4-0000-002a3603a20d",
"request_id": "8476a536-e9f4-11e8-9739-2dfe598c3fcd"
},
"cnt": 4000,
"correlationid": "sf-query-id:01978dbc-0582-d7e4-0000-002a3603a20d",
"logtype": "Protection",
"level": "SUCESS",
"origin": {
"hostname": "localhost",
"time_utc": 1635363966
},
"protection": {
"dataelement": "deAddress",
"operation": "Protect",
"audit_code": 6,
"datastore": "SAMPLE_POLICY",
"policy_user": "test_user"
},
"client": {},
"protector": {
"family": "cp",
"version": "3.1.0",
"vendor": "aws.snowflake",
"pcc_version": "3.4.0.14",
"core_version": "1.2.1+55.g590fe.HEAD"
},
"signature": {
"key_id": "95f5a194-b0a4-4351-a",
"checksum": "B324AF7C56944D91C47847A77C0367C594C0B948E7E75654B889571BD4F60A71"
}
}
Reprotect Success:
{
"additional_info": {
"description": "Data reprotect operation was successful.",
"query_id": "sf-query-id:01978dbc-0582-d7e4-0000-002a3603a20d",
"request_id": "8476a536-e9f4-11e8-9739-2dfe598c3fcd"
},
"cnt": 4000,
"correlationid": "sf-query-id:01978dbc-0582-d7e4-0000-002a3603a20d",
"logtype": "Protection",
"level": "SUCCESS",
"origin": {
"hostname": "localhost",
"time_utc": 1635363966
},
"protection": {
"old_dataelement": "deAddress1",
"dataelement": "deAddress2",
"operation": "Reprotect",
"audit_code": 50,
"datastore": "SAMPLE_POLICY",
"policy_user": "test_user"
},
"client": {},
"protector": {
"family": "cp",
"version": "3.1.0",
"vendor": "aws.snowflake",
"pcc_version": "3.4.0.14",
"core_version": "1.2.1+55.g590fe.HEAD"
},
"signature": {
"key_id": "95f5a194-b0a4-4351-a",
"checksum": "B324AF7C56944D91C47847A77C0367C594C0B948E7E75654B889571BD4F60A71"
}
}
User permission denied:
{
"additional_info": {
"description": "The user does not have the appropriate permissions to perform the requested operation.",
"query_id": "sf-query-id:01978dbc-0582-d7e4-0000-002a3603a20d",
"request_id": "8476a536-e9f4-11e8-9739-2dfe598c3fcd"
},
"cnt": 4000,
"correlationid": "sf-query-id:01978dbc-0582-d7e4-0000-002a3603a20d",
"logtype": "Protection",
"level": "ERROR",
"origin": {
"hostname": "localhost",
"time_utc": 1635363966
},
"protection": {
"dataelement": "deAddress",
"operation": "Protect",
"audit_code": 3,
"datastore": "SAMPLE_POLICY",
"policy_user": "test_user"
},
"client": {},
"protector": {
"family": "cp",
"version": "3.1.0",
"vendor": "aws.snowflake",
"pcc_version": "3.4.0.14",
"core_version": "1.2.1+55.g590fe.HEAD"
},
"signature": {
"key_id": "95f5a194-b0a4-4351-a",
"checksum": "A216797C56944D91C47847A77C0367C594C0B948E7E75654B889571BD4F60A71"
}
}
Data element not found:
{
"additional_info": {
"description": "The data element could not be found in the policy in shared memory.",
"query_id": "sf-query-id:01978dbc-0582-d7e4-0000-002a3603a20d",
"request_id": "8476a536-e9f4-11e8-9739-2dfe598c3fcd"
},
"cnt": 4000,
"correlationid": "sf-query-id:01978dbc-0582-d7e4-0000-002a3603a20d",
"logtype": "Protection",
"level": "ERROR",
"origin": {
"hostname": "localhost",
"time_utc": 1635363966
},
"protection": {
"dataelement": "deAddress",
"operation": "Protect",
"audit_code": 2,
"datastore": "SAMPLE_POLICY",
"policy_user": "test_user"
},
"client": {},
"protector": {
"family": "cp",
"version": "3.1.0",
"vendor": "aws.snowflake",
"pcc_version": "3.4.0.14",
"core_version": "1.2.1+55.g590fe.HEAD"
},
"signature": {
"key_id": "95f5a194-b0a4-4351-a",
"checksum": "AF09217C56944D91C47847A77C0367C594C0B948E7E75654B889571BD4F60A71"
}
}
7 - No Access Behavior
Unauthorized unprotect requests behaviour.
No Access Behavior
The security policy maintains a No Access Operation, configured in an ESA, which determines the response for unauthorized unprotect requests.

The following table describes the result returned in the response for the various no access unprotect permissions.
| No Access Operation | Data Returned |
|---|
| Null | null |
| Protected | (protected value) |
| Exception | Query will fail with an exception |
Note
An unauthorized protect will throw an exception.8 - Upgrading To The Latest Version
Instructions for upgrading the protector.
Important
- Upgrading the Policy Agent component to version 4 from any previous major version requires a new installation
- Upgrading the Protector component to version 4 from any previous major version requires a new installation
- Upgrading the Log Forwarder component to version 4 from any previous major version requires a new installation
9 - Known Limitations
Known product limitations.
Cloud Function (Gen2) labels must not be updated from the Cloud Run Services console. When updating labels for a GCP Cloud Function (Gen2) through the Cloud Run Services console, GCP creates a new Cloud Run revision with the updated labels, but the underlying Cloud Function retains the old labels. Because the policy agent reads labels from the Cloud Function definition (not the Cloud Run revision), it will not detect the label change and will not trigger a policy update.

To avoid this issue, always update labels using one of the following methods:
- Cloud Run Functions console — Navigate to Cloud Run Functions, select the function, and update labels there. This ensures both the Cloud Function and its underlying Cloud Run revision are updated consistently.
- Terraform — Update the
labels variable in your Terraform configuration and run terraform apply. - gcloud CLI — Use
gcloud functions deploy with the updated --update-labels flag.
If labels were already updated incorrectly through the Cloud Run Services console, redeploy the function using one of the methods above to synchronize the labels and trigger a policy update.
10 - Appendices
Additional references for the protector.
10.1 - Integrating Cloud Protect with PPC (Protegrity Provisioned Cluster)
Concepts for integrating with PPC (Protegrity Provisioned Cluster)
This guide describes how to configure the Protegrity Policy Agent and Log Forwarder to connect to a Protegrity Provisioned Cluster (PPC), highlighting the differences from connecting to ESA.
Key Differences: PPC vs ESA
| Feature | ESA 10.2 | PPC (this guide) |
|---|
| Datastore Key Fingerprint | Optional/Recommended | Required |
| CA Certificate on Agent | Optional/Recommended | Optional/Recommended |
| CA Certificate on Log Forwarder | Optional/Recommended | Not supported |
| Client Certificate Authentication from Log Forwarder | Optional/Recommended | Not supported |
| IP Address | ESA IP address | PPC address |
Prerequisites
- Access to PPC and required credentials.
- Tools:
curl, kubectl installed.
Policy Agent Setup with PPC
Important
When connecting to PPC, the Policy Agent
requires use of a datastore key fingerprint. For connecting to ESA 10.2 with Cloud Protect Policy Agent, the fingerprint is optional but recommended. See
Policy Agent Installation for general setup steps.
Follow these instructions as a guide for understanding specific inputs for Policy Agent integrating with PPC:
Obtain the Datastore Key Fingerprint
To retrieve the fingerprint for your Policy Agent:
Retrieve public key from the Cloud Provider Key Management service for the policy encryption key created in pre-configuration:
- Navigate to the Key Management Service in AWS console and open Customer Managed Keys
- Select the desired key
- Select the Public Key tab
- Select Download
- Navigate to the Key Vault in Azure console and open Objects>Keys
- Select the desired key
- Select the key indicated as CURRENT VERSION
- Select Download public key
- Navigate to Key Management in GCP console
- Select the desired key and open the Versions tab
- Select Get public key from the Actions column menu
- Select Download
Escape the new line characters in the downloaded public key for use in the next step - for example:
awk 'NF {printf "%s\\n",$0}' "<public_key_file>" > "new-line-escaped-public-key.pem"
cat new-line-escaped-public-key.pem
Export key fingerprint using the PPC API as indicated in the curl example below:
curl -k -H "Authorization: Bearer ${TOKEN}" -X POST https://${HOST}/pty/v2/pim/datastores/1/export/keys -H "Content-Type: application/json" --data '{
"algorithm": "RSA-OAEP-256",
"description": "example-key-from-key-management",
"pem": "<value of new-line-escaped-public-key>"
}'
Sample Output:
{"uid":"1","algorithm":"RSA-OAEP-256","fingerprint":"4c:46:d8:05:35:2e:eb:39:4d:39:8e:6f:28:c3:ab:d3:bc:9e:7a:cb:95:cb:b1:8e:b5:90:21:0f:d3:2c:0b:27","description":"example-key-from-kms"}
Record the value for fingerprint and configure the Policy Agent:
Set the environment variable PTY_DATASTORE_KEY in the Policy Agent Lambda function to the fingerprint value.
Set the environment variable PTY_DATASTORE_KEY in the Policy Agent Function App to the fingerprint value.
Set the variable in Policy Agent main.tf pty_datastore_key to the fingerprint value and apply the changes.
Retrieve the PPC CA Certificate
To obtain the CA certificate from PPC:
kubectl -n api-gateway get secret ingress-certificate-secret -o jsonpath='{.data.ca\.crt}' | base64 -d > CA.pem
Use the ProtegrityCA.pem that was returned as described in Policy Agent Installation.
Configure the PPC Address
Use the PPC address in place of the ESA IP address wherever required in your configuration.
Log Forwarder Setup with PPC
Note
When using PPC, certificate authentication and CA validation are
not supported for the Log Forwarder. Configuration steps related to certificates in
Log Forwarder Installation do
not apply to PPC.
If you attempt to use certificates provided by PPC, the Log Forwarder will not function correctly.
- The Log Forwarder will proceed without certificates and will print a warning if
PTY_ESA_CA_SERVER_CERT is not provided. - No additional certificate or CA configuration is needed for PPC.
10.2 - Protection Methods
Cloud API supported protection methods
Protection Methods
For more information about the protection methods supported by Protegrity, refer to the Protection Methods Reference.
Tokenization Type | Supported Input Data Types | Notes |
|---|
Numeric Credit Card Alpha Upper-case Alpha Alpha-Numeric Upper Alpha-Numeric Lower ASCII Printable Decimal Unicode Unicode Base64 Unicode Gen2 Email | STRING NULL | |
Integer | NUMBER NULL | |
Date Datetime | STRING NULL | For information about supported formats, refer to the Protection Methods Reference. |
Binary | STRING NULL | Must be hex encoded unless a different encoding is specified. Another supported encoding is base64. |
Protection Method | Supported Input Data Types | Notes |
|---|
No Encryption | STRING NUMBER NULL | |
Encryption Algorithm | Supported Input Data Types | Notes |
|---|
3DES AES-128 AES-256 CUSP 3DES CUSP AES-128 CUSP AES-256 | STRING | Must be hex encoded unless a different encoding is specified. Another supported encoding is base64. |
10.3 - Configuring Regular Expression to Extract Policy Username
Example configurations for user extraction with regular expressions
Cloud Protect Cloud Function exposes USERNAME_REGEX configuration to allow extraction of policy username from user in the request.
USERNAME_REGEX Cloud Function Environment configuration
The USERNAME_REGEX environment variable can be set to contain regular expression with one capturing group. This group is used to extract the username. Examples below show different regular expression values and the resulting policy user.
10.4 - Associating ESA Data Store With Cloud Protect Agent
ESA controls policy access by mapping server IPs to data stores, registering a node when an agent requests a policy and its IP is identified.
Associating ESA Data Store With Cloud Protect Agent
ESA controls which policy is deployed to protector using concept of data store. A data store may contain a list of IP addresses identifying servers allowed to pull the policy associated with that specific data store. Data store may also be defined as default data store, which allows any server to pull the policy, provided it does not belong to any other data stores. Node registration occurs when the policy server (in this case the policy agent) makes a policy request to ESA, where the agent’s IP address is identified by ESA.
Note
For more information about ESA data store refer to Policy Management Guide which is part of Protegrity ESA documentation.Policy agent function source IP address used for node registration on ESA depends on ESA hubcontroller configuration ASSIGN_DATASTORE_USING_NODE_IP and the PTY_ADDIPADDRESSHEADER configuration exposed by the agent function.
The function service uses multiple network interfaces, internal network interface with ephemeral IP range of 169.254.x.x and external network interface with IP range described in Function app outbound IP addresses section under function configuration. By default, when agent function is contacting ESA to register node for policy download, ESA uses agent function outbound IP address. This default behavior is caused by the default ESA hubcontroller configuration ASSIGN_DATASTORE_USING_NODE_IP=false and agent default configuration PTY_ADDIPADDRESSHEADER=yes.
In some cases, when there is a proxy server between the ESA and agent function, the desirable ESA configuration is ASSIGN_DATASTORE_USING_NODE_IP=true. and PTY_ADDIPADDRESSHEADER=no which will cause the ESA to use proxy server IP address.
The table below shows how the hubcontroller and agent settings will affect node IP registration on ESA.
| Agent source IP | Agent Function Outbound IP | Proxy IP | ESA config - ASSIGN_DATASTORE_USING_NODE_IP | Agent function config - PTY_ADDIPADDRESSHEADER | Agent node registration IP |
|---|
| 169.254.144.81 | 20.75.43.207 | No Proxy | true | yes | 169.254.144.81 |
| true | no | 20.75.43.207 | | | |
| false | yes | | | | |
| false | no | | | | |
| 169.254.144.81 | 20.75.43.207 | 34.230.42.110 | true | yes | 169.254.144.81 |
| true | no | 34.230.42.110 | | | |
| false | yes | | | | |
| false | no | | | | |
10.5 - Undeliverable Audit Log Recovery
Cloudapi Audit log Recovery
Protegrity Cloud Protect Log Forwarder installation provides a solution to recover undelivered audit logs. Reasons for undeliverable logs may include:
- Changes to network configuration in ESA or cloud provider (VPC, firewall, certificate rotation, service user credentials)
- Log Forwarder IAM Service Account permissions
- Log Forwarder Cloud Run Function configuration
- Disruption in cloud provider service
Log Forwarder Dead Letter Pub/Sub Architecture
Log Forwarder is triggered by pub/sub events generated by Protect Functions. If Log Forwarder is unable to reach ESA to deliver the logs, they are pushed to a dead letter pub/sub topic. Dead letter pub/sub topic is created when installing the Log Forwarder with the service installation script. See Install Log Forwarder Function via Terraform Scripts for dead letter topic configuration options and naming conventions.

Monitoring Undelivered Logs
Logs pushed to the dead letter pub/sub topic will be purged and no longer recoverable when specified dlq_topic_message_retention_duration has been reached. Monitoring the dead letter topic is recommended to ensure timely recovery of audit messages before they are permanently lost. Consult the GCP monitoring alerts documentation for setting up alerts based on pub/sub topic metrics.
Recovering Logs in Dead Letter Topic (Recommended)
Protegrity recommends creation of an additional Log Forwarder installation in the case where logs are not delivered to ESA, as described in Log Forwarder Dead Letter Pub/Sub Architecture.

Steps to recover audit logs using new Log Forwarder installation:
Create a second Log Forwarder installation (Log Forwarder 2 in the above diagram) for processing undelivered logs. Value for audit_log_dead_letter_topic in the terraform script should be set to null during installation.
Configure and test newly installed Log Forwarder to verify ESA connectivity. See Install Log Forwarder Function via Terraform Scripts for installation instructions.
Identify the dead letter pub/sub topic (DLQ 1 in the above diagram) resource name by running command
for the Log Forwarder which failed to deliver logs (Log Forwarder as described in Log Forwarder Dead Letter Pub/Sub Architecture). Note the value for audit_log_dlq_topic.
Set audit_log_dead_letter_topic in the new Log Forwarder (Log Forwarder 2 in the above diagram) terraform installation script to the value of audit_log_dlq_topic identified in previous step. Apply the changes with terraform apply.
Monitor the new Log Forwarder function logs for any failures.
Note
Any additional failed logs will be pushed to the dead letter pub/sub topic (DLQ 2 in the above diagram) of the new Log Forwarder.Recovering Logs in Dead Letter Topic (Alternative)
When the recommended method of for recovery described in Recovering Logs in Dead Letter Topic (Recommended) is not an option, you may use the existing Log Forwarder to reprocess undelivered logs.

Warning
This approach is only recommended for implementors with advanced knowledge of the involved GCP services and can result in permanent loss/duplication of audit logs and additional cost. If unsure, install an additional log forwarder to reprocess logs or reach out to Protegrity for guidance.Steps to recover audit logs using existing Log Forwarder installation:
Fix any configuration errors causing the Log Forwarder to fail. Verify audit logs are being transmitted successfully to ESA.
Identify the dead letter pub/sub topic (DLQ 1 in the above diagram) resource name by running command
for the Log Forwarder. Note the value for audit_log_dlq_topic.
Set audit_log_dead_letter_topic in the terraform installation script to the value of audit_log_dlq_topic identified in previous step. Apply the changes with
When audit logs have been transmitted to ESA, revert setting audit_log_dead_letter_topic to null Apply the changes with