All posts

How to setup license keys in a native MacOS app

Nicholas Affonso

October 26, 2025

How to setup license keys in a native MacOS app

Building a paid MacOS app often means you need a way to verify license keys, prevent piracy, and give customers a simple way to manage their access. In this guide, you'll learn how to set up license key validation and activation in a Swift-based MacOS app using Keyforge.

We'll also cover how to integrate payments through Stripe and how to let users manage their licenses through the customer portal.

Prerequisites

Before adding licensing to your Mac app, make sure you've completed these steps:

Once done, you'll have a license key you can use to activate your app.

Activating a license in Swift

When a user launches your app for the first time (or when no license key is stored), prompt them to enter their license key. Send it to the Keyforge API to activate the license on that device.

import Foundation

Task {
  let url = URL(string: "https://keyforge.dev/api/v1/public/licenses/activate")!
  var request = URLRequest(url: url)
  request.httpMethod = "POST"
  request.setValue("application/json", forHTTPHeaderField: "Content-Type")

  let body: [String: Any] = [
    "licenseKey": "ABCDE-ABCDE-ABCDE-ABCDE-ABCDE",
    "deviceIdentifier": "macbook-unique-id",
    "deviceName": "John's MacBook Pro",
    "productId": "p_123456"
  ]

  request.httpBody = try! JSONSerialization.data(withJSONObject: body)

  let (data, _) = try! await URLSession.shared.data(for: request)
  let json = try! JSONSerialization.jsonObject(with: data) as! [String: Any]

  print("License activated:", json)
}

After activation, securely store the license key in the Keychain so it can be reused for future validations.

Getting a unique device identifier

There are many ways to acquire a consistent device identifier:

  • IOPlatformUUID from the I/O Registry
  • A UUID stored in Keychain on first launch. Make sure the identifier remains stable between app restarts to keep license activations consistent.

Validating a license at startup

Every time the app launches, you should verify that the license is still valid. This ensures it hasn't been revoked or expired.

import Foundation

Task {
  let url = URL(string: "https://keyforge.dev/api/v1/public/licenses/validate")!
  var request = URLRequest(url: url)
  request.httpMethod = "POST"
  request.setValue("application/json", forHTTPHeaderField: "Content-Type")

  let body: [String: Any] = [
    "licenseKey": "ABCDE-ABCDE-ABCDE-ABCDE-ABCDE",
    "deviceIdentifier": "macbook-unique-id",
    "productId": "p_123456"
  ]

  request.httpBody = try! JSONSerialization.data(withJSONObject: body)

  let (data, _) = try! await URLSession.shared.data(for: request)
  let json = try! JSONSerialization.jsonObject(with: data) as! [String: Any]

  if let isValid = json["isValid"] as? Bool, isValid {
    print("License is valid ✅")
  } else {
    print("License invalid ❌")
  }
}

This call can be made periodically, such as every time the app opens or every few hours.


Extending your setup

Once you have license activation and validation working, you can extend your setup with payments, customer management, and offline support.

Payments

You can automatically generate licenses when a customer buys your app on Stripe. Check out the Stripe integration guide to set this up.

The Stripe integration works with both one-time payments and subscriptions. For recurring payments, licenses automatically expire or renew based on the customer's subscription status.

Customer portal

Customers can view and manage their licenses through the portal. They can:

  • View licenses and activations
  • Reset active devices
  • Download invoices and manage their subscriptions

Offline licensing

If your app needs to run without internet access, Keyforge supports offline license tokens. These are signed JSON Web Tokens (JWTs) that can be verified locally without contacting the server. Protecting your app even without an active connection. Learn more.


Conclusion

You've now implemented a full licensing system in your Swift MacOS app using Keyforge, from activation and validation to payments and customer self-service. This setup helps protect your app while providing a smooth experience for users, whether they're online or offline.

For more details, visit the Keyforge documentation.

Simplify your licensing process

Focus on building your product and let us handle licensing. Generate license keys via Stripe and offer your customers a smooth self-serve experience.