Elixir reaches the dongle through the SDK’s flat C API with a NIF of two hundred lines that loads the native library at run time and resolves the functions by name, so nothing is linked and nothing sits in the path of the check that a customer could substitute for something more agreeable. The NIF is compiled with the package (elixir_make), every dongle call runs on a dirty I/O scheduler. keynub_licdongle from Hex, Elixir 1.13 or later, on Windows, Linux and macOS.
# mix.exs
def deps do
[{:keynub_licdongle, "~> 1.1"}]
endCode language: Elixir (elixir)
Reading a License
alias KeyNub.LicDongle
{:ok, license} =
LicDongle.with_dongle(fn d -> # first dongle, or with_dongle("serial", fn ...)
LicDongle.verify_genuine!(d) # raises unless genuine
LicDongle.with_session!(d, fn ->
LicDongle.read_record!(d, "license")
end)
end)Code language: Elixir (elixir)
What You Are Protecting
Elixir software that is sold is usually the kind whose value is in what it does for a customer on their own premises: a telemetry backend, a trading gateway, a message broker, an industrial supervisor. The release ships as BEAM bytecode, which decompiles well, and a check that returns a boolean is still one conditional branch, and patching one of those is a beginner exercise.
So the strong pattern is the one to reach for: the data the program needs only exists when the dongle is present.
# Weak: one patched branch.
unless LicDongle.genuine?(d), do: System.halt(1)
# Strong: the parameters only exist with the dongle present.
{:ok, parameters} =
LicDongle.with_session(d, fn ->
d |> LicDongle.app_decrypt!(sealed_blob_shipped_with_your_program) |> decode_parameters()
end)Code language: Elixir (elixir)
Every call returns {:ok, value} or {:error, %KeyNub.LicDongle.Error{}} with the status (:no_device, :not_genuine, :auth_required, …), the operation and the library’s detail; the ! variants raise instead, and genuine?/1 fails closed. with_dongle and with_session release the dongle and the session on every exit path. The package calls the SDK’s flat companion API, the one designed for foreign function interfaces: integer handles and buffers, no hand-written structure layouts.
Shipping the Native Library with an Elixir Application
The keynub_licdongle Hex package has a NIF of two hundred lines that is compiled when the package is (elixir_make: a C compiler on Linux and macOS, Visual C++ with nmake on Windows) and that loads the SDK’s flat library at run time. A mix release carries the compiled NIF in the application’s priv/ folder; the flat library itself is deployed beside the release or named with set_library_path/1 or KEYNUB_LICDONGLE_FLAT_LIBRARY.
Every dongle call runs on a dirty I/O scheduler, so a slow USB exchange never blocks the schedulers. The prebuilt libraries for every platform are in the SDK repository’s natives/<platform>/ folder, with a SHA-256 manifest: Windows x64, x86 and ARM64, Linux x86_64 and aarch64, and universal macOS binaries for Intel and Apple silicon. On Linux, install the udev rule from NATIVES.md once, so that ordinary users may open the device.
Questions Elixir Developers Ask
Which Elixir and Erlang Versions Does the Binding Support?
Elixir 1.13 and later on the Erlang/OTP releases that go with them, on Windows, Linux and macOS.
Can an Elixir Release on a Customer’s Server Be Protected with a Dongle?
Yes, when the release runs where the dongle is attached: an on-premises backend, a gateway, an industrial supervisor. The release reads the data it needs through the dongle at start and holds no other copy.
Does a Elixir Application Need Administrator Rights to Talk to the Dongle?
No, and no driver either: the dongle is a USB HID device that the operating systems handle with their built-in class drivers. On Linux, install the shipped udev rule once so that ordinary users may open it; without the rule the SDK reports access denied and names the cause in its error detail.
Does a Elixir License Check Need an Internet Connection?
No. Verification is a local exchange between your program and the dongle over USB: the SDK checks the dongle’s certificate chain to KeyNub’s root and runs a live challenge-response. There is no activation server and no account, so the check works on air-gapped machines.
Who Can Read the License Records on a Dongle?
Anyone holding the dongle: a program opens a session and reads records, and can decrypt data sealed for that dongle. Writing records, erasing them and incrementing counters need your write key. What the dongle guarantees is that none of it is available without the dongle present.
Can a License Written from Elixir Be Read by a Program in Another Language?
Yes. Every binding drives the same core library and the same dongle, and records and sealed data are language-neutral bytes. Your issuing tool can be written in one language and your product in another.
Code
Runnable sample: elixir/verify_and_read.exs. Binding source: bindings/elixir. Both are Apache-2.0, in the public SDK repository; the prebuilt native libraries are in the repository’s natives/ folder, one per platform.
All supported languages · All industries · Buy a KeyNub · Ask us something