config.v1.schema.json (20534B)
1 { 2 "$schema": "https://json-schema.org/draft/2020-12/schema", 3 "$id": "https://radroots.org/contracts/rhi/config.v1.schema.json", 4 "title": "Radroots RHI configuration v1", 5 "type": "object", 6 "additionalProperties": false, 7 "required": [ 8 "schema", 9 "schema_version", 10 "service", 11 "logging", 12 "operations", 13 "database", 14 "identity", 15 "relays", 16 "network", 17 "evidence", 18 "reconciliation", 19 "attestation", 20 "publication", 21 "presence", 22 "resource_limits", 23 "retention" 24 ], 25 "properties": { 26 "schema": { "const": "radroots.rhi.config" }, 27 "schema_version": { "const": 1 }, 28 "service": { "$ref": "#/$defs/service" }, 29 "logging": { "$ref": "#/$defs/logging" }, 30 "operations": { "$ref": "#/$defs/operations" }, 31 "database": { "$ref": "#/$defs/database" }, 32 "identity": { "$ref": "#/$defs/identity" }, 33 "relays": { 34 "type": "array", 35 "minItems": 1, 36 "maxItems": 32, 37 "items": { "$ref": "#/$defs/relay" } 38 }, 39 "network": { "$ref": "#/$defs/network" }, 40 "evidence": { "$ref": "#/$defs/evidence" }, 41 "reconciliation": { "$ref": "#/$defs/reconciliation" }, 42 "attestation": { "$ref": "#/$defs/attestation" }, 43 "publication": { "$ref": "#/$defs/publication" }, 44 "presence": { "$ref": "#/$defs/presence" }, 45 "resource_limits": { "$ref": "#/$defs/resource_limits" }, 46 "retention": { "$ref": "#/$defs/retention" } 47 }, 48 "$defs": { 49 "stable_id": { 50 "type": "string", 51 "minLength": 1, 52 "maxLength": 64, 53 "pattern": "^[a-z][a-z0-9_-]*$" 54 }, 55 "contract_id": { 56 "type": "string", 57 "minLength": 1, 58 "maxLength": 128, 59 "pattern": "^[a-z][a-z0-9._-]*$" 60 }, 61 "absolute_path": { 62 "type": "string", 63 "minLength": 1, 64 "maxLength": 4096, 65 "pattern": "^/" 66 }, 67 "credential_reference": { 68 "type": "string", 69 "minLength": 1, 70 "maxLength": 128, 71 "pattern": "^[a-z][a-z0-9_-]*$" 72 }, 73 "public_key": { 74 "type": "string", 75 "minLength": 64, 76 "maxLength": 64, 77 "pattern": "^[0-9a-f]{64}$" 78 }, 79 "relay_id": { "$ref": "#/$defs/stable_id" }, 80 "relay_url": { 81 "type": "string", 82 "minLength": 1, 83 "maxLength": 2048, 84 "pattern": "^(wss|ws)://" 85 }, 86 "service": { 87 "type": "object", 88 "additionalProperties": false, 89 "properties": { 90 "shutdown_grace_ms": { 91 "type": "integer", 92 "minimum": 1000, 93 "maximum": 300000, 94 "default": 30000, 95 "x-radroots-default-source": "accepted_service_authority" 96 } 97 } 98 }, 99 "logging": { 100 "type": "object", 101 "additionalProperties": false, 102 "properties": { 103 "level": { 104 "enum": ["error", "warn", "info", "debug", "trace"], 105 "default": "info", 106 "x-radroots-default-source": "engineering_safety" 107 }, 108 "format": { 109 "enum": ["json", "text"], 110 "default": "json", 111 "x-radroots-default-source": "engineering_safety" 112 } 113 } 114 }, 115 "operations_limits": { 116 "type": "object", 117 "additionalProperties": false, 118 "properties": { 119 "header_count": { "type": "integer", "minimum": 1, "maximum": 64, "default": 32, "x-radroots-default-source": "radroots_service_host" }, 120 "header_bytes": { "type": "integer", "minimum": 8192, "maximum": 32768, "default": 16384, "x-radroots-default-source": "radroots_service_host" }, 121 "response_body_utf8_bytes": { "type": "integer", "minimum": 1, "maximum": 1048576, "default": 1048576, "x-radroots-default-source": "radroots_service_host" }, 122 "concurrent_connections": { "type": "integer", "minimum": 1, "maximum": 64, "default": 32, "x-radroots-default-source": "radroots_service_host" }, 123 "request_deadline_ms": { "type": "integer", "minimum": 1, "maximum": 30000, "default": 15000, "x-radroots-default-source": "radroots_service_host" }, 124 "idle_timeout_ms": { "type": "integer", "minimum": 1, "maximum": 60000, "default": 30000, "x-radroots-default-source": "radroots_service_host" } 125 } 126 }, 127 "operations": { 128 "type": "object", 129 "additionalProperties": false, 130 "required": ["enabled"], 131 "properties": { 132 "enabled": { "type": "boolean" }, 133 "listen": { "type": "string", "minLength": 1, "maxLength": 256 }, 134 "bind_policy": { "enum": ["loopback_only", "explicit_public"] }, 135 "limits": { "$ref": "#/$defs/operations_limits" } 136 }, 137 "allOf": [ 138 { 139 "if": { "properties": { "enabled": { "const": true } }, "required": ["enabled"] }, 140 "then": { "required": ["listen", "bind_policy", "limits"] }, 141 "else": { "maxProperties": 1 } 142 } 143 ] 144 }, 145 "database": { 146 "type": "object", 147 "additionalProperties": false, 148 "required": ["minimum_free_bytes"], 149 "properties": { 150 "busy_timeout_ms": { "type": "integer", "minimum": 1, "maximum": 60000, "default": 5000, "x-radroots-default-source": "radroots_service_sqlite" }, 151 "max_connections": { "type": "integer", "minimum": 1, "maximum": 8, "default": 8, "x-radroots-default-source": "radroots_service_sqlite" }, 152 "minimum_free_bytes": { "type": "integer", "minimum": 1, "maximum": 9223372036854775807 } 153 } 154 }, 155 "encrypted_file_identity": { 156 "type": "object", 157 "additionalProperties": false, 158 "required": ["provider", "envelope_path", "credential_reference", "expected_public_key"], 159 "properties": { 160 "provider": { "const": "encrypted_file" }, 161 "envelope_path": { "$ref": "#/$defs/absolute_path" }, 162 "credential_reference": { "$ref": "#/$defs/credential_reference" }, 163 "expected_public_key": { "$ref": "#/$defs/public_key" } 164 } 165 }, 166 "identity": { 167 "type": "object", 168 "additionalProperties": false, 169 "required": ["service"], 170 "properties": { "service": { "$ref": "#/$defs/encrypted_file_identity" } } 171 }, 172 "relay": { 173 "type": "object", 174 "additionalProperties": false, 175 "required": ["id", "url", "read", "write", "required", "authentication"], 176 "properties": { 177 "id": { "$ref": "#/$defs/relay_id" }, 178 "url": { "$ref": "#/$defs/relay_url" }, 179 "read": { "type": "boolean" }, 180 "write": { "type": "boolean" }, 181 "required": { "type": "boolean" }, 182 "authentication": { "enum": ["none", "required"] } 183 } 184 }, 185 "network": { 186 "type": "object", 187 "additionalProperties": false, 188 "properties": { 189 "connect_deadline_ms": { "type": "integer", "minimum": 100, "maximum": 30000, "default": 10000, "x-radroots-default-source": "engineering_safety" }, 190 "dns_answer_limit": { "type": "integer", "minimum": 1, "maximum": 64, "default": 16, "x-radroots-default-source": "engineering_safety" } 191 } 192 }, 193 "evidence_source": { 194 "type": "object", 195 "additionalProperties": false, 196 "required": ["source_id", "kind", "relay_id", "required", "selector", "deadline_ms", "lookback_seconds", "overlap_seconds"], 197 "properties": { 198 "source_id": { "$ref": "#/$defs/stable_id" }, 199 "kind": { "const": "nostr_relay" }, 200 "relay_id": { "$ref": "#/$defs/relay_id" }, 201 "required": { "type": "boolean" }, 202 "selector": { "const": "trade_mutation_lineage_v1" }, 203 "deadline_ms": { "type": "integer", "minimum": 100, "maximum": 30000 }, 204 "lookback_seconds": { "type": "integer", "minimum": 60, "maximum": 2678400 }, 205 "overlap_seconds": { "type": "integer", "minimum": 1, "maximum": 86400 } 206 } 207 }, 208 "evidence": { 209 "type": "object", 210 "additionalProperties": false, 211 "required": ["contract", "contract_version", "policy_id", "sources"], 212 "properties": { 213 "contract": { "const": "radroots.rhi.evidence-policy" }, 214 "contract_version": { "const": 1 }, 215 "policy_id": { "$ref": "#/$defs/stable_id" }, 216 "sources": { 217 "type": "array", 218 "minItems": 1, 219 "maxItems": 16, 220 "items": { "$ref": "#/$defs/evidence_source" } 221 } 222 } 223 }, 224 "reconciliation": { 225 "type": "object", 226 "additionalProperties": false, 227 "properties": { 228 "concurrency": { "type": "integer", "minimum": 1, "maximum": 64, "default": 8, "x-radroots-default-source": "engineering_safety" }, 229 "queue_capacity": { "type": "integer", "minimum": 1, "maximum": 65536, "default": 4096, "x-radroots-default-source": "engineering_safety" }, 230 "lease_ms": { "type": "integer", "minimum": 1000, "maximum": 300000, "default": 30000, "x-radroots-default-source": "engineering_safety" }, 231 "lease_renewal_ms": { "type": "integer", "minimum": 100, "maximum": 150000, "default": 10000, "x-radroots-default-source": "engineering_safety" }, 232 "max_attempts": { "type": "integer", "minimum": 1, "maximum": 100, "default": 10, "x-radroots-default-source": "engineering_safety" }, 233 "initial_backoff_ms": { "type": "integer", "minimum": 1, "maximum": 60000, "default": 250, "x-radroots-default-source": "engineering_safety" }, 234 "maximum_backoff_ms": { "type": "integer", "minimum": 1, "maximum": 3600000, "default": 30000, "x-radroots-default-source": "engineering_safety" }, 235 "attempt_deadline_ms": { "type": "integer", "minimum": 100, "maximum": 300000, "default": 30000, "x-radroots-default-source": "engineering_safety" } 236 } 237 }, 238 "attestation": { 239 "type": "object", 240 "additionalProperties": false, 241 "required": ["contract", "contract_version", "method", "reducer_contract", "reducer_contract_version"], 242 "properties": { 243 "contract": { "const": "radroots.rhi.evidence_attestation.v1" }, 244 "contract_version": { "const": 1 }, 245 "method": { "const": "signed_evidence_snapshot" }, 246 "reducer_contract": { "const": "radroots.trade.reducer.v1" }, 247 "reducer_contract_version": { "const": 1 } 248 } 249 }, 250 "retry": { 251 "type": "object", 252 "additionalProperties": false, 253 "properties": { 254 "max_attempts": { "type": "integer", "minimum": 1, "maximum": 100, "default": 10, "x-radroots-default-source": "engineering_safety" }, 255 "initial_backoff_ms": { "type": "integer", "minimum": 1, "maximum": 60000, "default": 250, "x-radroots-default-source": "engineering_safety" }, 256 "maximum_backoff_ms": { "type": "integer", "minimum": 1, "maximum": 3600000, "default": 30000, "x-radroots-default-source": "engineering_safety" }, 257 "attempt_deadline_ms": { "type": "integer", "minimum": 100, "maximum": 30000, "default": 15000, "x-radroots-default-source": "engineering_safety" } 258 } 259 }, 260 "publication": { 261 "type": "object", 262 "additionalProperties": false, 263 "required": ["mode"], 264 "properties": { 265 "mode": { "enum": ["required", "disabled"] }, 266 "target_relay_ids": { "type": "array", "minItems": 1, "maxItems": 32, "uniqueItems": true, "items": { "$ref": "#/$defs/relay_id" } }, 267 "retry": { "$ref": "#/$defs/retry" } 268 }, 269 "allOf": [ 270 { 271 "if": { "properties": { "mode": { "const": "required" } }, "required": ["mode"] }, 272 "then": { "required": ["target_relay_ids", "retry"] }, 273 "else": { "maxProperties": 1 } 274 } 275 ] 276 }, 277 "presence": { 278 "type": "object", 279 "additionalProperties": false, 280 "required": ["enabled", "profile", "application_handler"], 281 "properties": { 282 "enabled": { "type": "boolean" }, 283 "profile": { "type": "boolean" }, 284 "application_handler": { "type": "boolean" }, 285 "target_relay_ids": { "type": "array", "minItems": 1, "maxItems": 32, "uniqueItems": true, "items": { "$ref": "#/$defs/relay_id" } } 286 }, 287 "allOf": [ 288 { 289 "if": { "properties": { "enabled": { "const": true } }, "required": ["enabled"] }, 290 "then": { "required": ["target_relay_ids"] }, 291 "else": { "maxProperties": 3 } 292 } 293 ] 294 }, 295 "admin_limits": { 296 "type": "object", 297 "additionalProperties": false, 298 "properties": { 299 "header_count": { "type": "integer", "minimum": 1, "maximum": 64, "default": 32, "x-radroots-default-source": "radroots_service_host" }, 300 "header_bytes": { "type": "integer", "minimum": 8192, "maximum": 32768, "default": 16384, "x-radroots-default-source": "radroots_service_host" }, 301 "request_body_utf8_bytes": { "type": "integer", "minimum": 1, "maximum": 65536, "default": 65536, "x-radroots-default-source": "radroots_service_host" }, 302 "response_body_utf8_bytes": { "type": "integer", "minimum": 512, "maximum": 1048576, "default": 1048576, "x-radroots-default-source": "radroots_service_host" }, 303 "concurrent_connections": { "type": "integer", "minimum": 1, "maximum": 64, "default": 32, "x-radroots-default-source": "radroots_service_host" }, 304 "request_deadline_ms": { "type": "integer", "minimum": 1, "maximum": 30000, "default": 15000, "x-radroots-default-source": "radroots_service_host" }, 305 "idle_timeout_ms": { "type": "integer", "minimum": 1, "maximum": 60000, "default": 30000, "x-radroots-default-source": "radroots_service_host" }, 306 "query_items": { "type": "integer", "minimum": 1, "maximum": 200, "default": 100, "x-radroots-default-source": "accepted_service_authority" } 307 } 308 }, 309 "event_limits": { 310 "type": "object", 311 "additionalProperties": false, 312 "properties": { 313 "wire_bytes": { "type": "integer", "minimum": 1, "maximum": 524288, "default": 262144, "x-radroots-default-source": "radroots_event" }, 314 "content_bytes": { "type": "integer", "minimum": 1, "maximum": 131072, "default": 131072, "x-radroots-default-source": "radroots_event" }, 315 "tag_count": { "type": "integer", "minimum": 1, "maximum": 1024, "default": 1024, "x-radroots-default-source": "radroots_event" }, 316 "tag_total_elements": { "type": "integer", "minimum": 1, "maximum": 4096, "default": 4096, "x-radroots-default-source": "radroots_event" }, 317 "tag_element_bytes": { "type": "integer", "minimum": 1, "maximum": 4096, "default": 4096, "x-radroots-default-source": "radroots_event" }, 318 "tag_total_bytes": { "type": "integer", "minimum": 1, "maximum": 131072, "default": 131072, "x-radroots-default-source": "radroots_event" } 319 } 320 }, 321 "source_result_limits": { 322 "type": "object", 323 "additionalProperties": false, 324 "properties": { 325 "events": { "type": "integer", "minimum": 1, "maximum": 4096, "default": 4096, "x-radroots-default-source": "rhi_evidence_policy" }, 326 "bytes": { "type": "integer", "minimum": 1, "maximum": 8388608, "default": 8388608, "x-radroots-default-source": "rhi_evidence_policy" } 327 } 328 }, 329 "queue_limits": { 330 "type": "object", 331 "additionalProperties": false, 332 "properties": { 333 "ingress": { "type": "integer", "minimum": 1, "maximum": 65536, "default": 1024, "x-radroots-default-source": "engineering_safety" }, 334 "reconciliation": { "type": "integer", "minimum": 1, "maximum": 65536, "default": 4096, "x-radroots-default-source": "engineering_safety" }, 335 "publication": { "type": "integer", "minimum": 1, "maximum": 65536, "default": 4096, "x-radroots-default-source": "engineering_safety" }, 336 "presence": { "type": "integer", "minimum": 1, "maximum": 4096, "default": 64, "x-radroots-default-source": "engineering_safety" } 337 } 338 }, 339 "metrics_limits": { 340 "type": "object", 341 "additionalProperties": false, 342 "properties": { 343 "descriptors": { "type": "integer", "minimum": 1, "maximum": 64, "default": 64, "x-radroots-default-source": "radroots_service_host" }, 344 "samples": { "type": "integer", "minimum": 1, "maximum": 512, "default": 512, "x-radroots-default-source": "radroots_service_host" }, 345 "labels_per_sample": { "type": "integer", "minimum": 1, "maximum": 8, "default": 8, "x-radroots-default-source": "radroots_service_host" }, 346 "render_utf8_bytes": { "type": "integer", "minimum": 1, "maximum": 1048576, "default": 1048576, "x-radroots-default-source": "radroots_service_host" } 347 } 348 }, 349 "runtime_limits": { 350 "type": "object", 351 "additionalProperties": false, 352 "properties": { 353 "worker_threads": { "type": "integer", "minimum": 2, "maximum": 32, "default": 4, "x-radroots-default-source": "engineering_safety" }, 354 "blocking_threads": { "type": "integer", "minimum": 1, "maximum": 32, "default": 8, "x-radroots-default-source": "engineering_safety" } 355 } 356 }, 357 "resource_limits": { 358 "type": "object", 359 "additionalProperties": false, 360 "properties": { 361 "admin": { "$ref": "#/$defs/admin_limits" }, 362 "events": { "$ref": "#/$defs/event_limits" }, 363 "source_results": { "$ref": "#/$defs/source_result_limits" }, 364 "queues": { "$ref": "#/$defs/queue_limits" }, 365 "metrics": { "$ref": "#/$defs/metrics_limits" }, 366 "runtime": { "$ref": "#/$defs/runtime_limits" } 367 } 368 }, 369 "retention": { 370 "type": "object", 371 "additionalProperties": false, 372 "required": ["duplicate_observations_ms", "completed_jobs_ms", "terminal_publication_attempts_ms", "terminal_presence_attempts_ms", "operation_dedup_ms", "audit_ms"], 373 "properties": { 374 "duplicate_observations_ms": { "type": "integer", "minimum": 1000, "maximum": 31536000000 }, 375 "completed_jobs_ms": { "type": "integer", "minimum": 1000, "maximum": 31536000000 }, 376 "terminal_publication_attempts_ms": { "type": "integer", "minimum": 1000, "maximum": 31536000000 }, 377 "terminal_presence_attempts_ms": { "type": "integer", "minimum": 1000, "maximum": 31536000000 }, 378 "operation_dedup_ms": { "type": "integer", "minimum": 1000, "maximum": 31536000000 }, 379 "audit_ms": { "type": "integer", "minimum": 1000, "maximum": 31536000000 } 380 } 381 } 382 }, 383 "x-radroots-contract": { 384 "schema": "radroots.rhi.configuration-contract.v1", 385 "contract_version": 1, 386 "document_format": "toml_utf8", 387 "document_max_utf8_bytes": 1048576, 388 "unknown_fields": "reject_at_every_object_boundary", 389 "duplicate_keys": "reject_on_original_wire", 390 "null_values": "reject_on_original_wire", 391 "environment_overlay": "forbidden", 392 "protected_material": "forbidden", 393 "effective_output": "deterministic_redacted_with_exact_provenance", 394 "bootstrap_only": ["profile", "instance", "repo_local_root", "config_path"], 395 "evidence_policy": "contracts/services_hardening/evidence_policy.v1.json", 396 "evidence_policy_sha256": "b4da4aa2863905975c577668bc75cbb03857106a67899278130915e085319dc8", 397 "safe_default_sources": ["radroots_service_host", "radroots_service_sqlite", "radroots_event", "rhi_evidence_policy", "accepted_service_authority", "engineering_safety"], 398 "semantic_relationships": [ 399 "relay_ids_unique", 400 "relay_urls_canonical_unique", 401 "relay_read_or_write", 402 "production_relays_wss_only", 403 "repo_local_plaintext_relays_loopback_only", 404 "identity_envelope_path_is_canonical_absolute_non_root", 405 "configured_service_public_key_is_valid_x_only_secp256k1", 406 "evidence_source_ids_unique", 407 "evidence_source_bindings_unique", 408 "evidence_source_relays_reference_read_relays", 409 "at_least_one_required_evidence_source", 410 "evidence_overlap_not_greater_than_lookback", 411 "evidence_completion_is_nostr_eose_before_deadline", 412 "source_result_limits_match_evidence_policy_maxima", 413 "reconciliation_renewal_less_than_lease", 414 "reconciliation_initial_backoff_not_greater_than_maximum_backoff", 415 "reconciliation_attempt_deadline_not_less_than_source_deadlines", 416 "publication_targets_reference_write_relays", 417 "publication_disabled_has_no_targets_or_retry", 418 "publication_initial_backoff_not_greater_than_maximum_backoff", 419 "presence_targets_reference_write_relays", 420 "presence_disabled_has_no_targets_and_no_desired_documents", 421 "operations_public_bind_requires_explicit_public_policy", 422 "retention_preserves_current_and_reproducibility_authority" 423 ], 424 "forbidden_prototype_fields": ["paths", "storage", "workers", "worker", "output_dir", "state_file", "state_path", "relay_url", "env_file", "environment", "identity_path", "private_key", "secret_key", "wrapping_key_path", "sqlite_path", "json_state", "hot_reload", "include"] 425 } 426 }