Files
suaveplan/openspec/archive/2026-05-12-enterprise-network-governance/proposal.md
2026-05-27 23:29:53 +01:00

5.8 KiB

OpenSpec Change: enterprise-network-governance

  • Change ID: enterprise-network-governance
  • Package: @suaveplan/network-governance
  • Category: universal/network
  • Target path: universal/network/network-governance
  • Status: SUPERSEDED-BY-GENESIS-WAVE
  • Date: 2026-04-24

Summary

Deliver @suaveplan/network-governance on the genesis branch from scratch at enterprise quality. The package provides network policy governance: define and enforce rate limits, access control policies (IP allowlist/denylist, peer authentication, capability gating), connection quotas, and audit trails for policy decisions. Genesis adds structured errors via @suaveplan/error, Zod schemas for all policy types, OTel instrumentation on policy evaluations, AbortSignal on async operations, injectable Clock for time-window rate limiting, event-bus emission for policy violations, and property-based tests for policy evaluation invariants.


Current-state audit (genesis)

The package does not exist on genesis yet — this is a fresh build.


Available workspace deps on genesis

Package Role
@suaveplan/error (workspace:^) Base class for NetworkGovernanceError; stable error codes
@suaveplan/types (workspace:^) LoggerLike, Clock, EventBusLike
@suaveplan/events (workspace:^) Event bus for policy violation events
@suaveplan/logger (workspace:^) Structured logging with audit trail
@suaveplan/rules (workspace:^) Business rules engine for policy evaluation
zod (catalog:forms) Zod schemas
@opentelemetry/api (catalog:observability) Spans + counters on policy evaluation
tslib (catalog:build) Runtime helpers

Dev deps: vitest, @vitest/coverage-istanbul, fast-check (all catalog:testing).


Public API surface

Core

function createGovernanceEngine(options?: GovernanceEngineOptions): GovernanceEngine

interface GovernanceEngine {
  addPolicy(policy: NetworkPolicy): void
  removePolicy(policyId: string): void
  evaluate(request: GovernanceRequest, signal?: AbortSignal): Promise<GovernanceDecision>
  getAuditLog(limit?: number): ReadonlyArray<AuditEntry>
  on(event: GovernanceEvent, handler: (entry: AuditEntry) => void): () => void
}

Policy types

type NetworkPolicy =
  | RateLimitPolicy
  | AccessControlPolicy
  | QuotaPolicy
  | CapabilityPolicy

interface BasePolicy {
  id: string
  name: string
  priority: number
  action: 'allow' | 'deny' | 'throttle'
  enabled?: boolean
}

interface RateLimitPolicy extends BasePolicy {
  type: 'rate-limit'
  maxRequests: number
  windowMs: number
  keyBy: 'peer-id' | 'ip' | 'user-id' | string
}

interface AccessControlPolicy extends BasePolicy {
  type: 'access-control'
  allowlist?: string[]
  denylist?: string[]
  requireAuth?: boolean
}

interface QuotaPolicy extends BasePolicy {
  type: 'quota'
  maxConnections?: number
  maxBandwidthBps?: number
  resetIntervalMs?: number
}

interface CapabilityPolicy extends BasePolicy {
  type: 'capability'
  requiredCapabilities: string[]
  target?: string  // endpoint or channel pattern
}

Evaluation types

interface GovernanceRequest {
  peerId?: string
  ip?: string
  userId?: string
  capabilities?: string[]
  target?: string
  metadata?: Record<string, unknown>
}

interface GovernanceDecision {
  readonly allowed: boolean
  readonly reason?: string
  readonly appliedPolicies: ReadonlyArray<string>
  readonly throttleMs?: number
}

interface AuditEntry {
  readonly timestamp: number
  readonly peerId?: string
  readonly decision: GovernanceDecision
  readonly policyId: string
  readonly type: GovernanceEvent
}

type GovernanceEvent = 'allowed' | 'denied' | 'throttled' | 'quota-exceeded'

interface GovernanceEngineOptions {
  logger?: LoggerLike
  clock?: Clock
  eventBus?: EventBusLike
  auditLogSize?: number
}

Error codes

type NetworkGovernanceErrorCode =
  | 'GOVERNANCE_POLICY_NOT_FOUND'
  | 'GOVERNANCE_EVALUATION_FAILED'
  | 'GOVERNANCE_INVALID_POLICY'
  | 'GOVERNANCE_ABORT'

function registerNetworkGovernanceErrorCodes(): void

Genesis additions

  1. Structured NetworkGovernanceError with stable GOVERNANCE.* codes
  2. Zod schemas for all policy types and GovernanceRequest
  3. Rate limiting with sliding window — injectable Clock for time-window bounds
  4. Audit log with bounded ring buffer (auditLogSize, default 1000)
  5. Policy priority ordering — higher-priority policies evaluated first; first deny wins
  6. Event-bus violation emission — fires governance.denied, governance.throttled
  7. OTel instrumentation — span governance.evaluate, counter governance.decisions_total, attributes decision.allowed, policy_id
  8. Property-based tests — deny wins over allow when both match same request; rate limit counter monotonically increases per key

File layout

universal/network/network-governance/
  package.json
  tsconfig.json
  vitest.config.ts
  src/
    index.ts
    error-codes.ts
    constants/
      index.ts
    types/
      common.ts
      common.md
    core/
      engine/
        engine.ts
        engine.md
        engine.types.ts
        engine.test.ts
        index.ts
    policies/
      rate-limit/
        rate-limit.ts
        rate-limit.md
        rate-limit.test.ts
        index.ts
      access-control/
        access-control.ts
        access-control.md
        access-control.test.ts
        index.ts
      quota/
        quota.ts
        quota.md
        quota.test.ts
        index.ts
      capability/
        capability.ts
        capability.md
        capability.test.ts
        index.ts
  tests/
    integration.test.ts
    property.test.ts

Impact

Workspace dep prerequisites: @suaveplan/error, @suaveplan/types, @suaveplan/events, @suaveplan/logger, @suaveplan/rules must be published.