Skip to content

Comments

feat(system): ISO 27001:2022 compliance schemas — incident response, supplier security, training, audit governance#793

Merged
hotlong merged 3 commits intomainfrom
copilot/fix-iso-27001-compliance-gaps
Feb 23, 2026
Merged

feat(system): ISO 27001:2022 compliance schemas — incident response, supplier security, training, audit governance#793
hotlong merged 3 commits intomainfrom
copilot/fix-iso-27001-compliance-gaps

Conversation

Copy link
Contributor

Copilot AI commented Feb 23, 2026

Closes schema gaps identified in the ISO 27001:2022 compliance audit that block certification at the organizational control layer.

New schemas

  • system/incident-response.zod.ts (A.5.24–A.5.28) — Incident severity/category/status enums, NIST SP 800-61 response phases, notification matrix with escalation chains, org-level response policy
  • system/supplier-security.zod.ts (A.5.19–A.5.22) — Supplier risk levels, per-requirement compliance assessment, remediation tracking, reassessment policy
  • system/training.zod.ts (A.6.3) — Course definitions with validity/passing scores, completion records, org training plans with recertification intervals

Extended schemas

  • system/compliance.zod.ts (A.5.35) — AuditScheduleSchema for recurring internal/external audits, AuditFindingSchema with severity→remediation→verification lifecycle. ComplianceConfigSchema gains auditSchedules field.
  • system/change-management.zod.ts (A.8.32) — securityImpact optional field on ChangeRequestSchema: risk level, affected data classifications, security reviewer sign-off workflow
  • system/security-context.zod.ts — Extracted DataClassificationSchema and ComplianceFrameworkSchema as canonical shared enums, eliminating inline duplication across all security subsystem schemas
// Security impact assessment on change requests (A.8.32)
const change = ChangeRequestSchema.parse({
  // ...existing fields...
  securityImpact: {
    assessed: true,
    riskLevel: 'high',
    affectedDataClassifications: ['pii', 'confidential'],
    requiresSecurityApproval: true,
    reviewedBy: 'ciso',
    reviewedAt: Date.now(),
  },
});

Deduplication with existing protocols

  • DataClassificationSchema (pii/phi/pci/financial/confidential/internal/public) — extracted from security-context.zod.ts as canonical source; all new schemas import instead of inlining. Also replaced 3 pre-existing inline copies within security-context.zod.ts itself.
  • ComplianceFrameworkSchema (gdpr/hipaa/sox/pci_dss/ccpa/iso27001) — extracted from security-context.zod.ts; used by both existing ComplianceAuditRequirementSchema and new AuditFindingSchema/AuditScheduleSchema.
  • Verified no conceptual overlap between new and existing schemas:
    • incident-response (incident lifecycle management) ≠ audit.zod.ts (automated event logging)
    • AuditScheduleSchema (planned human audits) ≠ AuditConfigSchema (automated audit trail config)
    • AuditFindingSeveritySchema (critical/major/minor/observation) ≠ AuditEventSeverity (syslog-style debug→emergency)
    • IncidentNotificationRuleSchema (severity-based escalation with pagerduty) ≠ NotificationConfigSchema (general delivery channels)

Infrastructure

  • Barrel exports updated in system/index.ts
  • 73 new tests across 5 files (6275 total, all passing)
  • ROADMAP.md — new Phase 6.5 section tracking ISO 27001 schema coverage

Not in scope (tracked in roadmap)

  • OAuth scope binding on API endpoints (A.8.1)
  • Permission registry refactor from string[] to structured enum (A.8.2)
  • Temporary privilege elevation protocol
Original prompt

This section details on the original issue you should resolve

<issue_title>ISO 27001:2022 合规性差距分析与强化计划</issue_title>
<issue_description>## 背景
根据对当前协议仓库的全面审计,ObjectStack Protocol 在技术控制与安全治理层具备良好基础(符合大部分 ISO 27001:2022 的技术要求),但在组织管理层面仍存在几项必要补充以满足认证:

主要合规差距与建议行动(基于 ISO 27001:2022 最新要求)

1. 🔴 高优先级(直接阻碍认证)

  • 信息安全事件管理(A.5.24-5.28)
    • 建议:新增 system/incident-response.zod.ts,实现安全事件分类、严重性分级、响应流程、通知矩阵等 schema。
  • 信息安全独立审查(A.5.35)
    • 建议:在 compliance.zod.ts 扩展审计调度、发现追踪 schema,支持独立评估与追踪建议整改。
  • 变更管理安全审批(A.8.32)
    • 建议:在 change-management.zod.ts 中完善审批流程,增加安全影响评估节点。

2. 🟡 中优先级(影响合规完整性)

  • 供应商安全评估(A.5.19-5.22)
    • 建议:新增 system/supplier-security.zod.ts,记录供应商安全审查与风险评估。
  • OAuth Scope 明确绑定(A.8.1)
    • 建议:API 端点 schema 补充所需 OAuth Scopes。
  • 权限注册中心(A.8.2)
    • 建议:将 manifest.permissions 从 string[] 改造为注册中心枚举 schema。
  • 信息安全培训追踪(A.6.3)
    • 建议:建立培训计划与完成记录 schema。

3. 🟢 低优先级(增强项)

  • 权限委派与临时权限提升协议(如 AWS STS AssumeRole 类库型);设备信任策略扩展等。

支持性依据

  • iso27001 已为一等公民合规框架(ComplianceAuditRequirementSchema/ComplianceEncryptionRequirementSchema);相关安全上下文治理已涵盖大部分技术控制指标。
  • 但组织控制与合规治理(如事件管理、审计调度、供应商、培训)需补全 schema 才能满足 ISO 27001 全面认证。

验证方法

  • 新增/完善 schema 后,全量运行测试用例(已存在 6,202 个通过测试)。
  • 用例应覆盖 ISO 27001 合规相关的新业务场景与边界。

路线建议

  • 参考本 Issue,分子任务创建 Roadmap 多项子 issue,确保规范修正后组织盖章认证可一次通过。

如需详细映射到 Annex A 93 项控制要求清单,可补充子任务。
</issue_description>

Comments on the Issue (you are @copilot in this section)


🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.

@vercel
Copy link

vercel bot commented Feb 23, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
objectstack-play Error Error Feb 23, 2026 1:04pm
spec Error Error Feb 23, 2026 1:04pm

Request Review

…se, supplier security, training, audit scheduling, security impact assessment

Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix ISO 27001:2022 compliance gap issues feat(system): ISO 27001:2022 compliance schemas — incident response, supplier security, training, audit governance Feb 23, 2026
Copilot AI requested a review from hotlong February 23, 2026 11:55
@hotlong
Copy link
Contributor

hotlong commented Feb 23, 2026

@copilot 仔细检查,避免和现有协议重复

…ums via shared schemas from security-context.zod.ts

Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Feb 23, 2026

@copilot 仔细检查,避免和现有协议重复

已完成全面检查,发现并修复了以下重复项(9bc437c):

已去重:

  • DataClassificationSchemapii/phi/pci/financial/confidential/internal/public)— 从 security-context.zod.ts 提取为共享 enum,所有新文件统一 import,消除了 3 处内联重复
  • ComplianceFrameworkSchemagdpr/hipaa/sox/pci_dss/ccpa/iso27001)— 同样从 security-context.zod.ts 提取,compliance.zod.ts 的新 schema 引用共享定义

确认无概念重叠:

  • incident-response(事件生命周期管理)≠ audit.zod.ts(自动审计日志)
  • AuditScheduleSchema(人工计划审计)≠ AuditConfigSchema(自动审计配置)
  • AuditFindingSeveritySchema(critical/major/minor/observation)≠ AuditEventSeverity(syslog 风格 debug→emergency)
  • IncidentNotificationRuleSchema(含 pagerduty 的严重性升级)≠ NotificationConfigSchema(通用通知投递)

@hotlong hotlong marked this pull request as ready for review February 23, 2026 12:44
Copilot AI review requested due to automatic review settings February 23, 2026 12:44
@hotlong hotlong merged commit f112dbf into main Feb 23, 2026
2 of 4 checks passed
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds ISO 27001:2022 organization-level compliance governance schemas to packages/spec/src/system, extending the spec’s security/compliance protocol coverage (incident response, supplier security, training, and audit governance) and deduplicating shared security enums.

Changes:

  • Introduces new Zod protocols + tests for incident response (A.5.24–A.5.28), supplier security (A.5.19–A.5.22), and training (A.6.3).
  • Extends compliance governance with audit scheduling + finding lifecycle (A.5.35) and change-management with security impact assessment (A.8.32).
  • Extracts canonical shared enums (DataClassificationSchema, ComplianceFrameworkSchema) and updates system barrel exports + roadmap.

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
packages/spec/src/system/training.zod.ts Adds training course/record/plan schemas (A.6.3).
packages/spec/src/system/training.test.ts Adds validation coverage for training schemas.
packages/spec/src/system/supplier-security.zod.ts Adds supplier assessment + policy schemas (A.5.19–A.5.22).
packages/spec/src/system/supplier-security.test.ts Adds validation coverage for supplier security schemas.
packages/spec/src/system/security-context.zod.ts Defines canonical shared enums for classification + frameworks and reuses them in existing schemas.
packages/spec/src/system/index.ts Re-exports new system protocols from the barrel.
packages/spec/src/system/incident-response.zod.ts Adds incident lifecycle + notification/policy schemas (A.5.24–A.5.28).
packages/spec/src/system/incident-response.test.ts Adds validation coverage for incident response schemas.
packages/spec/src/system/compliance.zod.ts Adds audit schedule + finding schemas and wires them into ComplianceConfig (A.5.35).
packages/spec/src/system/compliance.test.ts Adds validation coverage for audit schedules/findings and config integration.
packages/spec/src/system/change-management.zod.ts Adds securityImpact assessment block to ChangeRequest (A.8.32).
packages/spec/src/system/change-management.test.ts Adds validation coverage for change request security impact.
ROADMAP.md Tracks ISO 27001 schema coverage status and remaining work.

/**
* Retention period for incident records in days
*/
retentionDays: z.number().default(2555)
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

retentionDays should not accept negative (or non-integer) values, but it’s currently z.number().default(2555). Consider constraining it to a positive integer (e.g., .int().min(1)) to avoid validating impossible retention policies.

Suggested change
retentionDays: z.number().default(2555)
retentionDays: z.number().int().min(1).default(2555)

Copilot uses AI. Check for mistakes.
/**
* Reassessment interval in days
*/
reassessmentIntervalDays: z.number().default(365)
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reassessmentIntervalDays is an interval but is currently unconstrained (z.number().default(365)), so negative or fractional values validate. Consider restricting it to a positive integer (e.g., .int().min(1)) to keep supplier policy configs valid.

Suggested change
reassessmentIntervalDays: z.number().default(365)
reassessmentIntervalDays: z.number().int().min(1).default(365)

Copilot uses AI. Check for mistakes.
/**
* Training completion date (Unix milliseconds)
*/
completedAt: z.number().optional().describe('Completion timestamp'),
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

completedAt is optional even when status is completed/failed/expired, which allows internally inconsistent training records (e.g., completed training with no completion timestamp). Consider adding an object-level refinement to require completedAt when the status implies the training attempt finished (and potentially require expiresAt when status is expired).

Copilot uses AI. Check for mistakes.
Comment on lines +133 to +137
status: SupplierAssessmentStatusSchema.describe('Assessment status'),

/**
* User or team who performed the assessment
*/
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SupplierAssessmentStatusSchema includes pending/in_progress, but the assessment record schema requires fields that imply completion (e.g., assessedAt / validUntil). Consider either (a) splitting “assessment in progress” vs “completed assessment” into separate schemas, or (b) making completion/validity timestamps conditional via refinement based on status.

Copilot uses AI. Check for mistakes.
Comment on lines +143 to +148
assessedAt: z.number().describe('Assessment timestamp'),

/**
* Assessment validity expiry (Unix milliseconds)
*/
validUntil: z.number().describe('Assessment validity expiry timestamp'),
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

assessedAt/validUntil are required even when status is pending or in_progress, which makes it hard to represent an assessment that hasn’t completed yet. If you keep these statuses, consider making these fields optional and enforcing them only for terminal states (completed/expired/failed).

Suggested change
assessedAt: z.number().describe('Assessment timestamp'),
/**
* Assessment validity expiry (Unix milliseconds)
*/
validUntil: z.number().describe('Assessment validity expiry timestamp'),
assessedAt: z.number().optional().describe('Assessment timestamp'),
/**
* Assessment validity expiry (Unix milliseconds)
*/
validUntil: z.number().optional().describe('Assessment validity expiry timestamp'),

Copilot uses AI. Check for mistakes.
* Regulatory notification deadline in hours (e.g., GDPR 72h)
*/
regulatorDeadlineHours: z.number().optional()
.describe('Regulatory notification deadline in hours'),
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

notifyRegulators and regulatorDeadlineHours are logically dependent, but the schema currently allows notifyRegulators: true without a deadline (and allows a deadline when notifyRegulators is false). Consider adding an object-level refinement so regulatorDeadlineHours is required (and positive) when notifyRegulators is true.

Suggested change
.describe('Regulatory notification deadline in hours'),
.describe('Regulatory notification deadline in hours'),
}).superRefine((value, ctx) => {
if (value.notifyRegulators) {
if (value.regulatorDeadlineHours == null) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
path: ['regulatorDeadlineHours'],
message: 'regulatorDeadlineHours is required when notifyRegulators is true',
});
} else if (value.regulatorDeadlineHours <= 0) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
path: ['regulatorDeadlineHours'],
message: 'regulatorDeadlineHours must be a positive number when notifyRegulators is true',
});
}
} else if (value.regulatorDeadlineHours != null) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
path: ['regulatorDeadlineHours'],
message: 'regulatorDeadlineHours must be omitted when notifyRegulators is false',
});
}

Copilot uses AI. Check for mistakes.
Comment on lines +183 to +184
recertificationIntervalDays: z.number().default(365)
.describe('Default recertification interval in days'),
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

recertificationIntervalDays (and related plan intervals like gracePeriodDays / reminderDaysBefore) are currently unconstrained numbers, so negative or fractional values validate. Consider constraining these to non-negative/positive integers (e.g., .int().min(0|1)) to keep plan configs meaningful.

Copilot uses AI. Check for mistakes.
/**
* Recurrence interval in months (0 = one-time)
*/
recurrenceMonths: z.number().default(0).describe('Recurrence interval in months (0 = one-time)'),
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

recurrenceMonths represents a recurrence interval ("0 = one-time") but is currently z.number() with no bounds, so negative or fractional values will validate. Consider constraining it to a non-negative integer (e.g., .int().min(0)) to prevent invalid schedules from being accepted.

Suggested change
recurrenceMonths: z.number().default(0).describe('Recurrence interval in months (0 = one-time)'),
recurrenceMonths: z.number().int().min(0).default(0).describe('Recurrence interval in months (0 = one-time)'),

Copilot uses AI. Check for mistakes.
/**
* Default escalation timeout in minutes before auto-escalation
*/
escalationTimeoutMinutes: z.number().default(30)
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

escalationTimeoutMinutes is a duration but currently allows negative / fractional values (z.number().default(30)). Consider adding bounds (e.g., .int().min(1) or .min(0) depending on whether 0 is meaningful) so invalid escalation policies can’t validate.

Suggested change
escalationTimeoutMinutes: z.number().default(30)
escalationTimeoutMinutes: z.number().int().min(1).default(30)

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ISO 27001:2022 合规性差距分析与强化计划

2 participants