Repository navigation
Upgrading
What each upgrade asks of someone already running Anonify. The authoritative per-release notes are in CHANGELOG.md and summarised in Release History.
git pull
pnpm install
pnpm db:migrate:deploy # safe to run every time; a no-op when nothing is pending
pnpm build # or: docker compose up -d --build --waitWith Docker Compose, docker compose up -d --build is enough: the migrate service applies migrations (and the workflow schema) before the app starts. On Vercel, run pnpm db:migrate:deploy from your machine against production before deploying.
Never change ENCRYPTION_KEY during an upgrade. It would make every stored document permanently unreadable. pnpm setup offers to keep it.
| Release | Migration | What it adds |
|---|---|---|
| ≤ 1.0.0 |
db_init, add_settings, add_document_error_code, add_export_report, add_batches, add_document_preset, add_format_quotas, add_batch_exports, add_attachment_provenance, add_redaction_method, add_export_variant, add_export_vault
|
the base schema, settings, failure codes, export reports, batches, presets, per-format quotas, batch-export runs, attachment provenance, methods, variants, batch vaults |
| 1.6.0 | add_encryption_format |
Document.encryptionFormat (v0 / v1) |
| 1.7.0 | add_normalized_index |
Document.normalizedIndex (page offsets) |
| 1.9.0 |
add_pattern_rules, add_assistant_quota
|
RegEx / match-case / whole-word / enabled on rules, OwnerRule, UsageRecord.assistantTokens
|
Documents stored before a migration keep working. A v0 document stays v0 until it expires, and a model without a page index is read whole. Nothing is backfilled.
- The batch download defaults to original format: one upload comes back as that file (e.g.
inbox-redacted.mbox), not a zip. Scripts callingGET /api/batches/:id/downloadthat expect a zip should passoutput=processedoroutput=both, or checkcontent-type. - The archive is no longer flat (folders by upload, message number and part path; reports under
reports/).
- Run the migration.
- A batch or global rule that matches too much of a newly processed document now fails that document with
rule-too-broad. It is retryable, and the document still opens for review. - New rate-limit bucket
search(ANONIFY_RATE_LIMIT_SEARCH), and a new quotaANONIFY_QUOTA_ASSISTANT_TOKENS(300,000 ondemo, unlimited onself-hosted). Set it explicitly on a shared instance. - The session cookie now renews on upload and on rule changes.
- If you built standalone on a machine with local storage and copied
.next/standaloneelsewhere, delete that copy's.anonify-storage(it also contained.env). See Deployment §4. - Set
ANONIFY_PUBLIC_URLfor correct link previews, then rebuild the image.
- Run the migration (the image does it).
- Memory needs drop sharply; revisit any container memory limits you raised for large files.
- Run the migration before starting.
- New documents are sealed in chunks, and existing ones stay readable. New optional settings:
ANONIFY_ENCRYPTION_CHUNK_SIZE,ANONIFY_STREAM_MEMORY_BUDGET. The app refuses to start if the budget cannot give every concurrent document two chunks. LowerANONIFY_BATCH_PROCESSINGor raise the budget.
- Re-upload PDFs that were analysed before 1.5.0 if you want tight redaction boxes. Their boxes cover whole text runs as a fallback (GHSA-h3hv-rpqw-7p84).
- Next.js moved to 16.3.6 and patched transitive dependencies were pinned; run
pnpm install.
The local stack replaced the archived MinIO Community Edition with RustFS. Compose mounts your existing anonify_minio-data volume, and RustFS imports MinIO's unencrypted on-disk format in place, one way. After RustFS writes to it, MinIO can no longer read it.
-
Stop the stack:
docker compose down -
Back up the volume:
docker run --rm \ -v anonify_minio-data:/source:ro \ -v "${PWD}:/backup" \ alpine:3.22.1 \ sh -c "cd /source && tar czf /backup/anonify-object-storage-before-rustfs.tgz ."
-
Rename host-port overrides in
.env:MINIO_PORT→RUSTFS_PORT,MINIO_CONSOLE_PORT→RUSTFS_CONSOLE_PORT. The application'sS3_*settings keep their names and values. -
Start and check:
docker compose up -d --build --wait pnpm smoke:storage http://127.0.0.1:9000 docker compose logs --no-color rustfs rustfs-init app
Rollback means restoring the pre-migration backup and the previous application version together.
If you enabled MinIO server-side encryption (SSE-S3/KMS/C), tiering or custom bucket features, do not use the in-place path. Run the old server on a private endpoint, start RustFS on an empty volume, and copy through the S3 API:
rclone copy legacy:anonify rustfs:anonify --checksum --progress
rclone check legacy:anonify rustfs:anonify --checksum(Anonify's own envelope encryption is unaffected: to the S3 server it is opaque bytes.) Full guide: docs/migrate-object-storage-to-rustfs.md.
Existing Gateway configurations keep working with no change. To switch provider, run pnpm setup or pnpm ai verify. A non-Gateway provider needs AI_MODEL and the AI_MODEL_CAPABILITIES declaration those commands write.
Anonify: AI proposes, the application applies, and only what a person accepted is removed.
Repository · Report a bug · Request a feature · Security policy · Apache-2.0
This wiki describes v1.10.0 and summarises and links the in-repo documentation. Where the two disagree, the files under docs/, CHANGELOG.md and SECURITY.md are canonical.
Getting going
Using it
- Supported Formats
- Review Workspace
- Search and Rules
- Hush Assistant
- Redaction Presets
- Export and Anonymisation
- Batches and Mailboxes
How it works
- Architecture
- Processing Workflow
- Redaction Engine
- Storage and Encryption
- Streaming IO
- Data Model
- API Reference
- Security Model
When it breaks
Contributing
Repository · Issues · Releases · Changelog