feat: Add Go module and workspace test fixtures
- Created expected JSON files for Go modules and workspaces. - Added go.mod and go.sum files for example projects. - Implemented private module structure with expected JSON output. - Introduced vendored dependencies with corresponding expected JSON. - Developed PostgresGraphJobStore for managing graph jobs. - Established SQL migration scripts for graph jobs schema. - Implemented GraphJobRepository for CRUD operations on graph jobs. - Created IGraphJobRepository interface for repository abstraction. - Added unit tests for GraphJobRepository to ensure functionality.
This commit is contained in:
334
docs/schemas/sealed-mode.schema.json
Normal file
334
docs/schemas/sealed-mode.schema.json
Normal file
@@ -0,0 +1,334 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://stellaops.io/schemas/sealed-mode.v1.json",
|
||||
"title": "SealedMode",
|
||||
"description": "Sealed mode contract for air-gapped operation - state management, egress policy, and bundle verification",
|
||||
"type": "object",
|
||||
"$defs": {
|
||||
"AirGapState": {
|
||||
"type": "object",
|
||||
"description": "Controller state for air-gapped environment",
|
||||
"required": ["id", "tenantId", "sealed", "lastTransitionAt"],
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"default": "singleton",
|
||||
"description": "State identifier (typically singleton)"
|
||||
},
|
||||
"tenantId": {
|
||||
"type": "string",
|
||||
"default": "default"
|
||||
},
|
||||
"sealed": {
|
||||
"type": "boolean",
|
||||
"description": "Whether environment is in sealed mode"
|
||||
},
|
||||
"policyHash": {
|
||||
"type": "string",
|
||||
"pattern": "^sha256:[a-f0-9]{64}$",
|
||||
"description": "Hash of active policy pack"
|
||||
},
|
||||
"timeAnchor": {
|
||||
"$ref": "#/$defs/TimeAnchor"
|
||||
},
|
||||
"lastTransitionAt": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"description": "When seal/unseal last occurred"
|
||||
},
|
||||
"stalenessBudget": {
|
||||
"$ref": "#/$defs/StalenessBudget"
|
||||
}
|
||||
}
|
||||
},
|
||||
"TimeAnchor": {
|
||||
"type": "object",
|
||||
"description": "Trusted time anchor for air-gapped time verification",
|
||||
"required": ["anchorTime", "source", "format"],
|
||||
"properties": {
|
||||
"anchorTime": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"description": "The anchored timestamp"
|
||||
},
|
||||
"source": {
|
||||
"type": "string",
|
||||
"description": "Time source type",
|
||||
"enum": ["roughtime", "rfc3161", "unknown"]
|
||||
},
|
||||
"format": {
|
||||
"type": "string",
|
||||
"description": "Token format identifier"
|
||||
},
|
||||
"signatureFingerprint": {
|
||||
"type": "string",
|
||||
"description": "Hex-encoded fingerprint of signing key"
|
||||
},
|
||||
"tokenDigest": {
|
||||
"type": "string",
|
||||
"pattern": "^[a-f0-9]{64}$",
|
||||
"description": "SHA-256 digest of the time token"
|
||||
}
|
||||
}
|
||||
},
|
||||
"StalenessBudget": {
|
||||
"type": "object",
|
||||
"description": "Thresholds for staleness warnings and breaches",
|
||||
"properties": {
|
||||
"warningThresholdSeconds": {
|
||||
"type": "integer",
|
||||
"default": 3600,
|
||||
"description": "Seconds until warning (default: 1 hour)"
|
||||
},
|
||||
"breachThresholdSeconds": {
|
||||
"type": "integer",
|
||||
"default": 7200,
|
||||
"description": "Seconds until breach (default: 2 hours)"
|
||||
}
|
||||
}
|
||||
},
|
||||
"StalenessEvaluation": {
|
||||
"type": "object",
|
||||
"description": "Result of staleness check",
|
||||
"required": ["ageSeconds", "isWarning", "isBreach"],
|
||||
"properties": {
|
||||
"ageSeconds": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"description": "Age of data since last sync"
|
||||
},
|
||||
"isWarning": {
|
||||
"type": "boolean",
|
||||
"description": "Age exceeds warning threshold"
|
||||
},
|
||||
"isBreach": {
|
||||
"type": "boolean",
|
||||
"description": "Age exceeds breach threshold"
|
||||
}
|
||||
}
|
||||
},
|
||||
"SealRequest": {
|
||||
"type": "object",
|
||||
"description": "Request to seal the environment",
|
||||
"required": ["policyHash"],
|
||||
"properties": {
|
||||
"policyHash": {
|
||||
"type": "string",
|
||||
"pattern": "^sha256:[a-f0-9]{64}$"
|
||||
},
|
||||
"timeAnchor": {
|
||||
"$ref": "#/$defs/TimeAnchor"
|
||||
},
|
||||
"stalenessBudget": {
|
||||
"$ref": "#/$defs/StalenessBudget"
|
||||
}
|
||||
}
|
||||
},
|
||||
"SealResponse": {
|
||||
"type": "object",
|
||||
"required": ["success", "state"],
|
||||
"properties": {
|
||||
"success": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"state": {
|
||||
"$ref": "#/$defs/AirGapState"
|
||||
},
|
||||
"error": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"SealedModeStatus": {
|
||||
"type": "object",
|
||||
"description": "Current sealed mode status with staleness evaluation",
|
||||
"required": ["sealed", "staleness"],
|
||||
"properties": {
|
||||
"sealed": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"policyHash": {
|
||||
"type": "string"
|
||||
},
|
||||
"timeAnchor": {
|
||||
"$ref": "#/$defs/TimeAnchor"
|
||||
},
|
||||
"staleness": {
|
||||
"$ref": "#/$defs/StalenessEvaluation"
|
||||
},
|
||||
"lastTransitionAt": {
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
}
|
||||
}
|
||||
},
|
||||
"EgressPolicy": {
|
||||
"type": "object",
|
||||
"description": "Network egress policy for sealed mode",
|
||||
"required": ["enabled", "rules"],
|
||||
"properties": {
|
||||
"enabled": {
|
||||
"type": "boolean",
|
||||
"description": "Whether egress policy is enforced"
|
||||
},
|
||||
"allowLoopback": {
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
},
|
||||
"allowPrivateNetworks": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"rules": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/$defs/EgressRule"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"EgressRule": {
|
||||
"type": "object",
|
||||
"required": ["pattern", "action"],
|
||||
"properties": {
|
||||
"pattern": {
|
||||
"type": "string",
|
||||
"description": "Host pattern (domain or CIDR)"
|
||||
},
|
||||
"action": {
|
||||
"type": "string",
|
||||
"enum": ["allow", "deny"]
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"EgressRequest": {
|
||||
"type": "object",
|
||||
"required": ["host"],
|
||||
"properties": {
|
||||
"host": {
|
||||
"type": "string"
|
||||
},
|
||||
"port": {
|
||||
"type": "integer"
|
||||
},
|
||||
"protocol": {
|
||||
"type": "string",
|
||||
"enum": ["http", "https", "tcp"]
|
||||
}
|
||||
}
|
||||
},
|
||||
"EgressDecision": {
|
||||
"type": "object",
|
||||
"required": ["allowed"],
|
||||
"properties": {
|
||||
"allowed": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"matchedRule": {
|
||||
"type": "string"
|
||||
},
|
||||
"reason": {
|
||||
"type": "string"
|
||||
},
|
||||
"remediation": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"BundleVerifyRequest": {
|
||||
"type": "object",
|
||||
"description": "Request to verify an offline bundle",
|
||||
"required": ["bundlePath"],
|
||||
"properties": {
|
||||
"bundlePath": {
|
||||
"type": "string"
|
||||
},
|
||||
"verifyDsse": {
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
},
|
||||
"verifyTuf": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"verifyMerkle": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"BundleVerifyResponse": {
|
||||
"type": "object",
|
||||
"required": ["valid"],
|
||||
"properties": {
|
||||
"valid": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"dsseValid": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"tufValid": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"merkleValid": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"bundleDigest": {
|
||||
"type": "string",
|
||||
"pattern": "^sha256:[a-f0-9]{64}$"
|
||||
},
|
||||
"errors": {
|
||||
"type": "array",
|
||||
"items": {"type": "string"}
|
||||
}
|
||||
}
|
||||
},
|
||||
"TelemetryMetrics": {
|
||||
"type": "object",
|
||||
"description": "Telemetry metrics for sealed mode monitoring",
|
||||
"properties": {
|
||||
"metrics": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {"type": "string"},
|
||||
"type": {"type": "string", "enum": ["gauge", "counter"]},
|
||||
"description": {"type": "string"}
|
||||
}
|
||||
},
|
||||
"default": [
|
||||
{"name": "policy_airgap_sealed", "type": "gauge", "description": "1 if sealed, 0 if unsealed"},
|
||||
{"name": "policy_airgap_anchor_drift_seconds", "type": "gauge", "description": "Seconds since time anchor"},
|
||||
{"name": "policy_airgap_anchor_expiry_seconds", "type": "gauge", "description": "Seconds until anchor expiry"},
|
||||
{"name": "policy_airgap_seal_total", "type": "counter", "description": "Total seal operations"},
|
||||
{"name": "policy_airgap_unseal_total", "type": "counter", "description": "Total unseal operations"},
|
||||
{"name": "policy_airgap_bundle_import_blocked_total", "type": "counter", "description": "Blocked import attempts"}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"examples": [
|
||||
{
|
||||
"id": "singleton",
|
||||
"tenantId": "default",
|
||||
"sealed": true,
|
||||
"policyHash": "sha256:abc123def456789...",
|
||||
"timeAnchor": {
|
||||
"anchorTime": "2025-12-06T00:00:00Z",
|
||||
"source": "roughtime",
|
||||
"format": "roughtime-v1",
|
||||
"tokenDigest": "abc123..."
|
||||
},
|
||||
"lastTransitionAt": "2025-12-06T00:00:00Z",
|
||||
"stalenessBudget": {
|
||||
"warningThresholdSeconds": 3600,
|
||||
"breachThresholdSeconds": 7200
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user