C.W.K.
Stream
Lesson 04 of 06 · published

Scopes: Fencing the Filesystem & Network

~14 min · tauri, scopes, filesystem, security

Level 0Web Tourist
0 XP0/56 lessons0/13 achievements
0/100 XP to next level100 XP to go0% complete
"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.

Code

Fencing the filesystem to the app's own data dir·json
// A scoped fs permission inside a capability: read/write ONLY in the
// app's data dir, and explicitly never in a 'secrets' subfolder.
{
  "identifier": "main-caps",
  "windows": ["main"],
  "permissions": [
    "core:default",
    {
      "identifier": "fs:allow-read-text-file",
      "allow": [{ "path": "$APPDATA/**" }],
      "deny":  [{ "path": "$APPDATA/secrets/**" }]
    },
    {
      "identifier": "fs:allow-write-text-file",
      "allow": [{ "path": "$APPDATA/**" }]
    }
  ]
}

External links

Exercise

Take an fs permission in your app and scope it to $APPDATA/** with an explicit deny for $APPDATA/secrets/**. Write a command (or use the fs plugin) to read a file inside the allowed area (works) and one inside secrets/ (denied). Confirm the deny wins. You've fenced the filesystem with a precision the OS alone wouldn't give you.
Hint
Use the object form of the permission with allow/deny path arrays. $APPDATA resolves to your app's data directory (named by your identifier). The secrets/ read should fail even though the parent is allowed — that's deny-over-allow plus scoping working together.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.