DEV Community

Cover image for OpenAI text watermarking does not give your app a provenance log
Dave Kurian
Dave Kurian

Posted on Originally published at otf-kit.dev

OpenAI text watermarking does not give your app a provenance log

A text watermark can be useful evidence that an OpenAI system generated or processed part of a passage. It cannot tell your application who sent the request, how much a person changed the result, whether the text is accurate, or who owns it. If you need those facts later, your application must record them when work happens.

OpenAI announced textGrain on 5 October 2026 as part of its response to EU text provenance rules. API customers worldwide can opt in for select models, with watermarking off by default. OpenAI also plans to add an invisible watermark to eligible ChatGPT and Codex text in the EU over the coming weeks. Those changes make provenance a practical product question for teams that accept generated text, store it, or show it to other people.

The engineering choice is simple: treat a watermark as one optional signal, and keep a separate record of the app’s own generation and editing events. Do not use a watermark result as your user identity system, authorship label, or truth check.

Keep the signal separate from the record

A provenance record answers questions about your product’s workflow. Which signed-in account started the request? Which workspace or document received the text? Which provider and model handled it? Which version did the user keep? Did a person edit it before it reached another user?

A text watermark answers a narrower question. A detector can report whether it sees a statistical signal associated with an OpenAI system in a passage. OpenAI says its signal does not identify the account, prompt, or conversation. It also does not measure the person’s contribution, establish ownership or responsibility, or verify accuracy. A negative result does not prove that a person wrote the text.

Keep these as different records. Your app can know that an authenticated account requested a generation even when it cannot tell who wrote every sentence. It can also know that a user edited a passage without claiming that the edit made the whole passage human-authored. Those are useful facts for support, review, and product history. They are narrower than a claim about authorship.

Capture what your app can know

Write an event for each generation attempt and a separate event when a user accepts or edits the output. Use the identity already established by your own authentication flow. Keep the provider request ID when the provider returns one, but do not treat that ID as a substitute for your own event ID.

Byte and Dex trace an account request, an edited text version, and a saved revision as separate event markers.

A minimal schema can start like this:

CREATE TABLE text_generation_events (
  id uuid PRIMARY KEY,
  artifact_id uuid NOT NULL,
  artifact_revision integer NOT NULL,
  actor_id uuid,
  workspace_id uuid NOT NULL,
  provider text NOT NULL,
  model_name text NOT NULL,
  provider_request_id text,
  created_at timestamptz NOT NULL DEFAULT now(),
  prompt_record_ref text,
  prompt_digest text,
  output_digest text,
  watermark_opt_in_configured boolean NOT NULL DEFAULT false,
  outcome text NOT NULL
);

CREATE TABLE artifact_history_events (
  id uuid PRIMARY KEY,
  artifact_id uuid NOT NULL,
  artifact_revision integer NOT NULL,
  actor_id uuid,
  event_type text NOT NULL,
  created_at timestamptz NOT NULL DEFAULT now(),
  parent_generation_event_id uuid,
  content_digest text NOT NULL
);
Enter fullscreen mode Exit fullscreen mode

This is an example, not a required provider schema. Use your app’s existing key types and access controls. The important parts are the relationship between an artifact and its revisions, a reference to the authenticated actor when available, and an event that says what your application observed. watermark_opt_in_configured records your own integration setting; it does not claim that a provider returned a watermark or that a detector found one.

Do not store full prompts and outputs in a general-purpose log by default. They can contain personal data, source code, or business content. If support or a user-facing history needs the content, store it in the product’s protected content store and keep a reference here. A digest can help you compare versions, but it cannot restore the original text or explain a human edit. Set retention and deletion rules for both the event and the content it points to.

Record edits as edits

A generation event does not describe the full life of a passage. A person may reject the first result, rewrite a section, combine it with another document, or ask a second provider to revise it. Record those as new revisions or events that point to their parent. Keep the event name factual: accepted, edited, merged, or published describes an app action; human-authored makes a claim your event log cannot prove.

For example, when a person saves a changed version, create an artifact_history_events row with the new revision, the account that saved it, the event type edited, the parent generation event, and a digest of the saved version. If the product supports collaborative editing, record each save or meaningful edit boundary with the actor available to the app. Do not infer individual authorship from a document that several people and services changed.

This event chain is also more useful during an incident than a binary label. A support engineer can see whether a passage came from a generation request, which account accepted it, and which revision was displayed. They still need a separate accuracy review to decide whether its claims are correct.

Treat detector output as limited evidence

At launch, OpenAI says access to its text watermark detector is limited to approved researchers and expert organizations. Do not build a production workflow that assumes your application can call that detector. If you later use a permitted detector, store its result as a separate observation with the detector name, check time, passage digest, and result. Keep not checked, unavailable, and not detected distinct. A missing result is not a negative result.

Do not block a user, mark a submission as deceptive, or attach an authorship label only because a detector reports a signal. A signal does not establish who used the system or how a person contributed. It also does not establish that a passage is true, lawful, or safe for a given audience. Apply the same content review and moderation rules that you use for other text.

OpenAI reports that short or constrained passages are harder to detect and that editing can weaken the signal. Its announcement gives examples where replacing words reduced detection in a 400-token evaluation. This is another reason to preserve the event history instead of asking a watermark to carry the whole provenance job.

Luna checks a faint text signal while Byte follows saved revisions; Nova’s display keeps the signal separate from the app’s history.

Put the rule where text changes hands

Choose the point in your product where a generated passage becomes part of a saved artifact. At that point, store the generation reference and the saved revision together. When the text is shared, exported, or used in a decision, show the provenance information your app actually has. Do not turn an internal signal into a statement about a person’s effort or intent.

Review the fields with your privacy and product owners before adding them to an event store. Keep access narrow, avoid copying raw prompts into analytics, and test that deletion requests remove or detach content according to your product’s retention rules. These steps apply whether or not a provider offers watermarking.

If your app also stores credentials for model access, keep that concern separate from text history; see how to set an expiration and rotation plan for an OpenAI project API key. An API key identifies an integration credential. A watermark is a limited signal about text. Neither one replaces an application event that records who asked your product to do something.

A practical rule for builders

Use your authenticated account and version history to record the workflow. Keep any provider watermark setting or detector observation in separate fields, with a timestamp and clear status. Describe the result as a signal, not proof of authorship. If the app cannot identify an actor or verify a passage, say so rather than filling the gap with a watermark claim.

That design remains useful as providers change their watermark settings. You can adopt an opt-in feature when it fits your product, without making the rest of your audit trail depend on it. OpenAI’s own announcement says textGrain is an early technology and describes limits that matter in everyday use. Your records should make those limits visible instead of hiding them behind a single “AI-written” flag.

Sources

Top comments (0)