Deploying a connector with Terraform
Deploy your custom application connector to AWS Lambda or Google Cloud Run, grant P0 permission to invoke it, and register it with P0, all from Terraform.
This guide deploys a connector you have built with @p0security/connector-sdk (from the connector repository) and registers it as a Custom application, using the P0 Terraform provider alongside the AWS or Google Cloud provider.
Three things have to be true before a requestor can ask for access through your connector:
The connector is deployed and running in your account.
P0 is allowed to invoke it, and nothing else is.
P0 has the connector's address, which the
p0_appresource gives it.
Terraform does all three. The last one verifies the first two. Applying p0_app makes P0 call your connector, and the apply fails if the call does not succeed.
To deploy the SDK's example with a cloud CLI instead of Terraform, see Deploying a connector to AWS Lambda or Deploying a connector to Google Cloud Run.
Prerequisites
A connector built with
@p0security/connector-sdk. Start from theaws-lambdaorgcp-cloudrunexample in the connector repository and replace its placeholder actions with calls into your own application's API.Terraform installed, with the P0 provider configured. See Get started with the P0 Terraform provider.
For AWS Lambda hosting, an installed P0 AWS integration for the account the connector runs in, and permission to create Lambda functions and IAM roles there.
For Google Cloud Run hosting, an installed P0 Google Cloud integration, and permission to deploy Cloud Run services in the project.
A registry your cloud can pull from, if you deploy a container image.
Build the connector
Terraform deploys an artifact. It does not build one, so produce that first.
For Cloud Run, build and push a container image. The SDK example ships a Dockerfile:
Pass --platform linux/amd64 when you build on Apple silicon. Cloud Run runs linux/amd64, and an arm64 image fails to start with an exec format error.
For Lambda, bundle your connector into a zip archive whose entrypoint exports the handler returned by newCustomAppLambdaHandler. The aws-lambda example already wires this up in src/index.ts; build and package it with its own script:
This compiles src/ to dist/ and writes connector-lambda.zip, with dist/, a production-only node_modules, and package.json at the zip root. Because dist/ stays nested rather than flattened, the Lambda handler is dist/index.handler, not index.handler.
AWS Lambda
P0 assumes the role created by your AWS integration and invokes the connector's function. That role needs lambda:InvokeFunction on the function and no other permission on it.
Step 1: Deploy the connector
The connector runs under its own execution role. Grant that role whatever access your application requires, plus CloudWatch Logs.
Step 2: Let P0 invoke the connector
Attach the invoke policy to the role P0 assumes in this account. If you installed the AWS integration with Terraform, that role is the one your p0_aws_iam_write_staged resource named, as below. If you installed it from the P0 app, use P0RoleIamManager instead.
Step 3: Register the connector with P0
P0 derives the function's ARN from the account, region, and name you give it, so there is no ARN to paste.
Google Cloud Run
Two settings decide who may call a Cloud Run connector, and both take the same service account, the one from your P0 Google Cloud installation:
roles/run.invoker
Who may reach the service at all
INVOKER_SA_EMAIL
The identity the connector accepts on each request
The connector refuses to start when INVOKER_SA_EMAIL is unset, rather than failing request by request in a way that is hard to diagnose from outside.
Step 1: Deploy the connector
p0_gcp.example below is your existing Google Cloud installation. Its service_account_email is the identity P0 calls from, and it appears in both of the settings above.
The service relies on IAM to gate it rather than on ingress restrictions. P0 calls the connector with a signed identity token, and unauthenticated callers are turned away.
Grant google_service_account.connector whatever access your application requires.
Step 2: Let P0 invoke the connector
Step 3: Register the connector with P0
P0 looks up the service's invocation URL from the project, region, and service name, and reports it back on hosting.connector_service_uri. You do not paste the Cloud Run URL in.
Inputs
id
A unique identifier for the application. Any string, such as internal-admin-tool.
hosting.type
aws for Lambda, or gcp for Cloud Run
hosting.account_id
The AWS account the function is deployed in. AWS hosting only.
hosting.project_id
The Google Cloud project the service is deployed in. Cloud Run hosting only.
hosting.connector_name
The Lambda function name or Cloud Run service name
hosting.connector_region
The region the connector is deployed in
Outputs
hosting.connector_service_uri
The connector's invocation URL, resolved by P0. Cloud Run hosting only.
label
The label for this installation, defaulting to the application identifier
state
The install progress: stage, configure, or installed
After the apply
Apply, then check the install in the P0 app under Integrations > Custom application.
A failed apply on p0_app means P0 could not call the connector. The error names what failed, and the usual causes are a connector still deploying, a missing invoke grant, or, on Cloud Run, an INVOKER_SA_EMAIL that does not match the service account P0 uses. Fix the cause and apply again.
Then request access to one of your policies as a test user, let the grant expire or revoke it by hand, and confirm your application provisioned and deprovisioned the user as you expect.
Related links
Custom application integration, for what a connector does and how P0 reaches it
Deploying a connector to AWS Lambda, the same install with the AWS CLI
Deploying a connector to Google Cloud Run, the same install with the
gcloudCLIp0_appin the Terraform registry
Last updated