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

Proposal: Parameterized features #163

Closed
clelland opened this issue May 8, 2018 · 7 comments
Closed

Proposal: Parameterized features #163

clelland opened this issue May 8, 2018 · 7 comments

Comments

@clelland
Copy link
Collaborator

clelland commented May 8, 2018

There are several behaviours which are being considered for feature policy which could benefit from having finer-grained controls than a simple binary on/off switch.

  • Allowed image formats
  • Allowed animatable CSS properties
  • Maximum image downsampling ratio
  • Minimum image information content (pixels per kb)
  • (more? As a hypothetical example, I've used usb here, with an allowed-vendor-ids parameter)

Currently, these can all only be implemented by having the browser enforce a particular value -- a fixed set of allowed formats or properties, or a fixed threshold ratio. There is no way for a developer to relax this fixed value at all, while still having some value enforced.

It could be useful for a developer to be able to declare "I am not using any images downsampled more than 3x", and have that policy enforced on its pages, while still being able to iframe a page which declares for itself "I am not using any images downsampled more than 2x".

Similarly, a top-level page could include a policy allowing only PNG, WebP, JPEG and GIF images, which would apply to all subframes, but a particular subframe could further restrict itself to just PNG and WebP if it wanted to, and both of these would be enforced by the browser.

I'd like to propose a method for declaring these 'threshold values' as parameters for feature policy declarations. These thresholds are feature-dependent, and can take several forms:

  • Numeric (ints or floats)
  • Numeric ranges (also int or float)
  • Token lists
  • Boolean (this is the current behavior of all existing features)

What would not be allowed under this proposal is for any subframe to relax the restrictions placed upon it by its parent frame. If the parent is restricted to just PNG images, the child cannot operate with a policy that allows PNG and JPEG, for instance. This means that there must be some partial order ("more restrictive") on the allowed values for any given feature. For any given feature, the policy for a child frame must be equal to or more restrictive than the policy of the parent.

Syntax strawman proposal:

We allow a parenthesized value, either:

  • directly following an origin or keyword, or
  • by itself -- which would imply that it applies to all allowed origins not otherwise mentioned

Examples

Simplest: Provide a single parameter value:

Feature-Policy: allowed-image-formats (gif,jpeg,png)
<iframe src="https://www.example.com/demo" allow="animations (transform,opacity,filter)"></iframe>

Combine these in separate directives:

Feature-Policy: allowed-image-formats (gif,jpeg,png); maximum-downscaling (3)
Feature-Policy: usb (0x3022,0x2048)

In all these cases, the parameter is applied to the default allowlist for the feature: * for the image features, 'self' for usb.

Overriding applying a parameter for a particular origin: (probably less useful, but included for completeness)

Feature-Policy: image-compression *(12) https://example.com(24) 'self'(10)
<iframe src="https://www.example.net" allow="max-downscaling http://www.example.com(2.5)"></iframe>

How do these combine?

When allowed in a frame at all, the threshold value for a feature should be a combination of the value granted to it by its parent and it's own declared policy. The operation that combines them must obey the "more restrictive" relation. For token lists, this should be set intersection; for numeric values, it should be either min or max, depending on how the feature is defined. (For existing boolean properties, the operator is logical AND)

Examples (In all cases, Frame A embeds Frame B):

Intersection

Frame A has allowed-image-formats (gif,jpeg,png)
Frame B declares allowed-image-formats (png,jpeg,svg)
=> Frame B is granted allowed-image-formats (png,jpeg)

Frame A has usb (0x1234,0x2345)
Frame A embeds Frame B with allow="usb" (no vendor ids)
=> Frame B gets usb (0x1234,0x2345)

Frame A has usb (0x1234,0x2345)
Frame A embeds Frame B with allow="usb (0x2345,0x3456)"
=> Frame B gets usb (0x2345)

Numeric (min)

Frame A has image-compression (12)
Frame B declares image-compression (20)
=> Frame B gets image-compression (12)

@triblondon
Copy link

triblondon commented Feb 2, 2019

Having just come across the case of lazyload, I'm concerned here about what we do when a policy supports parameterised values but they are not used. You're implying in the sketch above that these policies would require a param, since it presumably doesn't make sense to say:

Feature-Policy: allowed-image-formats *

This implies very strongly that all image formats are allowed, but in fact applies the allowed-image-formats policy, with no parameter value, to all origins, with... undefined (?) results.

The case of lazyload is more problematic, because it has shipped, I think without support for params (I'm inexperienced at reading chromium diffs so apologies if I'm misreading). If that's correct, as of today it's a boolean, and one that doesn't seem to make any sense to me, but I see how it would potentially make sense if it were required to take a value.

@triblondon
Copy link

Another interesting example to add to the list here is legacy-image-formats, which is defined in a modification to an existing policy explainer, in an unmerged fork of the feature-policy repo, but has nevertheless shipped in Chrome under that name.

In the sketch of params above, there's an example of an allowed-image-formats policy, which seems like it is the same thing renamed? I think we should consider thrashing out these naming shenanigans in detail, because otherwise FP is going to cause a lot of confusion.

@loonybear
Copy link
Contributor

Hi, @triblondon, long story short, we initially implemented legacy-image-formats policy but decided to unship it and combine it with unoptimized-images policy.

Essentially what will happen is for image of non morden format, we will set the allowed size for the image's file size to 0, therefore disabled.

We are also thinking of creating 2 policies: unoptimized-lossy-images and unoptimized-lossless-images, and have different threshold for the allowed size for the images.

Please let me know what you think of the policies. Thanks

@triblondon
Copy link

I think first of all there should be more collaboration on these. I’ve spent a week writing a demo of every feature policy currently supported by chrome, and I’m finding fragments of spec in readmes, issues, unmerged PRs, spec text of non-FP specs, a couple of google docs... this makes it very hard to assess edge cases and side effects when there’s a proposal to the framework of feature policy itself, such as parameterised values.

On the new policies, in principle those names seem clear and are identifying a behaviour that can be allowed or denied in a binary way, so they fit the pre-params mental model of FP pretty well.

@RByers
Copy link

RByers commented Feb 22, 2019

@triblondon are you including the not-yet-on-by-default feature policies in your analysis? The blink launch process requires that all behavior enabled by default in chromium be precisely defined in some specification (including, if necessary, forks tracked by an active PR) and to have conformance tests in web-platform-tests. By it's nature feature-policy is cross-cutting (the right spec for a specific policy is often the spec that defines that feature, not an FP-specific spec). Generally we also try to document everything on MDN too - but I can believe we've got some catching up to do there for feature policy.

I know there's a lot of experimental policies not yet shipping on-by-default, and so lots of design discussions elsewhere. I believe that's all @loonybear is referring to when she mentions "unshpping legacy-image-formats - that's only ever been "shipped" behind an experimental flag AFAIK). So you should not have to rely on READMEs, Google docs, github issues etc. to understand any policy that's enabled by default in chromium (only to participate in the early incubation / brainstorming of new ideas well in advance of anything shipping). If you find counter examples that have somehow slipped through blink's launch requirements, I'd love to know (either as an issue here, or even by replying to the relevant intent-to-ship thread on blink-dev where the launch decision was made).

I agree though that it would be great to see more investment and collaboration with other browser vendors. I just don't think the web can afford for us to just wait for there to be sufficient interest. Obviously the chromium team should be doing everything practical to engage and collaborate wherever there is a desire backed by real engineering investment.

@triblondon
Copy link

are you including the not-yet-on-by-default feature policies in your analysis?

That's very true, I am. There are others that do ship by default and are somewhat loosely defined, in a non-normative document anyway. Since this issue relates to the image policies, though, I take your point.

@clelland
Copy link
Collaborator Author

Closing; with the Permissions/Document policy split, all parameterization has moved to Document Policy, which has built in support and syntax for it.

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

No branches or pull requests

5 participants