The format
The declaration
One JSON file, published once a year, at a path you control. This page is meant to be enough on its own — hand it to a developer and they can implement from it.
Where it goes
https://your-domain.example/.well-known/give-back.json
Content-Type: application/json
Same pattern as security.txt, ACME challenge responses and OpenID discovery.
There is nothing to register and nobody to tell. If you can serve a static file, you can
comply.
The path is not registered with IANA. Informal use of .well-known is entirely
normal, and registration is something you do once a thing has caught on, not before. Note
the absence of any vendor name in it, which is deliberate: nobody puts a competitor’s
product name in their own infrastructure.
The fields
Six are required, because section 3.2 requires six things. Everything else exists to make the file useful rather than merely compliant.
| Field | Required | What it is |
|---|---|---|
format | Yes | Literally "give-back/0.1". Tells a crawler how to read the rest. |
entity | Yes | Who is declaring, and a contact address. Optionally the affiliates covered, since one file can cover a whole group. |
period | Yes | Your twelve months. Choose your own year end and align it to your financial year. |
published | Yes | A date. Within ninety days of the period ending. |
reliance | Yes | What you are standing on. Only component_count and method are required inside it. |
contributions | Yes | What you gave. "items": [] is a valid and complete answer. |
rationale | Yes | Free text you write. No minimum length, no required tone, nobody scoring it. |
reliance.fragility | Optional | Single maintainers, unpaid maintainers, things with no commits in eighteen months. Optional, and the most valuable thing in the document. |
reliance.notable | Optional | Specific components worth naming. Eleven named well beats four hundred listed. |
omissions | Optional | Required only if you withheld something under the safety valve. Says that you withheld, never what or how much. |
previous | Optional | Link to last year’s file. Turns a document into a series, which is where the interest actually is. |
method is required and the count alone is not
“412 components” is meaningless without knowing whether that is direct or transitive, whether development dependencies are counted, and when it was measured. Two organisations of identical size can differ tenfold on the same tree. One sentence of method makes the number comparable; without it the whole corpus is noise.
Worked examples
Three real files. All three are compliant. Two of them give nothing.
Loading…
The privacy rules
Get these wrong and no company of any size adopts this, so they are part of the format rather than advice about it.
- Only publicly registered components are ever counted. If it is not already public in a package registry or a source repository, it does not go in the file.
- Your proprietary work never appears — not even its existence. There is no field for how many internal components you have, and there never will be. “We have 43 proprietary components” is competitive intelligence, and a format that asked for it would be declined by exactly the organisations whose participation matters.
-
Never a count of what was withheld. The
omissionsarray names the field and the reason. It does not have a quantity and cannot be given one. - Aggregate before publishing. Counts and bands, not contents, not identifiers, not usage telemetry. Nothing in this format describes what your software does or who uses it.
- No individuals’ names, except their own. A maintainer profile may name its author because its author wrote it. A declaration must not name individual maintainers who have not published a profile.
Section 6 lets you omit any detail whose publication would be unlawful or would create a demonstrable security risk, provided you say that you have omitted something. You never have to say what, and you never have to say how much. A stock licence cannot offer this, which is one of the few genuine reasons to draft a new one rather than adding a sentence to Apache 2.0.
Validating
The schema is plain JSON Schema 2020-12 with no extensions, so any standard validator works.
# with check-jsonschema
pipx run check-jsonschema \
--schemafile https://oosl.org/schema/give-back-1.json \
.well-known/give-back.json
# or ajv
npx ajv-cli validate \
-s give-back-1.json -d .well-known/give-back.json --spec=draft2020
Validation is a convenience, not a compliance test. Section 8.3 is explicit that no tool creates the obligation, and by the same logic no tool discharges it: a file that fails validation but contains the six things section 3.2 asks for is compliant, and a file that validates perfectly while omitting a required fact is not.
Design notes
Why not just extend CycloneDX or SPDX?
Because they answer a different question extremely well and this one not at all. An SBOM
tells you what you are running. This tells you who is behind it and what you did about that.
The right relationship is that a declaration links to an SBOM, via the
reliance.sbom field, and adds the column the SBOM does not have. Fighting a
mature standard for its own territory would be a bad use of everybody’s time.
Why package URLs?
purl is already the de facto identifier across SBOM tooling, and inventing an
identifier scheme here would be an unforced error. If your components have no purl, name
them in prose in the note field and move on.
Why is the full component list optional?
Because it is the least interesting part and the most tedious to produce, and requiring it would make the format feel like an audit. The counts do the analytical work, the notable list does the human work, and anyone who wants the full enumeration can follow the SBOM link.
Why no signature?
Because the file is served from a domain the entity controls over TLS, which is the same
assurance security.txt settles for. Signing adds key management, key rotation
and a revocation story for a threat model that mostly does not exist: there is very little
to gain from forging somebody else’s admission that they gave nothing. It can be
added later if that turns out to be wrong.