Automatically deploy your CTF challenges from GitHub to CTFd. Also supports containerised challenges on managed CTFd, Kubernetes, and Microsoft Azure.
- A managed or self-hosted CTFd instance
- An education discount is available for managed instances. Contact support for more details.
- GitHub account for each challenge author. Consider GitHub Education if you're eligible
- Click here to create a repository for your CTF. Select "Private" to prevent public access
- Allow GitHub Actions to create pull requests
- Create the following secrets:
Name | Value |
---|---|
CTFD_TOKEN |
CTFd admin access token |
CTFD_SITE_PASSWORD (optional) |
CTFd site password, if enabled |
Name | Value |
---|---|
CTFD_DOMAIN |
CTFd domain, eg example.ctfd.io |
FLAG_PREFIX (optional) |
Flag prefix for linting, eg ctf{ |
- See containers for more options
- Invite your team members to access the repo
- Create GitHub issues for each challenge. Send a link like this to your challenge authors: [your-repo-url]/issues/new/choose
- Consider using GitHub Codespaces for challenge development
- Add CTFd pages to the
pages
folder, and they'll automatically be deployed
Get the latest updates with the following commands. You may need to resolve merge conflicts.
git pull https://github.com/pl4nty/auto-CTFd --allow-unrelated-histories --rebase=false --squash -X theirs
git commit -m "chore: update repo template"
git push
Some challenges, like pwn or web, may need to run services in containers. These can be deployed to several platforms. To disable a platform, disable its GitHub workflow.
Note that managed CTFd has certain Dockerfile requirements and limitations. Please see the CTFd documentation for more details.
Create the following variables:
Name | Value |
---|---|
REGISTRY |
Managed CTFd registry, eg registry.ctfd.io/example |
- Add a Compose file like
docker-compose.yml
to each of your challenge(s) - Ensure TCP challenges have unique ports
- Create the following variables:
Name | Value |
---|---|
REGISTRY |
A container registry accessible by the Kubernetes cluster |
KUBE_HOST |
Hostname for challenges. HTTP challenges will be available via ingress on example.KUBE_HOST , and TCP challenges via load balancer service on KUBE_HOST:port |
- Create the following secrets:
Name | Value |
---|---|
REGISTRY_USERNAME |
Container registry username |
REGISTRY_PASSWORD |
Container registry password |
KUBE_CONFIG |
A static kubeconfig file. To use a dynamic file instead, modify the workflow to retrieve its own kubeconfig eg using azure/aks-set-context |
- Deploy the challenges
- Create an ingress controller in the cluster
- Create a public DNS record for
*.KUBE_HOST
to the controller's IP address - Create a public DNS record for
KUBE_HOST
to the load balancer IP address
- Create an Azure app registration and federated credentials
- Create an Azure Container Apps environment. Note that a custom vnet is required for TCP ports.
- Delete the quickstart Container App, and assign the
Contributor
role on its resource group to the app registration - Create a user-assigned managed identity and
- Create an Azure Container Registry and assign the
AcrPull
role on it to the managed identity - (Optional) Add a custom DNS suffix to the Container Apps environment
- Create the following variables:
Name | Value |
---|---|
REGISTRY |
A container registry accessible by the Container Apps environment |
AZURE_TENANT_ID |
App registration tenant ID |
AZURE_CLIENT_ID |
App registration client ID |
AZURE_CONTAINER_ENV |
Container Apps enviroment resource ID |
AZURE_CONTAINER_IDENTITY |
Managed identity resource ID |
AZURE_CONTAINER_SUFFIX |
Container Apps environment DNS suffix, eg chals.example.com |