RSS Amplifier

Sentinel Den · Engineering blog · Jun 29, 2026

Lockdown Mode and your security SDK: detecting + responding

0
Sign in to vote or save

Muhammad Khan · Sentinel Den

Apple introduced Lockdown Mode in iOS 16 for users targeted by sophisticated cyberattacks: journalists, activists, government officials, and anyone whose threat profile is mercenary spyware. Toggling it on disables a meaningful chunk of iOS attack surface: WebKit JIT, FaceTime invitations from unknown contacts, complex web fonts, MDM enrollment, attachments in Messages, and more.

For an SDK shipping in a security-relevant iOS app, Lockdown Mode is an important runtime state to know about. A user who has chosen Lockdown Mode is explicitly opting into a more restrictive runtime profile, and your SDK’s behavior should align. Done well, this can become a quiet differentiator: “this SDK respects user-chosen hardening.” Done badly, it can become a silent failure where your jailbreak detection or your TLS pinning is calibrated against assumptions Lockdown Mode invalidates.

Here’s the operational picture as of iOS 19.

What changes when Lockdown Mode is on

The user-visible features Apple documents are a partial list. From an SDK perspective, the changes that matter at runtime:

  1. Some APIs return different results. URLSession rejects connections to hosts using TLS configurations Lockdown considers weak (specific cipher suites, RSA key exchange, expired intermediates). Your TLS pinning logic must handle these failures distinctly from “pinning failed.”

  2. WebKit JIT is disabled. Any embedded WKWebView runs with the interpreter only. A SecurityReport that infers integrity from “JIT is active” is wrong on Lockdown devices.

  3. App-extension communication is restricted. Some background-task scheduling that would normally fire on idle is suppressed.

  4. Profile-based MDM enrollment is blocked. If your app expects to receive a managed-configuration profile, that pathway is closed.

  5. iCloud shared-album invitations from non-contacts are dropped. Niche, but the kind of API your social-photo app might still call.

Detecting Lockdown Mode at runtime

iOS exposes the user’s Lockdown Mode preference via ProcessInfo.processInfo.isLockedDown, an iOS-17+ Bool. The value is set at app launch based on the user’s Settings choice; toggling Lockdown Mode requires a device restart, so the value is stable for your process lifetime.

import Foundation

func isLockdownActive() -> Bool {
    if #available(iOS 17.0, *) {
        return ProcessInfo.processInfo.isLockedDown
    }
    return false
}

For iOS 16 (Lockdown shipped) but pre-iOS-17 (API not yet exposed): there is no first-party API, but the behavior is observable indirectly via a probe. Attempt a URLSession request to a host running a Lockdown-incompatible TLS profile (your test endpoint, NOT a production host). If it fails with a specific TLS error code, the device is in Lockdown. This is fragile and we recommend skipping pre-17 detection and treating the user as standard.

What RuntimeGuard SDK does with this signal

RuntimeGuard SDK’s SecurityReport carries a lockdownActive: Bool field. The report is consumed by your app’s policy code, so what you do with the flag is application-specific, but the framework’s defaults follow a principle: Lockdown users get strictly more conservative defaults, never less. Where this signal sits alongside the device-compromise adversaries is covered in the RuntimeGuard threat model.

Concrete examples:

  • Jailbreak detection threshold lowers. A normal device must trip two independent jailbreak probes to be flagged. A Lockdown device that trips one probe is flagged. The user has indicated they care about exotic compromise; we err toward refusal.

  • TLS pinning fail-mode tightens. A normal device that hits a single pinning mismatch on a non-critical host (analytics, optional CDN) emits a warning and proceeds. A Lockdown device refuses any pinning mismatch, no fallback.

  • App Attest assertion frequency increases. Where a normal session re-attests every 10 minutes, a Lockdown session re-attests every 2 minutes. The cost is small (App Attest assertions are cheap); the benefit is shorter compromise windows.

  • The audit log marks every entry with lockdown: true. Forensic review later can correlate the user’s stated preference with the events that occurred.

What your app’s UI should do

Lockdown Mode is not a binary “is the user a target.” It is a stated preference. The patterns I’ve seen work:

  1. Don’t surface a separate “you’re in Lockdown” banner. The user already knows; the OS told them. Surfacing it again is paternalistic.

  2. Do mention Lockdown-respecting behavior in your privacy / security page. A line like “we respect iOS Lockdown Mode by tightening our SDK’s defaults” tells potential customers that you’ve thought about this. Engineers in adversarial deployment environments notice.

  3. Don’t disable features that work fine under Lockdown. If your app’s feature would still function correctly with Lockdown active, leave it on. Lockdown is restrictive enough already.

  4. Do refuse features that you can’t run safely under Lockdown. A feature that depends on JIT, for instance, would not function under Lockdown. Surface this as “this feature isn’t available under Lockdown” with a brief explanation, rather than silently breaking.

What you should NOT do

Lockdown is a user signal, not an authentication factor. Two anti-patterns:

  • Don’t treat Lockdown as proof the user is high-value. Mercenary-spyware targets are often the customers your SDK most wants to protect, but the inverse is not true. Most Lockdown users are journalists with normal account profiles, not high-net-worth targets.

  • Don’t surface Lockdown status to your analytics pipeline. This is potentially identifying information. The user enabled Lockdown to be harder to track; your SDK propagating “this user is in Lockdown” to a third-party analytics service is a privacy violation in spirit even if not in letter.

Cross-SDK behavior

Across the Sentinel Den SDKs:

  • RuntimeGuard SDK: tightens jailbreak detection thresholds; increases App Attest assertion frequency.
  • PayloadGuardSDK: refuses any TLS pinning fallback; rejects connections at the first mismatch.
  • EnclaveVaultSDK: sets kSecAttrAccessibleWhenUnlocked by default for new keys (vs the more permissive WhenUnlockedThisDeviceOnly that’s the standard default).
  • InputGuardSDK: sets the secure clipboard’s expiration to 30 seconds (vs 5 minutes default).
  • ScreenGuardSDK: treats every screenshot detection as a HIGH-severity event (vs MEDIUM normal), and forwards every event to your SIEM immediately (vs the standard 30-second batch).

These defaults are configurable. If your app has a specific reason to NOT tighten under Lockdown (rare; usually only for niche enterprise customers), the framework lets you override. The defaults are the right answer for 95% of integrations.

When Lockdown is wrong

Two scenarios where the Lockdown adjustment is counterproductive:

  1. The user is on Lockdown for a reason unrelated to your app. A journalist using your wallet app benefits from your wallet’s normal security defaults, not from Lockdown-tightened ones that might cause friction. Your app’s specific threat model might genuinely not need additional tightening.

  2. The Lockdown adjustment breaks a feature the user needs. If a Lockdown user can’t complete a transaction because Lockdown-tightened defaults refuse a legitimate operation, the user will turn off Lockdown to use your app, which defeats the point.

The right answer in both cases is configurability + transparency: surface to the user what’s tightened, let them override if necessary, document the trade-off. The SDK’s defaults are a starting point, not a mandate.

Summary

Lockdown Mode is one of the few user-driven signals iOS exposes that maps cleanly to “this user wants more conservative security.” For an SDK in a security-relevant app, ignoring the signal is leaving useful information on the floor. Detecting it, adjusting defaults, surfacing the adjustment to your app’s policy code: that’s the loop. The cost is minimal; the signal alignment is the win.

Engineering opinion, not advice. This post reflects the author's engineering reasoning at time of publication. It is not professional security, legal, financial, or compliance advice; do not rely on it as a substitute for review by qualified professionals for your specific situation. Posts may become outdated as iOS, Apple frameworks, attacker techniques, and our own SDKs evolve. The canonical source of truth for shipped SDK behavior is /docs and /changelog.

Read the original on sentinelden.com

Comments

Nothing yet. Say the first thing.

    Sign in to join the conversation.