License validation

License validation ensures that a user has legitimate access to the premium features or content of an app. The rules for this access are defined by a specific licensing mechanism and implemented by a specific licensing framework.

A paid app with no license validation is as good as free.

License validation plays a critical role in app revenue and disabling it is often the primary target of hacking.

Licensing mechanisms

A licensing mechanism defines processes for distributing, purchasing, and using the app and the content it provides. Central to most licensing mechanisms is a license key, a unique token typically associated with a user's account. This key can be supplied in plain text or embedded within a file, which may also contain additional details about the user or transaction.

  1. App distribution: Direct distribution and app stores are the most common mechanisms of delivering an app to a user. Directly distributed apps are usually published on a developer's website, packaged into a DMG or other archive, and require manual download and installation by the user. For apps distributed via app stores, downloading and installation are typically managed by the app store itself.

  2. License purchase: This transaction defines the agreement between the user and the seller, which usually requires a payment in exchange for a license. Depending on the distribution method, this can be a manual procedure on a developer's website, or it can be fully automated and done behind the scenes in an app store. Apps that are directly distributed usually utilize payment processing and license management platforms. Once the transaction is complete, a unique license key is generated and delivered to the user.

  3. License activation: This process involves activating the license key to gain access to restricted features or content in the installed app. For apps distributed directly, the user typically needs to manually enter the license key. For apps distributed via app stores, everything is done behind the scenes. During activation, the app usually contacts a licensing server to verify the validity of the license key.

  4. License validation: After activating a license, its validity is periodically checked to prevent unauthorized app usage and enforce license restrictions. The specific implementation depends on many factors and varies greatly from app to app. Validation can be performed locally or remotely, at app startup or during usage, before accessing a feature, or at random intervals in the background.

  5. License restrictions: Depending on the license type (single-user, multi-user, or site), it can impose constraints on the number of users or devices that can concurrently use the app. Subscriptions often come with licenses that are valid for predetermined durations, requiring renewal after expiration. Licenses associated with in-app purchases, particularly in games, might restrict the frequency or duration of a feature's use.

  6. Trial period: Some apps offer a trial period that allows users to test and evaluate restricted features or content. To prevent users from resetting the trial period, the app can implement additional security measures, such as preventing multiple trials on the same machine or under the same user account.

Digest:

Selecting the appropriate distribution platform and licensing mechanism are foundational elements of the economy and revenue generation of any paid app.

The same app can be distributed on multiple platforms and support different license types and licensing mechanisms.

License validation is a critical part of app security and is often targeted by hackers, leaving apps vulnerable to piracy when not implemented properly.

Adopting a well-thought-out and unique license validation strategy will significantly improve an app's defense against reverse engineering.

Licensing frameworks

The specifics of a license validation solution will depend on the licensing framework used in an app. A licensing framework is usually provided by a distribution app store or a license management platform. In this section, we will examine the different license validation mechanisms offered by three popular licensing frameworks.

Apple’s App Store

Apple's App Stores manage licensing behind the scenes. When an app is installed, a special encrypted receipt file is added into the app's bundle, containing relevant details about the installation and purchases. Apple's StoreKit framework provides all necessary licensing management support, including receipt validation.

However, there is more than one way to validate a receipt. It can be done locally or remotely, using either Apple's tools or your own stack. To implement a successful strategy, it's important to understand how receipts work. There are several open source projects that offer alternative, and often more flexible, features such as TPInAppReceipt:

import Foundation
import TPInAppReceipt
do {
  // 1. Load the app's receipt.
  let receipt = try InAppReceipt.localReceipt()
  // 2. Verify the receipt's signature.
  try receipt.verifySignature()
  // 3. Verify the receipt's bundle ID matches the app's one.
  try receipt.verifyBundleIdentifier()
  // 4. Verify that the receipt's hash matches the local machine's one.
  try receipt.verifyHash()
  print("License is valid:", true)
} catch {
  print("Failed to validate license with error: \(error)")
}

Setapp

Similar to Apple's App Store, Setapp manages licensing behind the scenes, and the Setapp framework provides the necessary support for subscription validation:

import Foundation
import Setapp
// 1. Get Setapp subscription from Setapp manager.
let subscription = SetappManager.shared.subscription
guard let subscription else { fatalError("Cannot access Setapp subscription.") }
// 2. Check the subscription status.
print("License is valid:", subscription.isActive)
// Setapp manager may take a few seconds to initialize and connect with Setapp
// backend once the app is launched. Before this happens, the subscription
// object won't be accessible.

Paddle

Paddle is another lower-level alternative for payment processing and license management. Paddle's Mac SDK framework allows to activate and deactivate a license, as well as verify its activation status:

import Foundation
import Paddle
// 1. Set up your product and vendor details.
let productID = "YOUR_PRODUCT_ID"
let productName = "YOUR_PRODUCT_NAME"
let vendorName = "YOUR_VENDOR_NAME"
// 2. Create Paddle product configuration.
let configuration = PADProductConfiguration()
configuration.productName = productName
configuration.vendorName = vendorName
// 3. Create Paddle product.
let product = PADProduct(productID: productID, productType: .product, configuration: configuration)
guard let product else { fatalError("Cannot create Paddle product.") }
// 4. Verify Paddle license activation state.
let state = try await (product.verifyActivation as () async throws -> PADVerificationState)()
print("License is valid:", state == .verified)