Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Should <meta name=accept-ch content> be parsed like HTTP Permissions-Policy or HTML allow? #108

Closed
eeeps opened this issue Apr 20, 2022 · 20 comments · Fixed by #109
Closed
Assignees

Comments

@eeeps
Copy link
Collaborator

eeeps commented Apr 20, 2022

  • The spec (step 11) points to Permissions Policy's Parse a policy directive algorithm, which parses the HTML allow attribute.
  • allow has a different syntax than the HTTP Permissions-Policy header, which relies on Structured Field parsing.
  • Chrome is shipping with <meta name="accept-ch"> syntax that resembles Permissions-Policy/Structured Fields, with at least one subtle difference: origins can't be quoted, as sf-strings are.

Here's what I got to work in shipping Chrome:

<meta name="accept-ch" content="sec-ch-dpr=(self https://o.img.rodeo https://res.cloudinary.com), sec-ch-width=(self https://o.img.rodeo https://res.cloudinary.com)">

Here's what I would expect, based on the spec:

<meta name="accept-ch" content="sec-ch-dpr 'self' https://o.img.rodeo https://res.cloudinary.com; sec-ch-width 'self' https://o.img.rodeo https://res.cloudinary.com">

(although I'm not 100% on what quotes go where, honestly. luv 2 interpret ABNF...)

I see three ways forward:

  1. Chrome changes its implementation to match the spec, using theallow parsing rules (too late?)
  2. The spec changes, so that the content attribute is parsed using the Permissions-Policy sf-header rules, and Chrome updates its implementation to eliminate any subtle differences (e.g. sf-string quoting... perhaps others?)
  3. The spec changes to document the <meta name="accept-ch"> parsing rules that are shipping in Chrome, which match neither allow nor Permissions-Policy.

I'd prefer 1 over 2 over 3, but if there's any usage, we may be stuck with 3.

@arichiv
Copy link
Collaborator

arichiv commented Apr 20, 2022

I think 3 is most likely, I'll take a stab at that Friday.

@arichiv
Copy link
Collaborator

arichiv commented Apr 20, 2022

I think 3 is most likely, I'll take a stab at that Friday.

To elaborate on reasoning:
(1) We not only ignore * in the meta tag, but don't override a default/http-header policy of * no matter how the meta tag is defined.

Permissions-Policy: ch-dpr=*
+
<meta name="accept-ch" content="sec-ch-dpr=(https://foo.bar)">
=
ch-dpr=*

(2) We not only ignore self in the meta tag, but don't remove self as a valid target if it's in the default/http-header policy no matter how the meta tag is defined.

Permissions-Policy: ch-dpr=(self)
+
<meta name="accept-ch" content="sec-ch-dpr=(https://foo.bar)">
=
ch-dpr=(self "https://foo.bar")

(3) We only read the new list of hosts for each policy, and append it to the list that already exists.

Permissions-Policy: ch-dpr=(self "https://foo.bar")
+
<meta name="accept-ch" content="sec-ch-dpr=(https://baz.qux)">
+
<meta name="accept-ch" content="sec-ch-dpr=(https://dead.beef)">
=
ch-dpr=(self "https://foo.bar" "https://baz.qux" "https://dead.beef")

We are very deliberately providing something short of a true permissions policy and really need to document it.

@eeeps
Copy link
Collaborator Author

eeeps commented Apr 21, 2022

Is there any precedent for serializing:

[key1: [value1, value2,...], key2: [value1, value2...]]

...into an HTML attribute? allow is the only one I can think of. I get the argument that we don't want it to look like allow because it doesn't work like allow, but inventing something new that looks almost like Permissions-Policy but doesn't work like Permissions-Policy doesn't feel great either. But again, shipping/usage may make that moot.

@eeeps
Copy link
Collaborator Author

eeeps commented Apr 21, 2022

I suppose srcset with multiple descriptors is shaped like this, and just like allow, relies on white-space + comma separation, and order.

srcset="a.jpg 300w 200h, b.jpg 600w 400h, c.jpg 1200w 800h"

So is style, which is just CSS, which is its own little universe of DSLs and not really relevant, other than to say, putting other serializations (like Permissions-Policy's) into HTML has precedent.

style="font-family: system-ui, sans-serif; margin: 2em 1em;"

@eeeps
Copy link
Collaborator Author

eeeps commented May 6, 2022

@arichiv Is there any usage of the new <meta> yet?

Cloudinary, for one, is still well-situated to update our recommendations to customers, if the syntax changes. We haven't published docs or a blog post and have yet to reach out to many customers. But that door is closing.

For the (hopefully many) developers who try to implement HTML hint delegation in the future, I'd rather we end up with a less confusing syntax. Here are things I find tripping people up about it:

  • The <meta> has a name of accept-ch but doesn't interact with the accept-ch cache or use the accept-ch HTTP header syntax. Also, authors aren't expressing what hints they'll accept, but rather asking the user-agent to send hints to trusted third parties. This "who is accepting what?" ambiguity seems to have caused some of the confusion present in the TAG review. Would a name like delegate-ch make more sense?
  • The content looks a lot like the Permissions Policy Structured Headers syntax, but it isn't. As you point out, it's doing something very different; perhaps it should look even more different. As it stands I've already seen people try to copy and paste Permissions-Policy header values into this <meta content>, and fail.
  • There's no precedent for a Structured Headers syntax in HTML.
  • This isn't even valid Structured Headers syntax, due to the quoting of strings.

@arichiv do you agree with any of that? Is the door to changing Chrome's implementation already closed? Again, I'm most of all excited that this functionality exists. Existing >>> it being perfect, or even all that easy to learn/teach (most of our customers will be copy/pasting from our docs). And sincere apologies for swooping in with criticism late, after having ample opportunity to review earlier, after Chrome already shipped!

@arichiv
Copy link
Collaborator

arichiv commented May 10, 2022

  1. We wanted to use accept-ch because it's not just delegating (changing permissions policies) but requesting the hint be shared the same way the HTTP header does.
  2. I still need to update the spec to reflect the actual syntax, sorry for the delay on that.
  3. I still think the right choice is unifying the Permissions-Policy and Accept-CH headers into the meta tag's syntax. Long term, we probably want a meta tag for Permissions-Policy generally, but I don't think that's in the cards in the near future.
  4. I could add support for quoted strings, that would unify the syntax to a greater extent, but of course the naming (sec-ch-* vs ch-*) and the tokens allowed (no * or self) still prevent copying.

@yoavweiss wanted to get your take on the above ideas as well, it's true the place we ended up is kinda weird.

@eeeps
Copy link
Collaborator Author

eeeps commented May 26, 2022

Any progress? M104 is getting closer and Cloudinary has paused our customer outreach efforts until this is settled.

@arichiv
Copy link
Collaborator

arichiv commented May 27, 2022

Sorry for the delay, Yoav and I are slated to discuss next week. As long as the change is parsing only, there will not be an issue making M104. Additionally, if there is a parsing change we will support the current format for at least a milestone and add counters to detect when it's safe to remove.

@arichiv
Copy link
Collaborator

arichiv commented May 31, 2022

Okay @yoavweiss and I talked, we have four options:

  1. Keep current format
  • <meta name="accept-ch" content="sec-ch-dpr=(https://foo.bar/), sec-ch-width=(https://foo.bar/)">
  1. Support quotes (like PermissionsPolicy HTTP Header)
  • <meta name="accept-ch" content="sec-ch-dpr=("https://foo.bar/"), sec-ch-width=("https://foo.bar/")">
  1. Support allow like format
  • <meta name="accept-ch" content="sec-ch-dpr https://foo.bar/; sec-ch-width https://foo.bar/">
  1. Require http-equiv accept-ch and add delegate-ch
  • <meta http-equiv="accept-ch" content="sec-ch-dpr, sec-ch-width">
  • <meta name="delegate-ch" content="ch-dpr https://foo.bar/; ch-width https://foo.bar/">

We're leaning toward moving back the CH-Legacy-Mode change to M105 to have longer to discuss, and will be considering disabling the name="accept-ch" (not the http-equiv="accept-ch") in M104 while we consider. Options 1 and 4 are likely the best ones, but we'll be running this by TAG as well.

https://bugs.chromium.org/p/chromium/issues/detail?id=1330554

@miketaylr
Copy link
Collaborator

@eeeps would be interested in your thoughts to the options above. 🙇

@eeeps
Copy link
Collaborator Author

eeeps commented Jun 1, 2022

@arichiv Thanks for working on this and @miketaylr thanks for the ping!

Thanks also for the updates re: timelines!

Seeing them laid out like this, option 2 seems by far the worst, because you'd have to single quote the HTML attribute or I guess use &quot;s; which seems, at best, weird, and at worst, incompatible with anything (?) that assumes HTML attributes don't contain quotes. I totally get why you removed quotes from the shipping implementation...

I will also feel bad if this issue results in option 4, if only because, while I get that they're currently separate mechanisms, I don't see why an author would ever delegate without enabling (see: #23), and was excited that the initial proposal here rolled the two actions into one.

Between 1 and 3 I'd go with option 3, purely because it has the HTML-iest feel to it. I don't see the benefit of adopting a structured-headers-ish syntax in an HTML attribute.

I hesitate to do this but perhaps I could present... option 5?:

<meta name="send-ch" content="sec-ch-dpr https://foo.bar https://baz.qux; sec-ch-width https://foo.bar" />

  • send-ch name:
    1. Does what it says. We're asking the browser to send certain hints to certain origins within this document, not advertising that we (or anyone else) accepts hints.
    2. Doesn't look like <meta http-equiv=accept-ch>, clarifying that this works differently (no Accept-CH-Cache interactions, performing enablement + delegation in one...).
  • Allow-esque format, with hint names (not feature names) as keys:
    1. Parses in an HTML-y way (splitting on U+003B and then whitespace), yay no new microsyntaxes.
    2. Doesn't look like a Permissions-Policy, clarifying that it works differently (can only append origins, can't do anything with self or *).

@arichiv
Copy link
Collaborator

arichiv commented Jun 1, 2022

5 is the same as 3 but with a different name right? The one point of confusion we foresee is that it looks like allow syntax but rather than use policy names (ch-dpr) it uses the actual hint names (sec-ch-dpr). This makes sense as we aren't just delegating hints, but requesting hints as well. However, it's still a point of difference from the allow syntax.

@eeeps
Copy link
Collaborator Author

eeeps commented Jun 1, 2022

@arichiv Yeah. And that's valid; I'm worried about folks mistaking it for Permissions-Policy; I should also worry about it looking like allow. I'm less worried because I think allow looks more like other things in HTML, I think.

A rough survey of a few people and a quick tour through the HTML spec indicates that while spaces are the most common way to delimit lists in HTML, commas come in a close second. Maybe we could further differentiate by changing that second-level delimiter?

And @zcorpan pointed me to whatwg/html#2335, which, while unresolved, seems relevant.

[noises from the bikeshed intensify]:

<meta crossoriginclienthints="sec-ch-dpr https://foo.bar https://baz.qux, sec-ch-width https://foo.bar">

@miketaylr
Copy link
Collaborator

My own personal take is this is hopefully something that devs can just copy from a docs snippet (or have a tool auto-generate for them) and never think about. Wishful thinking!

Adding support for @domenic's proposal in w3ctag/design-reviews#702 (comment) seems like a good path forward. And then we eventually remove support for what we just shipped.

(while we're bikeshedding, another benefit of ; as a delimiter vs , is it follows CSP syntax.)

@arichiv
Copy link
Collaborator

arichiv commented Jun 7, 2022

Just to recap, a new syntax like the following will be introduced

<meta http-equiv="delegate-ch" value="sec-ch-dpr https://foo.bar https://baz.qux; sec-ch-width https://foo.bar">

in M105. No changes to the M104 launch schedule will occur.

@eeeps
Copy link
Collaborator Author

eeeps commented Jun 7, 2022

@arichiv sounds great. Thank you!

@arichiv arichiv closed this as completed in f1eabaf Jun 9, 2022
@arichiv arichiv reopened this Jun 9, 2022
arichiv added a commit that referenced this issue Jun 9, 2022
closes #108
https://bugs.chromium.org/p/chromium/issues/detail?id=1334152
This uses the iframe allow syntax (which we were already improperly referencing) and clarifies how the parsing should work based on chrome behavior.
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Jun 13, 2022
This adds support for the delegate-ch meta tag. It works like the
accept-ch meta tag, except it uses the same syntax as the allow iframe
attribute. WICG/client-hints-infrastructure#108

This CL is part of a series:
(1) Add support to chromium
(2) Add tests to devtools

Commit: false
Bug: 1334152
Change-Id: I19ce426da8a0aa158aad1fde24f3bd4f19581c52
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Jun 14, 2022
This adds support for the delegate-ch meta tag. It works like the
accept-ch meta tag, except it uses the same syntax as the allow iframe
attribute. WICG/client-hints-infrastructure#108

This CL is part of a series:
(1) Add support to chromium
(2) Add tests to devtools

Commit: false
Bug: 1334152
Change-Id: I19ce426da8a0aa158aad1fde24f3bd4f19581c52
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Jun 14, 2022
This adds support for the delegate-ch meta tag. It works like the
accept-ch meta tag, except it uses the same syntax as the allow iframe
attribute. WICG/client-hints-infrastructure#108

This CL is part of a series:
(1) Add support to chromium
(2) Add tests to devtools

Commit: false
Bug: 1334152
Change-Id: I19ce426da8a0aa158aad1fde24f3bd4f19581c52
arichiv added a commit that referenced this issue Jun 14, 2022
* Update parsing algorithm

closes #108
https://bugs.chromium.org/p/chromium/issues/detail?id=1334152
This uses the iframe allow syntax (which we were already improperly referencing) and clarifies how the parsing should work based on chrome behavior.

* Update index.bs

* Update index.bs

* Update index.bs

* Update index.bs

* Update index.bs

* Update index.bs

* Update index.bs

* Update index.bs

* Update index.bs

* Update index.bs
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Jun 15, 2022
This adds support for the delegate-ch meta tag. It works like the
accept-ch meta tag, except it uses the same syntax as the allow iframe
attribute. WICG/client-hints-infrastructure#108

This CL is part of a series:
(1) Add support to chromium
(2) Add tests to devtools

Commit: false
Bug: 1334152
Change-Id: I19ce426da8a0aa158aad1fde24f3bd4f19581c52
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Jun 27, 2022
This adds support for the delegate-ch meta tag. It works like the
accept-ch meta tag, except it uses the same syntax as the allow iframe
attribute. WICG/client-hints-infrastructure#108

This CL is part of a series:
(1) Add support to chromium
(2) Add tests to devtools

Commit: false
Bug: 1334152
Change-Id: I19ce426da8a0aa158aad1fde24f3bd4f19581c52
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Jun 29, 2022
This adds support for the delegate-ch meta tag. It works like the
accept-ch meta tag, except it uses the same syntax as the allow iframe
attribute. WICG/client-hints-infrastructure#108

This CL is part of a series:
(1) Add support to chromium
(2) Add tests to devtools

Commit: false
Bug: 1334152
Change-Id: I19ce426da8a0aa158aad1fde24f3bd4f19581c52
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Jun 29, 2022
This adds support for the delegate-ch meta tag. It works like the
accept-ch meta tag, except it uses the same syntax as the allow iframe
attribute. WICG/client-hints-infrastructure#108

This CL is part of a series:
(1) Add support to chromium
(2) Add tests to devtools

Commit: false
Bug: 1334152
Change-Id: I19ce426da8a0aa158aad1fde24f3bd4f19581c52
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Jun 30, 2022
This adds support for the delegate-ch meta tag. It works like the
accept-ch meta tag, except it uses the same syntax as the allow iframe
attribute. WICG/client-hints-infrastructure#108

This CL is part of a series:
(1) Add support to chromium
(2) Add tests to devtools

Commit: false
Bug: 1334152
Change-Id: I19ce426da8a0aa158aad1fde24f3bd4f19581c52
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Jul 6, 2022
This adds support for the delegate-ch meta tag. It works like the
accept-ch meta tag, except it uses the same syntax as the allow iframe
attribute. WICG/client-hints-infrastructure#108

This CL is part of a series:
(1) Add support to chromium
(2) Add tests to devtools

Commit: false
Bug: 1334152
Change-Id: I19ce426da8a0aa158aad1fde24f3bd4f19581c52
@arichiv
Copy link
Collaborator

arichiv commented Jul 7, 2022

Heads up that in M105 not only will the new http-equiv="delegate-ch" syntax be added, but the older name="accept-ch" syntax will be removed. The even older http-equiv="accept-ch" that does not support delegation will not be touched as usage is too high.

@zcorpan
Copy link

zcorpan commented Jul 7, 2022

Heads up that in M105 not only will the new http-equiv="delegate-ch" syntax be removed

Did you mean supported?

@arichiv
Copy link
Collaborator

arichiv commented Jul 8, 2022

Heads up that in M105 not only will the new http-equiv="delegate-ch" syntax be removed

Did you mean supported?

Very sorry yes, meant to say 'added'. The comment has been updated

chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Jul 11, 2022
This adds support for the delegate-ch meta tag. It works like the
accept-ch meta tag, except it uses the same syntax as the allow iframe
attribute. WICG/client-hints-infrastructure#108

This CL is part of a series:
(1) Add support to chromium
(2) Add tests to devtools

Commit: false
Bug: 1334152
Change-Id: I19ce426da8a0aa158aad1fde24f3bd4f19581c52
@jonarnes
Copy link

jonarnes commented Sep 13, 2022

Just to recap, a new syntax like the following will be introduced

<meta http-equiv="delegate-ch" value="sec-ch-dpr https://foo.bar https://baz.qux; sec-ch-width https://foo.bar">

in M105. No changes to the M104 launch schedule will occur.

Just a note on the actual implementation vs. the syntax described in this thread and and elsewhere :

It's the content attribute that holds the client hints, not value. A working opt in would be:

<meta http-equiv="delegate-ch" content="sec-ch-dpr https://foo.bar https://baz.qux; sec-ch-width https://foo.bar">

Hopefully this saves some time/frustration...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants