Skip to main content

iOS security and privacy

The Surface Security iOS app is designed to resist accidental (and casual intentional) data leakage of alert content. This page describes what's protected, how, and what's explicitly not protected so you can set realistic expectations.

Protections at a glance

ProtectionHow
Face ID / passcode on every app openLocalAuthentication evaluates the device-owner policy on every .active transition. No grace period.
Screenshots blockedContent is rendered inside a secure-entry UITextField layer — screenshots capture black.
Screen recording blockedSame secure-entry layer blanks recordings; a banner also warns the user.
Copy/paste disabled on alert contentSwiftUI Text is non-selectable by default; SecureTextView overrides every UIKit callout.
Pasteboard cleared on backgroundingUIPasteboard.general.items = [] every time the app backgrounds.
App-switcher preview hiddenAn opaque logo view is attached before iOS snaps the preview.
Tokens stored on-device onlyKeychain with kSecAttrAccessibleWhenUnlockedThisDeviceOnly — cannot be iCloud-backed-up.
Remote sign-outAdmins can revoke a device via the dashboard — next push is refused.

Not protected

Be realistic about the ceiling of what iOS alone can enforce:

  • Jailbroken devices. All of the above protections can be bypassed on a jailbroken phone. We do not attempt to detect jailbreak — the detection arms race is expensive and unreliable, and any organization requiring this protection should enforce it at the MDM layer (e.g. require a managed device, forbid jailbreak via compliance policy).
  • Photographing the screen. Nothing a software app can do prevents a second phone photographing the display. The screenshot and recording protections close the easy vectors, not this one.
  • Visual recall / OCR. If a user sees an alert, they can remember and retype facts elsewhere. These protections stop data export, not human recall.

What we store on-device

The Keychain stores:

  • accessToken (JWT, 24-hour lifetime)
  • refreshToken (longer-lived)
  • serverURL, tenantSlug, tenantID, deviceID

That is all. No alert bodies, screenshots, or user PII are cached to disk outside of normal in-memory rendering. Closing the app purges the render state.

Biometric policy

The gate uses LAPolicy.deviceOwnerAuthentication which:

  • Prefers Face ID / Touch ID if enrolled.
  • Falls back to the device passcode if biometrics fail or aren't enrolled.
  • Allows up to the OS's configured retries (typically 5) before requiring passcode.

Cancelling the prompt leaves the app locked — there is no way to see alert content without unlocking.

Reporting a suspected breach

If you suspect a device has been compromised:

  1. Have the user sign out from the app if possible.
  2. On the web, revoke their device(s) from the Admin users page.
  3. Rotate their password / expire their SSO session.
  4. Review the ios_screenshot_attempt events in the audit log for anomalous activity.