Sync: add identity and trust notes
This commit is contained in:
470
Project/fonrey/DATA_MODEL/DATA_MODEL_LOGIN.md
Normal file
470
Project/fonrey/DATA_MODEL/DATA_MODEL_LOGIN.md
Normal file
@@ -0,0 +1,470 @@
|
||||
# Fonrey — 登录与账号认证数据模型(DATA_MODEL_LOGIN)
|
||||
|
||||
> **所属系统**: Fonrey 房产经纪管理系统
|
||||
> **版本**: v1.0
|
||||
> **日期**: 2026-04-24
|
||||
> **关联模块**: `apps/accounts/` — 账号认证、登录安全、密码管理
|
||||
> **关联 PRD**: `Project/fonrey/PRD/登录管理/用户登录管理模块PRD.md` (v1.3)
|
||||
> **关联技术方案**: `Project/fonrey/TECH_STACK/登录管理技术方案.md`
|
||||
|
||||
---
|
||||
|
||||
## 一、领域概览(Domain Overview)
|
||||
|
||||
### 核心概念
|
||||
|
||||
- **UserAccount(用户账号)**:系统登录主体,必须与员工档案(`org.Staff`)1:1 绑定。分为 Tenant Admin(超级管理账号,每租户唯一)和普通员工账号(username 固定为手机号)。
|
||||
- **LoginAttempt(登录尝试记录)**:记录每次登录行为(成功/失败),用于安全审计和账号锁定判断,保留 ≥ 90 天。
|
||||
- **PasswordResetToken(密码重置令牌)**:通过邮件找回密码时生成的一次性令牌,有效期 30 分钟,使用后立即失效。
|
||||
- **PasswordHistory(历史密码记录)**:保存最近 3 次密码哈希,用于防止重复使用历史密码。
|
||||
|
||||
### 关键业务规则
|
||||
|
||||
1. **账号与员工强绑定**:每个登录账号 **必须** 与 `org.Staff` 中的员工档案 1:1 绑定(Tenant Admin 例外,可不绑定)。
|
||||
2. **用户名规则差异化**:
|
||||
- Tenant Admin:由平台运营自定义(字母开头,6~30 位,含字母/数字/下划线)
|
||||
- 普通员工:**固定为员工手机号**(11 位数字),创建后不可变更
|
||||
3. **初始密码强制修改**:新账号及密码重置后,`is_initial_password = True`,首次登录必须修改密码,不可跳过。
|
||||
4. **账号锁定机制**:同一账号连续密码错误 ≥ 5 次,状态置为 `locked`,30 分钟后自动恢复;Tenant Admin 可提前手动解锁。
|
||||
5. **员工离职联动**:员工离职时,对应账号的 `status` 自动置为 `disabled`,不可登录,历史操作记录保留。
|
||||
6. **不支持自助注册**:所有账号由有权限的管理角色创建,普通员工账号在新增员工时由系统自动生成。
|
||||
|
||||
---
|
||||
|
||||
## 二、实体关系
|
||||
|
||||
```
|
||||
UserAccount
|
||||
│
|
||||
├── 1:1 ── org.Staff (实名绑定,普通员工必须)
|
||||
├── 1:N ── LoginAttempt (登录审计记录)
|
||||
├── 1:N ── PasswordResetToken (密码重置令牌)
|
||||
├── 1:N ── PasswordHistory (历史密码记录)
|
||||
└── M:1 ── UserAccount.created_by (创建人自引用)
|
||||
```
|
||||
|
||||
### Schema 归属
|
||||
|
||||
| 表 | Schema 位置 | 说明 |
|
||||
|----|------------|------|
|
||||
| `user_accounts` | 租户 Schema | 账号数据按租户隔离,username 唯一性在 Schema 维度生效 |
|
||||
| `login_attempts` | 租户 Schema | 审计记录属于租户,跨租户不可见 |
|
||||
| `password_reset_tokens` | 租户 Schema | 令牌与租户账号绑定 |
|
||||
| `password_histories` | 租户 Schema | 历史密码与账号绑定 |
|
||||
|
||||
> **注意**:Tenant ID 验证相关逻辑在 **Public Schema**(`shared_apps`),使用 `django-tenants` 的 `TenantModel`,不在本文档范围内,详见 `DATA_MODEL.md` §四(公共 Schema)。
|
||||
|
||||
---
|
||||
|
||||
## 三、Schema 定义
|
||||
|
||||
### 3.1 `user_accounts` — 账号主表(租户 Schema)
|
||||
|
||||
**表说明**:系统登录主体,每个租户内独立隔离,`username` 唯一性约束在 Schema 维度生效。
|
||||
|
||||
#### 字段定义
|
||||
|
||||
| 字段名 | 类型 | 约束 | 默认值 | 说明 |
|
||||
|--------|------|------|--------|------|
|
||||
| `id` | `BIGSERIAL` | `PRIMARY KEY` | — | 自增主键(审计场景下 BigInt 更直观;跨环境引用使用 UUID 扩展字段见下) |
|
||||
| `username` | `VARCHAR(30)` | `NOT NULL` | — | 登录名;普通员工为手机号(11 位数字);Tenant Admin 为自定义字符串;创建后不可更改 |
|
||||
| `password` | `VARCHAR(128)` | `NOT NULL` | — | PBKDF2+SHA256 哈希存储,使用 Django `make_password` |
|
||||
| `email` | `VARCHAR(254)` | `NULL` | `NULL` | 绑定邮箱;用于找回密码/用户名;为空则无法自助找回;同租户唯一 |
|
||||
| `phone_enc` | `TEXT` | `NULL` | `NULL` | 手机号 AES-256-GCM 加密密文(`core.encryption`);普通员工必填 |
|
||||
| `phone_hash` | `VARCHAR(64)` | `NULL` | `NULL` | 手机号 SHA-256 哈希;用于唯一性校验和查询;不可反推原文 |
|
||||
| `staff_id` | `BIGINT` | `FK → org_staff.id`, `NULL`, `UNIQUE` | `NULL` | 员工档案绑定(1:1);普通员工必须有值;Tenant Admin 可为空 |
|
||||
| `is_tenant_admin` | `BOOLEAN` | `NOT NULL` | `FALSE` | 是否为该租户的超级管理账号;每个租户最多 1 个(应用层约束) |
|
||||
| `status` | `VARCHAR(10)` | `NOT NULL`, `CHECK(status IN ('active','disabled','locked'))` | `'active'` | 账号状态;`locked` 为密码错误锁定,30 分钟自动恢复 |
|
||||
| `is_initial_password` | `BOOLEAN` | `NOT NULL` | `TRUE` | 初始密码标记;True 时登录成功后强制跳转修改密码页,不可跳过 |
|
||||
| `last_login` | `TIMESTAMPTZ` | `NULL` | `NULL` | 最后登录时间 |
|
||||
| `locked_until` | `TIMESTAMPTZ` | `NULL` | `NULL` | 锁定到期时间;到期后应用层将 status 恢复 active |
|
||||
| `created_at` | `TIMESTAMPTZ` | `NOT NULL` | `NOW()` | 账号创建时间 |
|
||||
| `updated_at` | `TIMESTAMPTZ` | `NOT NULL` | `NOW()` | 最后更新时间(触发器维护) |
|
||||
| `created_by` | `BIGINT` | `FK → user_accounts.id`, `NULL` | `NULL` | 创建人;普通员工由 Tenant Admin 创建;Tenant Admin 由平台运营创建(可为 NULL) |
|
||||
|
||||
#### 唯一性约束
|
||||
|
||||
```sql
|
||||
UNIQUE (username) -- Schema 内唯一,跨租户不冲突(django-tenants 机制保障)
|
||||
UNIQUE (email) -- 同租户内邮箱唯一(可为 NULL,NULL 不参与唯一性校验)
|
||||
UNIQUE (phone_hash) -- 同租户内手机号唯一(通过 hash 实现,不暴露原文)
|
||||
UNIQUE (staff_id) -- 员工档案 1:1 绑定
|
||||
```
|
||||
|
||||
#### 索引
|
||||
|
||||
```sql
|
||||
CREATE UNIQUE INDEX uq_user_accounts_username ON user_accounts (username);
|
||||
CREATE UNIQUE INDEX uq_user_accounts_email ON user_accounts (email) WHERE email IS NOT NULL;
|
||||
CREATE UNIQUE INDEX uq_user_accounts_phone ON user_accounts (phone_hash) WHERE phone_hash IS NOT NULL;
|
||||
CREATE INDEX idx_user_accounts_status ON user_accounts (status);
|
||||
CREATE INDEX idx_user_accounts_staff ON user_accounts (staff_id);
|
||||
```
|
||||
|
||||
#### Django Model 定义
|
||||
|
||||
```python
|
||||
# apps/accounts/models.py
|
||||
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
|
||||
from django.db import models
|
||||
|
||||
|
||||
class UserAccountManager(BaseUserManager):
|
||||
def create_user(self, username, password, **extra_fields):
|
||||
if not username:
|
||||
raise ValueError("username 不能为空")
|
||||
user = self.model(username=username, **extra_fields)
|
||||
user.set_password(password)
|
||||
user.save(using=self._db)
|
||||
return user
|
||||
|
||||
|
||||
class UserAccount(AbstractBaseUser):
|
||||
"""
|
||||
租户级用户账号。
|
||||
- 普通员工:username 固定为手机号(11 位数字)
|
||||
- Tenant Admin:username 由平台运营自定义(字母开头,6~30 位)
|
||||
注意:此表位于租户 Schema,username 唯一性约束在 Schema 维度生效。
|
||||
"""
|
||||
username = models.CharField(max_length=30)
|
||||
email = models.EmailField(null=True, blank=True)
|
||||
phone_enc = models.TextField(null=True, blank=True) # AES-256-GCM 加密密文
|
||||
phone_hash = models.CharField(max_length=64, null=True, blank=True) # SHA-256 哈希索引
|
||||
staff = models.OneToOneField(
|
||||
'org.Staff',
|
||||
null=True, blank=True,
|
||||
on_delete=models.SET_NULL,
|
||||
related_name='account',
|
||||
)
|
||||
is_tenant_admin = models.BooleanField(default=False)
|
||||
status = models.CharField(
|
||||
max_length=10,
|
||||
choices=[('active', 'Active'), ('disabled', 'Disabled'), ('locked', 'Locked')],
|
||||
default='active',
|
||||
)
|
||||
is_initial_password = models.BooleanField(default=True)
|
||||
last_login = models.DateTimeField(null=True, blank=True)
|
||||
locked_until = models.DateTimeField(null=True, blank=True)
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
updated_at = models.DateTimeField(auto_now=True)
|
||||
created_by = models.ForeignKey(
|
||||
'self',
|
||||
null=True, blank=True,
|
||||
on_delete=models.SET_NULL,
|
||||
related_name='created_accounts',
|
||||
)
|
||||
|
||||
USERNAME_FIELD = 'username'
|
||||
REQUIRED_FIELDS = []
|
||||
|
||||
objects = UserAccountManager()
|
||||
|
||||
class Meta:
|
||||
db_table = 'user_accounts'
|
||||
# Schema 内唯一约束
|
||||
constraints = [
|
||||
models.UniqueConstraint(fields=['username'], name='uq_user_accounts_username'),
|
||||
]
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.username} ({'admin' if self.is_tenant_admin else 'staff'})"
|
||||
|
||||
def is_locked(self) -> bool:
|
||||
"""检查账号是否处于锁定状态(含自动过期判断)"""
|
||||
from django.utils import timezone
|
||||
if self.status == 'locked':
|
||||
if self.locked_until and timezone.now() >= self.locked_until:
|
||||
# 锁定已到期,应用层自动恢复(实际由 service 层处理)
|
||||
return False
|
||||
return True
|
||||
return False
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3.2 `login_attempts` — 登录尝试审计表(租户 Schema)
|
||||
|
||||
**表说明**:记录每次登录请求(成功/失败),用于安全审计和锁定判断。数据保留 ≥ 90 天,不得提前清理。
|
||||
|
||||
#### 字段定义
|
||||
|
||||
| 字段名 | 类型 | 约束 | 默认值 | 说明 |
|
||||
|--------|------|------|--------|------|
|
||||
| `id` | `BIGSERIAL` | `PRIMARY KEY` | — | 自增主键 |
|
||||
| `username` | `VARCHAR(30)` | `NOT NULL` | — | 尝试登录的用户名(冗余存储,即使账号不存在也记录) |
|
||||
| `ip_address` | `INET` | `NOT NULL` | — | 来源 IP 地址(支持 IPv4/IPv6) |
|
||||
| `user_agent` | `TEXT` | `NULL` | `NULL` | 客户端 User-Agent(Electron 版本信息) |
|
||||
| `success` | `BOOLEAN` | `NOT NULL` | — | 是否登录成功 |
|
||||
| `failure_reason` | `VARCHAR(30)` | `NULL` | `NULL` | 失败原因;可选值见下方枚举 |
|
||||
| `attempted_at` | `TIMESTAMPTZ` | `NOT NULL` | `NOW()` | 尝试时间 |
|
||||
|
||||
**`failure_reason` 枚举值**:
|
||||
|
||||
| 值 | 含义 |
|
||||
|----|------|
|
||||
| `wrong_password` | 用户名或密码错误 |
|
||||
| `wrong_captcha` | 行为验证码失败 |
|
||||
| `account_locked` | 账号已锁定 |
|
||||
| `account_disabled` | 账号已停用 |
|
||||
| `tenant_not_found` | 租户不存在(理论上不应出现,防御性记录) |
|
||||
|
||||
#### 索引
|
||||
|
||||
```sql
|
||||
CREATE INDEX idx_login_attempts_username ON login_attempts (username);
|
||||
CREATE INDEX idx_login_attempts_ip ON login_attempts (ip_address);
|
||||
CREATE INDEX idx_login_attempts_time ON login_attempts (attempted_at DESC);
|
||||
-- 复合索引:按账号查询最近失败记录(锁定判断场景)
|
||||
CREATE INDEX idx_login_attempts_fail_check ON login_attempts (username, success, attempted_at DESC);
|
||||
```
|
||||
|
||||
#### Django Model 定义
|
||||
|
||||
```python
|
||||
class LoginAttempt(models.Model):
|
||||
"""
|
||||
登录尝试审计记录。
|
||||
- 合规保留周期:≥ 90 天
|
||||
- 注意:failure_reason 不得存储密码明文(含错误密码)
|
||||
"""
|
||||
FAILURE_REASONS = [
|
||||
('wrong_password', '用户名或密码错误'),
|
||||
('wrong_captcha', '行为验证码失败'),
|
||||
('account_locked', '账号已锁定'),
|
||||
('account_disabled', '账号已停用'),
|
||||
('tenant_not_found', '租户不存在'),
|
||||
]
|
||||
|
||||
username = models.CharField(max_length=30)
|
||||
ip_address = models.GenericIPAddressField()
|
||||
user_agent = models.TextField(null=True, blank=True)
|
||||
success = models.BooleanField()
|
||||
failure_reason = models.CharField(max_length=30, null=True, blank=True, choices=FAILURE_REASONS)
|
||||
attempted_at = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
class Meta:
|
||||
db_table = 'login_attempts'
|
||||
indexes = [
|
||||
models.Index(fields=['username']),
|
||||
models.Index(fields=['ip_address']),
|
||||
models.Index(fields=['-attempted_at']),
|
||||
models.Index(fields=['username', 'success', '-attempted_at'],
|
||||
name='idx_login_attempts_fail_check'),
|
||||
]
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.username} @ {self.attempted_at} - {'OK' if self.success else self.failure_reason}"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3.3 `password_reset_tokens` — 密码重置令牌表(租户 Schema)
|
||||
|
||||
**表说明**:用于通过邮件找回密码的一次性令牌。单次有效,30 分钟过期。
|
||||
|
||||
#### 字段定义
|
||||
|
||||
| 字段名 | 类型 | 约束 | 默认值 | 说明 |
|
||||
|--------|------|------|--------|------|
|
||||
| `id` | `BIGSERIAL` | `PRIMARY KEY` | — | 自增主键 |
|
||||
| `user_id` | `BIGINT` | `FK → user_accounts.id`, `NOT NULL` | — | 关联账号 |
|
||||
| `token` | `VARCHAR(86)` | `NOT NULL`, `UNIQUE` | — | `secrets.token_urlsafe(64)` 生成(86 字符),全局唯一 |
|
||||
| `expires_at` | `TIMESTAMPTZ` | `NOT NULL` | — | 过期时间(`created_at + 30 分钟`) |
|
||||
| `is_used` | `BOOLEAN` | `NOT NULL` | `FALSE` | 是否已使用;使用后立即置 True,防止重放攻击 |
|
||||
| `created_at` | `TIMESTAMPTZ` | `NOT NULL` | `NOW()` | 创建时间 |
|
||||
|
||||
#### 索引
|
||||
|
||||
```sql
|
||||
CREATE UNIQUE INDEX uq_password_reset_tokens_token ON password_reset_tokens (token);
|
||||
CREATE INDEX idx_password_reset_tokens_user ON password_reset_tokens (user_id);
|
||||
CREATE INDEX idx_password_reset_tokens_expiry ON password_reset_tokens (expires_at) WHERE is_used = FALSE;
|
||||
```
|
||||
|
||||
#### Django Model 定义
|
||||
|
||||
```python
|
||||
class PasswordResetToken(models.Model):
|
||||
"""
|
||||
密码重置令牌。
|
||||
安全约束:
|
||||
- Token 单次有效(is_used=True 后立即失效)
|
||||
- 有效期 30 分钟
|
||||
- 同一账号 1 小时内最多生成 3 个(服务层限频,Redis 计数)
|
||||
"""
|
||||
user = models.ForeignKey(UserAccount, on_delete=models.CASCADE, related_name='reset_tokens')
|
||||
token = models.CharField(max_length=86, unique=True) # secrets.token_urlsafe(64)
|
||||
expires_at = models.DateTimeField()
|
||||
is_used = models.BooleanField(default=False)
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
class Meta:
|
||||
db_table = 'password_reset_tokens'
|
||||
indexes = [
|
||||
models.Index(fields=['user_id']),
|
||||
]
|
||||
|
||||
def is_valid(self) -> bool:
|
||||
from django.utils import timezone
|
||||
return not self.is_used and timezone.now() < self.expires_at
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3.4 `password_histories` — 历史密码记录表(租户 Schema)
|
||||
|
||||
**表说明**:保存账号最近 3 次密码哈希,用于防止重复使用历史密码(含初始密码)。
|
||||
|
||||
#### 字段定义
|
||||
|
||||
| 字段名 | 类型 | 约束 | 默认值 | 说明 |
|
||||
|--------|------|------|--------|------|
|
||||
| `id` | `BIGSERIAL` | `PRIMARY KEY` | — | 自增主键 |
|
||||
| `user_id` | `BIGINT` | `FK → user_accounts.id`, `NOT NULL` | — | 关联账号 |
|
||||
| `password_hash` | `VARCHAR(128)` | `NOT NULL` | — | PBKDF2+SHA256 哈希值 |
|
||||
| `created_at` | `TIMESTAMPTZ` | `NOT NULL` | `NOW()` | 记录时间(密码修改时间) |
|
||||
|
||||
#### 索引
|
||||
|
||||
```sql
|
||||
CREATE INDEX idx_password_histories_user ON password_histories (user_id, created_at DESC);
|
||||
```
|
||||
|
||||
#### Django Model 定义
|
||||
|
||||
```python
|
||||
class PasswordHistory(models.Model):
|
||||
"""
|
||||
历史密码记录,每个账号保留最近 N 条(默认 3 条)。
|
||||
新密码不得与最近 3 条历史记录相同(含系统初始密码 Fonrey@2025)。
|
||||
"""
|
||||
user = models.ForeignKey(UserAccount, on_delete=models.CASCADE, related_name='password_histories')
|
||||
password_hash = models.CharField(max_length=128)
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
class Meta:
|
||||
db_table = 'password_histories'
|
||||
ordering = ['-created_at']
|
||||
indexes = [
|
||||
models.Index(fields=['user', '-created_at']),
|
||||
]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 四、Redis 缓存结构(辅助状态,非持久化)
|
||||
|
||||
以下 Redis Key 不存入 PostgreSQL,属于运行时状态,需与数据库状态保持最终一致:
|
||||
|
||||
| Key 格式 | 类型 | TTL | 说明 |
|
||||
|----------|------|-----|------|
|
||||
| `captcha_token:{uuid}` | STRING | 3 分钟 | 滑块验证会话 Token;验证通过后生成 `captcha_pass_token` |
|
||||
| `captcha_pass:{uuid}` | STRING | 3 分钟 | 一次性通过凭证;登录提交时校验后立即删除 |
|
||||
| `login_fail:{tenant_id}:{username}` | STRING(计数) | 30 分钟 | 连续密码错误次数;≥ 5 触发锁定;TTL 30 分钟自动清零 |
|
||||
| `recover_email:{email}` | STRING(计数) | 1 小时 | 找回邮件发送次数;上限 3 次/小时 |
|
||||
| `recover_reset:{account_id}` | STRING(计数) | 1 小时 | 同一账号密码重置 Token 生成次数;上限 3 次/小时 |
|
||||
| `tenant_verify_ip:{ip}` | STRING(计数) | 1 分钟 | Tenant 验证接口 IP 限流;≥ 10 次拒绝请求 |
|
||||
|
||||
> **一致性说明**:账号锁定状态由 `user_accounts.status` 持久化,Redis 仅做计数触发器。当 Redis 数据丢失(如 Redis 重启),应用层通过 `locked_until` 字段恢复锁定状态判断。
|
||||
|
||||
---
|
||||
|
||||
## 五、账号创建流程与状态机
|
||||
|
||||
### 5.1 账号状态机
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────┐
|
||||
│ 账号生命周期状态机 │
|
||||
└─────────────────────────────────────┘
|
||||
|
||||
[创建账号]
|
||||
│ is_initial_password=True, status=active
|
||||
▼
|
||||
[初始密码态] ─── 使用初始密码登录成功 ───► [强制修改密码页]
|
||||
│ │ 修改成功
|
||||
│ ▼
|
||||
│ [正常使用态]
|
||||
│ status=active
|
||||
│ is_initial_password=False
|
||||
│
|
||||
├── 密码错误 ≥ 5 次 ──────────────────► [锁定态]
|
||||
│ status=locked
|
||||
│ locked_until = now+30min
|
||||
│ │
|
||||
│ ┌───────────────┤
|
||||
│ │ 30分钟到期 │ 管理员手动解锁
|
||||
│ ▼ ▼
|
||||
│ [正常使用态] ◄─── [管理员操作]
|
||||
│
|
||||
└── 员工离职 / 管理员停用 ──► [停用态]
|
||||
status=disabled
|
||||
│
|
||||
员工复职/管理员恢复
|
||||
│
|
||||
▼
|
||||
[正常使用态]
|
||||
```
|
||||
|
||||
### 5.2 账号创建触发时机
|
||||
|
||||
| 账号类型 | 触发时机 | 创建者 | username 规则 | 初始密码 |
|
||||
|----------|----------|--------|--------------|---------|
|
||||
| Tenant Admin | 平台运营在系统后台开通租户时 | 平台运营 | 自定义(字母开头,6~30 位) | 平台运营自定义 |
|
||||
| 普通员工 | Tenant Admin 在「新增员工」时系统自动生成 | 系统(Tenant Admin 触发) | 固定为员工手机号(11 位) | 系统统一初始密码(部署配置) |
|
||||
|
||||
---
|
||||
|
||||
## 六、关联约束与数据完整性
|
||||
|
||||
### 6.1 与 `org.Staff` 的关联规则
|
||||
|
||||
```
|
||||
org_staff (1) ──── (0..1) user_accounts
|
||||
```
|
||||
|
||||
- 普通员工账号:`staff_id` **必须**有值,且在 `org.Staff` 中对应记录的 `status` 为 active
|
||||
- Tenant Admin:`staff_id` **可为空**(平台运营账号可不绑定实名档案)
|
||||
- 员工离职时(`org.Staff.status` → `resigned`),触发账号 `status` → `disabled`(由 `org` App Service 层调用 `accounts` 服务执行,避免循环依赖)
|
||||
- 账号删除:**不允许物理删除**,仅允许 `status=disabled`,审计记录永久保留
|
||||
|
||||
### 6.2 跨 App 依赖方向
|
||||
|
||||
```
|
||||
accounts ──► org (单向依赖:accounts.UserAccount.staff_id → org.Staff)
|
||||
org ──► accounts (反向触发,通过 Service 层调用,不通过 FK 反查)
|
||||
```
|
||||
|
||||
> **设计原则**:避免循环 FK 依赖,跨 App 的状态联动通过 Service 层的显式调用完成,不在 Model 层建立反向 FK。
|
||||
|
||||
---
|
||||
|
||||
## 七、迁移说明(Django Migrations)
|
||||
|
||||
### 初始迁移顺序
|
||||
|
||||
```
|
||||
0001_initial_user_accounts.py # UserAccount 表(依赖 org.Staff 表已存在)
|
||||
0002_login_attempts.py # LoginAttempt 表
|
||||
0003_password_reset_tokens.py # PasswordResetToken 表
|
||||
0004_password_histories.py # PasswordHistory 表
|
||||
```
|
||||
|
||||
### 注意事项
|
||||
|
||||
- `accounts` App 的迁移依赖 `org` App(`org.Staff` 表须先创建),需在 `INSTALLED_APPS` 中确保 `org` 在 `accounts` 之前
|
||||
- 所有迁移均在**租户 Schema** 下执行(`django-tenants` 的 `migrate_schemas` 命令)
|
||||
- 不得为 `email` 字段设置 `NOT NULL` 约束(允许为空,是否绑定邮箱属于用户选择)
|
||||
|
||||
---
|
||||
|
||||
## 八、设计决策说明(ADR)
|
||||
|
||||
| 决策 | 选择 | 理由 |
|
||||
|------|------|------|
|
||||
| 主键类型 | `BIGSERIAL` (BigInt) | 登录审计场景下 BigInt 主键更简洁高效;跨环境引用场景少,无需 UUID 的随机性 |
|
||||
| `phone` 字段拆分为 `phone_enc` + `phone_hash` | 是 | 与 `org.Staff` 保持一致;`phone_enc` 保存原文用于展示,`phone_hash` 用于唯一性校验和快速查询,避免加密字段全表扫描 |
|
||||
| 不扩展 Django `User` | 使用 `AbstractBaseUser` | 避免 `django.contrib.auth.User` 的全局唯一性限制(多租户下同一 username 在不同租户是允许的) |
|
||||
| `LoginAttempt` 不设外键到 `UserAccount` | 是(冗余存储 username) | 即使账号被删除(停用),审计记录仍需保留;使用 username 字符串字段保证审计完整性 |
|
||||
| 历史密码单独建表 | `PasswordHistory` 独立表 | 而非在 `UserAccount` 中存 JSON 数组,便于查询和维护,支持未来扩展保留次数 |
|
||||
| 锁定到期时间持久化 | `locked_until` 字段 | Redis 可能重启丢失数据,持久化 `locked_until` 保证 Redis 故障时锁定状态不丢失 |
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
**状态**: Draft
|
||||
**作者**: 产品经理
|
||||
**最后更新**: 2026-04-24(v1.3 明确账号创建权限层级:Tenant Admin 可自定义用户名/密码;普通员工账号由 Tenant Admin 在新增员工时创建,用户名为手机号,初始密码固定,首次登录强制修改)
|
||||
**版本**: 1.3
|
||||
**最后更新**: 2026-04-25(v1.4 §5.5 后端数据模型迁移至独立文档 `DATA_MODEL/DATA_MODEL_LOGIN.md`)
|
||||
**版本**: 1.4
|
||||
**所属系统**: Fonrey 房产经纪管理系统
|
||||
**关联模块**: 组织人事管理、权限管理、系统管理
|
||||
|
||||
@@ -515,61 +515,19 @@ Response 200 (失败):
|
||||
|
||||
### 5.5 后端数据模型设计
|
||||
|
||||
#### 5.5.1 `auth` App 目录结构
|
||||
> **数据模型已迁移至独立文档**,请参阅:
|
||||
> **`Project/fonrey/DATA_MODEL/DATA_MODEL_LOGIN.md`**
|
||||
|
||||
在现有 `fonrey/apps/` 目录下新增(或扩展 Django `auth` 系统):
|
||||
|
||||
```
|
||||
apps/
|
||||
└── accounts/ # 账号认证管理(租户级 App)
|
||||
├── models.py # UserAccount, LoginAttempt, PasswordResetToken
|
||||
├── views.py # 登录/登出/找回账号/找回密码视图
|
||||
├── urls.py
|
||||
├── serializers.py # API 序列化(如需 JSON 接口)
|
||||
└── services/
|
||||
├── auth.py # 认证逻辑(验证码校验、账号锁定判断)
|
||||
├── recovery.py # 找回密码/用户名逻辑
|
||||
└── tenant.py # Tenant 验证逻辑(属于 shared_apps)
|
||||
```
|
||||
|
||||
#### 5.5.2 `UserAccount` 核心字段
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `id` | BigAutoField | 主键 |
|
||||
| `username` | CharField(30) | 登录名,同租户唯一,不可变更;普通员工账号固定为手机号(11位数字),Tenant Admin 为自定义字符串 |
|
||||
| `password` | CharField | PBKDF2+SHA256 哈希,使用 Django `make_password` |
|
||||
| `email` | EmailField | 绑定邮箱,同租户唯一,选填;为空时无法自助找回密码 |
|
||||
| `phone` | CharField(11) | 绑定手机号,加密存储(`core.encryption`);普通员工必填(同时作为 username 来源),Tenant Admin 选填 |
|
||||
| `staff` | OneToOneField → `org.Staff` | 员工档案绑定;普通员工必须,Tenant Admin 可为空 |
|
||||
| `is_tenant_admin` | BooleanField | 标记是否为该租户的 Tenant Admin 账号,默认 False |
|
||||
| `status` | CharField | `active` / `disabled` / `locked` |
|
||||
| `is_initial_password` | BooleanField | True 时登录成功后强制跳转修改密码页,不可跳过 |
|
||||
| `last_login` | DateTimeField | 最后登录时间 |
|
||||
| `created_at` | DateTimeField | 账号创建时间 |
|
||||
| `created_by` | ForeignKey → self | 创建人(普通员工由 Tenant Admin 创建;Tenant Admin 由平台运营创建) |
|
||||
|
||||
#### 5.5.3 `LoginAttempt` 登录尝试记录
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `username` | CharField | 尝试登录的用户名 |
|
||||
| `ip_address` | GenericIPAddressField | 来源 IP |
|
||||
| `success` | BooleanField | 是否成功 |
|
||||
| `failure_reason` | CharField | `wrong_password` / `wrong_captcha` / `account_locked` 等 |
|
||||
| `attempted_at` | DateTimeField | 尝试时间 |
|
||||
|
||||
> **注意**:`LoginAttempt` 属于合规审计数据,保留周期建议 ≥ 90 天。
|
||||
|
||||
#### 5.5.4 `PasswordResetToken`
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `user` | ForeignKey → `UserAccount` | 关联账号 |
|
||||
| `token` | CharField(64) | 加密 Token(`secrets.token_urlsafe(32)`) |
|
||||
| `expires_at` | DateTimeField | 过期时间(创建时间 + 30 分钟) |
|
||||
| `is_used` | BooleanField | 是否已使用(使用后立即标记为 True) |
|
||||
| `created_at` | DateTimeField | 创建时间 |
|
||||
该文档包含:
|
||||
- `user_accounts` 账号主表(完整字段定义、约束、索引、Django Model 代码)
|
||||
- `login_attempts` 登录审计表
|
||||
- `password_reset_tokens` 密码重置令牌表
|
||||
- `password_histories` 历史密码记录表
|
||||
- Redis 缓存结构说明
|
||||
- 账号状态机与创建流程
|
||||
- 与 `org.Staff` 的关联规则及跨 App 依赖设计
|
||||
- Django Migrations 迁移顺序说明
|
||||
- 架构决策说明(ADR)
|
||||
|
||||
---
|
||||
|
||||
@@ -686,3 +644,5 @@ apps/
|
||||
- 权限管理模块 PRD:`Project/fonrey/PRD/权限管理/权限管理模块PRD.md`
|
||||
- 系统管理模块 PRD:`Project/fonrey/PRD/系统管理/系统管理模块PRD.md`
|
||||
- 技术栈文档:`Project/fonrey/TECH_STACK/TECH_STACK.md`
|
||||
- **登录管理数据模型**:`Project/fonrey/DATA_MODEL/DATA_MODEL_LOGIN.md`
|
||||
- **登录管理技术方案**:`Project/fonrey/TECH_STACK/登录管理技术方案.md`
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
> **For AI assistants**: Read this entire file before writing any code. All decisions here are final. Do not suggest alternatives unless asked.
|
||||
# Fonrey 登录管理系统技术方案
|
||||
|
||||
**版本**: 1.0 | **项目**: Fonrey 房产经纪管理系统 | **技术栈**: Django 4.x + HTMX + Alpine.js + PostgreSQL + Redis + Celery
|
||||
**关联 PRD**: `Project/fonrey/PRD/登录管理/用户登录管理模块PRD.md` (v1.3)
|
||||
**版本**: 2.0 | **项目**: Fonrey 房产经纪管理系统 | **技术栈**: Django 4.x + HTMX + Alpine.js + PostgreSQL + Redis + Celery
|
||||
**关联 PRD**: `Project/fonrey/PRD/登录管理/用户登录管理模块PRD.md` (v1.3)
|
||||
**关联数据模型**: `Project/fonrey/DATA_MODEL/DATA_MODEL_LOGIN.md`
|
||||
**最后更新**: 2026-04-25(v2.0 补充服务层设计、HTMX 交互模式、Celery 任务、错误处理规范)
|
||||
|
||||
> **For AI assistants**: Read this entire file before writing any code.
|
||||
> All decisions here are final. Do not suggest alternatives unless asked.
|
||||
@@ -11,13 +13,26 @@
|
||||
|
||||
## 一、模块定位与架构边界
|
||||
|
||||
登录管理模块(`accounts` App)负责多租户环境下的身份识别、认证、账号安全及凭据找回。其架构边界如下:
|
||||
登录管理模块(`accounts` App)负责多租户环境下的身份识别、认证、账号安全及凭据找回。
|
||||
|
||||
### 架构层级边界
|
||||
|
||||
| 层级 | 位置 | 说明 |
|
||||
|------|------|------|
|
||||
| Tenant ID 验证 | `shared_apps`(公共 Schema) | 属于平台基础服务,在 `public` schema 下运行,无需租户切换 |
|
||||
| Tenant ID 验证 | `shared_apps`(Public Schema) | 属于平台基础服务,在 `public` schema 下运行,无需租户切换 |
|
||||
| 账号认证、找回密码等 | 租户 Schema(Tenant Schema) | 通过请求域名 `{tenant_slug}.fonrey.com` 自动切换,`django-tenants` 中间件处理 |
|
||||
| Electron 客户端 | 前端 | 负责 Tenant ID 本地缓存、Session Token 管理、页面加载 |
|
||||
| Electron 客户端 | 前端 | 负责 Tenant ID 本地缓存、Session 管理、页面加载 |
|
||||
|
||||
### 模块依赖关系
|
||||
|
||||
```
|
||||
accounts
|
||||
├── 依赖 → org (Staff 实名绑定,单向依赖)
|
||||
├── 依赖 → core.encryption (手机号加密)
|
||||
├── 依赖 → core.cache (Redis 工具封装)
|
||||
├── 依赖 → shared.tenants (Tenant ID 验证,Public Schema)
|
||||
└── 被依赖 ← org (离职联动,通过 Service 层调用)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
@@ -25,15 +40,15 @@
|
||||
|
||||
| 依赖项 | 版本/方案 | 用途 | 说明 |
|
||||
|--------|-----------|------|------|
|
||||
| `django.contrib.auth` | Django 内置 | 用户认证基础框架 | 扩展 `AbstractBaseUser`,**不直接使用** `User` 模型;username 唯一性约束在租户 Schema 维度生效,而非全局 |
|
||||
| `django.contrib.auth` | Django 内置 | 用户认证基础框架 | 扩展 `AbstractBaseUser`,**不直接使用** `User` 模型;username 唯一性约束在租户 Schema 维度生效 |
|
||||
| `django-tenants` | 已有 | 多租户隔离 | `UserAccount` 在租户 Schema;Tenant 验证接口在 `shared_apps` |
|
||||
| `PostgreSQL` | 已有 | 数据持久化 | Schema 级别隔离租户数据 |
|
||||
| `Redis` | 必须 | 多用途缓存 | 滑块验证 Token(TTL 3min)、登录失败计数(TTL 30min)、密码重置 Token 缓存 |
|
||||
| `Celery` | 必须 | 异步任务队列 | 邮件发送异步处理,防止登录/找回接口超时 |
|
||||
| `Redis` | 必须 | 多用途缓存 | 滑块验证 Token(TTL 3min)、登录失败计数(TTL 30min)、密码重置频率限制 |
|
||||
| `Celery` | 必须 | 异步任务队列 | 邮件发送异步处理,防止登录/找回接口超时(邮件发送可能耗时 > 500ms) |
|
||||
| `Pillow` | 必须(若自研验证码) | 图片处理 | 生成拼图背景图(抠出缺口)+ 拼图碎片,输出 Base64 |
|
||||
| `django-ratelimit` 或自定义中间件 | 必须 | 接口限流 | Tenant 验证、登录、找回密码接口均需限流 |
|
||||
| `electron-store` 或 AES 加密文件 | Electron 侧 | 本地持久化 | 加密存储 Tenant ID,不存明文;路径为 `app.getPath('userData')` |
|
||||
| `secrets` (Python 标准库) | Python 内置 | Token 生成 | 使用 `secrets.token_urlsafe(32)` 生成密码重置 Token |
|
||||
| `secrets` (Python 标准库) | Python 内置 | Token 生成 | 使用 `secrets.token_urlsafe(64)` 生成密码重置 Token(86 字符) |
|
||||
|
||||
### 滑块验证码方案选型(待确认,见开放问题)
|
||||
|
||||
@@ -51,107 +66,301 @@
|
||||
```
|
||||
fonrey/apps/
|
||||
└── accounts/ # 账号认证管理(租户级 App)
|
||||
├── models.py # UserAccount, LoginAttempt, PasswordResetToken
|
||||
├── views.py # 登录/登出/找回账号/找回密码视图
|
||||
├── models.py # UserAccount, LoginAttempt, PasswordResetToken, PasswordHistory
|
||||
├── views/
|
||||
│ ├── auth.py # 登录/登出视图(HTMX 响应)
|
||||
│ ├── captcha.py # 滑块验证码视图
|
||||
│ └── recovery.py # 找回用户名/密码视图
|
||||
├── urls.py
|
||||
├── serializers.py # API 序列化(JSON 接口)
|
||||
├── serializers.py # API 序列化(JSON 接口,供 Electron 前端使用)
|
||||
├── forms.py # 登录表单、找回密码表单
|
||||
├── templates/
|
||||
│ └── accounts/
|
||||
│ ├── login.html # 登录页(含滑块验证码区域)
|
||||
│ ├── tenant_verify.html # Tenant 识别页(首次启动)
|
||||
│ ├── change_password.html # 强制修改初始密码页
|
||||
│ ├── recover_username.html # 找回用户名页
|
||||
│ ├── recover_password.html # 找回密码(步骤 1:身份验证)
|
||||
│ └── reset_password.html # 重置密码(步骤 2:设置新密码)
|
||||
└── services/
|
||||
├── auth.py # 认证逻辑(验证码校验、账号锁定判断)
|
||||
├── recovery.py # 找回密码/用户名逻辑(含邮件发送 Celery 任务)
|
||||
└── tenant.py # Tenant 验证逻辑(属于 shared_apps,公共 Schema)
|
||||
├── auth.py # 认证逻辑:滑块验证、账号锁定、登录流程
|
||||
├── captcha.py # 验证码生成与校验(Pillow 或第三方)
|
||||
├── recovery.py # 找回用户名/密码逻辑(含 Celery 任务触发)
|
||||
├── password.py # 密码复杂度校验、历史密码比对
|
||||
└── tenant.py # Tenant 验证逻辑(属于 shared_apps,Public Schema)
|
||||
|
||||
fonrey/shared/ # Public Schema App(django-tenants shared_apps)
|
||||
└── tenants/
|
||||
├── models.py # TenantModel, Domain
|
||||
└── views.py # tenant/verify/ 接口(在公共 Schema 下)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 四、数据模型
|
||||
|
||||
### 4.1 `UserAccount`(核心账号表,位于租户 Schema)
|
||||
> **数据模型完整定义已迁移至** `Project/fonrey/DATA_MODEL/DATA_MODEL_LOGIN.md`,本节仅保留技术实现视角的关键说明。
|
||||
|
||||
```python
|
||||
class UserAccount(AbstractBaseUser):
|
||||
id = BigAutoField(primary_key=True)
|
||||
username = CharField(max_length=30) # 同租户内唯一;普通员工为手机号;Tenant Admin 为自定义字符串
|
||||
email = EmailField(null=True, blank=True) # 同租户唯一,为空则无法自助找回密码
|
||||
phone = CharField(max_length=11, null=True) # 加密存储(core.encryption);普通员工必填
|
||||
staff = OneToOneField('org.Staff', null=True, on_delete=SET_NULL) # 实名绑定;普通员工必须
|
||||
is_tenant_admin = BooleanField(default=False)
|
||||
status = CharField(max_length=10) # active / disabled / locked
|
||||
is_initial_password = BooleanField(default=True) # True → 登录后强制跳转修改密码
|
||||
last_login = DateTimeField(null=True)
|
||||
created_at = DateTimeField(auto_now_add=True)
|
||||
created_by = ForeignKey('self', null=True, on_delete=SET_NULL)
|
||||
### 4.1 表归属汇总
|
||||
|
||||
USERNAME_FIELD = 'username'
|
||||
| 表名 | Schema | 说明 |
|
||||
|------|--------|------|
|
||||
| `user_accounts` | 租户 Schema | 账号主表,`username` 唯一性在 Schema 维度生效 |
|
||||
| `login_attempts` | 租户 Schema | 登录审计,保留 ≥ 90 天 |
|
||||
| `password_reset_tokens` | 租户 Schema | 一次性重置令牌,30 分钟过期 |
|
||||
| `password_histories` | 租户 Schema | 最近 3 次密码哈希,防重用 |
|
||||
|
||||
class Meta:
|
||||
unique_together = [('username',)] # Schema 内唯一,跨租户不冲突
|
||||
```
|
||||
### 4.2 关键约束汇总
|
||||
|
||||
**关键约束**:
|
||||
- `username` 唯一性约束仅在当前租户 Schema 内生效(`django-tenants` 隔离机制),不同租户可以有相同 username
|
||||
- `username` 唯一性约束仅在当前租户 Schema 内生效(`django-tenants` 隔离机制),**不同租户可以有相同 username**
|
||||
- 密码存储使用 Django 默认 `PBKDF2+SHA256`(`make_password`),**后端不得明文存储或传输**
|
||||
- `phone` 字段使用 `core.encryption` 加密存储
|
||||
|
||||
### 4.2 `LoginAttempt`(登录审计,位于租户 Schema)
|
||||
|
||||
```python
|
||||
class LoginAttempt(Model):
|
||||
username = CharField(max_length=30)
|
||||
ip_address = GenericIPAddressField()
|
||||
success = BooleanField()
|
||||
failure_reason = CharField(max_length=30, null=True)
|
||||
# 可选值:wrong_password / wrong_captcha / account_locked / account_disabled
|
||||
attempted_at = DateTimeField(auto_now_add=True)
|
||||
```
|
||||
|
||||
**保留策略**:合规审计数据,**最少保留 90 天**,不得提前清理。
|
||||
|
||||
### 4.3 `PasswordResetToken`(密码重置令牌,位于租户 Schema)
|
||||
|
||||
```python
|
||||
class PasswordResetToken(Model):
|
||||
user = ForeignKey(UserAccount, on_delete=CASCADE)
|
||||
token = CharField(max_length=64) # secrets.token_urlsafe(32) 生成
|
||||
expires_at = DateTimeField() # created_at + 30 分钟
|
||||
is_used = BooleanField(default=False)
|
||||
created_at = DateTimeField(auto_now_add=True)
|
||||
```
|
||||
|
||||
**安全约束**:
|
||||
- Token 单次有效(使用后立即设 `is_used=True`)
|
||||
- 有效期 30 分钟,过期后拒绝使用
|
||||
- 同一账号 1 小时内最多生成 3 个有效 Token(服务端计数)
|
||||
- `phone_enc` 字段使用 `core.encryption` AES-256-GCM 加密存储;`phone_hash` SHA-256 哈希用于唯一性校验
|
||||
- `locked_until` 字段持久化锁定到期时间,防止 Redis 故障导致锁定状态丢失
|
||||
|
||||
---
|
||||
|
||||
## 五、Redis Key 规范
|
||||
## 五、服务层设计(Service Layer)
|
||||
|
||||
| 用途 | Key 格式 | TTL | 说明 |
|
||||
|------|----------|-----|------|
|
||||
| 滑块验证会话 Token | `captcha_token:{uuid}` | 3 分钟 | 前端拖动完成后服务端生成一次性通过凭证 |
|
||||
| 登录失败计数 | `login_fail:{tenant_id}:{username}` | 30 分钟 | 计数 ≥ 5 时锁定账号;TTL 30 分钟自动解锁 |
|
||||
| 找回邮件发送频率 | `recover_email:{email}` | 1 小时 | 记录已发送次数,上限 3 次/小时 |
|
||||
| Tenant ID 限流 | `tenant_verify_ip:{ip}` | 1 分钟 | 计数 ≥ 10 时拒绝请求 |
|
||||
### 5.1 `services/auth.py` — 核心认证服务
|
||||
|
||||
```python
|
||||
# apps/accounts/services/auth.py
|
||||
|
||||
class AuthService:
|
||||
|
||||
LOGIN_FAIL_LIMIT = 5 # 连续失败次数触发锁定
|
||||
LOCK_DURATION_MINUTES = 30 # 锁定时长(分钟)
|
||||
|
||||
@classmethod
|
||||
def authenticate(cls, username: str, password: str, captcha_pass_token: str,
|
||||
tenant_id: str, ip_address: str, user_agent: str) -> dict:
|
||||
"""
|
||||
完整登录流程:
|
||||
1. 校验 captcha_pass_token(一次性凭证,Redis 查询后立即删除)
|
||||
2. 查询账号(不存在则记录审计日志,返回通用错误)
|
||||
3. 检查账号状态(locked / disabled)
|
||||
4. 校验密码
|
||||
5. 登录成功后:更新 last_login,清零失败计数,返回账号信息
|
||||
6. 失败时:递增失败计数,超限触发锁定
|
||||
|
||||
Returns:
|
||||
{'success': True, 'user': UserAccount, 'is_initial_password': bool}
|
||||
{'success': False, 'error_code': str, 'error_message': str}
|
||||
"""
|
||||
...
|
||||
|
||||
@classmethod
|
||||
def _check_lock_status(cls, user: 'UserAccount') -> bool:
|
||||
"""检查账号锁定状态,自动解锁已到期的锁定"""
|
||||
...
|
||||
|
||||
@classmethod
|
||||
def _increment_fail_count(cls, tenant_id: str, username: str) -> int:
|
||||
"""递增失败计数,返回当前计数;超限时触发账号锁定"""
|
||||
...
|
||||
|
||||
@classmethod
|
||||
def _trigger_lock(cls, user: 'UserAccount') -> None:
|
||||
"""触发账号锁定:status=locked, locked_until=now+30min"""
|
||||
...
|
||||
|
||||
@classmethod
|
||||
def unlock_account(cls, user: 'UserAccount') -> None:
|
||||
"""管理员手动解锁账号"""
|
||||
...
|
||||
```
|
||||
|
||||
### 5.2 `services/captcha.py` — 验证码服务
|
||||
|
||||
```python
|
||||
# apps/accounts/services/captcha.py
|
||||
|
||||
class CaptchaService:
|
||||
|
||||
CAPTCHA_TTL_SECONDS = 180 # 验证会话有效期(3分钟)
|
||||
PASS_TOKEN_TTL_SECONDS = 180 # 通过凭证有效期(3分钟)
|
||||
|
||||
@classmethod
|
||||
def generate(cls) -> dict:
|
||||
"""
|
||||
生成滑块拼图验证码。
|
||||
Returns:
|
||||
{
|
||||
'session_token': str, # Redis Key uuid,供前端提交时携带
|
||||
'background_b64': str, # 背景图(含缺口)Base64
|
||||
'puzzle_b64': str, # 拼图碎片 Base64
|
||||
'gap_y': int, # 缺口 Y 坐标(前端定位碎片初始位置)
|
||||
}
|
||||
注意:缺口 X 坐标(gap_x)不返回给前端,服务端保存在 Redis。
|
||||
"""
|
||||
...
|
||||
|
||||
@classmethod
|
||||
def verify(cls, session_token: str, slide_x: int, trajectory: list) -> dict:
|
||||
"""
|
||||
校验滑动结果。
|
||||
Args:
|
||||
session_token: generate() 返回的会话标识
|
||||
slide_x: 用户最终滑动距离(px)
|
||||
trajectory: 滑动轨迹,格式 [{'x': int, 'y': int, 't': int}, ...]
|
||||
Returns:
|
||||
{'pass': True, 'pass_token': str} # 通过,pass_token 用于登录接口
|
||||
{'pass': False, 'message': str} # 失败,前端自动刷新拼图
|
||||
校验规则:
|
||||
1. 位置偏差:abs(slide_x - gap_x) <= 5px
|
||||
2. 轨迹特征:存在加速→减速曲线,拒绝匀速/程序化轨迹
|
||||
"""
|
||||
...
|
||||
```
|
||||
|
||||
### 5.3 `services/recovery.py` — 找回账号服务
|
||||
|
||||
```python
|
||||
# apps/accounts/services/recovery.py
|
||||
|
||||
class RecoveryService:
|
||||
|
||||
RESET_LINK_EXPIRE_MINUTES = 30
|
||||
MAX_EMAILS_PER_HOUR = 3
|
||||
|
||||
@classmethod
|
||||
def request_username_recovery(cls, email: str) -> None:
|
||||
"""
|
||||
发起找回用户名。
|
||||
- 无论邮箱是否存在,统一返回「如该邮箱已绑定账号,您将收到邮件」
|
||||
- 邮箱存在时:触发 Celery 任务异步发送邮件
|
||||
- 限频:同一邮箱 1 小时内最多 3 次(Redis 计数)
|
||||
"""
|
||||
...
|
||||
|
||||
@classmethod
|
||||
def request_password_reset(cls, username: str, email: str) -> None:
|
||||
"""
|
||||
发起找回密码(步骤 1)。
|
||||
- 无论匹配结果,统一返回「如信息匹配,重置链接将发送至邮箱」(防枚举)
|
||||
- 匹配成功时:生成 PasswordResetToken,触发 Celery 异步发送邮件
|
||||
- 限频:同一账号 1 小时内最多 3 次(Redis 计数)
|
||||
"""
|
||||
...
|
||||
|
||||
@classmethod
|
||||
def reset_password(cls, token_str: str, new_password: str) -> dict:
|
||||
"""
|
||||
重置密码(步骤 2)。
|
||||
Returns:
|
||||
{'success': True}
|
||||
{'success': False, 'error_code': 'TOKEN_INVALID' | 'TOKEN_EXPIRED' | 'PASSWORD_REUSED'}
|
||||
操作顺序:
|
||||
1. 查询并校验 token(is_used=False, expires_at > now)
|
||||
2. 校验密码复杂度
|
||||
3. 校验历史密码(最近 3 次)
|
||||
4. 更新密码哈希,is_initial_password=False
|
||||
5. 标记 token is_used=True
|
||||
6. 清除该账号所有有效 Session(强制重新登录)
|
||||
7. 写入 PasswordHistory
|
||||
"""
|
||||
...
|
||||
```
|
||||
|
||||
### 5.4 `services/password.py` — 密码规则服务
|
||||
|
||||
```python
|
||||
# apps/accounts/services/password.py
|
||||
|
||||
class PasswordService:
|
||||
|
||||
MIN_LENGTH = 8
|
||||
MAX_LENGTH = 32
|
||||
HISTORY_COUNT = 3 # 保留最近 N 条历史密码
|
||||
|
||||
@classmethod
|
||||
def validate_complexity(cls, password: str) -> list[str]:
|
||||
"""
|
||||
校验密码复杂度。
|
||||
Returns: 错误列表(空列表表示通过)
|
||||
规则:
|
||||
- 长度 8~32 位
|
||||
- 必须包含字母(区分大小写)
|
||||
- 必须包含数字
|
||||
"""
|
||||
...
|
||||
|
||||
@classmethod
|
||||
def check_history(cls, user: 'UserAccount', new_password: str) -> bool:
|
||||
"""
|
||||
检查新密码是否与最近 3 次历史密码重复。
|
||||
Returns: True(允许使用)/ False(与历史重复)
|
||||
"""
|
||||
...
|
||||
|
||||
@classmethod
|
||||
def save_history(cls, user: 'UserAccount', password_hash: str) -> None:
|
||||
"""
|
||||
保存新密码哈希至历史记录,超出 HISTORY_COUNT 时删除最旧记录。
|
||||
"""
|
||||
...
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 六、接口清单
|
||||
## 六、Celery 异步任务
|
||||
|
||||
| 接口 | 方法 | Schema 位置 | 是否需要鉴权 | 限流规则 | 说明 |
|
||||
|------|------|------------|------------|---------|------|
|
||||
| `/api/auth/tenant/verify/` | POST | Public(shared) | 否 | 每 IP 每分钟 ≤ 10 次 | Tenant ID 验证 |
|
||||
| `/api/auth/captcha/` | GET | Tenant | 否 | — | 获取滑块拼图验证码(背景图 Base64 + 碎片图 Base64 + 验证 Token) |
|
||||
| `/api/auth/captcha/verify/` | POST | Tenant | 否 | — | 提交滑动轨迹 + 位置,返回一次性通过凭证 |
|
||||
| `/api/auth/login/` | POST | Tenant | 否 | 每 IP 每分钟 ≤ 20 次 | 账号密码登录 |
|
||||
| `/api/auth/logout/` | POST | Tenant | 是 | — | 登出,使服务端 Session 失效 |
|
||||
| `/api/auth/recover/username/` | POST | Tenant | 否 | 每邮箱每小时 ≤ 3 次 | 发起找回用户名(发送邮件) |
|
||||
| `/api/auth/recover/password/request/` | POST | Tenant | 否 | 每账号每小时 ≤ 3 次 | 发起找回密码(发送重置链接邮件) |
|
||||
| `/api/auth/recover/password/reset/` | POST | Tenant | 否(Token 鉴权) | — | 提交新密码,使用 PasswordResetToken 校验 |
|
||||
| `/api/auth/login/phone/` | POST | Tenant | 否 | — | **预留**,v2 实现,手机验证码登录 |
|
||||
| `/api/auth/wechat/qrcode/` | GET | Tenant | 否 | — | **预留**,v2 实现,获取微信二维码 |
|
||||
| `/api/auth/wechat/callback/` | POST | Tenant | 否 | — | **预留**,v2 实现,微信扫码回调 |
|
||||
```python
|
||||
# apps/accounts/tasks.py
|
||||
|
||||
### Tenant 验证接口 Request/Response 规范
|
||||
from celery import shared_task
|
||||
|
||||
@shared_task(
|
||||
name='accounts.send_username_recovery_email',
|
||||
max_retries=3,
|
||||
default_retry_delay=60, # 失败后 60 秒重试
|
||||
)
|
||||
def send_username_recovery_email(email: str, username: str, company_name: str) -> None:
|
||||
"""
|
||||
发送找回用户名邮件。
|
||||
失败时自动重试最多 3 次;3 次均失败则写入告警日志(Sentry)。
|
||||
邮件内容:用户名 + 发送时间 + 联系管理员说明。
|
||||
"""
|
||||
...
|
||||
|
||||
|
||||
@shared_task(
|
||||
name='accounts.send_password_reset_email',
|
||||
max_retries=3,
|
||||
default_retry_delay=60,
|
||||
)
|
||||
def send_password_reset_email(email: str, reset_link: str, company_name: str,
|
||||
expires_at: str) -> None:
|
||||
"""
|
||||
发送密码重置链接邮件。
|
||||
失败时自动重试最多 3 次;3 次均失败则写入告警日志(Sentry)。
|
||||
邮件内容:重置链接(30分钟有效)+ 安全说明。
|
||||
"""
|
||||
...
|
||||
```
|
||||
|
||||
> **重试策略**:邮件发送失败时不向前端返回错误(用户已看到「邮件已发送」提示),在后台静默重试;3 次重试均失败后通过 Sentry 上报告警,管理员可在后台查看 Token 手动告知用户。
|
||||
|
||||
---
|
||||
|
||||
## 七、接口清单
|
||||
|
||||
| 接口 | 方法 | Schema 位置 | 是否需要鉴权 | 限流规则 | 响应格式 | 说明 |
|
||||
|------|------|------------|------------|---------|---------|------|
|
||||
| `/api/auth/tenant/verify/` | POST | Public(shared) | 否 | 每 IP 每分钟 ≤ 10 次 | JSON | Tenant ID 验证 |
|
||||
| `/api/auth/captcha/` | GET | Tenant | 否 | — | JSON | 获取滑块拼图验证码 |
|
||||
| `/api/auth/captcha/verify/` | POST | Tenant | 否 | — | JSON | 提交滑动轨迹,返回一次性通过凭证 |
|
||||
| `/api/auth/login/` | POST | Tenant | 否 | 每 IP 每分钟 ≤ 20 次 | JSON | 账号密码登录 |
|
||||
| `/api/auth/logout/` | POST | Tenant | 是 | — | JSON | 登出,使服务端 Session 失效 |
|
||||
| `/api/auth/password/change/` | POST | Tenant | 是 | — | JSON / HTMX | 强制修改初始密码(登录后跳转) |
|
||||
| `/api/auth/recover/username/` | POST | Tenant | 否 | 每邮箱每小时 ≤ 3 次 | JSON / HTMX | 发起找回用户名(发送邮件) |
|
||||
| `/api/auth/recover/password/request/` | POST | Tenant | 否 | 每账号每小时 ≤ 3 次 | JSON / HTMX | 发起找回密码(发送重置链接邮件) |
|
||||
| `/api/auth/recover/password/reset/` | POST | Tenant | 否(Token 鉴权) | — | JSON / HTMX | 提交新密码,使用 PasswordResetToken 校验 |
|
||||
| `/api/auth/login/phone/` | POST | Tenant | 否 | — | JSON | **预留**,v2 实现,手机验证码登录 |
|
||||
| `/api/auth/wechat/qrcode/` | GET | Tenant | 否 | — | JSON | **预留**,v2 实现,获取微信二维码 |
|
||||
| `/api/auth/wechat/callback/` | POST | Tenant | 否 | — | JSON | **预留**,v2 实现,微信扫码回调 |
|
||||
|
||||
### 7.1 Tenant 验证接口规范
|
||||
|
||||
```
|
||||
POST /api/auth/tenant/verify/
|
||||
@@ -161,7 +370,7 @@ Request Body:
|
||||
"tenant_id": "202500010001" // 固定 12 位纯数字
|
||||
}
|
||||
|
||||
Response 200 (成功):
|
||||
Response 200 (验证通过):
|
||||
{
|
||||
"valid": true,
|
||||
"tenant_name": "XX房产经纪有限公司",
|
||||
@@ -169,7 +378,7 @@ Response 200 (成功):
|
||||
"login_url": "https://xxx.fonrey.com/auth/login/"
|
||||
}
|
||||
|
||||
Response 200 (失败):
|
||||
Response 200 (验证失败):
|
||||
{
|
||||
"valid": false,
|
||||
"error_code": "TENANT_NOT_FOUND",
|
||||
@@ -177,9 +386,9 @@ Response 200 (失败):
|
||||
}
|
||||
```
|
||||
|
||||
> **注意**:失败响应统一返回 HTTP 200,不区分"未找到"与"已禁用",防止枚举攻击。
|
||||
> 失败响应统一返回 HTTP 200,不区分「未找到」与「已禁用」,防止枚举攻击。
|
||||
|
||||
### 登录接口核心逻辑
|
||||
### 7.2 登录接口规范
|
||||
|
||||
```
|
||||
POST /api/auth/login/
|
||||
@@ -188,12 +397,12 @@ Request Body:
|
||||
{
|
||||
"username": "string",
|
||||
"password": "string",
|
||||
"captcha_token": "string", // 滑块验证通过后的一次性凭证
|
||||
"captcha_pass_token": "string"
|
||||
"captcha_pass_token": "string" // 滑块验证通过后的一次性凭证(UUID)
|
||||
}
|
||||
|
||||
Response 200 (成功):
|
||||
Response 200 (登录成功):
|
||||
{
|
||||
"success": true,
|
||||
"token": "...",
|
||||
"user": {
|
||||
"id": 1,
|
||||
@@ -202,49 +411,216 @@ Response 200 (成功):
|
||||
"is_initial_password": false
|
||||
}
|
||||
}
|
||||
|
||||
Response 200 (登录失败):
|
||||
{
|
||||
"success": false,
|
||||
"error_code": "WRONG_CREDENTIALS" | "ACCOUNT_LOCKED" | "ACCOUNT_DISABLED" | "CAPTCHA_INVALID",
|
||||
"message": "...",
|
||||
"lock_remaining_seconds": 1800 // 仅 ACCOUNT_LOCKED 时返回
|
||||
}
|
||||
```
|
||||
|
||||
> **注意**:`WRONG_CREDENTIALS` 不区分「用户名错误」与「密码错误」,防止枚举攻击。
|
||||
|
||||
### 7.3 验证码接口规范
|
||||
|
||||
```
|
||||
GET /api/auth/captcha/
|
||||
|
||||
Response 200:
|
||||
{
|
||||
"session_token": "uuid-string", // 提交验证时携带
|
||||
"background_b64": "data:image/png;base64,...", // 带缺口的背景图
|
||||
"puzzle_b64": "data:image/png;base64,...", // 拼图碎片
|
||||
"gap_y": 120, // 缺口 Y 坐标(用于定位碎片初始位置)
|
||||
"width": 320, // 背景图宽度(px)
|
||||
"height": 160 // 背景图高度(px)
|
||||
}
|
||||
|
||||
POST /api/auth/captcha/verify/
|
||||
|
||||
Request Body:
|
||||
{
|
||||
"session_token": "uuid-string",
|
||||
"slide_x": 185, // 最终滑动距离(px)
|
||||
"trajectory": [
|
||||
{"x": 0, "y": 0, "t": 0},
|
||||
{"x": 20, "y": 1, "t": 80},
|
||||
{"x": 185, "y": 2, "t": 1200}
|
||||
]
|
||||
}
|
||||
|
||||
Response 200 (验证通过):
|
||||
{
|
||||
"pass": true,
|
||||
"pass_token": "uuid-string" // 一次性凭证,TTL 3分钟,登录时携带
|
||||
}
|
||||
|
||||
Response 200 (验证失败):
|
||||
{
|
||||
"pass": false,
|
||||
"message": "验证失败,请重新拖动"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 七、安全机制设计
|
||||
## 八、前端交互模式(HTMX + Alpine.js)
|
||||
|
||||
### 7.1 滑块拼图验证码
|
||||
### 8.1 页面结构说明
|
||||
|
||||
登录相关页面均为**全页面渲染**(Server-Side Rendered),Electron 客户端通过 `BrowserWindow.loadURL()` 加载完整 HTML。登录流程中的局部交互(如验证码刷新、错误提示)通过 HTMX 局部刷新实现。
|
||||
|
||||
### 8.2 登录页核心交互
|
||||
|
||||
```html
|
||||
<!-- 登录页:accounts/login.html -->
|
||||
|
||||
<!-- 滑块验证码区域(Alpine.js 管理状态) -->
|
||||
<div x-data="captchaWidget()" x-init="loadCaptcha()">
|
||||
<!-- 背景图 + 拼图 -->
|
||||
<div class="captcha-container">
|
||||
<img :src="backgroundSrc" alt="验证图片">
|
||||
<div class="puzzle-piece"
|
||||
:style="`left: ${slideX}px; top: ${gapY}px`"
|
||||
:src="puzzleSrc">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 滑块轨道 -->
|
||||
<div class="slider-track"
|
||||
@mousedown="startSlide($event)"
|
||||
@touchstart="startSlide($event)">
|
||||
<div class="slider-thumb" :class="{'verified': passed, 'shake': failed}">
|
||||
<span x-show="!passed && !failed">拖动完成拼图</span>
|
||||
<span x-show="passed" class="text-green-500">验证通过 ✓</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 刷新按钮 -->
|
||||
<button @click="loadCaptcha()" type="button">🔄</button>
|
||||
</div>
|
||||
|
||||
<!-- 登录表单(HTMX 提交) -->
|
||||
<form hx-post="/api/auth/login/"
|
||||
hx-target="#login-feedback"
|
||||
hx-swap="innerHTML"
|
||||
hx-indicator="#login-spinner">
|
||||
<input type="hidden" name="captcha_pass_token" x-bind:value="passToken">
|
||||
<input type="text" name="username" placeholder="请输入用户名">
|
||||
<input type="password" name="password" placeholder="请输入密码">
|
||||
<button type="submit" :disabled="!passed">登录</button>
|
||||
</form>
|
||||
<div id="login-feedback"></div>
|
||||
<div id="login-spinner" class="htmx-indicator">登录中...</div>
|
||||
```
|
||||
|
||||
> **Alpine.js 职责**:管理验证码状态(加载中/通过/失败)、滑动轨迹记录、`pass_token` 绑定到表单隐藏字段。
|
||||
> **HTMX 职责**:表单提交、错误反馈局部渲染(`hx-target="#login-feedback"`)。
|
||||
|
||||
### 8.3 HTMX 响应片段规范
|
||||
|
||||
登录接口在 HTMX 请求时(`HX-Request: true` Header)返回 HTML 片段而非 JSON,供 `hx-target` 局部替换:
|
||||
|
||||
**登录成功**(服务端返回 302 重定向,HTMX 通过 `HX-Redirect` Header 处理):
|
||||
```python
|
||||
# views/auth.py
|
||||
if request.headers.get('HX-Request'):
|
||||
response = HttpResponse()
|
||||
response['HX-Redirect'] = '/dashboard/' # 跳转首页
|
||||
return response
|
||||
```
|
||||
|
||||
**登录失败**(返回错误提示 HTML 片段):
|
||||
```html
|
||||
<!-- 服务端渲染的错误片段 -->
|
||||
<div class="text-red-500 text-sm mt-2">
|
||||
用户名或密码错误,请重新输入
|
||||
</div>
|
||||
```
|
||||
|
||||
**初始密码状态**(登录成功但需修改密码):
|
||||
```python
|
||||
if request.headers.get('HX-Request'):
|
||||
response = HttpResponse()
|
||||
response['HX-Redirect'] = '/auth/password/change/'
|
||||
return response
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 九、Redis Key 规范
|
||||
|
||||
| 用途 | Key 格式 | 类型 | TTL | 说明 |
|
||||
|------|----------|------|-----|------|
|
||||
| 滑块验证会话(含缺口位置) | `captcha_session:{uuid}` | HASH | 3 分钟 | 存储 `gap_x`, `session_token`;验证后立即删除 |
|
||||
| 滑块验证通过凭证 | `captcha_pass:{uuid}` | STRING | 3 分钟 | 登录接口验证后立即删除(单次有效) |
|
||||
| 登录失败计数 | `login_fail:{tenant_id}:{username}` | STRING | 30 分钟 | 计数 ≥ 5 时触发锁定;TTL 30 分钟自动清零 |
|
||||
| 找回邮件发送频率 | `recover_email:{email}` | STRING | 1 小时 | 记录已发送次数,上限 3 次/小时 |
|
||||
| 密码重置 Token 生成频率 | `recover_reset:{user_id}` | STRING | 1 小时 | 同一账号生成次数,上限 3 次/小时 |
|
||||
| Tenant ID 限流 | `tenant_verify_ip:{ip}` | STRING | 1 分钟 | 计数 ≥ 10 时拒绝请求 |
|
||||
|
||||
> **故障恢复**:Redis 重启后,登录失败计数归零(用户可正常登录);账号锁定状态由 `user_accounts.locked_until` 持久化保证,不依赖 Redis。
|
||||
|
||||
---
|
||||
|
||||
## 十、安全机制设计
|
||||
|
||||
### 10.1 滑块拼图验证码
|
||||
|
||||
- **图片生成**:`Pillow` 从预置图库随机抽取背景图,服务端随机生成缺口位置,抠出缺口并生成拼图碎片,两者分别以 Base64 返回前端
|
||||
- **轨迹校验**:前端记录滑动过程的坐标序列 + 时间戳,提交至 `/api/auth/captcha/verify/`;服务端综合校验:
|
||||
- **位置偏差**:碎片最终位置与缺口中心偏差 ≤ ±5px
|
||||
- **轨迹特征**:存在加速→减速的非线性运动曲线;拒绝匀速/程序化轨迹
|
||||
- **独立性**:验证码失败**不计入**账号密码错误次数,两者独立计数
|
||||
- **有效期**:通过凭证(`captcha_pass_token`)TTL 3 分钟,单次有效
|
||||
- **缺口位置保护**:`gap_x`(水平位置)仅存于服务端 Redis,**不返回给前端**;前端通过 `slide_x` 提交,服务端对比 `gap_x` 校验
|
||||
- **轨迹校验**(双重判断):
|
||||
- **位置偏差**:`abs(slide_x - gap_x) ≤ 5px`
|
||||
- **轨迹特征**:速度变化曲线存在加速→减速(人类滑动特征),拒绝匀速/程序化轨迹
|
||||
- **独立计数**:验证码失败**不计入**账号密码错误次数,两者独立计数
|
||||
- **单次有效**:`captcha_pass_token` TTL 3 分钟,登录接口校验后立即删除
|
||||
|
||||
### 7.2 账号锁定机制
|
||||
### 10.2 账号锁定机制
|
||||
|
||||
- 同一账号(`login_fail:{tenant_id}:{username}`)连续密码错误 ≥ 5 次:
|
||||
- 账号状态置为 `locked`,持续 30 分钟
|
||||
- Redis TTL 30 分钟到期后自动恢复,同时 `status` 更新为 `active`
|
||||
- Tenant Admin 可在管理界面手动解锁(提前恢复)
|
||||
```
|
||||
同一账号连续密码错误 ≥ 5 次:
|
||||
1. Redis `login_fail:{tenant_id}:{username}` 计数达到阈值
|
||||
2. 更新 user_accounts.status = 'locked'
|
||||
3. 设置 user_accounts.locked_until = now() + 30min
|
||||
4. 锁定状态下,登录接口直接返回 ACCOUNT_LOCKED,不再校验密码
|
||||
|
||||
### 7.3 密码安全
|
||||
解锁条件(任一满足):
|
||||
A. locked_until 到期:应用层在下次登录时检测,自动恢复 status=active
|
||||
B. Tenant Admin 手动解锁:调用 AuthService.unlock_account()
|
||||
```
|
||||
|
||||
### 10.3 密码安全
|
||||
|
||||
| 规则 | 说明 |
|
||||
|------|------|
|
||||
| 存储哈希 | Django `PBKDF2+SHA256`(`make_password`) |
|
||||
| 传输安全 | 强制 HTTPS,前端**不加密**密码(HTTPS 层保证) |
|
||||
| 复杂度 | 长度 8~32 位,必须包含字母(区分大小写)+ 数字;建议特殊符号(非强制) |
|
||||
| 历史密码 | 不得与最近 3 次历史密码相同(含系统固定初始密码 `Fonrey@2025`) |
|
||||
| 历史密码 | 不得与最近 3 次历史密码哈希相同(含系统固定初始密码) |
|
||||
| Session 有效期 | 默认 8 小时;可由 Tenant Admin 在「系统设置」中调整 |
|
||||
|
||||
### 7.4 密码重置流程安全要点
|
||||
### 10.4 防枚举攻击设计
|
||||
|
||||
- Token 由 `secrets.token_urlsafe(32)` 生成,64 字符,全局唯一
|
||||
- 单次有效:使用后立即标记 `is_used=True`
|
||||
| 场景 | 防御措施 |
|
||||
|------|---------|
|
||||
| 登录失败 | 不区分「用户名错误」与「密码错误」,统一返回 `WRONG_CREDENTIALS` |
|
||||
| 找回用户名/密码 | 无论邮箱/用户名是否存在,统一返回相同响应文案 |
|
||||
| Tenant ID 验证 | 不区分「租户不存在」与「租户已禁用」;IP 限流每分钟 ≤ 10 次 |
|
||||
| 密码重置 Token | Token 使用 `secrets.token_urlsafe(64)` 生成(86 字符),不可预测 |
|
||||
|
||||
### 10.5 密码重置流程安全要点
|
||||
|
||||
- Token 由 `secrets.token_urlsafe(64)` 生成,86 字符,全局唯一
|
||||
- 单次有效:使用后立即标记 `is_used=True`(先标记再执行,防止并发重放)
|
||||
- 有效期 30 分钟(`expires_at = created_at + timedelta(minutes=30)`)
|
||||
- 重置成功后:清除该账号所有有效 Session(强制重新登录)
|
||||
- 重置成功后:`is_initial_password = False`
|
||||
- 重置成功后:`is_initial_password = False`,写入 `PasswordHistory`
|
||||
|
||||
---
|
||||
|
||||
## 八、Electron 客户端约定
|
||||
## 十一、Electron 客户端约定
|
||||
|
||||
| 约定项 | 规格 |
|
||||
|--------|------|
|
||||
@@ -254,44 +630,73 @@ Response 200 (成功):
|
||||
| 多标签页 | 同一 `BrowserWindow` 内所有页面共享同一 Session Cookie |
|
||||
| 客户端登出 | 调用 `POST /api/auth/logout/` 使服务端 Session 失效 + 清除 Chromium Session Cookie |
|
||||
| 窗口关闭 | Session 保留(不自动登出),下次打开若 Session 未过期则直接进入系统 |
|
||||
| 强制更新 | 客户端版本低于服务端 `min_required_version` 时,阻断登录流程,展示更新提示 |
|
||||
| 强制更新 | 客户端版本低于服务端 `min_required_version` 时,阻断登录流程,展示更新提示(详见发布管理模块 PRD) |
|
||||
| Tenant ID 缓存校验 | 非首次启动时,客户端向服务端发起缓存 Tenant ID 有效性校验(`POST /api/auth/tenant/verify/`);无效则清除缓存,重新显示 Tenant 识别界面 |
|
||||
|
||||
---
|
||||
|
||||
## 九、多租户隔离要点
|
||||
## 十二、多租户隔离要点
|
||||
|
||||
- `UserAccount`、`LoginAttempt`、`PasswordResetToken` 均位于**租户 Schema 内**,数据完全隔离
|
||||
- `UserAccount`、`LoginAttempt`、`PasswordResetToken`、`PasswordHistory` 均位于**租户 Schema 内**,数据完全隔离
|
||||
- `username` 唯一性约束在 Schema 维度生效,不同租户可以存在相同 username
|
||||
- Tenant 验证接口(`/api/auth/tenant/verify/`)位于 **Public Schema**(`shared_apps`),查询 `TenantModel`
|
||||
- 登录等接口通过请求域名(`{tenant_slug}.fonrey.com`)自动切换 Schema,由 `django-tenants` 中间件处理,**无需手动切换**
|
||||
- 所有接口禁止跨租户数据访问,ORM 查询范围自动限制在当前 Schema
|
||||
|
||||
---
|
||||
|
||||
## 十、已知风险与缓解措施
|
||||
## 十三、错误处理规范
|
||||
|
||||
### 13.1 标准错误码
|
||||
|
||||
| Error Code | HTTP Status | 含义 | 前端显示文案 |
|
||||
|------------|-------------|------|-------------|
|
||||
| `WRONG_CREDENTIALS` | 200 | 用户名或密码错误 | 「用户名或密码错误,请重新输入」 |
|
||||
| `ACCOUNT_LOCKED` | 200 | 账号已锁定 | 「账号已被临时锁定,请 30 分钟后重试,或联系管理员解锁」 |
|
||||
| `ACCOUNT_DISABLED` | 200 | 账号已停用 | 「账号已停用,请联系您的管理员」 |
|
||||
| `CAPTCHA_INVALID` | 200 | 验证码凭证无效/已过期 | 「验证码已失效,请重新验证」 |
|
||||
| `CAPTCHA_FAIL` | 200 | 滑块位置/轨迹校验失败 | 「验证失败,请重新拖动」 |
|
||||
| `TENANT_NOT_FOUND` | 200 | Tenant ID 无效 | 「识别码无效,请联系您的系统管理员获取正确的识别码」 |
|
||||
| `TOKEN_INVALID` | 200 | 重置 Token 无效或已使用 | 「链接已过期或已使用,请重新申请」 |
|
||||
| `TOKEN_EXPIRED` | 200 | 重置 Token 已过期 | 「链接已过期,请重新申请」 |
|
||||
| `PASSWORD_TOO_WEAK` | 200 | 密码不符合复杂度 | 逐条显示不满足的规则 |
|
||||
| `PASSWORD_REUSED` | 200 | 密码与历史密码相同 | 「新密码不能与最近 3 次历史密码相同」 |
|
||||
|
||||
> **设计原则**:所有登录相关接口统一返回 HTTP 200,通过 `error_code` 字段区分业务错误,避免 HTTP 状态码暴露系统行为(防止通过 4xx/5xx 枚举账号状态)。
|
||||
|
||||
### 13.2 异常监控
|
||||
|
||||
- 所有未预期异常(5xx)通过 Sentry 上报,含 `tenant_id`、`username`(脱敏)、堆栈信息
|
||||
- 邮件发送 Celery 任务 3 次重试失败后,上报 Sentry 告警并记录 `task_id`,管理员可在系统后台查询
|
||||
|
||||
---
|
||||
|
||||
## 十四、已知风险与缓解措施
|
||||
|
||||
| 风险 | 可能性 | 影响 | 缓解措施 |
|
||||
|------|--------|------|---------|
|
||||
| 滑块验证被机器模拟轨迹绕过 | 低 | 高 | 服务端同时校验位置偏差 + 轨迹曲线特征,拒绝匀速/程序化轨迹;后续可引入设备指纹 |
|
||||
| Tenant ID 枚举攻击 | 低 | 中 | 限流(每 IP 每分钟 ≤ 10 次);响应不区分"未找到"与"已禁用" |
|
||||
| Tenant ID 枚举攻击 | 低 | 中 | 限流(每 IP 每分钟 ≤ 10 次);响应不区分「未找到」与「已禁用」 |
|
||||
| 密码重置 Token 泄露 | 低 | 高 | 单次有效 + 30 分钟过期 + HTTPS 传输 |
|
||||
| 邮件发送失败 | 中 | 中 | 异步任务失败写入告警日志;管理员可通过后台查看 Token 手动告知用户 |
|
||||
| 邮件发送失败 | 中 | 中 | 异步任务自动重试 3 次;失败写入 Sentry 告警;管理员可通过后台查看 Token 手动告知用户 |
|
||||
| 多端并发登录 | 高(正常场景) | 低 | 本期允许;v2 可在 Token 引入版本号实现踢出策略 |
|
||||
| Redis 故障导致锁定状态丢失 | 低 | 中 | `locked_until` 字段持久化至 PostgreSQL,Redis 故障不影响锁定判断 |
|
||||
|
||||
---
|
||||
|
||||
## 十一、开放问题(开发启动前必须确认)
|
||||
## 十五、开放问题(开发启动前必须确认)
|
||||
|
||||
| 问题 | 负责人 | 截止 |
|
||||
|------|--------|------|
|
||||
| 邮件服务商选型:SendGrid / 阿里云邮件推送 / SMTP 自建? | 后端负责人 + 运维 | 开发启动前 |
|
||||
| 滑块验证码方案:自研(Pillow)还是第三方(极验 / 网易易盾)? | 后端负责人 + 安全 | 开发启动前 |
|
||||
| Session 有效期默认值 8 小时,是否允许 Tenant Admin 自行配置? | 产品经理 | 开发启动前 |
|
||||
| 账号锁定后是否自动发邮件通知用户和/或管理员? | 产品经理 | 开发启动前 |
|
||||
| 历史密码校验范围:最近 3 次是否足够?是否增加"不得与用户名相同"规则? | 产品经理 | 开发启动前 |
|
||||
| # | 问题 | 负责人 | 截止 |
|
||||
|---|------|--------|------|
|
||||
| 1 | 邮件服务商选型:SendGrid / 阿里云邮件推送 / SMTP 自建? | 后端负责人 + 运维 | 开发启动前 |
|
||||
| 2 | 滑块验证码方案:自研(Pillow)还是第三方(极验 / 网易易盾)? | 后端负责人 + 安全 | 开发启动前 |
|
||||
| 3 | Session 有效期默认值 8 小时,是否允许 Tenant Admin 自行配置? | 产品经理 | 开发启动前 |
|
||||
| 4 | 账号锁定后是否自动发邮件通知用户和/或管理员? | 产品经理 | 开发启动前 |
|
||||
| 5 | 历史密码校验范围:最近 3 次是否足够?是否增加「不得与用户名相同」规则? | 产品经理 | 开发启动前 |
|
||||
|
||||
---
|
||||
|
||||
## 十二、明确禁止
|
||||
## 十六、明确禁止
|
||||
|
||||
- ❌ 不得使用 Django 原生 `User` 模型,必须扩展 `AbstractBaseUser`
|
||||
- ❌ 不得在全局 Schema 创建 `UserAccount` 表(必须在租户 Schema 内)
|
||||
@@ -299,6 +704,8 @@ Response 200 (成功):
|
||||
- ❌ 不得在 `LoginAttempt` 记录中存储密码明文(含错误密码)
|
||||
- ❌ 不得在前端做密码哈希(HTTPS 层保证传输安全)
|
||||
- ❌ 不得将 Session Token 写入 Electron 磁盘明文文件
|
||||
- ❌ 不得在找回账号/密码响应中区分"邮箱存在"与"邮箱不存在"(防止枚举)
|
||||
- ❌ 不得在找回账号/密码响应中区分「邮箱存在」与「邮箱不存在」(防止枚举)
|
||||
- ❌ `PasswordResetToken` 不得重复使用(`is_used=True` 后立即失效)
|
||||
- ❌ 登录失败响应不得区分"用户名错误"与"密码错误"
|
||||
- ❌ 登录失败响应不得区分「用户名错误」与「密码错误」
|
||||
- ❌ 不得将 `gap_x`(缺口水平位置)返回给前端(防止绕过验证)
|
||||
- ❌ 耗时超过 500ms 的操作(如邮件发送)必须通过 Celery 异步执行,不得在请求线程中同步等待
|
||||
|
||||
48
wiki/concepts/Algorithm-Agility.md
Normal file
48
wiki/concepts/Algorithm-Agility.md
Normal file
@@ -0,0 +1,48 @@
|
||||
---
|
||||
title: "Algorithm-Agility"
|
||||
type: concept
|
||||
tags: [cryptography, post-quantum, future-proof]
|
||||
sources: [agentic-identity-trust.md]
|
||||
last_updated: 2026-04-25
|
||||
---
|
||||
|
||||
## Definition
|
||||
|
||||
Algorithm-Agility(算法敏捷性)是一种密码学系统设计原则——将密码学算法作为可替换参数抽象,而非硬编码选择,从而使系统能够在不破坏现有身份链的前提下完成算法升级(如从经典加密迁移到后量子加密)。
|
||||
|
||||
## Motivation
|
||||
|
||||
当前使用的 Ed25519/ECDSA 等经典签名算法面临量子计算威胁。当 NIST 后量子标准(ML-DSA、ML-KEM、SLH-DSA)成熟并部署时,需要确保:
|
||||
- 历史签名的身份链仍可验证
|
||||
- 无需重新颁发所有现有凭证
|
||||
- 迁移过程平滑,无需停机
|
||||
|
||||
## Design Pattern
|
||||
|
||||
```python
|
||||
# 差的实践:硬编码算法
|
||||
signature = ed25519.sign(private_key, payload)
|
||||
|
||||
# 好的实践:算法作为参数
|
||||
class IdentityVerifier:
|
||||
def verify(self, payload, signature, algorithm="Ed25519"):
|
||||
impl = self._get_implementation(algorithm)
|
||||
return impl.verify(self.public_key, payload, signature)
|
||||
```
|
||||
|
||||
## Hybrid Scheme(过渡期策略)
|
||||
|
||||
在经典算法向量子安全算法迁移期间,使用混合签名:
|
||||
```
|
||||
hybrid_signature = concat(
|
||||
classical_signature(Ed25519, payload),
|
||||
post_quantum_signature(ML-DSA, payload)
|
||||
)
|
||||
```
|
||||
|
||||
## Relationships
|
||||
- [[Zero-Trust]]:Algorithm-Agility 确保 Zero-Trust 基础设施在后量子时代仍可用
|
||||
- [[Evidence-Chain]]:历史 Evidence-Chain 记录必须在新算法体系下仍可独立验证
|
||||
|
||||
## Sources
|
||||
- [[agentic-identity-trust.md]]
|
||||
46
wiki/concepts/Blocking.md
Normal file
46
wiki/concepts/Blocking.md
Normal file
@@ -0,0 +1,46 @@
|
||||
---
|
||||
title: "Blocking"
|
||||
type: concept
|
||||
tags: ["identity-resolution", "performance", "algorithm", "entity-matching"]
|
||||
sources: ["identity-graph-operator"]
|
||||
last_updated: 2026-04-25
|
||||
---
|
||||
|
||||
# Blocking(阻塞/分块)
|
||||
|
||||
## Definition
|
||||
身份解析中的候选对筛选技术——通过预计算的 **blocking key** 将全量 O(n²) 记录对比较减少为可控规模候选集的 O(n×k) 操作,是大规模实体解析的性能关键。
|
||||
|
||||
## Blocking Key Types
|
||||
|
||||
| 类型 | 示例 | 适用场景 |
|
||||
|------|------|----------|
|
||||
| Email Domain | `acme.com` | 同一公司账号 |
|
||||
| Phone Prefix | `+1555` | 同一地区号码 |
|
||||
| Name Soundex | `S530` | 语音相似姓名(Williams→W452) |
|
||||
| Postal Code | `94105` | 同一地理区域 |
|
||||
| Composite | email_domain + name_soundex | 联合分块,减少假阳性 |
|
||||
|
||||
## Workflow
|
||||
|
||||
```
|
||||
全量记录
|
||||
↓
|
||||
为每条记录生成 blocking key(s)
|
||||
↓
|
||||
按 blocking key 分组(分块)
|
||||
↓
|
||||
仅对同组记录对进行 pairwise scoring
|
||||
↓
|
||||
跨块记录对被阻塞(不比较)
|
||||
```
|
||||
|
||||
## Design Considerations
|
||||
- **召回率 vs 性能**:blocking key 越宽松 → 更多候选对 → 更高召回率但更慢;越严格 → 更少候选对但可能遗漏真匹配
|
||||
- **假阴性风险**:两个同实体但 blocking key 不同(如 "gmail.com" vs "googlemail.com")会跨块遗漏
|
||||
- **假阳性成本**:同块内异实体(如同名不同人的 "John Smith")需靠 scoring 层排除
|
||||
|
||||
## Relationship to Related Concepts
|
||||
- [[Blocking]] 是 [[Identity Resolution]] 的性能优化组件,通过牺牲少量召回率换取大规模场景可接受的计算成本
|
||||
- [[Fuzzy-Matching]] 在 Blocking 筛选出的候选对上执行细粒度评分
|
||||
- [[Confidence-Score]] 综合 Blocking + Scoring 的结果给出最终合并决策
|
||||
52
wiki/concepts/Confidence-Score.md
Normal file
52
wiki/concepts/Confidence-Score.md
Normal file
@@ -0,0 +1,52 @@
|
||||
---
|
||||
title: "Confidence Score"
|
||||
type: concept
|
||||
tags: ["identity-resolution", "decision-making", "threshold", "multi-agent"]
|
||||
sources: ["identity-graph-operator"]
|
||||
last_updated: 2026-04-25
|
||||
---
|
||||
|
||||
# Confidence Score(置信度评分)
|
||||
|
||||
## Definition
|
||||
身份解析决策的核心度量——综合所有字段级匹配证据,通过加权求和得出的合并置信度。是决定"自动合并 / 提案审查 / 创建新实体"三类决策的分界指标。
|
||||
|
||||
## Calculation
|
||||
|
||||
```
|
||||
confidence = Σ(score_i × weight_i) / Σ(weight_i)
|
||||
```
|
||||
|
||||
其中 `score_i` 是字段级 fuzzy/exact match 分数(0–1),`weight_i` 是字段可靠性权重。
|
||||
|
||||
### 示例(来自 Identity Graph Operator 源码)
|
||||
| 字段 | 记录A值 | 记录B值 | Normalizer | Comparator | Score | Weight |
|
||||
|------|---------|---------|-----------|------------|-------|--------|
|
||||
| email | wsmith@acme.com | wsmith@acme.com | email | exact | 1.0 | 高 |
|
||||
| last_name | Smith | Smith | name | exact | 1.0 | 高 |
|
||||
| first_name | William | Bill | name | nickname | 0.82 | 中 |
|
||||
| phone | +155****0142 | +155****0142 | phone | exact | 1.0 | 高 |
|
||||
|
||||
综合置信度 = `1.0×0.3 + 1.0×0.3 + 0.82×0.2 + 1.0×0.2` ≈ **0.96**
|
||||
|
||||
## Decision Thresholds
|
||||
|
||||
```
|
||||
confidence > 0.95 → 自动合并(单 Agent 高置信)
|
||||
0.60 ≤ confidence ≤ 0.95 → 提案审查(多 Agent 协作)
|
||||
confidence < 0.60 → 创建新实体
|
||||
```
|
||||
|
||||
## Field Reliability Weights
|
||||
|
||||
| 字段 | 权重 | 原因 |
|
||||
|------|------|------|
|
||||
| Email | 高 | 几乎唯一,变更需主动操作 |
|
||||
| Phone | 高 | 需验证,变更成本高 |
|
||||
| Name | 中 | 常见同名不同人,需结合其他字段 |
|
||||
| Address | 低 | 常见地址变更(搬家) |
|
||||
|
||||
## Why Thresholds Matter
|
||||
- **防止假阳性**(False Merge):将两个不同人(如同名"John Smith")错误合并——高阈值 + 字段级证据防止
|
||||
- **防止假阴性**(Missed Match):将同一人(如"Bill Smith"/"William Smith")遗漏为不同实体——中等阈值触发提案审查而非直接拒绝
|
||||
- **可解释性**:per-field evidence 使决策可被其他 Agent 和人类审计
|
||||
40
wiki/concepts/Delegation-Chain.md
Normal file
40
wiki/concepts/Delegation-Chain.md
Normal file
@@ -0,0 +1,40 @@
|
||||
---
|
||||
title: "Delegation-Chain"
|
||||
type: concept
|
||||
tags: [authorization, delegation, multi-hop]
|
||||
sources: [agentic-identity-trust.md]
|
||||
last_updated: 2026-04-25
|
||||
---
|
||||
|
||||
## Definition
|
||||
|
||||
Delegation-Chain(委托链)是一种多跳授权链机制——当 Agent A 授权 Agent B 代表其行事,Agent B 可以进一步授权 Agent C,但每一跳都必须满足:签名有效 + 作用域不扩大 + 时间未过期。
|
||||
|
||||
## Chain Structure
|
||||
|
||||
```
|
||||
Agent A ──signs──> Agent B (scope: trade.execute)
|
||||
│
|
||||
└──signs──> Agent C (scope: trade.execute, audit.write) ❌ scope_escalation
|
||||
```
|
||||
|
||||
## Verification Rules
|
||||
|
||||
每条委托链必须通过三项验证:
|
||||
1. **签名有效性**:当前 Agent 的签名必须可被其公钥验证
|
||||
2. **作用域不扩大**:本跳授权的作用域不得宽于上一跳
|
||||
3. **时间有效性**:委托链中任意节点过期,则整链失效
|
||||
|
||||
## Fail-Closed Behavior
|
||||
|
||||
- 委托链的任意链节断裂 → **整链无效**
|
||||
- 委托链的任意节点过期 → **整链无效**
|
||||
- 无法验证某节点签名 → **整链无效**
|
||||
|
||||
## Relationships
|
||||
- [[Zero-Trust]]:Delegation-Chain 是 Zero-Trust 授权验证的核心机制
|
||||
- [[Fail-Closed]]:委托链验证采用 Fail-Closed 策略(任意断裂则整链失效)
|
||||
- [[Peer-Verification]]:Peer-Verification 协议在有委托时必须验证 Delegation-Chain
|
||||
|
||||
## Sources
|
||||
- [[agentic-identity-trust.md]]
|
||||
50
wiki/concepts/Dengbao-2.0.md
Normal file
50
wiki/concepts/Dengbao-2.0.md
Normal file
@@ -0,0 +1,50 @@
|
||||
---
|
||||
title: "Dengbao 2.0"
|
||||
type: concept
|
||||
tags: [China, cybersecurity, compliance, ToG, government]
|
||||
sources: [government-digital-presales-consultant]
|
||||
last_updated: 2026-04-25
|
||||
---
|
||||
|
||||
# Dengbao 2.0(网络安全等级保护)
|
||||
|
||||
网络安全等级保护制度(Classified Protection of Cybersecurity),是中国政府强制性的网络安全合规框架,要求所有政府信息系统按照安全等级进行保护和评估。
|
||||
|
||||
## 基本概念
|
||||
|
||||
- **等级划分**:1级(自主保护)→ 2级(指导保护)→ 3级(监督保护)→ 4级(强制保护)→ 5级(专控保护)
|
||||
- **政府系统要求**:通常要求**等保三级**,核心系统可能要求**等保四级**
|
||||
- **强制性质**:等保不是加分项,而是**投标入围的强制性前置条件**
|
||||
|
||||
## 等保三级核心控制域
|
||||
|
||||
| 安全域 | 控制要求 | Proposed Measure |
|
||||
|--------|---------|-----------------|
|
||||
| 安全通信网络 | 网络架构安全 | 安全域划分、VLAN 隔离 |
|
||||
| 安全通信网络 | 传输安全 | SM4 加密传输,国密 VPN 网关 |
|
||||
| 安全边界 | 边界防护 | 下一代防火墙访问控制策略 |
|
||||
| 安全边界 | 入侵防范 | IDS/IPS 部署 |
|
||||
| 安全计算环境 | 身份鉴别 | 双因素认证,国密 CA + 动态令牌 |
|
||||
| 安全计算环境 | 数据完整性 | SM3 校验,国密中间件 |
|
||||
| 安全计算环境 | 数据备份恢复 | 本地 + 异地备份 |
|
||||
| 安全管理中心 | 集中管理 | 统一安全管理平台,SIEM/SOC |
|
||||
| 安全管理中心 | 审计管理 | 日志集中采集分析 |
|
||||
|
||||
## 实施时间线
|
||||
|
||||
- **关键里程碑**:系统上线前必须完成等保评估
|
||||
- **整改周期**:通常需要 **2-3 个月**进行整改
|
||||
- **评估流程**:系统建设 → 差距分析 → 整改加固 → 正式评估 → 备案
|
||||
|
||||
## 与信创的关系
|
||||
|
||||
等保三级与[[Xinchuang]](信创)结合是政府项目的标准合规要求:
|
||||
- 信创适配产品(国产 CPU/OS/数据库/中间件)需提供兼容测试报告
|
||||
- 等保三级安全架构设计需在信创平台上重新验证
|
||||
- 两者共同构成政府 IT 项目投标的技术门槛
|
||||
|
||||
## Aliases
|
||||
- 网络安全等级保护
|
||||
- 等保 2.0
|
||||
- Classified Protection of Cybersecurity
|
||||
- Wangluo Anquan Dengji Baohu
|
||||
42
wiki/concepts/Evidence-Chain.md
Normal file
42
wiki/concepts/Evidence-Chain.md
Normal file
@@ -0,0 +1,42 @@
|
||||
---
|
||||
title: "Evidence-Chain"
|
||||
type: concept
|
||||
tags: [audit, security, tamper-detection]
|
||||
sources: [agentic-identity-trust.md]
|
||||
last_updated: 2026-04-25
|
||||
---
|
||||
|
||||
## Definition
|
||||
|
||||
Evidence-Chain(证据链)是一种仅追加(append-only)、链式哈希、防篡改的操作记录系统。每个证据记录包含:意图(intent)、决策(decision)、结果(outcome),并通过哈希链指向前一记录,形成完整操作审计链。
|
||||
|
||||
## Core Properties
|
||||
|
||||
- **仅追加**:历史记录不可修改,只能添加新记录
|
||||
- **链式哈希**:每个记录包含前一条记录的哈希值,篡改任意记录都会破坏链的完整性
|
||||
- **独立可验证**:任何第三方可以在不信任记录系统的前提下验证链的完整性
|
||||
- **防篡改检测**:链中任意记录被修改,后续所有哈希校验将失败
|
||||
|
||||
## Structure
|
||||
|
||||
```python
|
||||
{
|
||||
"agent_id": "trading-agent-prod-7a3f",
|
||||
"action_type": "trade.execute",
|
||||
"intent": {"symbol": "AAPL", "quantity": 100, "side": "buy"},
|
||||
"decision": "approved: scope verified, trust score 0.94",
|
||||
"outcome": {"filled": true, "price": 182.50, "order_id": "ord-xyz"},
|
||||
"timestamp_utc": "2026-03-01T14:30:00Z",
|
||||
"prev_record_hash": "0"*64,
|
||||
"record_hash": "sha256(...)",
|
||||
"signature": "Ed25519(agent_private_key, record_hash)"
|
||||
}
|
||||
```
|
||||
|
||||
## Relationships
|
||||
- [[Zero-Trust]]:Evidence-Chain 是 Zero-Trust 日志完整性的核心机制
|
||||
- [[Trust-Scoring]]:Trust-Scoring 的评分依据来源于 Evidence-Chain 的可验证结果
|
||||
- [[Algorithm-Agility]]:算法升级时需要保证历史证据链的可验证性
|
||||
|
||||
## Sources
|
||||
- [[agentic-identity-trust.md]]
|
||||
49
wiki/concepts/Evidence-based-Merge-Proposal.md
Normal file
49
wiki/concepts/Evidence-based-Merge-Proposal.md
Normal file
@@ -0,0 +1,49 @@
|
||||
---
|
||||
title: "Evidence-based Merge Proposal"
|
||||
type: concept
|
||||
tags: ["multi-agent", "identity", "coordination", "decision-making"]
|
||||
sources: ["identity-graph-operator"]
|
||||
last_updated: 2026-04-25
|
||||
---
|
||||
|
||||
# Evidence-based Merge Proposal(证据驱动合并提案)
|
||||
|
||||
## Definition
|
||||
多 Agent 身份协调中的标准提案协议——当发现两个实体应合并时,不直接执行 merge 操作,而是构造包含完整 per-field evidence 的提案,供其他 Agent 审查后再执行。
|
||||
|
||||
## Structure
|
||||
|
||||
```json
|
||||
{
|
||||
"entity_a_id": "a1b2c3d4-...",
|
||||
"entity_b_id": "e5f6g7h8-...",
|
||||
"confidence": 0.87,
|
||||
"evidence": {
|
||||
"email_match": { "score": 1.0, "values": ["wsmith@acme.com", "wsmith@acme.com"] },
|
||||
"name_match": { "score": 0.82, "values": ["William Smith", "Bill Smith"] },
|
||||
"phone_match": { "score": 1.0, "values": ["+155****0142", "+155****0142"] },
|
||||
"reasoning": "Same email and phone. Name differs but 'Bill' is a known nickname for 'William'."
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## When to Propose vs. Direct Merge
|
||||
|
||||
| 场景 | 动作 | 原因 |
|
||||
|------|------|------|
|
||||
| 单 Agent,置信度 > 0.95 | 直接合并 | 无歧义,无其他 Agent 需协商 |
|
||||
| 多 Agent,置信度中等 | 提案合并 | 让其他 Agent 审查证据 |
|
||||
| Agent 不同意既有合并 | 提案拆分(含 member_ids) | 不直接撤销,由多方验证 |
|
||||
| 修正数据字段 | 带 expected_version 的直接变更 | 字段更新无需多 Agent 审查 |
|
||||
|
||||
## Core Principles
|
||||
- **永远不带证据不合并**:"These look similar" 不是证据,per-field comparison scores + confidence thresholds 才是证据
|
||||
- **提案优于断言**:提出 merge(带证据)而非直接执行,让对方 Agent 有机会审查
|
||||
- **反压不覆盖**:当 Agent 间存在冲突(一个提出 merge,另一个提出 split),不直接覆盖另一方证据,而是呈现反证据让最强证据胜出
|
||||
|
||||
## Conflict Resolution
|
||||
当两个 Agent 对同一对实体给出矛盾提案时:
|
||||
1. 标记为 `conflict` 状态
|
||||
2. 双方添加评论讨论证据
|
||||
3. 等待人类或仲裁 Agent 最终裁决
|
||||
4. 永不通过"强行覆盖"解决冲突
|
||||
36
wiki/concepts/Fail-Closed.md
Normal file
36
wiki/concepts/Fail-Closed.md
Normal file
@@ -0,0 +1,36 @@
|
||||
---
|
||||
title: "Fail-Closed"
|
||||
type: concept
|
||||
tags: [authorization, security, default-deny]
|
||||
sources: [agentic-identity-trust.md]
|
||||
last_updated: 2026-04-25
|
||||
---
|
||||
|
||||
## Definition
|
||||
|
||||
Fail-Closed(故障关闭)是一种安全授权策略——当验证系统无法完成验证时,默认结果为**拒绝**,而非**允许**。这是 Zero-Trust 架构的必然推论。
|
||||
|
||||
## Fail-Closed Rules
|
||||
|
||||
| 验证失败场景 | 默认行为 |
|
||||
|------------|---------|
|
||||
| 身份无法验证 | 拒绝操作 |
|
||||
| 委托链存在断裂 | 拒绝操作 |
|
||||
| 证据无法写入 | 拒绝操作 |
|
||||
| 信任评分低于阈值 | 要求重新验证,拒绝操作 |
|
||||
| 凭证已过期 | 拒绝操作 |
|
||||
|
||||
## vs. Fail-Open
|
||||
|
||||
| 策略 | 无法验证时的行为 | 适用场景 |
|
||||
|------|----------------|---------|
|
||||
| **Fail-Closed**(本文档) | 拒绝操作 | 高风险操作(金融交易、基础设施部署、物理控制) |
|
||||
| **Fail-Open** | 允许操作 | 低风险操作(读操作、内部服务调用) |
|
||||
|
||||
## Relationships
|
||||
- [[Zero-Trust]]:Fail-Closed 是 Zero-Trust 默认不信任原则的具体化
|
||||
- [[Delegation-Chain]]:委托链验证采用 Fail-Closed 策略
|
||||
- [[Peer-Verification]]:Peer 验证的所有检查均采用 Fail-Closed
|
||||
|
||||
## Sources
|
||||
- [[agentic-identity-trust.md]]
|
||||
57
wiki/concepts/Fuzzy-Matching.md
Normal file
57
wiki/concepts/Fuzzy-Matching.md
Normal file
@@ -0,0 +1,57 @@
|
||||
---
|
||||
title: "Fuzzy Matching"
|
||||
type: concept
|
||||
tags: ["identity-resolution", "string-similarity", "normalization", "entity-matching"]
|
||||
sources: ["identity-graph-operator"]
|
||||
last_updated: 2026-04-25
|
||||
---
|
||||
|
||||
# Fuzzy Matching(模糊匹配)
|
||||
|
||||
## Definition
|
||||
处理"相同实体但文本表达不同"记录的能力——通过规范化(Normalization)和相似度算法,将表面不同的记录识别为同一实体。是身份解析的核心挑战之一。
|
||||
|
||||
## Core Techniques
|
||||
|
||||
### 1. Nickname Normalization
|
||||
```python
|
||||
nicknames = {
|
||||
"bill": "william", "bob": "robert", "jim": "james",
|
||||
"mike": "michael", "dave": "david", "joe": "joseph",
|
||||
"tom": "thomas", "dick": "richard", "jack": "john",
|
||||
}
|
||||
# "Bill Smith" → "william smith"
|
||||
```
|
||||
|
||||
### 2. String Similarity
|
||||
| 算法 | 适用场景 |
|
||||
|------|----------|
|
||||
| Levenshtein Distance | 字符级编辑距离 |
|
||||
| Jaro-Winkler | 人名高权重前缀匹配 |
|
||||
| Soundex / Metaphone | 语音相似性("Jon" = "John") |
|
||||
| Token-based(TF-IDF) | 多词短语 |
|
||||
|
||||
### 3. Field-specific Normalization
|
||||
| 字段类型 | 规范化规则 |
|
||||
|----------|------------|
|
||||
| Email | `lower().strip()` |
|
||||
| Phone | `re.sub(r"[^\d+]", "", value)` → E.164 格式 |
|
||||
| Name | Nickname expansion + lowercase |
|
||||
| Address | Street abbreviation(St→Street)、directionals(NE→Northeast) |
|
||||
|
||||
## Example
|
||||
```
|
||||
记录A: "Bill Smith", wsmith@acme.com, +1-555-0142
|
||||
记录B: "William Smith", wsmith@acme.com, +15550142
|
||||
↓ Normalize + Score
|
||||
Email: 1.0(exact match)
|
||||
Name: 0.82(Bill→William nickname expansion)
|
||||
Phone: 1.0(E.164 normalized)
|
||||
────────────────────────────────
|
||||
Total: 0.94 confidence → 触发自动 merge(> 0.95 阈值接近)
|
||||
```
|
||||
|
||||
## Relationship to Related Concepts
|
||||
- [[Fuzzy-Matching]] 是 [[Identity-Resolution]] scoring 层的核心技术
|
||||
- [[Blocking]] 筛选候选对后,[[Fuzzy-Matching]] 执行细粒度字段比较
|
||||
- [[Confidence-Score]] 综合所有字段的 fuzzy match scores 得出最终决策
|
||||
43
wiki/concepts/Identity-Resolution.md
Normal file
43
wiki/concepts/Identity-Resolution.md
Normal file
@@ -0,0 +1,43 @@
|
||||
---
|
||||
title: "Identity Resolution"
|
||||
type: concept
|
||||
tags: ["identity", "entity-resolution", "multi-agent", "data-matching"]
|
||||
sources: ["identity-graph-operator"]
|
||||
last_updated: 2026-04-25
|
||||
---
|
||||
|
||||
# Identity Resolution(身份解析)
|
||||
|
||||
## Definition
|
||||
将来自不同来源的多条记录归一化为同一 **canonical entity_id** 的过程——确保同一个真实世界实体(人/公司/产品)在系统中只对应一个唯一标识符,所有 Agent 共享这一规范视图。
|
||||
|
||||
## Core Workflow
|
||||
|
||||
```
|
||||
原始记录 → 规范化(Normalize) → 阻塞(Blocking) → 评分(Scoring) → 聚类(Clustering) → Canonical Entity
|
||||
```
|
||||
|
||||
1. **规范化**:邮箱小写、电话 E.164 格式、昵称扩展(Bill→William)
|
||||
2. **阻塞**:用 blocking key(email domain / phone prefix / name soundex)快速筛选候选对,避免 O(n²) 全图扫描
|
||||
3. **评分**:字段级加权相似度(email exact match = 1.0,name fuzzy = 0.82)
|
||||
4. **聚类**:高置信度候选归入同一 cluster,生成 canonical entity_id
|
||||
|
||||
## Key Properties
|
||||
- **确定性**:相同输入必须返回相同 entity_id(由 Identity Graph Operator 强制执行)
|
||||
- **证据驱动**:每条合并决策必须有 per-field evidence,拒绝"看起来相似"断言
|
||||
- **并发安全**:通过乐观锁(version field)防止并发写入冲突
|
||||
- **可审计**:完整事件历史(entity.created / merged / split / updated)
|
||||
|
||||
## Confidence Thresholds
|
||||
| 置信度 | 操作 |
|
||||
|--------|------|
|
||||
| > 0.95 | 直接合并(单 Agent 高置信) |
|
||||
| 0.60–0.95 | 提案审查(多 Agent 协作) |
|
||||
| < 0.60 | 创建新实体 |
|
||||
|
||||
## Relationship to Related Concepts
|
||||
- [[Identity Resolution]] ⊂ [[Master-Data-Management]](MDM):身份解析是 MDM 在多 Agent 系统中的分布式实现,增加了并发协调维度
|
||||
- [[Identity Resolution]] 应用层:[[Personal CRM]] 联系人去重、[[Identity-Graph-Operator]] 企业级多 Agent 协调
|
||||
|
||||
## Related Agents
|
||||
- [[identity-graph-operator]]:Identity Resolution 能力在多 Agent 系统中的 Agent 化封装
|
||||
54
wiki/concepts/Miping.md
Normal file
54
wiki/concepts/Miping.md
Normal file
@@ -0,0 +1,54 @@
|
||||
---
|
||||
title: "Miping"
|
||||
type: concept
|
||||
tags: [China, cryptography, compliance, ToG, government, SM2, SM3, SM4]
|
||||
sources: [government-digital-presales-consultant]
|
||||
last_updated: 2026-04-25
|
||||
---
|
||||
|
||||
# Miping(商用密码应用安全性评估)
|
||||
|
||||
商用密码应用安全性评估(Commercial Cryptographic Application Security Assessment),是中国政府对涉及密码使用的信息系统进行强制性安全评估的合规制度。
|
||||
|
||||
## 基本概念
|
||||
|
||||
- **全称**:商用密码应用安全性评估
|
||||
- **拼音缩写**:密评(Mìpíng)
|
||||
- **主管机构**:国家密码管理局
|
||||
- **强制性质**:政府系统涉及密码应用的上线**前置条件**,验收必须提供密评报告
|
||||
|
||||
## 强制使用场景
|
||||
|
||||
涉及以下场景的政府系统**必须使用国密算法**:
|
||||
1. **身份认证**:用户身份鉴别、单点登录
|
||||
2. **数据传输**:系统间 API 通信、数据同步
|
||||
3. **数据存储**:敏感数据加密存储
|
||||
4. **电子签章**:电子印章、CA 证书
|
||||
|
||||
## 国密算法体系
|
||||
|
||||
| 算法类型 | 算法名称 | 用途 |
|
||||
|---------|---------|------|
|
||||
| 非对称加密 | SM2 | 密钥交换、数字签名 |
|
||||
| 哈希算法 | SM3 | 数据完整性校验 |
|
||||
| 对称加密 | SM4 | 数据加密传输和存储 |
|
||||
|
||||
## 密评要求
|
||||
|
||||
- 电子印章和 CA 证书必须使用**国密证书**
|
||||
- 密码产品必须通过国家密码管理局审批
|
||||
- 密评报告是系统验收的**必要文件**
|
||||
|
||||
## 与等保的关系
|
||||
|
||||
- [[Dengbao-2.0]](等保)和 Miping 是政府 IT 系统的两项**并列合规要求**
|
||||
- 等保关注整体安全架构,Miping 专注于密码应用正确性
|
||||
- 两者在投标时通常作为独立章节分别论述
|
||||
|
||||
## Aliases
|
||||
- 商用密码应用安全性评估
|
||||
- 密评
|
||||
- Shangmi Yingyong Anquan Xing Pinggu
|
||||
- Commercial Cryptographic Application Security Assessment
|
||||
- 国密算法(SM2/SM3/SM4)
|
||||
- Guomi Algorithms
|
||||
58
wiki/concepts/Peer-Verification.md
Normal file
58
wiki/concepts/Peer-Verification.md
Normal file
@@ -0,0 +1,58 @@
|
||||
---
|
||||
title: "Peer-Verification"
|
||||
type: concept
|
||||
tags: [verification, authentication, protocol]
|
||||
sources: [agentic-identity-trust.md]
|
||||
last_updated: 2026-04-25
|
||||
---
|
||||
|
||||
## Definition
|
||||
|
||||
Peer-Verification(对等验证)是一种 Agent 间在接受委托工作前互相验证身份和授权的安全协议。在 Agent 接受来自其他 Agent 的工作请求前,必须完成五项独立验证——全部通过才接受工作。
|
||||
|
||||
## Verification Checks
|
||||
|
||||
```python
|
||||
checks = {
|
||||
"identity_valid": # 1. 密码学身份证明是否有效
|
||||
"credential_current": # 2. 凭证是否在有效期内
|
||||
"scope_sufficient": # 3. 授权范围是否覆盖请求的操作
|
||||
"trust_above_threshold": # 4. 信任评分是否 ≥ 0.5
|
||||
"delegation_chain_valid": # 5. 委托链是否完整(如涉及委托)
|
||||
}
|
||||
# 全部通过才接受工作(Fail-Closed)
|
||||
```
|
||||
|
||||
## Protocol Flow
|
||||
|
||||
```
|
||||
Agent A Agent B
|
||||
│ │
|
||||
│──── request_work ─────────>│
|
||||
│ │
|
||||
│<--- identity_proof -------│ (Agent B 提供公钥 + 签名)
|
||||
│<--- credential -----------│ (Agent B 提供凭证 + 过期时间)
|
||||
│<--- delegation_chain -----│ (如为委托工作)
|
||||
│ │
|
||||
│ 验证身份 → 验证凭证 → 验证作用域 → 验证信任分 → 验证委托链
|
||||
│ │
|
||||
│<--- verification_result --│
|
||||
│ │
|
||||
if all_passed:
|
||||
Agent A 接受 Agent B 的工作
|
||||
else:
|
||||
Agent A 拒绝 Agent B 的工作
|
||||
```
|
||||
|
||||
## Performance Requirement
|
||||
|
||||
- **P99 延迟 < 50ms**:验证过程不得成为系统性能瓶颈
|
||||
|
||||
## Relationships
|
||||
- [[Zero-Trust]]:Peer-Verification 是 Zero-Trust 在 Agent 间交互中的实现
|
||||
- [[Trust-Scoring]]:Trust-Scoring 提供 Peer-Verification 的决策依据
|
||||
- [[Delegation-Chain]]:当 Agent 间存在委托关系时,Peer-Verification 必须验证 Delegation-Chain
|
||||
- [[Fail-Closed]]:所有检查项均采用 Fail-Closed 策略
|
||||
|
||||
## Sources
|
||||
- [[agentic-identity-trust.md]]
|
||||
54
wiki/concepts/Trust-Scoring.md
Normal file
54
wiki/concepts/Trust-Scoring.md
Normal file
@@ -0,0 +1,54 @@
|
||||
---
|
||||
title: "Trust-Scoring"
|
||||
type: concept
|
||||
tags: [trust, scoring, agent-reliability]
|
||||
sources: [agentic-identity-trust.md]
|
||||
last_updated: 2026-04-25
|
||||
---
|
||||
|
||||
## Definition
|
||||
|
||||
Trust-Scoring 是一种基于**可验证结果**的惩罚型信任量化模型。Agent 从初始分数 1.0 开始,仅通过可客观验证的问题进行扣分;Agent 不得自我报告信号来提高信任分。
|
||||
|
||||
## Scoring Model
|
||||
|
||||
```python
|
||||
score = 1.0
|
||||
|
||||
# 证据链损坏(最高惩罚)
|
||||
if not check_chain_integrity(agent_id):
|
||||
score -= 0.5
|
||||
|
||||
# 结果验证(失败率 × 0.4)
|
||||
outcomes = get_verified_outcomes(agent_id)
|
||||
if outcomes.total > 0:
|
||||
failure_rate = 1.0 - (outcomes.achieved / outcomes.total)
|
||||
score -= failure_rate * 0.4
|
||||
|
||||
# 凭证新鲜度
|
||||
if credential_age_days(agent_id) > 90:
|
||||
score -= 0.1
|
||||
```
|
||||
|
||||
## Trust Levels
|
||||
|
||||
| 分数区间 | 信任等级 | 说明 |
|
||||
|---------|---------|------|
|
||||
| ≥ 0.9 | HIGH | 完全可信任,可执行高风险操作 |
|
||||
| ≥ 0.5 | MODERATE | 有限信任,需额外验证 |
|
||||
| > 0.0 | LOW | 高度谨慎,需全面验证 |
|
||||
| 0.0 | NONE | 不可信,拒绝所有操作请求 |
|
||||
|
||||
## Key Properties
|
||||
|
||||
- **无自我报告**:Agent 不能声称自己是可信的——信任来自客观可验证的证据
|
||||
- **信任衰减**:长期未活动的 Agent 或过期凭证自动降低信任分
|
||||
- **证据驱动**:评分基于 [[Evidence-Chain]] 中的实际执行结果,而非声誉或声明
|
||||
|
||||
## Relationships
|
||||
- [[Zero-Trust]]:Trust-Scoring 是 Zero-Trust 可量化验证的实现
|
||||
- [[Evidence-Chain]]:Trust-Scoring 的评分依据来源
|
||||
- [[Peer-Verification]]:Peer-Verification 协议使用 Trust-Scoring 作为决策依据之一
|
||||
|
||||
## Sources
|
||||
- [[agentic-identity-trust.md]]
|
||||
65
wiki/concepts/Xinchuang.md
Normal file
65
wiki/concepts/Xinchuang.md
Normal file
@@ -0,0 +1,65 @@
|
||||
---
|
||||
title: "Xinchuang"
|
||||
type: concept
|
||||
tags: [China, domestic-IT, localization, ToG, government, Kunpeng, Phytium, UOS]
|
||||
sources: [government-digital-presales-consultant]
|
||||
last_updated: 2026-04-25
|
||||
---
|
||||
|
||||
# Xinchuang(信息技术应用创新)
|
||||
|
||||
信息技术应用创新(Xìnxì Jìshù Yìngyòng Chuàngxīn),是中国政府推动的 IT 基础设施国产化替代战略,旨在用国产技术和产品替代国外产品,确保关键信息系统的自主可控。
|
||||
|
||||
## 全称
|
||||
|
||||
- **中文**:信息技术应用创新
|
||||
- **拼音**:Xinchuang / Xìnchuàng
|
||||
- **英文**:Innovation in Information Technology
|
||||
|
||||
## 核心替代领域
|
||||
|
||||
| 层级 | 国外产品 | 国产替代 |
|
||||
|-----|---------|---------|
|
||||
| CPU 芯片 | Intel Xeon / AMD EPYC | 鲲鹏(Kunpeng 920)/ 飞腾(Phytium S2500)/ 海光 / 龙芯 |
|
||||
| 操作系统 | Windows Server / CentOS | 统信 UOS / 银河麒麟(Kylin) |
|
||||
| 数据库 | Oracle / MySQL / PostgreSQL | 达梦(DM)/ 人大金仓(KingbaseES)/ GaussDB |
|
||||
| 中间件 | Tomcat / JBoss / WebLogic | 东方通(TongWeb)/ 宝兰德(BES) |
|
||||
| 办公软件 | MS Office | WPS Office / 永中 Office |
|
||||
|
||||
## 适配策略
|
||||
|
||||
- **优先采用目录内产品**:选择进入信创产品目录的主流产品
|
||||
- **兼容性测试矩阵**:建立完整的产品兼容测试矩阵(CPU×OS×数据库×中间件)
|
||||
- **分阶段替代**:并非所有组件都需要立即替代,分阶段替代是被接受的
|
||||
- **信创适配认证**:需提供适配认证报告和兼容性测试证明
|
||||
|
||||
## 信创适配检查清单
|
||||
|
||||
| 层级 | 组件 | 当前产品 | 信创替代方案 | 兼容性测试 | 优先级 |
|
||||
|-----|-----|---------|------------|-----------|-------|
|
||||
| Chip | CPU | Intel Xeon | Kunpeng 920 / Phytium S2500 | | P0 |
|
||||
| OS | 服务器 OS | CentOS 7 | UnionTech UOS V20 / Kylin V10 | | P0 |
|
||||
| Database | RDBMS | MySQL / Oracle | DM8 / KingbaseES | | P0 |
|
||||
| Middleware | 应用服务器 | Tomcat | TongWeb / BES | | P1 |
|
||||
| Middleware | 消息队列 | RabbitMQ | 国产替代方案 | | P2 |
|
||||
| Office | 办公套件 | MS Office | WPS / Yozo Office | | P1 |
|
||||
|
||||
## 实施原则
|
||||
|
||||
1. **不是加分项,而是必选项**:信创是政府 IT 项目的强制性要求
|
||||
2. **不是一步到位**:允许分阶段实施,优先替换核心组件
|
||||
3. **必须提供测试报告**:兼容性测试报告是投标文件的必要附件
|
||||
4. **与等保协同**:信创平台需重新进行 [[Dengbao-2.0]] 安全架构验证
|
||||
|
||||
## Aliases
|
||||
- 信创
|
||||
- 信息技术应用创新
|
||||
- Xinchuang
|
||||
- Xìnchuàng
|
||||
- 国产化替代
|
||||
- Domestic IT Substitution
|
||||
- IT Localization
|
||||
- Kunpeng(鲲鹏)
|
||||
- Phytium(飞腾)
|
||||
- UnionTech UOS(统信 UOS)
|
||||
- DM Database(达梦数据库)
|
||||
35
wiki/concepts/Zero-Trust.md
Normal file
35
wiki/concepts/Zero-Trust.md
Normal file
@@ -0,0 +1,35 @@
|
||||
---
|
||||
title: "Zero-Trust"
|
||||
type: concept
|
||||
tags: [security, identity, authorization]
|
||||
sources: [agentic-identity-trust.md]
|
||||
last_updated: 2026-04-25
|
||||
---
|
||||
|
||||
## Definition
|
||||
|
||||
Zero-Trust 是一种安全架构范式——**永不信任,必须验证**(Never Trust, Always Verify)。在多 Agent 系统中,该原则要求每个 Agent 在执行操作前必须提供密码学可验证的身份证明,而非依赖自我声明。
|
||||
|
||||
## Core Principles
|
||||
|
||||
- **身份与授权分离**:证明"我是谁"(身份验证)与证明"我被允许做这个"(授权验证)是两个独立步骤。
|
||||
- **最小权限原则**:Agent 仅被授予完成特定任务所需的最小权限范围。
|
||||
- **假设已失陷**:设计时假设网络中至少有一个 Agent 已失陷或被错误配置。
|
||||
- **显式验证**:每次交互都必须进行验证,不能依赖先前交互的信任状态。
|
||||
|
||||
## Application in Multi-Agent Systems
|
||||
|
||||
| 层面 | Zero-Trust 要求 |
|
||||
|------|----------------|
|
||||
| 身份验证 | Agent 必须提供密码学签名证明,而非声称身份 |
|
||||
| 授权验证 | 必须提供可验证的委托链,而非声称"我被授权了" |
|
||||
| 日志完整性 | 日志写入者不得同时具备修改日志的能力 |
|
||||
| 跨框架互操作 | 每个框架的信任模型必须可被其他框架独立验证 |
|
||||
|
||||
## Relationships
|
||||
- [[Evidence-Chain]]:Zero-Trust 日志层的实现机制
|
||||
- [[Trust-Scoring]]:Zero-Trust 信任评估的量化手段
|
||||
- [[Fail-Closed]]:Zero-Trust 失败时的默认行为
|
||||
|
||||
## Sources
|
||||
- [[agentic-identity-trust.md]]
|
||||
@@ -4,6 +4,11 @@
|
||||
- [Overview](overview.md) — living synthesis
|
||||
|
||||
## Sources
|
||||
- [2026-04-24] [Government Digital Presales Consultant](sources/government-digital-presales-consultant.md)
|
||||
- [2026-04-24] [Agentic Identity & Trust Architect](sources/agentic-identity-trust.md)
|
||||
- [2026-04-24] [Document Generator Agent](sources/specialized-document-generator.md)
|
||||
- [2026-04-24] [Identity Graph Operator](sources/identity-graph-operator.md)
|
||||
- [2026-04-24] [Accounts Payable Agent Personality](sources/accounts-payable-agent.md)
|
||||
- [2026-04-24] [Recruitment Specialist Agent](sources/recruitment-specialist.md)
|
||||
- [2026-04-24] [Specialized Civil Engineer Agent](sources/specialized-civil-engineer.md)
|
||||
- [2026-04-24] [Experiment Tracker Agent Personality](sources/project-management-experiment-tracker.md)
|
||||
@@ -408,11 +413,6 @@
|
||||
- [2026-04-20] [healthcare-marketing-compliance](sources/healthcare-marketing-compliance.md) — (expected: wiki/sources/healthcare-marketing-compliance.md — source missing)
|
||||
- [2026-04-20] [llm-wiki](sources/llm-wiki.md) — (expected: wiki/sources/llm-wiki.md — source missing)
|
||||
- [2026-04-20] [specialized-workflow-architect](sources/specialized-workflow-architect.md) — (expected: wiki/sources/specialized-workflow-architect.md — source missing)
|
||||
- [2026-04-20] [government-digital-presales-consultant](sources/government-digital-presales-consultant.md) — (expected: wiki/sources/government-digital-presales-consultant.md — source missing)
|
||||
- [2026-04-20] [agentic-identity-trust](sources/agentic-identity-trust.md) — (expected: wiki/sources/agentic-identity-trust.md — source missing)
|
||||
- [2026-04-20] [specialized-document-generator](sources/specialized-document-generator.md) — (expected: wiki/sources/specialized-document-generator.md — source missing)
|
||||
- [2026-04-20] [identity-graph-operator](sources/identity-graph-operator.md) — (expected: wiki/sources/identity-graph-operator.md — source missing)
|
||||
- [2026-04-20] [accounts-payable-agent](sources/accounts-payable-agent.md) — (expected: wiki/sources/accounts-payable-agent.md — source missing)
|
||||
- [2026-04-20] [baoyu-skills](sources/baoyu-skills.md) — (expected: wiki/sources/baoyu-skills.md — source missing)
|
||||
- [Your-AI-Isn-t-Stupid---It-Just-Needs-a-Better-Harness--Lychee-Technology-Engineering-Blog](sources/Your-AI-Isn-t-Stupid---It-Just-Needs-a-Better-Harness--Lychee-Technology-Engineering-Blog.md) — (expected: wiki/sources/Your-AI-Isn-t-Stupid---It-Just-Needs-a-Better-Harness--Lychee-Technology-Engineering-Blog.md — source missing)
|
||||
- [Expose-hermes-agent-as-an-OpenAI-compatible-API-for-any-frontend](sources/Expose-hermes-agent-as-an-OpenAI-compatible-API-for-any-frontend.md) — (expected: wiki/sources/Expose-hermes-agent-as-an-OpenAI-compatible-API-for-any-frontend.md — source missing)
|
||||
@@ -826,6 +826,7 @@
|
||||
- [AI文生视频](concepts/AI文生视频.md)
|
||||
- [AI簡報工作流](concepts/AI簡報工作流.md)
|
||||
- [Alerting](concepts/Alerting.md)
|
||||
- [Algorithm-Agility](concepts/Algorithm-Agility.md)
|
||||
- [Amazon-EKS](concepts/Amazon-EKS.md)
|
||||
- [AmbientMessageMonitoring](concepts/AmbientMessageMonitoring.md)
|
||||
- [Analogy-as-Straitjacket](concepts/Analogy-as-Straitjacket.md)
|
||||
@@ -846,6 +847,7 @@
|
||||
- [BEATS](concepts/BEATS.md)
|
||||
- [BindMount](concepts/BindMount.md)
|
||||
- [BI平台](concepts/BI平台.md)
|
||||
- [Blocking](concepts/Blocking.md)
|
||||
- [Blue-Green-Deployment](concepts/Blue-Green-Deployment.md)
|
||||
- [BOOTSTRAP.md](concepts/BOOTSTRAP.md.md)
|
||||
- [Brain-Dump](concepts/Brain-Dump.md)
|
||||
@@ -900,6 +902,7 @@
|
||||
- [Compaction](concepts/Compaction.md)
|
||||
- [Competition-Analysis](concepts/Competition-Analysis.md)
|
||||
- [Compliance-Automation](concepts/Compliance-Automation.md)
|
||||
- [Confidence-Score](concepts/Confidence-Score.md)
|
||||
- [Configuration-Management](concepts/Configuration-Management.md)
|
||||
- [Consensus-Voting-Pattern](concepts/Consensus-Voting-Pattern.md)
|
||||
- [Constraint-Driven-Control-Mechanics](concepts/Constraint-Driven-Control-Mechanics.md)
|
||||
@@ -935,8 +938,10 @@
|
||||
- [DealHealthScoring](concepts/DealHealthScoring.md)
|
||||
- [Defense-in-Depth](concepts/Defense-in-Depth.md)
|
||||
- [Defuddle](concepts/Defuddle.md)
|
||||
- [Delegation-Chain](concepts/Delegation-Chain.md)
|
||||
- [Delivery-Traceability](concepts/Delivery-Traceability.md)
|
||||
- [Demo-Engineering](concepts/Demo-Engineering.md)
|
||||
- [Dengbao-2.0](concepts/Dengbao-2.0.md)
|
||||
- [Dependency-Management](concepts/Dependency-Management.md)
|
||||
- [Deployment-Automation](concepts/Deployment-Automation.md)
|
||||
- [Deployment-vs-Release](concepts/Deployment-vs-Release.md)
|
||||
@@ -978,10 +983,13 @@
|
||||
- [Event-Correlation](concepts/Event-Correlation.md)
|
||||
- [Event-Driven-Architecture](concepts/Event-Driven-Architecture.md)
|
||||
- [EventSourcing](concepts/EventSourcing.md)
|
||||
- [Evidence-based-Merge-Proposal](concepts/Evidence-based-Merge-Proposal.md)
|
||||
- [Evidence-Chain](concepts/Evidence-Chain.md)
|
||||
- [Expert-User-Assumption](concepts/Expert-User-Assumption.md)
|
||||
- [Exporter](concepts/Exporter.md)
|
||||
- [Extended Thinking](concepts/Extended Thinking.md)
|
||||
- [external配置](concepts/external配置.md)
|
||||
- [Fail-Closed](concepts/Fail-Closed.md)
|
||||
- [Failover](concepts/Failover.md)
|
||||
- [Feature-Flag](concepts/Feature-Flag.md)
|
||||
- [FeatureList](concepts/FeatureList.md)
|
||||
@@ -994,6 +1002,7 @@
|
||||
- [Food-Sensitivity-Tracking](concepts/Food-Sensitivity-Tracking.md)
|
||||
- [Full-Draft-Generation](concepts/Full-Draft-Generation.md)
|
||||
- [Full-Funnel-Campaign-Architecture](concepts/Full-Funnel-Campaign-Architecture.md)
|
||||
- [Fuzzy-Matching](concepts/Fuzzy-Matching.md)
|
||||
- [Gatekeeper](concepts/Gatekeeper.md)
|
||||
- [GDM3](concepts/GDM3.md)
|
||||
- [Generalist](concepts/Generalist.md)
|
||||
@@ -1027,6 +1036,7 @@
|
||||
- [Idea-Density](concepts/Idea-Density.md)
|
||||
- [Idea-Museum](concepts/Idea-Museum.md)
|
||||
- [Identity-Governance](concepts/Identity-Governance.md)
|
||||
- [Identity-Resolution](concepts/Identity-Resolution.md)
|
||||
- [IDENTITY.md](concepts/IDENTITY.md.md)
|
||||
- [Ikigai框架](concepts/Ikigai框架.md)
|
||||
- [Immutable-Infrastructure](concepts/Immutable-Infrastructure.md)
|
||||
@@ -1080,6 +1090,7 @@
|
||||
- [MEMORY.md](concepts/MEMORY.md.md)
|
||||
- [MessageMatch](concepts/MessageMatch.md)
|
||||
- [Micro-Recovery](concepts/Micro-Recovery.md)
|
||||
- [Miping](concepts/Miping.md)
|
||||
- [Model-Context-Protocol](concepts/Model-Context-Protocol.md)
|
||||
- [Model-Fallback](concepts/Model-Fallback.md)
|
||||
- [Morning-Briefing](concepts/Morning-Briefing.md)
|
||||
@@ -1119,6 +1130,7 @@
|
||||
- [Passive-Learning](concepts/Passive-Learning.md)
|
||||
- [passkey](concepts/passkey.md)
|
||||
- [Pay-as-you-go](concepts/Pay-as-you-go.md)
|
||||
- [Peer-Verification](concepts/Peer-Verification.md)
|
||||
- [Penetration-Testing](concepts/Penetration-Testing.md)
|
||||
- [PerformanceMax](concepts/PerformanceMax.md)
|
||||
- [Personal-CRM](concepts/Personal-CRM.md)
|
||||
@@ -1277,6 +1289,7 @@
|
||||
- [Transcript-Based-Summarization](concepts/Transcript-Based-Summarization.md)
|
||||
- [TranscriptProcessing](concepts/TranscriptProcessing.md)
|
||||
- [Tree-of-Thoughts](concepts/Tree-of-Thoughts.md)
|
||||
- [Trust-Scoring](concepts/Trust-Scoring.md)
|
||||
- [tui](concepts/tui.md)
|
||||
- [Tutor-Skills](concepts/Tutor-Skills.md)
|
||||
- [Two-Way-Voice-Conversation](concepts/Two-Way-Voice-Conversation.md)
|
||||
@@ -1309,8 +1322,10 @@
|
||||
- [Workflow-Engineering](concepts/Workflow-Engineering.md)
|
||||
- [Workspace](concepts/Workspace.md)
|
||||
- [X11](concepts/X11.md)
|
||||
- [Xinchuang](concepts/Xinchuang.md)
|
||||
- [Y-Combinator](concepts/Y-Combinator.md)
|
||||
- [Zero-Friction-Capture](concepts/Zero-Friction-Capture.md)
|
||||
- [Zero-Trust](concepts/Zero-Trust.md)
|
||||
- [Zero-Trust-Architecture](concepts/Zero-Trust-Architecture.md)
|
||||
- [一人公司](concepts/一人公司.md)
|
||||
- [上下文刷新](concepts/上下文刷新.md)
|
||||
|
||||
38
wiki/log.md
38
wiki/log.md
@@ -1,3 +1,33 @@
|
||||
## [2026-04-25] ingest | Agentic Identity & Trust Architect(补充摄入)
|
||||
- Source file: Agent/agency-agents/specialized/agentic-identity-trust.md
|
||||
- Status: ✅ 补充摄入(source page 已存在,本次补充 Concept 页面)
|
||||
- Summary: Agentic Identity & Trust Architect——自主 Agent 身份认证与信任验证基础设施专家 Agent,解决多 Agent 环境中的身份伪造、授权冒用、审计日志篡改等安全威胁。核心方法:密码学身份体系(Ed25519)、零信任验证模型、惩罚型信任评分(初始1.0,证据链损坏扣0.5,结果失败率×0.4扣分,凭证超90天扣0.1)、append-only 哈希链式证据记录、多跳委托链验证(任意链节断裂则全链失效)、Fail-Closed 授权(无法验证时默认拒绝)、对等验证协议(Peer Verifier)。高级能力:算法敏捷性(后量子迁移预留抽象层)、NIST 后量子标准评估(ML-DSA/ML-KEM/SLH-DSA)、跨框架身份联邦(A2A/MCP/REST/SDK)。
|
||||
- Concepts created: [[Zero-Trust]](永不信任,必须验证)、[[Evidence-Chain]](哈希链式仅追加证据记录)、[[Trust-Scoring]](基于可验证结果的惩罚型信任评分)、[[Delegation-Chain]](多跳委托链验证)、[[Fail-Closed]](失败默认拒绝授权)、[[Peer-Verification]](对等验证协议)、[[Algorithm-Agility]](密码学算法可升级性)
|
||||
- Source page: wiki/sources/agentic-identity-trust.md
|
||||
- Notes: 与 [[Identity Graph Operator]] 互补——前者处理 Agent 身份证明(密码学确定性),后者处理实体身份匹配(概率性),共同构成完整身份层。与 [[Designing-for-Agentic-AI]] 存在潜在冲突(零信任要求确定性 vs LLM 概率性),已在 Contradictions 中记录。本文件在 index.md中原标记为"source missing",本次已补全为完整 source page。
|
||||
- Source file: Agent/agency-agents/specialized/specialized-document-generator.md
|
||||
- Status: ✅ 成功摄入
|
||||
- Summary: Document Generator——The Agency Specialized 部门的程序化文档生成专家 Agent,通过代码方式(Python/Node.js)生成 PDF、PPTX、DOCX、XLSX 等专业文档。核心工具栈:PDF(reportlab/weasyprint/fpdf2)、PPTX(python-pptx/pptxgenjs)、XLSX(openpyxl/xlsxwriter/exceljs)、DOCX(python-docx/docx)。核心原则:样式系统优先、品牌一致性、数据驱动、无障碍设计、模板可复用。
|
||||
- Concepts created: 无(文档生成工具库不宜抽象为 Concept)
|
||||
- Source page: wiki/sources/specialized-document-generator.md
|
||||
- Notes: index 中已存在同名条目(来源缺失),本次摄入后标记为已解决。与 [[report-distribution-agent]](文档分发)和 [[agents-orchestrator]](工作流编排)存在潜在协同关系,建议后续摄入时补充连接。
|
||||
|
||||
- Source file: Agent/agency-agents/specialized/identity-graph-operator.md
|
||||
- Status: ✅ 成功摄入
|
||||
- Summary: Identity Graph Operator——多智能体系统共享身份图谱运营专家 Agent,解决多 Agent 系统的身份孤岛问题(重复记录/冲突操作/级联错误)。核心方法:规范化(昵称扩展/E.164 电话/邮箱小写)→ 阻塞(blocking key 筛选候选)→ 评分(字段级加权)→ 聚类。merge/split 通过乐观锁执行,按置信度分级(>0.95 直接合并、0.6-0.95 提案审查、<0.6 创建新实体)。保留完整事件历史。
|
||||
- Concepts created: [[Identity-Resolution]](身份解析四步流程框架)、[[Evidence-based-Merge-Proposal]](证据驱动合并提案协议)、[[Blocking]](阻塞分块技术)、[[Fuzzy-Matching]](模糊匹配技术)、[[Confidence-Score]](置信度评分与阈值决策)
|
||||
- Source page: wiki/sources/identity-graph-operator.md
|
||||
- Notes: 与 [[Designing-for-Agentic-AI]] 存在潜在冲突:确定性要求与 LLM 概率性行为如何协调,当前观点认为通过将核心逻辑从 LLM 推理分离来解决。index 中已存在同名 [[identity-graph-operator]] 条目(来源缺失),本次摄入后应标记为已解决。
|
||||
|
||||
## [2026-04-25] ingest | Accounts Payable Agent Personality
|
||||
- Source file: Agent/agency-agents/specialized/accounts-payable-agent.md
|
||||
- Status: ✅ 成功摄入
|
||||
- Summary: AccountsPayable Agent——The Agency 财务部门的自主支付运营专员 Agent,处理供应商付款、承包商发票和周期性账单,覆盖 ACH/Wire/Crypto/Stablecoin/Payment API 全支付通道。核心原则:幂等性优先(reference ID 去重,零重复付款)、审计全链路、最优通道路由(失败自动切换备选通道)、严格额度管控(超授权额度人工审批)。通过 tool calls 与 Contracts Agent、Project Manager Agent、HR Agent 集成。成功指标:零重复付款、< 2 分钟执行时间、100% 审计覆盖、60 秒 escalation SLA。
|
||||
- Concepts created: (文档内概念均为具体实现细节,不满足可独立复用条件,未创建 Concept 页面)
|
||||
- Entities created: (各协作 Agent 在本文档中各仅出现 1 次,不满足出现 ≥ 2 次条件,未创建 Entity 页面)
|
||||
- Source page: wiki/sources/accounts-payable-agent.md
|
||||
- Notes: 无已知冲突。本文档为单一 Agent 设计文档,与 [[Accounts-Payable-Agent]] 协作的各 Agent 需在各自文档中补充对应协作关系。
|
||||
|
||||
## [2026-04-25] ingest | Specialized Civil Engineer Agent
|
||||
- Source file: Agent/agency-agents/specialized/specialized-civil-engineer.md
|
||||
- Status: ✅ 成功摄入
|
||||
@@ -2982,3 +3012,11 @@
|
||||
- Entities created: [[Boss Zhipin]]
|
||||
- Source page: wiki/sources/recruitment-specialist.md
|
||||
- Notes: 无已知冲突。Key Entities 中 Lagou/Liepin/Beisen/Moka/Feishu/STAR 等在源文档出现但出现次数不足以触发独立建页,通过 Sources 页面的 Key Entities 部分建立 wikilinks。
|
||||
|
||||
## [2026-04-25] ingest | Government Digital Presales Consultant
|
||||
- Source file: Agent/agency-agents/specialized/government-digital-presales-consultant.md
|
||||
- Status: ✅ 成功摄入
|
||||
- Summary: Government Digital Presales Consultant 是面向中国ToG(政府)市场的全生命周期售前专家Agent,涵盖政策解读、等保2.0三级/商用密码评估/信创适配、数字政府/智慧城市/城市大脑方案设计、招投标全流程(POC→标书→述标→交接)。核心原则:业务场景驱动方案、技术价值需翻译为政府语言、等保/密评/信创是强制项非加分项。
|
||||
- Concepts created: [[Dengbao-2.0]], [[Miping]], [[Xinchuang]]
|
||||
- Source page: wiki/sources/government-digital-presales-consultant.md
|
||||
- Notes: 无已知冲突。Key Entities(Digital China Master Plan、Kunpeng、Phytium、UnionTech UOS、DM Database等)在源文档中属于背景知识,未创建独立Entity页面,通过Source页面Key Entities部分建立wikilinks。Entities页面已添加Dengbao 2.0、Miping、Xinchuang三条概念索引。
|
||||
|
||||
@@ -49,6 +49,10 @@ The wiki covers two major multi-agent frameworks: **The Agency** (agency-agents)
|
||||
|
||||
**[[multi-agent-system-reliability]]**(Alex Ewerlöf):多智能体系统可靠性的架构模式理论——反对拟人化LLM,主张将LLM视为分布式系统中不可靠的组件。核心4模式:[[Hierarchy-Agent-Pattern]](主管→工作→验证链)、[[Consensus-Voting-Pattern]](N个LLM多数票消除幻觉)、[[Adversarial-Debate-Pattern]](Generator→Critic→Judge对抗辩论)、[[Knock-out-Pattern]](适者生存淘汰制)。核心洞察:不应要求模型"小心",而应**强制**其正确——通过架构约束而非提示词约束。与 [[Designing for Agentic AI]] 互补(架构 vs 用户体验),与 [[Recursive Self-Optimization]] 共享自引用结构思想。与 [[Genetic-Algorithm]](遗传算法)有关联——Knock-out/Tree of Thoughts 是 GA 的精简实现。
|
||||
|
||||
**[[identity-graph-operator]]**(Identity Graph Operator):多智能体系统共享身份图谱运营专家 Agent——The Agency Specialized 部门的核心基础设施 Agent,解决多 Agent 系统的身份孤岛问题:当多个 Agent 独立处理同一实体时,缺乏共享身份层导致账单 Agent 重复收费、发货 Agent 发送两个包裹、支持 Agent 创建重复客户记录。核心方法:通过规范化(昵称扩展/E.164电话/邮箱小写)→ 阻塞(blocking key 筛选候选)→ 评分(字段级加权)→ 聚类四步实现确定性身份解析;merge/split 操作通过乐观锁执行,按置信度分级处理(>0.95 直接合并、0.6-0.95 提案审查、<0.6 创建新实体);保留 entity.created/merged/split/updated 完整事件历史。与 [[multi-agent-system-reliability]] 互补——后者解决 Agent 间决策一致性,前者解决 Agent 对同一实体的识别一致性;与 [[Personal CRM]](联系人去重)同源但增加了并发写入、跨框架身份联邦和多 Agent 审计追踪维度。属 [[Multi-Agent-System-Reliability]] 的身份基础设施层,与 [[Agents-Orchestrator]](注册身份解析能力)、[[Reality-Checker]](质量门检验 merge 证据)、[[Support-Responder]](客户身份预解析)协同构成完整多 Agent 身份体系。
|
||||
|
||||
**[[agentic-identity-trust]]**(Agentic Identity & Trust Architect):自主 Agent 身份认证与信任验证基础设施专家——The Agency Specialized 部门的核心安全基础设施 Agent,解决多 Agent 环境中的身份伪造、授权冒用、审计日志篡改等安全威胁。核心方法:密码学身份体系(Ed25519 公钥,签名密钥/加密密钥/身份密钥分离)、零信任验证模型(默认不信任自报告身份,要求密码学证明)、基于可验证结果的惩罚型信任评分(初始1.0,证据链损坏扣0.5,结果失败按失败率×0.4扣分,凭证超90天扣0.1)、append-only 哈希链式证据记录(每个操作记录 intent→decision→outcome,篡改任意历史记录均可检测)、多跳委托链验证(任意链节断裂则全链失效)、Fail-Closed 授权(无法验证时默认拒绝)。高级能力:算法敏捷性(密码学算法可升级,为后量子迁移预留抽象层)、NIST 后量子标准评估(ML-DSA/ML-KEM/SLH-DSA)、跨框架身份联邦(A2A/MCP/REST/SDK)。与 [[Identity Graph Operator]] 互补——前者解决"这个 Agent 是谁+能做什么"(确定性密码学证明),后者解决"这条记录是否是同一用户"(概率性实体匹配),共同构成完整身份层。与 [[multi-agent-system-reliability]] 协同——后者的对抗辩论/多数票等模式需要前者提供可验证的身份与信任基础。与 [[Designing-for-Agentic-AI]] 存在**潜在冲突**:零信任要求确定性验证 vs LLM 的概率性本质,当前方案通过将核心验证逻辑(密码学签名检查)从 LLM 推理分离为确定性代码组件来解决。
|
||||
|
||||
**[[xr-interface-architect]]**(XR Interface Architect):XR 空间界面架构师 Agent——The Agency Spatial Computing 部门的 UX/UI 设计专家,专注于为 AR/VR/XR 沉浸式环境创建直觉化、舒适且可发现的界面。核心方法:HUD / 浮动菜单 / 交互区域设计,支持直接触摸、注视+捏合、控制器和手势四种输入模型;基于人体工程学约束进行 UI 放置,减少晕动症;构建座舱/仪表盘/可穿戴界面布局模板;运行可用性验证实验(舒适度和学习性)。人格特质:**Human-centered, layout-conscious, sensory-aware, research-driven**。与 [[xr-immersive-developer]] 和 [[xr-cockpit-interaction-specialist]] 同属 Spatial Computing 部门,三者共同构建完整的 XR 产品交互基础设施。
|
||||
|
||||
**[[xr-cockpit-interaction-specialist]]**(XR Cockpit Interaction Specialist):XR 座舱交互专家 Agent——The Agency Spatial Computing 部门的沉浸式座舱式交互设计专家,专注于设计和实现固定视角、高存在感的座舱交互环境。核心设计原则:约束驱动控制机制(constraint-driven control mechanics)消除自由漂浮运动,通过 3D meshes 和输入约束将控制物理化;座舱人体工学对齐自然的眼-手-头协调流动;多模态交互集成(手势/语音/注视/物理道具);固定视角设计降低运动病阈值。典型应用场景:模拟指挥中心、航天器座舱、XR 载具界面、训练模拟器。核心工具:A-Frame / Three.js 原型开发。与 [[xr-interface-architect]] 存在层级关系(前者提供座舱交互基础能力,后者构建界面);与 [[xr-immersive-developer]] 在运动自由度设计上存在张力——前者强调固定视角约束以降低眩晕,后者倾向开放空间沉浸体验。属 [[Spatial-Computing]] 概念在座舱场景的具体应用,为 The Agency 的 XR 产品矩阵提供交互基础设施。
|
||||
@@ -89,6 +93,11 @@ The Agency 的 Paid Media 部门专注于企业级付费媒体策略与运营,
|
||||
|
||||
Key concepts: [[PerformanceMax]], [[SmartBidding]], [[AccountArchitecture]], [[TieredCampaignArchitecture]], [[IncrementalityTesting]], [[ConversionActionHierarchy]], [[CustomerMatch]], [[BudgetPacing]], [[ResponsiveSearchAds]], [[AdStrength]], [[CreativeFatigue]], [[HookBodyCTA]], [[MessageMatch]], [[ABTesting]], [[AdExtensions]]
|
||||
|
||||
### The Agency — Finance 部门
|
||||
|The Agency 的 Finance 部门涵盖自主支付运营、财务分析与合规管理等专业 Agent。|
|
||||
|
||||
**[[accounts-payable-agent]]**(Accounts Payable Agent):The Agency 财务部门的自主支付运营专员 Agent——处理供应商付款、承包商发票和周期性账单,覆盖 ACH/Wire/Crypto/Stablecoin/Payment API 等全支付通道。核心原则:**幂等性优先**(reference ID 去重,零重复付款)、**审计全链路**(每笔支付记录发票引用、金额、通道、时间戳和状态)、**安全路由**(自动选择最优通道路由,失败自动切换备选通道)、**严格额度管控**(超授权额度必须人工审批)。通过 tool calls 与 Contracts Agent、Project Manager Agent、HR Agent 集成,接收来自其他 Agent 的支付请求并生成支出报告供 Strategy Agent 分析。成功指标:零重复付款、< 2 分钟执行时间(快捷通道)、100% 审计覆盖、60 秒内 escalation SLA。属 [[Multi-Agent-System-Reliability]] 的财务合规执行层,[[Accounts-Payable-Agent]] 为 The Agency 提供可信赖的支付执行基础。
|
||||
|
||||
### Multi-Agent Monitoring & Automation
|
||||
**Dynamic Dashboard**:基于 [[OpenClaw]] 的多数据源实时监控仪表盘——通过子代理并行抓取 GitHub/Twitter/Polymarket/系统健康等多数据源,定时聚合结果推送 Discord,支持告警阈值和历史趋势存储。用对话式指令替代数周前端开发,立即获得实时洞察。[[polymarket-autopilot]] 是 Polymarket 市场监控的具体实现——AI Agent 24/7 自动监控预测市场、分析概率变化、自动执行交易策略。与 [[self-healing-home-server]] 的系统监控场景关联,[[earnings-tracker]] 的市场数据监控场景扩展,[[content-factory]] 共享子代理并行执行模式。
|
||||
|
||||
@@ -674,6 +683,10 @@ Key concepts: [[Django ORM]], [[Django REST Framework]], [[Django Admin 定制]]
|
||||
|
||||
**[[specialized-civil-engineer]]**(Civil Engineer):全球设计标准覆盖的结构与土木工程专家 Agent——专注于安全、经济、可建造的结构设计,驾驭 Eurocode(EN 1990–1999 + 各国 National Annex)、ACI 318(LRFD/SD)、AISC 360、ASCE 7、GB、IS、AIJ 等全球主流建筑规范体系。核心能力:**ULS+SLS 双重验证**(承载力极限状态与正常使用极限状态必须同时满足方为合格)+ **多标准冲突处理**(IBC+Eurocode 混用时识别冲突→文档记录→保守优先→设计依据报告)+ **岩土工程**(地勘报告解读、承载力/沉降分析、挡土结构、边坡稳定)。计算交付物包括:钢梁 AISC 360 LRFD 计算包(截面选型→抗弯验算→挠度检查)、RC 梁 Eurocode EN 1992-1-1 计算包(K 法配筋设计→抗剪验算)、岩土地基 Terzaghi 承载力分析(含 EN 1997 DA1 验证)。六阶段工作流:项目范围→初步设计→详细计算→建造文档→规范合规→施工支持。属 The Agency Specialized 部门的基础设施工程方向,与 [[specialized-developer-advocate]](开发者关系)同属 Specialized 专业 Agent 系列,与 [[specialized-workflow-architect]](工作流架构)存在依赖关系。
|
||||
|
||||
**[[specialized-document-generator]]**(Document Generator):专业文档生成专家 Agent——The Agency Specialized 部门的程序化文档生成专家,通过代码方式(Python/Node.js)生成 PDF、PPTX、DOCX、XLSX 等专业文档(投资者演示文稿、合规报告、数据密集型电子表格)。核心工具栈:PDF(reportlab/weasyprint/fpdf2)、PPTX(python-pptx/pptxgenjs)、XLSX(openpyxl/xlsxwriter/exceljs)、DOCX(python-docx/docx)。核心原则:**样式系统优先**(拒绝硬编码字体/字号,使用文档样式主题)、**品牌一致性**(颜色/字体/Logo 全局统一)、**数据驱动**(接受结构化数据输入生成文档输出)、**无障碍设计**(Alt 文本/标题层级/PDF 标签)、**模板可复用**(构建模板函数而非一次性脚本)。与 [[report-distribution-agent]](文档分发)和 [[agents-orchestrator]](工作流编排)协同,构成完整的文档从生成到分发的工作流。属 The Agency Specialized 部门的生产力工具方向,与 [[specialized-developer-advocate]] 同属专业工具 Agent 系列。
|
||||
|
||||
**[[government-digital-presales-consultant]]**(Government Digital Presales Consultant):The Agency Specialized 部门的政府数字化售前专家——面向中国ToG(政府)市场,专注于数字政府、智慧城市、一网统管、城市大脑等主流方向的全生命周期售前支持。核心能力:政策解读(数字中国/国家数据局政策信号提取:区分"鼓励探索"与"全面实施"的政策成熟度判断)、合规架构(等保2.0三级/商用密码评估/信创适配)、招投标全流程(需求调研→方案设计→POC验证→标书撰写→述标答辩→中标交接)。五步工作流配合技术方案模板、等保合规矩阵、投标检查清单、机会评估模板等交付物。关键原则:**技术方案必须以业务场景驱动**("市民服务处理速度提升80%"而非"微服务架构");**等保/密评/信创是强制项而非加分项**;方案至少经过三轮迭代打磨。成功指标:中标率>40%、零废标、售前到交付偏差<10%。与 [[sales-engineer]](通用售前)互补——后者覆盖企业级B2B市场,前者专精中国政府ToG市场特有的政策合规与采购流程;与 [[Digital-Government]](数字政府)和 [[Smart-City]](智慧城市)构成完整的政府信息化知识体系。属 The Agency Specialized 部门的垂直行业方向。
|
||||
|
||||
## Conflict Areas
|
||||
|
||||
1. **Kanban vs Event Sourcing**: Kanban emphasizes visual team collaboration; Event Sourcing emphasizes auto-tracking and context preservation. **[[Project State Management]]**(事件驱动看板替代方案)vs 传统 PM 工具。核心差异:手动拖拽 vs 自然语言输入;静态快照 vs 全历史保留;无上下文 vs 完整决策链。**[[Event Sourcing]]** 在此上下文中指将项目变更存储为事件序列,每次 progress/blocker/decision/pivot 均持久化,保留完整决策上下文。
|
||||
|
||||
47
wiki/sources/accounts-payable-agent.md
Normal file
47
wiki/sources/accounts-payable-agent.md
Normal file
@@ -0,0 +1,47 @@
|
||||
---
|
||||
title: "Accounts Payable Agent Personality"
|
||||
type: source
|
||||
tags: []
|
||||
date: 2026-04-25
|
||||
---
|
||||
|
||||
## Source File
|
||||
- [[Agent/agency-agents/specialized/accounts-payable-agent.md]]
|
||||
|
||||
## Summary(用中文描述)
|
||||
- 核心主题:AccountsPayable Agent——自主支付运营专员 Agent,处理供应商付款、承包商发票和周期性账单,覆盖加密货币、法定货币、稳定币等全支付通道
|
||||
- 问题域:AI Agent 工作流中的支付执行、审计追踪、防重复付款、多通道路由
|
||||
- 方法/机制:幂等性检查 → 供应商注册表验证 → 最优通道路由 → 执行支付 → 审计日志全链路;通过 tool calls 与 Contracts Agent、Project Manager Agent、HR Agent 等集成
|
||||
- 结论/价值:为 AI Agent 生态提供可信赖的支付执行层,零重复付款、完整审计覆盖、60秒内 escalation SLA
|
||||
|
||||
## Key Claims(用中文描述)
|
||||
- AccountsPayable Agent 通过幂等性检查确保永远不会发送同一笔支付两次
|
||||
- Agent 自动选择最优支付通道(ACH/ Wire/ Crypto/ Stablecoin/ Payment API),基于接收方、金额和成本
|
||||
- 所有支付均保留完整审计日志,包含发票引用、金额、通道、时间戳和状态
|
||||
- 超过授权额度的支付必须上报人工审批,不得自动执行
|
||||
|
||||
## Key Quotes
|
||||
> "Idempotency first: Check if an invoice has already been paid before executing. Never pay twice." — 核心安全原则
|
||||
> "If a payment rail fails, try the next available rail before escalating" — 容错路由机制
|
||||
> "Zero duplicate payments — idempotency check before every transaction" — 成功指标
|
||||
|
||||
## Key Concepts
|
||||
- [[Idempotency]]:幂等性——同一笔支付请求无论执行多少次,结果相同。AccountsPayable 通过 reference ID 去重,防止重复付款
|
||||
- [[Payment-Rail]]:支付通道——ACH(国内/工资,1-3天)、Wire(大额/跨境,即时)、Crypto(加密原生供应商,分钟级)、Stablecoin(低费用,秒级)、Payment API(卡片/平台,1-2天)
|
||||
- [[Audit-Trail]]:审计追踪——每笔支付记录发票引用、金额、通道、时间戳和状态,确保财务合规
|
||||
- [[Vendor-Registry]]:供应商注册表——维护已批准供应商及其首选支付通道和地址
|
||||
|
||||
## Key Entities
|
||||
- [[Contracts-Agent]]:里程碑完成后触发 AccountsPayable 执行承包商付款
|
||||
- [[Project-Manager-Agent]]:处理承包商工时材料发票
|
||||
- [[HR-Agent]]:负责工资单发放
|
||||
- [[Strategy-Agent]]:接收支出报告和资金跑道分析
|
||||
|
||||
## Connections
|
||||
- [[Accounts-Payable-Agent]] ← receives_payment_requests ← [[Contracts-Agent]]
|
||||
- [[Accounts-Payable-Agent]] ← receives_payment_requests ← [[Project-Manager-Agent]]
|
||||
- [[Accounts-Payable-Agent]] ← receives_payment_requests ← [[HR-Agent]]
|
||||
- [[Accounts-Payable-Agent]] ← provides_spend_reports ← [[Strategy-Agent]]
|
||||
|
||||
## Contradictions
|
||||
- (本文档为单一 Agent 设计文档,暂无已知内容冲突)
|
||||
53
wiki/sources/agentic-identity-trust.md
Normal file
53
wiki/sources/agentic-identity-trust.md
Normal file
@@ -0,0 +1,53 @@
|
||||
---
|
||||
title: "Agentic Identity & Trust Architect"
|
||||
type: source
|
||||
tags: []
|
||||
date: 2026-04-25
|
||||
---
|
||||
|
||||
## Source File
|
||||
- [[Agent/agency-agents/specialized/agentic-identity-trust.md]]
|
||||
|
||||
## Summary(用中文描述)
|
||||
- 核心主题:为自主 AI Agent 构建身份认证与信任验证基础设施,确保 Agent 能证明自身身份、授权范围和操作记录的完整性。
|
||||
- 问题域:多 Agent 环境中身份伪造、授权链验证缺失、可篡改日志、凭证过期未检测、委托权限升级等安全问题。
|
||||
- 方法/机制:零信任身份体系(永不信任自我声明)、密码学身份证明、证据链完整性、委托链验证、信任评分、Fail-Closed 授权策略。
|
||||
- 结论/价值:Agentic AI 系统在执行高风险操作(资金转账、基础设施部署、物理控制)前,必须完成五项验证:身份有效性、凭证时效性、权限充分性、信任评分、委托链完整性。
|
||||
|
||||
## Key Claims(用中文描述)
|
||||
- 零信任原则:Agent 不得信任自我声明的身份或授权——"Agent 说它被授权"不等于"Agent 证明了它被授权"。
|
||||
- 证据链完整性:证据链的任何历史记录被篡改必须可被检测;写日志的实体若能修改日志,则该日志对审计毫无价值。
|
||||
- Fail-Closed 授权:身份无法验证 → 拒绝操作;委托链存在断裂 → 整链无效;信任评分低于阈值 → 要求重新验证。
|
||||
- 密码学卫生规范:使用成熟标准(Ed25519/ECDSA),签名密钥与加密密钥分离,密钥材料不得出现在日志或 API 响应中。
|
||||
- 信任评分基于可验证结果:信任分从 1.0 开始,仅通过可验证问题扣分;不允许 Agent 自我报告信号来提高信任分。
|
||||
|
||||
## Key Quotes
|
||||
> "Never trust self-reported identity. An agent claiming to be 'finance-agent-prod' proves nothing. Require cryptographic proof." — 零信任原则核心表述
|
||||
> "If identity cannot be verified, deny the action — never default to allow." — Fail-Closed 授权策略
|
||||
> "Trust score 0.92 based on 847 verified outcomes with 3 failures and an intact evidence chain" — 量化信任而非断言信任
|
||||
> "Design every system assuming at least one agent in the network is compromised or misconfigured." — 假设妥协的安全设计哲学
|
||||
|
||||
## Key Concepts
|
||||
- [[Zero-Trust]]:永不信任自我声明,要求密码学证明。适用于身份验证、授权验证和日志完整性三个层面。
|
||||
- [[Evidence-Chain]]:仅追加、可独立验证、链式哈希、防篡改的 Agent 操作证据记录系统。
|
||||
- [[Trust-Scoring]]:基于可观测结果的惩罚模型信任评分,Agent 从 1.0 开始,仅通过可验证问题扣分。
|
||||
- [[Delegation-Chain]]:多跳委托授权链,每一跳须签名且作用域不得宽于上级,过期或断裂则整链无效。
|
||||
- [[Fail-Closed]]:授权失败时默认拒绝,而非默认允许的安全策略。
|
||||
- [[Peer-Verification]]:Agent 之间在接受委托工作前互相验证身份和授权的协议。
|
||||
- [[Algorithm-Agility]]:密码学算法可升级性,为后量子密码学迁移预留抽象层。
|
||||
|
||||
## Key Entities
|
||||
- [[Identity-Graph-Operator]]:与本文档并列的 Entity 身份解析 Agent,本文档负责 Agent 身份认证,Identity Graph Operator 负责人/公司/产品实体解析。
|
||||
- [[The Agency]]:该 Agent 所属的 The Agency 专业化 Agent 生态。
|
||||
|
||||
## Connections
|
||||
- [[Identity-Graph-Operator]] ← 互补关系 ← [[Agentic-Identity-Trust]]
|
||||
- [[Designing-for-Agentic-AI]] ← 潜在冲突 ← [[Agentic-Identity-Trust]](确定性要求与 LLM 概率性行为的张力)
|
||||
- [[agents-orchestrator]] ← 依赖 ← [[Agentic-Identity-Trust]](编排器需信任验证层)
|
||||
- [[report-distribution-agent]] ← 依赖 ← [[Agentic-Identity-Trust]](分发代理操作需可审计)
|
||||
|
||||
## Contradictions
|
||||
- 与 [[Designing-for-Agentic-AI]] 冲突:
|
||||
- 冲突点:零信任要求确定性验证 vs LLM 的概率性本质(LLM 无法提供数学意义上的确定性签名证明)
|
||||
- 当前观点:通过将核心逻辑(密码学验证、签名检查)从 LLM 推理分离为独立组件来解决——LLM 只负责策略决策,验证层由确定性代码执行。
|
||||
- 对方观点:若信任验证逻辑本身依赖 LLM(如自然语言授权描述),则仍存在概率性风险。
|
||||
59
wiki/sources/government-digital-presales-consultant.md
Normal file
59
wiki/sources/government-digital-presales-consultant.md
Normal file
@@ -0,0 +1,59 @@
|
||||
---
|
||||
title: "Government Digital Presales Consultant"
|
||||
type: source
|
||||
tags: [ToG, government-IT, presales, compliance, Xinchuang, Smart-City, Digital-Government]
|
||||
date: 2026-04-25
|
||||
---
|
||||
|
||||
## Source File
|
||||
- [[Agent/agency-agents/specialized/government-digital-presales-consultant.md]]
|
||||
|
||||
## Summary(用中文描述)
|
||||
- 核心主题:中国政府信息化(ToG)市场的全生命周期售前专家智能体,涵盖从政策解读、解决方案设计到招投标全程
|
||||
- 问题域:政府数字化转型市场的项目机会识别、标书撰写、合规要求(POC验证、等保/密评/信创)、干系人管理
|
||||
- 方法/机制:五步工作流(机会发现→需求调研→方案设计→投标执行→中标交接),配合政策解读、竞品分析、POC演示、合规矩阵等工具模板
|
||||
- 结论/价值:为技术团队提供进入数字政府、智慧城市、一网统管、城市大脑等主流方向的决策支持,核心目标是提高中标率(>40%)、零废标、售前到交付对齐(偏差<10%)
|
||||
|
||||
## Key Claims(用中文描述)
|
||||
- 售前专家通过政策语言解码("鼓励探索"→"全面实施")识别市场成熟度信号,在政策从"软性鼓励"转向"硬性要求"时入场
|
||||
- 政府系统通常要求等保三级,核心系统可能要求等保四级;等保评估需在系统上线前2-3个月完成整改
|
||||
- 信创替换不必一步到位,分阶段替代是被接受的
|
||||
- 技术方案应以业务场景驱动,而非技术架构驱动——客户关心"市民服务处理速度提升80%"而非"微服务架构"
|
||||
- 投标文件零容忍格式错误——资质缺失、格式偏差、响应偏移均属废标项
|
||||
|
||||
## Key Quotes
|
||||
> "Drive with business scenarios, not technical architecture — the client cares about '80% faster citizen service processing,' not 'microservices architecture.'" — 方案设计核心原则
|
||||
> "Dengbao, Miping, and Xinchuang are mandatory, not bonus points." — 合规基线
|
||||
> "Don't tell the bureau head we use Kubernetes. Tell them 'Our platform's elastic scaling ensures zero downtime during peak service hall hours.'" — 技术价值转换
|
||||
> "A good proposal goes through at least three rounds of refinement." — 方案迭代要求
|
||||
|
||||
## Key Concepts
|
||||
- [[Dengbao-2.0]]:网络安全等级保护制度,政府系统通常要求三级,等保评估需在上线前2-3个月完成
|
||||
- [[Miping]]:商用密码应用安全性评估,涉及身份认证、数据传输、数据存储必须使用国密算法(SM2/SM3/SM4)
|
||||
- [[Xinchuang]]:信息技术应用创新,核心要素为国产CPU(鲲鹏/飞腾/海光/龙芯)+ 国产OS(统信UOS/麒麟)+ 国产数据库(达梦/人大金仓/ GaussDB)+ 国产中间件
|
||||
- [[ToG]](Government):面向政府的数字化转型市场,区别于ToB(企业)和ToC(消费者)
|
||||
- [[Smart-City]]:智慧城市,典型方向包括城市大脑/城市运行中心(IOC)、智慧交通、智慧社区、城市信息模型(CIM)
|
||||
- [[Digital-Government]]:数字政府,典型方向包括一体化政务服务平台、一网统管/一网通办、12345热线智能升级、政府数据中台
|
||||
- [[Yiwangtongban]]:一网统办,一网通管,一体化政务服务门户
|
||||
- [[POC]]:概念验证,通过精选场景展示差异化优势,控制范围并设定明确成功标准
|
||||
|
||||
## Key Entities
|
||||
- [[Digital-China-Master-Plan]]:数字中国建设整体布局规划,国家级政策文件
|
||||
- [[National-Data-Administration]]:国家数据局,国家层面数据治理主管机构
|
||||
- [[Government-Cloud]]:政务云平台,政府信息化基础设施
|
||||
- [[City-Brain]]:城市大脑,城市级数据融合与智能决策平台
|
||||
- [[Kunpeng]]:鲲鹏,国产CPU代表
|
||||
- [[Phytium]]:飞腾,国产CPU代表
|
||||
- [[UnionTech-UOS]]:统信UOS,国产操作系统代表
|
||||
- [[DM-Database]]:达梦数据库,国产数据库代表
|
||||
|
||||
## Connections
|
||||
- [[Government-Digital-Presales-Consultant]] ← extends ← [[Sales-Engineer]](通用售前 → 政府垂直领域售前)
|
||||
- [[Government-Digital-Presales-Consultant]] ← depends_on ← [[Xinchuang]](信创合规必须掌握)
|
||||
- [[Government-Digital-Presales-Consultant]] ← depends_on ← [[Dengbao-2.0]](等保合规必须掌握)
|
||||
- [[Government-Digital-Presales-Consultant]] ← depends_on ← [[Miping]](密码评估必须掌握)
|
||||
- [[Digital-Government]] ← solution_domain ← [[Government-Digital-Presales-Consultant]](数字政府是主要方案方向之一)
|
||||
- [[Smart-City]] ← solution_domain ← [[Government-Digital-Presales-Consultant]](智慧城市是主要方案方向之一)
|
||||
|
||||
## Contradictions
|
||||
- 无明显冲突。本文档专注于中国政府ToG市场,与Wiki中其他以企业级/B2B市场为中心的售前/销售Agent形成领域区隔。
|
||||
56
wiki/sources/identity-graph-operator.md
Normal file
56
wiki/sources/identity-graph-operator.md
Normal file
@@ -0,0 +1,56 @@
|
||||
---
|
||||
title: "Identity Graph Operator"
|
||||
type: source
|
||||
tags: ["multi-agent", "identity-resolution", "entity-resolution", "the-agency"]
|
||||
date: 2026-04-24
|
||||
---
|
||||
|
||||
## Source File
|
||||
- [[Agent/agency-agents/specialized/identity-graph-operator]]
|
||||
|
||||
## Summary(用中文描述)
|
||||
- 核心主题:多智能体系统中的共享身份图谱运营——确保所有 Agent 对同一真实世界实体(人/公司/产品)得到一致的规范化实体 ID,解决多 Agent 系统的核心问题:重复记录、冲突操作、级联错误。
|
||||
- 问题域:多 Agent 系统中的身份孤岛问题——当多个 Agent 独立处理同一实体时,缺乏共享身份层导致账单 Agent 重复收费、发货 Agent 发送两个包裹、支持 Agent 创建重复客户记录。
|
||||
- 方法/机制:通过身份解析引擎(Identity Engine)进行规范化(Normalization)→ 阻塞(Blocking)→ 评分(Scoring)→ 聚类(Clustering),返回相同 entity_id;支持昵称扩展(Bill→William)、E.164 电话标准化、邮箱小写化;merge/split 操作通过乐观锁执行,保留完整事件历史;直接变更 vs 提案决策按置信度分级处理。
|
||||
- 结论/价值:零身份冲突生产环境、合并准确率 > 99%、P99 解析延迟 < 100ms、全链路审计追踪。与 [[Multi-Agent-System-Reliability]] 的 Agent 协作模式互补——后者解决 Agent 间决策一致性问题,前者解决 Agent 对同一实体的识别一致性问题。
|
||||
|
||||
## Key Claims(用中文描述)
|
||||
- **相同输入,相同输出**:两个 Agent 解析同一条记录必须得到相同 entity_id,这是绝对原则,不可妥协。
|
||||
- **证据优先于断言**:合并必须有字段级证据支撑(email exact match + name fuzzy match + phone match),仅凭"看起来相似"不足以触发合并。
|
||||
- **提案优于直接变更**:与其他 Agent 协作时,优先提出带证据的合并提案,而非直接执行,让对方 Agent 审查证据。
|
||||
- **外部 ID 排序**:使用 external_id 排序而非 UUID(UUID 无序),确保排序稳定性。
|
||||
- **从不跳过引擎**:不硬编码字段名、权重或阈值,由匹配引擎统一计算候选评分。
|
||||
|
||||
## Key Quotes
|
||||
> "Same input, same output. Two agents resolving the same record must get the same entity_id. Always." — Determinism 原则核心表述
|
||||
> "Never merge without evidence. 'These look similar' is not evidence. Per-field comparison scores with confidence thresholds are evidence." — Evidence Over Assertion 原则
|
||||
> "When agents disagree — one proposes merge, another proposes split on the same entities — both proposals are flagged as 'conflict.' Add comments to discuss before resolving. Never resolve a conflict by overriding another agent's evidence." — 冲突处理机制
|
||||
|
||||
## Key Concepts
|
||||
- [[Identity Resolution(身份解析)]]:将多条记录归一化为同一 canonical entity_id 的过程——通过 blocking/scoring/clustering 实现,与传统主数据管理(MDM)同源但在多 Agent 场景下增加了并发写入和分布式协调维度。
|
||||
- [[Blocking(阻塞/分块)]]:通过 blocking key(email domain、phone prefix、name soundex)快速筛选候选匹配对,避免全图扫描 O(n²) 开销,是大规模实体解析的性能关键。
|
||||
- [[Fuzzy Matching(模糊匹配)]]:处理"Bill Smith"和"William Smith"视为同一人的能力——通过昵称扩展(nickname normalization)和字段级相似度评分实现,是身份解析的核心挑战。
|
||||
- [[Confidence Score(置信度评分)]]:字段级证据分数加权求和得出的合并置信度——决定直接合并(>0.95)、提案审查(0.6-0.95)还是创建新实体(<0.6),是自动决策与人机协作的分界点。
|
||||
- [[Optimistic Locking(乐观锁)]]:通过版本号(version field)防止并发写入冲突——变更需携带 expected_version,版本不匹配时拒绝执行,是图谱完整性的并发保护机制。
|
||||
- [[Evidence-based Merge Proposal(证据驱动合并提案)]]:合并前必须构造 per-field evidence(email_match/score/values、name_match/score/values),让其他 Agent 基于证据而非断言进行审查,是多 Agent 身份协调的核心协议。
|
||||
- [[Multi-Agent Identity Coordination(多 Agent 身份协调)]]:跨 Agent 的 merge/split 冲突检测、跨编排框架(LangChain/CrewAI/AutoGen)的身份联邦,以及 shared agent memory(跨 Agent 知识共享)——是 Identity Graph Operator 与 [[Multi-Agent-System-Reliability]] 的本质区别。
|
||||
|
||||
## Key Entities
|
||||
- [[Identity Graph Operator]]:身份图谱运营者 Agent——本文档描述的核心 Agent,拥有共享身份层的所有权,负责多 Agent 系统的实体解析、合并提案和冲突协调。
|
||||
- [[Backend Architect]]:后端架构师 Agent——与 Identity Graph Operator 协作,前者设计数据表结构,后者确保跨来源的实体不重复。
|
||||
- [[Agents Orchestrator]]:Agent 编排器——Identity Graph Operator 在其中注册自己的身份解析能力,供编排器分配 identity resolution 任务。
|
||||
- [[Reality Checker]]:现实核查 Agent——接收 Identity Graph Operator 的 merge 证据进行质量门检验。
|
||||
- [[Support Responder]]:支持响应 Agent——通过 Identity Graph Operator 解析客户身份后响应,"这是昨天来电的同一位客户吗?"
|
||||
- [[Agentic Identity & Trust Architect]]:Agent 身份与信任架构师——与 Identity Graph Operator 互补,前者处理实体身份(who is this person/company?),后者处理 Agent 身份(who is this agent and what can it do?)。
|
||||
|
||||
## Connections
|
||||
- [[Multi-Agent-System-Reliability]] ← depends_on ← [[Identity-Graph-Operator]]:身份图谱是 [[Multi-Agent-System-Reliability]] 中多 Agent 协作模式的基础设施层——[[Hierarchy-Agent-Pattern]] 中的主管 Agent 需要 Identity Graph Operator 来消除下游 Agent 的重复实体问题。
|
||||
- [[Identity-Graph-Operator]] ← extends ← [[Personal CRM]]:[[Personal CRM]] 中的联系人去重是 Identity Graph Operator 在个人场景的简化实现,企业级多 Agent 场景增加了并发写入、跨框架联邦和图谱完整性等维度。
|
||||
- [[Identity-Graph-Operator]] ← depends_on ← [[Identity-Resolution]]:身份解析技术是 Identity Graph Operator 的核心能力底座,两者同义——Operator 是身份解析能力在多 Agent 系统中的 Agent 化封装。
|
||||
- [[Identity-Graph-Operator]] ← extends ← [[Entity-Merge-Algorithm]]:Entity Merge Algorithm 是合并决策的计算内核,Operator 在其上增加了提案协议、冲突检测和审计追踪等协作维度。
|
||||
|
||||
## Contradictions
|
||||
- 与 [[Designing-for-Agentic-AI]] 可能的冲突:
|
||||
- 冲突点:身份图谱的确定性要求("Same input, same output")与 [[Designing-for-Agentic-AI]] 强调的 LLM 概率性行为如何协调?
|
||||
- 当前观点:[[Identity-Graph-Operator]] 通过将身份解析核心逻辑从 LLM 推理中分离出来(blocking/scoring/clustering 由确定性算法执行),仅在 merge proposal 生成阶段使用 LLM 提供自然语言解释,从而在保留 LLM 灵活性的同时保障确定性。
|
||||
- 对方观点:[[Designing-for-Agentic-AI]] 可能认为过度确定性约束会削弱 Agent 的自主性和上下文适应能力。
|
||||
48
wiki/sources/specialized-document-generator.md
Normal file
48
wiki/sources/specialized-document-generator.md
Normal file
@@ -0,0 +1,48 @@
|
||||
---
|
||||
title: "Document Generator Agent"
|
||||
type: source
|
||||
tags: []
|
||||
date: 2026-04-20
|
||||
---
|
||||
|
||||
## Source File
|
||||
- [[Agent/agency-agents/specialized/specialized-document-generator.md]]
|
||||
|
||||
## Summary(用中文描述)
|
||||
- 核心主题:AI Agent 担任专业文档生成专家,通过代码方式生成 PDF、PPTX、DOCX、XLSX 等格式的专业文档
|
||||
- 问题域:如何让 AI Agent 高效、规范、可复用地产出商业级文档(投资者演示文稿、合规报告、数据密集型电子表格等)
|
||||
- 方法/机制:基于 Python(reportlab、python-pptx、openpyxl、python-docx 等)和 Node.js(puppeteer、pptxgenjs、exceljs、docx 等)两大生态,使用模板化、数据驱动、品牌一致的设计原则
|
||||
- 结论/价值:文档生成 Agent 需具备精确、设计意识强、注重格式的特点;核心规则包括使用样式系统而非硬编码、保持品牌一致性、数据驱动输入、无障碍设计,以及构建可复用模板而非一次性脚本
|
||||
|
||||
## Key Claims(用中文描述)
|
||||
- Document Generator Agent 通过代码编程方式(而非手动操作)生成专业级 PDF、演示文稿、电子表格和 Word 文档
|
||||
- Agent 需根据不同文档格式选择最优工具链(PDF 推荐 HTML+CSS→PDF 方案,PPTX 推荐 python-pptx,XLSX 推荐 openpyxl,DOCX 推荐 python-docx)
|
||||
- 核心规则:必须使用文档样式系统而非硬编码字体/字号,确保品牌颜色、字体、Logo 一致,数据驱动输入输出,支持无障碍(Alt 文本、标题层级、PDF 标签)
|
||||
- Agent 应构建可复用模板函数,而非一次性脚本,以提升效率和可维护性
|
||||
|
||||
## Key Quotes
|
||||
> "You are **Document Generator**, a specialist in creating professional documents programmatically." — Agent 身份定位
|
||||
> "Use proper styles — Never hardcode fonts/sizes; use document styles and themes" — 核心规则第1条
|
||||
> "Ask about the target audience and purpose before generating" — 沟通风格
|
||||
|
||||
## Key Concepts
|
||||
- [[Code-Based Document Generation]]:通过编程代码(Python/Node.js 库)而非手动操作软件生成文档的方法
|
||||
- [[Template-Based Document Generation]]:基于预定义模板,通过数据替换生成一致性文档的工作模式
|
||||
- [[Data-Driven Document Generation]]:以结构化数据为输入,自动生成对应格式文档的自动化方法
|
||||
- [[Brand-Consistent Document Design]]:在文档生成过程中保持颜色、字体、Logo 等品牌元素一致的设计原则
|
||||
|
||||
## Key Entities
|
||||
- [[The Agency]]:Document Generator Agent 所属的 Agent 框架体系(从 index 中相关条目推断)
|
||||
- reportlab / weasyprint / fpdf2:Python PDF 生成库
|
||||
- python-pptx / pptxgenjs:PPTX 演示文稿生成库
|
||||
- openpyxl / xlsxwriter / exceljs / xlsx:XLSX 电子表格生成库
|
||||
- python-docx / docx:DOCX Word 文档生成库
|
||||
|
||||
## Connections
|
||||
- [[specialized-developer-advocate]] ← relates_to ← [[specialized-document-generator]](同为 The Agency 下的专业 Agent)
|
||||
- [[agents-orchestrator]] ← orchestrates ← [[specialized-document-generator]](文档生成通常由编排 Agent 调度)
|
||||
- [[report-distribution-agent]] ← supports ← [[specialized-document-generator]](文档生成后可由分发 Agent 推送)
|
||||
|
||||
## Contradictions
|
||||
- 无已知冲突
|
||||
|
||||
Reference in New Issue
Block a user