// The packet filter's tools: the node-packet-filter seat's three verbs — what the machine enforces, // reload the mesh's own, remove one thing the mesh did not write — and the module's own reading of // the mesh's table (novox/hq ADR 0045, ADR 0168, ADR 0170). import { registerModuleTools, type ToolDefinition } from "@novox/mesh-sdk/tools"; import { FirewallClient } from "../client.js"; export function getSeatVerbs(firewall: FirewallClient): ToolDefinition[] { return [ { name: "rules", description: "The packet filter as this machine enforces it now: the nftables ruleset and, where the tool exists, the legacy filter's listings. Narrowed to one table or chain when asked.", input: { table: { type: "string", description: "one nftables table, as `family name` (optional)" }, chain: { type: "string", description: "one chain of that table (optional)" }, }, run: async (args) => firewall.rules(args.table ? String(args.table) : undefined, args.chain ? String(args.chain) : undefined), }, { name: "reload", description: "Load the mesh's own filter again from the file the mesh writes, and answer with the mesh's table as loaded.", input: {}, run: async () => firewall.reload(), }, { name: "remove", description: "Remove one rule set the mesh did not write, named exactly as `node show` lists it: `chain X (iptables-legacy)` or `table ip6 filter, chain DOCKER-USER`. " + "Refuses the mesh's tables, the runtime's own chains, a built-in chain and an active found firewall's chains. An operator's act, by name, never a flush.", input: { where: { type: "string", description: "the rule set, as `node show` lists it" } }, run: async (args) => firewall.remove(String(args.where ?? "")), }, ]; } export function getFirewallTools(firewall: FirewallClient): ToolDefinition[] { return [ { name: "firewall_rules", description: "The mesh's live nftables table on this node — what the mesh's own filter is accepting and dropping.", input: {}, run: async () => ({ ruleset: await firewall.ruleset() }), }, ]; } const firewall = FirewallClient.fromEnv(); // The seat's verbs under the seat's name: the runtime serves them on the seat's subjects where this // module holds it (ADR 0159, 0160). The module's own under its own. registerModuleTools("node-packet-filter", () => getSeatVerbs(firewall)); registerModuleTools("nftables", () => getFirewallTools(firewall));