Floor

NAME

MCP::Client::Policy::Floor - the danger floor: a fixed, auditable set of rules for the operations that are dangerous no matter who asked

DESCRIPTION

The danger floor is a permission posture no preset relaxes: the handful of operations that destroy work, hand over the machine, or let the agent edit its own permissions. It is deliberately a plain rule list plus a few named predicates — never a classifier — so it can be read, tested and reasoned about line by line.

Two pieces plug into a MCP::Client::Policy:

  • danger-floor(...) returns the rules, in the ordinary MCP::Client::Policy::Rules schema. Prepend them to a policy's rules (they are just data). Most are expressible as command/args matches; the few that need to look at what a command targets carry a check.

  • floor-checks(...) returns the checks map those check rules name — the target analysis for rm, and the shell-redirect analysis for writes to protected files. These are code, passed to the policy as checks.

The split

Almost everything asks (grantable, but the prompt is shown in red because each rule carries severity => 'danger' and a note saying why). Only two things are a hard deny that even the bypass preset cannot waive: a recursive delete of the filesystem root or your home directory, and a write to the agent's own policy/config. Everything else — force-pushes, reset --hard, sudo, curl | sh, shutdown, dd — is a red ask.

What the floor leaves to the sandbox

The write checks are lexical and best-effort: they resolve ~, ~user and .., and read both redirection targets and path arguments (so tee, cp and sed -i are caught as well as >). Three shapes they deliberately do not catch, because the target is not knowable lexically, are left to the OS sandbox layer (which makes $SADNA_HOME read-only): a redirect to an unreadable variable (> $CFG), a purely relative path (no working directory to measure from), and a glob whose expansion is unknown (> ~/.sadna/conf* — the literal prefix is under the config dir, but the decomposer drops the whole word once any part of it expands). The floor is the approval layer; the sandbox is the containment layer, and the two are meant to be composed.

SYNOPSIS

use MCP::Client::Policy;
use MCP::Client::Policy::Floor;

my $home  = %*ENV<HOME>;
my $sadna = "$home/.sadna";

my $policy = MCP::Client::Policy.new(
    :$provider,
    rules  => [ |danger-floor(:$home, sadna-home => $sadna), |@my-rules ],
    checks => floor-checks(:$home, sadna-home => $sadna),
);

MCP::Client v0.5.0

talk to an MCP server, in either protocol era

Authors

  • Matt Doughty

License

Artistic-2.0

Dependencies

MCP::Server:ver<0.6.0+>:auth<zef:apogee>JSON::Fast:ver<0.19+>:auth<cpan:TIMOTIMO>Cro::HTTP:ver<0.8.11+>:auth<zef:cro>:api<0>MIME::Base64:ver<1.2.5+>:auth<zef:raku-community-modules>

Test Dependencies

Provides

  • MCP::Client
  • MCP::Client::Cache
  • MCP::Client::Correlator
  • MCP::Client::Exceptions
  • MCP::Client::Leases
  • MCP::Client::Leases::Table
  • MCP::Client::Policy
  • MCP::Client::Policy::Commands
  • MCP::Client::Policy::Floor
  • MCP::Client::Policy::Grants
  • MCP::Client::Policy::Rules
  • MCP::Client::Protocol
  • MCP::Client::Reasons
  • MCP::Client::Registry
  • MCP::Client::SSE
  • MCP::Client::Transport
  • MCP::Client::Transport::HTTP
  • MCP::Client::Transport::Stdio
  • MCP::Client::UnknownKeys

The Camelia image is copyright 2009 by Larry Wall. "Raku" is a trademark of the Yet Another Society. All rights reserved.

Built with Podlite — the markup and publishing tools behind this site.