agent-access-control

TotalClaw 作者 totalclaw

AI 代理的分层陌生人访问控制。在设置联系人权限、处理未知发件人、管理批准的联系人或在消息传递平台(WhatsApp、Telegram、Discord、Signal)上配置陌生人偏转时使用。提供外交偏转、所有者批准流程和多层访问(所有者/受信任/仅限聊天/阻止)。

安装 / 下载方式

TotalClaw CLI推荐
totalclaw install totalclaw:totalclaw~bowen31337-agent-access-control
cURL直接下载,无需登录
curl -fsSL https://skills.taituai.com/api/skills/totalclaw%3Atotalclaw~bowen31337-agent-access-control/file -o bowen31337-agent-access-control.md
# Agent Access Control

Protect your agent from unauthorized access with tiered permissions and an owner-approval pairing flow.

## Setup

Create `memory/access-control.json` in workspace:

```json
{
  "ownerIds": [],
  "approvedContacts": {},
  "pendingApprovals": {},
  "blockedIds": [],
  "strangerMessage": "Hi there! 👋 I'm {{AGENT_NAME}}, an AI assistant. I'm currently set up to help my owner with personal tasks, so I'm not able to chat freely just yet. I've let them know you reached out — if they'd like to connect us, they'll set that up. Have a great day! 😊",
  "notifyChannel": "",
  "notifyTarget": ""
}
```

Fill in:
- `ownerIds`: Owner phone numbers, Telegram IDs, Discord IDs (strings)
- `strangerMessage`: Customize `{{AGENT_NAME}}` with agent's name
- `notifyChannel`: Channel to alert owner (`telegram`, `whatsapp`, `discord`, `signal`)
- `notifyTarget`: Owner's ID on that channel

## Access Tiers

| Tier | Level | Capabilities |
|------|-------|-------------|
| 0 | **Stranger** | Diplomatic deflection only, zero access |
| 1 | **Chat-only** | Basic conversation, no tools or private info |
| 2 | **Trusted** | Chat + public info (weather, time, general questions) |
| 3 | **Owner** | Full access to all tools, files, memory, actions |

## Message Handling Flow

On every incoming message from a messaging platform:

1. Extract sender ID (phone number, user ID, etc.)
2. Normalize ID: strip spaces, ensure country code prefix for phones
3. Check `ownerIds` → if match: **full access**, respond normally
4. Check `blockedIds` → if match: **silent ignore**, respond with NO_REPLY
5. Check `approvedContacts[senderId]` → if match: respond within their tier
6. Otherwise → **stranger flow**:

### Stranger Flow

```
a. Send strangerMessage to the sender
b. Notify owner:
   "🔔 Stranger contact from {senderId} on {platform}:
    '{first 100 chars of message}'
    Reply: approve (trusted) / chat (chat-only) / block"
c. Store in pendingApprovals:
   {
     "senderId": { 
       "platform": "whatsapp",
       "firstMessage": "...", 
       "timestamp": "ISO-8601",
       "notified": true
     }
   }
d. Respond with NO_REPLY after sending deflection
```

### Owner Approval

When owner replies to an approval notification:

| Owner says | Action |
|-----------|--------|
| `approve`, `yes`, `trusted` | Add to approvedContacts with tier 2 (trusted) |
| `chat`, `chat-only`, `chat only` | Add to approvedContacts with tier 1 (chat-only) |
| `block`, `no`, `deny` | Add to blockedIds |
| `ignore` | Remove from pendingApprovals, no action |

After approval, update `memory/access-control.json` and notify the contact:
- Trusted: "Great news! I've been given the go-ahead to chat with you. How can I help? 😊"
- Chat-only: "Great news! I can chat with you now, though I'm limited to basic conversation. What's on your mind?"

### Tier Enforcement

When responding to a non-owner contact, enforce tier restrictions:

**Tier 1 (chat-only):**
- Respond conversationally only
- Do NOT use any tools (read, write, exec, web_search, etc.)
- Do NOT share any info from memory files
- Do NOT mention the owner by name
- If asked to do something beyond chat: "I'm only set up for basic chat at the moment. For anything more, you'd need to check with my owner."

**Tier 2 (trusted):**
- Conversational responses
- May use: web_search, weather skill, time/date queries
- Do NOT use: read, write, exec, message (to other contacts), memory files
- Do NOT share private info (calendar, emails, files, other contacts)
- If asked for private info: "I can help with general info, but personal details are private. Hope you understand! 😊"

## Multi-Platform ID Matching

Normalize IDs for comparison:
- **Phone numbers**: Strip all non-digits except leading `+`. E.g., `+1 555 123 4567` → `+15551234567`
- **Telegram**: Use numeric user ID (not username, as usernames change)
- **Discord**: Use numeric user ID
- **Signal**: Use phone number (normalized)
- **WhatsApp**: Use phone number with country code

An owner may have multiple IDs across platforms. All should be in `ownerIds`.

## Rate Limiting

Apply per-tier rate limits to prevent abuse:

| Tier | Messages/hour | Messages/day |
|------|--------------|-------------|
| Stranger | 1 (deflection only) | 3 |
| Chat-only | 20 | 100 |
| Trusted | 50 | 500 |
| Owner | Unlimited | Unlimited |

If limit exceeded, respond: "I've reached my chat limit for now. Try again later! 😊"

Track in `memory/access-control.json` under `rateLimits`:
```json
"rateLimits": {
  "+61412345678": { "hourCount": 5, "dayCount": 23, "hourReset": "ISO", "dayReset": "ISO" }
}
```

## Audit Log

Log all stranger contacts to `memory/access-control-log.json`:
```json
[
  {
    "timestamp": "2026-02-07T17:30:00+11:00",
    "senderId": "+61412345678",
    "platform": "whatsapp",
    "action": "deflected",
    "message": "first 50 chars..."
  }
]
```

Keep last 100 entries. Rotate older entries out.

## Security Rules

- **NEVER** include real owner IDs, phone numbers, or tokens in skill files
- **NEVER** share the access-control.json contents with non-owners
- **NEVER** reveal that a specific person is the owner to strangers
- **NEVER** forward stranger messages to owner verbatim if they contain suspicious links
- Store all config in `memory/` (gitignored by default in most setups)
- The strangerMessage should not reveal the owner's name or personal details

## Example Config

See [references/example-config.md](references/example-config.md) for a complete annotated example.

---

## 中文说明

# 代理访问控制

通过分层权限和所有者批准的配对流程,保护你的代理免受未经授权的访问。

## 安装

在工作区中创建 `memory/access-control.json`:

```json
{
  "ownerIds": [],
  "approvedContacts": {},
  "pendingApprovals": {},
  "blockedIds": [],
  "strangerMessage": "Hi there! 👋 I'm {{AGENT_NAME}}, an AI assistant. I'm currently set up to help my owner with personal tasks, so I'm not able to chat freely just yet. I've let them know you reached out — if they'd like to connect us, they'll set that up. Have a great day! 😊",
  "notifyChannel": "",
  "notifyTarget": ""
}
```

填写:
- `ownerIds`:所有者的电话号码、Telegram ID、Discord ID(字符串)
- `strangerMessage`:用代理的名称自定义 `{{AGENT_NAME}}`
- `notifyChannel`:用于提醒所有者的通道(`telegram`、`whatsapp`、`discord`、`signal`)
- `notifyTarget`:所有者在该通道上的 ID

## 访问层级

| 层级 | 级别 | 能力 |
|------|-------|-------------|
| 0 | **陌生人** | 仅外交偏转,零访问权限 |
| 1 | **仅限聊天** | 基本对话,无工具或私密信息 |
| 2 | **受信任** | 聊天 + 公开信息(天气、时间、一般问题) |
| 3 | **所有者** | 完全访问所有工具、文件、记忆、操作 |

## 消息处理流程

对于来自消息平台的每条传入消息:

1. 提取发件人 ID(电话号码、用户 ID 等)
2. 归一化 ID:去除空格,为电话号码确保国家代码前缀
3. 检查 `ownerIds` → 若匹配:**完全访问**,正常响应
4. 检查 `blockedIds` → 若匹配:**静默忽略**,以 NO_REPLY 响应
5. 检查 `approvedContacts[senderId]` → 若匹配:在其层级内响应
6. 否则 → **陌生人流程**:

### 陌生人流程

```
a. Send strangerMessage to the sender
b. Notify owner:
   "🔔 Stranger contact from {senderId} on {platform}:
    '{first 100 chars of message}'
    Reply: approve (trusted) / chat (chat-only) / block"
c. Store in pendingApprovals:
   {
     "senderId": { 
       "platform": "whatsapp",
       "firstMessage": "...", 
       "timestamp": "ISO-8601",
       "notified": true
     }
   }
d. Respond with NO_REPLY after sending deflection
```

### 所有者批准

当所有者回复批准通知时:

| 所有者说 | 操作 |
|-----------|--------|
| `approve`、`yes`、`trusted` | 以层级 2(受信任)加入 approvedContacts |
| `chat`、`chat-only`、`chat only` | 以层级 1(仅限聊天)加入 approvedContacts |
| `block`、`no`、`deny` | 加入 blockedIds |
| `ignore` | 从 pendingApprovals 中移除,不执行操作 |

批准后,更新 `memory/access-control.json` 并通知该联系人:
- 受信任:"Great news! I've been given the go-ahead to chat with you. How can I help? 😊"
- 仅限聊天:"Great news! I can chat with you now, though I'm limited to basic conversation. What's on your mind?"

### 层级强制执行

在响应非所有者联系人时,强制执行层级限制:

**层级 1(仅限聊天):**
- 仅进行对话式响应
- 请勿使用任何工具(read、write、exec、web_search 等)
- 请勿分享记忆文件中的任何信息
- 请勿提及所有者的姓名
- 若被要求做超出聊天范围的事:"I'm only set up for basic chat at the moment. For anything more, you'd need to check with my owner."

**层级 2(受信任):**
- 对话式响应
- 可使用:web_search、天气技能、时间/日期查询
- 请勿使用:read、w