"A permission opens a door. A scope decides how far into the house the visitor may walk."
Why a Bare Permission Isn't Enough
Granting fs:allow-read-text-file says 'this app may read text files' — but which files? Without a scope, that could mean the user's entire disk. A scope narrows a permission to specific paths (for the filesystem) or specific URLs (for the network). It's the difference between 'may read files' and 'may read files inside the app's own data folder.' For anything touching the disk or the network, the scope is where the real safety lives.
Path Scopes with Variables
Filesystem scopes use path patterns, and Tauri provides variables so you don't hardcode absolute paths: $APPDATA, $APPCONFIG, $HOME, $RESOURCE, and more. You write a permission as an object with allow (and optionally deny) path patterns. A glob like $APPDATA/** means 'anything under the app's data directory.' Pair it with a deny for a sensitive subfolder and you've fenced the app into exactly the area it should touch.
Least Privilege, Mechanized
Scopes are how least privilege stops being a slogan and becomes config. Don't grant $HOME/** when the feature only writes to $APPDATA. Don't allow https://** when you only call one API host. Every wildcard you widen is attack surface a compromised frontend could exploit. The narrowest scope that makes the feature work is always the correct one — and deny patterns let you punch precise holes when you must grant broadly.