Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Changelog

All notable changes to Guard Proxy are documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
Python distributions use the [PEP 440](https://peps.python.org/pep-0440/)
spelling of the same version (e.g. `0.1.0b2` for `0.1.0-beta.2`).

## [0.1.0-beta.2] - 2026-07-21

### Added

- Per-policy DDoS protection: configurable request rate limiting and
concurrent-connection throttling applied at the HAProxy edge (#274).
- Config-only automatic IP banning for DDoS policies: repeat offenders are
tracked and denied for a configurable duration, evaluated before the
rate/connection deny rules.

### Changed

- The `/health` probe now reports the installed package version via
`importlib.metadata` instead of a hardcoded string, giving the backend a
single source of truth for its version.

## [0.1.0-beta.1] - 2026-07-21

### Added

- Image-only Compose release kit under `release/` (manifest, `.env` template,
HAProxy reference config, install/upgrade guide) for running published
images without the source tree.
- Publish workflow now tags beta images on the mutable `beta` channel and
attaches the release-kit archive to a GitHub prerelease.

### Fixed

- The release-kit Compose stack uses its own project name to avoid clashing
with a local development stack.

## [0.1.0-alpha] - 2026-07-07

### Added

- Initial alpha of the Guard Proxy WAF admin platform: HAProxy + Coraza data
plane with a FastAPI admin API and a React frontend.
- Management of virtual hosts, security policies, rule overrides, rule
exclusions, and custom rules, plus runtime config generation and apply.
- Coraza audit-log ingestion via the log-shipper sidecar.

[0.1.0-beta.2]: https://github.com/bihius/guard-proxy/compare/v0.1.0-beta.1...v0.1.0-beta.2
[0.1.0-beta.1]: https://github.com/bihius/guard-proxy/compare/v0.1.0-alpha...v0.1.0-beta.1
[0.1.0-alpha]: https://github.com/bihius/guard-proxy/releases/tag/v0.1.0-alpha
4 changes: 2 additions & 2 deletions release/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
# Replace every placeholder value below — these are NOT safe defaults.

# Image to pull. GUARD_PROXY_IMAGE_TAG must match a published release tag,
# e.g. v0.1.0-beta.1. GUARD_PROXY_IMAGE_REPO only needs to change if you are
# e.g. v0.1.0-beta.2. GUARD_PROXY_IMAGE_REPO only needs to change if you are
# pulling from a fork or a private mirror.
GUARD_PROXY_IMAGE_REPO=ghcr.io/bihius
GUARD_PROXY_IMAGE_TAG=v0.1.0-beta.1
GUARD_PROXY_IMAGE_TAG=v0.1.0-beta.2

POSTGRES_USER=guard_proxy
POSTGRES_PASSWORD=change-me-generate-a-strong-password
Expand Down
4 changes: 2 additions & 2 deletions release/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ between beta releases yet — back up `pgdata` before upgrading. See

## 1. Get the release kit

Download and extract the `guard-proxy-release-v0.1.0-beta.1.tar.gz` asset
Download and extract the `guard-proxy-release-v0.1.0-beta.2.tar.gz` asset
from the [GitHub Releases page](https://github.com/bihius/guard-proxy/releases),
or copy this `release/` directory if you already have the repository
checked out. You should end up with:
Expand All @@ -45,7 +45,7 @@ cp .env.example .env
Edit `.env` and replace every `change-me` placeholder:

- `GUARD_PROXY_IMAGE_TAG` — pin this to the release you're installing,
e.g. `v0.1.0-beta.1`. Do not use a mutable tag like `beta` for anything
e.g. `v0.1.0-beta.2`. Do not use a mutable tag like `beta` for anything
you want to reproduce later.
- `POSTGRES_PASSWORD`, `JWT_SECRET_KEY`, `LOG_INGEST_SHARED_SECRET` —
generate real secrets, e.g. `openssl rand -hex 32`.
Expand Down
10 changes: 5 additions & 5 deletions release/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ name: guard-proxy-release
#
# This file pulls prebuilt images from GHCR instead of building from
# source. Set GUARD_PROXY_IMAGE_TAG (see .env.example) to the release
# you want to run, e.g. v0.1.0-beta.1.
# you want to run, e.g. v0.1.0-beta.2.

services:
postgres:
Expand All @@ -26,7 +26,7 @@ services:
- gp_internal

backend:
image: ${GUARD_PROXY_IMAGE_REPO:-ghcr.io/bihius}/guard-proxy-backend:${GUARD_PROXY_IMAGE_TAG:?set GUARD_PROXY_IMAGE_TAG in .env, e.g. v0.1.0-beta.1}
image: ${GUARD_PROXY_IMAGE_REPO:-ghcr.io/bihius}/guard-proxy-backend:${GUARD_PROXY_IMAGE_TAG:?set GUARD_PROXY_IMAGE_TAG in .env, e.g. v0.1.0-beta.2}
restart: unless-stopped
env_file:
- .env
Expand Down Expand Up @@ -55,7 +55,7 @@ services:
- gp_internal

frontend:
image: ${GUARD_PROXY_IMAGE_REPO:-ghcr.io/bihius}/guard-proxy-frontend:${GUARD_PROXY_IMAGE_TAG:?set GUARD_PROXY_IMAGE_TAG in .env, e.g. v0.1.0-beta.1}
image: ${GUARD_PROXY_IMAGE_REPO:-ghcr.io/bihius}/guard-proxy-frontend:${GUARD_PROXY_IMAGE_TAG:?set GUARD_PROXY_IMAGE_TAG in .env, e.g. v0.1.0-beta.2}
restart: unless-stopped
environment:
# Explicit base URL is optional. If unset, the frontend uses relative
Expand All @@ -77,7 +77,7 @@ services:
- gp_internal

coraza:
image: ${GUARD_PROXY_IMAGE_REPO:-ghcr.io/bihius}/guard-proxy-coraza:${GUARD_PROXY_IMAGE_TAG:?set GUARD_PROXY_IMAGE_TAG in .env, e.g. v0.1.0-beta.1}
image: ${GUARD_PROXY_IMAGE_REPO:-ghcr.io/bihius}/guard-proxy-coraza:${GUARD_PROXY_IMAGE_TAG:?set GUARD_PROXY_IMAGE_TAG in .env, e.g. v0.1.0-beta.2}
restart: unless-stopped
depends_on:
backend:
Expand All @@ -95,7 +95,7 @@ services:
- gp_internal

log-shipper:
image: ${GUARD_PROXY_IMAGE_REPO:-ghcr.io/bihius}/guard-proxy-log-shipper:${GUARD_PROXY_IMAGE_TAG:?set GUARD_PROXY_IMAGE_TAG in .env, e.g. v0.1.0-beta.1}
image: ${GUARD_PROXY_IMAGE_REPO:-ghcr.io/bihius}/guard-proxy-log-shipper:${GUARD_PROXY_IMAGE_TAG:?set GUARD_PROXY_IMAGE_TAG in .env, e.g. v0.1.0-beta.2}
restart: unless-stopped
env_file:
- .env
Expand Down
21 changes: 19 additions & 2 deletions src/backend/app/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
import os
from collections.abc import AsyncIterator
from contextlib import asynccontextmanager
from importlib.metadata import PackageNotFoundError
from importlib.metadata import version as _package_version
from pathlib import Path

from fastapi import Depends, FastAPI
Expand Down Expand Up @@ -39,6 +41,21 @@
logger = logging.getLogger(__name__)


def _resolve_app_version() -> str:
"""Return the installed package version, the single source of truth.

Falls back gracefully when the app runs from a source tree that has not
been installed as a distribution (e.g. some local dev setups).
"""
try:
return _package_version("guard-proxy-backend")
except PackageNotFoundError: # pragma: no cover - dev-only fallback
return "0.0.0+unknown"


APP_VERSION = _resolve_app_version()


class _HealthcheckAccessFilter(logging.Filter):
def filter(self, record: logging.LogRecord) -> bool:
args = record.args
Expand Down Expand Up @@ -101,7 +118,7 @@ def _seed_runtime_config() -> None:

app = FastAPI(
title=settings.app_name,
version="0.1.0",
version=APP_VERSION,
lifespan=lifespan,
)

Expand Down Expand Up @@ -134,7 +151,7 @@ def health_check() -> dict[str, str]:
"""Liveness probe — always returns 200 if the process is running."""
return {
"status": "healthy",
"version": "0.1.0",
"version": APP_VERSION,
}


Expand Down
2 changes: 1 addition & 1 deletion src/backend/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "guard-proxy-backend"
version = "0.1.0b1"
version = "0.1.0b2"
description = "Guard Proxy — admin panel REST API"
requires-python = ">=3.13"
dependencies = [
Expand Down
2 changes: 1 addition & 1 deletion src/backend/uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/frontend/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "guard-proxy-frontend",
"private": true,
"version": "0.1.0-beta.1",
"version": "0.1.0-beta.2",
"type": "module",
"packageManager": "pnpm@10.30.0",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion src/log-shipper/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "guard-proxy-log-shipper"
version = "0.1.0b1"
version = "0.1.0b2"
description = "Guard Proxy — Coraza audit log to ingest endpoint sidecar"
requires-python = ">=3.13"
dependencies = [] # runtime: stdlib only
Expand Down
2 changes: 1 addition & 1 deletion src/log-shipper/uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading