kboykov/wazuh-1password
GitHub: kboykov/wazuh-1password
将 1Password Events API 的审计事件、登录尝试和条目使用数据集成到 Wazuh SIEM 的生产就绪方案,包含轮询脚本、解码器和 35 条预构建检测规则。
Stars: 0 | Forks: 0
# Wazuh — 1Password Events API 集成
一个生产就绪的集成方案,用于将 [1Password Events API](https://developer.1password.com/docs/events-api/) 中的审计事件、登录尝试和条目使用事件拉取到 Wazuh 中,以实现实时告警、关联分析和取证调查。
## 工作原理
```
1Password Events API
│
│ POST /api/v2/{auditevents,signinattempts,itemusages}
│ Bearer JWT · cursor-based pagination
▼
onepassword_events.py (runs every minute via Wazuh wodle command)
│
│ Appends newline-delimited JSON to:
│ /var/ossec/logs/onepassword/onepassword-events.json
▼
Wazuh localfile (json format)
│
│ Matches prematch: "op_integration":"1password"
▼
100-onepassword_decoders.xml (JSON_Decoder → extracts all fields)
│
▼
100-onepassword_rules.xml (35 rules across 3 event types)
│
▼
Wazuh alerts / dashboards / SOAR
```
该脚本每分钟运行一次,获取自上次游标以来的新页面数据,并将每行一个 JSON 对象写入日志文件。首次运行时,它会回填过去 24 小时(可配置)的数据。状态(每个端点的 API 游标)在两次运行之间以原子方式持久化,因此在重启期间不会丢失或重复任何事件。
由于 Wazuh 保留了诸如 `action`、`type`、`category` 和 `timestamp` 等字段名,该脚本会自动添加 `op_*` 别名(`op_action`、`op_type`、`op_category`、`op_event_timestamp`)并展平嵌套对象,以便规则能够匹配简单的顶层字段名。
## 仓库内容
| 文件 | 用途 |
|---|---|
| `onepassword_events.py` | 轮询脚本 — 获取事件并写入 Wazuh 日志文件 |
| `onepassword-events.env` | 环境配置(token、URL、调优参数) |
| `ossec_config.xml` | Wazuh `ossec.conf` 配置片段 — wodle 命令 + localfile 配置段 |
| `100-onepassword_decoders.xml` | Wazuh 解码器 — 识别并解析 1Password 事件的 JSON |
| `100-onepassword_rules.xml` | Wazuh 规则 — 包含覆盖所有三种事件类型的 35 条规则 |
## 前置条件
- Wazuh manager 4.x(在 4.7 版本上测试)
- Wazuh manager 主机上的 Python 3.8+(仅使用标准库 — 无需额外安装包)
- 1Password Business 或 Enterprise 账户
- 具有所需功能范围(`auditevents`、`signinattempts`、`itemusages`)的 1Password Events API token
- 如果您想通过 GitHub Actions 进行派生/部署,需要 `gh` CLI 或等效工具
### 生成 1Password Events API token
1. 在 `.1password.com`(EU 租户为 `.eu`)登录您的 1Password 账户。
2. 转到 **Integrations → Directory → Events API**。
3. 点击 **Add Integration**,为其命名,并选择所有三种事件类型。
4. 复制 bearer token — 此令牌仅显示一次。
## 安装说明
### 1. 部署轮询脚本
```
sudo cp onepassword_events.py /var/ossec/integrations/
sudo chown root:wazuh /var/ossec/integrations/onepassword_events.py
sudo chmod 750 /var/ossec/integrations/onepassword_events.py
```
### 2. 部署环境文件
```
sudo cp onepassword-events.env /var/ossec/etc/onepassword-events.env
sudo chown root:wazuh /var/ossec/etc/onepassword-events.env
sudo chmod 640 /var/ossec/etc/onepassword-events.env
```
编辑文件并设置您的 token 和基础 URL:
```
sudo nano /var/ossec/etc/onepassword-events.env
```
```
ONEPASSWORD_EVENTS_TOKEN="eyJhbGc..." # paste your JWT here
ONEPASSWORD_EVENTS_BASE_URL="https://events.1password.eu" # or .com for US
```
### 3. 部署解码器和规则
```
sudo cp 100-onepassword_decoders.xml /var/ossec/etc/decoders/
sudo cp 100-onepassword_rules.xml /var/ossec/etc/rules/
sudo chown root:wazuh /var/ossec/etc/decoders/100-onepassword_decoders.xml
sudo chown root:wazuh /var/ossec/etc/rules/100-onepassword_rules.xml
sudo chmod 640 /var/ossec/etc/decoders/100-onepassword_decoders.xml
sudo chmod 640 /var/ossec/etc/rules/100-onepassword_rules.xml
```
### 4. 添加 Wazuh 配置片段
将 `ossec_config.xml` 的内容添加到 `/var/ossec/etc/ossec.conf` 的 `` 块中:
```
no
onepassword-events
/var/ossec/integrations/onepassword_events.py
1m
yes
yes
60
json
/var/ossec/logs/onepassword/onepassword-events.json
```
### 5. 验证并重启
```
sudo /var/ossec/bin/wazuh-logtest # optional — test decoder/rules manually
sudo /var/ossec/bin/ossec-control restart
```
### 6. 确认
```
# 检查脚本是否正在运行并写入事件
sudo tail -f /var/ossec/logs/onepassword/onepassword-events.json | python3 -m json.tool
# 检查状态(每个 endpoint 的 cursors)
sudo cat /var/ossec/queue/onepassword/onepassword-events-state.json
# 检查 Wazuh 是否正在生成 alerts
sudo tail -f /var/ossec/logs/alerts/alerts.json | grep 1password
```
## 配置参考
所有设置均通过环境变量控制,这些变量可以放置在 `/var/ossec/etc/onepassword-events.env` 环境文件中,或直接在进程环境中设置。
| 变量 | 默认值 | 描述 |
|---|---|---|
| `ONEPASSWORD_EVENTS_TOKEN` | _(必填)_ | 来自 1Password Events API 集成页面的 Bearer JWT |
| `ONEPASSWORD_EVENTS_TOKEN_FILE` | — | 包含该 token 的文件路径(上述变量的替代方案) |
| `ONEPASSWORD_EVENTS_BASE_URL` | `https://events.1password.eu` | API 基础 URL。EU 租户:`events.1password.eu`。US 租户:`events.1password.com` |
| `ONEPASSWORD_ENV_FILE` | `/var/ossec/etc/onepassword-events.env` | 启动时加载的环境文件路径 |
| `ONEPASSWORD_STATE_FILE` | `/var/ossec/queue/onepassword/onepassword-events-state.json` | 在两次运行之间持久化 API 游标的路径 |
| `ONEPASSWORD_OUTPUT_FILE` | `/var/ossec/logs/onepassword/onepassword-events.json` | 供 Wazuh 读取的 JSON 日志文件路径 |
| `ONEPASSWORD_BACKFILL_HOURS` | `24` | 首次运行(无现有游标)时要回填的小时数。最小 1,最大 720。 |
| `ONEPASSWORD_LIMIT` | `500` | 每个 API 页面的事件数。最小 1,最大 1000。 |
| `ONEPASSWORD_MAX_PAGES_PER_ENDPOINT` | `10` | 每次调用每个端点获取的最大页数。用于限制运行时间。 |
| `ONEPASSWORD_HTTP_TIMEOUT` | `60` | HTTP 请求超时时间(以秒为单位)。 |
| `ONEPASSWORD_SLEEP_BETWEEN_PAGES` | `0.25` | 分页请求之间的休眠时间(出于速率限制礼节)。 |
| `ONEPASSWORD_ENABLE_AUDIT_EVENTS` | `yes` | 设置为 `no` 可禁用审计事件端点。 |
| `ONEPASSWORD_ENABLE_SIGNIN_ATTEMPTS` | `yes` | 设置为 `no` 可禁用登录尝试端点。 |
| `ONEPASSWORD_ENABLE_ITEM_USAGES` | `yes` | 设置为 `no` 可禁用条目使用端点。 |
| `ONEPASSWORD_RUN_INTROSPECTION` | `yes` | 在轮询之前验证 token 并发现有权限的端点。如果您遇到自省速率限制,请禁用此选项。 |
| `ONEPASSWORD_DEBUG` | `no` | 将每个 HTTP 请求和页面结果记录到 stderr。 |
## 解码字段参考
解码器从每个事件中提取所有 JSON 字段。规则中使用的关键字段:
| 字段 | 来源 | 示例 |
|---|---|---|
| `op_integration` | 由脚本添加 | `1password` |
| `op_event_type` | 由脚本添加 | `audit_events`、`sign_in_attempts`、`item_usages` |
| `op_ingested_at` | 由脚本添加 | `2026-05-09T22:02:56Z` |
| `op_action` | `action` 的别名 | `ssotknv`、`patch`、`delete`、`secure-copy` |
| `op_object_type` | `object_type` 的别名 | `ssotkn`、`items`、`user`、`satoken` |
| `op_category` | `category` 的别名 | `success`、`firewall_failed`、`mfa_failed` |
| `op_type` | `type` 的别名 | `country_blocked`、`totp_bad`、`credentials_ok` |
| `op_event_timestamp` | `timestamp` 的别名 | `2026-05-09T04:42:41Z` |
| `op_uuid` | `uuid` 的别名 | `UNTSAALFEWVMF4PVTOIZVQYOM5` |
| `op_actor_email` | 从 `actor_details.email` 展平 | `user@example.com` |
| `op_actor_name` | 从 `actor_details.name` 展平 | `Jane Smith` |
| `op_user_email` | 从 `user.email` 展平 | `user@example.com` |
| `op_target_user_email` | 从 `target_user.email` 展平 | `user@example.com` |
| `op_client_ip` | 从 `client.ip_address` 展平 | `203.0.113.10` |
| `op_session_ip` | 从 `session.ip` 展平 | `203.0.113.10` |
嵌套对象(`client`、`user`、`target_user`、`actor_details`、`session`、`location`)也会以其原始嵌套形式保留。Wazuh 的 JSON 解码器会使用点表示法(例如 `client.ip_address`、`target_user.email`)公开它们,关联规则会利用这些表示法进行 `` 分组。
## 规则覆盖范围
### 基本规则
| 规则 ID | 级别 | 触发条件 | 描述 |
|---|---|---|---|
| 120000 | 4 | `op_integration = 1password` | 任何 1Password Events API 事件 |
| 120001 | 3 | `op_event_type = audit_events` | 接收到审计事件 |
| 120002 | 3 | `op_event_type = sign_in_attempts` | 接收到登录尝试事件 |
| 120003 | 3 | `op_event_type = item_usages` | 接收到条目使用事件 |
### 登录尝试
| 规则 ID | 级别 | 触发条件 | 描述 |
|---|---|---|---|
| 120010 | 3 | `op_category = success` | 成功登录 |
| 120011 | 7 | `op_category ∈ {credentials_failed, mfa_failed, sso_failed, modern_version_failed}` | 登录尝试失败 |
| 120012 | 9 | `op_category = firewall_failed` | 登录被防火墙策略阻止 |
| 120013 | 8 | `op_type ∈ 地理/IP 拦截值` AND category ≠ firewall_reported_success | 登录被地理/IP 访问策略阻止 |
| 120014 | 8 | `op_type ∈ MFA 失败/禁用值` | 与 MFA 相关的登录失败 |
| 120015 | 8 | `op_type ∈ SSO 失败值` | 与 SSO 相关的登录事件 |
| 120016 | 7 | `op_type ∈ 凭据/密钥失败值` | 凭据或密钥登录失败 |
| 120017 | 7 | `op_type ∈ {modern_version_missing, modern_version_old}` | 客户端版本过时或缺失 |
| 120018 | 5 | `op_category = firewall_reported_success` | 成功的登录匹配了防火墙规则(报告模式) |
**每条规则匹配的 op_type 值:**
- **120013**(地理/IP 拦截):`ip_blocked`、`country_blocked`、`continent_blocked`、`anonymous_blocked`、`all_blocked`
- **120014**(MFA):`mfa_missing`、`totp_bad`、`totp_timeout`、`totp_disabled`、`u2f_bad`、`u2f_timeout`、`u2f_disabled`、`duo_bad`、`duo_timeout`、`duo_disabled`、`duo_native_bad`
- **120015**(SSO):`sso_user_mismatch`、`non_sso_user`、`service_account_sso_denied`、`federated`
- **120016**(凭据):`password_secret_bad`、`platform_secret_bad`、`platform_secret_disabled`、`platform_secret_proxy`、`code_bad`、`code_timeout`、`code_disabled`
### 审计事件
| 规则 ID | 级别 | 触发条件 | 描述 |
|---|---|---|---|
| 120020 | 10 | `op_action ∈ 高风险集合` | 高风险管理操作(禁用 MFA/SSO/Duo、防火墙更改、撤销 token、批量设备解除授权、删除、清除) |
| 120021 | 10 | `op_object_type ∈ {sa, satoken}` + 特定操作 | 服务账户或服务账户 token 已更改 |
| 120022 | 9 | `op_object_type = sso` + SSO 配置操作 | SSO 配置已更改 |
| 120023 | 9 | `op_object_type ∈ {user, account}` + 安全操作 | 用户安全设置或生命周期已更改 |
| 120024 | 8 | `op_object_type ∈ {group, gm, gva, uva}` + 访问操作 | 组或保险库访问权限已更改 |
| 120025 | 9 | `op_object_type ∈ 保险库/条目类型` + `op_action ∈ {delete, purge, export, share, delshare, sendpkg}` | 敏感保险库或条目操作 |
| 120026 | 8 | `op_object_type = invite` + 配置操作 | 邀请或配置活动 |
| 120027 | 9 | `op_object_type = report` + `op_action ∈ {view, export}` | 报告已查看或导出 |
| 120028 | 10 | `op_action = unknown` | 未知审计操作 |
| 120029 | 10 | `op_object_type ∈ {satoken, ssotkn, device, ec, cred, vault}` + 非常规操作 | 敏感对象操作(token、设备、凭据、保险库密钥、电子邮件更改) |
| 120030 | 3 | `op_action ∈ {ssotknv, ssotknr}` 作用于 `ssotkn` | SSO token 已验证或轮换(常规) |
| 120031 | 3 | `op_action = dlgsess` 作用于 `dlgdsess` | 会话已委派(常规 SSO 事件) |
| 120032 | 5 | `op_object_type ∈ 保险库/条目类型` + `op_action = patch` | 保险库条目已修改 |
| 120033 | 9 | `op_action ∈ {vrfydmn, uvrfydmn, dvrfydmn}` | 已验证域名的添加、更新或移除 |
| 120034 | 6 | `op_action ∈ {trvlaway, trvlback}` | 旅行模式已启用或禁用 |
**规则 120020(高风险)匹配的操作:** `disblmfa`、`disblduo`、`disblsso`、`updatfw`、`trevoke`、`delete`、`purge`、`dealldev`
**规则 120023(用户/账户安全)匹配的操作:** `enblmfa`、`disblmfa`、`updatmfa`、`enblduo`、`disblduo`、`updatduo`、`changemp`、`changesk`、`changeks`、`beginr`、`completr`、`cancelr`、`activate`、`reauth`、`suspend`、`delete`、`reactive`
### 条目使用事件
| 规则 ID | 级别 | 触发条件 | 描述 |
|---|---|---|---|
| 120040 | 5 | `op_action = fill` | 条目用于自动填充 |
| 120041 | 7 | `op_action ∈ {reveal, secure-copy}` | 密钥已查看或安全复制 |
| 120042 | 9 | `op_action = export` | 条目已导出 |
| 120043 | 8 | `op_action = share` | 条目已外部共享 |
| 120044 | 4 | `op_action ∈ {server-create, server-fetch, server-update, enter-item-edit-mode, select-sso-provider, other}` | 常规条目使用活动 |
### 关联和频率规则
| 规则 ID | 级别 | 条件 | 描述 |
|---|---|---|---|
| 120060 | 10 | 规则 120011 在 5 分钟内触发 ≥5 次,同一个 `target_user.email` | 同一用户的多次登录失败 — 疑似暴力破解 |
| 120061 | 10 | 规则 120011 在 5 分钟内触发 ≥10 次,同一个 `client.ip_address` | 同一 IP 的多次登录失败 — 疑似暴力破解 |
| 120062 | 10 | 规则 120041 在 10 分钟内触发 ≥5 次,同一个 `user.email` | 同一用户多次查看或复制密钥 |
| 120063 | 11 | 规则 120042 在 10 分钟内触发 ≥3 次,同一个 `user.email` | 同一用户多次导出条目 |
| 120064 | 11 | 规则 120020 在 10 分钟内触发 ≥3 次 | 短时间内的多次高风险管理操作 |
## 日志和状态文件位置
| 路径 | 描述 |
|---|---|
| `/var/ossec/integrations/onepassword_events.py` | 轮询脚本 |
| `/var/ossec/etc/onepassword-events.env` | 配置(包含 token — 请限制访问权限) |
| `/var/ossec/logs/onepassword/onepassword-events.json` | 供 Wazuh 读取的实时 JSON 日志文件 |
| `/var/ossec/queue/onepassword/onepassword-events-state.json` | 持久化的 API 游标(每个端点一个) |
## 故障排除
**没有事件出现**
1. 确认脚本能够正常运行并干净退出:
sudo -u wazuh /var/ossec/integrations/onepassword_events.py
echo $? # 应该为 0
2. 启用调试日志记录:在环境文件中添加 `ONEPASSWORD_DEBUG=yes` 并重新运行。
3. 检查输出文件是否正在写入:
sudo wc -l /var/ossec/logs/onepassword/onepassword-events.json
**HTTP 401 Unauthorized**
- 验证 token 设置正确且尚未过期。
- 确保该 token 已被授予所需的功能范围(`auditevents`、`signinattempts`、`itemusages`)。
- 确认 `ONEPASSWORD_EVENTS_BASE_URL` 与您的租户区域匹配(`.eu` 与 `.com`)。
**事件出现在归档中但未出现在告警中**
- 无论是否触发规则,Wazuh 都会归档所有已解码的事件。
- 如果事件进入了 `archives.json` 但未进入 `alerts.json`,说明解码器在工作,但没有规则匹配。请使用 `wazuh-logtest` 来准确追踪匹配了哪条规则(如果有的话)。
- 检查解码器和规则文件是否位于正确的目录中,以及 Wazuh manager 在部署后是否已重启。
**状态文件损坏 / 事件正在被重新获取**
- 脚本会自动将损坏的状态文件移至一旁,并从回填窗口重新开始。
- 要有意重置某个端点的状态,请从状态文件中删除 `endpoints.` 键,或者直接删除该文件。
**存储在文件中的 Token(适用于 secrets 管理器)**
设置 `ONEPASSWORD_EVENTS_TOKEN_FILE=/run/secrets/op_token` 并确保文件可被 `wazuh` 用户读取。如果两者都设置了,`ONEPASSWORD_EVENTS_TOKEN` 优先。
## 安全说明
- 环境文件包含 API bearer token。权限设置为 `640`(属主 `root`,属组 `wazuh`),因此只有 Wazuh 进程可以读取它。
- 脚本通过 wodle `command` 块以 `wazuh` 用户(而非 root)身份运行。
- 输出日志文件和状态文件目录使用 `750` 权限创建。
- API token 永远不会写入输出日志或状态文件中。
## 许可证
MIT License — 详见 [LICENSE](LICENSE)。
标签:1Password, AMSI绕过, API集成, JSON解析, PB级数据处理, URL发现, Wazuh, 可观测性, 告警关联, 威胁检测, 安全事件, 安全检测, 安全运维, 审计日志, 密码管理器, 数字取证, 日志采集, 自动化脚本, 身份验证监控, 逆向工具