Licensing and the DCO

This chapter is the legal and provenance foundation under every Firecracker contribution: the Apache-2.0 license the project is distributed under, the NOTICE/THIRD-PARTY/CREDITS attribution files it maintains, the Developer Certificate of Origin (DCO) it uses instead of a Contributor License Agreement (CLA), the exact Signed-off-by mechanics the DCO bot enforces, the license header that goes on source files, and the dependency-license gate (cargo-deny / deny.toml) that keeps a bad-licensed crate out of the build. None of this is optional and none of it is waved through for cleverness or seniority — a PR with a missing sign-off or a GPL dependency is blocked the same way a failing test is blocked.

The throughline: Firecracker is a piece of production infrastructure distributed to the world under a permissive open-source license, and the licensing machinery exists to guarantee, mechanically and on every PR, that the project can keep distributing it cleanly. Get the licensing wrong and the problem isn't a style nit — it's a contribution that legally cannot be accepted.

cd ~/fc-src
# The authoritative artifacts this chapter explains. Read them, don't trust this page:
ls LICENSE NOTICE CONTRIBUTING.md
ls THIRD-PARTY THIRD_PARTY CREDITS deny.toml 2>/dev/null   # names/locations vary — find yours
find . -maxdepth 2 -iname "third*party*" -o -iname "credits*" -o -iname "deny.toml" 2>/dev/null
# The DCO and sign-off requirement in the contribution doc (verify wording on your branch):
rg -n -i "DCO|Developer Certificate of Origin|Signed-off-by|sign-off|sign off|CLA" CONTRIBUTING.md

Why Apache-2.0

Firecracker is distributed under the Apache License 2.0, the same permissive, OSI-approved license AWS uses for most of its open-source infrastructure and the license shared by the rust-vmm crates Firecracker builds on. Apache-2.0 is the deliberate choice for a piece of software that AWS both runs as production infrastructure (Lambda, Fargate) and wants the broadest possible ecosystem to adopt and embed (Kata, firecracker-containerd, Fly.io, Vercel, and others).

What Apache-2.0 gives the project, and why it matters for you as a contributor:

Apache-2.0 propertyWhat it means in practice
PermissiveAnyone may use, modify, and redistribute (including commercially) without copyleft obligations — this is why an ecosystem could grow around it
Explicit patent grantContributors grant a patent license for their contributions; users get patent protection — unusually important for low-level systems code
Attribution preservedRedistributors must keep LICENSE and NOTICE; this is the mechanism behind the attribution files below
No "viral" reachEmbedding Firecracker (or a microVM stack atop it) does not force you to open-source your own code — the reason Kata/containerd can build on it

Note: The permissive choice is the opposite of the OpenSearch story, where the project exists precisely because a permissive license was taken away (the 2021 SSPL relicensing) and the fork reasserted Apache-2.0. Firecracker never had that fight — AWS open-sourced it under Apache-2.0 from the start and has kept it there. But the enforcement discipline is the same in both projects: the license is checked mechanically, and a dependency or a header that compromises it is an existential problem, not a cosmetic one.

The whole patent-grant point is why the project cares so much about provenance — which is exactly what the DCO certifies.


DCO, not CLA: why the difference matters

Many corporate open-source projects require a Contributor License Agreement — a separate legal document you (or your employer) sign once, often assigning or licensing broad rights to the project's owner before any contribution is accepted. Firecracker does not use a CLA. It uses the Developer Certificate of Origin instead, and the difference is worth understanding because it shapes how every commit you make must look.

CLADCO (Firecracker's choice)
What it isA legal agreement signed out-of-band, often per-contributor or per-employerA per-commit certification embedded in the commit itself
FrictionHigh: paperwork, legal review, an employer signature, a bot tracking who signedLow: one git flag per commit
What you assertVaries; sometimes a copyright assignment or a broad license grantA narrow, standard statement: you have the right to submit this under the project's license
Where it livesA separate database/agreementThe Signed-off-by: trailer in the commit message
The contributor costSign once, but a real barrier — especially for employees needing legal sign-offgit commit -s — no separate paperwork

The DCO is a short, fixed text (the canonical version at developercertificate.org). When you add a Signed-off-by: trailer to a commit, you are certifying that statement for that commit: in plain terms, that the contribution is yours to give (you wrote it, or it was given to you under a compatible license), and that you're submitting it under the project's open-source license.

Why Firecracker prefers it: a DCO is lighter weight for contributors (no out-of-band paperwork, so a strong systems engineer can land a fix the same afternoon they wrote it), it keeps the provenance attached to the commit (the certification travels with the code in git history forever, not in a separate database), and it asks for exactly what's needed and no more (the right to contribute under Apache-2.0, not a copyright assignment). For a project that wants a broad contributor base while staying legally clean, the DCO is the lower-friction, provenance-preserving choice. This is the legal substance behind the mechanics you met in the GitHub review chapter.


The Signed-off-by mechanics

The DCO is enforced by a bot that checks every commit in a PR. The rule is binary: every commit must carry a Signed-off-by: trailer whose name and email match the commit author, or the bot blocks the merge. No maintainer can wave it through — it is the most impersonal gate in the whole process.

# Set the identity you will sign with — BEFORE you start. The email must match.
git config user.name  "Your Name"
git config user.email "you@example.com"

# Sign off as you commit. This appends the trailer using your git identity:
git commit -s -m "vmm: validate balloon target against guest memory size"
# The commit message now ends with:
#   Signed-off-by: Your Name <you@example.com>

The trailer is the literal line Signed-off-by: Your Name <you@example.com>, and git commit -s generates it from your configured identity — never type it by hand with a different name/email, because the bot compares it against the author and a mismatch blocks the PR.

Fixing the common failures (you will hit at least one of these):

# Forgot to sign off the LAST commit:
git commit --amend -s --no-edit
git push --force-with-lease

# A whole branch of commits is missing sign-offs — rebase and re-sign every one:
git rebase --signoff main
git push --force-with-lease

# The sign-off email doesn't match the author email (a silent, common blocker):
git config user.email "the-address-you-signed-with@example.com"
git rebase --signoff main           # re-sign with the corrected identity
git push --force-with-lease

Warning: A green-looking commit with a Signed-off-by whose email doesn't match the author is still a blocked PR — the bot checks the match, not just the presence of the trailer. The single most common avoidable DCO failure is an anonymized GitHub no-reply email in the commit author field that doesn't match the address you signed with. Set git config user.email correctly before your first commit and this never happens.

Tip: Wire sign-off into your habit so you never forget it: git config alias.cs 'commit -s', or a prepare-commit-msg hook that appends the trailer. CONTRIBUTING.md also recommends the tools/devtool checkstyle/checkbuild hooks (code style & trust) — add the sign-off habit to the same muscle memory.


License headers on source files

Source files carry a license header so the license travels with the code even when a single file is copied out of the repo. The exact header text and the SPDX form are project conventions — read an existing file rather than inventing one, because the precise wording (and whether files inherited from crosvm carry an additional provenance line) matters.

cd ~/fc-src
# See the real header on a representative source file (don't guess — copy the live form):
sed -n '1,5p' src/vmm/src/lib.rs
sed -n '1,5p' src/firecracker/src/main.rs
# Firecracker forked originally from crosvm; some files carry crosvm/Chromium provenance.
# Confirm the header convention and any BSD-3-Clause provenance notice on inherited files:
rg -n "SPDX-License-Identifier|Copyright|Apache-2.0|crosvm|Chromium|BSD-3" src/vmm/src/lib.rs

What to get right:

  • Every new source file gets the project's standard header — the SPDX Apache-2.0 identifier and the copyright line in the exact form the existing files use.
  • Inherited files keep their provenance. Firecracker was forked from Google's crosvm; files derived from crosvm may carry the original BSD-3-Clause copyright notice in addition to Firecracker's. Don't strip a provenance notice — preserving it is an Apache-2.0/BSD attribution obligation, not a formality.
  • The header is checked. The style/checkstyle gate (tools/devtool checkstyle) flags a file missing or mismatching the header — so a missing header fails CI, exactly like a clippy warning. Run it locally and it never surprises you.

Attribution files: NOTICE, THIRD-PARTY, CREDITS

Apache-2.0 requires that redistributors preserve attribution, and Firecracker maintains the files that carry it. The exact set and naming vary by branch — find yours — but the roles are stable:

FileRoleWhy it matters
LICENSEThe full Apache-2.0 textThe license itself; must ship with every redistribution
NOTICERequired attribution notices (Apache-2.0 §4(d))Downstream redistributors must preserve it; dropping required content is a compliance defect
THIRD-PARTY / THIRD_PARTYLicenses/attributions of bundled or vendored third-party codeRecords what FC ships that isn't FC's, and under what terms
CREDITSAcknowledgements / contributor or upstream creditsAttribution for code and ideas the project builds on (e.g. crosvm)
cd ~/fc-src
# Find and read whichever exist on your branch:
ls LICENSE NOTICE 2>/dev/null
find . -maxdepth 2 \( -iname "third*party*" -o -iname "credits*" \) 2>/dev/null
sed -n '1,30p' NOTICE 2>/dev/null

What a contributor must get right: if you add or vendor third-party code, you must add its license and attribution to the appropriate file, and if a dependency ships a NOTICE whose content Apache-2.0 (or its own license) requires you to carry, that content must land in the right place. Dropping or mangling a required attribution is a license compliance defect, not a cosmetic one — and it's exactly the kind of thing a maintainer checks when a PR adds a dependency.


Dependency licensing: cargo-deny and deny.toml

Because Firecracker is a Rust project that pulls a tree of crates from crates.io and the rust-vmm org, the highest-leverage license risk is a transitive dependency with an incompatible license sneaking in. The defense is cargo-deny, configured by a deny.toml in the repo, run in CI (and runnable locally), which checks the entire dependency graph against a policy.

cd ~/fc-src
# The policy file — read it to see exactly what's allowed/denied on your branch:
cat deny.toml 2>/dev/null || find . -iname deny.toml
# Run the license check across the whole dependency tree:
cargo deny check licenses
# cargo-deny also checks more than licenses (verify which the policy enables):
cargo deny check        # licenses, bans, advisories (security), sources

What deny.toml typically governs (confirm the exact policy on your branch — it's the source of truth):

cargo-deny checkWhat it enforces
licensesEvery crate's license is on the allowed list (Apache-2.0, MIT, BSD, ISC, etc.) and none is on the denied list (GPL/AGPL/copyleft, source-available) — across the whole transitive graph
bansSpecific crates/versions are banned; duplicate versions are flagged; a [bans] allow/deny list
advisoriesCrates with known security advisories (RustSec) are flagged — supply-chain security, not just licensing
sourcesDependencies come only from approved registries/git sources, not arbitrary ones

The practical rule for a contributor: adding a dependency is never just a Cargo.toml line. When you add a crate, cargo deny check runs over the new graph; if the crate (or anything it pulls in transitively) has a disallowed license, the build fails. You then either drop the dependency, find a permissively-licensed alternative, or — if it's genuinely needed and its license is acceptable but not yet allowed — propose a deny.toml change, which a maintainer reviews as the license decision it is. A new dependency is a supply-chain and a license decision, and the maintainers scrutinize it accordingly (maintainer mindset).

Warning: A disallowed-license crate three levels deep in the dependency tree is just as blocking as a direct one — cargo-deny checks the whole graph. Before adding a dependency, run cargo deny check licenses locally and read what it pulls in. "It's only a transitive dependency" is not a defense; the build checks transitively on purpose.


What a contributor must get right (the checklist)

Run this on every PR, before you ask for review — every box is a thing the bots or a maintainer will otherwise bounce the PR on:

  • DCO sign-off on every commit (git commit -s), with the trailer email matching the author email — DCO bot green.
  • License header on every new source file, in the project's exact form (tools/devtool checkstyle clean); inherited/crosvm-provenance notices preserved.
  • Attribution updated if you added/vendored third-party code: its license and any required NOTICE content carried in the right file (NOTICE/THIRD-PARTY/CREDITS).
  • Dependency licensing clean: cargo deny check licenses passes for the new graph; any new crate's license (and its transitive deps') is on the allowed list — or a reviewed deny.toml change justifies it.
  • No new copyleft/source-available dependency introduced directly or transitively.
  • If you touched deny.toml, the change is explained in the PR as the license decision it is.

If every box is checked, the only licensing question left is a human one — and there usually isn't one, which is exactly the point: the machinery makes the clean Apache-2.0 property automatic on every PR.


Prove You Understand This

  1. Why is Firecracker Apache-2.0 rather than copyleft, and what specifically does the explicit patent grant buy a low-level systems project?
  2. Explain the DCO-vs-CLA choice: what does a Signed-off-by certify, and why does Firecracker prefer it over a CLA for both the contributor and the project?
  3. Your PR has three commits; the DCO bot is red on one because its sign-off email doesn't match the author. Give the exact commands to fix the whole branch without losing work.
  4. You're adding a new file derived from crosvm and a new crate dependency. What must you get right on the header, the attribution files, and the dependency license — and which command checks the last one across the whole graph?
  5. A maintainer asks you to justify a deny.toml change. Why is adding a dependency a license and a supply-chain decision, and what does cargo-deny check beyond licenses?
  6. Why is a disallowed-license crate three levels deep in the dependency tree just as blocking as a direct one?

Next: Code Style, Test Quality, and Building Trust — the everyday craft gates that, together with the licensing discipline here, earn you the review bandwidth that turns contributions into influence.