Skip to content

Migrate from CTFd or another platform

Moving to Flagpost from CTFd — or any other platform — is an afternoon’s work, not a rewrite, but different parts of an event move differently. This guide walks the whole thing: what imports automatically, what you recreate (and how fast), what deliberately doesn’t move, and the cutover itself. (Still deciding? See Flagpost vs CTFd.)

One rule up front: migrate between events, never mid-event. Finish (or archive) the running competition where it is; launch the next one on Flagpost.

Challenges are the bulk of the value, and they port in one step: Flagpost bulk-imports ctfcli-format YAML zips — the format the CTFd ecosystem already uses.

  • Your challenge repo is already ctfcli-format? Zip the challenge directories and import (Manage challenges → Import). Titles, categories, descriptions, point values, dynamic-decay settings, static and regex flags, hints, attachment files, tags, difficulty, visibility state, title-referenced prerequisites, and a challenge’s connection_info (its live-service address) all come across; categories are created and tags join the competition vocabulary automatically. As of v1.5.0 connection_info round-trips through ctfcli import — before that it was silently dropped.
  • Challenges only live inside a CTFd instance? Pull them out with ctfcli first (ctf challenge pull), then zip and import.

Details and the field map: Import & export and the ctfcli format reference.

There’s no importer for another platform’s configuration — settings models differ too much for that to be honest — but a Flagpost competition is a few minutes of Settings tabs:

  • General — visibility, join mode (self-serve or invite code), participation mode (team or individual), max team size, divisions (brackets), public spectator board and CTFtime feed opt-ins.
  • Schedule — start/end (the scheduler emits the lifecycle events your automations can hang off).
  • Challenges — categories arrive with the import; add tag/difficulty vocab, the multiple-choice guess cap, and challenge ratings if you want them.
  • Automations — the things you previously scripted or did by hand (first-blood announcements, hint waves, end-of-event freeze + survey) become When → If → Then rules.

Once configured, you never rebuild this again: clone the competition for your next event, or use the platform backup to move whole installs — both are full-fidelity within Flagpost.

3. People — SSO, or fresh accounts by design

Section titled “3. People — SSO, or fresh accounts by design”

If your organisation runs an identity provider, single sign-on dissolves this step entirely: connect Google, Okta, Keycloak, or Entra over OIDC, a campus or enterprise IdP (Shibboleth, ADFS) over SAML 2.0, or bind directly against Active Directory or OpenLDAP with the LDAP provider — and your people sign in with the accounts they already have, provisioned just-in-time on first login, nothing to migrate.

Without an IdP, accounts are the one thing that genuinely can’t port: no platform can (or should) export usable password hashes into another. Flagpost keeps re-registration as close to zero-friction as it gets:

  • Username-first identity — email is optional, so sign-up is one field and a password.
  • Self-serve joining — public competitions are one click to enter; private ones take an invite code you share once.
  • Teams re-form themselves — captains create the team and share its invite code; optional approval and size caps enforce your rules without staff involvement.
  • Closed registration? Mint accounts from Admin → Users and hand out credentials; self-service password reset takes over from there (with SMTP configured).

For recurring events this is a one-time cost: from then on your users live in your install, and platform backups carry them between Flagpost installs with full fidelity.

Historical state belongs to the old platform: past scores, solve logs, submission history, old support threads, and write-ups won’t import — there’s no honest way to translate another platform’s scoring history into Flagpost’s event-sourced records. Keep the old instance around read-only (or export its data to cold storage) if you need the archive; start the new era clean.

CTFd’s custom pages don’t carry over as raw markup either. Flagpost has its own custom pages, but they’re structured rich text — a deliberate security stance — not the raw HTML/CSS/script CTFd lets you paste, so recreate any custom pages in the editor rather than expecting a copy-paste import.

  1. Stand up Flagpost — production deployment on your domain; run the setup wizard.
  2. Import challenges into a rehearsal competition; test flags, attachments, and unlock chains.
  3. Configure the real competition (§2) and clone from the rehearsal if you like what you have.
  4. Wire the event ops — automations, announcement templates, a feedback survey scheduled for the final hour.
  5. Open registration ahead of the event so teams form early.
  6. Repoint the world — DNS, event page links, and the CTFtime feed URL if your event is rated.
  7. Retire the old instance to read-only once the archive question is settled.

Stuck on something this guide doesn’t cover? Ask in GitHub Discussions — migration friction is exactly the feedback that shapes the roadmap.