Security

    iOS App Transport Security (ATS) and its exceptions

    A 2026 view of iOS App Transport Security enforcing HTTPS by default with a narrow per-domain exception, contrasted with a blanket NSAllowsArbitraryLoads that disables it app-wide

    App Transport Security is iOS's way of making secure network connections the default rather than something each developer has to remember to enforce. Out of the box, ATS requires your app's connections to use HTTPS with modern TLS, and it blocks plaintext HTTP. That default does a lot of security work for free. The risk comes from the exceptions: ATS lets you relax its requirements through Info.plist keys, and a blanket exception that disables it, often added to make one thing work, quietly removes the protection app-wide. Here is what ATS is, how its exceptions work, and how to configure it without undoing the default.

    Short answer

    App Transport Security (ATS) is an iOS feature that enforces secure connections by default: it requires HTTPS with modern TLS and blocks plaintext HTTP unless you declare an exception. Per Apple, ATS is configured through the NSAppTransportSecurity dictionary in your Info.plist, where you can add exceptions, but the broad NSAllowsArbitraryLoads key disables ATS app-wide and is strongly discouraged, with the App Store expecting justification for exceptions. The right approach is to keep ATS enabled, avoid blanket exceptions, and if you genuinely must connect to a server that cannot use modern TLS, add a narrow per-domain exception rather than disabling ATS globally. Let the secure default stand and relax it only as narrowly as necessary.

    What you should know

    • ATS enforces secure connections by default: HTTPS with modern TLS.
    • It blocks plaintext HTTP: unless you declare an exception.
    • It is configured in Info.plist: via the NSAppTransportSecurity dictionary.
    • Blanket exceptions are discouraged: NSAllowsArbitraryLoads disables ATS app-wide.
    • Prefer narrow per-domain exceptions: relax only what you must.

    What is App Transport Security?

    It is an iOS policy that requires app network connections to meet a secure baseline by default. Since it was introduced, ATS has applied to the connections an app makes through the system networking APIs, requiring them to use HTTPS with a modern TLS version, forward secrecy, and strong ciphers, and blocking plaintext HTTP connections. The intent is to make transport security the default state of an app, so that a developer who does nothing special gets encrypted, properly configured connections, rather than having to remember to enforce them. ATS is enforced by the platform and configured declaratively in your Info.plist through the NSAppTransportSecurity dictionary, which is where any relaxations live. So rather than a feature you turn on, ATS is a default you either leave in place or weaken through explicit declarations, which is why the configuration of its exceptions is where the security decisions actually happen.

    How do ATS exceptions work, and where is the risk?

    Through Info.plist keys that relax the default, with broad ones being the risk. The table summarizes.

    KeyEffect
    Default ATSHTTPS with modern TLS required; plaintext blocked
    NSAllowsArbitraryLoadsDisables ATS app-wide; strongly discouraged
    NSExceptionDomainsRelaxes requirements for specific named domains
    Per-domain sub-keysNarrow exceptions, such as allowing a specific domain
    App Store reviewExpects justification for ATS exceptions

    The exceptions exist for real cases, connecting to a third-party server or legacy endpoint that cannot meet the modern requirements, but they differ enormously in scope. NSAllowsArbitraryLoads set to true disables ATS for the entire app, so every connection loses the protection, which is why it is strongly discouraged and why the App Store expects a justification for it. Per-domain exceptions under NSExceptionDomains, by contrast, relax requirements only for the specific domains you name, leaving ATS fully in force everywhere else. The risk is almost always a broad exception added for convenience, often to get a single non-compliant endpoint or a debugging setup working, that ends up disabling transport security across the whole app and then ships.

    How do you configure ATS correctly?

    Keep the default, and scope any exception as narrowly as possible. The baseline is to leave ATS enabled and make sure your own servers use modern TLS so they need no exception at all, which is the case for any current, properly configured backend. If a specific external domain genuinely cannot meet ATS requirements, add a per-domain exception for that domain under NSExceptionDomains, relaxing only what is necessary, rather than reaching for NSAllowsArbitraryLoads, so the rest of your app keeps full protection. Avoid disabling ATS app-wide, and if you ever add a broad exception for development, make sure it does not ship in your release build. Be prepared to justify any exception to App Store review, which is a useful forcing function: if you cannot justify it, you probably should not have it. Periodically revisit exceptions, since a server that needed one may have since upgraded, allowing you to remove it. The principle is to treat ATS as a default worth keeping and to relax it only domain by domain, only when truly required.

    What to watch out for

    The first trap is NSAllowsArbitraryLoads set to true in a release build, which disables ATS for the whole app, often added to fix one endpoint and never narrowed; scope it per domain instead. The second is a development exception that ships to production. The third is stale exceptions for servers that have since upgraded to modern TLS. ATS is Info.plist configuration, so a pre-submission scan such as PTKD.com (https://ptkd.com), which reads the compiled IPA against OWASP MASVS, surfaces your ATS settings and any cleartext or arbitrary-load exceptions, which is exactly the configuration to confirm before release.

    What to take away

    • App Transport Security enforces HTTPS with modern TLS by default on iOS and blocks plaintext HTTP unless you declare an exception in the NSAppTransportSecurity dictionary.
    • The risk is in the exceptions: NSAllowsArbitraryLoads disables ATS app-wide and is strongly discouraged, while per-domain exceptions relax only the domains you name.
    • Keep ATS enabled, make your own servers use modern TLS so they need no exception, scope any required exception per domain, and never ship a development blanket exception.
    • Use a pre-submission scan such as PTKD.com to surface your ATS configuration and any arbitrary-load or cleartext exceptions before release.
    • #ios
    • #app-transport-security
    • #ats
    • #tls
    • #info-plist
    • #owasp-masvs
    • #app-security

    Frequently asked questions

    What is App Transport Security?
    ATS is an iOS policy that requires an app's network connections to meet a secure baseline by default: HTTPS with a modern TLS version, forward secrecy, and strong ciphers, with plaintext HTTP blocked. The intent is to make transport security the default state of an app, so a developer who does nothing special gets encrypted, properly configured connections rather than having to remember to enforce them. It is enforced by the platform and configured declaratively in the Info.plist NSAppTransportSecurity dictionary, where any relaxations are declared.
    What is NSAllowsArbitraryLoads and should I use it?
    NSAllowsArbitraryLoads is an ATS key that, set to true, disables App Transport Security for the entire app, so every connection loses the modern-TLS requirement and plaintext is allowed. It is strongly discouraged, and the App Store expects a justification for it, because it removes transport security app-wide, usually far beyond what was actually needed. If a single endpoint cannot meet ATS, add a per-domain exception for that domain instead, which keeps full protection everywhere else. Avoid shipping a blanket arbitrary-loads exception.
    How do I connect to a server that can't use modern TLS?
    Add a narrow per-domain exception under NSExceptionDomains for that specific domain, relaxing only what is necessary, rather than disabling ATS app-wide with NSAllowsArbitraryLoads. That way the non-compliant server is accommodated while the rest of your app keeps full transport protection. Be prepared to justify the exception to App Store review, and revisit it later, since the server may upgrade to modern TLS and let you remove the exception. The goal is to scope any relaxation as tightly as possible, domain by domain.
    Do ATS exceptions affect App Store review?
    Yes. The App Store expects you to justify ATS exceptions, particularly broad ones like NSAllowsArbitraryLoads, so an unjustified blanket exception can draw scrutiny. This review expectation is a useful forcing function: if you cannot articulate why an exception is necessary, you probably should not have it. Keep exceptions narrow and defensible, prefer per-domain relaxations over disabling ATS globally, and make sure any exception added for development does not ship in your release build, where it would both weaken security and invite questions.
    How do I check my app's ATS configuration?
    Scan the build. ATS is Info.plist configuration, so a pre-submission scan such as PTKD.com reads the compiled IPA against OWASP MASVS and surfaces your ATS settings and any cleartext or arbitrary-load exceptions, which is exactly the configuration to confirm before release. If it shows NSAllowsArbitraryLoads enabled or broad exceptions, the fix is to remove them, ensure your own servers use modern TLS, and scope any genuinely required exception to the specific domain under NSExceptionDomains.

    Keep reading

    Scan your app in minutes

    Upload an APK, AAB, or IPA. PTKD returns an OWASP-aligned report with copy-paste fixes.

    Try PTKD free