feat: add fixed enterprise Agent gate

Part 2/4 of verified local 18dfdfd: fail-closed navigation and intent gate, fixed Agent connector, loopback code-channel candidate scripts and tests.
This commit is contained in:
bingshuo 2026-07-26 23:13:12 +08:00
commit 8485822da6
10 changed files with 643 additions and 49 deletions

View file

@ -5,42 +5,145 @@ import subprocess
import sys
import tempfile
import time
import urllib.error
import urllib.request
from pathlib import Path
ROOT = Path(__file__).parent
NODE_MAP = ROOT.parents[1] / "deployment" / "navigation-maps" / "AW-GZ-001.json"
BASE = "http://127.0.0.1:48031"
HEADERS = {
"X-Lighthouse-Admin-Token": "test-token",
"X-Guanghu-Principal-Id": "ICE-GL-ZY001:TEST-INSTANCE",
"X-Guanghu-Subject-Kind": "persona",
"X-Guanghu-Human-Anchor": "ICE-GL-INF",
}
def post(path, payload, headers=HEADERS):
request = urllib.request.Request(
BASE + path,
data=json.dumps(payload).encode(),
method="POST",
headers=headers,
)
return json.load(urllib.request.urlopen(request))
def expect_error(code, path, payload, headers=HEADERS):
try:
post(path, payload, headers)
except urllib.error.HTTPError as error:
assert error.code == code, (error.code, json.load(error))
return json.load(error)
raise AssertionError(f"{path} unexpectedly succeeded")
with tempfile.TemporaryDirectory() as temp:
env = {**os.environ, "LIGHTHOUSE_DB": f"{temp}/lighthouse.db", "LIGHTHOUSE_ADMIN_TOKEN": "test-token", "LIGHTHOUSE_PORT": "48031"}
process = subprocess.Popen([sys.executable, "lighthouse.py"], cwd=ROOT, env=env, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
env = {
**os.environ,
"LIGHTHOUSE_DB": f"{temp}/lighthouse.db",
"LIGHTHOUSE_ADMIN_TOKEN": "test-token",
"LIGHTHOUSE_PORT": "48031",
"LIGHTHOUSE_NODE_MAP": str(NODE_MAP),
}
process = subprocess.Popen(
[sys.executable, "lighthouse.py"],
cwd=ROOT,
env=env,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
)
try:
for _ in range(30):
try:
assert json.load(urllib.request.urlopen("http://127.0.0.1:48031/health", timeout=1))["execution"] == "disabled"
health = json.load(urllib.request.urlopen(BASE + "/health", timeout=1))
assert health["execution"] == "disabled"
assert health["mode"] == "map-intent-agent-gate"
break
except OSError:
time.sleep(.1)
else: raise AssertionError("server did not start")
locked = urllib.request.Request("http://127.0.0.1:48031/v1/intakes", data=json.dumps({"human_name":"Test","email":"test@example.invalid","server_ip":"203.0.113.8","domain_id":"DOMAIN-ZS"}).encode(), method="POST", headers={"X-Lighthouse-Admin-Token":"test-token"})
try: urllib.request.urlopen(locked)
except urllib.error.HTTPError as error: assert error.code == 423
else: raise AssertionError("mutation was allowed before navigation map acknowledgement")
nav = json.load(urllib.request.urlopen("http://127.0.0.1:48031/v1/navigation-map"))
ack = urllib.request.Request("http://127.0.0.1:48031/v1/navigation-map/ack", data=json.dumps({"map_hash":nav["map_hash"]}).encode(), method="POST", headers={"X-Lighthouse-Admin-Token":"test-token"})
assert json.load(urllib.request.urlopen(ack))["ok"] is True
request = urllib.request.Request("http://127.0.0.1:48031/v1/intakes", data=json.dumps({"human_name":"Test","email":"test@example.invalid","server_ip":"203.0.113.8","domain_id":"DOMAIN-ZS"}).encode(), method="POST", headers={"X-Lighthouse-Admin-Token":"test-token"})
assert json.load(urllib.request.urlopen(request))["state"] == "PENDING_REVIEW"
bootstrap = urllib.request.Request("http://127.0.0.1:48031/v1/nodes/bootstrap", data=json.dumps({"id":"NODE-TEST-001","domain_id":"DOMAIN-ZS","display_name":"Test entry","server_ip":"203.0.113.8"}).encode(), method="POST", headers={"X-Lighthouse-Admin-Token":"test-token"})
assert json.load(urllib.request.urlopen(bootstrap))["state"] == "CONNECTED_PENDING_CONNECTOR"
preflight = urllib.request.Request("http://127.0.0.1:48031/v1/preflight", data=json.dumps({"action":"health_check","target_node_id":"NODE-TEST-001"}).encode(), method="POST", headers={"X-Lighthouse-Admin-Token":"test-token"})
assert json.load(urllib.request.urlopen(preflight))["decision"] == "REJECT"
fifth = urllib.request.Request("http://127.0.0.1:48031/v1/nodes/bootstrap", data=json.dumps({"id":"NODE-FIFTH-001","domain_id":"DOMAIN-FIFTH","display_name":"Not allowed","server_ip":"203.0.113.8"}).encode(), method="POST", headers={"X-Lighthouse-Admin-Token":"test-token"})
try: urllib.request.urlopen(fifth)
except urllib.error.HTTPError as error: assert error.code == 403
else: raise AssertionError("private fifth domain was accepted by enterprise lighthouse")
bad = urllib.request.Request("http://127.0.0.1:48031/v1/intakes", data=b'{"cmd":"rm -rf /"}', method="POST", headers={"X-Lighthouse-Admin-Token":"test-token"})
try: urllib.request.urlopen(bad)
except urllib.error.HTTPError as error: assert error.code == 400
else: raise AssertionError("raw command was not rejected")
else:
raise AssertionError("server did not start")
intake = {
"human_name": "Test",
"email": "test@example.invalid",
"server_ip": "203.0.113.8",
"domain_id": "DOMAIN-ZS",
}
expect_error(423, "/v1/intakes", intake)
nav = json.load(urllib.request.urlopen(BASE + "/v2/global-navigation-map"))
assert nav["navigation_map"]["schema"] == "guanghu.enterprise-global-navigation-map/v2"
assert nav["navigation_map"]["node_map"]["node_id"] == "AW-GZ-001"
assert post("/v1/navigation-map/ack", {"map_hash": nav["map_hash"]})["ok"] is True
expect_error(423, "/v1/intakes", intake)
capsule = {
"schema": "guanghu.intent-state-capsule/v1",
"human_anchor": "ICE-GL-INF",
"persona_id": "ICE-GL-ZY001",
"task_intent": "Test the enterprise navigation and Agent gate.",
"identity_boundary": "The public operations system is not a persona.",
"established_facts": ["AW map is current."],
"decisions": ["Use only a registered Agent."],
"rejected_routes": ["raw shell"],
"authorization_state": "test-only",
"current_checkpoint": "map acknowledged",
"next_action": "unlock inspector",
"completion_definition": ["preflight is gated"],
"evidence": ["deployment/navigation-maps/AW-GZ-001.json"],
}
restored = post("/v1/intent-state/restore", capsule)
assert restored["ok"] is True
assert json.load(urllib.request.urlopen(urllib.request.Request(
BASE + "/v1/intakes",
data=json.dumps(intake).encode(),
method="POST",
headers=HEADERS,
)))["state"] == "PENDING_REVIEW"
bootstrap = post("/v1/nodes/bootstrap", {
"id": "AW-GZ-001",
"domain_id": "DOMAIN-ZS",
"display_name": "Enterprise root node",
"server_ip": "203.0.113.8",
})
assert bootstrap["state"] == "CONNECTED_PENDING_CONNECTOR"
preflight = {"action": "health_check", "target_node_id": "AW-GZ-001", "agent_id": "AW-INSPECTOR"}
expect_error(423, "/v1/preflight", preflight)
unlocked = post("/v1/agents/unlock", {
"agent_id": "AW-INSPECTOR",
"action": "health_check",
"target_node_id": "AW-GZ-001",
})
preflight["unlock_id"] = unlocked["unlock_id"]
assert post("/v1/preflight", preflight)["decision"] == "REJECT"
assert post("/v1/agents/consume", {
**preflight,
"unlock_id": unlocked["unlock_id"],
})["consumed"] is True
expect_error(423, "/v1/preflight", preflight)
expect_error(403, "/v1/nodes/bootstrap", {
"id": "NODE-FIFTH-001",
"domain_id": "DOMAIN-FIFTH",
"display_name": "Not allowed",
"server_ip": "203.0.113.8",
})
expect_error(400, "/v1/intakes", {"cmd": "unsafe"})
other_headers = {
**HEADERS,
"X-Guanghu-Principal-Id": "ANOTHER-PERSONA:TEST",
}
expect_error(423, "/v1/intent-state/restore", capsule, other_headers)
assert post("/v1/navigation-map/ack", {"map_hash": nav["map_hash"]}, other_headers)["ok"] is True
expect_error(400, "/v1/intent-state/restore", {**capsule, "token": "forbidden"}, other_headers)
finally:
process.terminate(); process.wait(timeout=5)
process.terminate()
process.wait(timeout=5)
print("enterprise lighthouse tests passed")