Cloudflare Web Application Firewall downloader
A library, CLI, and docker image that downloads Cloudflare WAF logs for a specified zone and time range.
Schema
See src/waf_logs/resources/db/ for a list of schemas that are auto-applied at start. This can be disabled by passing --ensure_schema False.
Quickstart
The project is published at https://pypi.org/project/waf-downloader/.
Install it via:
pip install waf-downloader
# or alternatively, directly from git
pip install "git+https://github.com/MihaiBojin/waf-downloader@main"
Or with Docker:
docker pull docker.io/mihaibojin/waf-downloader:latest
The list of published images can be found at: https://github.com/MihaiBojin/waf-downloader/pkgs/container/waf-downloader
and
https://hub.docker.com/repository/docker/mihaibojin/waf-downloader/tags
Or with Helm
See charts/waf-downloader/README.md for more details.
Development
This project uses uv. Install it, then one command gets you a working development environment:
uv sync --all-extras
That creates .venv/, installs everything from the committed uv.lock, and
provisions a Python interpreter if you do not have a suitable one. Run
commands through uv run (uv run pytest tests) or activate the environment
with source .venv/bin/activate.
To also install the git hooks, run task setup.
Dependencies
Declare them in pyproject.toml, under [project] dependencies or
[project.optional-dependencies], then refresh the lock file:
uv lock
Commit uv.lock alongside the pyproject.toml change; CI runs
uv sync --locked and fails if the two disagree.
Build and run with Docker
Define secrets in an .env file (do not quote values):
CLOUDFLARE_API_TOKEN=...
DB_CONN_STR=...
The Cloudflare token is required (see required permissions), but the connection string is optional. If skipped, it will result in logs being printed to stdout.
IMPORTANT: This project uses taskfile.dev, which you will need to install for running the following commands:
# Build
task docker-build
# Load all logs in zone, starting 5 minutes prior
task docker-run -- --zone_id zoneid1 --start_minutes_ago 5
# And alternatively, only output the logs
task docker-run -- --zone_id zoneid1 --start_minutes_ago 5 2>/dev/null
# Do not specify a start time, relying on a starting timestamp stored in the database
# If a timestamp is not found in the database, or specified with --start_minutes_ago, the downloader will start 5 minutes prior
# This functionality makes it easy to run waf-downloader as a cron job
# NOTE: specifying --start_minutes_ago will always override the timestamp stored in the database, causing potential gaps in the data
task docker-run -- --zone_id zoneid1
# Do not exit and keep downloading new logs forever
# These will be recent up to the last minute
task docker-run -- --zone_id zoneid1 --follow
# Multiple zones can be specified via a comma-separated string
task docker-run -- --zone_id zoneid1,zoneid2,zoneid3,etc
# Or by repeating the flag
task docker-run -- --zone_id zoneid1 --zone_id zoneid2 --zone_id zoneid3 ...
Publishing to PyPI
GitHub-based version publishing
The simplest way to publish a new version (if you have committer rights) is to tag a commit and push it to the repo:
# At a certain commit, ideally after merging a PR to main
git tag v0.1.x
git push origin v0.1.x
A GitHub Action will run, build the library and publish it to the PyPI repositories.
Manual publish
These steps can also be performed locally. For these commands to work, you will need to export two environment variables (or define them in .env):
export TESTPYPI_PASSWORD=... # token for https://test.pypi.org/legacy/
export PYPI_PASSWORD=... # token for https://upload.pypi.org/legacy/
The tasks pass these to uv publish as UV_PUBLISH_TOKEN; the test index is
defined as testpypi under [[tool.uv.index]] in pyproject.toml.
First, publish to the test repo and inspect the package:
task publish-test
If correct, distribute the wheel to the PyPI index:
task publish
Verify the distributed code
task publish-verify
Cloudflare WAF documentation
Metadata
Release files for waf_downloader 0.3.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| waf_downloader-0.3.3.tar.gz | 217.0 kB | Without provenance | Details for waf_downloader-0.3.3.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| waf_downloader-0.3.3-py3-none-any.whl | Python 3 | none | any | Details for waf_downloader-0.3.3-py3-none-any.whl |
Total release size: 238.8 kB
Release files / waf_downloader-0.3.3.tar.gz
| Download URL | waf_downloader-0.3.3.tar.gz |
|---|---|
| Size | 217.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
383ae5308d17ed3eb2bdda61f5115519f26019546bbe2e0fd80f3c1206b415bd
|
|
BLAKE2b-256 checksum How to use checksums |
c524dea242fc7f04a99f8b074af96916875ac1ab9ce8b3762557ab3e36e381b3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.0 {"installer":{"name":"uv","version":"0.12.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / waf_downloader-0.3.3-py3-none-any.whl
| Download URL | waf_downloader-0.3.3-py3-none-any.whl |
|---|---|
| Size | 21.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
e41887a2a4ed846577f077ac4ecff6c0e6cc8e0dd4f45925677fdd9f54e57930
|
|
BLAKE2b-256 checksum How to use checksums |
9d105f7eea23c55be3ed045879f96d24f34e09b3865e8b39dbfa84b2fd070f8f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.0 {"installer":{"name":"uv","version":"0.12.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Security for waf_downloader 0.3.3
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.