Skip to content

mesh.firewall.apply

Run the commands mesh.firewall renders, on this host, as root: one allow per rule and source network on ufw or nftables, the executable admitted on the macOS application firewall; nothing else is touched, and every rule written carries the comment `majordomus mesh` so it can be told from an operator's own. Refuses, running nothing, without root or without a backend; records every command with its exit and output; and asks the firewall again afterwards, so the verdict is the firewall's. Offered on the command line only: it runs a privileged host tool, which nothing reachable over HTTP or MCP may do.

Run the commands mesh.firewall renders, on this host, as root: one allow per rule and source network on ufw or nftables, the executable admitted on the macOS application firewall; nothing else is touched, and every rule written carries the comment `majordomus mesh` so it can be told from an operator's own. Refuses, running nothing, without root or without a backend; records every command with its exit and output; and asks the firewall again afterwards, so the verdict is the firewall's. Offered on the command line only: it runs a privileged host tool, which nothing reachable over HTTP or MCP may do.

Exposure

Where this one definition is reachable. Absence is explicit: a surface not listed does not carry it.

surfaceas
MCP—
HTTP—
command linemajordomus mesh firewall apply

Schemas

The canonical input and output, from the Rust types; the MCP tool schema and the OpenAPI parameters and responses are derived from these.

input · FirewallInput

The input of mesh.firewall and mesh.firewall.apply.
propertytyperequireddescription
port integer | null no The port this checkout's server listens on beyond loopback, when it does: a peer dials it there on the link protocol, so it needs admitting too. Omitted, the plan holds the discovery ports and the hub ports the declaration gives this machine.
JSON Schema
{
  "additionalProperties": false,
  "description": "The input of `mesh.firewall` and `mesh.firewall.apply`.",
  "properties": {
    "port": {
      "description": "The port this checkout's server listens on beyond loopback, when it does: a peer\ndials it there on the link protocol, so it needs admitting too. Omitted, the plan\nholds the discovery ports and the hub ports the declaration gives this machine.",
      "format": "uint16",
      "maximum": 65535,
      "minimum": 0,
      "type": [
        "integer",
        "null"
      ]
    }
  },
  "title": "FirewallInput",
  "type": "object"
}

output · FirewallApplyReport

What apply did: the refusal when nothing ran, every command that ran with its outcome, the firewall's word afterwards, and the report the commands came from. ok is the firewall's verdict after the run, never the commands' exit codes alone.

use majordomus_cli::mesh::firewall::{apply, report, FirewallApplyReport};

let a: FirewallApplyReport = apply(report(None, &[], None));
assert!(!a.ok && a.applied.is_empty());
assert!(a.refused.as_deref().unwrap().contains("nothing to apply"));
propertytyperequireddescription
applied array yes The commands, in order, with their exit and output.
before reference yes The report the commands came from.
observation reference yes The firewall's word after the commands ran.
ok boolean yes Whether every command ran and the firewall admits the plan afterwards.
refused string | null no The refusal, when nothing ran: not root, or no backend.
JSON Schema
{
  "$defs": {
    "AdmitCommand": {
      "description": "One command that admits a rule: the rule's label, its argument vector exactly as\n`apply` executes it, and the same quoted as one line a person pastes into a root\nshell. The two are projections of one vector, so what the report shows is what runs.\n\n```\nuse std::net::Ipv4Addr;\nuse majordomus_cli::mesh::firewall::{plan, render, AdmitCommand, Backend};\nuse majordomus_cli::mesh::MeshConfig;\n\nlet config: MeshConfig = serde_json::from_value(serde_json::json!({\n    \"schema\": \"mesh/v1\", \"kind\": \"mesh-declaration\", \"id\": \"doc\", \"enabled\": true,\n})).unwrap();\nlet p = plan(Some(&config), &[Ipv4Addr::new(10, 0, 0, 2)], None);\nlet commands: Vec<AdmitCommand> = render(Backend::Ufw, &p, None);\nassert_eq!(commands[0].argv[0], \"ufw\");\nassert_eq!(commands[0].rule, \"udp/7741 to 239.255.77.77 from any\");\nassert_eq!(commands[0].line, \"ufw allow in proto udp to 239.255.77.77 port 7741 comment 'majordomus mesh: multicast discovery'\");\n```",
      "properties": {
        "argv": {
          "description": "The program and its arguments, as executed.",
          "items": {
            "type": "string"
          },
          "type": "array"
        },
        "line": {
          "description": "The same, quoted for a shell.",
          "type": "string"
        },
        "rule": {
          "description": "The rule it admits.",
          "type": "string"
        }
      },
      "required": [
        "rule",
        "argv",
        "line"
      ],
      "type": "object"
    },
    "Applied": {
      "description": "One command `apply` ran: the line, whether it exited 0 without printing an error,\nand everything it printed, so a refusal by the tool is read in the report and not in\na log.\n\n```\nuse majordomus_cli::mesh::firewall::Applied;\n\nlet a: Applied = serde_json::from_value(serde_json::json!({\n    \"line\": \"ufw allow in proto udp to 239.255.77.77 port 7741\", \"ok\": true, \"output\": \"Rule added\",\n})).unwrap();\nassert!(a.ok && a.output == \"Rule added\");\n```",
      "properties": {
        "line": {
          "description": "The line that ran.",
          "type": "string"
        },
        "ok": {
          "description": "Whether it exited 0.",
          "type": "boolean"
        },
        "output": {
          "description": "What it printed.",
          "type": "string"
        }
      },
      "required": [
        "line",
        "ok",
        "output"
      ],
      "type": "object"
    },
    "Backend": {
      "description": "The firewall front this host runs, as far as the executable can tell without privilege:\ndecided by `detect` from the platform and the path, and the thing `render`,\n`observe` and `apply` are specific to.\n\n```\nuse majordomus_cli::mesh::firewall::Backend;\n\nassert_eq!(serde_json::to_value(Backend::ApplicationFirewall).unwrap(), \"application_firewall\");\nassert_eq!(Backend::None.as_str(), \"none\");\n```",
      "oneOf": [
        {
          "const": "ufw",
          "description": "Uncomplicated Firewall, the Debian and Ubuntu front: `ufw` is on the path.",
          "type": "string"
        },
        {
          "const": "nftables",
          "description": "nftables without ufw in front: `nft` is on the path.",
          "type": "string"
        },
        {
          "const": "application_firewall",
          "description": "macOS: the application firewall (`socketfilterfw`), which admits executables, not ports.",
          "type": "string"
        },
        {
          "const": "none",
          "description": "No firewall front this executable knows; nothing is observed and nothing is applied.",
          "type": "string"
        }
      ]
    },
    "FirewallObservation": {
      "description": "The firewall's own word, judged against the plan: the state, the evidence behind it,\nand the labels of the rules not admitted when the state is `missing`.\n\n```\nuse majordomus_cli::mesh::firewall::{judge_ufw, plan, FirewallObservation, FirewallObservationState};\n\nlet o: FirewallObservation = judge_ufw(\"Status: inactive\\n\", &plan(None, &[], None));\nassert_eq!(o.state, FirewallObservationState::Inactive);\nassert!(o.missing.is_empty() && o.detail.contains(\"inactive\"));\n```",
      "properties": {
        "detail": {
          "description": "The evidence: the status line, the rules found, or the refusal.",
          "type": "string"
        },
        "missing": {
          "description": "The rules not admitted, by label, when `state` is `missing`.",
          "items": {
            "type": "string"
          },
          "type": "array"
        },
        "state": {
          "$ref": "#/$defs/FirewallObservationState",
          "description": "The verdict."
        }
      },
      "required": [
        "state",
        "detail"
      ],
      "type": "object"
    },
    "FirewallObservationState": {
      "description": "What the host's firewall says about the plan, as one word. Only `missing` is a failure\non its own; `unobservable` is an absence that the kernel log may still turn into one.\n\n```\nuse majordomus_cli::mesh::firewall::FirewallObservationState;\n\nassert_eq!(serde_json::to_value(FirewallObservationState::Unobservable).unwrap(), \"unobservable\");\n```",
      "oneOf": [
        {
          "const": "no_backend",
          "description": "No backend to ask.",
          "type": "string"
        },
        {
          "const": "inactive",
          "description": "The firewall is off: nothing filters, nothing is needed.",
          "type": "string"
        },
        {
          "const": "present",
          "description": "Every rule of the plan is admitted.",
          "type": "string"
        },
        {
          "const": "missing",
          "description": "At least one rule of the plan is not admitted.",
          "type": "string"
        },
        {
          "const": "unobservable",
          "description": "The firewall could not be asked from this process — it needs root.",
          "type": "string"
        }
      ]
    },
    "FirewallPlan": {
      "description": "What the declaration implies this host must admit: the rules, the networks they admit\nfrom, the hub ports this machine is listed for, and the addresses the plan saw. The\nanswer of `plan`; an empty `rules` is \"nothing is needed\", which is the answer for no\ndeclaration and for a disabled one.\n\n```\nuse majordomus_cli::mesh::firewall::{plan, FirewallPlan};\n\nlet nothing: FirewallPlan = plan(None, &[], None);\nassert!(nothing.rules.is_empty() && nothing.hub_ports.is_empty() && nothing.networks.is_empty());\n```",
      "properties": {
        "hub_ports": {
          "description": "The ports of the declared hubs this machine is.",
          "items": {
            "format": "uint16",
            "maximum": 65535,
            "minimum": 0,
            "type": "integer"
          },
          "type": "array"
        },
        "local_addresses": {
          "description": "This machine's addresses, as the plan saw them.",
          "items": {
            "type": "string"
          },
          "type": "array"
        },
        "networks": {
          "description": "The private networks peers come from: the enclosing ranges of every address the\ndeclaration names, or of this machine's own when it names none.",
          "items": {
            "type": "string"
          },
          "type": "array"
        },
        "rules": {
          "description": "The admissions, in a fixed order.",
          "items": {
            "$ref": "#/$defs/FirewallRule"
          },
          "type": "array"
        }
      },
      "required": [
        "local_addresses",
        "networks",
        "hub_ports",
        "rules"
      ],
      "type": "object"
    },
    "FirewallReport": {
      "description": "The whole report: the plan, the backend, the commands, the firewall's word and the\nkernel's, with one verdict sentence and one `ok`. What `mesh.firewall` answers and\nwhat the doctor's `firewall` check reads.\n\n```\nuse majordomus_cli::mesh::firewall::{report, FirewallReport, BLOCK_WINDOW_SECONDS};\n\nlet r: FirewallReport = report(None, &[], None);\nassert!(r.ok && r.commands.is_empty());\nassert_eq!(r.window_seconds, BLOCK_WINDOW_SECONDS);\nassert_eq!(r.platform, std::env::consts::OS);\n```",
      "properties": {
        "backend": {
          "$ref": "#/$defs/Backend",
          "description": "The firewall front found."
        },
        "blocked_recently": {
          "additionalProperties": {
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "description": "Drops the kernel logged toward the plan's ports within the window, per port;\nabsent when the log could not be read.",
          "type": [
            "object",
            "null"
          ]
        },
        "commands": {
          "description": "The commands that admit it on this backend; what `apply` runs.",
          "items": {
            "$ref": "#/$defs/AdmitCommand"
          },
          "type": "array"
        },
        "executable": {
          "description": "The executable the server runs as, which is what the macOS firewall admits.",
          "type": [
            "string",
            "null"
          ]
        },
        "observation": {
          "$ref": "#/$defs/FirewallObservation",
          "description": "The firewall's own word about the plan."
        },
        "ok": {
          "description": "Whether the host admits the mesh as far as it can be observed: nothing missing, and\nnothing logged as dropped.",
          "type": "boolean"
        },
        "plan": {
          "$ref": "#/$defs/FirewallPlan",
          "description": "What the declaration implies this host must admit."
        },
        "platform": {
          "description": "The platform (`linux`, `macos`, …).",
          "type": "string"
        },
        "verdict": {
          "description": "The sentence a person reads.",
          "type": "string"
        },
        "window_seconds": {
          "description": "The window `blocked_recently` covers, in seconds.",
          "format": "uint64",
          "minimum": 0,
          "type": "integer"
        }
      },
      "required": [
        "ok",
        "platform",
        "backend",
        "plan",
        "commands",
        "observation",
        "window_seconds",
        "verdict"
      ],
      "type": "object"
    },
    "FirewallRule": {
      "description": "One inbound admission the mesh needs on this host: a protocol and a port, the group it is\naddressed to when it is multicast, the networks it may come from, and the sentence that\nsays why. A rule is derived, never written by hand; `FirewallRule::label` is how a\nverdict names it.\n\n```\nuse majordomus_cli::mesh::firewall::{FirewallRule, Protocol, Role};\n\nlet rule = FirewallRule {\n    role: Role::Hub,\n    protocol: Protocol::Tcp,\n    port: 8791,\n    destination: None,\n    sources: vec![\"192.168.7.0/24\".into()],\n    reason: \"this machine is a declared rendezvous hub\".into(),\n};\nassert_eq!(rule.label(), \"tcp/8791 from 192.168.7.0/24\");\n```",
      "properties": {
        "destination": {
          "description": "The destination address when it is a multicast group; `None` for this host's own.",
          "type": [
            "string",
            "null"
          ]
        },
        "port": {
          "description": "The destination port.",
          "format": "uint16",
          "maximum": 65535,
          "minimum": 0,
          "type": "integer"
        },
        "protocol": {
          "$ref": "#/$defs/Protocol",
          "description": "The transport protocol."
        },
        "reason": {
          "description": "The sentence a person reads beside the rule.",
          "type": "string"
        },
        "role": {
          "$ref": "#/$defs/Role",
          "description": "Why."
        },
        "sources": {
          "description": "The networks the traffic may come from, as CIDR; empty admits any source, which is\nonly ever the case for the multicast group, whose TTL keeps it on the segment.",
          "items": {
            "type": "string"
          },
          "type": "array"
        }
      },
      "required": [
        "role",
        "protocol",
        "port",
        "sources",
        "reason"
      ],
      "type": "object"
    },
    "Protocol": {
      "description": "The transport protocol of a rule: discovery is datagrams, registration and the link\nprotocol are connections. Serialised as the word a firewall front takes.\n\n```\nuse majordomus_cli::mesh::firewall::Protocol;\n\nassert_eq!(serde_json::to_value(Protocol::Udp).unwrap(), \"udp\");\nassert_eq!(serde_json::to_value(Protocol::Tcp).unwrap(), \"tcp\");\n```",
      "oneOf": [
        {
          "const": "udp",
          "description": "Datagrams: discovery.",
          "type": "string"
        },
        {
          "const": "tcp",
          "description": "Connections: the hub's registrations and the link protocol.",
          "type": "string"
        }
      ]
    },
    "Role": {
      "description": "Why a rule exists: which part of the declaration implied it. The role is what a person\nreads beside the rule and what a verdict names, and it is serialised in snake case.\n\n```\nuse majordomus_cli::mesh::firewall::Role;\n\nassert_eq!(serde_json::to_value(Role::Hub).unwrap(), \"hub\");\nlet back: Role = serde_json::from_value(serde_json::json!(\"multicast\")).unwrap();\nassert_eq!(back, Role::Multicast);\n```",
      "oneOf": [
        {
          "const": "multicast",
          "description": "The declared multicast group: every runtime of the segment advertises to it.",
          "type": "string"
        },
        {
          "const": "broadcast",
          "description": "The declared broadcast port, when broadcast is a permitted fallback.",
          "type": "string"
        },
        {
          "const": "hub",
          "description": "This machine is a declared rendezvous hub: the fleet registers here.",
          "type": "string"
        },
        {
          "const": "link",
          "description": "This machine's server is dialed by peers on the link protocol.",
          "type": "string"
        }
      ]
    }
  },
  "description": "What `apply` did: the refusal when nothing ran, every command that ran with its\noutcome, the firewall's word afterwards, and the report the commands came from. `ok`\nis the firewall's verdict after the run, never the commands' exit codes alone.\n\n```\nuse majordomus_cli::mesh::firewall::{apply, report, FirewallApplyReport};\n\nlet a: FirewallApplyReport = apply(report(None, &[], None));\nassert!(!a.ok && a.applied.is_empty());\nassert!(a.refused.as_deref().unwrap().contains(\"nothing to apply\"));\n```",
  "properties": {
    "applied": {
      "description": "The commands, in order, with their exit and output.",
      "items": {
        "$ref": "#/$defs/Applied"
      },
      "type": "array"
    },
    "before": {
      "$ref": "#/$defs/FirewallReport",
      "description": "The report the commands came from."
    },
    "observation": {
      "$ref": "#/$defs/FirewallObservation",
      "description": "The firewall's word after the commands ran."
    },
    "ok": {
      "description": "Whether every command ran and the firewall admits the plan afterwards.",
      "type": "boolean"
    },
    "refused": {
      "description": "The refusal, when nothing ran: not root, or no backend.",
      "type": [
        "string",
        "null"
      ]
    }
  },
  "required": [
    "ok",
    "applied",
    "observation",
    "before"
  ],
  "title": "FirewallApplyReport",
  "type": "object"
}

Policies

benchmark
waived — waived: destructive
cache
disabled — every call runs the handler

Benchmark targets

Derived from the registry for this repository: one requirement per transport, and the cases the input type provides. The whole matrix is on the benchmarks page.

transportstatecasestargets
directwaived (destructive)0

Searches the titles and descriptions of every page this site publishes.