Repository navigation
Releases: Anonify-v2-0/Anonify2.0
Release list
Anonify v1.19.0
Added
- The Helm chart is published to Docker Hub next to the image, so
helm install anonify oci://registry-1.docker.io/nabeelwasif/anonify --version <version>
installs a release without downloading the chart first. It is still attached
to every GitHub release as well (#246)
Changed
- Progress streams send a keep-alive comment after 15 quiet seconds, so a
proxy or load balancer that closes idle connections after a minute (the AWS
ALB's default, Fly's proxy, ingress-nginx) no longer cuts them while a long
step runs. No setting needs raising for that any more (#244) - A PDF export of 64 MiB or more is rebuilt by pdf-lib on a thread of its own,
so the rebuild no longer pauses the server's other requests and health
probes (by up to 160ms on a 361-page scan). The exported file is the same as
before, andANONIFY_RENDER_THREADS=offkeeps it on the main thread (#245)
Fixed
- An export a killed worker left behind (a background export or a batch
export) is started again by the sweep afterANONIFY_STUCK_RUN_MINUTES, as
document processing already was. Before, it sat at "running" for about four
hours. After two restarts it fails with a message saying to start it again.
Adds a migration (#243)
Full Changelog: v1.18.0...v1.19.0
Docker
docker pull nabeelwasif/anonify2.0:1.19.0linux/amd64 and linux/arm64, index digest sha256:72ff19b3233dd55cb42d28b158eccb141bdc71f140279ff4cf874f5df520d198. To check it was built here, from this release:
gh attestation verify oci://docker.io/nabeelwasif/anonify2.0:1.19.0 --repo Anonify-v2-0/Anonify2.0To run this release with Compose, without cloning anything:
curl -LO https://github.com/Anonify-v2-0/Anonify2.0/releases/download/v1.19.0/docker-compose.yml
[ -e .env ] || docker run --rm nabeelwasif/anonify2.0:1.19.0 keys > .env
echo "ANONIFY_VERSION=1.19.0" >> .env
docker compose up -dAnonify v1.18.0
Added
- A Helm chart for Kubernetes, attached to every release
(releases/latest/download/anonify-chart.tgz): separate web and worker
deployments, migrations before every install and upgrade, health probes, a
graceful drain on rollouts, pods that pass therestrictedPod Security
Standard, and worker autoscaling on queue depth with KEDA, including scale to
zero. Seedeploy/helm/anonify/README.md(#191)
Changed
- Heavy PDF work runs on background threads, so the app stays responsive while
documents process, even on a single container: drawing pages for OCR, the
vision pass and export no longer stalls requests and health checks (event-loop
delay at the 99th percentile went from 680ms to 23ms while exporting a scan).
A page that takes longer thanANONIFY_RENDER_TIMEOUT_MS(two minutes) to draw
now fails its document as too complex instead of holding up the whole server.
ANONIFY_RENDER_THREADS=offdraws pages on the main thread as before (#194)
Fixed
- A document whose worker was killed after its file had been read in (a
SIGKILL, an out-of-memory kill, a node lost) is processed again once the
sweep recovers it. Recovery queued it again, but nothing started it, so it sat
at "queued" until it expired (#190) - Docker builds and
pnpm ocr:warmstop OCR workers as soon as warming finishes,
avoiding an extra five-minute wait before exiting.
Security
- Next.js receives security patches for cache poisoning, information disclosure,
and server-side request forgery. (#249)
Full Changelog: v1.17.0...v1.18.0
Docker
docker pull nabeelwasif/anonify2.0:1.18.0linux/amd64 and linux/arm64, index digest sha256:8d5f8759ac57c7f3c01cc8fac60a32039422b9ce4b2cc67c362dc1e19869f4ca. To check it was built here, from this release:
gh attestation verify oci://docker.io/nabeelwasif/anonify2.0:1.18.0 --repo Anonify-v2-0/Anonify2.0To run this release with Compose, without cloning anything:
curl -LO https://github.com/Anonify-v2-0/Anonify2.0/releases/download/v1.18.0/docker-compose.yml
[ -e .env ] || docker run --rm nabeelwasif/anonify2.0:1.18.0 keys > .env
echo "ANONIFY_VERSION=1.18.0" >> .env
docker compose up -dAnonify v1.17.0
Added
- Containers shut down gracefully: on
SIGTERMreadiness drops first, the
worker stops taking jobs and finishes the steps it is running, progress
streams hand their clients to another replica, and then the process exits,
withinANONIFY_DRAIN_SECONDS(120). The image setsNEXT_MANUAL_SIG_HANDLE
for this, and Compose now gives the app a 130sstop_grace_period; on other
platforms raise the grace period to match (docs/workflow.md). Documents left
behind by a crashed or killed worker are picked up again by the sweep after
ANONIFY_STUCK_RUN_MINUTES(20) instead of about four hours, and fail with
the retryableworker-lostcode if that happens three times (#182) - Worker containers run the sweep themselves (expiry, restarting lost runs and
starting documents stuck in the queue) every five minutes, with one replica
leading at a time, so a self-hosted install no longer needs a separate
scheduler container, cron job or sharedCRON_SECRET.ANONIFY_SCHEDULER=off
andANONIFY_SCHEDULER_INTERVAL_SECONDScontrol it./api/cron/cleanupand
anonify cleanupkeep working and share its lock (#183) - Install with Docker without cloning the repository: each release attaches its
docker-compose.yml, which now runs the publishednabeelwasif/anonify2.0
image (pin it withANONIFY_VERSION), anddocker run nabeelwasif/anonify2.0 keysprints the secrets a.envneeds. Upgrading is
docker compose pull && docker compose up -d. From a clone,
docker compose up -dnow runs the published image too: add--buildto
run your checkout (#186) - Optional Prometheus metrics at
/api/metrics(ANONIFY_METRICS=on, behind
ANONIFY_METRICS_TOKENor served only to direct peers on a private network),
including the job queue's depth for autoscaling workers, step durations and
retries, CPU slots, provider calls and the database pool, with the
equivalent KEDA query in docs/operations.md. Setting
OTEL_EXPORTER_OTLP_ENDPOINTexports traces for requests and workflow steps.
No document data appears in any metric, and error messages and URL query
strings are removed from every span (#188)
Changed
- Each container bounds the CPU-heavy work it runs at once
(ANONIFY_CPU_CONCURRENCY) and the jobs it takes
(WORKFLOW_POSTGRES_WORKER_CONCURRENCY), both defaulting from the CPUs it may
use, its CPU quota included, where the job count used to be 10 on any machine.
The streaming memory budget is now per container and divided by its job count.
AnANONIFY_STREAM_MEMORY_BUDGETyou set yourself can be refused at start on
a machine with many CPUs, with a message saying what to change.
ANONIFY_PROCESSING_GLOBAL_MAXoptionally caps documents processing across
all owners, handing freed slots to whoever has waited longest (#181) - Exports run in the background on a worker and show their progress: closing
the export dialog no longer loses an export in progress, a server restart
picks it up again, and large PDFs export with less memory. A tokenized or
encrypted copy's vault is sealed to the browser that asked for it and handed
over once, so Anonify still cannot reverse an encrypted export. Opening a vault
needs the page served over HTTPS or from localhost (#187) - Scanned documents are read about twice as fast: OCR workers are kept warm and
shared across documents (at most one per CPU, stopped after
ANONIFY_OCR_IDLE_SECONDSidle), a document's pages are drawn while earlier
ones are being read, and pages reach Tesseract without a PNG round trip. The
words and boxes read are unchanged.ANONIFY_OCR_RENDER_SCALEsets the scale
scans are drawn at (2, as before) (#189)
Deprecated
- The Compose
schedulerservice (--profile scheduler), which is no longer
needed now that the app sweeps on its own timer. It still works, warns when
it starts, and is removed in 1.18.0 (#183) POST /api/documents/:id/exportwithoutPrefer: respond-async, for scripts
that export through the API: the synchronous answer is removed in 1.18.0. Send
the header and arecipientKey, then follow the export (docs/api.md). Until
then it answers as before, with aDeprecationheader (#187)
Fixed
- A document whose upload landed just as a sweep ran could be started twice,
the second run working on a document that was not its own and logging
internal-statefailures once the first had finished. Admission now claims
a document before starting its run (#183)
Full Changelog: v1.16.2...v1.17.0
Docker
docker pull nabeelwasif/anonify2.0:1.17.0linux/amd64 and linux/arm64, index digest sha256:a772511ce703c165fff87c7d613b08cb56667a04923015594b78eea09e386d9d. To check it was built here, from this release:
gh attestation verify oci://docker.io/nabeelwasif/anonify2.0:1.17.0 --repo Anonify-v2-0/Anonify2.0To run this release with Compose, without cloning anything:
curl -LO https://github.com/Anonify-v2-0/Anonify2.0/releases/download/v1.17.0/docker-compose.yml
[ -e .env ] || docker run --rm nabeelwasif/anonify2.0:1.17.0 keys > .env
echo "ANONIFY_VERSION=1.17.0" >> .env
docker compose up -dAnonify v1.16.2
Fixed
- The Docker Hub image is published for this release. v1.16.1 announced it,
but its image build failed and nothing was pushed (#180)
Full Changelog: v1.16.1...v1.16.2
Docker
docker pull nabeelwasif/anonify2.0:1.16.2linux/amd64 and linux/arm64, index digest sha256:21e7ea2516c66eeb701febb0bb242980c55752b6d5fbd6ab2e97880602f6ab1c. To check it was built here, from this release:
gh attestation verify oci://docker.io/nabeelwasif/anonify2.0:1.16.2 --repo Anonify-v2-0/Anonify2.0Anonify v1.16.1
Added
- Every release is published to Docker Hub as
nabeelwasif/anonify2.0for
amd64 and arm64, with build provenance, an SBOM and a GitHub attestation. Set
ANONIFY_IMAGE=nabeelwasif/anonify2.0:<version>in.envand pull it instead
of building from source (#180)
Full Changelog: v1.16.0...v1.16.1
Anonify v1.16.0
Added
ANONIFY_SERVICE_LIMIT_SCOPE=clustermakes the AI and OCR rate and concurrency
limits apply to the whole deployment rather than to each container, with the
shared state in Postgres (one new table,ServiceLease) or, optionally, Redis or
Valkey (ANONIFY_RATE_STORE=redis,REDIS_URL), which also takes over the
inbound rate limiter. If Redis is unreachable, documents keep processing on
per-container limits and/api/readyreports it asdegradedinstead of failing (#184)
Changed
- Uploads through the app are streamed to storage instead of held in memory, so
large files no longer need a large web container. Direct-to-bucket uploads are
documented for each storage provider and recommended in production: when a
bucket's CORS rule would refuse the browser,/api/readyreports
presigned-corsasdegradedwith what is missing, and the upload falls back
through the app with a warning in the log instead of failing (#185)
Deprecated
POST /api/upload/localwith a multipart body, for scripts that upload through
the API.PUTthe file as the request body instead, with?documentId=and a
Content-Length(docs/api.md). The multipart form answers with a
Deprecationheader until it is removed in 1.17.0 (#185)
Full Changelog: v1.15.0...v1.16.0
Anonify v1.15.0
Added
- Azure Blob Storage is a supported storage backend (
STORAGE_DRIVER=azure-blob), with managed identity, account keys or a connection string, and direct browser uploads. Every upload is now also refused at ingest if its stored size is not the size it was reserved with (#176) ANONIFY_ROLEruns a container asweb(serves the app),worker(processes documents) orall(the default, as before), so serving and processing can be scaled separately.docker-compose.split.ymlruns one web container and two workers (#179)
Changed
- Scanned and image-heavy PDFs finish analysis sooner: the vision pass sends up to
ANONIFY_AI_CONCURRENCYpages to the model at once instead of one at a time, and holds fewer page images in memory while it does (#173) - Exporting a redacted PDF is about three times faster, and a document whose pages share a font or an image no longer copies it once per page, so long documents export much smaller (a 50-page test document went from 33.7 MB to 2.6 MB) (#174)
- The app image runs its own migrations (
docker run IMAGE migrate, safe on every deploy and from several replicas at once) and the expiry sweep (docker run IMAGE cleanup), so Compose builds one image instead of two. The image now has ananonifyentrypoint; a command override such asnode server.jsstill works (#175) - The document list and the batch page stop checking for updates while their tab is in the background, and check once when you come back to it. When nothing has changed, the server answers without sending the list again (#177)
- The container image includes the default OCR model, so scanned documents are read without internet access; runs under an init process; supports a read-only root filesystem with only
/tmpand/datawritable; is built on a digest-pinned base; and reports its build in/api/healthand the startup log (#178)
Security
- Outside Vercel, the internal workflow routes (
/.well-known/workflow/v1/flowand/step) only accept deliveries from the instance's own job runner. Before, anyone who could reach the app's port could post a well-formed delivery to them (#179)
Full Changelog: v1.14.5...v1.15.0
Anonify v1.14.5
Security
- Dependencies updated to patched releases for 29 of the 30 advisories
pnpm auditreported, among them proxy-addr (critical), undici, sharp, brace-expansion, http-cache-semantics and the MCP TypeScript SDK. The one left, braces, has no patched release yet, and is reached only by developer tooling (#222)
Full Changelog: v1.14.4...v1.14.5
Anonify v1.14.4
Added
- Health endpoints for orchestrators:
/api/health(liveness, no I/O) and/api/ready(database, storage and workflow worker readiness, 503 naming what failed). The container healthcheck uses/api/health, and the Composeappservice waits on/api/ready(#167) DATABASE_POOL_MAXandDATABASE_POOL_IDLE_TIMEOUT_MSsize the app's Postgres pool, malformed pool settings (including the workflow world's) stop the server at start instead of being ignored, anddocs/deploy/database.mdexplains the connection budget and how to put a connection pooler in front of the app while the job queue connects directly (#169)
Changed
- Rate limiting takes one database statement per request instead of a transaction of three, and the processing queue is indexed, so a busy instance spends less time in Postgres. A database migration adds the index (#171)
Fixed
ANONIFY_PUBLIC_URLis read when a page is served, not when the image is built, so link previews use your address without rebuilding, and a malformed value stops the server at start (#168)- The expiry sweep clears its whole backlog on each run, within a time budget (
ANONIFY_CLEANUP_BUDGET_MS), instead of stopping at 50 documents, so a once-a-day cron (Vercel Hobby) no longer leaves expired documents behind. It purges several documents at once and deletes each one's objects in a single request on S3 and Vercel Blob, and overlapping sweeps now skip instead of racing (#170)
Full Changelog: v1.14.3...v1.14.4
Anonify v1.14.3
Fixed
- The second-opinion check on uncertain pattern matches now knows what each category means, as the main detection already does. It had been throwing out real customer numbers, addresses and dates of birth as mere references, places and dates, three labelled values in four in the benchmark (#214)
Full Changelog: v1.14.2...v1.14.3