Provide a reusable local trust broker for agent-mediated tool execution on a single-user machine.
The system should stay:
- small enough to audit
- narrow enough to trust
- practical enough to use in real local workflows
The current repo ships as a single-shot Swift CLI, not a long-running daemon.
That boundary is still intentional:
- one executable
- one manifest-driven trust root
- one validation path
- multiple policy modes
The internal shape is still broker-oriented so later daemonization does not require changing the trust model.
Responsibilities:
- expose a narrow command surface
- load the trust manifest
- resolve the selected secret backend
- verify trusted wrapper identity
- verify trusted downstream executable identity
- enforce the selected execution mode
- emit structured errors and audit events
Current command surface:
statusmanifest initmanifest refreshmanifest verifyexecvalidate
Responsibilities:
- record trusted wrapper paths and hashes
- record trusted binary paths and hashes
- define the selected secret backend
- define named secret entries
- define reusable brokered operation sets
- define exec policies with explicit mode
Requirements:
- canonical path storage
- cryptographic hash pinning
- fail-closed verification
- human-editable format
Current repo shape:
{
"version": 2,
"backend": {
"type": "file",
"filePath": "/abs/path/to/demo-secrets.json"
},
"wrappers": {
"example-wrapper": {
"path": "/abs/path/to/example-wrapper",
"sha256": "..."
}
},
"binaries": {
"example-cli": {
"path": "/abs/path/to/example-cli",
"sha256": "...",
"lookupName": "example-demo-cli"
}
},
"secrets": {
"example-token": {
"envVar": "LATCHKEYD_EXAMPLE_TOKEN",
"backendKey": "example-token"
}
},
"operationSets": {
"example-brokered-ops": {
"operations": [
{
"name": "secret.resolve",
"allowedSecrets": ["example-token"],
"allowedResponseFields": ["secretName", "value", "lifetimeSeconds"]
}
]
}
},
"execPolicies": {
"example-demo": {
"mode": "handoff",
"wrapper": "example-wrapper",
"binary": "example-cli",
"secrets": ["example-token"]
},
"example-brokered": {
"mode": "brokered",
"wrapper": "example-wrapper",
"binary": "example-cli",
"secrets": ["example-token"],
"operationSet": "example-brokered-ops"
}
}
}The backend interface stays intentionally small:
- availability check
- resolve named secret
Current backends:
filefor demos, tests, CI, and first-run evaluationkeychainfor real macOS local use
Responsibilities:
- normalize user or agent input
- keep the allowed command surface small and discoverable
- fail closed on unknown operations
- call
latchkeyd execinstead of resolving secrets themselves
Reference wrapper contract:
--health--whoami--version--discover- explicit safe action surfaces such as
demoandbrokered-demo
See ../examples/wrapper-contract.md.
The validation layer exists to prove the expected trust boundary still works.
Current validation checks:
- manifest readability
- trust entry verification
- mode-aware manifest validation
- backend availability
- example wrapper health
- example wrapper handoff demo success
- example wrapper brokered demo success
- at least one denied-path scenario
Observability is local JSONL event logging with no secret values.
The repo now treats execution mode as a first-class architectural boundary.
What enters the child:
- approved secret env vars at launch
What the broker still controls:
- pre-launch wrapper verification
- pre-launch binary verification
- policy scope
- audit event emission
What the broker stops controlling:
- what the child does with the secret after launch
What enters the child:
- approved secret env vars at launch
What the broker still controls:
- everything from
handoff - a narrow first slice of long-lived argument rejection
What the broker stops controlling:
- post-handoff retention inside the child
What enters the child:
- session metadata only at launch
What the broker still controls:
- wrapper verification
- binary verification
- operation-set validation
- live session checks
- request-time allowlist enforcement
- per-request audit events
What the broker stops controlling:
- same-user compromise outside its own trust boundary
- universal tool semantics
Planned mode.
Intent:
- hand the child a scoped short-lived credential instead of a longer-lived root secret
Planned mode.
Intent:
- avoid direct raw secret visibility in the child for high-risk workflows
- A wrapper calls
latchkeyd exec. latchkeydloads the manifest and selected backend.latchkeydverifies the wrapper path and hash.latchkeydverifies the trusted binary path and hash.latchkeydresolves only the approved named secret entries.latchkeydinjects only the approved env vars.latchkeydlaunches the trusted binary.latchkeydemits an audit event.
- A wrapper calls
latchkeyd execfor a brokered policy. latchkeydloads the manifest and verifies wrapper, binary, mode, and operation set.latchkeydcreates a local brokered session and Unix socket.latchkeydlaunches the trusted child without raw secret env vars.- The child receives only session metadata.
- The child requests an approved operation such as
secret.resolve. - The broker verifies session identity, operation allowlist, and secret binding.
- The broker returns the approved result and records audit events.
If any trust, manifest, backend, mode, or brokered-session check fails:
- return a structured error
- record a denial or failure event
- do not fall back to weaker behavior
- do not release the secret
The operator loop is intentionally explicit:
- initialize the manifest
- refresh trust entries when expected local paths change
- verify trust state
- choose the right mode for the task
- use wrappers for approved operations
- validate the workstation setup after changes
The project is not trying to hide trust decisions behind automatic repair.
The broker core is a Swift command-line tool:
- source consumption via Swift Package Manager
- local builds via
swift build - tagged release artifacts via GitHub Releases
- optional Homebrew distribution later
V1 remains macOS-first because local secret-store integration is part of the value.
Possible later backends:
- Linux Secret Service
- Windows Credential Manager
Those are future extensions, not part of the current contract.
- organization-specific policy
- broad connector catalogs
- UI or browser automation logic
- generic auth discovery
- giant policy DSL work
- cloud control-plane assumptions
The repo should expose auditable primitives, reference wrappers, and clear trust boundaries, not a large policy platform.