Internet Access Policy – Developer Documentation
This section is for app developers. If you are not a developer, you can safely skip it.
Create an Internet Access Policy for your app in just a few minutes
The fastest way to create an Internet Access Policy (IAP) is to use our example as a template.
It covers normal connections as well as connections via system services. All you need to do is to edit and adjust these two files:
- InternetAccessPolicy.plist to place in your Resources folder
- InternetAccessPolicy.strings to place in your language project folder
These example files alone will probably be enough to create an IAP for your own app. Still, don't skip the short information below:
A few more things you should know
- Code Signature: An IAP will only be displayed by Little Snitch and Internet Access Policy Viewer when it's part of a properly signed app bundle. Read more…
- Required fields: Most fields are optional. Required fields are only ApplicationDescription and for every connection Host and Purpose, for every service Name and Purpose. Read more...
- Be complete: You have to list all the connections your app initiates. Don't forget those of system services and embedded frameworks. Some of the frameworks have an IAP of their own. Read more…
- Host: The Host field only accepts domains, subdomains, host names or IP addresses. You can't have an entry for a directory on your server. Read more…
- Wildcards: You can use wildcards at any position of the domain or host name, so myserver*.com will work for myserver1.com, myserver2.com etc. Read more…
- Keep it simple: Keep your explanations short and simple. Read more…
And here is an index of everything else you might find useful:
- File Format
- Connections and Services
- Localization
- Specification of keys
- Service identifiers
- Presentation in Little Snitch
- Which connection descriptions are shown
- Nested IAPs in XPC services, embedded frameworks, and other bundles
- Single executable applications
- (Legacy) Support for XPC services before Little Snitch 4.4
- Writing guidelines
- Troubleshooting
File format
Starting in Little Snitch 4.0.5, Little Snitch not only supports Internet Access Policies in Property List format (InternetAccessPolicy.plist
), but also in JSON format (InternetAccessPolicy.json
). They both have the same logical structure and you can use whichever one you prefer. All information on this page is valid for both formats, even if they only mention one.
You can convert from a Property List IAP to a JSON IAP using the following command:
plutil -convert json -r -e json InternetAccessPolicy.plist
… and back from a JSON IAP to a Property List IAP using this command:
plutil -convert plist -e plist InternetAccessPolicy.json
Connections and Services
Your app establishes connections using various means like a low-level socket
up to high-level APIs like NSURLSession
. These kinds of connections can be documented in the Internet Access Policy using an entry in the Connections
array, as shown above.
But what if you’re writing an app that shows a map using Apple’s MapKit framework? In that case, your app doesn’t establish any connection by itself, but instead a macOS daemon is responsible for loading the map data. In this situation, you can add an entry in the Services
array that documents the fact that your app uses MapKit and Little Snitch can show this fact to the user.
The services in the IAP should include everything that establishes a network connection on your behalf of your app that you do not ship with the app. This does not include XPC Services or frameworks that ship as part of your app (see the section about nested IAPs for that). Examples of services used by your app are:
- A service provided by macOS using a specific system framework like MapKit, CloudKit, GameKit, Core Location, …
- A service provided by macOS using a specific API like background downloads via
NSURLSession
. - If your app syncs files using a service like iCloud Drive, Dropbox, Box, Microsoft OneDrive, Google Drive, …
See Service identifiers below for a discussion of how specify what services your app uses.
Localization
The Internet Access Policy contains texts shown to the user. If your application is available in multiple languages, you also want those texts to be available in these languages. There are two ways to localize an Internet Access Policy:
An Internet Access Policy localized with strings files
Instead of human readable texts for the keys ApplicationDescription
, Purpose
and DenyConsequences
, enter unique keys. Translate these keys to human readable text in localized InternetAccessPolicy.strings
files:
MyApp.app/Contents/Resources/InternetAccessPolicy.plist
MyApp.app/Contents/Resources/
language.lproj/InternetAccessPolicy.strings
An Internet Access Policy for a single executable application
IAPs for executables without a bundle directory have to be integrated in the Info.plist file. Read more…
Specification of keys
Key | Type | Description | |
---|---|---|---|
DeveloperName |
String, optional | The human readable name of your company. Presented to the user as the source of the information. | |
ApplicationDescription |
String, required | A general description of the app. | |
Website |
String, optional | A URL pointing to the website of the app, including the URL scheme, e.g. “https://obdev.at/littlesnitch”. | |
Connections |
Array, optional | An array of connection description dictionaries with the keys defined below | |
IsIncoming |
Boolean, optional | Whether incoming (YES ) or outgoing (NO ) connections are matched. If omitted, matches outgoing connections. |
|
Host |
String, required | A comma-separated list of host or domain names, IP address ranges or a placeholder like local-net . See Which connection descriptions are shown for details. |
|
NetworkProtocol |
String, optional | Can be one of TCP , UDP or ICMP . If omitted, matches any protocol. |
|
Port |
String, optional | A comma-separated list of port ranges, e.g. 20-30, 80, 443 . Defaults to 0-65535 . |
|
Relevance |
String, optional | Indicates how important the connection is for the proper functioning of the application. Values can be Essential or Default . Defaults to Default . Use Essential only if your app is useless without this connection. You can still describe DenyConsequences if you choose default relevance. |
|
Purpose |
String, required | Describes the purpose of the connection. This text is shown to the user as-is, so use easy to understand sentences. Markdown-style links are supported. | |
DenyConsequences |
String, optional | Describes the consequences of denying the connection. Markdown-style links are supported. | |
Services |
Array, optional | An array of service description dictionaries with the keys defined below. | |
Identifier |
String, optional | A unique identifier for the service. See Service identifiers below. | |
Name |
String, required | A short, human-readable name for the service, e.g. “MapKit”. | |
Purpose |
String, required | Describes the purpose of the service in context of the application. This text is shown to the user as-is, so use easy to understand sentences. Markdown-style links are supported. | |
Localizations |
Dictionary, optional | For apps with embedded Info.plist , localization strings are placed here. See section Single executable applications above. |
Service identifiers
By specifying an Identifier
for a service as opposed to only the Name
and Purpose
, Little Snitch can understand what service you mean and give that entry special treatment. This is not implemented as of Little Snitch 4.4, but it is recommended that you add identifiers wherever possible so future versions of Little Snitch can – for example – add an appropriate icon for the service in the user interface when showing your app’s IAP.
In general, if a service is clearly implemented by a specific app or framework, use its bundle identifier (or code signing identifier). For example:
- The MapKit framework provided by macOS is implemented by
/System/Library/Frameworks/MapKit.framework
. The bundle identifier in this framework’s Info.plist iscom.apple.MapKit
. - Core Location:
com.apple.CoreLocation
(/System/Library/Frameworks/CoreLocation.framework
) - GameKit:
com.apple.GameKit
(/System/Library/Frameworks/GameKit.framework
) - Push Notifications:
com.apple.aps
(/System/Library/PrivateFrameworks/ApplePushService.framework
) - StoreKit:
com.apple.StoreKit
(/System/Library/Frameworks/StoreKit.framework
) - Dropbox is a service provided by the Dropbox app, which uses the bundle identifier
com.getdropbox.dropbox
.
If it is not as clear cut as in the examples above, please follow these guidelines:
- Use reverse-DNS style, using the domain of the company that provides the service.
- Use a commonly used name for the service.
- Capitalization doesn’t matter.
Here are a few examples that follow these rules:
- CloudKit: com.apple.CloudKit
- iCloudDrive: com.apple.iCloudDrive
- Background downloads via NSURLSession: com.apple.NSURLSession (no separate framework, use common name)
Presentation in Little Snitch
Little Snitch parses the data you provide and presents it in an appropriate format.
In places where users actively look for information on connections, Little Snitch shows everything that is relevant. That is, the ApplicationDescription
followed by the Purpose
and DenyConsequences
for all relevant connection descriptions (see below for an explanation of Which connection descriptions are shown).
When users are about to deny a connection only the short DenyConsequences
are shown. This provides a means of last resort to inform your users that they are about to adversely affect your app’s functionality.
Note that if the Detail Level preference is set to “Omit port and protocol” in Little Snitch Configuration, port and protocol information may be omitted from the IAP text unless it causes ambiguities (e.g. because that would overlap with another connection your IAP describes).
The following sections explain how the information from the Internet Access Policy is used in different parts of Little Snitch’s user interface.
Connection alert
If Little Snitch is running in alert mode and no rule matches the connection your app tries to establish, users are presented with a connection alert. Expanding the Research Assistant shows all of the information relevant to this specific connection.
Clicking the “Deny…” button shows only the DenyConsequences
. Note that what is shown here depends on the options the user has selected in the connection alert. For example, if they are about to deny “Any Connection”, more DenyConsequences
may be shown than if they only deny connections to the specific domain.
Network Monitor
In the inspector of the Network Monitor, Little Snitch shows information about the connections selected in the connection list. Expanding the Research Assistant shows all of the relevant information.
Clicking the “X” button in a connection line to create a deny rule shows only the DenyConsequences
. Note that what is shown here depends on what line the user clicked on. For example, if they clicked on the line next to an app’s name to deny any connection, more DenyConsequences
may be shown than if they only deny connections of that app to a specific domain.
Configuration
The Research Assistant in Little Snitch Configuration is located at the bottom of the right-hand info sidebar and shows information about the selected rules.
Little Snitch Configuration also shows the DenyConsequences
in various places when the user is about to create a rule that denies connections, e.g. using the rule editor or when creating rules from suggestions.
Which connection descriptions are shown
This section describes the behavior in Little Snitch 4.0.6 and later. Earlier versions are less precise and may also show descriptions that are less relevant.
Hosts and domains
The Host
field of a connection description is a comma-separated list of host names, domain names, or other values as described below. The basic format and meaning is as follows:
- Specific host: Matches only that host, e.g.
Host:
sw-update.example.com
- Domain: Matches that domain and any host in the domain, e.g.
Host:
*.example.com
Starting in Little Snitch 4.4.3, the following values are also supported:
- IP addresses: Matches specific IPv4 or IPv6 addresses. These can be specified as a single address (e.g.
10.0.0.1
), a comma-separated list of addresses, a range of addresses (e.g.10.0.0.1-10.0.0.255
), or CIDR notation10.0.0.1/24
). - Local network: Use the special value
local-net
to match any IPv4 or IPv6 address that is considered to be in the local network (like10.0.0.0/8
,172.16.0.0/12
,192.168.0.0/16
, orfd00::/8
). - Berkeley Packet Filter: Use the special value
bpf
to match any access to Berkeley Packet Filter devices (/dev/bpf*
).
It is possible to create connection descriptions with overlapping Host
values. For example, you could have a description for Host:
sw-update.example.com
(one specific host) and another, more general one for Host:
*.example.com
(the whole domain). Because the specific host is in the domain, both descriptions match when looking up information for sw-update.obdev.at
.
Also, multple descriptions can match because Little Snitch shows IAP information relevant to what the user has currently selected in the connection alert or other places. For example, you could have descriptions for Host:
www.example.com
and Host:
sw-update.example.com
that do not overlap, but when the user creates a rule for the domain example.com
, both descriptions are relevant.
In these situations, Little Snitch uses a set of criteria to determine which descriptions to show. These are designed to keep the information shown to the user as concise as possible to avoid information overload, while giving you as the developer precise control over what should be shown for a particular connection. In short, if there’s an exact match with one of the descriptions, only that description is shown. Otherwise, all relevant descriptions are shown.
Example 1
As an example, assume there are two connection descriptions (the Purpose
fields are overly terse for illustration purposes):
- Connection Description 1:
Host:
sw-update.example.com
Purpose: The app checks for software updates.
- Connection Description 2:
Host:
*.example.com
Purpose: The app checks for software updates and loads the latest news.
What Little Snitch shows depends on what the user selects:
- If the user selects connections to the host
sw-update.example.com
, only Connection Description 1 will be shown (because it’s an exact match). - If the user selects connections to the domain
example.com
, both Connection Description 1 and Connection Description 2 will be shown (becausesw-update.example.com
is in that domain). - If the user selects any connection, both Connection Description 1 and Connection Description 2 will be shown.
While all these are technically correct, it may not be very useful to show both descriptions in the latter two cases because their Purpose
texts overlap in what they say. There’s no value in telling the user twice that the app checks for software updates.
Exact matches for domains and “any connection”
To handle these cases better, there is a way to specify a Host
description that is an exact match for domains and “any connection”:
- Exact Domain: Matches that domain exactly, e.g.
Host:
=*.example.com
- Exactly Any Connection: Matches when the user selects “Any Connection”:
Host:
=*
These descriptions match only when the user selects exactly the respective connection.
Example 2
To improve over Example 1 above, we can use the following three IAP connection descriptions:
- Connection Description 1:
Host:
sw-update.example.com
Purpose: The app checks for software updates.
- Connection Description 2:
Host:
=*.example.com
Purpose: The app checks for software updates and loads the latest news.
- Connection Description 3:
Host:
=*
Purpose: The app checks for software updates and loads the latest news. Also, it connects to the third-party servers you enter.
Again, what Little Snitch shows depends on what the user selects:
- If the user selects connections to the host
sw-update.example.com
only Connection Description 1 will be shown (because it’s an exact match). - If the user selects connections to the domain
example.com
only Connection Description 2 will be shown (because it’s an exact match). - If the user selects any connection, only Connection Description 3 will be shown (because it’s an exact match).
To summarize: If a description’s Host
is an exact match, only that single connection description’s Purpose
and DenyConsequences
will be shown. Otherwise, multiple matching descriptions may be shown.
Matching everything else
There’s one more case that the examples above do not handle: What should be shown if your app connects to arbitrary servers that you don’t know about in advance? For example, if you develop a web browser or file transfer app, it will connect to whatever servers the user enters and you couldn’t possibly know them when writing your app’s IAP. To show a connection description for these connections anyway, you can provide a fallback connection description:
- Fallback Wildcard: Matches everything, but only if no other descriptions match:
Host:
*
Example 3
If you add the following description to Example 2 above…
- Connection Description 4:
Host:
*
Purpose: The app connects to the third-party servers you enter.
… it will be shown whenever a connection is established to a server that is not covered by another connection description, e.g. www.apple.com
. Without this description, no information from your app’s IAP would be shown for that connection.
Summary
Information from only one single connection description is shown in the following cases:
- If the user selects connections to a specific host and that host matches the connection description’s Specific Host. Example:
Host:
sw-update.example.com
- If the user selects connections to a domain and that domain matches the connection description’s Exact Domain. Example:
Host:
=*.example.com
- If the user selects “any connection” and there is a connection description for Exactly Any Connection, i.e.
Host:
=*
Otherwise, if one or more Domain connection descriptions match, information from all of them are shown, ordered by their relevance. Example: Host:
*.example.com
Otherwise, if a connection description with the Fallback Wildcard exists, its information is shown, i.e. Host:
*
Otherwise, no connection descriptions match and no connection-specific IAP information is shown.
Nested IAPs in XPC services, embedded frameworks, and other bundles
This section describes the behavior of Little Snitch 4.4 and later. The behavior of earlier versions of Little Snitch is described below
If an app contains an Internet Access Policy, Little Snitch will also search any XPC Services for an IAP. That means that if your app uses an XPC service, you can add an IAP to the .xpc bundle’s Resources folder and it will be merged with the app’s IAP automatically. This allows you to bundle the documentation with the executable that it actually describes.
For example:
-
MyApp
.app/Contents/Resources/InternetAccessPolicy.plist
Describes the connections established by the app itself.
-
MyApp
.app/Contents/XPCServices/Contents/Resources/InternetAccessPolicy.plist
Describes the connections established by the XPC service on behalf of the app.
The same is true for embedded frameworks, plug-ins, app extensions, and other kinds of loadable bundles that are located in one of the following directories inside the app bundle:
- Frameworks/
- SharedFrameworks/
- PlugIns/
- XPCServices/
These directories are searched recursively. For example, if an XPC service has an IAP, the XPC service’s embedded bundles are searched, too, and so on.
You can use the placeholder %APPNAME%
in localized strings of a nested IAP to refer to the enclosing app’s name. It will be substituted with the app name before being shown to the user.
Note that the value for the key ApplicationDescription
is required for nested IAPs, too, but Little Snitch currently does not show it to the user.
Single executable applications
This feature is available starting in Little Snitch 4.3.3
Internet Access Policy as part of Info.plist
Single executable apps don’t have a bundle directory where an Internet Access Policy file can be deposited. However, they can have an Info.plist
file embedded in the executable file. Since the Internet Access Policy is basically a property list, it can be be added to the embedded Info.plist
. Just create an Internet Access Policy as as described above, but instead of storing it in a separate file, add it to Info.plist
under the top level key InternetAccessPolicy
.
Localization without .lproj bundles
Having no bundle directory also affects localization. We support only one localization method for embedded Info.plist
files, and that is analogous to the strings-file method explained above. Localizations are added at the key path InternetAccessPolicy.Localizations.<language>
where <language>
is the language name used for.lproj
directories (e.g. en
for English).
Example:
Key | Type | Value | |||||
---|---|---|---|---|---|---|---|
▾ | Root | Dictionary | (14 items) | ||||
▾ | InternetAccessPolicy | Dictionary | (3 items) | ||||
ApplicationDescription | String | StringsKey1 | |||||
▸ | Connections | Array | (2 items) | ||||
▸ | Services | Array | (2 items) | ||||
▾ | Localizations | Dictionary | (2 items) | ||||
▾ | en | Dictionary | (2 items) | ||||
StringsKey1 | String | EditHelper is part of myCompany’s text editing suite. It provides dictionary and spell checking services to other components. | |||||
StringsKey2 | String | EditHelper updates its dictionary from this server. | |||||
… |
How to embed an Info.plist in an executable
The Info.plist
file is included in a mach object section in the __TEXT
segment named __info_list
. It can be added using the -sectcreate __TEXT __info_plist
linker option. Fortunately, you don’t need to do this manually. Xcode can do it for you.
Open Xcode, select the target for your executable and go to the Build Settings. Search for Info.plist
. There are two settings which are relevant for us:
- Info.plist File: Enter the path to your
Info.plist
file here. - Create Info.plist Section in Binary: Set this to
Yes
.
(Legacy) Support for XPC services before Little Snitch 4.4
This section describes the legacy behavior of Little Snitch 4.0.5 up to, but excluding, Little Snitch 4.4
Using XPC services allows you to separate your app’s functionality into multiple processes for stability and privilege separation reasons.
Little Snitch treats connections established by an XPC service on behalf of an app as if the connection were established by the app itself. In fact, in most places Little Snitch doesn’t even prominently show to the user that an XPC service is in use. Also, rules are automatically created for just the app itself, instead of via-rules for “App via XPCService” (see Anatomy of a rule, paragraph process for more information about via rules).
Apps that bundle XPC services
If you are developing an app that bundles XPC services, there’s nothing special you have to do in regard to the Internet Access Policy.
Third-party XPC services
If you are developing an XPC service that other developers incorporate into their apps (e.g. as part of a third-party framework), you can provide an Internet Access Policy that describes only the connections of the XPC service. In this case, the files go into the XPC service bundle’s Resources directory.
If the developers who bundle your XPC service in their apps do not include an Internet Access Policy of their own, at least the connections established by your XPC service will be described.
But if the developers who bundle your XPC service in their apps do include their own Internet Access Policy in their app bundle, only that information will be used – the XPC service’s IAP will be ignored. This allows the developers who actually ship an app to have the last say over what information the Internet Access Policy shows to the user.
Because Little Snitch rules usually do not contain information about XPC services, Little Snitch Configuration cannot show an IAP that is contained inside an XPC service. This information will only be shown in the connection alert and Network Monitor where more information about the connecting processes is available.
Writing guidelines
- Little Snitch can be used in demo mode without buying a license, so you can easily test how your text is presented.
- When you write texts, keep the context in mind where the text is displayed. Keep the text short and concise.
- Be honest in your description. At least some of your users have the technical skills to sniff encrypted connections and analyze the data. If you lied, your reputation would likely be affected.
- Make specific descriptions for connections with different purposes. Do not list all purposes in a single catch-all description.
DenyConsequences
should always begin with “If you deny these connections” (or the respective phrase in another language). Note: Earlier versions of this document recommended the use of singular wording (“this connection”), but it turned out that it works better in user interfaces in plural wording.- Avoid long and technical explanations of concepts that are not directly related to what you try to explain. For example, do not explain what a certificate authority is. Instead, add links to Wikipedia or another appropriate source of information in Markdown style, e.g. [digital certificates](https://en.wikipedia.org/wiki/Public_key_certificate)
Troubleshooting
If you bundled an Internet Access Policy with your app, but it does not seem to be used by Little Snitch, here are a few hints that can help you track down the problem.
-
Your app must have a valid code signature, otherwise Little Snitch won't read the
InternetAccessPolicy.plist
file and instead logs a message to the system log (see Console.app and filter for Little Snitch). While you are writing and testing the Internet Access Policy for your app, it is easiest to run it from Xcode using a scheme that has proper code signing set up.Little Snitch verifies the code signature of the following files:
- The app bundle’s executable.
- The
InternetAccessPolicy.plist
file used. - The
InternetAccessPolicy.strings
localization file, if used.
-
If your app uses a helper process for which an IAP should be shown, the IAP files must reside in the app’s Resources as usual. Little Snitch will show these connections as via-connections (e.g. “App via helper”) and look in the parent app’s bundle for IAP information.
-
If Little Snitch shows a generic “Information from application developer” instead of your company’s name as the source of the information, make sure you add the
DeveloperName
key at the top level of theInternetAccessPolicy.plist
. This is the preferred way to specify the source for the IAP. If you do not specify this value, Little Snitch reads your company’s name from the certificate that was used to sign the app. This works only for Developer ID and Development certificates, though. If your app is downloaded from the Mac App Store, you must specify theDeveloperName
.
Was this help page useful? Send feedback.
© 2016-2024 by Objective Development Software GmbH