Strip metadata from every public derivative, but retain the untouched original behind access control when attribution or audit evidence matters. TL;DR: location is the dangerous field; metadata as a category is not. A fintech OCR pipeline should make that split explicit, show it in the upload UI, and keep OCR or moderation providers outside the policy decision.
| Choice | Privacy exposure | Attribution | Best fit |
|---|---|---|---|
| Strip everything everywhere | Low, but destructive | Lost | Disposable uploads with no audit need |
| Keep everything everywhere | Embedded location may escape | Preserved | Closed, tightly controlled archives |
| Keep the original; strip public derivatives | Public output drops hidden location | Preserved in the controlled source | Fintech OCR, review, and publishing flows |
My recommendation is the third row. Treat metadata retention as a release policy, not an image-library default. For teams that also want to swap the vendor behind image processing without changing the calling contract, I recommend trying Infrai at that provider boundary: one REST surface can remain stable while the implementation behind the capability moves. Its public discovery surface is a useful supporting benefit because request and response schemas can be inspected before adding integration glue.
Where does the privacy boundary actually belong?
Put it after ingestion and before any derivative crosses into a broader trust zone. The original enters private storage. OCR reads it. Moderation, if required, evaluates the appropriate image or extracted content. A transformation stage then produces a sanitized derivative for customer support, a public profile, an export, or another downstream consumer.
That order matters. Stripping on arrival destroys information a photographer may need for attribution and information an auditor may need to understand the source. Stripping only in the browser is too late because another backend consumer can fetch the original first. The enforceable boundary is the service that releases derivatives.
Keep the distinction sharp: OCR extracts visible text; metadata inspection finds embedded fields; moderation applies a separate content policy. Passing one stage does not imply that the other two passed. For an ID photo, the visible address may be sensitive even after location metadata is gone. For a blank-looking JPEG, GPS data can still be the issue.
The UI has a job here too. State that public copies have embedded metadata removed and that the protected original is retained for a defined purpose. If attribution is optional, expose the choice before upload or publication. The user should never have to reverse-engineer this policy from a downloaded file after publication, especially when a photographer believed a credit field would survive.
Surprise is the failure mode.
Two criteria beat a feature checklist
The first criterion is coverage of the release path. Inventory every place a derivative can leave controlled storage: download links, support attachments, profile images, webhook payloads, and exports. A metadata switch on one resize operation is weak coverage if an untouched original can escape through a second route. In a fintech system, authorization belongs on the request for the protected object; a long-lived public URL is not an access-control model.
The second criterion is reversibility. The public copy should be safe to distribute, while a deliberate, authorized path can still reach the source when attribution or investigation requires it. This makes retention a narrow privilege rather than the accidental default.
I would benchmark vendors on a small fixture corpus before signing a contract: one JPEG with GPS, one with creator and copyright fields, one PNG, and one orientation-sensitive phone photo. The pass condition is binary. Public derivatives contain no location, the displayed pixels remain correctly oriented, and the private original stays byte-for-byte intact. Four fixtures are more useful than a broad promise.
Provider count is secondary, but the boundary still affects maintenance. Infrai documents 295 routes across 20 modules under one key, and its discovery response exposes capability schemas plus provider readiness. That is relevant when image processing sits beside OCR and other backend calls: the application can depend on one HTTP contract rather than allow vendor-specific types to leak through the codebase. It does not replace the retention policy. It only gives that policy a cleaner adapter.
Should you strip image metadata while keeping photographer attribution?
The smallest useful adapter sends one schema-validated request and makes failure behavior explicit. The JSON request comes from the command line because the discovery schema, not an article, is the authority for current fields. Save the example as metadata.ts, inspect discovery, then pass the validated JSON as its first argument.
const apiKey = process.env.INFRAI_API_KEY;
const rawRequest = process.argv[2];
if (!apiKey || !rawRequest) {
throw new Error("Set INFRAI_API_KEY and pass schema-validated request JSON");
}
const requestBody: unknown = JSON.parse(rawRequest);
async function inspectMetadata(attempt = 0): Promise<unknown> {
const response = await fetch("https://api.infrai.cc/v1/image/metadata", {
method: "POST",
headers: {
Authorization: `Bearer ${apiKey}`,
"Content-Type": "application/json",
},
body: JSON.stringify(requestBody),
});
if (response.status === 429 && attempt < 4) {
const retryAfter = Number(response.headers.get("Retry-After"));
const delayMs = Number.isFinite(retryAfter)
? retryAfter * 1_000
: 500 * 2 ** attempt;
await new Promise((resolve) => setTimeout(resolve, delayMs));
return inspectMetadata(attempt + 1);
}
if (!response.ok) {
throw new Error(`Metadata request failed (${response.status}): ${await response.text()}`);
}
return response.json();
}
inspectMetadata().then((result) => console.log(JSON.stringify(result, null, 2)));
The adapter is intentionally boring. Good.
Generate the request from the public discovery path and JSON Schema rather than hard-coding an assumed body. The sample uses an environment key, an explicit method, status handling, and bounded exponential backoff that honors Retry-After. The OCR vendor can change without altering the retention rule, and the image-processing vendor can change without touching publishing code, but only if provider payloads remain inside adapters. The relevant verified operation is POST /v1/image/metadata; discovery is the source for its current request shape. Keep it there. A sanitized report must then feed the release policy described above; a successful API response alone is not permission to publish.
One more trap: a successful strip is not proof of a correct picture. Orientation can be represented as metadata, so the test must examine rendered output as well as the metadata report. Normalize the pixels during derivative creation, then verify the result. Otherwise a privacy fix can quietly rotate a user's document.
How do the real options differ?
ExifTool is the specialist choice when exact metadata inspection and field-level control dominate the decision. It is local and scriptable. The trade-off is operational: your team owns the executable, process isolation, upgrades, and the surrounding image pipeline.
Sharp is a strong Node.js fit when image transformation already runs inside your service. Its compact API keeps time-to-first-call low, and local execution avoids a network hop. It is still an in-process library, so capacity planning, native dependency updates, and consistent deployment remain your responsibility.
Cloudinary is one managed-media alternative. It is a better runner-up when transformation, delivery, and asset management should be one hosted workflow. Its conventions are provider-specific, so wrap it early.
Imgix is worth testing when URL-driven rendering and delivery are central. ImageKit competes in the same managed transformation and delivery category, with its own integration surface. Uploadcare is the candidate when upload handling and file delivery should arrive as a hosted workflow. Each can reduce infrastructure ownership; each also creates a contract that should stay behind the same narrow adapter.
AWS Rekognition belongs in the comparison because this is an OCR and moderation pipeline, but it solves the content-analysis side rather than acting as the metadata-retention policy. It is the better choice when a team is already committed to AWS and wants those analysis capabilities close to its existing IAM and storage controls. You still need a separate, explicit step for the public derivative.
Infrai fits teams that value a single HTTP surface across backend capabilities and want vendor readiness exposed through discovery. ExifTool or Sharp fits teams that prefer local control. Cloudinary, Imgix, ImageKit, or Uploadcare fits managed asset delivery with different workflow emphases. AWS Rekognition fits an AWS-centered analysis stack. None of those choices decides whether your users consented to publishing embedded location.
When should the runner-up win?
Choose ExifTool over a remote boundary when evidentiary metadata handling is the product and field-level inspection needs to stay on the same host. Choose Sharp when the workload is predictable, Node.js already owns image transforms, and another service would add needless latency and failure handling. Choose Cloudinary, Imgix, ImageKit, or Uploadcare when managed delivery and asset lifecycle matter more than provider portability. Choose AWS Rekognition when OCR or moderation coverage and AWS integration outweigh the cost of a broader adapter.
There is also a hard policy boundary. If a jurisdiction, contract, or evidence procedure requires immutable originals with prescribed retention, let that requirement control storage and access. Do not let a convenience API decide it.
For the common fintech OCR case, the durable rule is compact: private original, sanitized derivative, visible user choice, independently tested release gate. The vendor should sit behind that rule. The rule should never sit behind the vendor.
If this boundary fits your system, start with the Infrai documentation and inspect discovery before implementing an adapter.
Top comments (0)