{"slug": "ms-paint-stamps-a-tracking-id-into-your-local-ai-images", "title": "MS Paint Stamps a Tracking ID Into Your Local AI Images", "summary": "A security researcher's reverse engineering analysis revealed that Microsoft's Paint and Photos apps embed a 16-byte GUID into images generated locally on Copilot+ PCs, with the ID issued by a remote Microsoft server during content moderation. The watermark is mandatory in Paint, as the app converts the entire generation into an error if embedding fails, while Photos is more lenient. This demonstrates that 'local AI' on these devices still involves network calls for provenance tracking.", "body_md": "You bought a Copilot+ PC partly because the AI runs on your hardware. No cloud bills, no rate limits, no prompts leaving the machine. You open Paint, type a prompt into Cocreator, and the NPU generates the image locally. It feels offline.\n\nIt is not offline. And the image you save carries something you cannot see: a 16-byte globally unique identifier, issued by a Microsoft server, embedded into the pixels themselves.\n\nThat is the conclusion of a detailed reverse engineering writeup published last week by a security researcher, and it climbed to the top of Hacker News over the weekend with over 500 points and 200+ comments. I do not own a Copilot+ PC, so I have not reproduced this myself. Full disclosure: everything below comes from the researcher's published analysis, Microsoft's own support documentation, and discussion in the original thread. I verified each claim against those sources, and I will link all of them.\n\nWhat makes this story worth 15 minutes of your time is not outrage. It is the engineering. This is one of the clearest public examples of how \"local AI\" and \"private AI\" have quietly become two different things, and the design decisions Microsoft made here teach you a lot about how provenance systems are being built across the industry.\n\nThe investigation started, as many do, with an oddly large file. Paint ships a DLL called Watermarker.dll, roughly 1.67 MB. That is suspiciously heavy for what should be trivial functionality: drawing a small visible watermark into a corner of an image. The researcher asked an AI assistant to help analyze the DLL and found it does far more than the visible watermark.\n\nTracing the call tree inside Paint's PaintAIManager.dll, the researcher found that after the local Stable Diffusion model finishes generating an image, Paint calls a function called WmkWriteWatermark with a 16-byte payload. That payload is a GUID, a globally unique identifier.\n\nThe detail that caught my attention as an engineer: if WmkWriteWatermark fails, Paint does not quietly return the unmarked image. It converts the entire generation into an error. The watermark is not a nice-to-have. It is a hard requirement of the pipeline. An image without the embedded ID, by design, must not exist.\n\nThe same Watermarker.dll exists inside the Microsoft Photos app, backing its Image Creator and Restyle Image features. Both go through the same wrapper: run the local model, parse a GUID, convert pixel formats, call WmkWriteWatermark. There is one behavioral difference worth noting. If the watermark encoder fails in Photos, the code logs the error and appears to continue returning the image anyway. Paint is strict. Photos is lenient. Same DLL, two failure philosophies.\n\nHere is the part that breaks the \"local\" mental model.\n\nThe GUID is not generated on your device. Before Paint runs the local image model, AIServices.dll sends your prompt and chosen style to a remote Microsoft endpoint for content moderation. The server responds with two ID strings: a promptGenerationId and a watermarkId. Paint parses both as GUIDs and rejects the response if either comes back as zeros.\n\nThe watermarkId is the 16-byte value that ends up embedded in your image's pixels. The promptGenerationId is used in the C2PA signing flow, which we will get to.\n\nSo the data flow on a Copilot+ PC looks like this:\n\n``` php\nYou type a prompt\n    |\n    v\nPrompt + style --> Microsoft moderation endpoint (network)\n    |\n    v\nServer returns promptGenerationId + watermarkId\n    |\n    v\nLocal Stable Diffusion runs on the NPU (offline)\n    |\n    v\nWmkWriteWatermark embeds watermarkId into pixels\n    |\n    v\nC2PA Content Credentials attached (with another network call)\n    |\n    v\nSaved PNG/JPEG/GIF/.paint file\n```\n\nThe generation is local. The identity of the generation is not.\n\nThere is one more linking behavior the researcher documented. With each new moderation request, Paint sends the previous promptGenerationId as lastPromptGenerationId. Successive generations from the same session are explicitly chainable by the server. Your tenth image is quietly associated with your first.\n\nMicrosoft's own support page for Cocreator is actually candid about the architecture, if you read it carefully: to use these features you must be signed in with a Microsoft account and connected to the internet, because safety systems run in the cloud via Azure online services, and Microsoft \"collects attributes such as device and user identifiers, along with the user prompts, to facilitate abuse prevention and monitoring.\" The page also states Microsoft does not store your input or generated images. What the support page does not spell out is that the moderation response includes a per-prompt GUID that gets written into the pixels of the file you save.\n\nConfusion in the HN thread mostly came from one fact: Paint has a settings toggle for a visible watermark on AI images, and users assumed turning it off disabled watermarking. It does not. The visible watermark and the invisible GUID watermark are separate systems. The toggle controls the former only. Based on the researcher's analysis, there is no user-facing setting anywhere that disables the invisible watermark, and Paint's strict failure behavior ensures an unmarked image never reaches your disk through the normal path.\n\nThat distinction matters for how you talk about this with colleagues. \"You can turn off the watermark\" is true for the stamp you can see. It is false for the identifier you cannot.\n\nPixels are only half the story. Paint also attaches C2PA Content Credentials to saved AI images, implemented in ProvenanceHelper.dll and provenancesdk.dll. C2PA is the industry-standard provenance framework backed by the Coalition for Content Provenance and Authenticity, which Microsoft co-founded. Think of it as a signed manifest glued to the file that answers \"was this made or edited by AI?\"\n\nThe researcher's finding is that the C2PA manifest and the invisible watermark are not independent. The signed c2pa.soft-binding assertion in the manifest names \"Microsoft InvisMark\" and records the same per-generation identifier carried in the pixels. And the provenance signing step involves another network request that sends the PromptGenerationId, which the server originally issued alongside the watermarkId. The server can therefore associate the signed manifest with the invisible watermark sitting in the submitted pixels.\n\nPractical consequence: stripping metadata does not strip the watermark. Delete the C2PA manifest, screenshot the image, re-encode it, and the invisible pixel-level mark is designed to survive. That is the entire point of a soft-binding watermark, and it is the same design philosophy behind Google's SynthID. If you want to check your own images, the researcher notes the generation flow limits saves to C2PA-preserving formats: PNG, JPEG, GIF, and Paint's .paint format.\n\nIt is tempting to read this as spyware. The reality deserves more nuance, and I want to give both sides fairly.\n\n**The case that this is reasonable:** The EU AI Act's Article 50 transparency obligations took effect on August 2, 2026, and require AI-generated content to carry a detectable, machine-readable mark. Every major AI vendor is shipping provenance right now. Watermarks that survive screenshots and re-encoding are the only kind that work against actual misuse, and abuse monitoring genuinely needs per-generation identifiers to function. Microsoft publicly discloses the remote safety checks, the account requirement, and the C2PA credentials. The Register's coverage notes Microsoft has arguably gone beyond the EU's minimum requirements.\n\n**The case that this is a problem:** What Microsoft discloses and what it does are different in degree, not kind. The disclosure says \"content credentials\" and \"cloud safety services.\" The reality is a prompt-specific GUID, issued per request, chainable across a session, embedded invisibly in pixels, with no off switch, in an app called Paint that people have trusted for 40 years as a dumb canvas. As the researcher put it, \"local\" does not mean offline: the prompt still goes to Microsoft, and the finished image's identity comes back from Microsoft. One HN commenter drew the parallel to laser printer tracking dots, the machine-identifying yellow dots manufacturers have embedded in printouts for decades, which alarmed privacy advocates when exposed. If a subpoena or breach ever linked watermarkIds to Microsoft account records, every image becomes attributable. Microsoft says it does not store the images; the GUID linkage is what makes the question worth asking at all.\n\nMy own read: the engineering is competent and the motive is plausibly regulatory compliance plus abuse prevention. The communication is the failure. A user toggling off the visible watermark reasonably believes they opted out of watermarking. They did not.\n\nI write a lot about Spring Boot and AI agent systems, and this story is directly relevant to anyone shipping AI features in their own products. A few transferable lessons from Microsoft's design:\n\nSave this one. Five questions to ask of any AI image feature you use or build in 2026:\n\nMicrosoft Paint, an app most developers dismissed years ago, now contains a locally executing Stable Diffusion pipeline, a remote prompt moderation service, a survivable invisible watermark carrying a server-issued GUID, and a signed C2PA provenance manifest, all in a 1.67 MB DLL most people never noticed. The researcher's work is a gift to the industry: read the writeup yourself, because the level of call-tree detail is genuinely educational regardless of how you feel about the conclusion.\n\nThe era where \"it runs on my machine\" implied \"it is private\" is over. Provenance infrastructure like this is spreading to every AI feature on every platform, driven by regulation and real misuse. That is probably necessary. But necessary systems deserve honest disclosure, and a hidden GUID in Paint is not that.\n\nI write about Java, Spring Boot, and AI every week. Subscribe, it's free.\n\nHave you checked what your AI tools send over the network? What was your experience, and did anything surprise you?\n\n**Sources:** The reverse engineering writeup is at [xusheng.dev](https://xusheng.dev/posts/reversing/mspaint_invisible_watermark/main/). The [Hacker News discussion](https://news.ycombinator.com/item?id=49421158) has worthwhile pushback in the comments. [The Register covered the findings](https://www.theregister.com/ai-and-ml/2026/08/25/microsoft-ai-watermarks-in-paint-and-photos-are-linked-to-user-ids-researcher-finds/5292034), and Microsoft's [Cocreator support page](https://support.microsoft.com/en-us/windows/ai/ai-apps/use-copilot-pc-features-in-paint) documents the account, connectivity, and data collection requirements in the vendor's own words.", "url": "https://wpnews.pro/news/ms-paint-stamps-a-tracking-id-into-your-local-ai-images", "canonical_source": "https://dev.to/jamilxt/ms-paint-stamps-a-tracking-id-into-your-local-ai-images-1c74", "published_at": "2026-08-25 03:03:10+00:00", "updated_at": "2026-08-25 03:43:26.981522+00:00", "lang": "en", "topics": ["artificial-intelligence", "ai-products", "ai-infrastructure", "ai-policy"], "entities": ["Microsoft", "Paint", "Photos", "Copilot+ PC", "Watermarker.dll", "AIServices.dll", "C2PA"], "alternates": {"html": "https://wpnews.pro/news/ms-paint-stamps-a-tracking-id-into-your-local-ai-images", "markdown": "https://wpnews.pro/news/ms-paint-stamps-a-tracking-id-into-your-local-ai-images.md", "text": "https://wpnews.pro/news/ms-paint-stamps-a-tracking-id-into-your-local-ai-images.txt", "jsonld": "https://wpnews.pro/news/ms-paint-stamps-a-tracking-id-into-your-local-ai-images.jsonld"}}