myc

Self-custodial remote signer for Radroots apps
git clone https://radroots.dev/git/myc.git
Log | Files | Refs | README | LICENSE

config.v1.schema.json (23818B)


      1 {
      2   "$schema": "https://json-schema.org/draft/2020-12/schema",
      3   "$id": "https://github.com/radrootslabs/myc/contracts/services_hardening/config.v1.schema.json",
      4   "title": "Radroots Myc configuration v1",
      5   "description": "Strict, immutable, non-secret Myc service configuration.",
      6   "type": "object",
      7   "additionalProperties": false,
      8   "required": [
      9     "schema",
     10     "schema_version",
     11     "service",
     12     "logging",
     13     "operations",
     14     "database",
     15     "identity",
     16     "relays",
     17     "transport",
     18     "policy",
     19     "rate_limits",
     20     "resource_limits",
     21     "discovery"
     22   ],
     23   "properties": {
     24     "schema": { "const": "radroots.myc.config" },
     25     "schema_version": { "const": 1 },
     26     "service": { "$ref": "#/$defs/service" },
     27     "logging": { "$ref": "#/$defs/logging" },
     28     "operations": { "$ref": "#/$defs/operations" },
     29     "database": { "$ref": "#/$defs/database" },
     30     "identity": { "$ref": "#/$defs/identity" },
     31     "relays": {
     32       "type": "array",
     33       "minItems": 1,
     34       "maxItems": 32,
     35       "items": { "$ref": "#/$defs/relay" }
     36     },
     37     "transport": { "$ref": "#/$defs/transport" },
     38     "policy": { "$ref": "#/$defs/policy" },
     39     "rate_limits": { "$ref": "#/$defs/rate_limits" },
     40     "resource_limits": { "$ref": "#/$defs/resource_limits" },
     41     "discovery": { "$ref": "#/$defs/discovery" }
     42   },
     43   "$defs": {
     44     "absolute_path": {
     45       "type": "string",
     46       "minLength": 1,
     47       "maxLength": 4096,
     48       "x-radroots-maximum-utf8-bytes": 4096,
     49       "pattern": "^/"
     50     },
     51     "bounded_id": {
     52       "type": "string",
     53       "minLength": 1,
     54       "maxLength": 128,
     55       "x-radroots-maximum-utf8-bytes": 128,
     56       "pattern": "^[a-z][a-z0-9]*(?:_[a-z0-9]+)*$"
     57     },
     58     "relay_id": {
     59       "type": "string",
     60       "minLength": 1,
     61       "maxLength": 64,
     62       "x-radroots-maximum-utf8-bytes": 64,
     63       "pattern": "^[a-z][a-z0-9]*(?:_[a-z0-9]+)*$"
     64     },
     65     "credential_reference": {
     66       "type": "string",
     67       "minLength": 1,
     68       "maxLength": 128,
     69       "x-radroots-maximum-utf8-bytes": 128,
     70       "pattern": "^[a-z0-9](?:[a-z0-9._-]{0,126}[a-z0-9])?$"
     71     },
     72     "public_key": {
     73       "type": "string",
     74       "pattern": "^[0-9a-f]{64}$"
     75     },
     76     "relay_url": {
     77       "type": "string",
     78       "minLength": 1,
     79       "maxLength": 2048,
     80       "x-radroots-maximum-utf8-bytes": 2048,
     81       "pattern": "^(wss://|ws://(localhost|127\\.0\\.0\\.1|\\[::1\\])(?::[1-9][0-9]{0,4})?(?:/|$))"
     82     },
     83     "https_url": {
     84       "type": "string",
     85       "minLength": 1,
     86       "maxLength": 2048,
     87       "x-radroots-maximum-utf8-bytes": 2048,
     88       "pattern": "^https://"
     89     },
     90     "nostrconnect_url_template": {
     91       "type": "string",
     92       "minLength": 1,
     93       "maxLength": 2048,
     94       "x-radroots-maximum-utf8-bytes": 2048,
     95       "pattern": "^https://[^ ]*<nostrconnect>[^ ]*$"
     96     },
     97     "service": {
     98       "type": "object",
     99       "additionalProperties": false,
    100       "properties": {
    101         "shutdown_grace_ms": {
    102           "type": "integer",
    103           "minimum": 1,
    104           "maximum": 300000,
    105           "default": 30000,
    106           "x-radroots-default-source": "engineering_safety"
    107         }
    108       }
    109     },
    110     "logging": {
    111       "type": "object",
    112       "additionalProperties": false,
    113       "properties": {
    114         "level": {
    115           "type": "string",
    116           "enum": ["trace", "debug", "info", "warn", "error"],
    117           "default": "info",
    118           "x-radroots-default-source": "engineering_safety"
    119         },
    120         "format": {
    121           "const": "json",
    122           "default": "json",
    123           "x-radroots-default-source": "accepted_service_authority"
    124         }
    125       }
    126     },
    127     "operations_limits": {
    128       "type": "object",
    129       "additionalProperties": false,
    130       "properties": {
    131         "header_count": { "type": "integer", "minimum": 1, "maximum": 64, "default": 32, "x-radroots-default-source": "radroots_service_host" },
    132         "header_bytes": { "type": "integer", "minimum": 8192, "maximum": 32768, "default": 16384, "x-radroots-default-source": "radroots_service_host" },
    133         "response_body_utf8_bytes": { "type": "integer", "minimum": 1, "maximum": 1048576, "default": 1048576, "x-radroots-default-source": "radroots_service_host" },
    134         "concurrent_connections": { "type": "integer", "minimum": 1, "maximum": 64, "default": 32, "x-radroots-default-source": "radroots_service_host" },
    135         "request_deadline_ms": { "type": "integer", "minimum": 1, "maximum": 30000, "default": 15000, "x-radroots-default-source": "radroots_service_host" },
    136         "idle_timeout_ms": { "type": "integer", "minimum": 1, "maximum": 60000, "default": 30000, "x-radroots-default-source": "radroots_service_host" }
    137       }
    138     },
    139     "operations": {
    140       "oneOf": [
    141         {
    142           "type": "object",
    143           "additionalProperties": false,
    144           "required": ["enabled"],
    145           "properties": { "enabled": { "const": false } }
    146         },
    147         {
    148           "type": "object",
    149           "additionalProperties": false,
    150           "required": ["enabled", "listen", "bind_policy"],
    151           "properties": {
    152             "enabled": { "const": true },
    153             "listen": { "type": "string", "minLength": 1, "maxLength": 128, "x-radroots-maximum-utf8-bytes": 128 },
    154             "bind_policy": { "type": "string", "enum": ["loopback_only", "public"] },
    155             "limits": { "$ref": "#/$defs/operations_limits" }
    156           }
    157         }
    158       ]
    159     },
    160     "database": {
    161       "type": "object",
    162       "additionalProperties": false,
    163       "required": ["minimum_free_bytes"],
    164       "properties": {
    165         "busy_timeout_ms": { "type": "integer", "minimum": 1, "maximum": 60000, "default": 5000, "x-radroots-default-source": "radroots_service_sqlite" },
    166         "max_connections": { "type": "integer", "minimum": 1, "maximum": 8, "default": 8, "x-radroots-default-source": "radroots_service_sqlite" },
    167         "minimum_free_bytes": { "type": "integer", "minimum": 1, "maximum": 9223372036854775807 }
    168       }
    169     },
    170     "encrypted_file_provider": {
    171       "type": "object",
    172       "additionalProperties": false,
    173       "required": ["provider", "envelope_path", "credential_reference", "expected_public_key"],
    174       "properties": {
    175         "provider": { "const": "encrypted_file" },
    176         "envelope_path": { "$ref": "#/$defs/absolute_path" },
    177         "credential_reference": { "$ref": "#/$defs/credential_reference" },
    178         "expected_public_key": { "$ref": "#/$defs/public_key" }
    179       }
    180     },
    181     "local_signer_provider": {
    182       "type": "object",
    183       "additionalProperties": false,
    184       "required": ["provider", "socket_path", "request_deadline_ms", "request_max_bytes", "response_max_bytes", "concurrency", "expected_public_key"],
    185       "properties": {
    186         "provider": { "const": "local_signer" },
    187         "socket_path": { "$ref": "#/$defs/absolute_path" },
    188         "request_deadline_ms": { "type": "integer", "minimum": 1, "maximum": 30000 },
    189         "request_max_bytes": { "type": "integer", "minimum": 1, "maximum": 65536 },
    190         "response_max_bytes": { "type": "integer", "minimum": 1, "maximum": 1048576 },
    191         "concurrency": { "type": "integer", "minimum": 1, "maximum": 64 },
    192         "expected_public_key": { "$ref": "#/$defs/public_key" }
    193       }
    194     },
    195     "provider": {
    196       "oneOf": [
    197         { "$ref": "#/$defs/encrypted_file_provider" },
    198         { "$ref": "#/$defs/local_signer_provider" }
    199       ]
    200     },
    201     "discovery_identity": {
    202       "oneOf": [
    203         {
    204           "type": "object",
    205           "additionalProperties": false,
    206           "required": ["enabled"],
    207           "properties": { "enabled": { "const": false } }
    208         },
    209         {
    210           "type": "object",
    211           "additionalProperties": false,
    212           "required": ["enabled", "binding"],
    213           "properties": {
    214             "enabled": { "const": true },
    215             "binding": { "$ref": "#/$defs/provider" }
    216           }
    217         }
    218       ]
    219     },
    220     "identity": {
    221       "type": "object",
    222       "additionalProperties": false,
    223       "required": ["transport", "user", "discovery"],
    224       "properties": {
    225         "transport": { "$ref": "#/$defs/provider" },
    226         "user": { "$ref": "#/$defs/provider" },
    227         "discovery": { "$ref": "#/$defs/discovery_identity" }
    228       }
    229     },
    230     "relay": {
    231       "type": "object",
    232       "additionalProperties": false,
    233       "required": ["id", "url", "read", "write", "required", "authentication"],
    234       "properties": {
    235         "id": { "$ref": "#/$defs/relay_id" },
    236         "url": { "$ref": "#/$defs/relay_url" },
    237         "read": { "type": "boolean" },
    238         "write": { "type": "boolean" },
    239         "required": { "type": "boolean" },
    240         "authentication": { "type": "string", "enum": ["disabled", "required"] }
    241       }
    242     },
    243     "delivery_policy": {
    244       "oneOf": [
    245         {
    246           "type": "object",
    247           "additionalProperties": false,
    248           "required": ["mode"],
    249           "properties": { "mode": { "enum": ["all_required", "at_least_one_required"] } }
    250         },
    251         {
    252           "type": "object",
    253           "additionalProperties": false,
    254           "required": ["mode", "required_acknowledgements"],
    255           "properties": {
    256             "mode": { "const": "required_quorum" },
    257             "required_acknowledgements": { "type": "integer", "minimum": 1, "maximum": 32 }
    258           }
    259         }
    260       ]
    261     },
    262     "publish_retry": {
    263       "type": "object",
    264       "additionalProperties": false,
    265       "properties": {
    266         "max_attempts": { "type": "integer", "minimum": 1, "maximum": 32, "default": 5, "x-radroots-default-source": "engineering_safety" },
    267         "initial_backoff_ms": { "type": "integer", "minimum": 1, "maximum": 30000, "default": 250, "x-radroots-default-source": "engineering_safety" },
    268         "maximum_backoff_ms": { "type": "integer", "minimum": 1, "maximum": 300000, "default": 30000, "x-radroots-default-source": "engineering_safety" },
    269         "attempt_deadline_ms": { "type": "integer", "minimum": 1, "maximum": 30000, "default": 15000, "x-radroots-default-source": "radroots_service_host" }
    270       }
    271     },
    272     "transport": {
    273       "type": "object",
    274       "additionalProperties": false,
    275       "required": ["delivery_policy", "ingress"],
    276       "properties": {
    277         "connect_deadline_ms": { "type": "integer", "minimum": 1, "maximum": 30000, "default": 10000, "x-radroots-default-source": "engineering_safety" },
    278         "delivery_policy": { "$ref": "#/$defs/delivery_policy" },
    279         "ingress": { "$ref": "#/$defs/ingress" },
    280         "publish_retry": { "$ref": "#/$defs/publish_retry" }
    281       }
    282     },
    283     "ingress": {
    284       "type": "object",
    285       "additionalProperties": false,
    286       "required": [
    287         "subscription_deadline_ms",
    288         "maximum_past_seconds",
    289         "maximum_future_seconds"
    290       ],
    291       "properties": {
    292         "subscription_deadline_ms": {
    293           "type": "integer",
    294           "minimum": 1000,
    295           "maximum": 300000
    296         },
    297         "maximum_past_seconds": {
    298           "type": "integer",
    299           "minimum": 0,
    300           "maximum": 3600
    301         },
    302         "maximum_future_seconds": {
    303           "type": "integer",
    304           "minimum": 0,
    305           "maximum": 3600
    306         }
    307       }
    308     },
    309     "permission": {
    310       "type": "string",
    311       "minLength": 1,
    312       "maxLength": 64,
    313       "x-radroots-maximum-utf8-bytes": 64,
    314       "pattern": "^(nip04_decrypt|nip04_encrypt|nip44_decrypt|nip44_encrypt|switch_relays|sign_event:kind:(0|[1-9][0-9]{0,9}))$"
    315     },
    316     "challenges": {
    317       "oneOf": [
    318         {
    319           "type": "object",
    320           "additionalProperties": false,
    321           "required": ["enabled"],
    322           "properties": { "enabled": { "const": false } }
    323         },
    324         {
    325           "type": "object",
    326           "additionalProperties": false,
    327           "required": ["enabled", "url", "pending_lifetime_ms", "authorized_lifetime_ms"],
    328           "properties": {
    329             "enabled": { "const": true },
    330             "url": { "$ref": "#/$defs/https_url" },
    331             "pending_lifetime_ms": { "type": "integer", "minimum": 1000, "maximum": 86400000 },
    332             "authorized_lifetime_ms": { "type": "integer", "minimum": 1000, "maximum": 2592000000 }
    333           }
    334         }
    335       ]
    336     },
    337     "retention": {
    338       "type": "object",
    339       "additionalProperties": false,
    340       "required": ["terminal_connections_ms", "terminal_challenges_ms", "request_dedup_ms", "audit_ms", "completed_outbox_ms"],
    341       "properties": {
    342         "terminal_connections_ms": { "type": "integer", "minimum": 1, "maximum": 31536000000 },
    343         "terminal_challenges_ms": { "type": "integer", "minimum": 1, "maximum": 31536000000 },
    344         "request_dedup_ms": { "type": "integer", "minimum": 1, "maximum": 31536000000 },
    345         "audit_ms": { "type": "integer", "minimum": 1, "maximum": 31536000000 },
    346         "completed_outbox_ms": { "type": "integer", "minimum": 1, "maximum": 31536000000 }
    347       }
    348     },
    349     "policy": {
    350       "type": "object",
    351       "additionalProperties": false,
    352       "required": ["connection_approval", "trusted_clients", "denied_clients", "permission_ceiling", "allowed_sign_event_kinds", "challenges", "retention"],
    353       "properties": {
    354         "connection_approval": { "const": "explicit_user" },
    355         "trusted_clients": { "type": "array", "maxItems": 1024, "uniqueItems": true, "items": { "$ref": "#/$defs/public_key" } },
    356         "denied_clients": { "type": "array", "maxItems": 1024, "uniqueItems": true, "items": { "$ref": "#/$defs/public_key" } },
    357         "permission_ceiling": { "type": "array", "minItems": 1, "maxItems": 64, "uniqueItems": true, "items": { "$ref": "#/$defs/permission" } },
    358         "allowed_sign_event_kinds": { "type": "array", "minItems": 1, "maxItems": 64, "uniqueItems": true, "items": { "type": "integer", "minimum": 0, "maximum": 4294967295 } },
    359         "challenges": { "$ref": "#/$defs/challenges" },
    360         "retention": { "$ref": "#/$defs/retention" }
    361       }
    362     },
    363     "rate_limit": {
    364       "type": "object",
    365       "additionalProperties": false,
    366       "required": ["scope", "window_ms", "max_attempts", "retention_ms", "maximum_tracked_subjects"],
    367       "properties": {
    368         "scope": { "type": "string", "enum": ["global_and_relay", "connection"] },
    369         "window_ms": { "type": "integer", "minimum": 1, "maximum": 86400000 },
    370         "max_attempts": { "type": "integer", "minimum": 1, "maximum": 10000 },
    371         "retention_ms": { "type": "integer", "minimum": 1, "maximum": 2592000000 },
    372         "maximum_tracked_subjects": { "type": "integer", "minimum": 1, "maximum": 65536 }
    373       }
    374     },
    375     "rate_limits": {
    376       "type": "object",
    377       "additionalProperties": false,
    378       "required": ["connection_admission", "challenge_creation", "challenge_authorization"],
    379       "properties": {
    380         "connection_admission": { "$ref": "#/$defs/rate_limit" },
    381         "challenge_creation": { "$ref": "#/$defs/rate_limit" },
    382         "challenge_authorization": { "$ref": "#/$defs/rate_limit" }
    383       }
    384     },
    385     "admin_limits": {
    386       "type": "object",
    387       "additionalProperties": false,
    388       "properties": {
    389         "header_count": { "type": "integer", "minimum": 1, "maximum": 64, "default": 32, "x-radroots-default-source": "radroots_service_host" },
    390         "header_bytes": { "type": "integer", "minimum": 1, "maximum": 32768, "default": 16384, "x-radroots-default-source": "radroots_service_host" },
    391         "request_body_utf8_bytes": { "type": "integer", "minimum": 1, "maximum": 65536, "default": 65536, "x-radroots-default-source": "radroots_service_host" },
    392         "response_body_utf8_bytes": { "type": "integer", "minimum": 8382, "maximum": 1048576, "default": 1048576, "x-radroots-default-source": "radroots_service_host" },
    393         "concurrent_connections": { "type": "integer", "minimum": 1, "maximum": 64, "default": 32, "x-radroots-default-source": "radroots_service_host" },
    394         "request_deadline_ms": { "type": "integer", "minimum": 1, "maximum": 30000, "default": 15000, "x-radroots-default-source": "radroots_service_host" },
    395         "idle_timeout_ms": { "type": "integer", "minimum": 1, "maximum": 60000, "default": 30000, "x-radroots-default-source": "radroots_service_host" },
    396         "query_items": { "type": "integer", "minimum": 1, "maximum": 200, "default": 100, "x-radroots-default-source": "radroots_service_host" }
    397       }
    398     },
    399     "event_limits": {
    400       "type": "object",
    401       "additionalProperties": false,
    402       "properties": {
    403         "wire_bytes": { "type": "integer", "minimum": 1, "maximum": 524288, "default": 262144, "x-radroots-default-source": "radroots_event" },
    404         "content_bytes": { "type": "integer", "minimum": 1, "maximum": 131072, "default": 131072, "x-radroots-default-source": "radroots_event" },
    405         "tag_count": { "type": "integer", "minimum": 1, "maximum": 1024, "default": 1024, "x-radroots-default-source": "radroots_event" },
    406         "tag_total_elements": { "type": "integer", "minimum": 1, "maximum": 4096, "default": 4096, "x-radroots-default-source": "radroots_event" },
    407         "tag_element_bytes": { "type": "integer", "minimum": 1, "maximum": 4096, "default": 4096, "x-radroots-default-source": "radroots_event" },
    408         "tag_total_bytes": { "type": "integer", "minimum": 1, "maximum": 131072, "default": 131072, "x-radroots-default-source": "radroots_event" },
    409         "decrypted_plaintext_bytes": { "type": "integer", "minimum": 1, "maximum": 262144, "default": 262144, "x-radroots-default-source": "radroots_nostr_connect" }
    410       }
    411     },
    412     "queue_limits": {
    413       "type": "object",
    414       "additionalProperties": false,
    415       "properties": {
    416         "ingress": { "type": "integer", "minimum": 1, "maximum": 65536, "default": 1024, "x-radroots-default-source": "engineering_safety" },
    417         "provider": { "type": "integer", "minimum": 1, "maximum": 1024, "default": 64, "x-radroots-default-source": "engineering_safety" },
    418         "outbox": { "type": "integer", "minimum": 1, "maximum": 65536, "default": 4096, "x-radroots-default-source": "engineering_safety" },
    419         "discovery": { "type": "integer", "minimum": 1, "maximum": 1024, "default": 64, "x-radroots-default-source": "engineering_safety" }
    420       }
    421     },
    422     "metrics_limits": {
    423       "type": "object",
    424       "additionalProperties": false,
    425       "properties": {
    426         "descriptors": { "type": "integer", "minimum": 1, "maximum": 64, "default": 64, "x-radroots-default-source": "radroots_service_host" },
    427         "samples": { "type": "integer", "minimum": 1, "maximum": 512, "default": 512, "x-radroots-default-source": "radroots_service_host" },
    428         "labels_per_sample": { "type": "integer", "minimum": 1, "maximum": 8, "default": 8, "x-radroots-default-source": "radroots_service_host" },
    429         "render_utf8_bytes": { "type": "integer", "minimum": 1, "maximum": 1048576, "default": 1048576, "x-radroots-default-source": "radroots_service_host" }
    430       }
    431     },
    432     "runtime_limits": {
    433       "type": "object",
    434       "additionalProperties": false,
    435       "properties": {
    436         "worker_threads": { "type": "integer", "minimum": 2, "maximum": 32, "default": 4, "x-radroots-default-source": "engineering_safety" },
    437         "blocking_threads": { "type": "integer", "minimum": 1, "maximum": 32, "default": 8, "x-radroots-default-source": "engineering_safety" }
    438       }
    439     },
    440     "resource_limits": {
    441       "type": "object",
    442       "additionalProperties": false,
    443       "properties": {
    444         "admin": { "$ref": "#/$defs/admin_limits" },
    445         "events": { "$ref": "#/$defs/event_limits" },
    446         "queues": { "$ref": "#/$defs/queue_limits" },
    447         "metrics": { "$ref": "#/$defs/metrics_limits" },
    448         "runtime": { "$ref": "#/$defs/runtime_limits" }
    449       }
    450     },
    451     "discovery_metadata": {
    452       "type": "object",
    453       "additionalProperties": false,
    454       "required": ["name", "display_name", "about", "website", "picture"],
    455       "properties": {
    456         "name": { "type": "string", "minLength": 1, "maxLength": 128, "x-radroots-maximum-utf8-bytes": 128 },
    457         "display_name": { "type": "string", "minLength": 1, "maxLength": 128, "x-radroots-maximum-utf8-bytes": 128 },
    458         "about": { "type": "string", "maxLength": 1024, "x-radroots-maximum-utf8-bytes": 1024 },
    459         "website": { "$ref": "#/$defs/https_url" },
    460         "picture": { "$ref": "#/$defs/https_url" }
    461       }
    462     },
    463     "discovery": {
    464       "oneOf": [
    465         {
    466           "type": "object",
    467           "additionalProperties": false,
    468           "required": ["enabled"],
    469           "properties": { "enabled": { "const": false } }
    470         },
    471         {
    472           "type": "object",
    473           "additionalProperties": false,
    474           "required": ["enabled", "domain", "handler_identifier", "public_relay_ids", "publish_relay_ids", "nostrconnect_url_template", "metadata"],
    475           "properties": {
    476             "enabled": { "const": true },
    477             "domain": { "type": "string", "minLength": 1, "maxLength": 253, "x-radroots-maximum-utf8-bytes": 253, "pattern": "^[a-z0-9.-]+$" },
    478             "handler_identifier": { "$ref": "#/$defs/bounded_id" },
    479             "public_relay_ids": { "type": "array", "minItems": 1, "maxItems": 32, "uniqueItems": true, "items": { "$ref": "#/$defs/relay_id" } },
    480             "publish_relay_ids": { "type": "array", "minItems": 1, "maxItems": 32, "uniqueItems": true, "items": { "$ref": "#/$defs/relay_id" } },
    481             "nostrconnect_url_template": { "$ref": "#/$defs/nostrconnect_url_template" },
    482             "metadata": { "$ref": "#/$defs/discovery_metadata" }
    483           }
    484         }
    485       ]
    486     }
    487   },
    488   "x-radroots-contract": {
    489     "schema": "radroots.myc.configuration-contract.v1",
    490     "contract_version": 1,
    491     "document_format": "toml_utf8",
    492     "document_max_utf8_bytes": 1048576,
    493     "unknown_fields": "reject_at_every_object_boundary",
    494     "duplicate_keys": "reject_on_original_wire",
    495     "null_values": "reject_on_original_wire",
    496     "environment_overlay": "forbidden",
    497     "protected_material": "forbidden",
    498     "effective_output": "deterministic_redacted_with_exact_provenance",
    499     "bootstrap_only": ["profile", "instance", "repo_local_root", "config_path"],
    500     "safe_default_sources": ["radroots_service_host", "radroots_service_sqlite", "radroots_event", "radroots_nostr_connect", "accepted_service_authority", "engineering_safety"],
    501     "semantic_relationships": [
    502       "relay_ids_unique",
    503       "relay_urls_canonical_unique",
    504       "relay_read_or_write",
    505       "required_relay_read_or_write",
    506       "production_relays_wss_only",
    507       "repo_local_plaintext_relays_loopback_only",
    508       "at_least_one_read_relay",
    509       "at_least_one_write_relay",
    510       "at_least_one_required_read_relay",
    511       "at_least_one_required_write_relay",
    512       "configured_public_keys_are_valid_x_only_secp256k1",
    513       "enabled_role_expected_public_keys_unique",
    514       "trusted_and_denied_clients_disjoint",
    515       "permission_sign_event_kinds_equal_allowed_sign_event_kinds",
    516       "challenge_rate_limits_present_even_when_challenges_disabled",
    517       "rate_retention_not_less_than_window",
    518       "challenge_authorized_lifetime_not_less_than_pending_lifetime",
    519       "delivery_quorum_not_greater_than_required_write_relays",
    520       "publish_initial_backoff_not_greater_than_maximum_backoff",
    521       "discovery_enabled_iff_discovery_identity_enabled",
    522       "discovery_public_relay_ids_reference_read_relays",
    523       "discovery_publish_relay_ids_reference_write_relays",
    524       "operations_public_bind_requires_explicit_public_policy"
    525     ],
    526     "forbidden_prototype_fields": [
    527       "paths",
    528       "custody",
    529       "persistence",
    530       "audit",
    531       "observability",
    532       "env_file",
    533       "worker",
    534       "signer_state_backend",
    535       "runtime_audit_backend",
    536       "output_dir",
    537       "stdout",
    538       "external_command",
    539       "host_vault",
    540       "keyring",
    541       "managed_account",
    542       "plaintext_file"
    543     ]
    544   }
    545 }