OpenScope is a scoped access broker for AI agents. Today it brokers protected macOS app access such as Apple Notes and Apple Mail, and the same model can extend to sandboxed agents and future remote operations.
In the broader Cylonix + OpenScope model, Cylonix provides secure private reach into environments, and OpenScope provides the brokered action layer on top of that reach.
AI agent
→ openscope CLI (thin client, one invocation per request)
→ openscoped daemon (signed background process, holds macOS Automation approval)
→ asapple helper (Swift binary that executes AppleScript in-process)
→ Apple Notes / Apple Mail
openscope— CLI wrapper that sends requests to the daemon over a Unix socket or an optional localhost HTTP bridgeopenscoped— signed broker daemon: validates requests, enforces policy, executes actions, appends audit events, returns resultsasapple— compiled Swift helper co-located withopenscopedinside the signed app bundle; the only process that directly touches Apple automation APIs
App behavior is declared in YAML — actions, parameters, scripts — so new integrations can be added without changing Go code.
go build ./...
go test ./...
go vet ./...The asapple Swift helper and the signed macOS app bundle are built via Xcode.
See macos/XcodeSetup.md for setup instructions.
To package for distribution:
# Step 1: Xcode → Product → Archive → Distribute App → Developer ID → export to dist/export/
# Step 2:
scripts/build_pkg.sh --version 0.1.0 # produces dist/OpenScope-0.1.0.pkgAfter installing the .pkg, an openclaw agent is pre-registered with default
scoped access to Apple Notes and Apple Mail:
# Verify the daemon is running
openscope status
# List notes in a folder
openscope notes list_notes --agent openclaw --folder Work
# Read a note
openscope notes read_note --agent openclaw --folder Work --note "My Note"
# Read just the body (plain text, suitable for piping)
openscope notes read_note --agent openclaw --folder Work --note "My Note" --body-only
# List up to 20 unread messages in Inbox
openscope mail list_messages --agent openclaw --mailbox Inbox --limit 20 --unread true
# Read a message by id
openscope mail read_message --agent openclaw --mailbox Inbox --id "<message-id>"
# Read just the message body
openscope mail read_message --agent openclaw --mailbox Inbox --id "<message-id>" --body-only
# Opt in to bundled passthrough apps such as Calendar
sudo openscope app activate --agent openclaw calendar reminders
# Validate the installed setup end to end
openscope-diag# Protected app actions
openscope <app> <action> --agent <agent-id> [flags]
# Reset user config to the current app defaults
openscope init --force
# App management
openscope app list
openscope app show <app>
openscope app enable <app> # user-defined apps only
openscope app disable <app>
sudo openscope app activate --agent <agent-id> <app> [app...]
sudo openscope app deactivate --agent <agent-id> <app> [app...]
openscope app validate [--file <path>]
# Policy management
openscope policy list
openscope policy show --agent <agent-id>
openscope policy validate
sudo openscope policy allow --agent <id> --app <app> --action <action> [--<param> <value> ...]
sudo openscope policy deny --agent <id> --app <app> --action <action> [--<param> <value> ...]
# Agent registry
openscope agent register <agent-id>
openscope agent list
# Protected Notes folder blacklist
openscope notes blacklist list
sudo openscope notes blacklist add private
sudo openscope notes blacklist remove hidden
# Mail sender-domain allowlist
openscope mail domains list
sudo openscope mail domains add mycompany.com
sudo openscope mail domains remove gmail.com
# Root-owned HTTP profiles
openscope http profiles list
sudo openscope http profiles add --name jira-work --base-url https://example.atlassian.net --headers "Authorization=Basic <token>,Accept=application/json"
sudo openscope http profiles remove jira-work
# Root-owned SSH targets
openscope ssh targets list
sudo openscope ssh targets add --alias prod-api-1 --host prod-api-1.internal --user deploy --services web --path-prefixes /var/log/app
sudo openscope ssh targets remove prod-api-1
# Diagnostics
openscope status
openscope doctorRules control which agent may call which action, with optional parameter constraints.
deny overrides allow; no matching allow defaults to deny.
# Allow access to a specific folder only
sudo openscope policy allow --agent my-agent --app notes --action list_notes --folder Work
sudo openscope policy allow --agent my-agent --app notes --action read_note --folder Work
# Block a folder (overrides any allow)
sudo openscope policy deny --agent my-agent --app notes --action list_notes --folder PrivatePolicy is stored in ~/.openscope/policies.yaml. Every allow and deny decision is
appended to ~/.openscope/audit.jsonl.
OpenScope also enforces a root-owned protected-folder blacklist in
/Library/Application Support/OpenScope/protected_folders.yaml. By default,
folders whose names contain private or hidden are denied even if the user
policy would otherwise allow them.
For brokered HTTP integrations such as Jira, root-owned HTTP profiles live in
/Library/Application Support/OpenScope/http_profiles.yaml. For brokered SSH
integrations, named targets live in
/Library/Application Support/OpenScope/ssh_targets.yaml.
For Mail, the default openclaw policy is read-only and constrained to the
Inbox mailbox. No attachment access is provided in the bundled app, and you can
optionally restrict readable messages to specific sender domains with
/Library/Application Support/OpenScope/mail_filters.yaml or the
openscope mail domains CLI.
If you want to reset your user-owned OpenScope YAML files to the current app
defaults, run openscope init --force.
~/.openscope/
agents.yaml # registered agent IDs
policies.yaml # allow/deny rules
audit.jsonl # append-only decision log
apps.d/ # user-defined app definitions (YAML)
state/
enabled_apps.yaml # which user-defined apps are enabled
run/
openscoped.sock # daemon Unix socket
- Create a YAML manifest following the schema in
resources/bundled/apps/notes.yaml. - Place AppleScript files alongside it (or reference them via the
script:field). - Copy the manifest to
~/.openscope/apps.d/myapp.yaml. - Enable it:
openscope app enable myapp
Bundled apps (like notes) are always enabled and live in resources/bundled/.
For a worked example of a custom HTTP-backed app, see docs/jira_over_http.md.
The first time openscoped accesses Apple Notes or Apple Mail, macOS may show a
one-time Automation prompt. Accept it, or pre-grant via:
System Settings → Privacy & Security → Automation → OpenScope → Notes ✓ / Mail ✓
| Code | Meaning |
|---|---|
| 0 | success |
| 2 | invalid command or parameters |
| 3 | denied by policy |
| 4 | target not found |
| 5 | executor or automation failure |
| 6 | configuration or manifest error |
| 7 | daemon unavailable or IPC failure |
openscope doctor # runs all diagnostic checks
openscope status # daemon liveness, socket path, config summary
# Restart the daemon
launchctl kickstart -k gui/$(id -u)/com.ezblock.openscope.openscoped
# Reset Notes Automation permission (triggers a fresh prompt on next use)
tccutil reset AppleEvents com.ezblock.openscope && open /Applications/OpenScope.appSee docs/pilot_guide.md for a full walkthrough.
If you want to use OpenScope as the security boundary for an OpenClaw agent:
- use the runtime instructions in
docs/openclaw/SKILL.md - use the setup guide in
docs/openclaw_user_guide.md - use the sandbox bridge guide in
docs/nemoclaw_socket_demo.mdfor NemoClaw/OpenShell - use the install guide in
docs/nemoclaw_install.mdfor client-only sandbox installs - use the architecture note in
docs/cylonix_openscope_architecture.mdfor the Cylonix + OpenScope model
For local native agents, keep using the openscope CLI directly. For sandboxed
agents, use the same CLI and point it at either:
OPENSCOPE_SOCKETfor a provisioned Unix socketOPENSCOPE_HTTP_URLfor a localhost bridge such ashttp://host.docker.internal:42357
For local setups, OpenScope agent names are best treated as policy and audit labels. For enterprise deployments, registration and policy should be centrally managed and distributed to devices rather than created ad hoc on each machine.
Common Apple apps such as Calendar, Reminders, Contacts, Safari, and Messages
are now bundled as brokered passthrough apps. They are still denied by default
until you opt in with sudo openscope app activate --agent openclaw <app>.
For Notes, a practical default is to name sensitive folders with Private or
Hidden, or add more protected keywords with
sudo openscope notes blacklist add <keyword>. For Mail, keep the default
scope to Inbox and optionally add sender-domain restrictions with
sudo openscope mail domains add <domain>.
BSD 3-Clause — see LICENSE.