The two governance properties an AI automation lives or dies on, made into checks a pipeline can block on.
Everything else in this portfolio argues one rule: nothing an AI system does reaches the outside world without a deterministic check and a human approving it, and no secret sits in the open. That rule is easy to state and easy to break by hand, which I proved by finding an API key inline in one of my own workflow headers. I looked at what already exists, and the n8n security scanners on the market are real but generic: secrets, SSRF, injection. None of them check the property that actually defines an AI automation, whether raw model output is allowed to drive an action. So gatekeep leads there.
It had to be safe to run on a real automation estate without becoming a second liability. It reads exported JSON, never needs credentials or a live connection, and refuses to hold a real secret itself: even its test fixtures use redacted placeholders that match the patterns. The rubric is deliberately eight sharp checks with documented heuristics and a config file to extend them, not a hundred-rule scanner nobody trusts the scope of.
Anyone running AI automations who has to promise a client or an auditor that nothing fires unreviewed.
Governance as code, aimed at the AI-specific property generic scanners miss, and CI-blockable.
The check no generic scanner has: raw model output must never reach an action unchecked. gatekeep walks backward from every external action, and a Code or IF node on the path shields it, so anything a deterministic guard validates is considered safe. If the walk reaches an LLM call with nothing in between, it fails. This is the 'model proposes, code decides' rule expressed as reachability, and it is paired with a stricter gate check that refuses to count a timer-resume Wait as human approval, because a lot of automations fake governance with a delay.
The model-to-action check is structural reachability, not true data-flow taint. A workflow that launders model output through a node type I do not classify as a guard, a Set node say, could read as guarded when it is not. I would add lightweight taint tracking on the actual field references, so the check follows the data instead of the graph shape.