Figment.so
Mac hostingWebsite hostingGuidesHow to usePricing

Protect Private Data in Remote Mac Screenshots

Automated screenshots power visual regression tests, evidence captures and monitoring dashboards — until one frame lands a password field or a customer record in your artifact store. The macOS screencapture tool captures exactly what you point it at, so region discipline, a permission check and a retention policy are your responsibility. This page gives you a short consent-crop-retention runbook, a test that catches silent TCC denials, and a cost note tied to the specific Figment plan you should use.

Choose a Figment Mac plan for the job

For most web dashboards, Intel-native desktop apps and headless browser pipelines, the $29 Figment virtual Intel macOS VM is the right starting point. It is a real macOS environment (not a relay to another Mac) running on Intel virtualization, with 2 vCPU, 8 GiB RAM and 80 GiB disk. It has no GPU acceleration and no audio device, which matters if the app you screenshot relies on Metal-rendered UI or captures audio alongside video. Access is through the browser console, which gives you a desktop session and a terminal.

If your target app ships Apple-silicon-only, uses Metal-heavy rendering, or you need ARM execution for the toolchain, choose an M-series plan from $95/month. Specific M-series chip, RAM and disk are confirmed in the quote rather than on the pricing card — ask us for a configuration on /mac-hosting and we will tell you what is available before you pay.

One VM-specific note: screencapture on the VM reads the desktop session you see through the browser console. If your automation needs a specific native Mac app, open and test it in that session before you wire it into a schedule.

Grant the Screen Recording TCC permission once, correctly

macOS gates screen reads through TCC (Transparency, Consent, and Control). Any process that invokes screencapture or ScreenCaptureKit must hold Screen & System Audio Recording, and when it does not, the system returns a blank or black frame rather than an error — see Apple's Control access to screen and system audio recording on Mac. Silent blank capture is the single most common failure in automated screenshot pipelines.

To grant it:

  1. Open System Settings → Privacy & Security → Screen & System Audio Recording.
  2. Add the executable that will run your script (your automation binary, Terminal, or iTerm2).
  3. Restart that process after granting — TCC changes do not apply to already-running processes.

tccutil can reset an entry but cannot add one, so plan this step into provisioning and record the exact binary path so the grant survives a rebuild. On a managed fleet, deploy an MDM Privacy Preferences Policy Control payload instead of clicking through the UI.

Test that the grant actually took effect before you trust a scheduled job. Put a full-screen page of a known colour on the display, then capture a small region and compare its hash against a baseline you captured by hand once:

#!/usr/bin/env bash
set -euo pipefail

TEST_FILE="$(mktemp -t tcc_check).png"
trap 'rm -f "${TEST_FILE}"' EXIT

# Capture a 4x4 region where you have displayed a known colour page.
screencapture -R 10,10,4,4 -x -t png "${TEST_FILE}"

WIDTH=$(sips -g pixelWidth  "${TEST_FILE}" | awk '/pixelWidth/{print $2}')
HEIGHT=$(sips -g pixelHeight "${TEST_FILE}" | awk '/pixelHeight/{print $2}')
echo "capture ${WIDTH}x${HEIGHT}"

BASELINE="${HOME}/.tcc_baseline.sha256"
HASH=$(shasum -a 256 "${TEST_FILE}" | awk '{print $1}')
if [[ -f "${BASELINE}" ]]; then
  if [[ "${HASH}" == "$(cat "${BASELINE}")" ]]; then
    echo "OK  pixel hash matches baseline"
  else
    echo "FAIL pixel hash mismatch - TCC denied or display changed"
    exit 1
  fi
else
  echo "no baseline; storing current hash"
  echo "${HASH}" > "${BASELINE}"
fi

File-size heuristics are unreliable because a blank PNG can be the same size as a valid one. Use dimensions and a hashed baseline on a controlled region instead. The screencapture flags used here — -R x,y,w,h, -x (no sound), -t png — are documented in man screencapture on the host; check the exact wording on your installed version.

Apply this three-phase check once per job type, not once per run.

CheckAction
Does the target screen contain user PII, credentials or financial data?Exclude that UI region from capture; if avoidance is impossible, do not capture.
Who is authorised to view the screenshots?Define the access list before the first run.
Is screen capture a documented business requirement?Record the justification in the runbook.
Is the machine shared?Use a dedicated agent account and never run personal sessions on the same desktop.

Phase 2 — Crop (during capture)

Use -R x,y,width,height to limit screencapture to the exact element you need. Never default to full-screen in automation.

#!/usr/bin/env bash
set -euo pipefail

# Capture only the status indicator at top-right (example coordinates).
# Measure with Accessibility Inspector or screencapture -i once.
CAPTURE_REGION="1400,24,480,36"
OUTPUT_DIR="${HOME}/screenshots/$(date -u +%Y-%m-%d)"
OUTPUT_FILE="${OUTPUT_DIR}/status-$(date -u +%H%M%S).png"

mkdir -p "${OUTPUT_DIR}"
screencapture -R "${CAPTURE_REGION}" -x -t png "${OUTPUT_FILE}"

echo "captured: ${OUTPUT_FILE}"
echo "sha256:   $(shasum -a 256 "${OUTPUT_FILE}" | awk '{print $1}')"

Define CAPTURE_REGION as a named constant, comment the UI element it targets, and require code review when the value changes. -t png produces lossless output so text stays legible for evidence captures.

Phase 3 — Retention

Retention ruleRecommended default
Maximum age before deletion7 days (adjust to your compliance requirement)
Storage locationPrivate bucket or volume, not a shared CI artifact store
Encryption at restRequired if screenshots may contain personal data
Access logRecord each read next to the job receipt

Enforce the maximum age with a scheduled launchd job. Apple's Creating Launch Daemons and Agents documents ProgramArguments and StartCalendarInterval for a daily run:

<key>ProgramArguments</key>
<array>
  <string>/bin/bash</string>
  <string>-c</string>
  <string>find /Users/agent/screenshots -mtime +7 -name "*.png" -delete</string>
</array>
<key>StartCalendarInterval</key>
<dict>
  <key>Hour</key><integer>2</integer>
  <key>Minute</key><integer>0</integer>
</dict>

Failure and recovery checks

Blank images. screencapture can exit 0 and still produce a blank frame when TCC is denied or the display is locked. Run the hash check above on each cycle; if it fails, page the owner and skip the downstream steps instead of uploading a black image as evidence.

Drifted coordinates. A macOS update or an app update can shift element positions. After any upgrade, drop the schedule to once a day for a week and spot-check the crops before returning to the normal cadence.

Unexpected content. Popovers, autocomplete dropdowns and notification banners can cover a carefully chosen region. Compare pixel entropy of the captured region against a baseline and flag sharp deviations for human review before storage.

Cost and operating limits

The $29 virtual Intel macOS VM comfortably handles region-cropped screenshot workflows. A 480x36 PNG is roughly 15 KB; 1,000 captures per day is about 15 MB, trivial against the 80 GiB disk. A full 1080p PNG is 1–3 MB, so one-per-minute full-frame capture is 1.4–4.3 GB/day — right-size the region and the schedule rather than the disk.

TierMonthlyUse when
Virtual Intel macOS$29Web dashboards and Intel-native desktop capture without GPU/audio needs
M-seriesfrom $95Apple-silicon-only apps or Metal-rendered UI (exact chip/RAM in quote)

Tax and any setup fees are shown in the checkout for your account; we do not add surprise line items between the plan page and the invoice.

Start or migrate the workload

Migrating from a local Mac: copy your capture scripts, re-measure the crop coordinates on the hosted display resolution, grant Screen Recording to the exact binary you will run, and trigger one manual launchctl start before enabling the schedule. New build: pick the $29 VM, run the TCC baseline test, and wire the retention job on day one so you never store an un-pruned screenshot.

Start a hosted Mac on /mac-hosting/start →


Related guides:
App crash recovery on a hosted Mac · Disk pressure on a hosted Mac agent · GitHub Actions self-hosted runner on Mac


Subscribe for Figma design and website publishing guides.


Figment.so

Contact

Twitter

Website pricing

Compute index

About

Privacy

Terms