Help us shape the future of Go! Take the 2026 Go Developer Survey

umbra

module
v0.244.0 Latest Latest
Warning

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

Go to latest
Published: Oct 2, 2026 License: MIT

README

umbra

occlusion for agent CLIs and APIs

umbra - occlusion for agent CLIs and APIs

Occlusion is the idea. umbra is a least-privilege boundary between an agent and the host system, and what you did not declare does not get through. The boundary lives in a KDL guardfile rather than in code, so it is one artifact a reviewer reads in a sitting. umbra ships no denylist and knows nothing about your tools: policy is yours, and umbra enforces it across two surfaces, cli/ around subprocess exec and http/ around outbound requests.

It validates argv before execve, checks a scope token per verb, prunes every upstream surface to what was granted, and appends every call to a rotating JSONL audit log. A public exit-code taxonomy separates a policy refusal from a tool failure. Full documentation in docs/index.md.

umbra is not a sandbox. It performs no execution isolation, and that is deliberate rather than unfinished. Validating argv and auditing every call does nothing to contain a process that is already running. Isolation is a container's job, and umbra is the gate in front of it.

Two ways in

Generate the CLI. umbra reads KDL policy plus committed locks out of a .umbra/ directory and builds a standalone guarded CLI with no hand-written Go, over three transports: an HTTP API from its OpenAPI contract, a wrapped binary, and an upstream MCP server. --skills-out also renders a native agent skill and a lazy command index.

A wrapped binary may go one step further. A replace wrap is installed under the wrapped tool's own name, ahead of it on PATH, so a caller types git commit and the guardfile's grants are the whole git they can see. umbra install places it and umbra doctor reports what it occludes, including the finding that never passes: a PATH shim is what a caller sees rather than what a caller can reach. See docs/execverb-replacement.md.

Import the primitives. Every package stands alone if you are adding a boundary to an existing urfave/cli v3 app. Nothing consumer-shaped leaks into the API.

go get github.com/coilyco/umbra

Install umbra

brew tap coilyco/tap
brew install coilyco/tap/umbra
scoop bucket add coilyco https://github.com/coilyco/scoop-bucket
scoop install coilyco/umbra

Tagged releases also publish raw binaries and SHA256SUMS for Linux, macOS, and Windows on amd64 and arm64. umbra --version reports both the driver and the umbra ref lock freezes by default. It shells out to the Go toolchain to resolve locks and build, so Go has to be present.

Try it

guides/quickstart.md goes from an empty terminal to a git that can read your repository and cannot push it, assuming no checkout of this one. guides/primitives.md is the shortest look at a refusal, and guides/ holds one walkthrough per surface.

Status and development

v0.x. Minor API breaks land on main with a note in the commit body and no deprecation cycle, so pin a commit in your go.mod until v1.0.0. The API locks once a second consumer lands. umbra is deliberately unguarded, being the framework rather than a consumer of one, so its dev verbs run through the justfile: just build, just test, just lint, just vet, and just docs-cli for the generated CLI reference.

See also

MIT. See LICENSE.

Directories

Path Synopsis
cli
execverb
Package execverb mounts exec-shaped verbs from a KDL Guardfile: the exec dialect of the spec-driven design.
Package execverb mounts exec-shaped verbs from a KDL Guardfile: the exec dialect of the spec-driven design.
verb
Package verb is the middleware that wraps every consumer command action in the standard pipeline of:
Package verb is the middleware that wraps every consumer command action in the standard pipeline of:
cmd
kdl-specs command
Command kdl-specs is the compatibility entrypoint for consumers that have not migrated their Go invocation path to cmd/umbra.
Command kdl-specs is the compatibility entrypoint for consumers that have not migrated their Go invocation path to cmd/umbra.
umbra command
Command umbra is the no-code driver for generating guarded consumer CLIs.
Command umbra is the no-code driver for generating guarded consumer CLIs.
http
guardfile
Package guardfile parses a KDL Guardfile, the human authoring layer (L2) of the specverb engine, into a typed model.
Package guardfile parses a KDL Guardfile, the human authoring layer (L2) of the specverb engine, into a typed model.
mcpverb
Package mcpverb mounts MCP-shaped verbs from a KDL Guardfile: the mcp dialect of the spec-driven design, beside the spec dialect (specverb) and the exec dialect (execverb).
Package mcpverb mounts MCP-shaped verbs from a KDL Guardfile: the mcp dialect of the spec-driven design, beside the spec dialect (specverb) and the exec dialect (execverb).
opcore
Package opcore is the urfave/cli-free engine core of the spec-driven verb design: the per-operation descriptor, the request runtime, and the self-guarding Operation.Execute entrypoint.
Package opcore is the urfave/cli-free engine core of the spec-driven verb design: the per-operation descriptor, the request runtime, and the self-guarding Operation.Execute entrypoint.
respfmt
Package respfmt renders a JSON response body through an optional JMESPath projection and one of five output formats: yaml (default),
Package respfmt renders a JSON response body through an optional JMESPath projection and one of five output formats: yaml (default),
specverb
Package specverb is the runtime engine of the spec-driven verb design: it builds a guarded cli tree from a Guardfile + spec.
Package specverb is the runtime engine of the spec-driven verb design: it builds a guarded cli tree from a Guardfile + spec.
umbra
Cache layout and staleness for the out-of-band materialized consumer binary, keyed by the Guardfile's location.
Cache layout and staleness for the out-of-band materialized consumer binary, keyed by the Guardfile's location.
umbra/codegen
Package codegen renders a complete consumer `main.go` from a KDL Guardfile, so a consumer never hand-writes the specverb wiring.
Package codegen renders a complete consumer `main.go` from a KDL Guardfile, so a consumer never hand-writes the specverb wiring.
umbra/embedfile
Package embedfile materializes umbra-embedded build inputs for one guarded process lifetime.
Package embedfile materializes umbra-embedded build inputs for one guarded process lifetime.
internal
clitrees
Package clitrees exports the demo command trees scripts/gen-webdocs renders into site/cli/.
Package clitrees exports the demo command trees scripts/gen-webdocs renders into site/cli/.
umbracli
Package umbracli owns the shared command tree behind the canonical umbra binary and its temporary kdl-specs compatibility entrypoint.
Package umbracli owns the shared command tree behind the canonical umbra binary and its temporary kdl-specs compatibility entrypoint.
pkg
audit
Package audit writes one JSONL record per CLI invocation to an append-only log outside the working tree.
Package audit writes one JSONL record per CLI invocation to an append-only log outside the working tree.
audit/otelsink
Package otelsink emits umbra audit records as OpenTelemetry spans.
Package otelsink emits umbra audit records as OpenTelemetry spans.
config
App-dir namespacing.
App-dir namespacing.
exitcode
Package exitcode is the public contract for what the process exit code means.
Package exitcode is the public contract for what the process exit code means.
flock
Package flock wraps the BSD advisory whole-file lock (flock(2)) so a consumer can serialise mutually-exclusive work across processes that share a lock file - e.g.
Package flock wraps the BSD advisory whole-file lock (flock(2)) so a consumer can serialise mutually-exclusive work across processes that share a lock file - e.g.
mcpapps
Package mcpapps is the MCP Apps host bridge: the frame-level half of a terminal or embedded host that renders an MCP App and answers the calls that App makes back through its postMessage channel.
Package mcpapps is the MCP Apps host bridge: the frame-level half of a terminal or embedded host that renders an MCP App and answers the calls that App makes back through its postMessage channel.
mcpclient
Package mcpclient is the Model Context Protocol client umbra's mcp dialect speaks: one declared upstream server, a session over it, and the three calls the dialect needs (tools/list, tools/call, resources/read).
Package mcpclient is the Model Context Protocol client umbra's mcp dialect speaks: one declared upstream server, a session over it, and the three calls the dialect needs (tools/list, tools/call, resources/read).
negcontrol
Package negcontrol is the shared result of a negative control, which the dialects produce and the umbra driver reports.
Package negcontrol is the shared result of a negative control, which the dialects produce and the umbra driver reports.
policy
Package policy validates that verb arguments do not contain shell metacharacters.
Package policy validates that verb arguments do not contain shell metacharacters.
scope
Package scope resolves cwd to its git toplevel for an audit record's RepoRoot.
Package scope resolves cwd to its git toplevel for an audit record's RepoRoot.
skillgen
Package skillgen renders an urfave/cli v3 command tree into agent-facing discovery artifacts without making those artifacts runtime authority.
Package skillgen renders an urfave/cli v3 command tree into agent-facing discovery artifacts without making those artifacts runtime authority.
stepflow
Package stepflow executes transport-agnostic ordered step sequences.
Package stepflow executes transport-agnostic ordered step sequences.
tokenmint
Package tokenmint resolves a value that has to be MINTED rather than read.
Package tokenmint resolves a value that has to be MINTED rather than read.
ttlcache
Package ttlcache is a small on-disk key/value cache with per-entry TTLs.
Package ttlcache is a small on-disk key/value cache with per-entry TTLs.
valuesource
Package valuesource is umbra's shared value-resolution layer: a Provider reads a named address at request time, so neither engine imports a store SDK.
Package valuesource is umbra's shared value-resolution layer: a Provider reads a named address at request time, so neither engine imports a store SDK.

Jump to

Keyboard shortcuts

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