Skip to content

Software License Dongle for Go (Golang)

Go binds over cgo to the same core library. If shipping a single self-contained binary is the reason you chose Go, link the static library and you still ship one file — the dongle support goes inside it.

Go module version badge

go get github.com/AB-KeyNub/KeyNub-SDK/bindings/goCode language: Bash (bash)
ctx, err := keynub.NewContext()
if err != nil { return err }
defer ctx.Close()

dongle, err := ctx.Open("")          // first dongle found
if err != nil { return err }
defer dongle.Close()

if _, err := dongle.VerifyGenuine(); err != nil { return err }

session, err := dongle.OpenSession()
if err != nil { return err }
defer session.Close()

license, err := session.ReadRecord("license")Code language: Go (go)

A Note on cgo

cgo is the trade-off here: it means a C toolchain on your build machines and it rules out CGO_ENABLED=0 builds. There is no way around that for a library that talks to USB hardware through the operating system’s HID stack, and it is the same trade-off any hardware-backed licensing makes in Go.

And the rule that matters in every language: do not branch on a boolean. Encrypt data your program needs with appEncrypt at build time and decrypt it through the dongle at run time, so removing the check leaves the program with nothing to compute rather than a working unlicensed copy.

Building and Linking

cgo finds the headers by itself, but the directory holding the built native library is not knowable at compile time, so you pass it in through CGO_LDFLAGS. At run time the shared library has to be findable the usual way: PATH on Windows, the loader search path on Linux and macOS. Link the static library instead and the dongle support goes inside your binary, which is usually the point of having chosen Go.

Go 1.17 or later is required, because handing a Go progress callback down to C uses runtime/cgo.Handle rather than passing a Go pointer into C and hoping the garbage collector agrees.

Shipping the Native Library with a Go Application

The Go binding uses cgo and links the core library: point the linker at the platform folder with CGO_LDFLAGS="-L<path to natives/<platform>>" and build as usual. At run time the shared library must be findable as any other: on PATH on Windows, through an rpath or LD_LIBRARY_PATH on Linux, next to the binary or in a framework path on macOS.

Because cgo is involved, a build for another platform needs a C toolchain for that target rather than a plain GOOS/GOARCH switch; building on each platform, or in its container, is the simple route. One cgo limitation: a checkout path containing # breaks the #cgo directives. On Linux, install the udev rule from NATIVES.md once, so that ordinary users may open the device.

Questions Go Developers Ask

Which Go Versions Does the Binding Support?

Go 1.17 and later, with cgo enabled, on Windows, Linux and macOS. Errors are sentinel values that work with errors.Is.

Can I Use the Dongle with CGO_ENABLED=0?

No. The binding calls the native library through cgo, so cgo must be enabled and a C compiler present at build time. The resulting binary needs only the shared library beside it.

Does a Go 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 Go 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.

Does It Run on ARM: Windows on ARM, Apple Silicon, aarch64 Linux?

Yes. The SDK ships native libraries for Windows x64, x86 and ARM64, Linux x86_64 and aarch64, and universal macOS binaries for Intel and Apple silicon.

Can a License Written from Go 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: go/verify_and_read. Binding source: bindings/go. 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