2026-07-14 18:54:54 +08:00
#!/usr/bin/env python3
""" Enterprise Lighthouse foundation: registry, preflight, and audit only.
This service is deliberately not a remote shell . It accepts node admission
requests and validates fixed operation plans ; execution remains with a future
GLSV node connector after human authorization .
"""
import hmac
import json
import os
import sqlite3
import time
import uuid
from http . server import BaseHTTPRequestHandler , ThreadingHTTPServer
from ipaddress import ip_address
DB = os . environ . get ( " LIGHTHOUSE_DB " , " /var/lib/guanghu-enterprise-lighthouse/lighthouse.db " )
TOKEN = os . environ . get ( " LIGHTHOUSE_ADMIN_TOKEN " , " " )
HOST = os . environ . get ( " LIGHTHOUSE_BIND " , " 127.0.0.1 " )
PORT = int ( os . environ . get ( " LIGHTHOUSE_PORT " , " 8031 " ) )
FIXED_ACTIONS = { " health_check " , " backup " , " deploy_release " , " restart_service " , " rollback " }
DOMAINS = {
" DOMAIN-ZS " : " 零感域 " , " DOMAIN-MAIN " : " 光湖主域 " , " DOMAIN-SUB " : " 光湖分域 " ,
" DOMAIN-ZERO " : " 光湖零域 " , " DOMAIN-FIFTH " : " 第五域 " ,
}
2026-07-14 19:14:10 +08:00
ENTERPRISE_MANAGED_DOMAINS = { " DOMAIN-ZS " , " DOMAIN-MAIN " , " DOMAIN-SUB " , " DOMAIN-ZERO " }
EXTERNAL_FOUNDATION_DOMAINS = { " DOMAIN-FIFTH " }
2026-07-14 18:54:54 +08:00
def now ( ) :
return int ( time . time ( ) )
def connection ( ) :
os . makedirs ( os . path . dirname ( DB ) , exist_ok = True )
db = sqlite3 . connect ( DB )
db . row_factory = sqlite3 . Row
db . executescript ( """
CREATE TABLE IF NOT EXISTS domains (
id TEXT PRIMARY KEY , name TEXT NOT NULL , state TEXT NOT NULL , created_at INTEGER NOT NULL
) ;
CREATE TABLE IF NOT EXISTS intakes (
id TEXT PRIMARY KEY , created_at INTEGER NOT NULL , state TEXT NOT NULL ,
human_name TEXT NOT NULL , email TEXT NOT NULL , server_ip TEXT NOT NULL ,
domain_id TEXT NOT NULL , persona_ids TEXT NOT NULL , repository_urls TEXT NOT NULL ,
hosting_mode TEXT NOT NULL , notes TEXT NOT NULL
) ;
CREATE TABLE IF NOT EXISTS nodes (
id TEXT PRIMARY KEY , domain_id TEXT NOT NULL , intake_id TEXT , state TEXT NOT NULL ,
display_name TEXT NOT NULL , server_ip TEXT NOT NULL , allowed_actions TEXT NOT NULL ,
public_key_fingerprint TEXT , last_heartbeat INTEGER , created_at INTEGER NOT NULL
) ;
CREATE TABLE IF NOT EXISTS audit (
id TEXT PRIMARY KEY , created_at INTEGER NOT NULL , kind TEXT NOT NULL , payload TEXT NOT NULL
) ;
""" )
for domain_id , name in DOMAINS . items ( ) :
2026-07-14 19:14:10 +08:00
state = " EXTERNAL_PRIVATE_FOUNDATION " if domain_id in EXTERNAL_FOUNDATION_DOMAINS else " PENDING_ENTRY_NODE "
db . execute ( " INSERT OR IGNORE INTO domains VALUES (?, ?, ?, ?) " , ( domain_id , name , state , now ( ) ) )
2026-07-14 18:54:54 +08:00
db . commit ( )
return db
def audit ( db , kind , payload ) :
db . execute ( " INSERT INTO audit VALUES (?, ?, ?, ?) " , ( str ( uuid . uuid4 ( ) ) , now ( ) , kind , json . dumps ( payload , ensure_ascii = False ) ) )
db . commit ( )
def parse_json ( handler ) :
length = int ( handler . headers . get ( " Content-Length " , " 0 " ) )
if not 0 < length < = 50_000 :
raise ValueError ( " request body must be between 1 and 50000 bytes " )
return json . loads ( handler . rfile . read ( length ) . decode ( " utf-8 " ) )
def valid_email ( value ) :
return isinstance ( value , str ) and len ( value ) < = 254 and value . count ( " @ " ) == 1
def require_admin ( handler ) :
received = handler . headers . get ( " X-Lighthouse-Admin-Token " , " " )
return bool ( TOKEN ) and hmac . compare_digest ( received , TOKEN )
class Handler ( BaseHTTPRequestHandler ) :
server_version = " GuanghuEnterpriseLighthouse/1.0 "
def log_message ( self , fmt , * args ) :
print ( " [lighthouse] " + fmt % args )
def respond ( self , status , body ) :
encoded = json . dumps ( body , ensure_ascii = False ) . encode ( " utf-8 " )
self . send_response ( status )
self . send_header ( " Content-Type " , " application/json; charset=utf-8 " )
self . send_header ( " Content-Length " , str ( len ( encoded ) ) )
self . send_header ( " Cache-Control " , " no-store " )
self . end_headers ( )
self . wfile . write ( encoded )
def do_GET ( self ) :
db = connection ( )
try :
if self . path == " /health " :
return self . respond ( 200 , { " ok " : True , " service " : " guanghu-enterprise-lighthouse " , " mode " : " registry-and-preflight-only " , " execution " : " disabled " } )
if self . path == " /v1/status " :
counts = { row [ " state " ] : row [ " count " ] for row in db . execute ( " SELECT state, COUNT(*) AS count FROM nodes GROUP BY state " ) }
return self . respond ( 200 , { " ok " : True , " domains " : [ dict ( row ) for row in db . execute ( " SELECT id,name,state FROM domains ORDER BY id " ) ] , " node_counts " : counts , " fixed_actions " : sorted ( FIXED_ACTIONS ) , " raw_shell " : " rejected " } )
if self . path == " /v1/nodes " :
return self . respond ( 200 , { " ok " : True , " nodes " : [ dict ( row ) for row in db . execute ( " SELECT id,domain_id,state,display_name,allowed_actions,last_heartbeat,created_at FROM nodes ORDER BY created_at DESC " ) ] } )
return self . respond ( 404 , { " ok " : False , " error " : " not found " } )
finally :
db . close ( )
def do_POST ( self ) :
if not require_admin ( self ) :
return self . respond ( 401 , { " ok " : False , " error " : " admin authorization required " } )
try :
payload = parse_json ( self )
except ( ValueError , json . JSONDecodeError ) as error :
return self . respond ( 400 , { " ok " : False , " error " : str ( error ) } )
if " cmd " in payload or " shell " in payload or " command " in payload :
return self . respond ( 400 , { " ok " : False , " error " : " raw commands are never accepted by the lighthouse " } )
db = connection ( )
try :
if self . path == " /v1/intakes " :
required = ( " human_name " , " email " , " server_ip " , " domain_id " )
if any ( not payload . get ( field ) for field in required ) or payload [ " domain_id " ] not in DOMAINS or not valid_email ( payload [ " email " ] ) :
return self . respond ( 400 , { " ok " : False , " error " : " human_name, valid email, server_ip, and known domain_id are required " } )
2026-07-14 19:14:10 +08:00
if payload [ " domain_id " ] not in ENTERPRISE_MANAGED_DOMAINS :
return self . respond ( 403 , { " ok " : False , " error " : " this domain is not managed by the enterprise lighthouse; a separate explicit sovereign authorization is required " } )
2026-07-14 18:54:54 +08:00
try :
ip_address ( payload [ " server_ip " ] )
except ValueError :
return self . respond ( 400 , { " ok " : False , " error " : " server_ip must be a valid IP address " } )
intake_id = " INTAKE- " + uuid . uuid4 ( ) . hex [ : 12 ] . upper ( )
db . execute ( " INSERT INTO intakes VALUES (?, ?, ' PENDING_REVIEW ' , ?, ?, ?, ?, ?, ?, ?, ?) " , (
intake_id , now ( ) , payload [ " human_name " ] . strip ( ) , payload [ " email " ] . strip ( ) , payload [ " server_ip " ] , payload [ " domain_id " ] ,
json . dumps ( payload . get ( " persona_ids " , [ ] ) ) , json . dumps ( payload . get ( " repository_urls " , [ ] ) ) ,
payload . get ( " hosting_mode " , " own " ) , payload . get ( " notes " , " " ) ,
) )
audit ( db , " intake_created " , { " intake_id " : intake_id , " domain_id " : payload [ " domain_id " ] } )
return self . respond ( 201 , { " ok " : True , " intake_id " : intake_id , " state " : " PENDING_REVIEW " , " next " : " sovereign approval, human email confirmation, then node connector enrollment " } )
2026-07-14 19:06:11 +08:00
if self . path == " /v1/nodes/bootstrap " :
""" Register a manually verified routing node without enabling execution.
This exists for the controlled migration of an already verified
domain entry . It deliberately cannot make a node ACTIVE : the
GLSV connector , server - local key enrollment , and human email
confirmation remain required before any operation can proceed .
"""
required = ( " id " , " domain_id " , " display_name " , " server_ip " )
if any ( not isinstance ( payload . get ( field ) , str ) or not payload [ field ] . strip ( ) for field in required ) :
return self . respond ( 400 , { " ok " : False , " error " : " id, domain_id, display_name, and server_ip are required " } )
2026-07-14 19:14:10 +08:00
if payload [ " domain_id " ] not in ENTERPRISE_MANAGED_DOMAINS :
return self . respond ( 403 , { " ok " : False , " error " : " this domain cannot be registered by the enterprise lighthouse " } )
2026-07-14 19:06:11 +08:00
try :
ip_address ( payload [ " server_ip " ] )
except ValueError :
return self . respond ( 400 , { " ok " : False , " error " : " server_ip must be a valid IP address " } )
node_id = payload [ " id " ] . strip ( )
if db . execute ( " SELECT 1 FROM nodes WHERE id=? " , ( node_id , ) ) . fetchone ( ) :
return self . respond ( 409 , { " ok " : False , " error " : " node id is already registered " } )
db . execute ( " INSERT INTO nodes VALUES (?, ?, NULL, ' CONNECTED_PENDING_CONNECTOR ' , ?, ?, ?, NULL, ?, ?) " , (
node_id , payload [ " domain_id " ] , payload [ " display_name " ] . strip ( ) , payload [ " server_ip " ] ,
json . dumps ( [ " health_check " ] ) , now ( ) , now ( ) ,
) )
db . execute ( " UPDATE domains SET state= ' ENTRY_NODE_CONNECTED ' WHERE id=? " , ( payload [ " domain_id " ] , ) )
audit ( db , " node_bootstrap_connected " , { " node_id " : node_id , " domain_id " : payload [ " domain_id " ] , " mode " : " manual_verified_routing_only " } )
return self . respond ( 201 , { " ok " : True , " node_id " : node_id , " state " : " CONNECTED_PENDING_CONNECTOR " , " execution " : " disabled until GLSV connector enrollment and human authorization " } )
2026-07-14 19:14:10 +08:00
if self . path == " /v1/nodes/revoke " :
node_id = payload . get ( " node_id " )
if not isinstance ( node_id , str ) or not node_id . strip ( ) :
return self . respond ( 400 , { " ok " : False , " error " : " node_id is required " } )
node = db . execute ( " SELECT id, domain_id, state FROM nodes WHERE id=? " , ( node_id . strip ( ) , ) ) . fetchone ( )
if not node :
return self . respond ( 404 , { " ok " : False , " error " : " node is not registered " } )
if node [ " state " ] == " ACTIVE " :
return self . respond ( 409 , { " ok " : False , " error " : " ACTIVE nodes require a separate migration or retirement procedure " } )
db . execute ( " DELETE FROM nodes WHERE id=? " , ( node [ " id " ] , ) )
if node [ " domain_id " ] in EXTERNAL_FOUNDATION_DOMAINS :
db . execute ( " UPDATE domains SET state= ' EXTERNAL_PRIVATE_FOUNDATION ' WHERE id=? " , ( node [ " domain_id " ] , ) )
audit ( db , " node_revoked " , { " node_id " : node [ " id " ] , " domain_id " : node [ " domain_id " ] , " reason " : " administrative revocation " } )
return self . respond ( 200 , { " ok " : True , " node_id " : node [ " id " ] , " state " : " REVOKED " , " execution " : " disabled " } )
2026-07-14 18:54:54 +08:00
if self . path == " /v1/preflight " :
action , node_id = payload . get ( " action " ) , payload . get ( " target_node_id " )
if action not in FIXED_ACTIONS or not node_id :
return self . respond ( 400 , { " ok " : False , " error " : " fixed action and target_node_id are required " , " allowed_actions " : sorted ( FIXED_ACTIONS ) } )
node = db . execute ( " SELECT * FROM nodes WHERE id=? " , ( node_id , ) ) . fetchone ( )
if not node :
return self . respond ( 404 , { " ok " : False , " decision " : " REJECT " , " reason " : " target node is not registered " } )
allowed = json . loads ( node [ " allowed_actions " ] )
reasons = [ ]
if node [ " state " ] != " ACTIVE " : reasons . append ( " target node is not ACTIVE " )
if action not in allowed : reasons . append ( " action is not in the node allowlist " )
if action in { " deploy_release " , " restart_service " , " rollback " } and not payload . get ( " rollback_plan " ) : reasons . append ( " rollback_plan is required " )
if action in { " deploy_release " , " restart_service " } and not payload . get ( " backup_reference " ) : reasons . append ( " backup_reference is required " )
decision = " ALLOW_FOR_AUTHORIZATION " if not reasons else " REJECT "
result = { " ok " : not reasons , " decision " : decision , " reasons " : reasons , " execution " : " not performed; GLSV human authorization still required " }
audit ( db , " preflight " , { " target_node_id " : node_id , " action " : action , " decision " : decision , " reasons " : reasons } )
return self . respond ( 200 , result )
return self . respond ( 404 , { " ok " : False , " error " : " not found " } )
finally :
db . close ( )
if __name__ == " __main__ " :
print ( f " Enterprise Lighthouse listening on { HOST } : { PORT } " )
ThreadingHTTPServer ( ( HOST , PORT ) , Handler ) . serve_forever ( )