# RMDC Authorization Layers

## Overview

RMDC 采用双层授权架构，确保跨网络操作的安全性。

```
┌────────────────────────────────────────────────────────────┐
│                    RMDC Platform (内网)                     │
│  ┌──────────────────┐     ┌──────────────────┐            │
│  │ project-mgmt     │────▶│ exchange-hub     │            │
│  │ (L1 Auth Center) │     │ (MQTT Gateway)   │            │
│  └──────────────────┘     └────────┬─────────┘            │
└────────────────────────────────────┼───────────────────────┘
                                     │ MQTT (公网)
┌────────────────────────────────────┼───────────────────────┐
│                    Project Env (边缘/外网)                  │
│                            ┌───────▼─────────┐             │
│                            │ rmdc-watchdog   │             │
│                            │ (L2 Auth Center)│             │
│                            └───────┬─────────┘             │
│                    ┌───────────────┼───────────────┐       │
│              ┌─────▼─────┐   ┌─────▼─────┐                 │
│              │ watchdog  │   │ watchdog  │                 │
│              │   -node   │   │  -agent   │                 │
│              └───────────┘   └───────────┘                 │
└────────────────────────────────────────────────────────────┘
```

## L1 Authorization (一级授权)

| Attribute | Value |
|-----------|-------|
| Scope | project-management ↔ watchdog |
| Algorithm | SHA256 |
| Code Length | 8 digits |
| Validity | 30 minutes |
| Transport | MQTT message payload |

### L1 Flow

1. `project-management` 创建项目时生成 `auth_secret`
2. 部署 watchdog 时将 `auth_secret` 写入配置文件
3. watchdog 启动后生成 TOTP 验证码发送注册请求
4. `exchange-hub` 转发给 `project-management` 验证
5. 验证通过后项目状态变为 `ONLINE`

### L1 Code Generation

```go
func GenerateL1Code(secret string, timestamp int64) string {
    // 30-minute window
    counter := timestamp / (30 * 60)
    h := hmac.New(sha256.New, []byte(secret))
    h.Write([]byte(fmt.Sprintf("%d", counter)))
    hash := h.Sum(nil)
    offset := hash[len(hash)-1] & 0x0F
    code := binary.BigEndian.Uint32(hash[offset:offset+4]) & 0x7FFFFFFF
    return fmt.Sprintf("%08d", code%100000000)
}
```

## L2 Authorization (二级授权)

| Attribute | Value |
|-----------|-------|
| Scope | watchdog ↔ watchdog-agent/node |
| Algorithm | SHA1 (RFC 6238 TOTP) |
| Code Length | 6 digits |
| Validity | 30 seconds |
| Transport | HTTP Header / gRPC Metadata |

### L2 Flow

1. watchdog 作为二级授权中心持有本项目 `agent_secret`
2. agent/node 启动时从配置获取 `agent_secret`
3. 每次请求携带当前 TOTP 验证码
4. watchdog 验证后执行操作

### L2 Code Generation

```go
// Standard TOTP (RFC 6238)
func GenerateL2Code(secret string) string {
    key, _ := base32.StdEncoding.DecodeString(secret)
    return totp.GenerateCode(key, time.Now())
}
```

## Security Considerations

1. **Secret Storage**: 所有 secret 必须加密存储（AES-256-GCM）
2. **Transport Security**: MQTT 必须启用 TLS
3. **Clock Sync**: 所有节点时间偏差 < 30 秒
4. **Replay Protection**: 每个 message_id 只能使用一次
5. **Rate Limiting**: 验证失败超过 5 次锁定 15 分钟

## Error Codes

| Code | Description | Action |
|------|-------------|--------|
| AUTH_L1_INVALID | L1 验证码无效 | 检查 secret 配置 |
| AUTH_L1_EXPIRED | L1 验证码过期 | 重新生成验证码 |
| AUTH_L2_INVALID | L2 TOTP 无效 | 检查时间同步 |
| AUTH_L2_LOCKED | L2 验证已锁定 | 等待 15 分钟 |
