PiotrMackowski/ClosedSSPM
GitHub: PiotrMackowski/ClosedSSPM
一款开源的 SaaS 安全态势管理工具,用于审计多种云平台的安全配置合规性。
Stars: 1 | Forks: 0
# ClosedSSPM
[](https://github.com/PiotrMackowski/ClosedSSPM/actions/workflows/ci.yml)
[](https://github.com/PiotrMackowski/ClosedSSPM/actions/workflows/codeql.yml)
[](https://goreportcard.com/report/github.com/PiotrMackowski/ClosedSSPM)
[](LICENSE)
[](go.mod)
[](https://github.com/PiotrMackowski/ClosedSSPM/releases)
[](https://www.bestpractices.dev/projects/12061)
[](https://scorecard.dev/viewer/?uri=github.com/PiotrMackowski/ClosedSSPM)
开源 SaaS 安全态势管理 (SSPM) 工具。用于审计 ServiceNow、Snowflake、Google Workspace 和 Microsoft Entra ID 等 SaaS 平台的安全配置错误。

## 功能特性
- **多平台架构** — 可插拔的连接器注册表;无需修改核心代码即可添加新的 SaaS 平台 (ServiceNow, Snowflake, Google Workspace, Entra ID)
- **166 项安全检查** — 覆盖四个平台,涉及身份、访问控制、配置、网络、脚本、集成、密钥扫描、OAuth 授权和凭证规范
- **策略即代码** — 审计检查使用 YAML 定义,易于通过自定义策略进行扩展
- **嵌入式策略** — 所有检查内置于二进制文件中;运行时无需外部文件
- **HTML 报告** — 独立、深色主题的 HTML 报告,包含态势评分
- **JSON 输出** — 用于流水线集成的机器可读输出
- **CSV 导出** — 适用于合规工作流的各种电子表格友好输出
- **MCP server** — 通过模型上下文协议 (Model Context Protocol) 进行 AI 辅助审计分析 (支持 Claude, OpenCode 等)
- **离线分析** — 一次收集数据,通过快照持久化进行多次分析
- **并行收集** — 具有可配置速率限制的并发 API 请求
- **SARIF 输出** — [SARIF 2.1.0](https://docs.oasis-open.org/sarif/sarif/v2.1.0/sarif-v2.1.0.html) 格式,用于 GitHub Code Scanning 集成
- **GitHub Action** — 使用 `PiotrMackowski/ClosedSSPM` 直接在 CI/CD 流水线中运行审计
- **`--fail-on` 阈值** — 当发现结果达到或超过严重级别时以代码 2 退出
## 安装
### Homebrew (macOS / Linux)
```
brew tap PiotrMackowski/closedsspm
brew install closedsspm
```
### 二进制文件 (GitHub Releases)
从 [Releases](https://github.com/PiotrMackowski/ClosedSSPM/releases) 页面下载适用于您平台的最新版本。
```
# Linux amd64
curl -Lo closedsspm.tar.gz https://github.com/PiotrMackowski/ClosedSSPM/releases/latest/download/closedsspm_Linux_amd64.tar.gz
tar xzf closedsspm.tar.gz
sudo mv closedsspm closedsspm-mcp /usr/local/bin/
```
### Debian / Ubuntu (.deb)
```
# 从最新版本下载 .deb
sudo dpkg -i closedsspm_*.deb
```
### Red Hat / Fedora (.rpm)
```
# 从最新版本下载 .rpm
sudo rpm -i closedsspm_*.rpm
```
### Docker
```
docker pull ghcr.io/piotrmackowski/closedsspm:latest
# 运行审计
docker run --rm \
-e SNOW_INSTANCE=https://mycompany.service-now.com \
-e SNOW_USERNAME=audit_user \
-e SNOW_PASSWORD=secret \
-v "$(pwd):/out" \
ghcr.io/piotrmackowski/closedsspm:latest audit --output /out/report.html
```
### 从源码构建
```
git clone https://github.com/PiotrMackowski/ClosedSSPM.git
cd ClosedSSPM
make all
```
## 快速入门
### 运行审计
```
# --- 选项 1:Basic auth ---
export SNOW_INSTANCE=https://mycompany.service-now.com
export SNOW_USERNAME=audit_user
export SNOW_PASSWORD=secret
# --- 选项 2:OAuth (client credentials) ---
export SNOW_INSTANCE=https://mycompany.service-now.com
export SNOW_CLIENT_ID=your_client_id
export SNOW_CLIENT_SECRET=your_client_secret
# --- 选项 3:Key pair (JWT bearer) ---
export SNOW_INSTANCE=https://mycompany.service-now.com
export SNOW_CLIENT_ID=your_client_id
export SNOW_CLIENT_SECRET=your_client_secret
export SNOW_PRIVATE_KEY_PATH=/path/to/private-key.pem
export SNOW_KEY_ID=your_key_id
export SNOW_JWT_USER=svc_audit_user
# --- 选项 4:API Key ---
export SNOW_INSTANCE=https://mycompany.service-now.com
export SNOW_API_KEY=your_api_key
# 完整审计:collect + evaluate + report (ServiceNow 是默认平台)
closedsspm audit --output report.html
# 显式指定平台
closedsspm audit --platform servicenow --output report.html
# 或分步执行:
closedsspm collect --output snapshot.json
closedsspm evaluate --snapshot snapshot.json --output report.html
```
### Snowflake 审计
```
# --- 选项 1:Basic auth ---
export SNOWFLAKE_ACCOUNT=xy12345.us-east-1
export SNOWFLAKE_USER=audit_user
export SNOWFLAKE_PASSWORD=secret
# --- 选项 2:Key pair (JWT) ---
export SNOWFLAKE_ACCOUNT=xy12345.us-east-1
export SNOWFLAKE_USER=audit_user
export SNOWFLAKE_PRIVATE_KEY_PATH=/path/to/rsa_key.p8
# --- 选项 3:OAuth ---
export SNOWFLAKE_ACCOUNT=xy12345.us-east-1
export SNOWFLAKE_TOKEN=your_oauth_access_token
# --- 选项 4:Programmatic Access Token (PAT) ---
export SNOWFLAKE_ACCOUNT=xy12345.us-east-1
export SNOWFLAKE_USER=audit_user
export SNOWFLAKE_PAT=your_programmatic_access_token
# 可选:覆盖默认值
export SNOWFLAKE_ROLE=SECURITYADMIN # default: SECURITYADMIN
export SNOWFLAKE_WAREHOUSE=COMPUTE_WH # default: COMPUTE_WH
# 运行审计
closedsspm audit --platform snowflake --output report.html
```
### Google Workspace 审计
```
# 具有域范围委派的服务账号
export GW_CREDENTIALS_FILE=/path/to/service-account.json
export GW_DELEGATED_USER=admin@yourdomain.com
# 运行审计
closedsspm audit --platform googleworkspace --output report.html
```
### Entra ID (Azure AD) 审计
```
# 具有 Microsoft Graph API 权限的 App registration
export ENTRA_TENANT_ID=your-tenant-id
export ENTRA_CLIENT_ID=your-client-id
export ENTRA_CLIENT_SECRET=your-client-secret
# 运行审计
closedsspm audit --platform entra --output report.html
```
### 列出可用检查
```
closedsspm checks list
```
### MCP Server (AI 辅助分析)
```
# 使用快照启动 MCP server
closedsspm mcp --snapshot snapshot.json
```
添加到您的 MCP 客户端配置:
```
{
"mcpServers": {
"closedsspm": {
"command": "/path/to/closedsspm",
"args": ["mcp", "--snapshot", "/path/to/snapshot.json"]
}
}
}
```
### 自定义策略目录
默认情况下,二进制文件使用其嵌入的策略。要使用外部策略进行覆盖:
```
closedsspm audit --policies /path/to/my/policies --output report.html
```
## CLI 参考
### `closedsspm audit`
运行完整的安全审计:连接到 SaaS 平台,收集数据,评估策略,并生成报告。
```
Flags:
--platform string SaaS platform to audit (default "servicenow")
--instance string Platform instance URL (or set via env var)
--output string Output file path (default "report.html")
--format string Report format: html, json, csv, or sarif (default "html")
--policies string Path to custom policies directory (default: embedded)
--save-snapshot string Also save the raw snapshot to this file
--concurrency int Max parallel API requests (default 5)
--rate-limit float Max API requests per second (default 10)
--fail-on string Exit with code 2 if findings at or above this severity (CRITICAL, HIGH, MEDIUM, LOW, INFO)
```
### `closedsspm collect`
从 SaaS 平台收集数据并保存快照以供离线分析。
```
Flags:
--platform string SaaS platform to collect from (default "servicenow")
--instance string Platform instance URL (or set via env var)
--output string Output snapshot file path (default "snapshot.json")
--concurrency int Max parallel API requests (default 5)
--rate-limit float Max API requests per second (default 10)
```
### `closedsspm evaluate`
针对先前保存的快照评估策略。
```
Flags:
--snapshot string Path to snapshot file (default "snapshot.json")
--output string Output file path (default "report.html")
--format string Report format: html, json, csv, or sarif (default "html")
--policies string Path to custom policies directory (default: embedded)
--fail-on string Exit with code 2 if findings at or above this severity (CRITICAL, HIGH, MEDIUM, LOW, INFO)
```
### `closedsspm mcp`
通过 stdio 启动模型上下文协议服务器,用于 AI 辅助审计分析。
```
Flags:
--snapshot string Path to snapshot file (default "snapshot.json")
--policies string Path to custom policies directory (default: embedded)
```
### `closedsspm checks list`
列出所有可用的安全检查。
```
Flags:
--policies string Path to custom policies directory (default: embedded)
```
### 环境变量
所有凭证均从环境变量中读取。
每个平台使用其自己的一组环境变量。`--platform` 标志 (默认: `servicenow`) 决定了读取哪些变量。
#### ServiceNow (`--platform servicenow`)
| Variable | Description | Required |
|----------|-------------|----------|
| `SNOW_INSTANCE` | ServiceNow 实例 URL (例如 `https://mycompany.service-now.com`) | Yes |
| `SNOW_USERNAME` | 用于 Basic 认证的用户名 | For basic auth |
| `SNOW_PASSWORD` | 用于 Basic 认证的密码 | For basic auth |
| `SNOW_CLIENT_ID` | OAuth 2.0 客户端 ID | For OAuth / key pair |
| `SNOW_CLIENT_SECRET` | OAuth 2.0 客户端密钥 | For OAuth / key pair |
| `SNOW_PRIVATE_KEY_PATH` | RSA 私钥 PEM 文件路径 | For key pair |
| `SNOW_KEY_ID` | 来自 ServiceNow JWT Verifier Map 的密钥 ID | For key pair |
| `SNOW_JWT_USER` | 用于 JWT `sub` 声明的 ServiceNow 用户名 (不能是 admin) | For key pair |
| `SNOW_API_KEY` | API 密钥令牌 (来自 REST API Key 表) | For API key auth |
**认证方式根据设置的变量自动检测**:
| Priority | Method | Required Variables |
|----------|--------|--------------------|
| 1 | API key | `SNOW_API_KEY` |
| 2 | Key pair (JWT bearer) | `SNOW_CLIENT_ID` + `SNOW_CLIENT_SECRET` + `SNOW_PRIVATE_KEY_PATH` |
| 3 | OAuth (client credentials) | `SNOW_CLIENT_ID` + `SNOW_CLIENT_SECRET` |
| 4 | Basic | `SNOW_USERNAME` + `SNOW_PASSWORD` |
#### Snowflake (`--platform snowflake`)
| Variable | Description | Required |
|----------|-------------|----------|
| `SNOWFLAKE_ACCOUNT` | 账户标识符 (例如 `xy12345.us-east-1`) | Yes |
| `SNOWFLAKE_USER` | 用户名 | For basic / key pair auth |
| `SNOWFLAKE_PASSWORD` | 密码 | For basic auth |
| `SNOWFLAKE_PRIVATE_KEY_PATH` | RSA 私钥 PEM 文件路径 | For key pair (JWT) |
| `SNOWFLAKE_TOKEN` | OAuth 访问令牌 | For OAuth |
| `SNOWFLAKE_PAT` | 程序化访问令牌 | For PAT auth |
| `SNOWFLAKE_ROLE` | 要担任的角色 (默认: `SECURITYADMIN`) | No |
| `SNOWFLAKE_WAREHOUSE` | 用于查询的 Warehouse (默认: `COMPUTE_WH`) | No |
| `SNOWFLAKE_DATABASE` | 数据库 (默认: `SNOWFLAKE` 用于 ACCOUNT_USAGE 视图) | No |
**认证方式根据设置的变量自动检测**:
| Priority | Method | Required Variables |
|----------|--------|--------------------|
| 1 | Key pair (JWT) | `SNOWFLAKE_USER` + `SNOWFLAKE_PRIVATE_KEY_PATH` |
| 2 | PAT | `SNOWFLAKE_USER` + `SNOWFLAKE_PAT` |
| 3 | OAuth | `SNOWFLAKE_TOKEN` |
| 4 | Basic | `SNOWFLAKE_USER` + `SNOWFLAKE_PASSWORD` |
#### Google Workspace (`--platform googleworkspace`)
| Variable | Description | Required |
|----------|-------------|----------|
| `GW_CREDENTIALS_FILE` | Google 服务账户 JSON 凭证文件路径 | Yes |
| `GW_DELEGATED_USER` | 用于全域委派的 Google Workspace 管理员电子邮件 | Yes |
**前提条件:**
1. 创建一个启用了全域委派的 GCP 服务账户
2. 在 Google Workspace 管理控制台 → 安全性 → API 控制 → 全域委派中,为该服务账户授予以下 OAuth scope:
- `https://www.googleapis.com/auth/admin.directory.user.readonly`
- `https://www.googleapis.com/auth/admin.directory.user.security`
- `https://www.googleapis.com/auth/admin.reports.audit.readonly`
#### Entra ID (`--platform entra`)
| Variable | Description | Required |
|----------|-------------|----------|
| `ENTRA_TENANT_ID` | Azure AD 租户 ID | Yes |
| `ENTRA_CLIENT_ID` | 应用注册客户端 (应用程序) ID | Yes |
| `ENTRA_CLIENT_SECRET` | 应用注册客户端密钥 | Yes |
**前提条件:**
1. 在 Entra ID (Azure AD) 中创建应用注册
2. 授予以下 Microsoft Graph **Application** 权限:
- `Application.Read.All`
- `Directory.Read.All`
- `AuditLog.Read.All`
3. 为权限授予管理员同意
## 架构
```
closedsspm/
├── cmd/
│ ├── closedsspm/
│ │ ├── main.go # CLI commands (platform-agnostic)
│ │ ├── main_test.go # CLI helper tests
│ │ └── platforms.go # Blank imports to register platform connectors
│ └── mcp/ # Standalone MCP server
├── internal/
│ ├── collector/ # Collector interface & snapshot model
│ ├── connector/
│ │ ├── registry.go # Platform connector registry
│ │ ├── entra/ # Microsoft Entra ID (Azure AD) client & collector
│ │ ├── googleworkspace/ # Google Workspace Admin SDK client & collector
│ │ ├── servicenow/ # ServiceNow API client & collector
│ │ └── snowflake/ # Snowflake SQL client & collector
│ ├── finding/ # Finding model & severity
│ ├── mcpserver/ # MCP server implementation
│ ├── policy/ # Policy engine (YAML loading & evaluation)
│ └── report/
│ ├── csv/ # CSV report generator
│ ├── html/ # HTML report generator
│ └── json/ # JSON report generator
│ ├── sarif/ # SARIF 2.1.0 report generator
└── policies/
├── entra/ # Entra ID policy definitions (YAML, embedded at build)
├── googleworkspace/ # Google Workspace policy definitions (YAML, embedded at build)
├── servicenow/ # ServiceNow policy definitions (YAML, embedded at build)
└── snowflake/ # Snowflake policy definitions (YAML, embedded at build)
```
## 子项目
| Repository | Purpose | Status |
|------------|---------|--------|
| [homebrew-closedsspm](https://github.com/PiotrMackowski/homebrew-closedsspm) | Homebrew tap — 托管用于 `brew install closedsspm` 的 formula | Active — 每次发布时由 goreleaser 自动更新 |
## 安全检查
### ServiceNow (86 项检查)
| Category | Count | Examples |
|----------|-------|---------|
| **ACL** | 9 | 未受保护的 ACL,通配符角色,公开访问,deny-unless 审计 |
| **Roles** | 10 | 管理员角色分配,提权,角色包含,security_admin,impersonator,oauth_admin |
| **Scripts** | 6 | eval() 使用,客户端可调用脚本包含,全局 UI 脚本 |
| **Integrations** | 7 | 未认证端点,Basic auth,未验证的 MID 服务器 |
| **Instance Config** | 32 | HTTPS 强制,会话超时,密码策略,CSRF,XSS 防护,TLS,沙箱,SAML 签名,SSO 绕过 |
| **Users** | 5 | 从未登录的账户,被锁定的活跃用户,服务账户规范 |
| **SAST** | 17 | 硬编码凭证,eval(),GlideEvaluator,不安全的 HTTP,查询注入,XSS sinks,工作流绕过 |
### Snowflake (55 项检查)
| Category | Count | Examples |
|----------|-------|---------|
| **IAM** | 8 | 未启用 MFA,ACCOUNTADMIN/SYSADMIN 默认角色,仅密码认证,带有角色的禁用用户,缺少 email/owner,MFA 注册提示 |
| **ACL** | 8 | ACCOUNTADMIN/SECURITYADMIN/SYSADMIN 授权,MANAGE GRANTS 权限,GRANT OPTION,角色所有权,ACCOUNT 所有权 |
| **Network** | 3 | 缺少网络策略,无阻止 IP 列表,网络策略 IP 限制摘要 |
| **Config** | 22 | 未加密复制,存储集成,数据渗透控制,加密密钥更新,会话/密码策略,Warehouse 监视器,MFA 缓存,会话保活,OAuth 角色阻止,网络策略执行 |
| **Data Sharing** | 1 | 出站共享审查 |
| **Audit** | 3 | 登录失败,无 MFA 登录,仅密码登录 |
| **SAST** | 10 | 存储过程/UDF 中的 AWS 密钥,私钥,eval(),new Function(),SQL 注入,subprocess/os.system |
### Google Workspace (10 项检查)
| Category | Count | Examples |
|----------|-------|---------|
| **OAuth** | 10 | 完整 Gmail/Drive/Admin SDK 访问令牌,Gmail 发送权限,联系人/日历访问,匿名应用令牌,原生应用令牌,OAuth 授权事件,已暂停用户账户 |
### Entra ID (15 项检查)
| Category | Count | Examples |
|----------|-------|---------|
| **OAuth Permissions** | 8 | Mail.ReadWrite, Mail.Send, Directory.ReadWrite.All, Files.ReadWrite.All, User.ReadWrite.All, RoleManagement.ReadWrite, Sites.FullControl.All, application permissions |
| **Credential Hygiene** | 2 | 过期凭证,密码凭证 (对比证书) |
| **OAuth Governance** | 1 | 租户范围的管理员同意授权 |
| **Application Registration** | 1 | 多租户应用注册 |
| **Application Governance** | 1 | 无所有者的应用注册 |
| **Access Control** | 1 | 不需要用户分配的服务主体 |
| **Asset Hygiene** | 1 | 已禁用的服务主体 |
运行 `closedsspm checks list` 查看所有单独的规则。
## MCP Server 接口
MCP server 通过 **stdio transport**暴露 6 个工具和 2 个资源,用于 AI 辅助的安全审计分析。
### 工具
| Tool | Parameters | Description |
|------|-----------|-------------|
| `list_findings` | `severity?` `category?` | 列出发现结果,可选按严重程度 (CRITICAL/HIGH/MEDIUM/LOW/INFO) 或类别筛选 |
| `get_finding` | `finding_id` (required) | 获取特定发现结果的详细信息 |
| `get_summary` | _(none)_ | 包含态势评分和按严重程度/类别统计发现数量的整体审计摘要 |
| `query_snapshot` | `table` (required) `field?` `value?` `limit?` | 从快照中查询原始 ServiceNow 记录 (默认限制: 50,最大: 500) |
| `suggest_remediation` | `finding_id` (required) | 获取特定发现结果的修复步骤和上下文 |
| `list_tables` | _(none)_ | 列出所有已收集的表及其记录数 |
### 资源
| URI | Description |
|-----|-------------|
| `closedsspm://summary` | 审计态势摘要 (JSON) |
| `closedsspm://snapshot/meta` | 快照元数据:平台,实例 URL,收集时间,表数量 (JSON) |
## GitHub Action
直接在您的 CI/CD 流水线中运行 ClosedSSPM 审计:
```
- name: Run ClosedSSPM audit
id: audit
uses: PiotrMackowski/ClosedSSPM@v0 # or pin to a specific release tag
with:
instance: ${{ secrets.SNOW_INSTANCE }}
# --- Basic auth ---
username: ${{ secrets.SNOW_USERNAME }}
password: ${{ secrets.SNOW_PASSWORD }}
# --- OR OAuth (client credentials) ---
# client-id: ${{ secrets.SNOW_CLIENT_ID }}
# client-secret: ${{ secrets.SNOW_CLIENT_SECRET }}
# --- OR Key pair (JWT bearer) ---
# client-id: ${{ secrets.SNOW_CLIENT_ID }}
# client-secret: ${{ secrets.SNOW_CLIENT_SECRET }}
# private-key: ${{ secrets.SNOW_PRIVATE_KEY }}
# key-id: ${{ secrets.SNOW_KEY_ID }}
# jwt-user: ${{ secrets.SNOW_JWT_USER }}
# --- OR API Key ---
# api-key: ${{ secrets.SNOW_API_KEY }}
format: sarif
fail-on: HIGH
- name: Upload SARIF to GitHub Code Scanning
if: always()
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: ${{ steps.audit.outputs.sarif-path }}
```
### Action Inputs
| Input | Required | Default | Description |
|-------|----------|---------|-------------|
| `instance` | Yes | — | 平台实例 URL |
| `platform` | No | `servicenow` | 要审计的 SaaS 平台 |
| `username` | No | — | 用于 Basic auth 的用户名 |
| `password` | No | — | 用于 Basic auth 的密码 |
| `client-id` | No | — | OAuth 2.0 客户端 ID |
| `client-secret` | No | — | OAuth 2.0 客户端密钥 |
| `private-key` | No | — | 用于 JWT 密钥对认证的 RSA 私钥 PEM 内容 |
| `key-id` | No | — | 来自 ServiceNow JWT Verifier Map 的密钥 ID |
| `jwt-user` | No | — | 用于 JWT `sub` 声明的 ServiceNow 用户名 (不能是 admin) |
| `api-key` | No | — | ServiceNow API 密钥令牌 |
| `format` | No | `sarif` | 报告格式:html, json, csv, 或 sarif |
| `fail-on` | No | `none` | 如果发现结果达到/超过以下严重级别则失败:CRITICAL, HIGH, MEDIUM, LOW, INFO |
所有凭证输入应通过 [GitHub encrypted secrets](https://docs.github.com/en/actions/security-for-github-actions/security-guides/using-secrets-in-github-actions) 传递。认证方式根据提供的输入自动检测 (优先级与 CLI 相同)。
### Action Outputs
| Output | Description |
|--------|-------------|
| `report-path` | 生成的报告文件路径 |
| `finding-count` | 发现结果总数 |
| `posture-score` | 态势评分等级 (A–F) |
| `sarif-path` | SARIF 文件路径 (仅当 format=sarif 时) |
## 安全最佳实践
- 快照可能包含敏感数据 — 请将其视为机密
- MCP server **仅使用 stdio transport** (无网络暴露)
- 该工具是**只读的** — 它永远不会写入您的 SaaS 平台
- ServiceNow 审计用户应具有**只读**角色
### 最小 ServiceNow 权限
创建一个具有以下角色的专用审计用户:
- `itil` (对大多数表的读取权限)
- `security_admin` (对 ACL 和安全配置的读取权限)
## DefectDojo 集成
ClosedSSPM 的 SARIF 输出可以直接导入到 [DefectDojo](https://github.com/DefectDojo/django-DefectDojo) 以进行集中化的漏洞管理。生成 SARIF 报告并通过 DefectDojo API 上传:
```
# 生成 SARIF 报告
closedsspm audit --platform servicenow --format sarif --output report.sarif
# 导入到 DefectDojo
curl -X POST "https://your-defectdojo.example.com/api/v2/reimport-scan/" \
-H "Authorization: Token YOUR_DEFECTDOJO_API_TOKEN" \
-F "scan_type=SARIF" \
-F "file=@report.sarif" \
-F "product_name=ClosedSSPM" \
-F "engagement_name=SSPM Audit" \
-F "auto_create_context=True"
```
使用 `reimport-scan` (而不是 `import-scan`) 在连续运行中去重发现结果。
## 编写自定义策略
策略是按平台组织在 `policies/` 目录中的 YAML 文件 (例如 `policies/servicenow/`):
```
id: CUSTOM-001
title: "Custom check description"
description: "Detailed explanation of what this checks"
severity: HIGH # CRITICAL, HIGH, MEDIUM, LOW, INFO
category: Custom
platform: servicenow
query:
table: sys_security_acl
field_conditions:
- field: "active"
operator: "equals" # empty, not_empty, equals, not_equals, contains
value: "true"
remediation: "How to fix the issue"
references:
- "https://docs.example.com"
```
## 测试
运行完整测试套件:
```
make test
# 或直接:
go test ./...
```
运行静态分析:
```
make vet
go vet ./...
```
所有合并请求必须在合并前通过 CI (测试 + `go vet`)。
## 贡献
欢迎贡献。请遵循以下准则:
1. **先开启一个 issue** — 在开始工作之前描述 bug 或功能
2. **Fork 并分支** — 从 `main` 创建一个功能分支
3. **遵循现有模式** — 匹配项目的代码风格和结构
4. **添加测试** — 新功能和错误修复应包含测试
5. **所有 CI 检查必须通过** — 测试,`go vet`,CodeQL,和 Trivy 扫描
6. **每个 PR 一个更改** — 保持合并请求专注且易于审查
请参阅 [SECURITY.md](SECURITY.md) 以报告漏洞。
## 报告问题
发现 bug 或有功能请求?请在 [GitHub Issues](https://github.com/PiotrMackowski/ClosedSSPM/issues) 页面上开启一个 issue。
报告 bug 时,请包括:
- ClosedSSPM 版本 (`closedsspm --version`)
- 操作系统和架构
- 重现问题的步骤
- 预期与实际行为
- 任何相关的错误输出
## 报告漏洞
请使用 [GitHub Security Advisories](https://github.com/PiotrMackowski/ClosedSSPM/security/advisories/new) 私下报告漏洞。有关详细信息,包括响应时间表和范围,请参阅 [SECURITY.md](SECURITY.md)。
## 开发
本项目使用 [OpenCode](https://github.com/anomalyco/opencode) 进行 AI 辅助编码开发。
## 许可证
Apache 2.0 — 请参阅 [LICENSE](LICENSE)
标签:Azure AD, CI/CD安全, EVTX分析, Golang, Google Workspace安全, HTML报告, Llama, LNA, Microsoft Entra ID, Modbus, OAuth安全, OpenSSF, SaaS安全态势管理, ServiceNow安全, Snowflake安全, SSPM, Streamlit, Web报告查看器, YAML, 反取证, 安全合规, 安全库, 安全编程, 安全评估, 日志审计, 策略即代码, 网络代理, 聊天机器人安全, 访问控制, 误配置检测, 请求拦截, 身份安全