Replace admin/admin credentials with Keycloak OIDC flow, fix Kubernetes deploy section to use create-secrets.sh instead of --set secrets.*, add CI/CD section, and update domain model references (masq→snat, new hosts/params).
Shorefront
A production-ready web application for managing Shorewall firewall configurations.
Stack
- Backend: Python 3.12, FastAPI, SQLAlchemy 2, Alembic, PostgreSQL 15
- Frontend: React 18, TypeScript, Vite, MUI v5, React Router v6, Axios
- Auth: Keycloak (OIDC), JWT session cookie
- Infra: Docker Compose (local dev), Helm + Kubernetes + Traefik (production)
Quick Start (Docker Compose)
# 1. Clone and enter the repo
git clone <repo-url> shorefront && cd shorefront
# 2. Start everything (postgres + backend + frontend)
docker compose up --build
# 3. Open http://localhost
Authentication is handled via Keycloak OIDC. You will be redirected to your Keycloak instance to log in. Your Keycloak user must be a member of the firewall admins group.
Development (without Docker)
Backend:
cd backend
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
# Set environment variables
export DATABASE_URL=postgresql://shorefront:changeme@localhost:5432/shorefront
export JWT_SECRET_KEY=dev-secret
export KEYCLOAK_URL=https://sso.example.com
export KEYCLOAK_REALM=myrealm
export KEYCLOAK_CLIENT_ID=shorefront
export KEYCLOAK_CLIENT_SECRET=<client-secret>
export KEYCLOAK_REDIRECT_URI=http://localhost:8000/auth/oidc/callback
# Run migrations (creates schema + seed data)
alembic upgrade head
# Start the API server
uvicorn app.main:app --reload
# API available at http://localhost:8000
# Interactive docs at http://localhost:8000/docs
Frontend:
cd frontend
npm install
npm run dev
# Vite dev server at http://localhost:5173
# Proxies /api/* → http://localhost:8000
First Steps After Login
- Log in — you will be redirected to Keycloak. Your account must be in the firewall admins group.
- A sample homelab config is pre-loaded with:
- Zones:
fw(firewall),net(ipv4),loc(ipv4) - Interface:
eth0→ zonenet - Policies: loc→net ACCEPT, net→fw DROP, etc.
- SNAT:
192.168.1.0/24viaeth0
- Zones:
- Click homelab to open the Config Detail page.
- Click Generate Config to preview or download the Shorewall files.
- Create your own configs from the Configurations page.
Generating Shorewall Files
On the Config Detail page, click Generate Config:
- Preview: File contents appear in a tabbed modal (zones / interfaces / policy / rules / snat) with copy-to-clipboard buttons.
- Download ZIP: Downloads
<config-name>-shorewall.zipwith all files ready to copy to/etc/shorewall/.
Command-Line Download
Each config has a Download Token — a secret string that allows downloading the generated ZIP without an active session. Useful for automation scripts and CI pipelines.
Finding your token
Open a config in the UI. The Download Token field is shown above the tabs. Click the copy icon to copy it.
Downloading via curl
curl -X POST "https://<host>/api/configs/<config-id>/generate?format=zip" \
-H 'Content-Type: application/json' \
-d '{"token": "<your-download-token>"}' \
-o shorewall.zip
Replace <config-id> with the numeric ID visible in the URL when you open a config (e.g. /configs/1).
Rotating the token
Click the Regenerate button (⟳) next to the token field. The old token is immediately invalidated. Update any scripts that use it.
API Documentation
FastAPI generates interactive docs automatically:
- Swagger UI:
http://localhost:8000/docs - ReDoc:
http://localhost:8000/redoc
Kubernetes Deployment (Helm)
Prerequisites
- Kubernetes cluster with Traefik as the ingress controller
- NFS share accessible at
192.168.17.199:/mnt/user/kubernetesdata/shorefront - Keycloak instance with a
shorefrontclient configured - Images available in the container registry (see CI/CD below)
1. Create Secrets
Helm does not manage the Kubernetes secret. Run this once before the first deploy (and whenever credentials change):
export POSTGRES_PASSWORD=<strong-password>
export JWT_SECRET_KEY=<strong-jwt-secret>
export KEYCLOAK_CLIENT_SECRET=<keycloak-client-secret>
bash scripts/create-secrets.sh
This creates/updates the shorefront-secret Secret in the shorefront namespace.
2. Deploy
helm upgrade --install shorefront ./helm/shorefront \
--namespace shorefront \
--create-namespace
Override values as needed (e.g. ingress host, Keycloak URL) via --set or a custom values file.
3. Verify Rollout
kubectl rollout status deployment/backend -n shorefront
kubectl rollout status deployment/frontend -n shorefront
kubectl get ingress -n shorefront
Storage
PostgreSQL data is persisted to 192.168.17.199:/mnt/user/kubernetesdata/shorefront via a static NFS PersistentVolume. Ensure the NFS export is accessible from all cluster nodes before deploying.
Uninstall
helm uninstall shorefront -n shorefront
# Note: PersistentVolume (Retain policy) and namespace are NOT deleted automatically.
kubectl delete namespace shorefront
kubectl delete pv shorefront-postgres-pv
CI/CD
A Gitea Actions workflow (.gitea/workflows/build-containers-on-demand.yml) automatically builds and pushes images when helm/shorefront/values.yaml, frontend/Dockerfile, or backend/Dockerfile change.
- Image tag is read from
containers.versioninvalues.yaml - Images are pushed to
git.baumann.gr/adebaumann/shorefront-{frontend,backend}:<version> - Requires a
REGISTRY_TOKENsecret configured in Gitea
To release a new version: bump containers.version in values.yaml and push. The workflow builds and pushes both images. Then run helm upgrade to deploy.
Project Structure
shorefront/
├── backend/
│ ├── Dockerfile
│ ├── requirements.txt
│ ├── alembic/ # DB migrations
│ └── app/
│ ├── main.py # FastAPI app
│ ├── models.py # SQLAlchemy ORM models
│ ├── schemas.py # Pydantic schemas
│ ├── auth.py # JWT + OIDC auth
│ ├── shorewall_generator.py
│ └── api/ # Route handlers
│ ├── auth.py # OIDC login/callback/logout
│ ├── configs.py # Config CRUD + generate
│ ├── zones.py
│ ├── interfaces.py
│ ├── policies.py
│ ├── rules.py
│ ├── snat.py
│ ├── hosts.py
│ └── params.py
├── frontend/
│ ├── Dockerfile
│ ├── nginx.conf
│ └── src/
│ ├── api.ts # Axios API client
│ ├── store/auth.ts # Auth state
│ ├── routes/ # Page components
│ └── components/ # Shared UI components
├── helm/shorefront/ # Kubernetes Helm chart
├── scripts/
│ └── create-secrets.sh # Creates k8s Secret before deploy
├── docker-compose.yml
└── README.md