License the runtime
Every ClikaRT runtime needs a credential your platform issued for the project it ships under, and Modelverse, which runs on the same runtime, needs the same one. Runtime licenses is the concept page: why the credential exists, the two kinds (an online key, an offline bundle), the entitlements it carries, and its lifecycle. This page is the runtime side of that loop: where the runtime looks for the credential, how to put it there from each language and packaging, and what a refused call carries.
Where the runtime reads the credential
The runtime looks in three places, in this order, and uses the first one it finds:
-
The environment variable
CLIKA_RT_LICENSE, holding either the credential text itself or the path of a file that holds it. -
The environment variable
CLIKA_LICENSE, in the same two forms. -
The per-user file
~/.clika/runtime/license(on Windows%USERPROFILE%\.clika\runtime\license), whichclikart-license-init <credential>writes once; the tool also takes the credential from a file with--from-file <path>, and prompts for it on standard input when given neither, which keeps it out of your shell history. It ships in the bundle'sbin/and as a console script of theclika-runtimePython wheel.The tool writes the file readable by its owner alone and says so, along with the credential's kind and the project it was issued for. It refuses to replace a file that is already there, so a second run asks for
--forcerather than overwriting what a machine is running on.
The credential is the CLIKA1-... license key or license bundle your project's Licenses page reveals. A bare clika_rk_... API key is not a runtime credential and is refused everywhere, the license-init tool included.
export CLIKA_RT_LICENSE=/path/to/credential # a file holding the credential
export CLIKA_RT_LICENSE="$(cat /path/to/credential)" # or the credential text itself
"$CLIKART_BUNDLE_DIR"/bin/clikart-license-init <credential> # or the per-user file, once per user
Put it in place before the program starts.
Set it from each language
- C++
- C
- Python
- Kotlin
- Go
- Rust
A C++ program carries no code for the credential. The runtime reads the process environment, so set the variable in the shell, the service unit or the launcher that starts the program, or run clikart-license-init once on the machine and rely on the per-user file.
export CLIKA_RT_LICENSE=/path/to/credential
./my_program
Same as C++. The C surface reaches the same runtime, which reads the process environment (the variable, or the per-user file).
export CLIKA_RT_LICENSE=/path/to/credential
./my_program
The clika-runtime wheel loads the runtime at import, so the variable is set before import clika_runtime: in the shell that starts Python, or in os.environ at the top of the program.
import os
os.environ["CLIKA_RT_LICENSE"] = "/path/to/credential" # before the import: the wheel loads the runtime here
import clika_runtime as crt
x = crt.tensor([1.0, 2.0, 3.0])
The wheel also installs clikart-license-init as a console script. After clikart-license-init <credential> has written the per-user file, the program needs no variable at all.
On Android there is no home directory for a per-user file and no bin/ for the tool, so the credential arrives through the loader itself. ClikaRtAndroid.load takes it as its license argument; an explicit value wins over an ambient variable, and null, the default, leaves the environment alone.
import android.app.Application
import io.clika.runtime.ClikaRtAndroid
class LicensedApp : Application() {
override fun onCreate() {
super.onCreate()
// readCredential() is the app's own: it returns the text the platform
// revealed, from wherever the app keeps its secrets.
ClikaRtAndroid.load(this, license = readCredential())
}
}
On a desktop JVM, ClikaRt.load() needs nothing extra: the runtime reads the process environment, as in the C++ tab.
The Go binding loads the runtime library, which reads the process environment. Set the variable for the process, or run clikart-license-init once on the machine.
CLIKA_RT_LICENSE=/path/to/credential go run .
Same for Rust. Api::load reaches the runtime, and the runtime reads the process environment or the per-user file.
CLIKA_RT_LICENSE=/path/to/credential cargo run
What a refusal looks like
A call the runtime may not serve fails through the three channels every runtime failure carries (Handle errors by code): the coarse status, a message, and the stable code name. The code name is LICENSE_EXPIRED when the credential's lifetime has run out and LICENSE_FAILED for every other refusal. It reads the same in every language, so branch on it, never on the message. A credential that lacks a grant refuses the call that needs it, with the code the entitlements section lists.
The coarse status on a licensing refusal reads Internal, whose usual policy is to log everything and file a report, which is the wrong reaction to an unset variable. Read the code name first; Handle errors by code shows the captured refusal and the branch.
Online and offline
An online key needs a route from the runtime to the platform; an offline bundle is verified locally against Clika's signature and needs none. Which to issue, and how each is revoked, is the concept page's Lifecycle section.
Containers and CI
Pass the credential through the environment of the service, never through the image. A docker run -e, an orchestrator secret exposed as an environment variable, or a CI job's secret variable all reach the runtime as the variable above; a credential written into an image layer travels with every copy of that image. Keep it out of logs the same way: log a refusal by its code name, and never echo the variable's value.
docker run --rm -e CLIKA_RT_LICENSE="$CLIKA_RT_LICENSE" my-image
Issuing, revealing, rotating and revoking a credential is platform work: Runtime licenses is the concept and the licensing commands drive it from the command line. Quick install lists the credential among ClikaRT's prerequisites, and Modelverse's quick install among its own. clika-modelverse runs on this runtime and reads the credential from the same places.