blackwell-systems/gcp-iam-emulator

GitHub: blackwell-systems/gcp-iam-emulator

本地GCP IAM策略引擎,用于在无需云凭证的情况下进行确定性授权测试和CI/CD集成。

Stars: 1 | Forks: 0

# GCP IAM 模拟器 [![Blackwell Systems](https://static.pigsec.cn/wp-content/uploads/repos/2026/04/dd77940fd7175006.svg)](https://github.com/blackwell-systems) [![Go Reference](https://pkg.go.dev/badge/github.com/blackwell-systems/gcp-iam-emulator.svg)](https://pkg.go.dev/github.com/blackwell-systems/gcp-iam-emulator) [![Go Version](https://img.shields.io/badge/go-1.24+-blue.svg)](https://go.dev/) [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE) 这是 **Blackwell 本地 IAM 控制平面**的核心组件。它负责评估 IAM 策略,并向服务模拟器(Secret Manager、KMS)指示是允许还是拒绝请求。 与模拟器(允许一切)或观察器(事后记录)不同,它会在请求到达数据平面之前**主动执行**策略。 ## 快速示例 ``` # policy.yaml - 正确定义测试所需内容 roles: roles/custom.ciRunner: permissions: - secretmanager.secrets.get - secretmanager.versions.access - cloudkms.cryptoKeys.encrypt groups: developers: members: - user:alice@example.com - user:bob@example.com projects: test-project: bindings: - role: roles/viewer members: - group:developers - role: roles/custom.ciRunner members: - serviceAccount:ci@test-project.iam.gserviceaccount.com condition: expression: 'resource.name.startsWith("projects/test-project/secrets/prod-")' title: "CI limited to production secrets" ``` ``` # 从严格模式开始(默认 - 捕获配置错误) server --config policy.yaml --trace # HTTP REST API server --config policy.yaml --http-port 8081 # 配置更改时热重载 server --config policy.yaml --watch ``` **结果:** 与您的策略匹配的本地 IAM 决策、授权逻辑的离线测试、无需 GCP 凭证的 CI 就绪。 ## 使用模式 **独立运行** - 作为策略引擎独立运行: ``` server --config policy.yaml # 单个 IAM 服务器,用于自定义模拟器 ``` **统一生态系统** - 与 [gcp-emulator](https://github.com/blackwell-systems/gcp-emulator) 一起使用,在单个进程中进行统一的多服务测试: ``` go install github.com/blackwell-systems/gcp-emulator/cmd/gcp-emulator@latest gcp-emulator --policy policy.yaml --iam-mode strict # IAM + Secret Manager + KMS + Eventarc # 单个进程,单个端口,单个策略文件 ``` **选择独立模式进行自定义集成,选择 gcp-emulator 获取完整的 GCP 模拟器栈。** ## 如何提供主体 模拟器需要知道**谁**在发出每个请求。通过元数据/标头提供身份: ### gRPC 元数据(Go SDK 示例) ``` import "google.golang.org/grpc/metadata" // Inject principal identity md := metadata.Pairs("x-emulator-principal", "serviceAccount:ci@project.iam.gserviceaccount.com") ctx = metadata.NewOutgoingContext(context.Background(), md) // Now use ctx for API calls - emulator sees the principal client.GetSecretVersion(ctx, &secretmanagerpb.GetSecretVersionRequest{...}) ``` ### HTTP 标头(REST API / curl) ``` curl -X POST http://localhost:8081/v1/projects/test/secrets/api-key:testIamPermissions \ -H "X-Emulator-Principal: serviceAccount:ci@project.iam.gserviceaccount.com" \ -H "Content-Type: application/json" \ -d '{"permissions": ["secretmanager.secrets.get"]}' ``` ### 支持的主体格式 - **服务账号:** `serviceAccount:name@project.iam.gserviceaccount.com` - **用户:** `user:alice@example.com` - **群组:** `group:eng-team@example.com`(在 policy.yaml 中定义群组) - **所有已认证用户:** `allAuthenticatedUsers` - **公开:** `allUsers` ### 与模拟器集成 与 Secret Manager / KMS 模拟器一起使用时,数据平面模拟器会自动将主体转发到 IAM 控制平面: ``` // Your test code sets principal once ctx = metadata.NewOutgoingContext(ctx, metadata.Pairs( "x-emulator-principal", "serviceAccount:ci@test.iam.gserviceaccount.com", )) // Secret Manager emulator forwards principal to IAM emulator automatically client.AccessSecretVersion(ctx, &secretmanagerpb.AccessSecretVersionRequest{...}) // ↓ Internally: IAM checks if ci@test.iam can secretmanager.versions.access ``` **无需额外配置** - 模拟器生态系统会自动处理主体传播. ## 架构 — 控制平面位置 ``` ┌─────────────────────────────────────────┐ │ Your Application Code │ │ (GCP client libraries) │ └────────────────┬────────────────────────┘ │ ▼ ┌─────────────────────────────────────────┐ │ DATA PLANES │ │ • Secret Manager Emulator │ │ • KMS Emulator │ │ • (Future: Tasks, Pub/Sub, Storage) │ │ │ │ Each checks IAM before data access │ └────────────────┬────────────────────────┘ │ │ CheckPermission(principal, resource, permission) ▼ ┌─────────────────────────────────────────┐ │ CONTROL PLANE (THIS REPO) │◄── You are here │ IAM Emulator — Policy Engine │ │ │ │ Evaluates: │ │ • Role bindings │ │ • Group memberships │ │ • Conditional policies (CEL) │ │ • Resource-level policy evaluation │ │ │ │ Returns: Allow / Deny │ └─────────────────────────────────────────┘ ``` **这是执行边界。** 请求在数据访问之前在此处进行授权。 | 方法 | 示例 | 时机 | 行为 | |----------|---------|------|----------| | 模拟器 | 标准模拟器 | 从不 | 始终允许 | | 观察器 | 执行后分析 | 之后 | 记录您使用的 | | **控制平面** | **Blackwell IAM** | **之前** | **拒绝未授权** | ## 确定性一致性(CI/CD 杀手级功能) **真实 GCP IAM 的问题:** GCP IAM 是**最终一致**的。当您创建或更新策略绑定时: - 更改可能需要 **1-60 秒** 才能在全球传播 - 您的测试变得**不稳定**(有时通过,有时失败) - CI/CD 管道出现**随机失败**,无法复现 **Blackwell 的优势:** 此模拟器是**强一致**的。策略更改: - **即时**(0ms 传播延迟) - **确定性**(相同输入 = 相同输出,每次都是) - **可重复**(运行测试 1000 次,获得相同结果) | 维度 | 真实 GCP IAM | Blackwell IAM 模拟器 | |-----------|--------------|------------------------| | **一致性模型** | 最终一致 | 强一致 | | **传播延迟** | 1-60 秒 | 0ms(即时) | | **测试不稳定性** | 高(依赖时序) | 零(确定性) | | **CI/CD 可靠性** | 不可预测 | 完全可重复 | | **网络依赖** | 需要 | 无 | | **每次测试运行成本** | API 费用 | 免费(本地) | ## 这是什么(不是什么) **GCP IAM 模拟器是一个用于测试云授权逻辑的确定性本地策略引擎。** **范围说明:** 此模拟器是用于 CI 测试的确定性 IAMPolicy 引擎。它不尝试实现完整的 Google Cloud IAM 对等(组织/文件夹层级、拒绝策略、完整 CEL)。 它不是 Google Cloud IAM 的完整重新实现,也不尝试完美保真。 相反,它提供: - **确定性权限评估** - 在本地测试"谁可以访问什么"(在您 policy.yaml 定义的权限范围内) - **严格的离线策略建模** - 无需 GCP 凭证或网络 - **可组合的认证层** - 本地 GCP 模拟器生态系统的基础 **用户定义自己的权限范围。模拟器执行它。** **目标:** 在 CI 中捕获授权错误(缺失权限、错误角色、配置错误的主体)。 **非目标:** 镜像 Google IAM 的每个边缘情况。如果您的测试在本地通过但在真实 GCP 中失败,请优化您的自定义角色定义。 **内置角色是有意精简的。模拟器通过自定义角色可以实现无限可能。** ## 为什么此 IAM 模拟器使用精选权限(有意为之) 此 IAM 模拟器特意限定用于**授权测试**,而非全面的 IAM 复制。我们建模了一小部分内置角色(基元 + Secret Manager + KMS)加上无限的自定义角色定义,以捕获实际上会导致生产故障的错误:缺失权限、错误的角色分配和配置错误的主体。这种精选优先的方法捕获了 95% 的真实世界授权错误,同时保持 hermetic 执行(无需 GCP 凭证)、确定性行为(0ms 传播延迟 vs 真实 GCP 的 1-60s),以及零维护负担(无需跟踪 GCP 不断演变的角色目录)。如果您需要测试其他 GCP 服务或权限,请在 `policy.yaml` 中将它们显式定义为自定义角色 — 这种显式方法更简单、更可靠,并避免了全面 IAM 模拟中常见的目录陈旧问题。我们优化的是**重要的授权失败**,而非理论上的 IAM 完整性。 ## 功能 - **完整的 IAMPolicy API 表面** - SetIamPolicy、GetIamPolicy、TestIamPermissions(gRPC + REST) - **确定性权限评估** - 明确的角色→权限定义(内置引导角色 + YAML 定义的自定义角色) - **条件绑定** - 支持 CEL 表达式的基于资源的访问控制 - **群组支持** - 定义可重用的群组和嵌套成员资格(1 级) - **策略 Schema v3** - 完全支持 etag、version、auditConfigs、conditions - **增强的跟踪模式** - JSON 输出、详细日志、持续时间指标 - **自定义角色** - 在 YAML 中定义任何 GCP 权限(可扩展,非硬编码) - **精简的内置核心** - 基元角色 + Secret Manager + KMS(仅引导) - **无需 GCP 凭证** - 完全离线工作,无需认证 - **快速且轻量** - 内存存储,毫秒级启动 - **线程安全** - 具有适当同步的并发访问 - **与模拟器集成** - 可与 gcp-secret-manager-emulator、gcp-kms-emulator 配合使用 ## 支持的操作 ### IAM 策略管理 - `SetIamPolicy` - 在任何资源上设置 IAM 策略 - `GetIamPolicy` - 检索资源的 IAM 策略 - `TestIamPermissions` - 检查授予了哪些权限 ### 内置角色(引导集) 模拟器包含**一小部分**内置角色,可立即使用。对于生产测试,请在 YAML 中定义自定义角色。 **基元角色:** - `roles/owner` - 完全访问所有资源 - `roles/editor` - 读写访问(无 IAM 管理,无删除) - `roles/viewer` - 只读访问 **Secret Manager 角色:** - `roles/secretmanager.admin` - 完整的密钥管理 - `roles/secretmanager.secretAccessor` - 仅读取密钥值 - `roles/secretmanager.secretVersionManager` - 管理版本 **KMS 角色:** - `roles/cloudkms.admin` - 完整的 KMS 管理 - `roles/cloudkms.cryptoKeyEncrypterDecrypter` - 仅加解密 - `roles/cloudkms.viewer` - 只读 KMS 访问 **总计:** 10 个内置角色,26 个权限 **需要更多服务?** 在 YAML 中定义自定义角色 - 请参阅下面的[自定义角色](#custom-roles-v040)部分。 ## 快速开始 ### 安装 ``` go install github.com/blackwell-systems/gcp-iam-emulator/cmd/server@latest ``` ### 运行服务器 **基本:** ``` # 默认端口 8080 启动 server # 自定义端口 server --port 9090 ``` **带策略配置(推荐用于 CI):** ``` # 从 YAML 加载策略 server --config policy.yaml # 启用跟踪模式进行调试 server --config policy.yaml --trace # 启用 HTTP REST API server --config policy.yaml --http-port 8081 # 启用详细跟踪并输出 JSON server --config policy.yaml --explain --trace-output trace.json # 文件更改时热重载策略 server --config policy.yaml --watch ``` **Docker:** ``` # 使用挂载配置运行 docker run -p 8080:8080 -v $(pwd)/policy.yaml:/policy.yaml \ ghcr.io/blackwell-systems/gcp-iam-emulator:latest --config /policy.yaml # 使用跟踪模式运行 docker run -p 8080:8080 \ ghcr.io/blackwell-systems/gcp-iam-emulator:latest --trace ``` ### 示例策略配置 创建 `policy.yaml`: ``` # 为测试环境定义自定义角色 roles: roles/custom.dataReader: permissions: - bigquery.datasets.get - bigquery.tables.list projects: test-project: bindings: - role: roles/owner members: - user:admin@example.com - role: roles/custom.dataReader members: - user:analyst@example.com - role: roles/secretmanager.secretAccessor members: - serviceAccount:ci@test-project.iam.gserviceaccount.com resources: secrets/db-password: bindings: - role: roles/secretmanager.secretAccessor members: - serviceAccount:app@test-project.iam.gserviceaccount.com ``` **注意:** 模拟器包含基元 + Secret Manager + KMS 的内置角色。对于其他 GCP 服务,请如上所示定义自定义角色。 ### 与 GCP SDK 一起使用 **带主体注入的 Go 客户端:** ``` package main import ( "context" iampb "google.golang.org/genproto/googleapis/iam/v1" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/metadata" ) func main() { ctx := context.Background() conn, _ := grpc.NewClient( "localhost:8080", grpc.WithTransportCredentials(insecure.NewCredentials()), ) defer conn.Close() client := iampb.NewIAMPolicyClient(conn) // Inject principal identity via metadata md := metadata.Pairs("x-emulator-principal", "serviceAccount:ci@test-project.iam.gserviceaccount.com") ctx = metadata.NewOutgoingContext(ctx, md) // Test permissions (checks if this principal has access) resp, _ := client.TestIamPermissions(ctx, &iampb.TestIamPermissionsRequest{ Resource: "projects/test-project/secrets/db-password", Permissions: []string{ "secretmanager.versions.access", "secretmanager.secrets.delete", }, }) // resp.Permissions = ["secretmanager.versions.access"] // (delete denied - secretAccessor role doesn't include it) } ``` **动态设置策略(无配置文件):** ``` // Set policy via API policy := &iampb.Policy{ Bindings: []*iampb.Binding{ { Role: "roles/secretmanager.secretAccessor", Members: []string{ "serviceAccount:ci@my-project.iam.gserviceaccount.com", }, }, }, } client.SetIamPolicy(ctx, &iampb.SetIamPolicyRequest{ Resource: "projects/my-project/secrets/my-secret", Policy: policy, }) ``` ## 用例 - **CI/CD 管道** - 用于 hermetic 测试的即插即用 IAM,无需 GCP 凭证 - **策略开发** - 通过即时反馈在本地迭代 IAM 策略 - **安全测试** - 在生产前验证"谁可以访问什么" - **权限调试** - 跟踪模式解释为何允许/拒绝访问 - **集成测试** - 与 Secret Manager + KMS 模拟器的真实权限评估 - **降低成本** - 在开发期间避免 GCP API 费用 ## CI/CD 集成 ### GitHub Actions ``` name: Integration Tests on: [push, pull_request] jobs: test: runs-on: ubuntu-latest services: iam-emulator: image: ghcr.io/blackwell-systems/gcp-iam-emulator:latest ports: - 8080:8080 options: --mount type=bind,source=${{ github.workspace }}/policy.yaml,target=/policy.yaml args: --config /policy.yaml --trace steps: - uses: actions/checkout@v4 - name: Run integration tests env: IAM_EMULATOR_HOST: localhost:8080 run: | go test ./... ``` ### Docker Compose **完整的 GCP 模拟器栈:** ``` # docker-compose.yml services: iam: image: ghcr.io/blackwell-systems/gcp-iam-emulator:latest ports: - "8080:8080" volumes: - ./policy.yaml:/policy.yaml command: --config /policy.yaml --trace secret-manager: image: ghcr.io/blackwell-systems/gcp-secret-manager-emulator:latest environment: IAM_EMULATOR_HOST: iam:8080 ports: - "9090:9090" depends_on: - iam kms: image: ghcr.io/blackwell-systems/gcp-kms-emulator:latest environment: IAM_EMULATOR_HOST: iam:8080 ports: - "9091:9090" depends_on: - iam ``` **运行:** ``` docker-compose up # 测试连接到 localhost:8080 (IAM)、localhost:9090 (Secret Manager)、localhost:9091 (KMS) ``` ## 跟踪模式 启用跟踪模式以调试授权决策: ``` server --config policy.yaml --trace ``` **示例输出:** ``` 2026/01/26 10:30:15 GCP IAM Emulator v0.2.0 2026/01/26 10:30:15 Loading policy config from policy.yaml 2026/01/26 10:30:15 Loaded 3 policies from config 2026/01/26 10:30:15 Trace mode: ENABLED (authz decisions will be logged) 2026/01/26 10:30:15 Server ready - listening on :8080 level=INFO msg="authz decision" decision=ALLOW principal=serviceAccount:ci@test.iam.gserviceaccount.com resource=projects/test/secrets/api-key permission=secretmanager.versions.access reason="matched binding: role=roles/secretmanager.secretAccessor member=serviceAccount:ci@test.iam.gserviceaccount.com" level=INFO msg="authz decision" decision=DENY principal=user:dev@example.com resource=projects/test/secrets/db-password permission=secretmanager.secrets.delete reason="no matching binding found for principal" ``` **使用跟踪模式来:** - 理解为何访问被拒绝 - 调试策略继承 - 验证主体匹配 - 在本地测试中审计授权决策 **增强的跟踪模式(v0.3.0+):** ``` # 使用 --explain 进行详细日志 server --config policy.yaml --explain # JSON 输出到文件 server --config policy.yaml --trace-output trace.json ``` **JSON 跟踪格式:** ``` { "time":"2026-01-26T10:30:15Z", "level":"INFO", "msg":"permission_check", "resource":"projects/test/secrets/api-key", "principal":"serviceAccount:ci@test.iam.gserviceaccount.com", "allowed_permissions":["secretmanager.versions.access"], "duration_ms":2, "timestamp":"2026-01-26T10:30:15Z" } ``` ## 授权跟踪 结构化日志记录 IAM 决策,用于调试、审计和测试。 ### 启用跟踪 ``` # 将结构化跟踪输出到文件 IAM_TRACE_OUTPUT=./authz-trace.jsonl ./server --config policy.yaml # 或输出到 stdout 用于调试 IAM_TRACE_OUTPUT=stdout ./server --config policy.yaml ``` ### 用例 **调试权限拒绝:** ``` # 查看访问被拒绝的确切原因 cat authz-trace.jsonl | jq 'select(.decision.outcome=="DENY")' # 输出显示 principal、resource、permission 和原因 ``` **审计测试覆盖率:** ``` # 列出测试实际使用的所有权限 cat authz-trace.jsonl | jq -r '.action.permission' | sort -u # 查看测试了哪些 principal cat authz-trace.jsonl | jq -r '.actor.principal' | sort -u ``` **验证策略更改:** ``` # 策略更改前 IAM_TRACE_OUTPUT=./before.jsonl go test ./... # 策略更改后 IAM_TRACE_OUTPUT=./after.jsonl go test ./... # 比较结果(检测回归) diff <(jq -r '.decision.outcome' before.jsonl | sort) \ <(jq -r '.decision.outcome' after.jsonl | sort) ``` **CI/CD 合规性:** ``` # 证明 CI 仅访问了允许的资源 cat ci-audit.jsonl | \ jq -r 'select(.decision.outcome=="ALLOW") | .target.resource' | \ grep -v "projects/prod/" && echo "❌ Unauthorized access" || echo "✅ Compliant" ``` ### 跟踪事件 Schema 每个跟踪事件都是一行 JSON,包含: - **Actor:** `actor.principal`(谁) - **Target:** `target.resource`(什么) - **Action:** `action.permission`(哪个权限) - **Decision:** `decision.outcome`(ALLOW 或 DENY) - **Reason:** `decision.reason`(原因) - **Timing:** `decision.latency_ms`(性能) **示例事件:** ``` {"schema_version":"1.0","event_type":"authz_check","timestamp":"2026-01-28T10:15:23.483Z","actor":{"principal":"user:alice@example.com"},"target":{"resource":"projects/test/secrets/db-password"},"action":{"permission":"secretmanager.secrets.get"},"decision":{"outcome":"ALLOW","reason":"binding_match","latency_ms":3}} ``` 请参阅 `gcp-emulator-auth/pkg/trace` 了解完整的 schema 定义。 ## v0.3.0 功能 ### 条件绑定 使用 CEL 表达式根据资源属性限制访问: ``` projects: test-project: bindings: # CI can only access production secrets - role: roles/secretmanager.secretAccessor members: - serviceAccount:ci@test-project.iam.gserviceaccount.com condition: expression: 'resource.name.startsWith("projects/test-project/secrets/prod-")' title: "Production secrets only" description: "CI service account restricted to production secrets" # Time-based access - role: roles/cloudkms.cryptoKeyEncrypterDecrypter members: - serviceAccount:temp-access@test-project.iam.gserviceaccount.com condition: expression: 'request.time < timestamp("2026-12-31T23:59:59Z")' title: "Temporary access" ``` **支持的 CEL 表达式:** - `resource.name.startsWith("prefix")` - 匹配资源名称前缀 - `resource.type == "SECRET"` - 匹配资源类型(SECRET、CRYPTO_KEY、KEY_RING) - `request.time < timestamp("2026-12-31T00:00:00Z")` - 基于时间的访问 ### 群组支持 定义可重用的群组以减少重复: ``` groups: developers: members: - user:alice@example.com - user:bob@example.com - serviceAccount:dev-bot@test-project.iam.gserviceaccount.com operators: members: - user:ops@example.com - group:oncall # Nested groups (1 level supported) oncall: members: - user:charlie@example.com - user:diana@example.com projects: test-project: bindings: - role: roles/viewer members: - group:developers # Reference group ``` ### REST API 所有 IAM 操作的 HTTP REST 网关: ``` # 使用 REST API server --config policy.yaml --http-port 8081 ``` **示例请求:** ``` # 设置 IAM 策略 curl -X POST http://localhost:8081/v1/projects/test-project:setIamPolicy \ -H "Content-Type: application/json" \ -d '{ "policy": { "bindings": [{ "role": "roles/viewer", "members": ["user:dev@example.com"] }] } }' # 获取 IAM 策略 curl http://localhost:8081/v1/projects/test-project:getIamPolicy # 测试权限 curl -X POST http://localhost:8081/v1/projects/test-project/secrets/api-key:testIamPermissions \ -H "Content-Type: application/json" \ -H "X-Emulator-Principal: serviceAccount:ci@test.iam.gserviceaccount.com" \ -d '{ "permissions": [ "secretmanager.versions.access", "secretmanager.secrets.delete" ] }' ``` **响应:** ``` { "permissions": ["secretmanager.versions.access"] } ``` ### 策略 Schema v3 完全支持 IAM Policy v3 功能: - **etag** - 基于 SHA256 的乐观并发控制 - **version** - 策略格式版本(1=基本,3=带条件) - **auditConfigs** - 审计日志配置 - **bindings[].condition** - 条件角色绑定 ### 自定义角色(v0.4.0) 为您自己的任何 GCP 服务定义角色到权限的映射: ``` roles: roles/custom.dataReader: permissions: - bigquery.datasets.get - bigquery.tables.list - bigquery.tables.getData roles/custom.pubsubPublisher: permissions: - pubsub.topics.publish - pubsub.topics.get roles/custom.storageAdmin: permissions: - storage.buckets.create - storage.buckets.delete - storage.objects.create - storage.objects.delete projects: test-project: bindings: - role: roles/custom.dataReader members: - user:analyst@example.com ``` **功能:** - **可扩展** - 为任何 GCP 服务定义权限 - **覆盖内置角色** - 自定义角色优先 - **默认严格模式** - 未知角色被拒绝(捕获配置错误) - **兼容模式可用** - 使用 `--allow-unknown-roles` 的通配符回退 - `roles/secretmanager.customRole` → 授予 `secretmanager.*` - `roles/cloudkms.encryptOnly` → 授予 `cloudkms.*` **为什么这很重要:** - GCP 有数千个权限 - 硬编码不可扩展 - 每个测试环境需要不同的权限 - 保持模拟器离线、确定性和 CI 友好 **模式:** **严格模式(默认,推荐):** ``` server --config policy.yaml ``` - 未知角色 → **拒绝** - 自定义角色 → 允许 - 内置角色 → 允许 - **捕获错误**:如果您使用未定义的角色,测试将失败 **兼容模式(不那么严格):** ``` server --config policy.yaml --allow-unknown-roles ``` - 未知角色 → **通配符匹配**(如果服务前缀匹配) - 更宽松,但可能隐藏错误 - 用于迁移现有测试时 **决策顺序:** 1. 自定义角色(最高优先级) 2. 内置角色(基元 + Secret Manager + KMS) 3. 通配符匹配(仅在兼容模式) 4. 拒绝(严格模式默认) ## 架构 **内存策略存储**,具有线程安全的并发访问。**简单的权限引擎**,将角色映射到权限。**资源级策略**(MVP 中无组织/文件夹层级)。**不铸造 token**(仅策略评估)。 ## 路线图 **未来考虑:** **角色包(可选的便利):** - 可选的导入包,如 `packs/pubsub.yaml`、`packs/bigquery.yaml` - 用户仅导入他们需要的 - 社区维护,非模拟器硬编码 - 示例:`roles: !include packs/storage.yaml` **不计划:** - 大型内置权限数据库(造成维护噩梦) - 与 GCP IAM API 自动同步(增加网络依赖) - 完美的 GCP IAM 保真度(不是目标) **策略:** 保持模拟器**专注和可持续**。用户通过自定义角色定义他们需要的。内置集保持精简(仅基元 + Secret Manager + KMS)。 请参阅 [ROADMAP.md](docs/ROADMAP.md) 了解完整详情。 ## 与 GCP IAM 的 API 对等 ### 已实现的内容 **方法:** - `SetIamPolicy` - 完整实现 - `GetIamPolicy` - 完整实现 - `TestIamPermissions` - 完整实现,带主体匹配 **策略字段:** - `bindings[]` - 带成员的角色分配 - `role` - IAM 角色字符串 - `members[]` - 主体标识符 - `version` - 策略格式版本(1=基本,3=条件) - `etag` - 基于 SHA256 的乐观并发控制 - `auditConfigs[]` - 审计日志配置 - `bindings[].condition` - 条件角色绑定(CEL 表达式) **功能:** - 通过 gRPC 元数据注入主体 - 资源层级策略继承 - 自定义角色(可扩展到任何 GCP 服务) - 条件绑定(CEL 表达式) - 群组支持(嵌套,1 级) - REST API 网关(HTTP/JSON) - 增强的跟踪模式(JSON 输出、持续时间指标) - 严格模式(默认拒绝未知角色) ### 限制 - 无组织/文件夹层级(项目是根) - 无服务账号或 token 铸造 - 无审计日志执行(接受 auditConfigs 但不执行) - CEL 表达式:仅基本子集(startsWith、类型相等、时间比较) **当前范围:** 用于与模拟器进行 CI/CD 测试的核心 IAM 策略操作 ## 项目状态 作为战略"基石"认证层提取,以支持完整的 GCP 模拟器生态系统测试。 ## 免责声明 此项目不隶属于 Google LLC 或 Google Cloud Platform,未经其认可或赞助。"Google Cloud"、"IAM"及相关商标是 Google LLC 的财产。这是用于测试和开发目的的独立开源实现。 ## 维护者 由 **Dayna Blackwell** 维护 — Blackwell Systems 创始人,构建云原生开发的参考基础设施。 [GitHub](https://github.com/blackwell-systems) · [LinkedIn](https://linkedin.com/in/dayna-blackwell) · [Blog](https://blog.blackwell-systems.com) ## 商标 **Blackwell Systems™** 和 **Blackwell Systems 标志**是 Dayna Blackwell 的商标。您可以使用"Blackwell Systems"名称来指代此项目,但不得以暗示认可或官方关联的方式使用该名称或标志,除非事先获得书面许可。使用指南请参阅 [BRAND.md](BRAND.md)。 ## 相关项目 - [**gcp-emulator**](https://github.com/blackwell-systems/gcp-emulator) - 统一单进程运行时(IAM + Secret Manager + KMS + Eventarc) - [CP Secret Manager 模拟器](https://github.com/blackwell-systems/gcp-secret-manager-emulator) - IAM 强制的 Secret Manager 数据平面 - [GCP KMS 模拟器](https://github.com/blackwell-systems/gcp-kms-emulator) - IAM 强制的 KMS 数据平面 - [GCP Eventarc 模拟器](https://github.com/blackwell-systems/gcp-eventarc-emulator) - IAM 强制的 Eventarc 数据平面 - [gcp-emulator-auth](https://github.com/blackwell-systems/gcp-emulator-auth) - 强制代理库(守护者) ## 谁在使用这个? 如果您正在使用此 IAM 模拟器 — 在 CI 中、本地或测试框架中 — 我很乐意了解您如何使用它。 - **您捕获了什么授权错误?**(缺失绑定、错误的角色定义、条件策略问题) - **您如何定义角色?**(主要是内置、主要是自定义 YAML、混合) - **您的设置是什么?**(独立策略引擎、与数据平面模拟器编排、自定义集成) - **还有什么摩擦?**(policy.yaml 复杂性、跟踪模式集成、缺失的 GCP 角色等效) 打开 issue、开始讨论或直接联系: 📬 dayna@blackwell-systems.com 这有助于塑造路线图,并确保项目与实际需求保持一致。 ## 许可证 Apache License 2.0 - 详情请参阅 [LICENSE](LICENSE)。
标签:EVTX分析, GCP, Go, IAM, Python工具, Ruby工具, SOC Prime, Streamlit, Web报告查看器, 安全测试, 开发工具, 授权测试, 攻击性安全, 无凭证测试, 日志审计, 本地开发, 权限管理, 模型越狱, 策略即代码, 策略模拟, 聊天机器人安全, 角色管理, 访问控制, 请求拦截