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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ follow [Semantic Versioning](https://semver.org/) from the first tagged release.
- CISA secure-by-design mapping in `docs/assurance.md`, including why monitor mode is the default.

### Changed
- README: v0.1.0 status, install section (container and release archive), a "What it does not do" section, governance and citation links. `docs/releasing.md` describes the signed-tag, pull-request release flow.
- The startup message that says monitor mode does not block is now a warning, so it shows at `-log-level warn`.
- `SECURITY.md` supported-versions table; `docs/releasing.md` states that breaking changes may land in a minor release below 1.0.

Expand Down
54 changes: 48 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,29 @@ what Log4j would see in each request, and blocks exploit attempts before they
reach the host. It is a **compensating control**, not a fix: patch, remove
`JndiLookup`, or retire the host as soon as you can.

> **Status: pre-release.** The inspection engine and the proxy (HTTP/1.1, HTTPS and HTTP/2,
> metrics, health checks, configuration) are heavily tested, and the detection corpus has
> been validated in a lab against real Log4j 2.14.1 (107 of 107 JNDI attempts caught, 0
> misses, 0 false positives; see [the lab report](docs/lab-report.md)). There is no tagged
> release yet, so pin a commit and test in monitor mode before relying on it. See the
> [roadmap](docs/ROADMAP.md).
> **Status: v0.1.0, first stable release.** The inspection engine and the proxy
> (HTTP/1.1, HTTPS and HTTP/2, metrics, health checks, configuration) are heavily
> tested, and the detection corpus was validated in a lab against real Log4j 2.14.1
> (107 of 107 JNDI attempts caught, 0 misses, 0 false positives; see
> [the lab report](docs/lab-report.md)). Releases are signed, reproducible and
> carry build provenance and an SBOM ([verify them](docs/releasing.md)). Below 1.0
> the public surface may still change in a minor release, always noted in the
> [changelog](CHANGELOG.md). Start in monitor mode before relying on it.

## What it does not do

Read this before deploying. LogShield is a compensating control for one attack
class, not a substitute for patching.

- It protects only traffic that **crosses the proxy**. Other ports, other
protocols (syslog, SMTP, LDAP, message queues) and internal pivots need network
segmentation.
- It cannot see **second-order injection**: data stored earlier and logged later
by another component.
- Any signature-style control can miss an **encoding it does not model**. The
[threat model](docs/threat-model.md) lists the known gaps.
- A fresh install is in **monitor mode**: it records and counts, it does not
block, until you switch to `-mode block` ([why](docs/assurance.md#cisa-secure-by-design)).

## Why a proxy, and why not just a regex

Expand All @@ -44,6 +61,25 @@ multipart parts, and Basic or Bearer credentials. LogShield therefore:

The proxy then guarantees that **what it forwards is exactly what it inspected**.

## Install

Pick one. Every release is signed and attested; the
[verification commands](docs/releasing.md#verifying-a-download) take a minute.

```sh
# Container: distroless, non-root, multi-arch. Pin the digest in production.
docker run --rm -p 8080:8080 \
-e LOGSHIELD_UPSTREAM=http://192.0.2.10:8081 \
ghcr.io/turlafsb/logshield:v0.1.0

# Static binary (Linux, macOS, Windows; amd64 and arm64): download from the
# Releases page, then
tar xzf logshield_v0.1.0_linux_amd64.tar.gz
./logshield_v0.1.0_linux_amd64/logshield -version
```

Or build from source (Go 1.24 or newer), as below.

## Quick start

```sh
Expand Down Expand Up @@ -205,6 +241,7 @@ test against systems you do not own or have written authorization to test.
| Load and latency report | [docs/load-report.md](docs/load-report.md) |
| Metrics, health checks, overload, Prometheus and Sigma rules | [docs/observability.md](docs/observability.md) |
| Roadmap and changelog | [docs/ROADMAP.md](docs/ROADMAP.md), [CHANGELOG.md](CHANGELOG.md) |
| Project governance, security policy, support | [GOVERNANCE.md](GOVERNANCE.md), [SECURITY.md](SECURITY.md), [SUPPORT.md](SUPPORT.md) |

## Development

Expand All @@ -223,6 +260,11 @@ make vuln # govulncheck

See [CONTRIBUTING.md](CONTRIBUTING.md), the [Code of Conduct](CODE_OF_CONDUCT.md) and [GOVERNANCE.md](GOVERNANCE.md).

## Citing

If you use LogShield in research, cite it with the metadata in
[CITATION.cff](CITATION.cff) (GitHub shows a "Cite this repository" button).

## Security

To report a vulnerability, use GitHub private vulnerability reporting as
Expand Down
6 changes: 3 additions & 3 deletions docs/releasing.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ rather than by tag.

## Cutting a release (maintainers)

1. `main` is green. Run `scripts/repo-settings.sh --protect` once, before the first release, so `main` requires pull requests and passing checks.
2. Move the `[Unreleased]` entries in `CHANGELOG.md` under a new `## [x.y.z] - date` heading.
3. Tag the merge commit and push the tag: `git tag -a vX.Y.Z -m vX.Y.Z && git push origin vX.Y.Z`. Use a suffix such as `-rc.1` for a pre-release (no `latest` image tag, marked as a pre-release).
1. `main` is green and protected: every change, including the release notes, goes through a pull request (`scripts/repo-settings.sh --protect` recreates the ruleset).
2. In a pull request, move the `[Unreleased]` entries in `CHANGELOG.md` under a new `## [x.y.z] - date` heading, and squash-merge it. GitHub signs the merge commit.
3. Pull `main`, then create a **signed** tag on that merge commit and push it: `git tag -s vX.Y.Z -m vX.Y.Z && git push origin vX.Y.Z`. Use a suffix such as `-rc.1` for a pre-release (no `latest` image tag, marked as a pre-release). The workflow refuses tags that are not on `main`.
4. The workflow tests, builds, signs, attests, pushes the image and creates the GitHub release. If anything fails nothing is published half-way: re-run the workflow, or delete the tag and the draft artifacts and start again.
5. Verify the release with the commands above before announcing it.
Loading