OpenClaw Enterprise Security: Private Bedrock Access with VPC PrivateLink | OpenClaw DC
Your OpenClaw instance talks to Bedrock over the public internet by default. For enterprise deployments with sensitive leadership data, that is not acceptable. Here is how to lock it down with VPC PrivateLink.
The problem: default OpenClaw talks to Bedrock over the internet
When you deploy OpenClaw on a LightSail instance and configure it to use Amazon Bedrock, every API call follows the same path: your instance resolves the public Bedrock endpoint (bedrock-runtime.us-east-1.amazonaws.com), sends an HTTPS request over the public internet, and receives the response the same way.
The traffic is encrypted with TLS. That is not the issue.
The issues are:
- Network path exposure. Your traffic traverses ISP backbone networks, internet exchange points, and potentially multiple autonomous systems before reaching the AWS Bedrock endpoint. Each hop is a potential inspection point.
- IP visibility. Your LightSail instance’s public IP is visible in connection logs along the path. An attacker who knows your IP knows where your AI workloads run.
- API key surface area. If TLS termination is ever compromised (misconfigured proxy, corporate MITM inspection appliance, or a CA breach), your Bedrock API credentials are exposed in transit.
- Compliance failure. Most enterprise security policies for sensitive data require network-level isolation. “It uses TLS” does not satisfy a SOC 2 auditor asking about network segmentation.
For a personal OpenClaw instance running your grocery list, none of this matters. For a leadership team running sensitive strategic analysis, competitive intelligence, or M&A due diligence through OpenClaw, it is a hard blocker.
Architecture overview
The goal is to keep all OpenClaw-to-Bedrock traffic on the AWS backbone network. No public internet involved.
+---------------------+ VPC Peering +----------------------+
| LightSail VPC | <--------------------> | Standard VPC |
| (AWS-managed) | | (you control) |
| | | |
| +---------------+ | | +----------------+ |
| | LightSail | | | | VPC Endpoint | |
| | Instance | | private traffic | | (Interface) | |
| | (OpenClaw) | | -----------------------> | | bedrock-runtime| |
| | 10.0.0.x | | stays on AWS backbone | | 10.1.0.x | |
| +---------------+ | | +-------+--------+ |
| | | | |
+---------------------+ +----------|----------+
|
AWS Internal Network
|
+---------|--------+
| Amazon Bedrock |
| (bedrock-runtime)|
+------------------+
What each component does:
- LightSail VPC — AWS manages this VPC for your LightSail instances. You cannot modify its route tables directly, but you can peer it with a standard VPC.
- VPC Peering — A networking connection between two VPCs that routes traffic using private IP addresses. No gateway, no VPN, no single point of failure.
- Standard VPC — A VPC you create and fully control. This is where the Bedrock VPC endpoint lives.
- VPC Endpoint (Interface type) — An elastic network interface with a private IP address that serves as an entry point for Bedrock API traffic. Powered by AWS PrivateLink.
- Amazon Bedrock — Receives your API calls through the AWS internal network instead of the public internet.
The result: OpenClaw sends a request to a private IP in your VPC. That request never leaves the AWS network. Bedrock responds the same way.
Step 1: Create a standard VPC with Bedrock endpoint
If you already have a VPC in the same region as your LightSail instance, you can reuse it. Otherwise, create one.
Create the VPC
aws ec2 create-vpc \
--cidr-block 10.1.0.0/16 \
--tag-specifications 'ResourceType=vpc,Tags=[{Key=Name,Value=openclaw-private}]'
Save the VPC ID from the output. You will need it for every subsequent step.
export VPC_ID=vpc-0abc123def456 # replace with your VPC ID
Create a private subnet
aws ec2 create-subnet \
--vpc-id $VPC_ID \
--cidr-block 10.1.1.0/24 \
--availability-zone us-east-1a \
--tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=openclaw-private-subnet}]'
export SUBNET_ID=subnet-0abc123def456 # replace with your subnet ID
Create a security group for the endpoint
This security group controls who can reach the Bedrock VPC endpoint. Lock it to your LightSail CIDR only.
aws ec2 create-security-group \
--group-name bedrock-endpoint-sg \
--description "Allow HTTPS from LightSail CIDR to Bedrock endpoint" \
--vpc-id $VPC_ID
export SG_ID=sg-0abc123def456 # replace with your security group ID
Add an inbound rule allowing HTTPS from the LightSail VPC CIDR. LightSail instances typically use the 172.26.0.0/16 range, but verify yours:
# Check your LightSail instance's private IP to confirm the CIDR
aws lightsail get-instance --instance-name your-openclaw-instance \
--query 'instance.privateIpAddress'
# Add the inbound rule
aws ec2 authorize-security-group-ingress \
--group-id $SG_ID \
--protocol tcp \
--port 443 \
--cidr 172.26.0.0/16
Create the VPC endpoint for Bedrock
aws ec2 create-vpc-endpoint \
--vpc-id $VPC_ID \
--vpc-endpoint-type Interface \
--service-name com.amazonaws.us-east-1.bedrock-runtime \
--subnet-ids $SUBNET_ID \
--security-group-ids $SG_ID \
--private-dns-enabled
Replace us-east-1 with your region if different.
The --private-dns-enabled flag is critical. It overrides the public DNS for bedrock-runtime.us-east-1.amazonaws.com within the VPC to resolve to the endpoint’s private IP. Any application inside this VPC (or peered to it) that calls Bedrock will automatically use the private path.
Step 2: Peer LightSail VPC with standard VPC
LightSail has a built-in VPC peering feature. It peers your LightSail VPC with your default VPC in the same region. If your Bedrock endpoint is in the default VPC, enable peering through the LightSail console and you are done.
If your Bedrock endpoint is in a non-default VPC (as in this guide), you need an additional step.
Enable LightSail VPC peering
aws lightsail peer-vpc
This peers LightSail with your default VPC. Verify:
aws lightsail get-vpc-peering-connections
Route from default VPC to your private VPC
Since LightSail peers with the default VPC, you need connectivity from the default VPC to the VPC containing the Bedrock endpoint. Two options:
Option A: Put the Bedrock endpoint in your default VPC. Simplest approach. Skip the custom VPC creation above and create the endpoint directly in your default VPC.
Option B: Transit Gateway or additional VPC peering. Create a peering connection between the default VPC and your private VPC. This adds a hop but keeps your Bedrock endpoint in an isolated VPC.
For most OpenClaw deployments, Option A is the correct choice. The security boundary is the endpoint’s security group, not the VPC itself.
If using Option A, create the Bedrock endpoint in your default VPC instead:
# Get your default VPC ID
export DEFAULT_VPC_ID=$(aws ec2 describe-vpcs \
--filters "Name=isDefault,Values=true" \
--query 'Vpcs[0].VpcId' --output text)
# Get a subnet in the default VPC
export DEFAULT_SUBNET_ID=$(aws ec2 describe-subnets \
--filters "Name=vpc-id,Values=$DEFAULT_VPC_ID" \
--query 'Subnets[0].SubnetId' --output text)
# Create security group in default VPC
aws ec2 create-security-group \
--group-name bedrock-endpoint-sg \
--description "Allow HTTPS from LightSail CIDR to Bedrock endpoint" \
--vpc-id $DEFAULT_VPC_ID
# Create the endpoint in the default VPC
aws ec2 create-vpc-endpoint \
--vpc-id $DEFAULT_VPC_ID \
--vpc-endpoint-type Interface \
--service-name com.amazonaws.us-east-1.bedrock-runtime \
--subnet-ids $DEFAULT_SUBNET_ID \
--security-group-ids $SG_ID \
--private-dns-enabled
Configure DNS resolution
For the private DNS override to work across the peering connection, enable DNS resolution on the peering connection:
# Get the peering connection ID
aws lightsail get-vpc-peering-connections \
--query 'vpcPeeringConnections[0].vpcPeeringConnectionId'
Verify that your LightSail instance can resolve the Bedrock endpoint to a private IP:
# SSH into your LightSail instance
ssh ubuntu@your-lightsail-ip
# Test DNS resolution
dig bedrock-runtime.us-east-1.amazonaws.com
# You should see a private IP (10.x.x.x or 172.x.x.x), NOT a public IP
If you see a public IP, the private DNS override is not propagating across the peering connection. In that case, you will need to configure the OpenClaw endpoint URL explicitly (see Step 3).
Step 3: Configure OpenClaw to use the private endpoint
If private DNS is working (the dig test above returned a private IP), OpenClaw will automatically route through the VPC endpoint. No configuration change needed.
If private DNS is not resolving across the peering connection, set the endpoint explicitly in your OpenClaw configuration:
# Get the VPC endpoint DNS name
aws ec2 describe-vpc-endpoints \
--filters "Name=service-name,Values=com.amazonaws.us-east-1.bedrock-runtime" \
--query 'VpcEndpoints[0].DnsEntries[0].DnsName' --output text
Then configure OpenClaw:
# ~/.openclaw/config.yaml
bedrock:
endpoint_url: "https://vpce-0abc123def456-xyz.bedrock-runtime.us-east-1.vpce.amazonaws.com"
region: "us-east-1"
Verify traffic stays private
Use CloudTrail to confirm that Bedrock API calls originate from the VPC endpoint, not the public internet:
aws cloudtrail lookup-events \
--lookup-attributes AttributeKey=EventSource,AttributeValue=bedrock.amazonaws.com \
--max-results 5
In the event details, check the vpcEndpointId field. If present, traffic is flowing through your VPC endpoint. If absent, traffic is still going over the public internet.
You can also verify from the LightSail instance:
# On the LightSail instance
curl -s https://bedrock-runtime.us-east-1.amazonaws.com --connect-timeout 5 -v 2>&1 | grep "Connected to"
# Should show a private IP, not a public one
Step 4: Lock down the LightSail instance
The VPC endpoint secures the Bedrock connection. Now secure the instance itself.
Restrict gateway access
OpenClaw’s gateway listens on port 18789. Restrict it to known IP addresses only.
# LightSail firewall: allow port 18789 from your office CIDR only
aws lightsail put-instance-public-ports \
--instance-name your-openclaw-instance \
--port-infos '[
{"fromPort": 22, "toPort": 22, "protocol": "tcp", "cidrs": ["YOUR.OFFICE.IP/32"]},
{"fromPort": 18789, "toPort": 18789, "protocol": "tcp", "cidrs": ["YOUR.OFFICE.IP/32"]}
]'
Replace YOUR.OFFICE.IP/32 with your actual office or VPN IP range.
Remove the public IP if possible
If your users access OpenClaw through a VPN or private network that can reach the LightSail instance’s private IP, you do not need a public IP at all. Unfortunately, LightSail assigns a public IP by default and does not allow removing it. The workaround:
- Migrate to an EC2 instance in a private subnet.
- Access it through a bastion host, VPN, or AWS Systems Manager Session Manager.
For most deployments, restricting the firewall to known CIDRs is sufficient.
Use IAM roles instead of static API keys
If your OpenClaw instance uses Bedrock through an IAM role attached to the instance (via the LightSail IAM role feature or an EC2 migration), you eliminate static API keys entirely.
# Attach an IAM role to a LightSail instance (requires LightSail to support this)
# Or migrate to EC2 and use an instance profile:
aws ec2 associate-iam-instance-profile \
--instance-id i-0abc123def456 \
--iam-instance-profile Name=openclaw-bedrock-role
The IAM role should have a minimal policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"bedrock:InvokeModel",
"bedrock:InvokeModelWithResponseStream"
],
"Resource": "arn:aws:bedrock:us-east-1::foundation-model/*"
}
]
}
No * actions. No broad resource permissions. Only the models you use.
Rotate any existing API keys
If you previously used static credentials, rotate them now:
# On the LightSail instance
openclaw config set bedrock.credentials.method iam_role
# Remove old static keys from the environment
unset AWS_ACCESS_KEY_ID
unset AWS_SECRET_ACCESS_KEY
# Remove from .env file
sed -i '/AWS_ACCESS_KEY_ID/d' ~/.openclaw/.env
sed -i '/AWS_SECRET_ACCESS_KEY/d' ~/.openclaw/.env
Multi-instance architecture for leadership teams
For organizations deploying OpenClaw to multiple leaders, credential isolation matters. Each leader should have their own instance with their own IAM role. Shared instances mean shared context windows, shared memory, and shared blast radius if one account is compromised.
Recommended architecture
+------------------+
| VPC Endpoint |
| (Bedrock) |
| Shared, one AZ |
+--------+---------+
|
+------------------+------------------+
| | |
+---------+------+ +-------+--------+ +------+---------+
| LightSail #1 | | LightSail #2 | | LightSail #3 |
| CEO Instance | | CTO Instance | | VP Eng Instance |
| IAM Role: ceo | | IAM Role: cto | | IAM Role: vpe |
| Memory: isolated| | Memory: isolated| | Memory: isolated |
+----------------+ +----------------+ +----------------+
Key design decisions:
- One VPC endpoint, shared. VPC endpoints cost ~$8-15/month. One endpoint serves all instances in the peered network. No reason to create duplicates.
- One IAM role per leader. Each role can have different model access permissions. The CEO might need Claude Opus for complex analysis. The VP of Engineering might only need Claude Sonnet.
- Isolated memory and context. Each OpenClaw instance maintains its own memory store. No cross-contamination of sensitive conversations.
- Central monitoring. All Bedrock API calls from all instances flow through the same VPC endpoint and are logged in CloudTrail. One place to audit everything.
CloudTrail monitoring
Enable CloudTrail data events for the Bedrock service to log every API call:
aws cloudtrail put-event-selectors \
--trail-name your-trail \
--event-selectors '[{
"ReadWriteType": "All",
"IncludeManagementEvents": true,
"DataResources": [{
"Type": "AWS::BedrockRuntime::Model",
"Values": ["arn:aws:bedrock:us-east-1::foundation-model/*"]
}]
}]'
This gives you a complete audit trail: who called which model, when, and from which instance. Required for SOC 2 and most enterprise compliance frameworks.
Cost breakdown
| Component | Monthly Cost | Notes |
|---|---|---|
| VPC Endpoint (1 AZ) | $7.30 | $0.01/hour x 730 hours |
| VPC Endpoint data processing | $1-8 | $0.01/GB, depends on usage |
| LightSail instance (per leader) | $7-20 | $7 for 1GB RAM, $20 for 4GB RAM |
| CloudTrail data events | $0.10/100K events | Negligible for most deployments |
| Total: 1 leader | $15-35/month | |
| Total: 5 leaders | $50-120/month | Shared endpoint + 5 instances |
Compare this to hosted AI assistant platforms that charge $50-100 per user per month with no data isolation, no audit trail, and no control over where your data goes.
The VPC endpoint is the only new cost. LightSail instances are what you are already paying for. The security upgrade costs less than a team lunch.
What this does not cover
This guide addresses network-level isolation between OpenClaw and Bedrock. It does not cover:
- Data encryption at rest for OpenClaw’s memory and context files. Use LightSail disk encryption or migrate to EBS-backed EC2 with KMS.
- Bedrock model invocation logging with content capture. CloudTrail logs the API call metadata but not the prompt/response content by default. Enable Bedrock model invocation logging separately if you need full content audit.
- Skill security. See our OpenClaw security checklist for skill vetting, gateway hardening, and CVE patching.
- Backup and disaster recovery. LightSail snapshots are the minimum. For enterprise, export OpenClaw memory to S3 with versioning.
Next steps
Enterprise OpenClaw security is not a one-hour fix. It is an architecture engagement. The VPC endpoint setup takes 30-60 minutes for someone comfortable with AWS networking. The multi-instance architecture, IAM role design, CloudTrail integration, and compliance documentation take longer.
Book a call to discuss your deployment.
Get guides like this in your inbox every Wednesday.
No spam. Unsubscribe anytime.
You'll probably need this again.
Press Cmd+D (Mac) or Ctrl+D (Windows) to bookmark this page.
Need help with your OpenClaw setup?
We do remote setup, troubleshooting, and training worldwide.
Book a Call