Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,5 +146,8 @@ knowing when deciding where to spend effort on packaging.

## Licensing of contributions

Flagpost is licensed under the **GNU AGPL-3.0** (see [`LICENSE`](LICENSE)). By
submitting a contribution, you agree that it is licensed under the same terms.
Flagpost is licensed under the **Apache License 2.0** (see [`LICENSE`](LICENSE)).
By submitting a contribution, you agree that it is licensed under the same terms
(Apache-2.0 §5: unless you explicitly state otherwise, any contribution
intentionally submitted for inclusion is under the terms of the license,
without additional terms or conditions).
863 changes: 202 additions & 661 deletions LICENSE

Large diffs are not rendered by default.

143 changes: 0 additions & 143 deletions MODULE-EXCEPTION

This file was deleted.

5 changes: 5 additions & 0 deletions NOTICE
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Flagpost
Copyright 2026 Tom Collier

This product includes software developed as part of the Flagpost project
(https://github.com/tbcsec/flagpost).
13 changes: 7 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

**A modern, open-source platform for running Capture&nbsp;the&nbsp;Flag competitions —<br>self-hosted, real-time, and batteries-included.**

[![License: AGPL v3](https://img.shields.io/badge/license-AGPL--3.0-2bbd7e.svg)](LICENSE)
[![License: Apache 2.0](https://img.shields.io/badge/license-Apache--2.0-2bbd7e.svg)](LICENSE)
[![CI](https://github.com/tbcsec/flagpost/actions/workflows/ci.yml/badge.svg)](https://github.com/tbcsec/flagpost/actions/workflows/ci.yml)
[![PRs welcome](https://img.shields.io/badge/PRs-welcome-2bbd7e.svg)](CONTRIBUTING.md)
![Backend: FastAPI](https://img.shields.io/badge/backend-FastAPI-009688.svg)
Expand Down Expand Up @@ -346,10 +346,11 @@ the call is never attempted at all. Full detail in [`PRIVACY.md`](PRIVACY.md).

Copyright © 2026 **Tom Collier**.

Flagpost is licensed under the **[GNU Affero General Public License v3.0](LICENSE)**.
You're free to use, modify, and self-host it; if you run a **modified** version as
a network service, the AGPL's §13 requires you to offer your users its source. The
built-in "Powered by Flagpost" footer links every page to this repository, which
is how Flagpost surfaces its source to remote users.
Flagpost is licensed under the **[Apache License 2.0](LICENSE)** (from v1.5.1 —
earlier releases were published under AGPL-3.0 and remain available on those
terms). You're free to use, modify, self-host, and build on it, commercially or
otherwise, with the license's explicit patent grant. The name "Flagpost" and the
project marks are not part of the grant (License §6). The built-in "Powered by
Flagpost" footer links every page back to this repository.

<div align="center"><sub>Built for the CTF community. Fly your flag. 🚩</sub></div>
9 changes: 5 additions & 4 deletions backend/plugins/loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@
additive, not a retrofit. The dependency machinery is built now because it's
pure logic that's cheap to get right early and awkward to bolt on later.

Licensing: third-party modules loaded through this mechanism are covered by
the Flagpost Module Exception, an additional permission under AGPL-3.0
Section 7 — see ``MODULE-EXCEPTION`` in the repository root, alongside
``LICENSE``.
Licensing: Flagpost is licensed under the Apache License 2.0 (``LICENSE`` in
the repository root), so third-party modules loaded through this mechanism may
carry any license — no exception instrument is needed. Releases up to v1.5.0
were AGPL-3.0 with the Flagpost Module Exception granting this same freedom;
the v1.5.1 relicense (ADR-0035) retired it.
"""

from __future__ import annotations
Expand Down
6 changes: 6 additions & 0 deletions docs/ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,12 @@ closed:
(#258), argon2 run at test cost with every CI job time-bounded (#207), and the
frontend image now ships its `public/` static assets (#282).

**v1.5.1** — **relicensed to Apache 2.0** (ADR-0035). The whole platform moves
from AGPL-3.0 to the Apache License 2.0 to remove the enterprise-adoption
blocker of a copyleft licence; the Flagpost Module Exception is retired (a
permissive licence needs none), and a `NOTICE` file is added. No functional
changes. Releases up to v1.5.0 remain available under AGPL-3.0 as published.

### Planned

Summarised from the open milestones; the milestone pages are authoritative.
Expand Down
69 changes: 69 additions & 0 deletions docs/adr/0035-relicense-apache-2.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# ADR-0035: Relicense from AGPL-3.0 to Apache 2.0

**Status:** Accepted
**Date:** 2026-08-25

## Context

Flagpost shipped v1.0.0 under AGPL-3.0, later adding the Flagpost Module
Exception (an AGPL §7 additional permission) so third-party modules could
carry their own licenses. The copyleft choice protected a possible future
hosted offering: AGPL §13 obliges anyone running a *modified* Flagpost as a
network service to offer its source.

In practice the license was costing the project its primary audience. A large
share of the target base — security and training teams at larger companies —
operates under corporate open-source policies that ban AGPL categorically,
regardless of the fact that self-hosting an unmodified copy carries almost no
obligations. Evaluation ends at the license line before features are seen, and
the actual posture was worse than plain AGPL: "AGPL plus a bespoke exception"
is two instruments for a corporate lawyer to review instead of a standard one.
The most direct open-source comparison, CTFd, is Apache-2.0 — so a shortlist
comparison was a strict licensing disadvantage.

The options actually considered:

- **Stay AGPL-3.0 (+ exception)** — keeps the strongest SaaS defence, keeps
losing the enterprise segment.
- **Apache 2.0** — permissive, OSI-approved, explicit patent grant and
patent-litigation termination (§3), trademark carve-out (§6). The standard
"enterprise-safe" choice; also what CTFd uses, and CTFd has run a paid
hosted offering on it for years.
- **MIT/BSD** — equally permissive but without the explicit patent language
that enterprise review looks for.
- **BSL/FSL-style source-available** — protects a hosted business but is not
open source, is itself blanket-banned by many of the same corporate
policies, and would defeat the adoption goal outright.
- **Dual licensing (AGPL + commercial)** — keeps the AGPL scare at evaluation
time and adds CLA overhead.

Feasibility was checked before deciding: the repository is effectively
sole-author (all human commits are the copyright holder's identities;
Dependabot's version bumps are not copyrightable), so no third-party consent
was required.

## Decision

From v1.5.1, Flagpost is licensed under the Apache License 2.0. The Flagpost
Module Exception is retired — under a permissive license, modules need no
additional permission to carry their own terms. Releases up to and including
v1.5.0 were published under AGPL-3.0 and remain available on those terms.

## Consequences

- **Easier:** enterprise adoption — plain, unmodified Apache-2.0 passes
corporate open-source review without legal escalation, and the custom
exception (one more thing to review) disappears. Third-party module
licensing becomes trivially simple.
- **Harder:** there is no longer a copyleft lever against someone offering
hosted Flagpost commercially. The protection for a future hosted offering
is now the trademark (Apache-2.0 §6 explicitly withholds it) plus the
operational moat, not the code. Judged acceptable: the code was never the
moat for event tooling, and the closest comparable has run this exact model
successfully.
- **Foreclosed (practically):** reversing course. Future versions could be
relicensed again, but every Apache-licensed release remains forkable
forever, and tightening later reliably provokes forks. The decision is made
as if permanent.
- Contributions are accepted inbound=outbound under Apache-2.0 §5
(CONTRIBUTING.md); no CLA is introduced.
1 change: 1 addition & 0 deletions docs/adr/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,4 @@ Status is one of:
| [0032](0032-multi-tenant-entra-issuer-validation.md) | Multi-tenant Entra issuer validation via a tenant-substituted issuer template | Accepted |
| [0033](0033-generic-oauth2-provider-kind.md) | A generic `oauth2` provider kind, with userinfo as the identity source | Accepted |
| [0034](0034-custom-pages-render-as-a-react-tree.md) | Custom pages store rich text and render as a React tree, never as HTML | Accepted |
| [0035](0035-relicense-apache-2.0.md) | Relicense from AGPL-3.0 to Apache 2.0; module exception retired | Accepted |
2 changes: 1 addition & 1 deletion frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "flagpost-frontend",
"version": "0.0.0",
"private": true,
"license": "AGPL-3.0-or-later",
"license": "Apache-2.0",
"scripts": {
"dev": "next dev",
"build": "next build && node scripts/check-yjs-singleton.mjs",
Expand Down