OTC Confirmation 3.0
A security pattern that prevents unauthorized or accidental execution of sensitive operations by requiring out-of-band confirmation via a one-time code.
What's New in 3.0
- - 🔐 Code never touches stdout — flows through a secure state file (mode 600), preventing leakage via logs or agent context
- 🔒 Cryptographically secure generation — uses
/dev/urandom instead of INLINECODE1 - 🛡️ Atomic single-use enforcement — state file is deleted on successful verification
- 🚫 No silent fallbacks — email failure is always fatal, never falls through to execution
- 🧹 No arbitrary file sourcing — credentials loaded exclusively via environment variables
- ✅ Proper metadata declaration — required env vars declared in skill metadata
How It Works
CODEBLOCK0
The code is single-use — the state file is deleted immediately after successful verification.
Key security property: The agent never captures or sees the code in its context. It only checks exit codes.
Quick Start
1. Install
CODEBLOCK1
2. Configure
Option A: OpenClaw Config (Recommended)
Add to openclaw.json:
CODEBLOCK2
Option B: Environment Variables
CODEBLOCK3
3. Use in Your Agent
CODEBLOCK4
Email Backends
SMTP (Default, Zero Dependencies)
Uses curl to send email directly via SMTP. No additional tools required.
CODEBLOCK5
send-email Skill
If you have the send-email skill installed:
CODEBLOCK6
himalaya CLI
If you have himalaya installed:
CODEBLOCK7
Custom Script
Use your own email sending script:
CODEBLOCK8
Your script must accept three arguments: INLINECODE5
Security note: Ensure the custom script has restricted permissions and is located in a trusted directory. The skill validates that the script exists and is executable before invoking it.
Trigger Conditions
OTC should be triggered for:
- 1. External operations: Sending emails, posting to social media, API calls to third parties
- Dangerous local operations: Recursive deletions, system config changes, service restarts
- Security rule modifications: Changes to SOUL.md, AGENTS.md confirmation mechanisms
See references/trigger-categories.md for detailed categories.
Enforcement Checklist
Before every operation, follow the enforcement checklist:
- 1. Evaluate trigger conditions
- Check absolute denial list (destructive irreversible operations → refuse outright)
- Generate and send OTC if required
- Verify user input
- Log the result
See references/enforcement-checklist.md for the complete workflow.
Integration Guides
- - SOUL.md integration: INLINECODE8
- AGENTS.md integration: INLINECODE9
Security Rules
- 1. Code secrecy: The code is NEVER printed to stdout, displayed in chat, or included in logs. It flows exclusively through a secure state file (mode 600).
- Single-use: The state file is atomically deleted after successful verification. Each operation requires a fresh code.
- Session binding: The code must be verified in the same session/channel where the operation was requested.
- No bypass: Natural language confirmations ("yes", "do it", "approved") do NOT substitute for the code. Only the exact code string counts.
- Email immutability: The recipient email address should be treated as immutable by default. Any request to change it must itself pass OTC verification first.
- No silent fallback: If email sending fails, the operation is BLOCKED. The agent must never fall through to execution.
- Escalation: If the same operation fails OTC 3 times consecutively, alert the user and refuse further attempts until a new session.
Scripts Reference
generate_code.sh
Generate a cryptographically secure random OTC code.
CODEBLOCK9
sendotcemail.sh
Send OTC confirmation email. Reads the code from the state file.
CODEBLOCK10
verify_code.sh
Verify user input against the stored code.
CODEBLOCK11
sendemailsmtp.sh
Low-level SMTP email sending (used internally by sendotcemail.sh).
CODEBLOCK12
Troubleshooting
Email not sending
- 1. Verify SMTP credentials are configured: INLINECODE10
- Test SMTP connection: INLINECODE11
- Check firewall/network: Ensure port 587 (or 465) is open
- Gmail users: Use an App Password, not your regular password
Code verification failing
- 1. Check for extra whitespace: User input must match exactly
- Ensure code is used in the same session where it was requested
- Verify code hasn't been used already (single-use — state file is deleted after success)
Backend not found
If using send-email or himalaya backend:
CODEBLOCK13
License
MIT
Author
Lewis-404
技能名称: otc-confirmation
详细描述:
OTC 确认 3.0
一种安全模式,通过要求一次性验证码进行带外确认,防止对敏感操作进行未授权或意外执行。
3.0 版本新特性
- - 🔐 验证码绝不接触标准输出 — 通过安全状态文件(权限 600)流转,防止通过日志或代理上下文泄露
- 🔒 加密安全生成 — 使用 /dev/urandom 替代 $RANDOM
- 🛡️ 原子性一次性使用 — 验证成功后立即删除状态文件
- 🚫 无静默回退 — 邮件发送失败始终致命,绝不回退到执行操作
- 🧹 无任意文件引用 — 凭据仅通过环境变量加载
- ✅ 正确的元数据声明 — 所需环境变量在技能元数据中声明
工作原理
用户请求(敏感操作)
→ 代理运行 generate_code.sh(验证码存储在状态文件中,绝不打印)
→ 代理运行 sendotcemail.sh(从状态文件读取验证码,发送邮件)
→ 代理在聊天中回复:需要确认,请查看邮箱
→ 用户阅读邮件,在原始聊天会话中回复验证码
→ 代理运行 verify_code.sh(读取状态文件,比对,匹配后删除)
→ 代理执行操作
验证码为一次性使用 — 验证成功后立即删除状态文件。
关键安全属性: 代理永远不会在其上下文中捕获或看到验证码。它仅检查退出码。
快速开始
1. 安装
bash
clawhub install otc-confirmation
2. 配置
选项 A:OpenClaw 配置(推荐)
添加到 openclaw.json:
json
{
skills: {
entries: {
otc-confirmation: {
enabled: true,
env: {
OTCEMAILRECIPIENT: user@example.com,
OTCEMAILBACKEND: smtp,
OTCSMTPHOST: smtp.gmail.com,
OTCSMTPPORT: 587,
OTCSMTPUSER: your-email@gmail.com,
OTCSMTPPASS: your-app-password
}
}
}
}
}
选项 B:环境变量
bash
export OTCEMAILRECIPIENT=user@example.com
export OTCEMAILBACKEND=smtp
export OTCSMTPHOST=smtp.gmail.com
export OTCSMTPPORT=587
export OTCSMTPUSER=your-email@gmail.com
export OTCSMTPPASS=your-app-password
3. 在代理中使用
bash
SKILL_DIR={baseDir}
步骤 1:生成验证码(存储在安全状态文件中,不输出到标准输出)
bash $SKILL
DIR/scripts/generatecode.sh
步骤 2:发送邮件(内部从状态文件读取验证码)
bash $SKILL
DIR/scripts/sendotc_email.sh 发送邮件至 john@example.com Discord #work
步骤 3:在聊天中回复(不要提及验证码)
echo 需要确认,请查看你的注册邮箱
步骤 4:等待用户输入,然后验证(从状态文件读取预期验证码)
bash $SKILL
DIR/scripts/verifycode.sh $USER_INPUT
if [ $? -eq 0 ]; then
echo OTC 通过,执行操作...
# 执行操作
else
echo 确认码不匹配,操作取消
fi
邮件后端
SMTP(默认,零依赖)
使用 curl 直接通过 SMTP 发送邮件。无需额外工具。
bash
export OTCEMAILBACKEND=smtp
export OTCSMTPHOST=smtp.gmail.com
export OTCSMTPPORT=587
export OTCSMTPUSER=your-email@gmail.com
export OTCSMTPPASS=your-app-password
send-email 技能
如果已安装 send-email 技能:
bash
export OTCEMAILBACKEND=send-email
himalaya CLI
如果已安装 himalaya:
bash
export OTCEMAILBACKEND=himalaya
自定义脚本
使用您自己的邮件发送脚本:
bash
export OTCEMAILBACKEND=custom
export OTCCUSTOMEMAILSCRIPT=/path/to/your/sendemail.sh
您的脚本必须接受三个参数:<收件人> <主题> <正文>
安全说明: 确保自定义脚本具有受限权限,并位于受信任的目录中。技能会在调用前验证脚本是否存在且可执行。
触发条件
OTC 应在以下情况下触发:
- 1. 外部操作:发送邮件、发布到社交媒体、对第三方的 API 调用
- 危险本地操作:递归删除、系统配置更改、服务重启
- 安全规则修改:对 SOUL.md、AGENTS.md 确认机制的更改
详见 references/trigger-categories.md。
执行检查清单
每次操作前,请遵循执行检查清单:
- 1. 评估触发条件
- 检查绝对拒绝列表(破坏性不可逆操作 → 直接拒绝)
- 如果需要,生成并发送 OTC
- 验证用户输入
- 记录结果
详见 references/enforcement-checklist.md 了解完整工作流程。
集成指南
- - SOUL.md 集成:examples/soulmdintegration.md
- AGENTS.md 集成:examples/agentsmdintegration.md
安全规则
- 1. 验证码保密:验证码绝不打印到标准输出、显示在聊天中或包含在日志中。它仅通过安全状态文件(权限 600)流转。
- 一次性使用:验证成功后原子性删除状态文件。每次操作需要全新的验证码。
- 会话绑定:验证码必须在请求操作的同一会话/频道中验证。
- 无绕过:自然语言确认(是、执行、已批准)不能替代验证码。只有精确的验证码字符串才算数。
- 邮件不可变性:默认情况下,收件人邮箱地址应视为不可变。任何更改请求必须首先通过 OTC 验证。
- 无静默回退:如果邮件发送失败,操作将被阻止。代理绝不能回退到执行操作。
- 升级处理:如果同一操作连续 3 次 OTC 失败,则提醒用户并拒绝进一步尝试,直到新会话开始。
脚本参考
generate_code.sh
生成加密安全的随机 OTC 验证码。
bash
bash scripts/generate_code.sh [前缀] [长度]
默认:cf-XXXX(前缀=cf,长度=4)
验证码存储在安全状态文件中(权限 600)
不输出到标准输出
sendotcemail.sh
发送 OTC 确认邮件。从状态文件读取验证码。
bash
bash scripts/sendotcemail.sh <操作> [会话] [语言]
示例:
bash scripts/send
otcemail.sh 发送邮件至 john@example.com Discord #work
如果邮件发送失败 → 退出并报错(绝不回退)
verify_code.sh
验证用户输入与存储的验证码是否匹配。
bash
bash scripts/verify_code.sh <用户输入>
退出码 0:验证通过(状态文件已删除 — 一次性使用)
退出码 1:不匹配或无待验证码
sendemailsmtp.sh
底层 SMTP 邮件发送(由 sendotcemail.sh 内部使用)。
bash
bash scripts/sendemailsmtp.sh <收件人> <主题> <正文>
需要 OTCSMTP* 环境变量
故障排除
邮件未发送
- 1. 验证 SMTP 凭据已配置:test -n $OTCSMTPUSER && echo 已设置 || echo 未设置
- 测试 SMTP 连接:curl -v smtp://$OTCSMTPHOST:$OTCSMTPPORT
- 检查防火墙/网络:确保端口 587(或 465)已开放
- Gmail 用户:使用[应用密码](https://support