All news

Factory

The harvest rule: when code moves into a kit

· Toolkit · 2 min read

Diagram: Reputo and Leadgener hand their copies to one Keycloak kit; the port is faithful, and realm exports prove it equal.

A product builds what it needs in its own repository first. The question is when a piece becomes a kit. Too early, and we design for consumers that do not exist. Too late, and the copies drift: on 10 October one fix to the Keycloak setup reached Reputo and Leadgener as two merge requests, one per copy.

Two conditions, both required

We move code into a kit only when a second product needs the same behaviour and that behaviour must not diverge: security, legal obligations, operations or an API contract. If only the first holds, the second product copies the piece and owns its copy; the app shell, the login theme and the landing page stay copies for that reason. A kit needs at least two consumers within six months, or it goes back into its product.

A product, in turn, does not edit kit code: it pins a version, and a kit change is made in the kit and released. For the NuGet packages, all five products carry the same check in their CI file:

test ! -e libs/microsaas-toolkit || { echo "libs/microsaas-toolkit is back; change the toolkit in its own repository"; exit 1; }

The Keycloak kit, harvested

Reputo and Leadgener each carried a copy of the realm provisioning script, 347 and 348 lines long respectively. It sets what every realm must share, such as self-registration off and PKCE with S256 for browser clients. Leadgener's copy appeared on 8 October; three days later, beyond each product's defaults, the two differed in comments and one role description.

On 11 October 2026 we moved it into the Keycloak kit as a faithful port: the same values in, the same realm out, no cleanup in the same step. We ran each product's own scripts, then the kit, on a fresh Keycloak and compared the normalized realm exports. They were identical byte for byte, except for that role description, which a divergence file records with its reason.

Each product then replaced its copy in its own merge request. The provisioning script became a 46-line wrapper in Reputo and a 47-line one in Leadgener, holding only the product's defaults, and each product pins the kit's image by version and digest.

The Keycloak kit is therefore code that already ran in two products, ported so that it behaves as it did there, proved by tests a reviewer reads as a diff. When a kit does not do what you need, you do not patch it: you ask for an option, which arrives in a minor release with the old behaviour as the default, and you pin it when you choose. What no other product needs stays yours.