bento

module
v0.2.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 3, 2026 License: Apache-2.0

README

Bento Gopher Logo

Bento

CI Release Go Reference OpenSSF Scorecard License

Run untrusted scripts under strict, manifest-declared permissions.

Bento is a lightweight, fail-closed sandbox for Linux that executes untrusted code (build scripts, CLI utilities, AI agent actions) with deny-by-default security. It shields host credentials even if a manifest includes broad read grants, isolates filesystem access, blocks unauthorized network egress, and prevents subprocess execution.

Bento surfaces any gap between what a manifest requests and what the host kernel can enforce, refusing to run under degraded security when --strict is enabled.

The boundary is the host's own kernel: bubblewrap namespaces, seccomp, Landlock, and cgroups are all host-kernel features, so a local privilege escalation in the kernel ends the sandbox. docs/threat-model.md is precise about what that does and does not cover.

Status: Fully implemented and verified on Linux (amd64) using bubblewrap, seccomp, Landlock, and systemd cgroups. Support for Linux (arm64) and macOS is planned; bento doctor names the platform it is reporting on and says when that platform is one of the unverified ones. See docs/architecture.md for architecture details and docs/threat-model.md for security boundaries.


Why Bento?

Bubblewrap and Landlock do the isolation, and Bento uses both. These five are what it adds on top:

  • Credentials stay shielded under a grant that covers them. read: "~" does not expose ~/.ssh, ~/.aws, GPG and OS keyrings, environment-relocated secret stores, .netrc, shell histories, runtime sockets in /run, or persistence targets like .git/hooks and .vscode. The denylist is a maintained corpus, held to parity with firejail's and AppArmor's reference definitions by make audit, and it shields paths that do not exist on the host yet. Parity with those corpora is not completeness - both are desktop-application sandboxes, so developer token stores are still found by review.
  • Permissions you can attest, not just declare. Policy lives in a readable manifest.yaml, and bento approve stamps a fingerprint over the policy fields. Edit the manifest afterwards and bento run refuses until a human re-reviews it. That is the answer to unreviewed permission creep in CI and autonomous agents, which is a likelier failure than an escape.
  • Egress decided per host, and decidable live. Traffic is denied by default in an unshared network namespace; allowed hosts route through a host-side HTTP CONNECT proxy with hostname validation and IP pin checks. An embedder can supply a NetworkGate and approve or refuse a connection at connect time, so a wrapper can ask a human.
  • Discovery that never opens the paths it records. bento profile watches a program under ptrace, reading the paths out of syscall registers rather than opening them, and the program runs sandboxed while it does. So drafting a manifest for code you do not trust is not its own exposure.
  • No quiet degradation. bento doctor reports what this kernel actually enforces, layer by layer. A core guarantee that can only be partially enforced stops the run rather than silently becoming a weaker sandbox, and --strict extends that to the hardening tier.

When not to use Bento

Bento shares the host kernel, so it is the wrong tool where a single kernel escape would be catastrophic: many tenants on one host, or code submitted by strangers at scale. That job wants a boundary that does not rest on the host kernel's own process isolation - a KVM MicroVM per sandbox (Firecracker, and the hosted code-execution services built on that model such as E2B and CubeSandbox), or a userspace kernel that services the guest's syscalls itself (gVisor). Neither takes the host kernel out of the picture, but both shrink what the guest can reach in it.

What that category does not set out to give you is the part Bento is actually for: a policy a human read and stamped. Their permissions are an argument the calling code passed at create time, so there is no artifact for a human to review and nothing to re-check before the next run. Bento's are a manifest.yaml that bento approve fingerprints and bento validate --strict checks, with host credentials shielded even under a grant that covers them.


Requirements & Installation

Requirements
  • OS: Linux with bubblewrap (bwrap) installed and unprivileged user namespaces enabled.
  • Build Toolchain: Go 1.26.5 or later.
  • Optional: systemd user manager with delegated memory, pids, and cpu controllers for resource limits.
Build from Source
make build                    # reproducible static binary (trimmed paths, source-derived stamp)
go build -o bento ./cmd/bento # plain build

Every install path answers bento version. make build stamps the commit and build time it derived from the source; a plain build or go install reports the module version Go recorded - a release tag for @latest, a pseudo-version for a checkout.

A macOS (darwin) build succeeds by design and produces a working binary - the tree carries a stub backend for it, so bento validate and bento approve answer there and a manifest can be reviewed and stamped on a Mac. Anything that has to build or probe a sandbox - run, profile, doctor - refuses at startup with a single message naming the platform. There is no build-time error to catch that on a Mac: Go has no compile-time warning, and a //go:build linux guard on the command would take the two commands that do work off Linux with it. Linux and macOS are the only targets that compile at all - the stub is tagged darwin rather than !linux because Windows has no syscall.SIGSYS or syscall.Stat_t and the BSDs no unix.ENODATA, so a build there fails at compile time rather than reaching the runtime refusal.

Running Inside a Container

A stock container cannot run Bento: it builds its sandbox out of the same kernel features the container runtime already restricts, so bento doctor reports the core layers degraded or unavailable and runs are refused. On Docker, three default restrictions are in the way, and all three have to be lifted:

docker run --security-opt seccomp=unconfined \
           --security-opt apparmor=unconfined \
           --security-opt systempaths=unconfined \
           ...

The image also has to carry bubblewrap itself. It is not in the stock ubuntu, debian, or alpine images, and without it neither core layer is enforced: the network layer is unavailable and the filesystem layer falls to Landlock at best, with doctor naming the missing package. The flags above change nothing until it is installed:

RUN apt-get update && apt-get install -y bubblewrap   # Debian/Ubuntu
  • seccomp=unconfined - the default profile blocks unshare(CLONE_NEWUSER) and pivot_root for a container without CAP_SYS_ADMIN, which is how bubblewrap builds its namespace and root.
  • apparmor=unconfined - needed on hosts with kernel.apparmor_restrict_unprivileged_userns=1 (Ubuntu 23.10 and later). Loading an AppArmor profile that permits bwrap is the narrower alternative, but it is a change to the host, which in CI you may not control.
  • systempaths=unconfined - Docker masks paths under /proc, and bubblewrap cannot mount a fresh procfs over a masked one. Without it doctor reports the filesystem layer degraded - unavailable on a kernel with no Landlock to fall back to - and names this flag, and a run is refused rather than failing at setup with Can't mount proc on /newroot/proc.

Weigh this honestly: those flags loosen the outer container, so the isolation the container gave you is traded for the isolation Bento gives you. That is a reasonable trade when the container is a CI job runner whose purpose is to run Bento, and a poor one when it is a shared multi-tenant sandbox. Running Bento directly on the CI host - GitHub-hosted runners permit unprivileged user namespaces - needs none of it.

Resource limits stay unavailable in a container without a systemd user manager. That is a hardening layer, so a manifest that asks for no limits: runs there unaffected, --strict included. A manifest that does ask for one is refused without --strict too: an unenforceable cap is the one hardening gap that protects the host rather than the target, so running unbounded is not a degradation bento takes on its own. Drop limits: for those hosts, or pass --allow-degraded to run uncapped knowingly - the two flags are opposites and bento refuses them together, so a pipeline gating on --strict wants the manifest edit.

In CI

The artifact CI consumes is the approved manifest, committed next to the script. Profiling and approval happen once, on a developer's terminal; the pipeline only checks the stamp is still good and runs under it. On a GitHub-hosted runner that is the whole job - unprivileged user namespaces are permitted there, so none of the container flags above apply:

jobs:
  sandboxed:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: sudo apt-get update && sudo apt-get install -y bubblewrap
      - run: go install github.com/whiskeyjimbo/bento/cmd/bento@latest
      - run: bento doctor
      - run: bento validate --strict ./fetch.py.manifest.yaml
      - run: bento run --env CI_TOKEN="$CI_TOKEN" ./fetch.py.manifest.yaml
        env:
          CI_TOKEN: ${{ secrets.CI_TOKEN }}

validate --strict is the gate: it fails the job if the manifest is unapproved or was edited since approval, which is what stops permission creep landing in a pipeline nobody re-reviewed. run needs no approval flags once the stamp is in the repo - if it did, the gate would not mean anything. The --env above supplies a secret's value, which is a separate thing from granting it: CI_TOKEN still has to be in the manifest's env: list, and that list is inside the fingerprint.


Quick Start Workflow

Bento follows a 4-step workflow: Profile → Validate → Approve → Run, with bento doctor before all of it.

Run it against examples/probe, a script that reports what the sandbox actually lets it read, write, reach, and execute - so each step has visible output rather than a silent success.

go build -o examples/probe/bento ./cmd/bento
cd examples/probe

./bento doctor                               # 0. what this host can actually enforce
./bento profile  ./probe.py                  # 1. observe what it touches, draft a manifest
./bento validate ./probe.py.manifest.yaml    # 2. check it, and read what it grants
./bento approve  ./probe.py.manifest.yaml    # 3. stamp a fingerprint over the permissions
./bento run      ./probe.py.manifest.yaml    # 4. execute under them

Run step 0 first on a host you have not run Bento on before. A core layer this kernel cannot enforce is a refusal at step 4, and doctor is where you find that out before drafting a manifest - a stock Ubuntu 24.04 install has no bubblewrap, which is one apt-get away but only if you know to look.

Each step has a detail worth knowing before you rely on it:

1. Profile is a loop on a terminal, not one shot: each round asks per path ([y]es / [n]o / [a]ll / [q]uit), mounts what you accept, and runs again until the target stops finding new ones. With stdin not a terminal (a pipe, CI, < /dev/null) it makes one non-interactive default-deny pass instead, granting nothing you were not asked about - only a write directory the target died on is created for a second pass - so a target that branches on a missing file under-reports, and you profile again with grants. Egress is recorded but blocked by default; host credentials are never exposed during profiling. Profiling again merges rather than replaces, so you end up with this run unioned with whatever was already there. Profile says what it changed, including an exec widened to all and an approval stamp the write drops.

2. Validate reports the approval state; --strict makes a missing or stale approval a failure, so it belongs after step 3 (in CI), not here. It also reports whether this host can start what the manifest names - an entrypoint that is not there, an interpreter not on PATH - which --strict fails on too.

3. Approve prints the policy, calls out what deserves a second look, and asks. --yes for CI; a stdin that is not a terminal (a pipe, a Makefile recipe) is refused rather than answered, so an unreviewed stamp is something a caller asked for with --yes.

4. Run refuses if the manifest is unapproved or modified, unless --allow-unapproved is passed.

Step 2 is where the work is. A profiled manifest describes what that one run did, not what the script should be allowed to do: here it proposes exec: all, a write grant over the whole example directory, and both hosts the probe tried - including the one it was denied. Profiling drafts a manifest; approving one is a judgement you make.

The credential shields are the headline feature and this sequence does not show them: the probe demonstrates them against BENTO_PROBE_HOME, and a profiled manifest allowlists only the variables the run actually read, so the shield probes report SKIPPED here. Env does not cross into the sandbox unless the manifest names it - which is the same lesson, arriving the hard way. The tour below runs them.

The probe example also ships hand-written manifests covering the deny-all floor, narrow grants, a broad home grant with the credential shields still holding, per-host egress, and the hardening tier. See its README for a five-minute tour.


Security & Threat Model

Bento assumes the sandboxed program may be hostile or contain compromised dependencies. For complete details on adversary assumptions, non-goals, and residual security gaps, see docs/threat-model.md.

To report a boundary failure privately, and for how versioning treats a shield regression, see SECURITY.md.

What Bento Protects
  1. Credentials & Secrets: SSH keys, cloud CLI tokens, GPG keyrings, crypto vaults, and shell histories under $HOME.
  2. Host Integrity & Persistence: Blocks write access to persistence vectors such as .git/hooks, .vscode, .idea, and shell initialization files (.bashrc, .zshrc).
  3. Host Service Sockets: Shields unix control sockets in /run and /var/run (e.g., Docker daemon, gpg-agent, session bus) to prevent host compromise via socket connections.
  4. Network Egress: Denies outbound network connections by default via an empty network namespace (--unshare-net).
  5. Secrecy During Profiling: Profiling inspects syscall registers directly (via ptrace) without opening host files, preventing untrusted scripts from probing secrets during manifest discovery.
Built-in Shields & Exceptions
  • Directory-Granular Write Grants: Write grants name directories, not individual files (preserving save-via-rename workflows like os.replace or git). Write grants covering shielded paths (e.g., write: "~") are strictly refused, and so are write grants naming or inside one (write: ~/.ssh, write: ~/.bashrc) - by validate --strict and approve on a host that can resolve the grants, and by run in any case.
  • Explicit Shield Opt-In: An explicit read grant naming an exact shield path (e.g., read: ~/.ssh) is honored as a deliberate, read-only exception with loud warnings. Write grants to shield paths remain forbidden.
  • Manifest Integrity Warnings: validate, approve, and run inspect the manifest's own ownership and permissions - including POSIX ACLs, which the mode bits cannot show - and warn when someone other than you can rewrite it. An approval stamp only attests to what whoever can write the file left there.
  • Fail-Closed Principle: Any ambiguity, missing permission, unhandled network request, or missing kernel feature fails closed by default.

Manifest Reference

Manifests define the sandbox policy in YAML:

entrypoint: ./fetch.py          # Script or binary to execute
interpreter: python3            # Optional interpreter (omit for compiled binaries)
interpreter_args: [-u]          # Options for the interpreter itself, before the entrypoint
args: [--verbose]               # Arguments for the script

env: [LANG, AWS_DEFAULT_REGION]  # Allowlist of environment variable names to pass through

read:  [./data]                 # Allowed read paths (deny-by-default; relative to manifest)
write: [./out]                  # Allowed write directories (automatically created if missing)

network:                        # Allowed egress rules (empty/omitted means all network denied)
  - host: api.github.com
    port: "443"

exec: none                      # Subprocess execution: none | none-strict | all
limits: { memory: 128M, cpu: 100%, pids: 32 }

# Provenance block generated by `bento approve`
provenance:
  generated-by: bento profile
  generated-at: 2026-07-14T00:00:00Z
  approves: <sha256-fingerprint-over-policy-fields>
  blocked-hosts: []             # Destinations bento's own egress guard refused to reach

A destination lands there only when the guard refused it because the name resolved into space the sandbox must not reach - loopback, private ranges, cloud metadata - not because a profiling run declined to forward it. A default bento profile forwards no egress at all, so nothing is dialed and the list stays empty; it is populated only under --allow-network.

The blocked-hosts list records how the manifest was drafted, not what it grants, so it stays out of the approves fingerprint. bento approve calls out any network: rule that matches one, so you are not asked to stamp egress bento itself would refuse.

Environment variables

env: is an allowlist of names, not of values. A name on it passes through with whatever value bento's own environment holds; everything else in that environment stays out of the sandbox. For a value the calling environment does not carry - a CI secret, most often - pass it to bento run on the command line:

bento run --env CI_TOKEN="$CI_TOKEN" ./fetch.py.manifest.yaml

--env supplies a value; it does not grant one. A name it names that is not in the manifest's env: list is refused, so a secret reaching the sandbox is a reviewed and stamped decision either way. An allowlisted name with no value anywhere says so at run time rather than handing the script an empty string.

--json, --interpreter and --out are documented in bento <command> --help.

Paths and ~

Read and write paths may start with ~. Bento replaces it with your home directory as it builds the sandbox, so read: [~/projects/api] grants /home/you/projects/api. Three details: quote a bare "~", because unquoted YAML reads it as null; only your own home expands, so spell out another user's (/home/operator/...); and a file whose name really starts with a tilde needs a ./ prefix (./~backup).

Your script does not see that same home directory. Bento sets HOME=/tmp in the sandbox to keep credential files under the real home out of reach, so a script that expands ~ itself gets /tmp/projects/api and fails to open a file you granted. Either have the script use the full path (/home/you/projects/api), or add HOME to the manifest's env: list so the real value is passed through. bento validate prints the HOME your script will see.


Enforcement Matrix

Bento organizes enforcement capabilities into Core and Hardening tiers:

Guarantee Tier Linux Mechanism
Read only granted paths Core Bubblewrap read-only bind mounts, deny-by-default root
Write only granted directories Core Bubblewrap read-write bind mounts; root remounted read-only
Shield credentials & dotfiles Core Mandatory denylist bind mounts (covers uncreated paths)
Deny network egress by default Core Empty network namespace (--unshare-net)
Per-host:port network egress Core Host-side HTTP CONNECT proxy over isolated unix socket
Block execve subprocesses Hardening Seccomp syscall filter (none-strict blocks fork/clone on amd64)
Memory / CPU / PID limits Hardening Systemd transient scope with cgroup v2 controllers
Filesystem backstop Hardening Landlock LSM rules (best-effort secondary layer)

If a hardening layer is missing on the host, bento doctor flags the shortfall. When --strict is passed, bento run refuses to execute under degraded enforcement.

A core guarantee that can only be partially enforced stops the run by default. --allow-degraded overrides that, and it is the widest escape hatch Bento has: it also skips the credential-alias scan entirely, so aliased copies of shielded paths under a granted tree are exposed rather than acknowledged. Use --accept-alias <path> to acknowledge a specific tree instead.


Architecture

Bento is architected around a platform-decoupled enforcement seam:

  • enforce: Core Enforcer interface (Probe + Run) and degradation reporting (Report, enforcement tiers).
  • policy: Domain model, manifest validation, host:port matching, and approval fingerprinting.
  • internal/denylist: Platform-independent mandatory denylist data structures and rules.
  • internal/linux: Linux implementation using bubblewrap, internal/launcher, internal/observe (ptrace profiler), seccomp, and Landlock.
  • internal/proxy: Shared host-side egress HTTP CONNECT proxy.
  • manifest: YAML manifest loader, serializer, and provenance tracker.
  • profile: The Observation a profiling pass records, which backend.Profile returns and manifest synthesis consumes.
  • backend: Backend selection logic and profiling synthesis.

Embedding Bento (Go Library)

Bento can be imported directly into Go applications to enforce sandbox policies in-process, receive structured execution results, or supply custom interactive network gates (such as prompting a human when an agent attempts undeclared network egress).

DispatchReexec is mandatory

Confining a target re-invokes the embedding binary as a hidden launch stage, so backend.DispatchReexec() must be the first statement in main() - before flag parsing, before any other initialization. This applies to tests too: any test package that performs an enforced or profiling run needs it at the top of TestMain, before the testing package parses flags. Without it the staged child runs the whole test suite again, which re-enters the sandbox and stages again.

func TestMain(m *testing.M) {
	backend.DispatchReexec()
	os.Exit(m.Run())
}

A call that never happened is caught before any run starts: backend.New and backend.Profile return an error naming the missed call. They panic instead when the process they are called in is itself an undispatched stage, which is what stops the test-suite fork bomb.

A call made too late - after flag parsing, where the stage dies on its own argv before reaching it - still reaches neither guard, so the parent-side guarantee stands behind both: the stage writes what it applied before it dispatches the target, so a run whose stage stayed silent provably never ran the target, and enforce.Run returns an *enforce.Refusal saying so. The log.Fatalf on err in the example below catches every one of these; it will never report a clean exit 0 for a target that never started.

Minimal Example
package main

import (
	"context"
	"fmt"
	"log"
	"os"

	"github.com/whiskeyjimbo/bento/backend"
	"github.com/whiskeyjimbo/bento/enforce"
	"github.com/whiskeyjimbo/bento/manifest"
)

func main() {
	// Dispatch sandbox re-exec stage before any other initialization
	backend.DispatchReexec()

	ctx := context.Background()

	// 1. Load and parse the manifest file
	manifestPath := "fetch.py.manifest.yaml"
	f, err := os.Open(manifestPath)
	if err != nil {
		log.Fatalf("failed to open manifest: %v", err)
	}
	defer f.Close()

	pol, err := manifest.Load(f)
	if err != nil {
		log.Fatalf("invalid manifest policy: %v", err)
	}

	// 2. Anchor the policy's relative paths to the manifest's own directory. Kept out
	// of Load because it must run after any approval/fingerprint check, never before.
	if err := manifest.Resolve(pol, manifestPath); err != nil {
		log.Fatalf("path resolution failed: %v", err)
	}

	// 3. Resolve environment variables allowed by the manifest policy
	env, _, err := enforce.ResolveEnv(pol, nil, os.LookupEnv)
	if err != nil {
		log.Fatalf("env resolution failed: %v", err)
	}

	// 4. Create the platform backend enforcer
	e, err := backend.New()
	if err != nil {
		log.Fatalf("failed to instantiate enforcer: %v", err)
	}

	// 5. Run the target inside the sandbox
	proc := enforce.Process{Stdin: os.Stdin, Stdout: os.Stdout, Stderr: os.Stderr, Env: env}
	res, err := enforce.Run(ctx, e, pol, proc, enforce.Options{})
	if err != nil {
		log.Fatalf("execution error: %v", err)
	}

	fmt.Printf("Exit Code: %d, Degraded: %v\n", res.ExitCode, res.Report.HasDegradation())
}
Runnable Examples

Explore the examples/ directory for complete, runnable reference code:

  • examples/embed: In-process execution with an interactive NetworkGate supervisor that prompts human approval for undeclared egress.
  • examples/supervise: Full 2-act interactive wrapper demonstrating trial profiling for filesystem access and live proxy gating for network egress.
Live Network Gates vs. Filesystem Approvals

When building a supervised wrapper (such as an editor agent or interactive CLI tool), Bento exposes two distinct interaction models:

  • Live Network Egress (NetworkGate): Outbound traffic is routed through Bento's host-side proxy, allowing your application to supply a live callback (opts.NetworkGate) that prompts or evaluates egress requests synchronously at connect time.
  • Pre-Run Filesystem Approvals: File access is enforced directly inside the Linux kernel (Landlock and mount namespaces) and fails fast with EACCES without a userspace callback seam. Supervised wrappers implement filesystem policy by running a trial profiling pass (backend.Profile), prompting the user to approve/deny recorded file paths, and passing the resulting policy into the enforced run (enforce.Run).

Development & Testing

Run tests and checks locally:

make test       # unit and integration tests (sandbox tests skip if bwrap/userns are missing;
                # the denylist parity tests also want firejail and its apparmor profiles)
make vet
make lint       # golangci-lint, pinned
make audit      # denylist parity against upstream firejail reference definitions
make race       # the proxy's concurrency tests under the race detector (needs a C toolchain)
make crossbuild # the tree still compiles for darwin and linux/arm64
make examples   # each examples/*/verify.sh; the root go test does not reach them

make check      # every gate above - the bar before merging

-race on internal/proxy is a gate, not extra credit: the proxy's cross-connection properties - a gate or egress-guard verdict never landing on another connection - rest on shared state whose narrower breakages pass hundreds of plain runs and fail immediately under the race detector.

The test suite executes real probes inside real bubblewrap sandboxes to verify that security boundaries strictly hold.

To exercise those boundaries by hand, examples/probe is a Python script that runs inside the sandbox and reports what it can actually read, write, reach, and execute, one line per probe. It ships with manifests covering the deny-all floor, narrow grants, a broad home grant with the credential shields still in place, per-host egress, and the hardening tier (none-strict, memory and pid caps). Useful for checking a host's enforcement after a kernel or bubblewrap change, and for seeing what a given manifest really buys before approving it.


License & Security

Bento is released under the Apache 2.0 License.

For security architecture, threat boundaries, and architectural decision records, refer to docs/architecture.md, docs/threat-model.md, and docs/adr/.

Directories

Path Synopsis
Package backend selects the enforcement backend for the host platform.
Package backend selects the enforcement backend for the host platform.
cmd
bento command
Command bento runs a script under a sandbox described by a manifest.
Command bento runs a script under a sandbox described by a manifest.
credhunt command
Command credhunt scans the running user's home directories for credential-shaped files bento does not shield, and prints them for a human to classify.
Command credhunt scans the running user's home directories for credential-shaped files bento does not shield, and prints them for a human to classify.
denylist-audit command
Command denylist-audit reports the home/runtime paths an upstream sandbox project shields that bento does not, so known denylist gaps surface on a cycle instead of in a review.
Command denylist-audit reports the home/runtime paths an upstream sandbox project shields that bento does not, so known denylist gaps surface on a cycle instead of in a review.
Package enforce defines the seam between Bento's platform-independent core and the platform backends that apply isolation (Linux, macOS).
Package enforce defines the seam between Bento's platform-independent core and the platform backends that apply isolation (Linux, macOS).
internal
credhunt
Package credhunt scans a real home directory for files that LOOK like credentials - by mode, by name, and by content shape - and reports the ones no bento shield covers.
Package credhunt scans a real home directory for files that LOOK like credentials - by mode, by name, and by content shape - and reports the ones no bento shield covers.
denylist
Package denylist declares the paths Bento shields no matter what a policy grants.
Package denylist declares the paths Bento shields no matter what a policy grants.
denylist/audit
Package audit cross-references bento's shield list against two upstream corpora - firejail's disable-common/disable-programs profiles and AppArmor's private-files abstractions - so a path they shield but bento does not surfaces as a candidate rather than waiting for an adversarial review to find it.
Package audit cross-references bento's shield list against two upstream corpora - firejail's disable-common/disable-programs profiles and AppArmor's private-files abstractions - so a path they shield but bento does not surfaces as a candidate rather than waiting for an adversarial review to find it.
grantrefusal
Package grantrefusal holds the words bento refuses a grant in.
Package grantrefusal holds the words bento refuses a grant in.
i386
Package i386 issues a syscall through the x86 compat ABI, so a test can prove the foreign-arch guard refuses it.
Package i386 issues a syscall through the x86 compat ABI, so a test can prove the foreign-arch guard refuses it.
landlock
Package landlock applies a Landlock filesystem ruleset as a second, independent kernel confinement layer behind bubblewrap.
Package landlock applies a Landlock filesystem ruleset as a second, independent kernel confinement layer behind bubblewrap.
landlock/internal/probe command
Command probe confines itself to a single directory with Landlock, then reports whether an inside and an outside path are readable, so a test can observe Landlock's real effect in a fresh process (Landlock is irreversible for the process that applies it).
Command probe confines itself to a single directory with Landlock, then reports whether an inside and an outside path are readable, so a test can observe Landlock's real effect in a fresh process (Landlock is irreversible for the process that applies it).
launcher
Package launcher is the in-sandbox stage bento re-execs into.
Package launcher is the in-sandbox stage bento re-execs into.
linux
Package linux enforces a policy with bubblewrap.
Package linux enforces a policy with bubblewrap.
observe
Package observe records what a program does - the files it opens and whether it spawns subprocesses - by running it under ptrace.
Package observe records what a program does - the files it opens and whether it spawns subprocesses - by running it under ptrace.
pathresolve
Package pathresolve resolves a host path the way a write through it would actually land, including through components that do not exist yet.
Package pathresolve resolves a host path the way a write through it would actually land, including through components that do not exist yet.
proxy
Package proxy is Bento's egress allowlist enforcement point.
Package proxy is Bento's egress allowlist enforcement point.
seccomp
Package seccomp installs the exec-blocking syscall filter and performs the execveat transition that lets the launcher start the target under it.
Package seccomp installs the exec-blocking syscall filter and performs the execveat transition that lets the launcher start the target under it.
Package manifest parses Bento's YAML manifest into a validated policy.Policy.
Package manifest parses Bento's YAML manifest into a validated policy.Policy.
Package policy defines the validated permission model at the core of Bento.
Package policy defines the validated permission model at the core of Bento.
Package profile turns what a script was observed doing into a proposed policy.
Package profile turns what a script was observed doing into a proposed policy.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL