Install

Verify your install

Four checks that tell you the release came up licensed and serving.

Verify your install

A successful helm install only means the objects were accepted. What you want to know is whether the license agent enrolled, whether the API came out of its gate, and whether the lease it is serving on is a live one. Four checks, in order.

The names below assume a release called my-mvno in a namespace called my-mvno. The chart names its objects <release>-platform-<component>, so substitute your own release name throughout.

1. Watch it converge

kubectl -n my-mvno get pods -w

The license agent and the API start at the same time. The API sits in Init:0/2 for a while, and that is expected: an initContainer called wait-for-lease blocks the API container from starting until the agent has written a license into the platform Secret. An unlicensed platform never serves, so the gate is the whole design rather than a startup race.

2. The agent says it licensed the deployment

kubectl -n my-mvno logs deploy/my-mvno-platform-license-agent

The line to look for is this one:

level=INFO msg="activate: deployment licensed" kind=mvno jti=<lease-id>

jti is the id of the lease the Hub just minted for you. Once you have that line, activation is done: the code was redeemed, the license came back bound to the key the agent generated in your cluster, and it has been written into your Secret. The agent then settles into its renew loop and logs its state as it goes (agent: state state=licensed).

You can confirm the license really landed in the Secret:

kubectl -n my-mvno get secret my-mvno-platform-env \
  -o jsonpath='{.data.PARENT_LEASE_TOKEN}' | base64 -d | head -c 20; echo

Any non-empty output is the head of a signed JWT. That is the value wait-for-lease is waiting for.

3. The API goes ready

kubectl -n my-mvno rollout status deploy/my-mvno-platform-api --timeout=180s
curl -sf https://esim.acme.com/health

rollout status returning cleanly means the gate opened and the API's own readiness probe passed. If it hangs instead, check the initContainer's log to see which gate it is stuck behind:

kubectl -n my-mvno logs deploy/my-mvno-platform-api -c wait-for-lease

waiting for PARENT_LEASE_TOKEN in the platform Secret still printing means the agent has not enrolled yet, so go back to check 2 and read its logs.

4. The lease has time left on it

Checks 1 to 3 tell you the platform booted. They do not tell you it is still licensed, because the API boots off whatever lease was in the Secret and only the agent knows whether that lease is current. Ask the agent. It publishes the remaining life of the lease it holds on its metrics port:

kubectl -n my-mvno port-forward deploy/my-mvno-platform-license-agent 9090:9090 &
curl -s localhost:9090/metrics | grep '^license_'

A healthy platform looks like this:

license_expiry_seconds 1.2089e+06
license_renew_failures_total 0
license_rotations_total 0
license_renew_last_success_timestamp_seconds 0
license_revoked 0

license_expiry_seconds is the check. Any positive number is the seconds left on the lease the platform is serving on, and the agent only ever puts a number there after it has read a lease out of the Secret and found a future expiry in it. A platform that never enrolled reports 0. So does one whose license the Hub revoked, and license_revoked 1 is what tells those two apart. The counters sit at zero on a fresh install and start moving at the first renewal.

/health cannot answer this question for you. It is deliberately ungated and returns 200 whether or not this platform holds a license.

Confirming it from the API's side

If you want the same answer from the API rather than the agent, send an authenticated request to a gated route:

curl -s -o /dev/null -w '%{http_code}\n' \
  -H "Authorization: Bearer $TOKEN" \
  https://esim.acme.com/v1/accounts

A licensed platform answers whatever that route normally answers for that token: 200, or 403 if the token does not carry the permission. An unlicensed one answers 424 Failed Dependency, and the body names the reason: parent lease not loaded, parent lease expired, or parent lease revoked. On an MVNE, use https://<platform.host>/v1/support/tickets for the same check.

Do not run this one without a token. Authentication runs first and the license gate sits behind it, so an anonymous request gets 401 on a licensed platform and 401 on an unlicensed one. The status code carries no licensing signal at all until you have authenticated. That is the same ordering described in How licensing works.

If the lease turns out to be missing or expired, Licensing failures covers what to do about it.

After that

The agent keeps renewing and rotating the license for as long as the release runs, without a restart and without you doing anything. How licensing works explains what it sends and when. If any of the four checks above went sideways, Install failures is the place to start.

Copyright © 2026