Skip to content

cylonix/openscope

Repository files navigation

OpenScope

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.

Architecture

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 bridge
  • openscoped — signed broker daemon: validates requests, enforces policy, executes actions, appends audit events, returns results
  • asapple — compiled Swift helper co-located with openscoped inside 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.

Build

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.pkg

Quick Start

After 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

Commands

# 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 doctor

Policy

Rules 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 Private

Policy 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.

Configuration Layout

~/.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

Adding a Custom App

  1. Create a YAML manifest following the schema in resources/bundled/apps/notes.yaml.
  2. Place AppleScript files alongside it (or reference them via the script: field).
  3. Copy the manifest to ~/.openscope/apps.d/myapp.yaml.
  4. 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.

macOS Automation Permission

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 ✓

Exit Codes

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

Troubleshooting

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.app

See docs/pilot_guide.md for a full walkthrough.

OpenClaw Integration

If you want to use OpenScope as the security boundary for an OpenClaw agent:

For local native agents, keep using the openscope CLI directly. For sandboxed agents, use the same CLI and point it at either:

  • OPENSCOPE_SOCKET for a provisioned Unix socket
  • OPENSCOPE_HTTP_URL for a localhost bridge such as http://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>.

License

BSD 3-Clause — see LICENSE.

About

OpenScope is a local application access broker for AI agents.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors