Open License Attestation

—

by Anonymous

A license that proves itself

MGLA v1 · published by HOMESERVER LLC · Apache-2.0 (code) / CC BY 4.0 (text)

This document is complete. A software engineer, or an AI coding agent, can rebuild the entire system from it — their own tools, their own backend — and the test vectors at the end decide whether they got it right.


The graveyard

In 2019 Microsoft closed its ebook store and every book its customers had bought stopped opening; refunds went out, the libraries did not. In 2009 Amazon reached into Kindles and deleted purchased copies of 1984, refunding the price of books people were partway through reading. When Games for Windows Live wound down, players lost multiplayer, saves, and achievements, and some paid games needed emergency patches to keep launching at all. Across two decades of digital rights management the pattern held: the honest customer carried the risk, the infringer rarely did, and when the activation server died the product was in trouble.

The mistake was structural. Every one of those schemes made the license depend on a server answering the phone. A license should be a fact, not a phone call.

What this is

MGLA makes a software license one signed line of text, packed into the product binary itself. This is a real one:

MGLA1|product=example-app|band=1.x|licensee=c3VwcG9ydGVy|grant=standard,seats:1|issued=2026-10-01T00:00:00Z|expiry=never|key=3e8256cf4ee9fcf7|sig=DX31_MTqHA7VkYOSzNbmxRC45Sp9ERNvvYIJwoljvAz-SvAoagHarBPjyG81oKIXMjz7GuvHI5vrXj93Le7hAg

Anyone can verify that line, offline, forever, with nothing but the developer’s published public key. There is no activation server and no remote kill. If every server on earth goes dark, every license already in the field still proves itself.

Here is what that buys and what it doesn’t. While the developer’s private key stays private, nobody can manufacture a grant the developer didn’t issue — a forged line fails the signature check in microseconds. The scheme does not make software uncopyable: a valid line travels with any copy of the binary, and a determined person can patch a license check out of their copy. Copying was never a winnable fight, and every scheme in the graveyard lost it expensively while punishing paying customers. MGLA fights the winnable fight: honest proof of a grant, cheap to issue, cheap to check, and still checkable decades from now because checking needs no one’s server.

Who this serves. A developer who wants to sell licenses without running license infrastructure. A customer who wants the thing they paid for to keep working. A court or auditor who wants proof a grant exists. And any operator who wants to run a software distribution service: the format is open and nobody’s property, so a license issued under one conformant service verifies under all of them.

The specification

The attestation line

A license attestation is a single line of printable ASCII:

MGLA1|product=<id>|band=<version band>|licensee=<opaque token>|grant=<terms>|issued=<ISO 8601 UTC>|expiry=<ISO 8601 UTC or "never">|key=<key id>|sig=<signature>

Rules:

  1. Fields appear in exactly this order, every field present.
  2. Field values are printable ASCII (bytes 0x20–0x7E) and never contain |.
  3. licensee is an opaque token the developer chooses. The format never requires a name, an email address, or any personal data.
  4. key is the first 16 lowercase hex characters of the SHA-256 of the developer’s raw 32-byte Ed25519 public key.
  5. sig is the Ed25519 signature (64 bytes) over the literal UTF-8 bytes of the line from MGLA1 up to and including the key value (everything before |sig=), encoded base64url without padding. Decoders re-add padding as needed; all base64url values in this format are unpadded.

Rule 5 is the load-bearing one. There is no canonicalization step and no re-serialization: the bytes found in the binary are the bytes that were signed. Two implementations cannot disagree about what was signed, because the attestation is its own canonical form.

Keys

The developer generates an Ed25519 keypair (RFC 8032; the private key is the raw 32-byte seed) and publishes the public key as a key line:

MGLA-KEY1|key=<key id>|pub=<base64url raw public key>

Published key lines live at a well-known HTTPS path on the developer’s own domain:

https://<domain>/.well-known/mgla/<key id>.txt

That is the online discovery path. Offline verification takes the key line directly, from anywhere: shipped beside the artifact, printed on paper, mirrored by a distribution service. The developer holds the private key, always; the format’s trust model gives a distribution service public keys and nothing else. A service may sell private-key custody as a convenience, and a developer who accepts that trade should know it is a trade.

Seats — where the line lives in an artifact

v1 defines two seats:

  • ELF binaries: a section named .mgla containing the line. Embed and extract with standard binutils:

    objcopy --add-section .mgla=license.mgla --set-section-flags .mgla=noload,readonly <binary>
    objcopy --dump-section .mgla=license.out <binary>
    
  • Any artifact: a sidecar file named <artifact>.mgla beside the artifact, containing the line.

Other container formats (PE, Mach-O, archives) arrive as future format versions.

Verification

A verifier, given a candidate line and a public key:

  1. Strip surrounding whitespace and trailing NUL padding (NULs first, then whitespace, as extraction from a padded section may yield either order; the reference implementation strips whitespace, NULs, then whitespace again).
  2. If the line does not begin MGLA1|: if it begins MGLA, return UNKNOWN (a line in this format family that this verifier does not judge — a future version, a key line, a revocation line); otherwise return INVALID.
  3. Split off |sig=<signature> from the end (last occurrence; rule 2 makes this unambiguous). Missing: INVALID.
  4. Parse the remaining fields. Wrong set or order: INVALID.
  5. Verify the signature over the literal remaining bytes against the public key. Failure, including a signature that does not decode to 64 bytes: INVALID.
  6. Confirm the key field equals the key id derived from the supplied public key, exact lowercase match. Mismatch: INVALID.
  7. Return VALID with the parsed fields. The caller judges the grant’s terms, bands, and dates against its own context.

Three verdicts, and the third is the one that matters: UNKNOWN never collapses into INVALID. A verifier that meets a line it cannot judge reports exactly that, and the fielded software it lives in keeps working. That single rule is why the format can evolve without strangling the binaries already in the world.

Revocation

Revocation is a published fact. A developer who needs to revoke an issued attestation publishes a revocation line at the same well-known path:

MGLA-RVK1|key=<key id>|sig=<revoked attestation's sig value>|rsig=<base64url Ed25519 signature by the same key over the literal bytes before "|rsig=">

Verifiers may consult published revocations and match them to attestations by the exact sig value; whether to enforce one is each implementer’s policy, stated to its own users. Nothing in the field stops working when the list is unreachable, and the format defines no way to reach into a fielded binary.

Updates and key succession

A new release repeats the issue path: build, embed a fresh attestation, publish. The band field says which releases a grant covers. Old releases stay published and stay verifiable; the format has no delete.

A developer rotating keys publishes a succession line, signed by the old key:

MGLA-SUCC1|old=<old key id>|new=<new key id>|pub=<base64url new public key>|ssig=<base64url Ed25519 signature by the old key over the literal bytes before "|ssig=">

Attestations signed by the old key remain valid forever. Succession extends trust forward, and the past stays signed exactly as it was. A future format version can carry a different signature algorithm the same way: the version prefix is the format’s algorithm agility, and a v1 verifier meeting such a line says UNKNOWN and moves on.

Bring your own backend

A distribution service, in this format’s eyes, is anything that can:

  1. serve artifacts and their attestations,
  2. serve developers’ key lines at the well-known path layout,
  3. and get out of the way — verification never requires it.

Storage, stack, language, hosting, pricing, business model: all yours. The format deliberately specifies nothing about the server, which is why there can be many of them, why none of them can hold a developer hostage, and why a license issued through one verifies through every other. Services compete on execution: uptime, tooling, support.

If you implement this with your own backend and your implementation passes the vectors below, you are conformant. You owe nobody a fee, a registration, or a notice. Ship a copy of this document with your implementation so the next implementer finds it.

Reference implementation

mgla.py, complete — the program that generated every vector in this paper. Python 3, the cryptography package, binutils for the ELF seat. Apache-2.0.

#!/usr/bin/env python3
# mgla.py — MGLA v1 reference implementation.
# Open License Attestation: sign, embed, extract, verify.
# Requires: python3, the 'cryptography' package, and (for ELF seats) objcopy.
# License: Apache-2.0. This file is a specification artifact; keep it small.

import base64, hashlib, subprocess, sys, tempfile, os

from cryptography.hazmat.primitives.asymmetric.ed25519 import (
    Ed25519PrivateKey, Ed25519PublicKey)
from cryptography.exceptions import InvalidSignature

MAGIC = "MGLA"
V1 = "MGLA1"
FIELDS = ("product", "band", "licensee", "grant", "issued", "expiry", "key")


def b64u(b: bytes) -> str:
    return base64.urlsafe_b64encode(b).decode().rstrip("=")


def unb64u(s: str) -> bytes:
    return base64.urlsafe_b64decode(s + "=" * (-len(s) % 4))


def key_id(pub_raw: bytes) -> str:
    return hashlib.sha256(pub_raw).hexdigest()[:16]


def keygen(seed_hex=None):
    """Return (seed, private, pub_raw, key_id). Deterministic when seed given."""
    seed = bytes.fromhex(seed_hex) if seed_hex else os.urandom(32)
    priv = Ed25519PrivateKey.from_private_bytes(seed)
    from cryptography.hazmat.primitives import serialization as ser
    pub_raw = priv.public_key().public_bytes(
        ser.Encoding.Raw, ser.PublicFormat.Raw)
    return seed, priv, pub_raw, key_id(pub_raw)


def sign_line(priv, kid, *, product, band, licensee, grant, issued, expiry):
    vals = dict(product=product, band=band, licensee=licensee,
                grant=grant, issued=issued, expiry=expiry, key=kid)
    for v in vals.values():
        if "|" in v or not v.isascii() or not v.isprintable():
            raise ValueError("field values are printable ASCII without '|'")
    body = V1 + "".join(f"|{k}={vals[k]}" for k in FIELDS)
    sig = priv.sign(body.encode())
    return f"{body}|sig={b64u(sig)}"


def verify_line(line, pub_raw):
    """Return (verdict, detail). Verdict is VALID | INVALID | UNKNOWN.
    UNKNOWN never collapses into INVALID: it marks a line this verifier
    cannot judge (another member of the format family), not a line that
    failed."""
    line = line.strip()
    if not line.startswith(V1 + "|"):
        if line.startswith(MAGIC):
            return "UNKNOWN", "format version beyond this verifier"
        return "INVALID", "not an MGLA line"
    body, sep, sigpart = line.rpartition("|sig=")
    if not sep:
        return "INVALID", "missing signature field"
    try:
        kv = dict(f.split("=", 1) for f in body.split("|")[1:])
        if tuple(kv) != FIELDS:
            return "INVALID", "field set or order is not MGLA1"
        Ed25519PublicKey.from_public_bytes(pub_raw).verify(
            unb64u(sigpart), body.encode())
    except InvalidSignature:
        return "INVALID", "signature does not verify"
    except Exception as e:
        return "INVALID", f"malformed: {e}"
    if kv["key"] != key_id(pub_raw):
        return "INVALID", "key id does not match the supplied public key"
    return "VALID", kv


def embed_elf(binary, line):
    with tempfile.NamedTemporaryFile("w", suffix=".mgla", delete=False) as f:
        f.write(line + "\n")
    subprocess.run(["objcopy", "--add-section", f".mgla={f.name}",
                    "--set-section-flags", ".mgla=noload,readonly", binary],
                   check=True)
    os.unlink(f.name)


def extract_elf(binary):
    with tempfile.NamedTemporaryFile(suffix=".mgla", delete=False) as f:
        out = f.name
    subprocess.run(["objcopy", "--dump-section", f".mgla={out}", binary],
                   check=True)
    data = open(out, "rb").read().rstrip(b"\x00").decode()
    os.unlink(out)
    return data.strip()


def main():
    a = sys.argv[1:]
    if a[:1] == ["keygen"]:
        seed, _, pub, kid = keygen(a[1] if len(a) > 1 else None)
        print(f"seed={seed.hex()}\npub={b64u(pub)}\n"
              f"MGLA-KEY1|key={kid}|pub={b64u(pub)}")
    elif a[:1] == ["sign"]:
        seed, priv, pub, kid = keygen(a[1])
        p = dict(x.split("=", 1) for x in a[2:])
        print(sign_line(priv, kid, **p))
    elif a[:1] == ["verify"]:
        pub = unb64u(a[1])
        verdict, detail = verify_line(open(a[2]).read(), pub)
        print(verdict, detail)
        sys.exit(0 if verdict == "VALID" else 1)
    elif a[:1] == ["embed-elf"]:
        embed_elf(a[1], open(a[2]).read().strip())
    elif a[:1] == ["extract-elf"]:
        print(extract_elf(a[1]))
    else:
        print("mgla.py keygen|sign|verify|embed-elf|extract-elf")


if __name__ == "__main__":
    main()

Test vectors

The private seed is published, so any implementation can regenerate the entire set from scratch: it is the ASCII of MGLA-test-vector-key-0001!!!!!!! (25 characters plus seven !, exactly 32 bytes). Test keys are public by definition; never use this keypair for anything real.

Keypair:

seed = 4d474c412d746573742d766563746f722d6b65792d3030303121212121212121
pub  = SDNZ1jXGM5jqm3eyAR6H3ajcl9HsR5j54dHdBw_m8TI
MGLA-KEY1|key=3e8256cf4ee9fcf7|pub=SDNZ1jXGM5jqm3eyAR6H3ajcl9HsR5j54dHdBw_m8TI

Vector 1 — a valid attestation. The line shown in “What this is”, reproduced here; signing input is everything before |sig=:

MGLA1|product=example-app|band=1.x|licensee=c3VwcG9ydGVy|grant=standard,seats:1|issued=2026-10-01T00:00:00Z|expiry=never|key=3e8256cf4ee9fcf7|sig=DX31_MTqHA7VkYOSzNbmxRC45Sp9ERNvvYIJwoljvAz-SvAoagHarBPjyG81oKIXMjz7GuvHI5vrXj93Le7hAg

Expected: VALID, fields parsed. Ed25519 is deterministic, so signing these fields with the vector key reproduces this exact line.

Vector 2 — tampered grant. The full tampered line (the substring standard replaced with premium.):

MGLA1|product=example-app|band=1.x|licensee=c3VwcG9ydGVy|grant=premium.,seats:1|issued=2026-10-01T00:00:00Z|expiry=never|key=3e8256cf4ee9fcf7|sig=DX31_MTqHA7VkYOSzNbmxRC45Sp9ERNvvYIJwoljvAz-SvAoagHarBPjyG81oKIXMjz7GuvHI5vrXj93Le7hAg

Expected: INVALID (signature does not verify).

Vector 3 — future format version. Vector 1 with the leading MGLA1 edited to MGLA2. Expected: UNKNOWN — never INVALID.

Vector 4 — wrong key. Vector 1 verified against the all-zero public key AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA (43 base64url characters decoding to 32 zero bytes). Expected: INVALID.

Vector 5 — ELF roundtrip. Compile any minimal C program. Embed vector 1 using the two objcopy commands given under “Seats” (the embedded license.mgla file carries the line with a single trailing newline). Extract with the dump command, strip trailing NUL padding and whitespace. Expected: the extracted line is byte-identical to vector 1, verifies VALID, and the host binary still executes normally.

Vector 6 — negatives. Three more lines, each derived from vector 1:

  • Everything before |sig= (signature field removed entirely). Expected: INVALID.
  • product and band fields swapped in order, signature unchanged. Expected: INVALID (field order).
  • The keypair’s own MGLA-KEY1 line passed to the attestation verifier. Expected: UNKNOWN (a format-family line this verifier does not judge).

Conformance: an implementation that reproduces all of these verdicts, and whose own freshly signed attestations verify under the reference verifier with the vector keypair, conforms to MGLA v1. Two independent implementations agreeing on these vectors need nothing else from us. This document was tested exactly that way before publication: an implementer working from the specification prose alone, without reading the reference listing, reproduced every verdict on the first attempt.

About this work

HOMESERVER LLC publishes this specification as its first work on behalf of The Merchants Guild. The Guild does not exist yet: it is a nonprofit we are in the process of completing and bringing to life, an Iowa institution whose purpose is developing, testing, and publishing useful technical knowledge as a public commons. The model it will live by is the one this paper practices: the commons publishes the what, openly and to everyone on identical terms, and any company that wants to sell the how competes on execution. That is why this specification carries permissive licenses rather than ours — a commons belongs to its public, including our future competitors.

If you build on this, you owe us nothing. If you want to follow the Guild as it forms, watch arpaservers.com.

The format is yours now. That was the design.


Comments

Leave a Reply

Your email address will not be published. Required fields are marked *