Docs

Licensing

What a license is, the FKL1 file format, offline verification, how to get and renew one, and what a license does not do.

On this page

A Firekeeper license is a small signed text file. Firekeeper checks it offline when it starts. It never phones home to do so.

Price

Licenses are free today. The one plan, community, costs $0 and includes Watch for 365 days.

What a license is

A license belongs to your account on this site and names one estate. An estate is one AWS organization and the EKS clusters in it, watched by one hub. A license carries:

  • the estate label you chose, and optionally the AWS account id of the hub;
  • the plan and the features it grants;
  • when it was issued, when it starts and when it expires;
  • an Ed25519 signature from us over all of the above.

The file is called firekeeper.license. You can open it in any text editor. It is one line.

The file format (FKL1)

FKL1.<payload>.<signature>
  • <payload> is the base64url (no padding) encoding of a UTF-8 JSON object.
  • <signature> is the base64url (no padding) Ed25519 signature over the ASCII bytes of FKL1.<payload>, exactly as written in the file.

Payload fields

FieldTypeMeaning
vnumberFormat version. Always 1.
kidstringId of the key that signed the license.
license_idstringUUID of this license.
account_idstringOpaque id of the account that owns the license.
licenseestringName of the license holder.
estatestringThe estate label, 1 to 64 characters.
hub_account_idstring or nullThe hub’s AWS account id, exactly 12 digits, or null.
planstringThe plan. Today always "community".
featuresarray of stringsWhat the license grants. Today ["watch"].
issued_atstringWhen the license was issued. RFC 3339, UTC.
not_beforestringThe license is not valid before this time. RFC 3339, UTC.
expires_atstringThe license is not valid at or after this time. RFC 3339, UTC.

An example payload, before encoding:

{
  "v": 1,
  "kid": "fk1-5c0f2a9e7d41b386",
  "license_id": "0f6b8a52-3c1d-4e7a-9b2f-6d4c8e1a7b30",
  "account_id": "a3e9c2d4-7b16-4f08-8c5a-2e9d1b6f4a73",
  "licensee": "Example Ltd",
  "estate": "production",
  "hub_account_id": "123456789012",
  "plan": "community",
  "features": ["watch"],
  "issued_at": "2026-10-02T12:00:00Z",
  "not_before": "2026-10-02T11:55:00Z",
  "expires_at": "2027-10-02T12:00:00Z"
}

The values above are illustrative. They do not belong to a real license.

The dashboard writes not_before five minutes before issued_at, so a new license is not rejected by a clock that runs a little slow. expires_at is issued_at plus the plan’s term. licensee is the name on your account when the license was issued.

Verification

A verifier does these steps in order and stops at the first failure:

  1. Reject input larger than 16 KiB (16,384 bytes of UTF-8). Remove spaces, tabs, carriage returns and line feeds at either end, and nothing else: a byte order mark or a no-break space makes the file invalid. Split the text on . into exactly three parts.
  2. Check that the first part is FKL1.
  3. Decode the payload. Reject it if it is not a JSON object, or if v is not 1. Unknown versions are rejected. The signature must decode to exactly 64 bytes.
  4. Look up kid in the trusted key list. Reject unknown keys.
  5. Verify the Ed25519 signature over the bytes of FKL1.<payload> as written.
  6. Check that every field above is present and well formed. Unknown fields are ignored. The term, expires_at minus issued_at, must be at most 400 days.
  7. If the key has a not_after time, check that issued_at is not later than it.
  8. Check the time: not_before <= now < expires_at. A clock that gives no valid time fails the check.

Nothing in the payload is trusted until step 5 has passed.

You can run these steps yourself, in your browser, on the verify page. Nothing you paste there is uploaded.

Public keys

We publish the keys we sign with at /.well-known/firekeeper/license-keys.json:

{
  "keys": [
    {
      "kid": "<key id>",
      "alg": "Ed25519",
      "public_key": "<base64url of the raw 32-byte public key>",
      "not_after": null
    }
  ]
}

not_after is null for a key in use. When a key is retired it is set to an RFC 3339 UTC time, and licenses issued after that time are not trusted under that key. Licenses issued before it keep working until they expire. Because no license may run longer than 400 days, nothing signed with a retired key is valid more than 400 days after its not_after.

Firekeeper will carry the same list built in. It will never fetch it. The published copy exists so that you can check a license without trusting the product. A new signing key is added to the product in a release before we sign with it, so a license we issue is never signed with a key your install does not know.

Offline means offline

Because a license is checked offline, nothing can switch it off remotely. A retired license file keeps working until it expires. Retiring a license in the dashboard only marks it as retired there.

Getting a license

  1. Create an account on this site with a passkey. There are no passwords.
  2. Create a license. Give it an estate label and, if you like, the 12-digit AWS account id of the hub.
  3. Download firekeeper.license, or copy its contents.

Each account can hold up to 10 active licenses. Expired, renewed and retired licenses do not count. An account can create or renew up to 10 licenses a day.

Renewing

A license lasts 365 days. To renew, open the license in the dashboard and choose Renew. You get a new file with a new license id, for the same estate and hub account, valid for another 365 days. Replace the old file with the new one. The old license is marked as renewed; its file keeps working until it expires.

Retiring

Choose Retire on a license you no longer use. It is marked as retired in the dashboard and stops counting toward the limit. The file itself keeps working until it expires, because nothing checks it over the network.

What a license does not do

  • It does not phone home, and nothing checks it over the network.
  • It does not report usage, and it does not count accounts or clusters.
  • It cannot be revoked remotely. It is valid until it expires.
  • It does not contain any secret. It is safe to keep with your configuration.