Your Polaris license
A Polaris deployment outside the cloud marketplaces runs on a license file that Fr0ntierX issues for your contract. This page covers what the file is, where it goes, how to renew it, and what the Policy Manager does as the end date approaches.
If you deployed from our GCP or AWS marketplace listing, you can skip this page. The marketplace bills you, and the image you launched already carries its license.
What the license is
The license is one file, a signed token with a .jws extension. It names your organization, a license id, a start date, an end date and a grace period. That is all it controls. It does not count machines, limit usage or switch features on and off, so you can use the same file on every deployment you run under that contract.
The Policy Manager checks the signature against keys built into it, so an edited file is refused. Nothing phones home. The check runs entirely inside your deployment, which is what makes it work on air-gapped sites.
Installing it
Pass the file when you deploy:
./scripts/deploy.sh deploy --license-file ./acme-corp.jws
or set it in your deployment config:
license:
file: ./acme-corp.jws
deploy.sh checks that the file is a Polaris license before it starts, and installs it on the Policy Manager at /etc/polaris/license/license.jws. On GCP, AWS, Azure and Oracle a later deploy that names no license keeps the one already installed, so you only pass it again when you renew.
With the Helm chart, put the file in a Secret under the key license.jws and name the Secret in policyManager.license.existingSecret:
kubectl create secret generic polaris-license --from-file=license.jws=./acme-corp.jws
A Policy Manager that enforces licensing will not start without a valid license file. Fr0ntierX issues yours before you move to a release that needs it.
Renewing
Put the new file in place of the old one. There is no restart. The Policy Manager re-reads the file every minute and switches to the new license as soon as it verifies.
On a cloud VM, copy the file over /etc/polaris/license/license.jws on the Policy Manager VM. Running deploy.sh deploy --license-file with the new file works too, but the license is part of the Policy Manager VM's boot configuration, so that replaces the VM. Copying the file in place is the gentler route. On Kubernetes, update the Secret. The pod sees the change without being restarted.
On your own hardware nobody logs in to the guests, so the license goes in with the Policy Manager guest's launch configuration. Pass the new file to deploy.sh and we walk through relaunching the Policy Manager guest with you. Nothing in this needs a network connection, so it works the same on an air-gapped site, with the new file carried in.
If the file on disk is missing, truncated or does not verify, the Policy Manager keeps using the license it already has and reports the problem, so a renewal that goes wrong partway through does not stop anything.
As the end date approaches
| State | When | What happens |
|---|---|---|
valid | More than 30 days before the end date | Nothing. |
expiring | The last 30 days | Every appraisal carries an alert saying when the license ends, and the Policy Manager logs a warning once a day. Keys keep flowing. |
grace | After the end date, for the grace period your license names | The alert names the date grants stop, and the warning is logged every minute. Keys keep flowing. |
expired | After the grace period | The Policy Manager stops renewing key grants and issuing node certificates. |
The alerts reach you wherever Policy Manager alerts already go: the status API, its event stream, webhooks and your logs. The Policy Manager also exports polaris.pm.license.days_remaining as a metric, which is the easiest thing to alert on from your monitoring.
What expiry does, and does not do
An expired license does not fail attestation and does not revoke anything. The appraisal still reports what it found, and your status page still shows whether each machine is healthy. The Policy Manager simply stops renewing key grants. Keys end when the grants already issued run out, which is the grant lifetime your deployment is configured with, and from then on the workload cannot get its keys until a renewed license is in place. Once it is, the next appraisal renews the grants as normal.
So an expired license never looks like an attack, and it never shows up as a failed attestation you would have to debug.
Checking the license
deploy.sh status shows the license on GCP deployments:
License: expiring, lic-2026-0042 for acme-corp, expires 2027-01-31 (21 days)
On any deployment, GET /api/v1/license on the Policy Manager returns the same information as JSON, with the read-only token:
curl -s -H "Authorization: Bearer $PM_READONLY_TOKEN" https://<pm>/api/v1/license
The fields to look at are state, expires_at, enforced_from (when grants stop renewing), days_remaining, and file_error, which is set when the file on disk could not be loaded and says why.
A state of not_enforced means the Policy Manager build you run does not check licenses yet. Nothing on this page applies to it.
The clock
The license is judged by the date, so the Policy Manager guards against its clock being moved. It keeps a mark of the latest time it has seen, in its state directory, and moves it forward only by the time it has actually been running. Setting the system clock back gains nothing while the Policy Manager runs.
A clock that moves backwards never stops the Policy Manager from starting. If your clock is corrected backwards by NTP, for example after a first boot with the wrong time, the Policy Manager judges the license by its mark until the system clock catches up, and /api/v1/license reports clock_behind meanwhile. If you see clock_behind and did not expect it, check your NTP source.
Marketplace deployments
A marketplace image carries a license tied to its listing. It is honoured only on a machine whose cloud-signed identity shows it was launched from that listing, which the Policy Manager checks on GCP and AWS. A copy taken out of the image and run anywhere else gets no key grants.
If you are moving from a marketplace deployment to a direct contract, Fr0ntierX issues you a direct license. Install it with --license-file and it replaces the one the image carries.