Syed Hasibur Rahman21 min read
Licenses That Can't Kill: Designing Commercial Licensing Without a Kill Switch
Every runtime license check on a serving path is a kill switch someone else's outage, bankruptcy, or sanctions-compliance lawyer can pull. The documented record — Logisticon disabling Revlon's distribution system in 1990, Amazon deleting Orwell from Kindles, Nest bricking Revolv hubs, Adobe cutting off Venezuela, Insteon going dark overnight — shows the blast radius always lands on end-users who were never party to the dispute. This post lays out the alternative as concrete engineering: JWT-shaped license tokens verified offline against embedded public keys, a state ladder that degrades but never dies, refresh-denial as the sole enforcement lever, and perpetual licenses whose irrevocability is a property of the verifier, not a promise in a PDF.
The page comes in at 2:47 AM: the authentication service at a customer site is refusing every login. Not crashing — refusing, cleanly, with an error code nobody on the on-call rotation has ever seen. Forty minutes of log-spelunking later the root cause surfaces, and it is not a bug. It is a feature, working exactly as some vendor’s product manager specified: the license-validation call that the service makes on every startup — and, it turns out, re-makes every twenty-four hours on the serving path — could not reach the vendor’s license server, because the vendor was having its own bad night. The customer’s contract was paid up. The software was healthy. Every user it turned away was turned away on purpose, by code written to protect a business relationship neither the users nor the on-call engineer were party to.
Every engineer who has operated commercial software long enough has a version of this story. It is worth saying plainly what the story is about: a kill switch. Any mechanism by which software in production can be remotely or automatically rendered non-functional over a licensing condition is a kill switch, whether the vendor calls it license enforcement, entitlement validation, or dynamic security. This post is an argument — and, more usefully, a concrete design — for commercial licensing without one. The claim is not that vendors should stop charging for software. It is that non-payment enforcement must never travel through the serving path of a running system, because the record of what happens when it does is thirty-five years long and unambiguous.
Let us start with the record.
The founding incident: Revlon v. Logisticon, 1990
At 2:30 in the morning on October 16, 1990, engineers at a software vendor called Logisticon dialed into the systems of their customer — the cosmetics giant Revlon — and remotely disabled the inventory-management software they had built, over a payment dispute. Revlon had paid $420,000 of a $600,000 contract and was withholding the final $180,000 over unresolved defects. Logisticon’s answer was electronic “repossession.” Revlon’s product-distribution operation went down for three days; the company claimed roughly $20 million in losses and sued for, among other things, trespass, conversion, and intentional interference with contractual relations. The parties settled12.
The incident became the canonical case study in what legal scholarship politely calls electronic self-help — the vendor’s unilateral, extrajudicial enforcement of a contract dispute by disabling software2. Two things make it worth re-reading today. First, the dispute itself was ordinary — a defect-and-payment standoff of the kind that happens on every large software contract, the kind courts and arbitrators exist to resolve. What was extraordinary was that one side had pre-installed the technical capability to impose its preferred outcome at 2:30 AM. Second, the damage did not land on Revlon’s legal department. It landed on warehouse workers who could not ship product, on truck drivers with nothing to load, on retail customers with empty shelves — hundreds of people downstream of a contract they had never seen.
That asymmetry — the switch is pulled in a dispute between two companies, but the outage lands on bystanders — is the moral signature of every kill-switch incident since. The technology changed; the signature never did.
Three decades of the same incident
Consider the documented lineage, each case verifiable and each one the same story wearing different hardware.
2009 — Amazon and Orwell. Amazon discovered that third-party copies of 1984 and Animal Farm on the Kindle store had a rights problem, and resolved it by remotely deleting purchased books from customers’ devices. The customers had done nothing wrong; the dispute was between Amazon and an uploader. Jeff Bezos later called the remedy “stupid, thoughtless and painfully out of line with our principles”34 — an apology notable mostly for confirming that the delete capability existed all along, waiting for a sufficiently bad decision.
2014 — starter interrupters. The New York Times documented lenders remotely disabling the ignitions of subprime borrowers’ cars via factory-installed “starter interrupt” devices — in one reported case while a mother was trying to take a feverish child to an emergency room, three days past a payment due date5. The lender-borrower dispute, enforced through the vehicle, landed on a sick kid.
2016 — Revolv. Google’s Nest division, having acquired the Revolv smart-home hub, shut down its backing service and deliberately turned every $299 hub — sold with a “lifetime subscription” — into scrap on May 15, 20166. Nothing was wrong with the hardware in anyone’s living room; the kill decision was a portfolio cleanup in Mountain View.
2019 — Adobe and Venezuela. Complying with U.S. Executive Order 13884, Adobe announced it would deactivate every Creative Cloud account in Venezuela — initially stating it could not even issue refunds, since refunds too were “activity” with sanctioned parties78. Photographers and designers in Caracas lost access to their tools and, for those on cloud storage, their work product, over a geopolitical dispute between governments. (Adobe later obtained a license to continue service — after the panic, not before it.) This is the case that should haunt architects most, because no one in the causal chain was even acting in bad faith: the vendor was obeying its regulator. The kill switch simply existed, so it got pulled.
2019–2020 — Sonos Recycle Mode. Sonos offered a 30% trade-up discount conditioned on putting your old speaker into “Recycle Mode” — a countdown that irreversibly bricked a working device after 21 days, by design, so it could not be resold or given away. Public outcry killed the program in March 20209.
2022 — Insteon. The smart-home company Insteon shut down its cloud servers essentially overnight, without warning, notice, or a sunset plan — and because hubs needed the server even for initial configuration, users who factory-reset their devices during normal troubleshooting bricked them permanently10. Here the kill switch was not even malice or policy. It was architecture: the dependency itself was the switch, and bankruptcy pulled it.
2023 — VanMoof. When the e-bike maker VanMoof entered bankruptcy in July 2023, owners of its app-unlocked bikes faced the real possibility that their €2,000+ bicycles would become unrideable when the key-serving backend went dark; a competitor, Cowboy, rushed out a “Bikey” app so owners could extract their bikes’ digital keys while the servers still answered11. A bicycle — a machine humanity has known how to unlock with a physical key for 150 years — had been architected such that a Dutch insolvency proceeding could immobilize it.
2022, the other direction — John Deere in Melitopol. When Russian troops looted $5 million of John Deere equipment from a dealership in occupied Melitopol and hauled it to Chechnya, Deere remotely locked the machines, rendering them useless to the thieves12. The episode was widely cheered, and honestly: it is the strongest case for remote-disable capability that reality has yet supplied. Note, though, what it proves — the capability’s existence, its global reach, and its efficacy against whoever the vendor decides is a thief. The same lock that defeats an occupying army sits in every legitimately purchased machine, and farmers’ advocates had spent the prior decade objecting to exactly that latent power. A kill switch does not know it is being used justly.
By November 2024 the pattern was common enough that the U.S. Federal Trade Commission published a staff study of 184 connected products, finding that roughly 89% of manufacturers failed to disclose how long the software their products depend on would remain supported — and noting that products that die when support ends may implicate warranty law13. The regulatory system, in its slow way, had begun to notice what the incident record shows: remote disablement is not an edge case. It is a standing capability that ships in the product, and every standing capability eventually finds its trigger — a payment dispute, an acquisition, a sanctions order, a bankruptcy, a discount program.
The structural error: enforcement through the wrong party
Abstract the incidents and you get a three-party graph. There is a vendor, a licensee (the customer who signed the contract), and — this is the party licensing discourse habitually forgets — end-users: the warehouse crew, the support agents, the patients, the commuter whose bike is a brick. The license relationship is an edge between vendor and licensee. Every kill switch is an enforcement mechanism that, instead of acting on that edge, acts on the edge between the licensee and its end-users — the one edge where neither node consented to the license terms or can cure the breach.
Stated as a design principle: enforcement against the licensee must never travel through end-users. A user locked out of a hospital’s login screen cannot pay the vendor’s invoice. A rider stranded by a bankrupt bike company cannot un-bankrupt it. Punishing the powerless to pressure the powerful is coercion-by-hostage, and the fact that it is implemented in a checkLicense() function rather than stated in those words does not change its structure.
There is a second, purely operational indictment, independent of the ethics. A runtime license check on a serving path is:
- A new single point of failure you have grafted onto every customer’s availability math. The vendor’s license server is now silently part of the customer’s SLA, unnegotiated, unmonitored by them, and typically run with far less rigor than the product it can veto.
- A new attack surface. A remote-disable channel is, by definition, remote code-effect on production. Whoever compromises the vendor’s signing keys or license API inherits a fleet-wide off switch. Security engineering spends enormous effort removing exactly this class of capability; licensing code smuggles it back in.
- A compliance transitive dependency. As Adobe/Venezuela demonstrated, your customers inherit not just your uptime but your regulator. Online-checked licensing means a sanctions ruling, a court injunction, or an acquirer’s policy change anywhere in the vendor’s jurisdiction propagates to every deployment within one token-refresh interval.
- Failure-mode-inverted. Distributed-systems doctrine says: fail open on auxiliary concerns, fail closed on security ones. A license check is auxiliary — it protects revenue, not users — yet naive implementations fail closed, converting every transient network partition, expired TLS certificate, or NTP drift into a customer outage. The dirty secret of the genre is that most “license server down” incidents involve customers whose payments were perfectly current.
The conclusion is not “don’t enforce licenses.” It is that the serving path is the wrong place, and the wrong time, to enforce them. So where is the right place?
The alternative: licenses as offline-verifiable signed documents
The sound architecture treats a license not as a live permission from a server but as a document: a signed, self-contained token the vendor issues and the software verifies locally, against public keys embedded in the binary at build time, with no network dependency whatsoever on the verification path.
The JWT family (RFC 751914) is a sensible wire shape for this — not because licensing needs the OAuth ecosystem, but because base64url-encoded, dot-separated, signed JSON segments are well-understood, trivially debuggable, and have mature parsing code in every language. A license token, structurally, is a JWT with licensing claims:
<header>.<payload>.<signature(s)>
with a payload along these lines:
{
"iss": "license.vendor.example",
"sub": "9f1c7d2e-…-project-uuid",
"iat": 1767225600,
"exp": 1775001600,
"tier": "commercial",
"features": ["auth.passwords", "auth.passkeys", "sso.saml"],
"perpetual": false
}
The verifier embedded in the product does exactly this, offline, at startup:
- Parse the token from an environment variable or file.
- Verify the signature(s) against public keys compiled into the binary — a
kid → public keymap, unknownkids rejected. - Validate structural invariants (more on one crucial invariant below).
- Compute a state — not a boolean — from
expand the local clock.
Two notes on the cryptography, briefly, because they matter for a document that must stay verifiable for decades. Ed25519 (RFC 803215) is the right default signature scheme: small keys, small signatures, no parameter footguns. And because perpetual licenses are promises with multi-decade horizons, there is a genuine argument for hybrid signing — an Ed25519 signature and an ML-DSA signature (FIPS 204, the NIST-standardized lattice scheme16) over the same bytes, both required to validate. A license that must remain unforgeable in 2045 should not bet the farm on the discrete-log assumption alone. AiCE-Lab’s published license specification — the working example this doctrine is distilled from, and worth reading as a complete public artifact — uses exactly this dual-signature format, with conformance vectors so third-party verifiers can prove they match the reference behavior17.
The key property to hold onto: verification requires no server. The vendor’s entire infrastructure can burn down — or be acquired, sanctioned, or bankrupted — and every issued token continues to verify, everywhere, forever. The failure modes that killed Insteon and nearly killed VanMoof’s fleet are not mitigated; they are absent from the design space.
The state ladder: warn → grace → degraded, never dead
A boolean license check — valid or dead — is where kill switches come from, because “dead” has to mean something, and what it ends up meaning is your users locked out. The alternative is a monotone ladder of states, computed locally from the token’s exp:
func computeState(exp *time.Time, now time.Time) State {
switch {
case exp == nil: // perpetual
return StateValid
case now.Before(*exp):
return StateValid // (warn in logs as exp approaches)
case now.Sub(*exp) < 30*24*time.Hour:
return StateInGracePeriod
default:
return StateDegraded
}
}
Three states, and the ladder has no bottom rung labeled “dead.”
Valid is business as usual, with the verifier logging escalating renewal warnings as expiry approaches — the warn phase costs the vendor nothing and resolves the large majority of lapses, which are administrative (a CI pipeline that didn’t redeploy the renewed token, a distracted finance department), not adversarial.
Grace — expired less than, say, thirty days — is full functionality plus loud noise: startup banners, health-endpoint annotations, a metric operators can alarm on. The window exists for a precise operational reason: so that the licensing system’s own failures — vendor outage on renewal day, network partition, misconfigured secret rotation — never become the customer’s production incident. It is worth being honest, as a spec should be, that grace is not a security control; a determined bad actor was never going to be stopped by an expiry date they control the clock for. Grace exists to make the honest-customer failure mode operationally pleasant.
Degraded is where the design earns its title. Past grace, the software may curtail — but what it curtails is bound by a normative floor:
A degraded license MUST NOT be used to refuse service to end-users who already exist in the deployment. End-users are not a party to the license relationship; enforcement against the licensee never travels through them.
Concretely, in an authentication product: degraded mode may refuse to boot a new process configured with commercial features, may block new tenant or deployment creation, may suspend administrative conveniences and vendor support entitlements. It may never refuse a login, a session refresh, or an OTP for the humans already relying on the system. The pressure lands where it belongs — on the licensee’s operators and roadmap (“we can’t stand up the new region until this is renewed”) — while the receptionists, patients, and customers downstream never learn the dispute exists. Degraded is uncomfortable, visible, and completely survivable. And critically, it is the terminal state: there is nothing below it. The ladder converges to “annoying,” not “dead.”
Refresh denial: the only non-payment lever
If the software never phones home and never dies, what does the vendor actually do about non-payment? The answer is almost anticlimactic: stop issuing new tokens.
Make tokens short-lived — ninety days is a reasonable cadence — and renewal an explicit, out-of-band act: an API the customer’s automation calls, a portal button, an emailed artifact. While the commercial relationship is healthy, renewal is boring plumbing. When it sours, the vendor’s entire enforcement arsenal is declining to sign the next token. The deployed system then walks the ladder on its own local clock: weeks of warnings, thirty days of grace, then degraded — every step predictable from the day the last token was issued, with no vendor action, no remote command, no server dependency. The vendor retains real commercial teeth (no renewals, no upgrades, no support, and eventually a visibly degraded system pressuring the licensee’s own operations) while holding zero technical capability to create a sudden outage. Not “promises not to” — cannot. The distinction is the whole design.
Refresh-time is also where verification conditions belong, because refresh is a vendor-side act where the vendor can consult anything it likes without touching production. A free-for-open-source tier, for instance, can re-check at every renewal that the licensed project is still publicly hosted under an OSI license, and simply decline to renew if it went closed — whereupon the project drifts down the ladder like any lapsed commercial customer17. All the policy richness of online licensing, none of the serving-path coupling.
Perpetual means the verifier can’t take it back
“Perpetual license” is traditionally a contractual term — a promise in a PDF, enforceable by lawsuit, revocable in practice by any vendor willing to eat the litigation risk (or, as with Revolv’s “lifetime,” by quietly redefining lifetime as “the product’s lifetime, which we just ended”). An engineering doctrine can do better: make irrevocability a property of the verifier.
A perpetual token carries "perpetual": true and either no expiry or an expiry that functions purely as a renewal horizon — refreshes may extend entitlements but the computed state of a perpetual token can never fall below the floor the customer bought. The verifier enforces the geometry with structural invariants; the reference behavior rejects, for example, any token claiming to be non-perpetual while lacking an expiry, so that no issuance bug can accidentally mint an un-expiring token that wasn’t a deliberate perpetual grant17. And the pointed omission: there is no revocation list on the verification path. No CRL fetch, no OCSP-style status check, no remote “actually, disregard that token.” Adding one would reintroduce the kill switch through the back door — a revocation check is just a phone-home with better branding. If a perpetual token is issued in error, that is the vendor’s loss to absorb, exactly as a bank absorbs a mistaken wire transfer. The asymmetry is deliberate. It is what “perpetual” means when code, rather than a courtroom, is the enforcement venue.
The customer-side consequence is profound: a perpetual licensee can verify — by reading the verifier’s open specification, or the vendored verification code in their own deployment — that no future change of vendor ownership, policy, or solvency can reach back into their production system. The promise is not trusted; it is checked.
The continuity argument: healthcare and other systems that must not stop
Everything above hardens into obligation the moment the software sits under something safety-critical. An authentication layer in front of a hospital’s clinical systems, a pharmacy’s dispensing workflow, an emergency-services dispatch console — for these, “the license degraded and locked out existing users” is not a commercial pressure tactic; it is a patient-safety event with a vendor’s name on the root-cause analysis.
The starter-interrupt reporting made this concrete a decade ago: the documented harm case was not an inconvenienced deadbeat, it was a mother unable to drive a feverish child to the ER over a three-days-late payment5. Scale that pattern up to enterprise software and the stakes scale with it. This is why a serious no-kill-switch doctrine pairs the technical floor with a contractual one — an emergency-continuity clause stating that licensing disputes never interrupt care-critical or safety-critical operation, full stop, whatever the payment status. (The AiCE-Lab spec names its version of this clause darura, after the Islamic-jurisprudence doctrine that necessity — the preservation of life — suspends ordinary rules17. The name is culturally specific; the engineering obligation is universal.) The technical design makes the promise credible: a clause like that is cheap to write when your architecture already cannot produce a sudden outage, and hollow when a checkLicense() on the serving path can.
There is a hard-nosed commercial argument hiding in the ethics, and vendors should hear it: procurement teams at hospitals, utilities, and governments are increasingly literate about exactly this failure mode — the FTC study is one symptom of a broader institutional awakening13 — and “our architecture is incapable of bricking you; here is the public spec and the verifier source” is a differentiator that shortens security reviews. Trustworthiness that can be audited is a feature. It sells.
What this design honestly does not do
Doctrine that hides its limits is marketing, so: three concessions.
It does not stop piracy. A signed-token scheme keeps honest customers compliant and makes entitlements auditable; it does not resist a determined adversary who patches the binary or forks the verifier — and neither, history shows, does anything else short of not shipping the software. The grace window’s own documentation should say what the AiCE spec says: it is not a security control. Licensing enforcement in this doctrine is a compliance instrument — it makes the licensed state legible to both parties and makes drift loud — while actual recourse against bad actors remains where it always really was: contracts, audits, and courts. Vendors whose revenue model requires technically coercing unwilling users should notice that this is precisely the requirement the last thirty-five years of incidents indict.
It costs the vendor leverage, on purpose. Refresh denial is slower than a kill switch; a licensee determined to squat on a degraded deployment can do so for a long time. That slowness is not a bug — it is the deliberate re-introduction of due process into a domain where vendors had quietly granted themselves summary judgment at 2:30 AM. The Revlon dispute belonged in front of an arbitrator; the design’s job is to make sure it has time to get there.
It demands more design effort than a boolean. Degraded-mode floors must be specified per product (“what exactly may degrade?”), state must surface in health endpoints and metrics, conformance vectors must pin verifier behavior across language implementations. That is real work. It is also, notice, exactly the same kind of work as designing graceful degradation for any other partial failure — which is what a lapsed license is: a partial failure of the commercial layer, deserving the same engineering dignity as a lost cache or a downed replica, rather than a self-inflicted total outage.
The judgment
The software industry has spent thirty-five years discovering, one incident at a time, that remote disablement is a capability no one can be trusted to hold — not because vendors are villains, but because the trigger conditions (payment standoffs, acquisitions, sanctions orders, bankruptcies, trade-in promotions) arrive faster than any organization’s wisdom about pulling them. Logisticon thought it was collecting a debt. Nest thought it was tidying a portfolio. Adobe thought it was obeying the law. Insteon didn’t think at all; it just stopped paying its server bills. In every case the harm landed on end-users who appeared nowhere in the decision, and in every case the harm was possible only because the capability had been built.
The engineering answer is not better judgment about when to pull the switch. It is switchlessness as an architectural property: licenses as signed documents verified offline against embedded keys; a state ladder whose terminal rung is degraded and loud, never dead; existing end-users behind a normative floor no license state can breach; refresh denial as the vendor’s only lever; and perpetuity enforced by a verifier that has no revocation path to consult. None of this is exotic — it is a JWT-shaped token, two signatures, a thirty-line state machine, and the discipline to leave capabilities unbuilt. The full worked example, spec and conformance vectors included, is public17.
A license is a promise about the future. Kill switches let one party rewrite that future unilaterally, at machine speed, with the blast radius aimed at bystanders. Licenses that can’t kill are simply promises engineered to be kept — including, and especially, when the relationship that made them goes bad. Build the promise into the verifier, and you never have to trust anyone to keep it. That is what code is for.
References
Johnston, D., “Software Repossession: Technological Novelty or Corporate Terrorism?” — a contemporaneous case study of the October 1990 Logisticon–Revlon incident, including the payment timeline and Revlon’s causes of action. https://www.davidjohnston.com/revlon.html ↩︎
Heaton, S. C., “Electronic Self-Help Software Repossession”, Boston University Journal of Science & Technology Law, Vol. 6 — legal analysis of vendor self-help disabling, with Revlon v. Logisticon as the anchor case. https://www.bu.edu/law/journals-archive/scitech/volume6/heaton.pdf ↩︎ ↩︎
CBC News, “Amazon apologizes for erasing Orwell books”, July 2009 — the remote deletion of 1984 and Animal Farm from customers’ Kindles. https://www.cbc.ca/news/science/amazon-apologizes-for-erasing-orwell-books-1.782347 ↩︎
Technologizer, “Jeff Bezos: Amazon’s 1984 Actions Were ‘Stupid’”, 23 July 2009 — Bezos’s Kindle Community apology, quoted. https://technologizer.com/2009/07/23/jeff-bezos-amazons-1984-actions-were-stupid/ ↩︎
Corkery, M. and Silver-Greenberg, J., “Miss a Payment? Good Luck Moving That Car”, The New York Times (DealBook), 24 September 2014 — starter-interrupt devices in subprime auto lending, including the emergency-room case. https://dealbook.nytimes.com/2014/09/24/miss-a-payment-good-luck-moving-that-car/ ↩︎ ↩︎
The Register, “Nest kills Revolv”, 6 April 2016 — Google/Nest’s shutdown of Revolv hubs effective 15 May 2016, bricking devices sold with lifetime service. https://www.theregister.com/2016/04/06/nest_kills_revolv/ ↩︎
Adobe, “Adobe compliance with U.S. Executive Order in Venezuela” — the company’s own notice on deactivating Venezuelan accounts under Executive Order 13884, and the subsequent U.S. license permitting continued service. https://helpx.adobe.com/x-productkb/policy-pricing/executive-order-venezuela.html ↩︎
Gizmodo, “Adobe Will Cancel All Subscriptions in Venezuela to Comply With U.S. Sanctions”, October 2019 — including the initial no-refunds position. https://gizmodo.com/adobe-will-cancel-all-subscriptions-in-venezuela-to-com-1838867205 ↩︎
Engadget, “Sonos kills its device-bricking ‘recycle mode’”, 5 March 2020 — the Trade Up program’s 21-day irreversible bricking countdown and its withdrawal. https://www.engadget.com/2020-03-05-sonos-kills-its-device-bricking-recycle-mode.html ↩︎
Hackaday, “Insteon Abruptly Shuts Down, Users Left Smart-Home-Less”, 25 April 2022 — the overnight server shutdown and the hub-bricking factory-reset trap. https://hackaday.com/2022/04/25/insteon-abruptly-shuts-down-users-left-smart-home-less/ ↩︎
Hackaday, “VanMoof E-Bike Bankruptcy: The Risks Of Cloud-Connected Transport”, 23 July 2023 — the July 2023 bankruptcy, app-dependent unlocking, and the scramble (including Cowboy’s Bikey app) to extract digital keys before the servers died. See also TechCrunch’s bankruptcy coverage: https://techcrunch.com/2023/07/18/vanmoof-goes-vanpoof-bankruptcy. https://hackaday.com/2023/07/23/vanmoof-e-bike-bankruptcy-the-risks-of-cloud-connected-transport/ ↩︎
CNN, “Russian troops in Melitopol plunder $5M farm vehicles from Ukraine — to find they’ve been remotely disabled”, 1 May 2022. https://www.cnn.com/2022/05/01/europe/russia-farm-vehicles-ukraine-disabled-melitopol-intl/index.html ↩︎
U.S. Federal Trade Commission, “Smart Products Surveyed Fail to Provide Consumers with Information on How Long Companies will Provide Software Updates”, press release and staff perspective, 26 November 2024 — 184 products surveyed, ~89% without support-duration disclosure, with Magnuson-Moss Warranty Act implications noted. https://www.ftc.gov/news-events/news/press-releases/2024/11/smart-products-surveyed-fail-provide-consumers-information-how-long-companies-will-provide-software ↩︎ ↩︎
Jones, M., Bradley, J., and Sakimura, N., “JSON Web Token (JWT)”, IETF RFC 7519, May 2015. https://www.rfc-editor.org/rfc/rfc7519 ↩︎
Josefsson, S. and Liusvaara, I., “Edwards-Curve Digital Signature Algorithm (EdDSA)”, IETF RFC 8032, January 2017. https://www.rfc-editor.org/rfc/rfc8032 ↩︎
National Institute of Standards and Technology, “Module-Lattice-Based Digital Signature Standard”, FIPS 204, August 2024. https://csrc.nist.gov/pubs/fips/204/final ↩︎
AiCE-Lab, License Token Specification — public specification of the dual-signature (Ed25519 + ML-DSA-65) offline-verifiable token format, the valid/grace/degraded state ladder, the degraded-mode end-user floor, tier and refresh semantics, perpetual invariants, and conformance vectors for third-party verifiers. https://gitlab.com/aice-lab/license/spec ↩︎ ↩︎ ↩︎ ↩︎ ↩︎