A tiny certificate authority (CA) web UI for issuing and managing certificates. This repository contains a small FastAPI (uvicorn) web application and a Dockerfile so you can run it locally or inside a container.
Browser
|
| HTTP :2000
v
+---------------------------+
| FastAPI / Uvicorn |
| (main.py) |
| |
| GET / (form) |
| POST / (issue) |
| POST /create-ca |
| GET /download/... |
+----------+----------------+
|
+------+-------+
| |
v v
+----------+ +-----------+
| /local-ca| | /data |
| CA key | | certs |
| CA cert | | (per CN) |
+----------+ +-----------+
cryptography library
RSA 2048/4096
ECC P-256/P-384/P-521
- Simple web UI for CA operations (templates and static assets included)
- RSA and ECC key support (RSA 2048/4096, P-256, P-384, P-521)
- SAN support for DNS names and IP addresses
- Downloads:
.crt,.key,.pem,.fullchain.crt - Two Docker images: standard (162 MB) and distroless (77 MB)
- Helm chart for Kubernetes with Istio and cert-manager support
- Run locally using the provided
uvwrapper commands
- Python 3.12+
- Docker (optional, for containerized runs)
- The repository uses
uvfor environment and process management.
These commands assume you use the included uv helper for environment management.
- Sync the environment (install/manage virtualenvs and/or tool-specific support):
uv lock --upgrade
uv sync
uv run pytest
uv run pyright
uv run ruff check- Compile dependencies from
pyproject.tomlto a staticrequirements.txt:
uv pip compile pyproject.toml -o requirements.txt- Run the app using uvicorn via the
uvhelper:
export LOCAL_DATA_PATH="./data"
export LOCAL_CA_PATH="/local-ca"
uv run uvicorn main:appBy default the app will bind to the host and port defined by the project (commonly 127.0.0.1:8000 or as configured). Check the logs printed by uvicorn for the exact listen address.
Build the image:
docker build -t caweb .
docker build -f DockerfileDistroless -t caweb:distro .
docker images --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}" | grep "caweb"
caweb latest 162MB
caweb distro 77MBRun interactively (temporary container):
# map port 2000 and mount a local CA directory
docker run --rm -p 2000:2000 -v /local-ca:/local-ca -v /data:/data caweb
docker run --rm -p 2000:2000 -v /local-ca:/local-ca -v /data:/data caweb:distroRun detached (long-running service) with dockerhub image:
docker run --name caweb -d -p 2000:2000 \
-v /local-ca:/local-ca -v /local-ca/data:/data \
--restart unless-stopped wlanboy/caweb:latest- The container expects a host directory mounted at
/local-ca(adjust-von the docker run command if you keep your data elsewhere). - The app listens on port 2000 in the image — change the host port mapping if 2000 is unavailable.
- If the
uvhelper is not available on your shell, you can run the same commands using the proper Python venv and uvicorn directly (for example, activate a virtualenv and runuvicorn main:app). - When editing templates or static files, restart the uvicorn server (or use an autoreload option during development, e.g.
uv run uvicorn main:app --reload). - Check
requirements.txtandpyproject.tomlfor dependency updates. Re-runuv pip compileafter modifyingpyproject.toml.


