Skip to content

Commit 6e192fc

Browse files
committed
Improve Full Disk Access detection with runtime probe
1 parent 806fd72 commit 6e192fc

2 files changed

Lines changed: 78 additions & 11 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ This script audits everything in one pass and tells you exactly what's wrong.
3838
| **PUID/PGID consistency** | All containers using the same user/group IDs |
3939
| **.env validation** | PUID/PGID set and matching your current user |
4040
| **Volume permissions** | Host directories owned by the expected user |
41-
| **Full Disk Access** | Docker/OrbStack has macOS disk access permissions |
41+
| **Full Disk Access** | Best-effort macOS privacy check + runtime bind-mount probe |
4242
| **Compose config** | docker-compose.yml exists and is parseable |
4343

4444
## Quick Start

fix-permissions.sh

Lines changed: 77 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,51 @@ echo " Full Disk Access"
398398
echo "=============================="
399399
echo ""
400400

401+
# Best-effort runtime probe: if a running container can see one of its bind-mounted
402+
# media paths, we treat disk access as effectively working even when TCC rows vary.
403+
runtime_bind_access_probe() {
404+
if [[ -z "$COMPOSE_FILE" ]]; then
405+
return 1
406+
fi
407+
if ! command -v docker >/dev/null 2>&1; then
408+
return 1
409+
fi
410+
411+
local container_ids
412+
container_ids="$(cd "$MEDIA_DIR" && docker compose -f "$COMPOSE_FILE" ps -q 2>/dev/null || true)"
413+
if [[ -z "$container_ids" ]]; then
414+
return 1
415+
fi
416+
417+
local cid src dst src_real
418+
while IFS= read -r cid; do
419+
[[ -n "$cid" ]] || continue
420+
while IFS='|' read -r src dst; do
421+
[[ -n "$src" && -n "$dst" ]] || continue
422+
if [[ ! -e "$src" ]]; then
423+
continue
424+
fi
425+
426+
src_real="$src"
427+
if [[ -d "$src" ]]; then
428+
src_real="$(canonical_dir "$src" || echo "$src")"
429+
fi
430+
431+
if [[ -n "$MEDIA_DIR_REAL" ]] && ! is_path_under "$src_real" "$MEDIA_DIR_REAL" && [[ "$src" != /Volumes/* ]]; then
432+
continue
433+
fi
434+
435+
if docker exec "$cid" sh -lc "test -e \"$dst\"" >/dev/null 2>&1 || \
436+
docker exec "$cid" /bin/sh -lc "test -e \"$dst\"" >/dev/null 2>&1; then
437+
echo "$src|$dst"
438+
return 0
439+
fi
440+
done < <(docker inspect -f '{{range .Mounts}}{{if eq .Type "bind"}}{{printf "%s|%s\n" .Source .Destination}}{{end}}{{end}}' "$cid" 2>/dev/null || true)
441+
done <<< "$container_ids"
442+
443+
return 1
444+
}
445+
401446
# Check Full Disk Access
402447
# macOS stores FDA grants in a TCC database. We can check if the binary is listed,
403448
# but the most reliable method is checking if we can read a protected path.
@@ -409,18 +454,40 @@ elif [[ "$RUNTIME" == "docker-desktop" ]]; then
409454
fi
410455

411456
if [[ -n "$FDA_APP" ]]; then
412-
# Try to detect via TCC database (read-only check)
457+
FDA_CONFIRMED=false
458+
FDA_PATTERN="docker"
459+
if [[ "$RUNTIME" == "orbstack" ]]; then
460+
FDA_PATTERN="orbstack"
461+
fi
462+
463+
# First try TCC database (read-only check). macOS versions can store grants
464+
# under different services, so check for any positive auth row for the runtime.
413465
TCC_DB="$HOME/Library/Application Support/com.apple.TCC/TCC.db"
414-
if [[ -r "$TCC_DB" ]]; then
415-
if sqlite3 "$TCC_DB" "SELECT client FROM access WHERE service='kTCCServiceSystemPolicyAllFiles'" 2>/dev/null | grep -qi "$FDA_APP"; then
416-
pass "Full Disk Access granted for $FDA_APP"
417-
else
418-
warn "Full Disk Access not confirmed for $FDA_APP"
419-
echo " Check: System Settings > Privacy & Security > Full Disk Access"
466+
if [[ -r "$TCC_DB" ]] && command -v sqlite3 >/dev/null 2>&1; then
467+
if sqlite3 "$TCC_DB" "SELECT lower(client),auth_value FROM access;" 2>/dev/null | \
468+
awk -F'|' -v pat="$FDA_PATTERN" '$1 ~ pat && ($2+0) > 0 {found=1} END{exit(found?0:1)}'; then
469+
FDA_CONFIRMED=true
470+
pass "Disk access permission entry found for $FDA_APP in macOS privacy database"
420471
fi
421-
else
422-
warn "Cannot read TCC database to verify Full Disk Access for $FDA_APP"
423-
echo " Manually check: System Settings > Privacy & Security > Full Disk Access"
472+
fi
473+
474+
# Fallback: if a running container can access one of its media bind mounts,
475+
# treat disk access as effectively working even when TCC is not explicit.
476+
if [[ "$FDA_CONFIRMED" == false ]]; then
477+
PROBE_RESULT="$(runtime_bind_access_probe || true)"
478+
if [[ -n "$PROBE_RESULT" ]]; then
479+
PROBE_SRC="${PROBE_RESULT%%|*}"
480+
PROBE_DST="${PROBE_RESULT#*|}"
481+
PROBE_SRC_SHORT="$(echo "$PROBE_SRC" | sed "s|$HOME|~|")"
482+
pass "Runtime bind-mount probe succeeded for $FDA_APP ($PROBE_SRC_SHORT -> $PROBE_DST)"
483+
FDA_CONFIRMED=true
484+
fi
485+
fi
486+
487+
if [[ "$FDA_CONFIRMED" == false ]]; then
488+
warn "Full Disk Access not confirmed for $FDA_APP (best-effort check)"
489+
echo " Check: System Settings > Privacy & Security > Full Disk Access"
490+
echo " If your containers can read/write media paths, this warning can be ignored."
424491
fi
425492
else
426493
warn "Unknown runtime, skipping Full Disk Access check"

0 commit comments

Comments
 (0)