Skip to content

Build-time key check

The failure this prevents is described in Signing keys and rotation: a product built with the wrong or stale public key activates on the server but rejects its own signed token. The guard turns that into a build failure.

1. An authoritative endpoint. GET /v1/products/{productId}/pubkey returns the keys the service signs with for that product. It is public, read-only, and carries no secrets (the public key ships in every product anyway).

2. The verify-baked-key CLI. It fetches the endpoint and compares. It ships with the TypeScript SDK as a bin, and as a zero-dependency verify-baked-key.mjs inside the JUCE kit’s CMake package.

Terminal window
node verify-baked-key.mjs --product <productId> --pubkey <base64url> --api <baseUrl>
# or, with the SDK installed:
npx --package=@waveform/licensing verify-baked-key --product … --pubkey … --api …

A match against any currently served key passes, not just the active one, so builds inside a rotation window do not fail their drift check.

Exit code Meaning
0 The baked key matches a served key.
1 Fail the build. A definitive mismatch, or missing or malformed arguments (a mistyped flag must not silently skip the check).
2 Could not verify: network error, endpoint unreachable, or product not found. Warn, do not block.

3. A CMake helper for JUCE. waveform_verify_license_key() is included in the kit’s CMake package. It can read apiBaseUrl, productId, and publicKeyB64 straight from your plugin’s config source, or take them as arguments, and runs the verifier at configure time:

include("${WaveformLicensing_DIR}/WaveformLicenseVerifier.cmake")
waveform_verify_license_key(
PRODUCT_ID "<productId>"
PUBLIC_KEY_B64 "<the base64url key you baked in>"
API_BASE_URL "https://api.waveformanager.com"
# or CONFIG_SOURCE <path/to/PluginProcessor.cpp> to parse the cfg.* values from your source
# REQUIRED # make "could not verify" fatal in every build type
)

It needs Node.js 18 or later on PATH at configure time. A definite mismatch always fails. A check that could not run (no Node, no network, product not found) is fatal in single-config Release and RelWithDebInfo builds and a warning otherwise, unless you pass REQUIRED.

Call the CLI, or the endpoint directly, from any build step or CI job. It is one HTTP GET and a string comparison. Wire it wherever the baked key is defined so a drifted key fails the build instead of shipping.