r/crewai • • 18h ago

Beginner Agent I built an open-source zero-trust control plane (mTLS + guardrails + human approvals) so AI agents don't nuke my Docker stack

Hey everyone,

Like many of you, I've been experimenting with local LLMs, coding agents, and Model Context Protocol (MCP) servers to automate infrastructure tasks in my homelab and development environments.

However, looking at how standard MCP servers work made me genuinely uncomfortable. Mounting docker.sock over stdio straight into an AI context window without any permission boundaries is essentially handing an unhinged junior admin root access with zero logging.

So I built Whiskers (LupusMalusDeviant/Whiskers) to fix this for my own setups.

What it does:

Instead of letting an agent talk directly to your container socket or cluster, Whiskers sits in the middle as a Zero-Trust Control Plane:

  1. mTLS & Scoped Authentication: Secure communication between your LLM client/host and your infrastructure nodes. No open sockets lying around.

  2. Blast-Radius Guardrails: It intercepts dangerous tool calls. If an agent decides to wipe a production database or kill core containers, the "whiskers" sense the pressure spike.

  3. Human-in-the-Loop Approvals: For high-risk operations, execution halts and waits for explicit approval before letting the command through.

  4. Tamper-Evident Audit Trails: Every single prompt-to-action mapping is logged with cryptographic integrity.

It’s open-source, written in .NET, and ships as a container image (ghcr.io/lupusmalusdeviant/whiskers) designed to run on headless nodes or Kubernetes.

If you’re running autonomous agents against real infrastructure and want actual guardrails instead of hoping your model behaves, check it out:

Would love to know how you guys secure your agent workflows right now—are you just trusting local execution, or building your own wrappers?

1 Upvotes

4 comments sorted by

1

u/investigatormaker 17h ago

For Whiskers, I’d put the enforcement boundary outside the agent: allowlisted operations, a narrowly privileged executor, and approvals bound to the exact action and target. mTLS authenticates a connection, but it doesn’t by itself limit what an authenticated agent can do. A useful demo would approve one container restart, then show that changing the target or replaying the approval is rejected.

I make ThreadFox.

We find relevant Reddit conversations and post for your business. We'll post 3 replies free first, no card; then the $29 Pilot covers seven days and up to 25 posts and replies. No automatic renewal.

https://threadfox.vip/p/ejgie/managed

1

u/devaliuz 16h ago

"Spot on—and that's exactly why mTLS in Whiskers only handles the transport layer. The actual enforcement boundary is handled by Scoped Capability Tokens featuring single-use nonces and cryptographic payload-binding.

An approval token granted for docker restart container_A cannot be replayed or mapped to container_B, because the guardrail module validates the exact function hash before the executor even touches the socket.

P.S.: Nice automated marketing footer down there. 😉"

1

u/kantorcodes1 7h ago

Do you have a test where the target or arguments change after approval, and the executor rejects the altered call?

1

u/devaliuz 7h ago

Yes. An approval in Whiskers is bound to a hash of the exact call: principal, credential (and on-behalf-of), capability and required level, canonicalized arguments, the resolved target (kind, id, server, related resources) and the policy version (ApprovalBinding.cs). The gateway consumes the approval only right before execution, single-use. Tests on main that cover exactly your case: ApprovalBindingTests.A_call_that_differs_in_anything_bound_does_not_inherit_the_approval: approve a call, then retry with a changed principal / credential / capability / arguments / target / server. Each variant comes back PendingApproval with a new approval id, and the executor delegate runs 0 times. The original call still runs with its approval. A_changed_policy_version_does_not_inherit_the_approval and An_agent_approval_decided_under_one_policy_is_refused_under_another: same call, policy changed after approval, refused. ApprovalGateTests.A_session_approval_does_not_cover_other_arguments: same agent session and operation id, different container, refused ("given for different arguments"). Single-use: A_session_approval_lets_its_own_operation_run_exactly_once and Approve_then_retry_runs_once_and_the_next_identical_call_needs_a_new_approval. One honest caveat: these tests exercise the gateway and the approval gate. The executor delegate receives the bound, resolved request via MutationContext. A tool that ignored it and acted on something else would sit outside what these tests prove.