Agentic Data Plane

Connect to a Private Environment from Your Computer

To use a private Agentic Data Plane environment from your computer, connect the computer, or the office network it’s on, to the environment’s virtual private cloud (VPC) through a VPN. Then ai.redpanda.com, rpk ai, and your local tools can reach the environment’s AI Gateway and API.

Workloads such as self-managed agents and test harnesses don’t need anything on this page. Run them in a VPC that you peer with the environment, and they reach it over the peering. See Run agents and harnesses in your VPC.

After reading this page, you will be able to:

  • Choose a connection method that can reach a private environment from your computer

  • Connect your computer or office network to the environment’s VPC through a VPN

  • Verify the connection and run rpk ai commands against a private environment

Prerequisites

  • An environment with Private access that shows Ready.

  • Permission to create resources in the AWS account or Google Cloud project where you deployed the environment. The VPN endpoint or gateway goes in the environment’s VPC.

  • rpk ai installed on your computer. See Use the Agentic Data Plane CLI.

  • The environment’s network ID, region, CIDR block, and AI Gateway URL, from its detail page in the Redpanda Cloud UI. The commands on this page use the placeholders <network-id>, <region>, <environment-cidr>, <ai-gateway-url>, and, on Google Cloud, <environment-project-id> for them, as described in Find the environment’s network details.

How the connection works

Diagram: your computer, with the AWS VPN Client, and your office network, with a VPN device, tunnel to a VPN gateway on the edge of the environment’s VPC, which forwards HTTPS to the internal load balancer for the AI Gateway and API. Sign-in goes to Redpanda Cloud over the internet.
Figure 1. Your computer or office network reaches the environment through a VPN gateway attached to the environment’s VPC

Signing in to ai.redpanda.com or rpk ai, and choosing an environment, go through Redpanda Cloud on the public internet. Everything that reads or changes the environment goes to its AI Gateway and API endpoints, which are reachable only from the environment’s private network.

A VPN into the environment’s VPC gives your computer that reach. A VPN works if it meets these requirements:

  • It ends in the environment’s VPC. On AWS, that’s the VPC with the Name tag network-<network-id>. On Google Cloud, it’s the network redpanda-<network-id>.

  • On Google Cloud, the VPN gateway and tunnel run in the environment’s region.

  • It routes the environment’s CIDR block, or at least the address that the environment’s hostnames resolve to.

  • It leaves DNS and TLS alone. The environment’s hostnames are in public DNS and resolve to private addresses, so your computer needs no DNS changes. Requests must reach the environment with TLS intact, so that the environment’s certificate verifies.

On AWS, the endpoints accept connections only from private address ranges. AWS Client VPN replaces your computer’s address with an address in the environment’s VPC, so it meets this requirement.

Resources you add to the environment’s VPC

Redpanda creates and manages the environment’s VPC, but not the VPN endpoints, gateways, security groups, and routes that you add to it.

  • Add your own resources, such as a VPN endpoint, a VPN gateway, or the static route that Classic VPN needs. Don’t change the environment’s existing subnets, route tables, routes, security groups, or firewall rules.

  • Delete the resources you added before you delete the environment. AWS and Google Cloud don’t delete a VPC while resources that you added remain in it, so deleting the environment can’t remove its VPC until they’re gone.

  • On AWS, associate the VPN endpoint with one of the environment’s private subnets that carry the tag kubernetes.io/role/internal-elb=1. Don’t use the private subnet tagged kubernetes.io/role/cni=1, which holds the Kubernetes cluster’s pod addresses.

    To list those private subnets:

    ENV_VPC_ID=$(aws ec2 describe-vpcs --region <region> \
      --filters "Name=tag:Name,Values=network-<network-id>" \
      --query 'Vpcs[0].VpcId' --output text)
    aws ec2 describe-subnets --region <region> \
      --filters "Name=vpc-id,Values=$ENV_VPC_ID" \
        "Name=tag:redpanda.subnet.private,Values=1" \
        "Name=tag:kubernetes.io/role/internal-elb,Values=1" \
      --query 'Subnets[].[SubnetId,AvailabilityZone,CidrBlock]' --output text

Choose a connection method

Method Fits when What you add to the environment’s VPC

AWS Client VPN

Your environment runs on AWS and you want a managed VPN for a team.

An AWS Client VPN endpoint

Google Cloud Classic VPN

Your environment runs on Google Cloud and people connect from an office or corporate network.

A Classic VPN gateway with its IP address, a tunnel, and a static route

If your organization’s VPN already reaches the environment’s VPC and meets the requirements above, use it. Then continue with Verify the connection and use rpk ai.

Connect with AWS Client VPN

An AWS Client VPN endpoint in the environment’s VPC accepts connections from the AWS VPN Client on your computer. With split tunnel turned on, only traffic for the endpoint’s routes goes through the VPN, so signing in to Redpanda Cloud stays on your normal connection.

This configuration refers to a third-party product. Specific UI elements may not be up to date. For current syntax, see the vendor documentation for AWS Client VPN.

Before you create the endpoint:

  • Create a server certificate and a client certificate, and import the server certificate into AWS Certificate Manager. Import the client certificate too if a different certificate authority issued it. For the steps, see Mutual authentication in the AWS Client VPN documentation.

  • Find the environment’s VPC ID and its private subnets with the commands in Resources you add to the environment’s VPC. They set ENV_VPC_ID, which the next steps use. Choose one of the listed subnets, and use its ID as <subnet-id> in the next steps.

Create the endpoint with the AWS CLI or with Terraform:

  • AWS CLI

  • Terraform

  1. Create a security group for the endpoint in the environment’s VPC. It needs no inbound rules.

    aws ec2 create-security-group --region <region> \
      --vpc-id "$ENV_VPC_ID" \
      --group-name client-vpn \
      --description "AWS Client VPN endpoint" \
      --query GroupId --output text

    The command prints the security group ID. You use it as <security-group-id> in the next step.

  2. Create the AWS Client VPN endpoint in the environment’s VPC:

    aws ec2 create-client-vpn-endpoint --region <region> \
      --client-cidr-block <vpn-client-cidr> \
      --server-certificate-arn <server-certificate-arn> \
      --authentication-options Type=certificate-authentication,MutualAuthentication={ClientRootCertificateChainArn=<client-root-certificate-arn>} \
      --connection-log-options Enabled=false \
      --split-tunnel \
      --vpc-id "$ENV_VPC_ID" \
      --security-group-ids <security-group-id>

    The command prints the endpoint ID, which has a cvpn-endpoint- prefix. You use it as <endpoint-id> in the next steps.

    Replace these placeholders:

    • <vpn-client-cidr>: An address range for VPN clients, from /12 to /22, that doesn’t overlap the environment’s CIDR block, such as 172.20.0.0/22.

    • <server-certificate-arn> and <client-root-certificate-arn>: The Amazon Resource Names (ARNs) of the server certificate and of the certificate authority that issued the client certificate, in AWS Certificate Manager. If one certificate authority issued both certificates, use the server certificate’s ARN for both.

  3. Associate the endpoint with the private subnet you chose, and authorize VPN clients to reach the environment:

    aws ec2 associate-client-vpn-target-network --region <region> \
      --client-vpn-endpoint-id <endpoint-id> \
      --subnet-id <subnet-id>
    aws ec2 authorize-client-vpn-ingress --region <region> \
      --client-vpn-endpoint-id <endpoint-id> \
      --target-network-cidr <environment-cidr> \
      --authorize-all-groups

    The endpoint adds a route for the associated VPC’s CIDR block automatically, which is the environment’s CIDR block, so you don’t add a route yourself.

Declare the same resources in Terraform. The example looks up the environment’s VPC by its tag, and var.subnet_id is one of the environment’s private subnets tagged kubernetes.io/role/internal-elb=1. Configure the AWS provider for the environment’s region separately.

variable "network_id" {
  description = "The environment's Redpanda network ID."
  type        = string
}

variable "environment_cidr" {
  description = "The environment's CIDR block."
  type        = string
}

variable "subnet_id" {
  description = "One of the environment's private subnets tagged kubernetes.io/role/internal-elb=1."
  type        = string
}

variable "vpn_client_cidr" {
  description = "An address range for VPN clients, /12 to /22, that doesn't overlap the environment's CIDR block."
  type        = string
}

variable "server_certificate_arn" {
  description = "The ARN of the server certificate in AWS Certificate Manager."
  type        = string
}

variable "client_root_certificate_arn" {
  description = "The ARN of the certificate authority that issued the client certificate, in AWS Certificate Manager."
  type        = string
}

data "aws_vpc" "environment" {
  tags = { Name = "network-${var.network_id}" }
}

resource "aws_security_group" "client_vpn" {
  name   = "client-vpn"
  vpc_id = data.aws_vpc.environment.id
  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

resource "aws_ec2_client_vpn_endpoint" "environment" {
  server_certificate_arn = var.server_certificate_arn
  client_cidr_block      = var.vpn_client_cidr
  split_tunnel           = true
  vpc_id                 = data.aws_vpc.environment.id
  security_group_ids     = [aws_security_group.client_vpn.id]

  authentication_options {
    type                       = "certificate-authentication"
    root_certificate_chain_arn = var.client_root_certificate_arn
  }

  connection_log_options {
    enabled = false
  }
}

resource "aws_ec2_client_vpn_network_association" "environment" {
  client_vpn_endpoint_id = aws_ec2_client_vpn_endpoint.environment.id
  subnet_id              = var.subnet_id
}

resource "aws_ec2_client_vpn_authorization_rule" "environment" {
  client_vpn_endpoint_id = aws_ec2_client_vpn_endpoint.environment.id
  target_network_cidr    = var.environment_cidr
  authorize_all_groups   = true
}

output "endpoint_id" {
  value = aws_ec2_client_vpn_endpoint.environment.id
}

For resource arguments, see aws_ec2_client_vpn_endpoint in the Terraform AWS provider documentation.

Run terraform apply. The endpoint_id output is the endpoint ID, which you use as <endpoint-id> in the next steps. Before you delete the environment, run terraform destroy for this configuration.

Then connect your computer:

  1. Download the client configuration, and add the client certificate and its private key to it:

    aws ec2 export-client-vpn-client-configuration --region <region> \
      --client-vpn-endpoint-id <endpoint-id> --output text > client-vpn.ovpn
    {
      echo "<cert>"; cat <client-certificate-file>; echo "</cert>"
      echo "<key>"; cat <client-key-file>; echo "</key>"
    } >> client-vpn.ovpn

    Replace <client-certificate-file> and <client-key-file> with the files of the client certificate and its private key that you created earlier. The <cert> and <key> tags are literal. Keep client-vpn.ovpn private, because it contains the client’s private key.

  2. In the AWS VPN Client on your computer, add a profile from client-vpn.ovpn, then connect.

Connect from your network with Google Cloud Classic VPN

If people connect from an office or corporate network, connect that network’s VPN device to the environment’s VPC with a Google Cloud Classic VPN gateway. Computers on the network can then reach a Google Cloud environment.

Classic VPN uses static routes, so you add a route on each side: one in the environment’s network for your network’s address range, and one on your VPN device for the environment’s CIDR block.

This configuration refers to a third-party product. Specific UI elements may not be up to date. For current syntax, see the vendor documentation for Classic VPN with static routing.

Create the gateway with the gcloud CLI or with Terraform. Use credentials for the project you deployed the environment into, and create every resource in the environment’s region.

  • gcloud CLI

  • Terraform

  1. Reserve a static external IP address for the gateway, and note the address. Replace <gateway-name> with a name for the gateway.

    gcloud compute addresses create <gateway-name> \
      --project=<environment-project-id> --region=<region>
    gcloud compute addresses describe <gateway-name> \
      --project=<environment-project-id> --region=<region> \
      --format='value(address)'

    The second command prints the address. You use it as <gateway-ip> in the next steps.

  2. Create the Classic VPN gateway in the environment’s network, and forward IPsec traffic to it:

    gcloud compute target-vpn-gateways create <gateway-name> \
      --project=<environment-project-id> --region=<region> \
      --network=redpanda-<network-id>
    gcloud compute forwarding-rules create <gateway-name>-esp \
      --project=<environment-project-id> --region=<region> \
      --address=<gateway-ip> --ip-protocol=ESP \
      --target-vpn-gateway=<gateway-name>
    gcloud compute forwarding-rules create <gateway-name>-udp500 \
      --project=<environment-project-id> --region=<region> \
      --address=<gateway-ip> --ip-protocol=UDP --ports=500 \
      --target-vpn-gateway=<gateway-name>
    gcloud compute forwarding-rules create <gateway-name>-udp4500 \
      --project=<environment-project-id> --region=<region> \
      --address=<gateway-ip> --ip-protocol=UDP --ports=4500 \
      --target-vpn-gateway=<gateway-name>
  3. Create a tunnel to your VPN device:

    gcloud compute vpn-tunnels create <tunnel-name> \
      --project=<environment-project-id> --region=<region> \
      --target-vpn-gateway=<gateway-name> \
      --peer-address=<office-vpn-ip> \
      --shared-secret=<shared-secret> \
      --ike-version=2 \
      --local-traffic-selector=0.0.0.0/0 \
      --remote-traffic-selector=0.0.0.0/0

    Replace <tunnel-name> with a name for the tunnel, <office-vpn-ip> with your VPN device’s public IP address, and <shared-secret> with a strong pre-shared key that you also configure on the device.

  4. Route your network’s address range through the tunnel, in the environment’s network:

    gcloud compute routes create <route-name> \
      --project=<environment-project-id> \
      --network=redpanda-<network-id> \
      --destination-range=<office-cidr> \
      --next-hop-vpn-tunnel=<tunnel-name> \
      --next-hop-vpn-tunnel-region=<region>

    Replace <route-name> with a name for the route, and <office-cidr> with your network’s address range. Classic VPN keeps your network’s own addresses, so the environment needs this route to reply. Without it, the tunnel comes up but requests time out.

Declare the same resources in Terraform. The example creates the gateway with its static IP address and forwarding rules, the tunnel, and the static route for your network’s address range in the environment’s network. It outputs the gateway’s IP address for your VPN device.

The example names every resource office-vpn, so rename them if that name is taken. Configure the Google Cloud provider and its credentials separately. Pass the shared secret in the TF_VAR_shared_secret environment variable rather than a file, and protect your Terraform state, which stores it.

variable "network_id" {
  description = "The environment's Redpanda network ID."
  type        = string
}

variable "environment_project_id" {
  description = "The project you deployed the environment into."
  type        = string
}

variable "region" {
  description = "The environment's region."
  type        = string
}

variable "office_vpn_ip" {
  description = "Your VPN device's public IP address."
  type        = string
}

variable "office_cidr" {
  description = "Your network's address range."
  type        = string
}

variable "shared_secret" {
  description = "The pre-shared key, also configured on your VPN device."
  type        = string
  sensitive   = true
}

data "google_compute_network" "environment" {
  name    = "redpanda-${var.network_id}"
  project = var.environment_project_id
}

resource "google_compute_address" "vpn" {
  name    = "office-vpn"
  project = var.environment_project_id
  region  = var.region
}

resource "google_compute_vpn_gateway" "office" {
  name    = "office-vpn"
  project = var.environment_project_id
  region  = var.region
  network = data.google_compute_network.environment.self_link
}

locals {
  ipsec = {
    esp     = { protocol = "ESP", port = null }
    udp500  = { protocol = "UDP", port = "500" }
    udp4500 = { protocol = "UDP", port = "4500" }
  }
}

resource "google_compute_forwarding_rule" "vpn" {
  for_each    = local.ipsec
  name        = "office-vpn-${each.key}"
  project     = var.environment_project_id
  region      = var.region
  ip_protocol = each.value.protocol
  port_range  = each.value.port
  ip_address  = google_compute_address.vpn.address
  target      = google_compute_vpn_gateway.office.id
}

resource "google_compute_vpn_tunnel" "office" {
  name                    = "office-vpn"
  project                 = var.environment_project_id
  region                  = var.region
  target_vpn_gateway      = google_compute_vpn_gateway.office.id
  peer_ip                 = var.office_vpn_ip
  shared_secret           = var.shared_secret
  ike_version             = 2
  local_traffic_selector  = ["0.0.0.0/0"]
  remote_traffic_selector = ["0.0.0.0/0"]
  depends_on              = [google_compute_forwarding_rule.vpn]
}

# The environment's route back to your network, through the tunnel.
resource "google_compute_route" "office" {
  name                = "office-vpn"
  project             = var.environment_project_id
  network             = data.google_compute_network.environment.self_link
  dest_range          = var.office_cidr
  next_hop_vpn_tunnel = google_compute_vpn_tunnel.office.id
}

output "gateway_ip" {
  value = google_compute_address.vpn.address
}

For resource arguments, see google_compute_address, google_compute_vpn_gateway, google_compute_forwarding_rule, google_compute_vpn_tunnel, and google_compute_route in the Terraform Google Cloud provider documentation.

Run terraform apply. Before you delete the environment, run terraform destroy for this configuration.

Then finish the connection:

  1. On your VPN device, configure the tunnel to the gateway’s IP address, <gateway-ip> or the gateway_ip Terraform output, with Internet Key Exchange version 2 (IKEv2) and the same shared secret, and route the environment’s CIDR block through it.

  2. Confirm that the tunnel shows ESTABLISHED:

    gcloud compute vpn-tunnels describe <tunnel-name> \
      --project=<environment-project-id> --region=<region> \
      --format='value(status,detailedStatus)'

    Until your device connects, the tunnel shows FIRST_HANDSHAKE. If you used the Terraform example, the tunnel name is office-vpn.

Verify the connection and use rpk ai

  1. Confirm that your computer reaches the environment:

    curl -sS --connect-timeout 5 -o /dev/null -w '%{http_code}\n' <ai-gateway-url>

    Any HTTP status code means the connection works. A timeout means requests don’t reach the environment. See Troubleshooting.

  2. Sign in and select the environment. Replace <environment> with the environment’s name or ID.

    rpk ai auth login
    rpk ai env use <environment>

    When you select a private environment, rpk ai prints a warning that the environment is private and that its endpoints resolve only on its private network. That’s expected. Your connection now provides that network.

  3. Run a command that reaches the AI Gateway and one that reaches the API:

    rpk ai llm-provider list
    rpk ai agent list

    LLM provider and MCP server commands call the environment’s AI Gateway. Agent, secret, and policy commands call its API. Both endpoints use the same private network path, so both commands work once the connection is in place.

  4. To see where each request goes, add --rpai-verbose. Each request prints a line with its method, URL, and result, for example:

    rpai: POST https://adp-api.<cluster-id>.clusters.rdpa.co/redpanda.api.adp.v1alpha1.AgentRegistryService/ListAgents -> 200 OK (760ms)

If ai.redpanda.com showed the page that asks you to connect to your private environment, click Reload page now that your computer is connected.

Troubleshooting

Symptom Action

An rpk ai command fails after about 30 seconds with deadline_exceeded and context deadline exceeded (Client.Timeout exceeded while awaiting headers).

Your computer doesn’t reach the environment. Confirm that the VPN is connected, then run the curl check in Verify the connection and use rpk ai. If curl also times out, check the requirements in How the connection works.

rpk ai env use or rpk ai auth login warns that the environment is private.

This is expected for a private environment. The warning doesn’t mean that the connection failed.

With AWS Client VPN, the VPN connects, but requests to the environment time out.

Check that the endpoint is associated with one of the environment’s private subnets tagged kubernetes.io/role/internal-elb=1 and has an authorization rule for the environment’s CIDR block.

From your office network, requests to a Google Cloud environment time out.

Check each of these:

  • The tunnel shows ESTABLISHED, and the gateway and tunnel are in the environment’s network and region.

  • The environment’s network has a static route for your network’s address range through the tunnel.

  • Your VPN device routes the environment’s CIDR block through the tunnel.

Deleting the environment doesn’t finish, or reports that its VPC is still in use.

Delete the VPN endpoints, gateways, security groups, and routes that you added to the environment’s VPC. See Resources you add to the environment’s VPC.

The environment’s hostname doesn’t resolve, or doesn’t resolve to a private address.

Some DNS resolvers and filters drop public answers that contain private addresses. Ask your network team to allow the environment’s hostnames, or test from a network that uses a different resolver.