fix(protocol): harden gateway contract validation
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Focused contract-boundary regressions for check_scope.py."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import pathlib
|
||||
import tempfile
|
||||
|
||||
import check_scope
|
||||
|
||||
|
||||
TEXT_PATHS = (
|
||||
"openapi/control-v1.yaml",
|
||||
"proto/versevdi/control/v1/control.proto",
|
||||
"proto/versevdi/tunnel/v1/tunnel.proto",
|
||||
"frames/datagram-v1.md",
|
||||
"frames/registry.json",
|
||||
"registries/features.json",
|
||||
"registries/datagrams.json",
|
||||
)
|
||||
PROVIDER_WORK_PROTO = """
|
||||
message ProviderSessionWork {
|
||||
string client_private_key_pem = 15;
|
||||
}
|
||||
"""
|
||||
|
||||
|
||||
def schema_with_private_key(owner: str) -> dict[str, object]:
|
||||
definitions = {
|
||||
name: {"type": "object", "properties": {}}
|
||||
for name in (
|
||||
"ConnectionManifest",
|
||||
"ManifestGateway",
|
||||
"ManifestTunnel",
|
||||
"ManifestProfile",
|
||||
"ManifestBounds",
|
||||
"GrantReference",
|
||||
"ProviderSessionWork",
|
||||
)
|
||||
}
|
||||
definitions[owner]["properties"] = {
|
||||
"client_private_key_pem": {"type": "string"},
|
||||
}
|
||||
return {"$defs": definitions}
|
||||
|
||||
|
||||
def run_scope(schema: dict[str, object], overrides: dict[str, str] | None = None) -> None:
|
||||
with tempfile.TemporaryDirectory() as directory:
|
||||
root = pathlib.Path(directory)
|
||||
schema_path = root / "schemas/control-v1.schema.json"
|
||||
schema_path.parent.mkdir(parents=True)
|
||||
schema_path.write_text(json.dumps(schema), encoding="utf-8")
|
||||
for relative in TEXT_PATHS:
|
||||
path = root / relative
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
default = PROVIDER_WORK_PROTO if relative == "proto/versevdi/tunnel/v1/tunnel.proto" else ""
|
||||
path.write_text((overrides or {}).get(relative, default), encoding="utf-8")
|
||||
(root / "gen").mkdir()
|
||||
|
||||
original_root = check_scope.ROOT
|
||||
check_scope.ROOT = root
|
||||
try:
|
||||
check_scope.check_manifest_schema()
|
||||
check_scope.check_text_boundaries()
|
||||
finally:
|
||||
check_scope.ROOT = original_root
|
||||
|
||||
|
||||
def expect_rejected(schema: dict[str, object], overrides: dict[str, str] | None = None) -> None:
|
||||
try:
|
||||
run_scope(schema, overrides)
|
||||
except ValueError:
|
||||
return
|
||||
raise AssertionError("client-visible private-key material was accepted")
|
||||
|
||||
|
||||
def main() -> None:
|
||||
run_scope(schema_with_private_key("ProviderSessionWork"))
|
||||
expect_rejected(schema_with_private_key("ConnectionManifest"))
|
||||
expect_rejected(schema_with_private_key("ManifestProfile"))
|
||||
expect_rejected(
|
||||
schema_with_private_key("ProviderSessionWork"),
|
||||
{
|
||||
"proto/versevdi/tunnel/v1/tunnel.proto": """
|
||||
message ConnectionManifest {
|
||||
string client_private_key_pem = 1;
|
||||
}
|
||||
"""
|
||||
},
|
||||
)
|
||||
expect_rejected(
|
||||
schema_with_private_key("ProviderSessionWork"),
|
||||
{"frames/datagram-v1.md": "client_private_key_pem"},
|
||||
)
|
||||
print("Protocol contract-aware scope regression passed")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user