CTFd does not have the concept of configuration file, leading to deployment complications and the impossibility to version configurations. This is problematic for reproducibility or sharing configuration for debugging or replicating a CTF infrastructure.
Moreover, the setup API does not exist, so we had to map it to what the frontend calls in go-ctfd.
To fill those gaps, we built ctfd-setup on top of the CTFd API. This utility helps setup a CTFd instance from a YAML configuration file, CLI flags and environment variables.
Thanks to this, you can integrate it using GitHub Actions, Drone CI or even as part of your IaC provisionning.
With ctfd-setup you can setup your CTFd in a second.
You can use ctfd-setup as a CLI tool and provision it a YAML configuration file.
appearance:
name: 'My CTF'
description: 'My CTF description'
admin:
name: 'admin'
email: 'admin@super.ctf'
password: 'admin_password'
mode: usersWe encourage you to version this file such that re-deployment is easy (e.g., for test purposes, or in case of a catastrophic failure of the infra during the event).
Nevertheless, please do not commit the admin credentials ! Use from_env objects instead (refer to the YAML Schema for more info) or use CLI overrides.
It could also deploy custom pages (like the index) as follows. This feature is not available in CLI, GitHub Actions and Drone CI.
# ... other configuration attributes
pages:
additional:
- title: CTFer.io example index
route: index
format: markdown
content: |
<div>
<p>Some index page content</p>
</div>For further configuration, please refer to the binary's specific API through ctfd-setup --help.
To improve our own workflows and share knownledges and tooling, we built a GitHub Action: ctfer-io/ctfd-setup.
You can use it given the following example.
name: 'My workflow'
on:
push:
branches:
- 'main'
jobs:
my-job:
runs-on: 'ubuntu-latest'
steps:
- name: 'Setup CTFd'
uses: 'ctfer-io/ctfd-setup@v1.8.1'
with:
url: ${{ secrets.CTFD_URL }}
file: '.ctfd.yaml'
# or directly attributes
appearance_name: 'My CTF'
appearance_description: 'My CTF description'
admin_name: ${{ secrets.ADMIN_USERNAME }}
admin_email: ${{ secrets.ADMIN_EMAIL }}
admin_password: ${{ secrets.ADMIN_PASSWORD }}
# ... and so on (non-mandatory attributes)This could also be used as part of a Drone CI use ctferio/ctfd-setup.
kind: pipeline
type: docker
name: 'My pipeline'
trigger:
branch:
- main
event:
- push
steps:
# ...
- name: 'Setup CTFd'
image: 'ctferio/ctfd-setup@v1.8.1'
settings:
url:
from_secret: CTFD_URL
file: '.ctfd.yaml'
# or directly attributes
appearance_name: 'My CTF'
appearance_description: 'My CTF description'
admin_name:
from_secret: ADMIN_USERNAME
admin_email:
from_secret: ADMIN_EMAIL
admin_password:
from_secret: ADMIN_PASSWORD
# ... and so on (non-mandatory attributes)For ease of use, you can generate and use the YAML schema using ctfd-setup schema.
(Optional) In your .ctfd.yaml file you could then prepend # yaml-language-server: $schema=file:///path/to/schema.json.
Note
This will appear by default if your IDE has a YAML extension with support of the JSON SchemaStore.
In case you are working in an air-gapped environment or working on improving the project, you may want your schema to automatically target your configuration files.
To do so, add the following to your .vscode/settings.json.
{
"yaml.schemas": {
"schema.json": ".ctfd.yaml"
}
}
