App Garden

Calculation Sign-Off and Lock

Countersigning public key

Everything you need to check an App Garden sign-off record yourself, without the add-in and without trusting us at the moment you check it.

The key

ECDSA, curve P-256, SHA-256. SPKI, base64url, no padding.

Key id: appgarden-csl-2026-09-11

MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE8G66G01uRbZKtO4HftENIssV3goga3XAU38YzkW6phY-9mp6aMeABibArGE0N7ftoE-cQbCkGtch7SroxXdPpA

The private half exists in exactly one place: the licence Worker, as a secret. It is not in the add-in, not in this repository, and not on any machine we develop on.

What the signature is over

The signature is over the record's recordHash, as its 64 ASCII hex characters — not over the decoded bytes, and not over the record body directly.

recordHash is the SHA-256 of the record body, which is a newline-separated list of name=value pairs in a fixed order:

v
canon
ruleset
logic
inputs
results
signer
role
revision
comment
officeUser
timestamp
inputRanges
outputRanges
findings
prev

Values are escaped: a backslash becomes \\, a newline \n, a carriage return \r. That escaping is not cosmetic — without it a comment containing a newline could forge an extra field, and a signer could make the signed body read as though the revision were something else.

The field order is fixed in code rather than taken from the object, because a record that has been written into a workbook, read back and re-parsed must produce the same bytes it did when it was signed. Otherwise the signature would fail on a file nobody had touched.

Where the record lives

Inside the workbook, in a custom XML part under the namespace https://appgarden.co.uk/calc-sign-off/record/1. A second part under .../index/1 holds the per-cell index used to list changes on a red verification; it is deliberately not covered by the signature, because tampering with it can only make the change list wrong, never make a changed workbook verify green.

Key rotation

Every record names the key that signed it in its keyId field. If the key is ever rotated, records signed under the old one stay verifiable — the add-in and this page carry both.