Skip to content

Commit 78fea0c

Browse files
authored
Merge pull request #38 from mikelixiang88/main
Remove curl piping patterns and exposed gateway token from disk and cloudformation
2 parents 36d27a0 + 3b11f20 commit 78fea0c

8 files changed

Lines changed: 235 additions & 201 deletions

DEPLOYMENT.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,8 @@ aws ssm start-session --target $INSTANCE_ID --region us-west-2
122122
# Switch to ubuntu user
123123
sudo su - ubuntu
124124

125-
# Get token
126-
cat ~/.openclaw/gateway_token.txt
125+
# Get token from SSM Parameter Store
126+
aws ssm get-parameter --name /openclaw/openclaw-bedrock/gateway-token --with-decryption --query Parameter.Value --output text --region us-west-2
127127
```
128128

129129
### Step 4: Open Web UI

README.md

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -109,15 +109,15 @@ Choose this if you need:
109109
**Just 3 steps**:
110110
1. ✅ Click "Launch Stack" button below
111111
2. ✅ Select your EC2 key pair in the form
112-
3. ✅ Wait ~8 minutes → Check "Outputs" tab → Copy URL → Start using!
112+
3. ✅ Wait ~8 minutes → Check "Outputs" tab → Retrieve token from SSM → Start using!
113113

114114
**What happens automatically**:
115115
- Creates VPC, subnets, security groups
116116
- Launches EC2 instance
117117
- Installs Node.js, openclaw
118118
- Configures Bedrock integration
119-
- Generates secure gateway token
120-
- Outputs ready-to-use URL with token
119+
- Generates secure gateway token (stored in SSM Parameter Store)
120+
- Outputs SSM retrieval command for token
121121

122122
Click to deploy:
123123

@@ -161,8 +161,9 @@ For AWS China deployments using SiliconFlow (DeepSeek, Qwen, GLM) instead of Bed
161161

162162
1. **Install SSM Plugin**: Click link in `Step1InstallSSMPlugin` (one-time setup)
163163
2. **Port Forwarding**: Copy command from `Step2PortForwarding`, run on your computer (keep terminal open)
164-
3. **Open URL**: Copy URL from `Step3AccessURL`, open in browser (token included!)
165-
4. **Start Chatting**: Connect WhatsApp/Telegram/Discord in Web UI
164+
3. **Get Token**: Run the command from `Step3GetToken` to retrieve your token from SSM Parameter Store
165+
4. **Open URL**: Open `http://localhost:18789/?token=<your-token>` in browser
166+
5. **Start Chatting**: Connect WhatsApp/Telegram/Discord in Web UI
166167

167168

168169
![CloudFormation Outputs](images/20260128-105244.jpeg)
@@ -204,8 +205,16 @@ aws ssm start-session \
204205
--document-name AWS-StartPortForwardingSession \
205206
--parameters '{"portNumber":["18789"],"localPortNumber":["18789"]}'
206207

207-
# Open in browser (token is shown in CloudFormation Outputs > Step3AccessURL)
208-
http://localhost:18789/?token=<your-token>
208+
# Retrieve token from SSM Parameter Store
209+
TOKEN=$(aws ssm get-parameter \
210+
--name /openclaw/openclaw-bedrock/gateway-token \
211+
--with-decryption \
212+
--query Parameter.Value \
213+
--output text \
214+
--region us-west-2)
215+
216+
# Open in browser
217+
http://localhost:18789/?token=$TOKEN
209218
```
210219

211220
## How to Use openclaw
@@ -503,7 +512,12 @@ EnableSandbox: false # Skip Docker installation
503512

504513
## Security Features
505514

506-
IAM roles eliminate API key risks. CloudTrail logs every API call. VPC Endpoints keep traffic private. Docker sandbox isolates execution.
515+
- **IAM Roles** — eliminate API key risks
516+
- **CloudTrail** — logs every Bedrock API call
517+
- **VPC Endpoints** — keep traffic on private network
518+
- **SSM Parameter Store** — gateway token stored as SecureString, never written to disk or CloudFormation outputs
519+
- **Supply-Chain Protection** — Docker and NVM installed via GPG-signed repos / download-then-execute (no `curl | sh`)
520+
- **Docker Sandbox** — isolates code execution
507521

508522
**Full details**: [SECURITY.md](SECURITY.md)
509523

README_CN.md

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,9 @@
117117

118118
1. **安装 SSM 插件**:点击 `Step1InstallSSMPlugin` 链接(一次性)
119119
2. **端口转发**:复制 `Step2PortForwarding` 命令,在本地运行(保持终端打开)
120-
3. **打开 URL**:复制 `Step3AccessURL`,在浏览器打开(已含 token)
121-
4. **开始使用**:在 Web UI 连接 WhatsApp/Telegram/Discord
120+
3. **获取 Token**:运行 `Step3GetToken` 中的命令,从 SSM Parameter Store 获取 token
121+
4. **打开 URL**:在浏览器打开 `http://localhost:18789/?token=<你的token>`
122+
5. **开始使用**:在 Web UI 连接 WhatsApp/Telegram/Discord
122123

123124
![CloudFormation 输出](images/20260128-105244.jpeg)
124125
![openclaw Web UI](images/20260128-105059.jpg)
@@ -156,8 +157,16 @@ aws ssm start-session \
156157
--document-name AWS-StartPortForwardingSession \
157158
--parameters '{"portNumber":["18789"],"localPortNumber":["18789"]}'
158159

159-
# 在浏览器打开(token 在 CloudFormation 输出 Step3AccessURL 中)
160-
http://localhost:18789/?token=<你的token>
160+
# 从 SSM Parameter Store 获取 token
161+
TOKEN=$(aws ssm get-parameter \
162+
--name /openclaw/openclaw-bedrock/gateway-token \
163+
--with-decryption \
164+
--query Parameter.Value \
165+
--output text \
166+
--region us-west-2)
167+
168+
# 在浏览器打开
169+
http://localhost:18789/?token=$TOKEN
161170
```
162171

163172
## 如何使用 openclaw

TROUBLESHOOTING.md

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ XDG_RUNTIME_DIR=/run/user/1000 journalctl --user -u openclaw-gateway.service -n
3737
# Check configuration
3838
cat ~/.openclaw/openclaw.json | python3 -m json.tool
3939

40-
# Get gateway token
41-
cat ~/.openclaw/gateway_token.txt
40+
# Get gateway token from SSM Parameter Store
41+
bash ~/ssm-portforward.sh
4242

4343
# Test Bedrock connection
4444
REGION=$(curl -s http://169.254.169.254/latest/meta-data/placement/region)
@@ -119,8 +119,8 @@ aws ssm start-session \
119119
--document-name AWS-StartPortForwardingSession \
120120
--parameters '{"portNumber":["18789"],"localPortNumber":["18789"]}'
121121

122-
# 3. Get correct token (on EC2)
123-
cat ~/.clawdbot/gateway_token.txt
122+
# 3. Get correct token (on EC2, via SSM Parameter Store)
123+
bash ~/ssm-portforward.sh
124124

125125
# 4. Clear browser cache
126126
# Chrome: Cmd+Shift+Delete (Mac) or Ctrl+Shift+Delete (Windows)
@@ -482,8 +482,11 @@ XDG_RUNTIME_DIR=/run/user/1000 systemctl --user stop clawdbot-gateway
482482
# Backup old config
483483
cp ~/.clawdbot/clawdbot.json ~/.clawdbot/clawdbot.json.backup.$(date +%s)
484484

485-
# Get current values
486-
TOKEN=$(cat ~/.clawdbot/gateway_token.txt)
485+
# Get current values (token from SSM Parameter Store)
486+
IMDS_TOKEN=$(curl -s -X PUT http://169.254.169.254/latest/api/token -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
487+
INSTANCE_ID=$(curl -s -H "X-aws-ec2-metadata-token: $IMDS_TOKEN" http://169.254.169.254/latest/meta-data/instance-id)
488+
STACK_NAME=$(aws ec2 describe-tags --filters "Name=resource-id,Values=$INSTANCE_ID" "Name=key,Values=aws:cloudformation:stack-name" --query "Tags[0].Value" --output text --region $REGION)
489+
TOKEN=$(aws ssm get-parameter --name "/openclaw/$STACK_NAME/gateway-token" --with-decryption --query Parameter.Value --output text --region $REGION)
487490
REGION=$(curl -s http://169.254.169.254/latest/meta-data/placement/region)
488491

489492
# Recreate config
@@ -643,7 +646,7 @@ cat /tmp/diagnostic-info.txt
643646

644647
```
645648
/home/ubuntu/.clawdbot/clawdbot.json # Main configuration
646-
/home/ubuntu/.clawdbot/gateway_token.txt # Gateway token
649+
# Gateway token: stored in SSM Parameter Store (not on disk)
647650
/home/ubuntu/.clawdbot/setup_status.txt # Setup completion status
648651
/var/log/clawdbot-setup.log # Installation log
649652
/tmp/clawdbot/clawdbot-YYYY-MM-DD.log # Daily logs
@@ -671,8 +674,8 @@ XDG_RUNTIME_DIR=/run/user/1000 systemctl --user restart clawdbot-gateway
671674
# Config
672675
cat ~/.clawdbot/clawdbot.json
673676

674-
# Token
675-
cat ~/.clawdbot/gateway_token.txt
677+
# Token (from SSM Parameter Store)
678+
bash ~/ssm-portforward.sh
676679

677680
# Test Bedrock
678681
aws bedrock-runtime invoke-model \

clawdbot-bedrock-agentcore-multitenancy.yaml

Lines changed: 53 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -565,20 +565,29 @@ Resources:
565565

566566
snap start amazon-ssm-agent || systemctl start amazon-ssm-agent
567567

568-
curl -fsSL https://get.docker.com | sh
568+
# Install Docker via GPG-signed apt repo
569+
install -m 0755 -d /etc/apt/keyrings
570+
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
571+
chmod a+r /etc/apt/keyrings/docker.asc
572+
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" > /etc/apt/sources.list.d/docker.list
573+
apt-get update
574+
apt-get install -y docker-ce docker-ce-cli containerd.io
569575
systemctl enable docker
570576
systemctl start docker
571577
usermod -aG docker ubuntu
572578

573579
sudo -u ubuntu bash << 'UBUNTU_SCRIPT'
574580
set -e
575581
cd ~
576-
for i in {1..3}; do
577-
if curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash; then
578-
break
579-
fi
582+
# Install NVM (download first, then execute)
583+
NVM_VERSION="v0.40.1"
584+
for i in 1 2 3; do
585+
curl -fsSL "https://raw.githubusercontent.com/nvm-sh/nvm/${!NVM_VERSION}/install.sh" -o /tmp/nvm-install.sh && break
586+
echo "NVM download attempt $i failed, retrying in 5s..."
580587
sleep 5
581588
done
589+
bash /tmp/nvm-install.sh
590+
rm -f /tmp/nvm-install.sh
582591
export NVM_DIR="$HOME/.nvm"
583592
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
584593
nvm install 22
@@ -720,25 +729,58 @@ Resources:
720729
--region $REGION \
721730
--overwrite || echo "Failed to save token to SSM"
722731
732+
# Save instance info (non-secret metadata only)
723733
echo "$INSTANCE_ID" > /home/ubuntu/.openclaw/instance_id.txt
724734
echo "$REGION" > /home/ubuntu/.openclaw/region.txt
725-
echo "$GATEWAY_TOKEN" > /home/ubuntu/.openclaw/gateway_token.txt
726735
chown ubuntu:ubuntu /home/ubuntu/.openclaw/*.txt
727736
737+
# Clear token from environment
738+
unset GATEWAY_TOKEN
739+
740+
# Create SSM access script (retrieves token from SSM at runtime — never stored on disk)
741+
cat > /home/ubuntu/ssm-portforward.sh << 'SSMEOF'
742+
#!/bin/bash
743+
IMDS_TOKEN=$(curl -s -X PUT http://169.254.169.254/latest/api/token -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
744+
INSTANCE_ID=$(curl -s -H "X-aws-ec2-metadata-token: $IMDS_TOKEN" http://169.254.169.254/latest/meta-data/instance-id)
745+
REGION=$(curl -s -H "X-aws-ec2-metadata-token: $IMDS_TOKEN" http://169.254.169.254/latest/meta-data/placement/region)
746+
STACK_NAME=$(aws ec2 describe-tags --filters "Name=resource-id,Values=$INSTANCE_ID" "Name=key,Values=aws:cloudformation:stack-name" --query "Tags[0].Value" --output text --region $REGION)
747+
TOKEN=$(aws ssm get-parameter --name "/openclaw/$STACK_NAME/gateway-token" --with-decryption --query Parameter.Value --output text --region $REGION)
748+
749+
echo "=========================================="
750+
echo "OpenClaw SSM Port Forwarding"
751+
echo "=========================================="
752+
echo ""
753+
echo "Run on your local computer:"
754+
echo ""
755+
echo "aws ssm start-session \\"
756+
echo " --target $INSTANCE_ID \\"
757+
echo " --region $REGION \\"
758+
echo " --document-name AWS-StartPortForwardingSession \\"
759+
echo " --parameters '{\"portNumber\":[\"18789\"],\"localPortNumber\":[\"18789\"]}'"
760+
echo ""
761+
echo "Then open in browser:"
762+
echo "http://localhost:18789/?token=$TOKEN"
763+
echo ""
764+
echo "=========================================="
765+
SSMEOF
766+
chmod +x /home/ubuntu/ssm-portforward.sh
767+
chown ubuntu:ubuntu /home/ubuntu/ssm-portforward.sh
768+
728769
apt-get install -y python3-pip 2>&1 | tee -a /var/log/openclaw-setup.log
729770
pip3 install https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-py3-latest.tar.gz 2>&1 | tee -a /var/log/openclaw-setup.log
730771

731772
CFN_SIGNAL=$(which cfn-signal 2>/dev/null || find /usr -name cfn-signal 2>/dev/null | head -1)
732-
COMPLETE_URL="http://localhost:18789/?token=$GATEWAY_TOKEN"
773+
COMPLETE_MSG="OpenClaw ready. Retrieve token from SSM: aws ssm get-parameter --name /openclaw/$STACK_NAME/gateway-token --with-decryption --query Parameter.Value --output text --region $REGION"
733774

734775
if [ -n "$CFN_SIGNAL" ]; then
735-
$CFN_SIGNAL -e 0 -d "$COMPLETE_URL" -r "OpenClaw ready" '${OpenClawWaitHandle}'
776+
$CFN_SIGNAL -e 0 -d "$COMPLETE_MSG" -r "OpenClaw ready" '${OpenClawWaitHandle}'
736777
else
737-
SIGNAL_JSON="{\"Status\":\"SUCCESS\",\"Reason\":\"OpenClaw ready\",\"UniqueId\":\"openclaw\",\"Data\":\"$COMPLETE_URL\"}"
778+
SIGNAL_JSON="{\"Status\":\"SUCCESS\",\"Reason\":\"OpenClaw ready\",\"UniqueId\":\"openclaw\",\"Data\":\"$COMPLETE_MSG\"}"
738779
curl -X PUT -H 'Content-Type:' --data-binary "$SIGNAL_JSON" '${OpenClawWaitHandle}'
739780
fi
740781

741782
echo "OpenClaw multi-tenant installation complete!"
783+
echo "Token stored in SSM Parameter Store"
742784
Tags:
743785
- Key: Name
744786
Value: !Sub "${AWS::StackName}-gateway"
@@ -763,16 +805,8 @@ Outputs:
763805
aws ssm get-parameter --name "/openclaw/${AWS::StackName}/gateway-token" --region ${AWS::Region} --with-decryption --query 'Parameter.Value' --output text
764806
765807
Step4AccessURL:
766-
Description: "STEP 4: Open this URL in browser"
767-
Value: !Select
768-
- 1
769-
- !Split
770-
- '":"'
771-
- !Select
772-
- 0
773-
- !Split
774-
- '"}'
775-
- !GetAtt OpenClawWaitCondition.Data
808+
Description: "STEP 4: Open in browser (replace <token> with value from Step 3)"
809+
Value: "http://localhost:18789/?token=<token>"
776810

777811
Step5StartChatting:
778812
Description: "STEP 5: Start using OpenClaw!"

0 commit comments

Comments
 (0)