# Sealed form fields move plaintext out of pages

> A WICG proposal encrypts selected form values for the destination while documenting its prototypes, limits, and unresolved review questions.

Sealed form fields would encrypt typed values in the browser using a public key published by the form destination, leaving the page with an encrypted envelope. The proposal opened in the WICG proposals repository on 2026-09-21 and includes a companion `sealed-fields` Content Security Policy directive for ordinary inputs identified by `autocomplete` tokens. Prototypes and review requests exist; the feature has not been standardized
([WICG proposal issue](https://github.com/WICG/proposals/issues/307)).

<span id="what-the-proposal-defines"></span>

## Encryption and form integration

The explainer starts from a narrow confidentiality problem. TLS protects data in transit,
but page scripts can read ordinary input values before submission. The proposed control
would encrypt a value to the recipient selected from the form's resolved `action`. Its
stated goal is for the embedding page and its dependencies to handle an envelope instead of plaintext.
Intermediaries before the private-key holder would also handle an envelope instead of plaintext. It explicitly does not
replace TLS or authenticate the user. It also provides no protection against a compromised recipient
([sealed form fields explainer](https://github.com/madeit-build/koschei/blob/main/docs/specs/explainer.md)).

The proposal uses a new element. It rules out adding a new `input` type. The explainer says an
unknown input type falls back to `text`, which would expose plaintext in a browser without
support. An unknown custom element cannot silently become an editable text field. The
polyfill spells the element `<sealed-input>`, while the native sketch uses
`<sealedinput>` or a similar platform-defined name. Unsupported or misconfigured cases
are intended to leave the control disabled instead of reverting to plaintext
([sealed form fields explainer](https://github.com/madeit-build/koschei/blob/main/docs/specs/explainer.md)).

Two origins have distinct roles in the design. The embedding origin owns the document and
form. The recipient origin comes from the form destination and holds the private key. It publishes key information at
`/.well-known/sealed-input`. The polyfill serves its isolated
frame from that recipient origin. The explainer says this avoids adding a polyfill vendor
or CDN as another party that can see the value
([sealed form fields explainer](https://github.com/madeit-build/koschei/blob/main/docs/specs/explainer.md)).

Existing CSP controls are part of that boundary. The recipient can restrict which pages
embed its frame with `frame-ancestors`. The embedding page can restrict the frame and form
destination with `frame-src` and `form-action`. The proposed recipient discovery uses the
resolved form action; page script does not supply the public key. Redirecting the
seal therefore also requires changing the destination that those policies govern
([sealed form fields explainer](https://github.com/madeit-build/koschei/blob/main/docs/specs/explainer.md)).

The draft envelope binds the encrypted value to an embedding origin and a field name. It also binds
the action URL, with its query and fragment removed. These values form additional authenticated data,
so a recipient that reconstructs a different slot cannot open the envelope. The draft
format also carries a version and key identifier, allowing the recipient to select a key
while rotating published key material
([sealed form fields explainer](https://github.com/madeit-build/koschei/blob/main/docs/specs/explainer.md)).

Compatibility with forms is a stated design goal. In the explainer, the value getter
returns the encrypted envelope and `FormData` receives it. The server opens the envelope
with a recipient library. Constraint checks occur inside the protected boundary and expose
only a generic validity result. The draft suppresses events and selection surfaces that
could carry plaintext, while retaining focus, reset, disabled-state, and form-submission
behavior described by the proposal
([sealed form fields explainer](https://github.com/madeit-build/koschei/blob/main/docs/specs/explainer.md)).

## What the prototypes demonstrate

The WICG issue reports two implementations that use the same envelope format. One is a
form-associated custom-element polyfill that performs sealing inside a recipient-served
frame. The other is a Ladybird patch series containing a native element and the
`sealed-fields` directive. The issue says a server implementation opened envelopes
produced by both, and that engine tests cover the element path and the header-delivered
directive path ([WICG proposal issue](https://github.com/WICG/proposals/issues/307)).

The native feasibility work focuses on surfaces through which typed data could escape.
The proposal author reports testing cases involving cloning, switching an input type,
paste events, detaching and reinserting a control, editing commands, and editing history
after a field name or form action changes. Those findings are evidence from the Ladybird
prototype. They make no claim about shipping Chromium behavior or about Firefox and WebKit
([native feasibility memo](https://github.com/madeit-build/koschei/blob/main/docs/research/native-feasibility-ladybird.md)).

The polyfill has a different boundary from a native control. Its own explainer says an
iframe can isolate keystrokes from page script, but cannot reproduce every engine-level
guarantee. It calls out differences in autofill behavior and extension execution worlds. Renderer heap
isolation also differs in a userland implementation. The native proposal also
contains CSP behavior that cannot be supplied by a JavaScript polyfill
([sealed form fields explainer](https://github.com/madeit-build/koschei/blob/main/docs/specs/explainer.md)).

The proposal does not claim that sealed fields stop every form attack. Its non-goals
include a compromised recipient and replay to the same slot. Sender authentication is also outside its scope. It
also discusses a decoy-field attack in which injected code displays an ordinary input
instead. The proposed CSP directive is meant to apply sealing by `autocomplete` token,
but the explainer says this narrows the decoy gap while leaving it open
([sealed form fields explainer](https://github.com/madeit-build/koschei/blob/main/docs/specs/explainer.md)).

<span id="why-it-matters-for-pwa-developers"></span>

## Potential impact on form libraries and recipients

A PWA can contain the same analytics, support widgets, application dependencies, and form
libraries as another web application. The proposal is relevant because its boundary is the
document and submission path, not an installation mode. If standardized, it would offer a
declarative distinction between values the application may process as plaintext and values
that should pass through application code as recipient-bound envelopes. That intended
distinction is the central goal stated by the explainer
([sealed form fields explainer](https://github.com/madeit-build/koschei/blob/main/docs/specs/explainer.md)).

 Returning ciphertext
from `.value` and `FormData` is intended to preserve submission and library flows that
treat a value as an opaque string. At the same time, setting the value from script is
designed to fail, and constraint information is deliberately reduced. Adoption would
therefore require auditing code that assumes it can populate, inspect, validate, log, or
restore every field through ordinary input APIs
([sealed form fields explainer](https://github.com/madeit-build/koschei/blob/main/docs/specs/explainer.md)).

Recipient availability would also become part of form availability. The explainer says a
missing or invalid well-known document, unusable key, blocked frame, insecure destination,
or other discovery failure leaves the field disabled. It describes that as a deliberate
trade-off: falling back to plaintext would defeat the confidentiality property. A product
evaluating the proposal would need to treat recipient static assets and key rotation as
part of the submission path
([sealed form fields explainer](https://github.com/madeit-build/koschei/blob/main/docs/specs/explainer.md)).

Security language must stay inside the documented threat model. The proposal aims to keep
plaintext away from page-level readers and infrastructure before the recipient. It does
not say that the value is safe after decryption or that the user is authenticated. It also
does not rule out injected code presenting deceptive UI. Describing it as general protection against
form skimming would therefore exceed the claims in the explainer
([sealed form fields explainer](https://github.com/madeit-build/koschei/blob/main/docs/specs/explainer.md)).

Standards review is still at an early stage. A Mozilla standards-position request was
opened on 2026-10-14 and is marked unscreened. That request asks for review of the
decoy-field argument and possible side channels. The WICG issue also links a WebKit
standards-position request. Neither request establishes browser support or consensus
([Mozilla standards-position request](https://github.com/mozilla/standards-positions/issues/1468)).

The proposal remains under review. The proposal identifies who selects the recipient, where plaintext is meant
to exist, what ordinary form surfaces would receive, and which failures should close the
field. The prototypes provide material for review, but the open standards-position work
means an application cannot treat the proposed element or directive as an interoperable
web-platform contract
([WICG proposal issue](https://github.com/WICG/proposals/issues/307)).

## Related entries

- [Web app manifest](/reference/manifest/): see the members and processing model of a web app manifest.
- [Service workers](/reference/service-worker/): see service worker registration and lifecycle, along with request handling.
- [By feature](/compatibility/by-feature/): see browsing OpenPWA compatibility data by capability.

## Open and unverified

- Whether the proposal will enter a standards-track specification is not confirmed.
- Implementation of the element or CSP directive remains unconfirmed for Chromium and for Firefox or WebKit.
- The final element name, envelope format, discovery contract, and event surface are not confirmed.
- Whether reviewers accept the proposal's treatment of decoy fields and observable side channels is not confirmed.
- How native implementations would integrate with each engine's autofill, accessibility, editing, and extension architecture is not confirmed.
- Whether the prototype's performance and availability trade-offs hold across production devices and recipient deployments is not confirmed.

## Sources

- [Sealed form fields proposal](https://github.com/WICG/proposals/issues/307) (github.com)
- [Sealed form fields explainer](https://github.com/madeit-build/koschei/blob/main/docs/specs/explainer.md) (github.com)
- [Ladybird native feasibility memo](https://github.com/madeit-build/koschei/blob/main/docs/research/native-feasibility-ladybird.md) (github.com)
- [Mozilla standards-position request](https://github.com/mozilla/standards-positions/issues/1468) (github.com)