capability

package
v0.8.70 Latest Latest
Warning

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

Go to latest
Published: Aug 20, 2026 License: Apache-2.0 Imports: 15 Imported by: 0

Documentation

Overview

Package capability runs curated host actions on behalf of a contained island — the execution half of the capability broker (docs/capability-broker-spec.md). An Adapter maps a (target, args) request to a host action without ever reaching a shell. Who may invoke what (grants) lives in internal/project; this package is only ever reached after a grant check.

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrTargetNotFound  = errors.New("capability target not found")
	ErrTargetUntrusted = errors.New("capability target failed its trust checks")
	ErrTimeout         = errors.New("capability execution timed out")
)

Sentinel errors let the API layer map adapter failures to HTTP status codes without leaking host detail. A target that *ran* and exited non-zero is NOT an error — it returns a Result with a non-zero ExitCode and a nil error.

Functions

This section is empty.

Types

type Adapter

type Adapter interface {
	Name() string
	Execute(ctx context.Context, req Request) (Result, error)
}

Adapter maps a (target, args) request to a host action. Implementations MUST never construct a shell command from request data: exec a fixed program with a fixed argv and pass args out-of-band (JSON on stdin). Name identifies the adapter for the Ledger ("script" | "shortcuts").

func DefaultAdapter

func DefaultAdapter() (Adapter, error)

DefaultAdapter returns the capability adapter for this daemon host. Linux (and other Unix) get the script adapter, backed by ~/.dejima/capabilities/. macOS will get the Apple Shortcuts adapter in Phase 4; until then it errs rather than silently falling back to scripts (a Mac user expects Shortcuts, not a scripts dir). Selection is by host OS because the adapter is the daemon-side mapping; the wire contract (Request/Result) is identical across adapters.

type Request

type Request struct {
	Island string
	Agent  string
	Target string
	Args   map[string]string
}

Request is one capability invocation.

type Result

type Result struct {
	Output   string
	ExitCode int
}

Result is the outcome of a target that started. Output is captured stdout+ stderr (bounded); ExitCode is the process exit status.

type ScriptAdapter

type ScriptAdapter struct {
	Dir       string
	Timeout   time.Duration // 0 → defaultScriptTimeout
	MaxOutput int64         // 0 → defaultScriptMaxOutput
}

ScriptAdapter runs a user-authored executable in Dir (e.g. ~/.dejima/capabilities/) addressed by basename. The directory is the curated allowlist: the island can't write to it, and each target must pass strict trust checks (regular file, owned by the daemon user, not group/world- writable, executable) before it runs. Args arrive as a JSON object on stdin; nothing from the request reaches a shell.

func (*ScriptAdapter) Execute

func (a *ScriptAdapter) Execute(ctx context.Context, req Request) (Result, error)

func (*ScriptAdapter) Name

func (a *ScriptAdapter) Name() string

type ShortcutsAdapter

type ShortcutsAdapter struct {
	Timeout   time.Duration // 0 → defaultScriptTimeout
	MaxOutput int64         // 0 → defaultScriptMaxOutput
}

ShortcutsAdapter runs a macOS Apple Shortcut by name via the `shortcuts` CLI. The user's Shortcuts library is the curated allowlist: the operator grants a Shortcut name, and the brain can invoke only granted ones. Args are handed to the shortcut as JSON on a temp input file; the shortcut's result is captured from stdout. The target is matched by exact name (no path to traverse) and only ever appears on argv — never a shell.

Environment caveat (see docs/capability-broker-spec.md): the `shortcuts` CLI talks to a GUI-session helper. A shortcut LOOKS UP fine from a background / daemon context (a missing name returns "Couldn't find shortcut"), but whether a system LaunchDaemon can actually EXECUTE one — versus needing the user's logged-in aqua session — must be verified live with a real Shortcut.

func (*ShortcutsAdapter) Execute

func (a *ShortcutsAdapter) Execute(ctx context.Context, req Request) (Result, error)

func (*ShortcutsAdapter) Name

func (a *ShortcutsAdapter) Name() string

Jump to

Keyboard shortcuts

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