Salta ai contenuti

paranco

Questi contenuti non sono ancora disponibili nella tua lingua.

paranco is a small macOS application whose only job is to hold Full Disk Access and copy files out of a folder macOS protects, along routes you write down, into an ordinary folder any program can read. It exists because macOS keeps some folders, the Voice Memos library among them, closed to any process without that permission, and because granting it to a script or an interpreter grants it to every package installed beside that runtime as well. paranco holds the permission itself and copies files one way, from one allowlisted source to one destination you choose, so whatever reads the destination reads an ordinary folder and is granted nothing.

  • It runs on macOS only. The permission and the protected folders it reads are macOS’s.
  • It reads from one source today, the Voice Memos library, from a list compiled into the binary. Adding a source means editing the source file and rebuilding.
  • It carries no Developer ID, so its bundle has an ad-hoc signature. Every ./build.sh produces a binary the privacy database treats as new, so Full Disk Access has to be granted to it again after each rebuild.
  • It offers no notarised download. It is built from the repository.
  • It writes nothing back to the source: no marker, no ledger, nothing.
  • The command line cannot install the launchd agent. The agent has to run the same bundle that was granted access, so only the window, which is that bundle, can install it.
Terminal window
git clone https://github.com/nerln/paranco
cd paranco
./build.sh

That leaves Paranco.app in the repository folder, built for release; ./build.sh debug builds the debug configuration instead. The first build also generates the icon through make-icon.sh, which needs swiftc and iconutil. Then:

  1. Add Paranco.app to Full Disk Access in System Settings > Privacy & Security.
  2. open Paranco.app.
  3. Add a route: a source from the list and a destination folder, for example ~/Recordings.
  4. Install the agent from the window.
Terminal window
paranco sources # the folders this build may read
paranco routes # the routes on disk
paranco add <source-id> <folder> [--name N] [--ext a,b]
paranco remove <name> # removes every route with that name
paranco check [<folder>] # readable, refused or missing
paranco lift [<name>] # run one route, or all of them, once
paranco watch [seconds] # run every route every N seconds (default 300)
paranco agent status|remove # the launchd agent

The binary can also be produced with swift build -c release --product paranco, which leaves it at .build/release/paranco. paranco add voice-memos ~/Recordings makes a route from the command line. Run from a terminal, the CLI carries the terminal’s own permission, not the application’s, so paranco check on a protected folder still says refused even after Paranco.app has been granted access; use the application or the agent for routes out of protected folders, and the command line for editing the route list or checking folders the terminal can already read.

A route names one source by identifier, never by path, and one destination. Running a route once is a lift: a file with the same name and size as one already at the destination is left alone; a different size means the copy is stale and is copied again; a file whose size changes between two checks two seconds apart is still being written and is skipped until the next run. The destination is the only bookkeeping there is.

A launchd agent runs every enabled route on a timer, every five minutes by default, and once when it is loaded, at install and at every login. It runs the application bundle’s own executable with --agent, the same binary the window uses, because Full Disk Access is granted to that one bundle and has to be spent by it. It logs a line only when a route is refused or something is copied or fails, to ~/Library/Application Support/paranco/agent.log.

Routes live in ~/Library/Application Support/paranco/routes.json, mode 0600 inside a 0700 folder, written through a rename so a reader never sees a half-written file.

paranco on GitHub, MIT licensed.