{"record":{"id":"9cbbe18cf765bbf7","repo":"astrid-runtime/astrid","slug":"mcp-gateway-control-authority-is-incomplete","errorCode":null,"errorMessage":"MCP gateway control authority is incomplete","messagePattern":"MCP gateway control authority is incomplete","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-cli/src/commands/mcp/gateway.rs","lineNumber":911,"sourceCode":"            break;\n        }\n        line.push(byte);\n    }\n    if !terminated {\n        anyhow::bail!(\"MCP attach registration is missing or too large\");\n    }\n    let request: GatewayRequest =\n        serde_json::from_slice(&line).context(\"MCP gateway registration is not valid JSON\")?;\n    match &request {\n        GatewayRequest::Control(control) => {\n            if control.version != GATEWAY_CONTROL_VERSION {\n                anyhow::bail!(\n                    \"unsupported MCP gateway control version {}\",\n                    control.version\n                );\n            }\n            if control.pid == 0 || control.hook_token.trim().is_empty() {\n                anyhow::bail!(\"MCP gateway control authority is incomplete\");\n            }\n        },\n        GatewayRequest::Attach(registration) => validate_registration(registration)?,\n    }\n    Ok(request)\n}\n\nfn validate_registration(registration: &AttachRegistration) -> Result<()> {\n    if registration.version != ATTACH_REGISTRATION_VERSION {\n        anyhow::bail!(\n            \"unsupported MCP attach registration version {}\",\n            registration.version\n        );\n    }\n    super::lifecycle::resolve_principal(Some(&registration.principal))?;\n    if registration.host.trim().is_empty() {\n        anyhow::bail!(\"MCP attach registration has an empty host\");\n    }","sourceCodeStart":893,"sourceCodeEnd":929,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-cli/src/commands/mcp/gateway.rs#L893-L929","documentation":"A parsed GatewayRequest::Control must carry authority proof: a nonzero pid and a non-empty hook_token. read_gateway_request_inner rejects control messages missing either. This ensures only a process that legitimately holds the gateway's minted hook capability can issue stop/status operations.","triggerScenarios":"Sending a control request where control.pid == 0 or control.hook_token.trim() is empty/whitespace, parsed in read_gateway_request_inner.","commonSituations":"Hand-crafted control payloads omitting the token; a client whose token-minting step failed or was skipped; serializing a GatewayControlRequest with default/uninitialized fields (pid defaults to 0, empty token).","solutions":["Populate hook_token with the token minted at gateway startup (mint_hook_token) before sending any control request.","Set pid to the real OS process id (e.g. std::process::id()) — pid 0 is rejected.","If the token is unknown, restart the gateway and read the fresh token from its ready/lease files rather than guessing.","Validate the control struct before sending: non-zero pid, non-blank token."],"exampleFix":"// before\nlet ctl = GatewayControlRequest { version: GATEWAY_CONTROL_VERSION, ..Default::default() };\n// after\nlet ctl = GatewayControlRequest { version: GATEWAY_CONTROL_VERSION, pid: std::process::id(), hook_token: hook_token.clone(), .. };\n","handlingStrategy":"validation","validationCode":"fn control_authority_ok(pid: u32, token: &str) -> bool {\n    pid != 0 && !token.trim().is_empty()\n}","typeGuard":"fn has_authority(ctl: &GatewayControlRequest) -> bool {\n    ctl.pid != 0 && !ctl.hook_token.trim().is_empty()\n}","tryCatchPattern":"match result {\n    Err(e) if e.to_string().contains(\"control authority is incomplete\") => eprintln!(\"control request needs nonzero pid and the minted hook_token\"),\n    other => other?,\n}","preventionTips":["Always load the hook token minted at gateway startup before issuing control requests.","Avoid Default::default() on control structs; set pid and token explicitly.","Never send pid = 0.","Refuse to send control messages when token acquisition failed upstream."],"tags":["mcp","authentication","gateway","validation"],"backgroundTag":"authentication-required","analyzedSha":"affd8760f44190dbdfbec23403f4c4b642c33112","analyzedAt":"2026-09-09T21:28:12.402Z","contentChangedAt":"2026-09-09T21:28:12.402Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}