- 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.
335 lines
9.0 KiB
JSON
335 lines
9.0 KiB
JSON
{
|
|
"$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
|
|
}
|
|
}
|
|
]
|
|
}
|