---
title: "Announcing Philter 4, the Most Capable Philter Yet"
description: "Philter 4 is out. It is API-only, stores data in SQLite or MongoDB, adds a tamper-evident redaction ledger, and tightens security defaults. See what changed."
url: "https://philterd.ai/blog/announcing-philter-4/"
---

[← All posts](https://philterd.ai/blog/)

# Announcing Philter 4, the Most Capable Philter Yet

By [Jeff Zemerick](https://philterd.ai/authors/jeff-zemerick/) October 26, 2026 [Philter](https://philterd.ai/categories/philter/) · [Redaction](https://philterd.ai/categories/redaction/)

> **Note:** Arbiter is now [Philter Workspace](https://philterd.ai/philter-workspace/).

Philter 4.0.0 is released, and it is the biggest change to [Philter](https://philterd.ai/philter/) since it went into production in 2019. The short version is that Philter is now an API-only service that keeps its own data, records evidence of what it redacted, and refuses to run with the loose defaults that 3.x tolerated. You can pull it today as `philterd/philter:4.0.0`, or download the jar from the [release page](https://github.com/philterd/philter/releases/tag/4.0.0).

I want to be upfront about one thing before getting into the features. Upgrading from 3.x is a migration, not a version bump. Configuration moved, storage moved, every request now needs an API key, and many API responses changed shape. The [upgrade guide](https://philterd.github.io/philter/latest/upgrading.html) recommends treating Philter 4 as a new deployment that runs beside 3.x until your clients work against it, and that is what I would do too. If you would rather not work that out alone, we can [scope the migration with you](https://philterd.ai/consulting/), starting with an inventory of your policies, clients, and settings and ending with a written cutover plan your team can follow.

![Comparison table of Philter 3.x and Philter 4 covering runtime, configuration, storage, authentication, interface, data at rest, and evidence](https://philterd.ai/images/philter-4-what-changed.svg)

The main differences between Philter 3.x and Philter 4. The policy JSON format itself carries over.

## Philter is now API-only

Philter 4 has no user interface. Everything, including creating users, issuing API keys, and changing deployment settings, happens over the API. A separate [Philter UI](https://github.com/philterd/philter-ui) project is in development for people who want one, and it signs in through the same API as any other client would.

Removing the UI was a deliberate choice. A UI that can only use the public API forces every administrative capability to exist in that API, which means the CLI, the [Java SDK](https://philterd.ai/blog/philter-sdk-java-2-0-0/), the MCP server, and your own automation can do everything a person at a screen can. It also keeps Philter nodes stateless, so they scale behind an ordinary load balancer without sticky sessions.

For people who do sign in, Philter 4 can store passwords and exchange them for expiring session keys, with TOTP multi-factor authentication and lockout. That is all off unless you set `PASSWORD_SIGN_IN_ENABLED=true`, so an API-only deployment does not carry a login surface it never uses.

The same design is what lets Philter 4 sit underneath [Philter One](https://philterd.ai/philter-one/), a small office computer we are building that runs Philter and [Arbiter](https://philterd.ai/philter-workspace/) together. People review and approve redactions in Arbiter, which signs them in through Philter’s API, so the box needs no Philter interface of its own.

## Storage without a database server

Philter 3.x had no database. It read policies from a directory, or from S3 or OpenSearch in some releases. Philter 4 stores policies, contexts, users, API keys, ledgers, and the audit log itself, and by default it puts all of that in a single SQLite file, so one instance needs no database server at all.

When you need several instances sharing data, set `STORAGE_TYPE=mongodb`. Moving later is supported too. With Philter stopped, `java -jar philter.jar migrate-storage --to mongodb` copies a SQLite database into an empty MongoDB, verifies the copy, and records the move in the audit log. From 4.0 on, Philter also tracks the version of its data layout and migrates it at startup when a new release needs it, so back up the database before each upgrade.

## An evidence trail for every redaction

The feature I am most glad to ship is the evidence trail. Redaction is one half of the job. The other half, especially in legal, healthcare, and government work, is being able to show later exactly what was removed and under which rules.

![Diagram of the Philter 4 evidence trail: a document is redacted under a recorded policy version, the output can carry a signature, each redaction in a ledger-enabled context becomes a chained and signed ledger entry, legal holds block deletion, and actions go to an exportable audit log](https://philterd.ai/images/philter-4-evidence-trail.svg)

How the pieces of the evidence trail relate. The ledger is enabled per context, and output signing is opt-in.

- **Redaction ledger.** In a context with the ledger enabled, each redacted span becomes a signed entry that includes the hash of the entry before it. Altering or removing an entry from the middle of a chain breaks it, and `GET /api/ledger/{documentId}/valid` reports that. Ledger exports contain the original values, so treat them as sensitive data.
- **Policy versions.** Every redaction is stamped with the name, version, and content hash of the policy that governed it, and that exact revision can be read back through the policy versions API.
- **Output signing.** When enabled, text responses carry an ES256 signature in `X-Philter-Signature` that binds the output to the policy that produced it. Anyone holding the public key from `GET /api/signing-key` can verify it. Binary PDF responses are not signed yet.
- **Legal holds.** A hold blocks deletion of a document’s ledger chain, or of all of a user’s evidence, until it is released. Only the user who placed it or an administrator can release it.
- **Audit log.** Administrative and redaction events are recorded with the actor and a request ID, and the log can be exported as CSV with cursor paging that returns each event once.

None of this makes detection perfect. What it does is give you a verifiable record of what Philter did, which is what you need when someone asks why a particular value was or was not redacted.

## Stricter security defaults

A lot of the 4.0 changelog is security work, and most of it shows up as things Philter now refuses to do. HTTPS is on by default, and the Docker image generates its own certificate on first start instead of shipping one key in every container. `PHILTER_ENCRYPTION_KEY` is required, and Philter encrypts policies, list items, ledger tokens, and queued documents under it. Back that key up, because the data cannot be recovered without it.

API keys are scoped, and the first administrator is created from `PHILTER_BOOTSTRAP_API_KEY`. Mutual TLS is still supported, but a client certificate no longer stands in for an API key. Policies are also checked much more carefully. A policy can no longer point Philter at an arbitrary model endpoint, read files outside the directories an administrator allows, or use environment variables that are not on an allowlist. A policy that Phileas cannot load is refused with a `400` when it is saved, instead of failing every redaction later with a `500`.

## Better detection out of the box

Philter 4 runs on Phileas 4.5, which changes how dates, cities, and driver’s license numbers are detected. The default policy now finds person names with the `ph-eye-pii-en-small` model running inside Philter through ONNX Runtime, so the Docker image redacts names without a separate PhEye service. The image is about 620 MB larger as a result. You can point a filter at other local models, run them on a GPU, or keep calling a PhEye service if you already have one.

PhEye filters now read long texts in overlapping windows, so a name after the model’s 512-word limit is no longer missed. New filters report ITINs, EINs, and Canadian SINs as their own types. If your policies rely on the `ssn` filter to catch values in the EIN form `NN-NNNNNNN`, enable the `ein` filter, because `ssn` no longer reports them.

## Smaller things that will save you time

PDF redaction is asynchronous by default, with signed webhooks that report when a document is done. Append `?async=false` if you want the old behavior. A redacted PDF page now keeps the size of the input page, and `config.pdf.scale` is ignored. `POST /api/reidentify/text` restores every `CRYPTO_REPLACE` value in a whole text, which is useful for an LLM’s response to a prompt you redacted first. Prometheus metrics are served at `/actuator/prometheus`, and integrations with [Phield](https://philterd.ai/phield/) and [Philter Diffuse](https://philterd.ai/philter-diffuse/) are available and off by default.

On the API side, errors are now JSON with a `message` and a `reason` code, listings return an object with a `total` and support sorting and search, and policy edits accept `If-Match` so two people cannot silently overwrite each other. These are breaking changes for existing clients, which is the main reason the upgrade takes planning. The full list is in the [release notes](https://github.com/philterd/philter/releases/tag/4.0.0).

## Upgrading from 3.x

Philter 4 requires Java 25, or you can use the `philterd/philter` image. The [upgrade guide](https://philterd.github.io/philter/latest/upgrading.html) maps each `philter.properties` setting to its environment variable and includes a script to upload a 3.x policy directory through the Policies API. If you call Philter from Java, move to [philter-sdk-java 2.0.0](https://philterd.ai/blog/philter-sdk-java-2-0-0/), which targets the 4.0 API. For other languages, generate a client from the [OpenAPI specification](https://github.com/philterd/philter/blob/main/docs/docs/api_and_sdks/openapi.json), which now matches the actual responses.

Whatever path you take, test your redaction workflows against your own data before retiring 3.x. Detection changed in this release, and you are the only one who can confirm that the output meets your requirements.

## Coming soon to the cloud marketplaces

The Philter listings on the [AWS](https://aws.amazon.com/marketplace/pp/B07YVB8FFT?ref=_ptnr_mf_launch), [Google Cloud](https://console.cloud.google.com/marketplace/product/philterd-public/philter), and [Microsoft Azure](https://azuremarketplace.microsoft.com/en-us/marketplace/apps/philterdllc1687189098111.philter?tab=Overview) marketplaces still deploy Philter 3.x today. Philter 4 images for all three will be available soon, and I will post here when they are live. Until then, the Docker image and the jar are the way to run Philter 4.

If you are planning a move from 3.x and would like help with it, or you want to talk through how the evidence trail fits your review process, [get in touch](https://philterd.ai/consulting/). Migration planning is one of the consulting engagements we offer, and I am happy to look at your setup before you start.

* * *

**Related posts:**

- [philter-sdk-java 2.0.0: Built for Philter 4.0.0](https://philterd.ai/blog/philter-sdk-java-2-0-0/)
- [Redact PII Before Sending It to an LLM](https://philterd.ai/blog/redact-pii-before-sending-to-an-llm/)

## Got a redaction problem that looks like this in your own pipeline?

Spend 30 minutes with Jeff (the engineer behind Philter) and walk away with a clear view of the architecture that fits your stack. No sales pitch.

[← Older post: Introducing Phield: Monitoring How PII Actually Moves Through Your Systems](https://philterd.ai/blog/introducing-phield-pii-drift-monitoring/)

[Newer post →: Philter Desktop 1.2.0 Adds ITIN and SIN Detection and Keep-Last-4 Redaction](https://philterd.ai/blog/philter-desktop-1-2-0-itin-sin-and-new-redaction-strategies/)

[← Back to all posts](https://philterd.ai/blog/)

Questions, ideas, or want to contribute? Join the conversation at [community.philterd.ai](https://philterd.ai/community/). Everything happens in public on GitHub.
