Skip to content
Menu
Search
Browse documentation & this page

Developer Guide

Licensing

Cendia needs a license to serve a public host. How keys work, where they go, what is enforced, and why your local machine needs nothing.

Local development needs no license. Clone, run, build a site, publish, break things — none of that asks you for a key. A license matters only once an installation answers on a host that is not local.

A license states its own terms, and the site follows them. It serves until the day the license says it stops, the CMS warns your administrators well before that day, and /cms stays open throughout so a renewed key can always be installed.

That is the whole shape of it. The rest of this page is detail.

What counts as local

Judged by the host name in the request, not by where the connection came from:

  • localhost, 127.0.0.1, ::1
  • any *.localhost name — arena.dev.localhost, partner.dev.localhost, whatever you invent
  • private network addresses: 10.x, 172.16–31.x, 192.168.x, and the IPv6 equivalents

Everything else needs a license, including staging.customer.com and a bare public IP.

The "host name, not connection address" rule is the one worth remembering. Behind a load balancer every request arrives from a private address, so judging by the connection would make every hosted site count as local and the license would mean nothing. www.customer.com is never local, whatever it resolves to.

If your proxy rewrites the Host header rather than forwarding it, turn on forwarded headers — the same setting the Geographic location criterion needs:

{
  "Cendia": {
    "ForwardedHeaders": {
      "Enabled": true,
      "KnownProxies": [ "10.0.0.4" ]
    }
  }
}

The three kinds of key

Trial Developer Production
For evaluating Cendia partners and implementation work a live customer site
Term 10 or 30 days 90, 180 or 365 days the contract's end date, or none (a master license)
At the end date publishing pauses; the site keeps serving the site stops serving an alert; nothing is restricted
Stops serving end date + renewal period on the end date end date + renewal period; a master license never stops
Daily request limit none yes, 50,000 unless the key says otherwise none
Binds localhost no yes no

The renewal period is the time a Trial or Production site keeps serving after its end date. It is 30 days unless the key says otherwise, and it is there so that a renewal which runs late costs nobody their site.

A Developer license is the metered one. Its daily limit counts rendered pages and Delivery API calls together. Working in /cms, previewing, and the presence endpoint do not count. Reaching the limit stops the front end until midnight UTC; the CMS itself keeps working.

A Developer license also applies on localhost, which is where it is used. Once one is installed, its end date and its daily limit hold on your own machine too. Removing the key returns that machine to plain local development, which needs no license at all.

Developer and Production keys name a root domain. It records who the license is for; it is not checked. One installation may answer on any number of domains, and none of them raises an alert.

Installing a key

Two routes, and configuration always wins.

Settings → Configuration → License is the normal one. Paste the key, press Install. It is verified before it is saved, and the card then shows what it says: type, who it is for, when it ends and how long the renewal period is, how many websites it allows, and for a Developer license how many of today's requests are used. Every key ever installed stays in the history below the card — including ones you replaced — so an installation can answer "what were we running in March?" without asking us.

Host configuration is for containers and automated deployments:

{
  "Cendia": {
    "License": {
      "Key": "eyJhbGciOiJFUzI1NiIsImtpZCI6..."
    }
  }
}

Or Cendia__License__Key as an environment variable, which is usually the better home for it in a container. When the host supplies a key, the Settings card goes read-only and says so — an administrator should not be able to half-replace something the next restart will put back.

A license is not a secret. It is signed, so it is tamper-evident on its own, and an administrator needs to be able to read what theirs says. It is stored in the clear in cms_Licenses, and it does not belong in your secret store.

A site on Cendia Hosting installs nothing. It receives its entitlement from the platform, and the License card shows it as hosted.

What is actually enforced

Situation What happens
No license, local host Everything works. This is your machine.
No license, public host Pages do not render (503). /cms and /preview stay reachable so you can install a key.
Valid license Nothing to see.
Production, past its end date An alert for administrators. Publishing and the site are unaffected through the renewal period.
Trial, past its end date An alert, and publishing is paused. The site keeps serving through the renewal period.
Trial or Production, renewal period over The site stops serving (503) until a renewed key is installed.
Developer, past its end date The site stops serving, localhost included, until a new key is installed or this one is removed.
Developer, today's limit reached The site stops serving until midnight UTC, localhost included. The 503 carries Retry-After.
Master license Never expires, never stops, never alerts.
Website cap reached Creating another website is refused. Existing ones are untouched.

"Stops serving" means rendered pages and the Delivery API. /cms, /preview and the presence endpoint always answer, so an administrator is never locked out of the one screen that fixes it.

Days are UTC days on the server. A visitor's or a developer's own time zone takes no part.

How you are warned

Nothing stops without notice. Administrators see a badge in the top bar, amber while a date is approaching and red once one has passed, and the same message on a page of its own when they sign in:

  • A Production license raises the alert 14 days before its end date; a Trial, 3 days before.
  • From 15 days before the site would stop, the alert names the day.
  • A Developer license names its end date from 15 days out, and warns at 80% of today's limit.

These alerts go to administrators only. An author can neither renew a license nor install one, so an author is not shown them.

An installation that has never been licensed renders nothing on a public host from the start. There is no customer site to interrupt, and without that the license would mean nothing.

What Cendia never does

  • It never calls home. No telemetry, no activation, no license server the site depends on. Verification is entirely offline: the public key that checks the signature ships inside the package. We ask your site instead — see below.
  • It never stops a site on terms the license did not state. The end date, the renewal period and any daily limit are in the key and on the License card from the day it is installed.
  • It never locks you out of the CMS. Whatever state the license is in, /cms opens and a key can be installed.
  • It never puts a notice on a page it serves. While the site is serving, nothing in your rendered HTML says anything about licensing. A site that has stopped answers with a plain holding page and a 503, marked noindex.

The presence endpoint

Your installation answers one documented URL:

GET /.well-known/cendia/license
{
  "product": "cendia",
  "status": "valid",
  "type": "production",
  "expires": "2027-03-31",
  "licence": "9f2c41ab77de"
}

status is valid, expired, invalid or unlicensed. A license past its end date reports expired whether or not the site is still inside its renewal period. licence is a truncated hash of the license id — we can match it against our own records; it is of no use to anyone else.

That is the entire response. Not your customer's name, not your domain, not how many websites you run, and not your Cendia version — an endpoint that named the version would be a convenient way for someone to find installations running a release with a known flaw.

This is the trade we made instead of a call-home. Nothing inside your CMS contacts us on a schedule, and nothing you run depends on our servers being available. When we need to know whether a license is still in use, we ask the site, the same way anybody's monitoring would.

It is cached for five minutes and rate-limited. If you would rather not answer at all:

{
  "Cendia": {
    "License": { "EnablePresenceEndpoint": false }
  }
}

The path then stops existing. Our reports say "unreachable" for your site, which is not the same as "not in use" — an installation on a private network is unreachable for the same reason, and that is fine.

How verification works

A key is a signed token — a readable JSON body plus a signature. The package holds public keys only, so Cendia can check a license and has no code that could produce one. Signing happens on our side, against a key that cannot leave its vault.

That means:

  • Editing a key invalidates it. There is nothing in it worth editing anyway — the claims are the ones above.
  • A key signed by anything other than our signing key is refused.
  • A key from a newer Cendia that demands a limit your build cannot enforce is refused rather than run without the limit. The message names the claim and tells you to upgrade.

Troubleshooting

"This site is not licensed" on a host you expected to work. The host name is not local and no valid key is installed. Check Settings → Configuration → License; if the card shows an error rather than claims, the key did not verify.

Everything works locally and fails on staging. Staging is a public host and has no key of its own. Install one there. The key's root domain does not have to match the staging host name.

Publishing is refused but the site is fine. A Trial past its end date and still inside its renewal period. Install a current key before the renewal period runs out.

"This site's license has expired" where the site used to be. A Trial or Production license whose renewal period is over, or a Developer license past its end date. Sign in at /cms and install a renewed key; the site serves again at once.

"Today's request limit has been reached", including on localhost. A Developer license at its daily limit. It clears at midnight UTC. On your own machine you can also remove the key and carry on unlicensed.

A key rejected as "signed with a key this build does not know". Either the key is not ours, or it was signed with a signing key newer than your build. Upgrade Cendia, or ask us for a key issued against the key your version carries.

Docker and CI. Containers usually answer on a container hostname, not localhost. Either map the port and browse via localhost, or supply a key through Cendia__License__Key. Test suites that drive the site through a non-local host name need a key for the same reason.

Getting a key

Trials are self-service once the licensing portal ships; until then, ask us. Developer licenses are issued to partners on request, and production keys are issued against a signed contract for a named root domain.