Re: On optionality

On Nov 27, 2012, at 5:50 PM, Ryan Sleevi wrote:

> On Tue, Nov 27, 2012 at 4:23 PM, Mark Watson <watsonm@netflix.com> wrote:
>> All,
>> 
>> This came up a lot in the recent discussion, but we did not have time to discuss it on the call yesterday.
>> 
>> All optional features are a pain for application developers, but I think we need to distinguish between two types of optionality:
>> (a) features that are just optional for UAs to implement
>> (b) features which are not present on all devices
>> 
>> It is in our power to reduce or eliminate features of type (a) from our specification, but the fact that different devices have different capabilities is just a fact of life over which we have limited influence. It would be ridiculous, for example, for us to say that because *some* devices support 3D video, *all* must support it. With respect to such features, there are three possibilities:
>> (i) don't provide support for any such features in the specification
>> (ii) require that where device support is absent, the UA must provide fall-back support in software
>> (iii) the feature is optional in the specification (with some kind of capability discovery, although this could just be the possibility to return NOT SUPPORTED to some operation).
>> 
>> (i) is a rather draconian least-common-denominator approach that would make our gadget lives rather dull (IMO).
>> 
>> (ii) should be preferred wherever possible.
>> 
>> But there remain some cases where (ii) is not possible, and then we have (iii). (ii) is not possible where the feature relies on hardware support (by definition). Whether a sensible software fall-back exists needs to be examined on a case-by-case basis, but sometimes there will be nothing of value that can be done without the hardware capabilities.
> 
> And in the realm of DAP, in the realm of WHATWG, and in the realm of
> WEBAPPS, there is a common pattern for this:
> 
> navigator.foo
> 
> This allows trivial detection of a feature:
> 
> var foo = navigator.foo;
> if (foo == undefined) {
> // not supported
> }
> 
> A reduced example of this can be seen in [GAMEPAD], which should be a
> minimal spec for perusing.
> 
> In some cases with WHATWG (and to a lesser degree, whatever HTMLWG has
> copied from the Living Standard in WHATWG), this may show up with
> explicit methods for gaining a specific context or determining support
> for it.
> 
> For example, from [CANVAS]
> 
> var foo = canvas.getContext('webgl', ...);
> // var foo now contains a WebGLRenderingContext
> 
>> 
>> The model of optionality we have in our specification now is Algorithms. It's wrong to characterize this as "void *dovoid(void*)". What we have is several instances of "<explicit type> do<explicit operation>( void *, <other explicit parameters> )". Yes, the first argument is completely open (The AlgorithmIdentifier, containing AlgorithmParameters), but what the method does, the return type and the input message data are explicitly defined. And the situation is the same for all our operations.
> 
> No, the API contract proposed **is** "Any DoSomething(Any, ...)" -
> simply relying on textual descriptions of possible values for "any".
> This is the exact same, from a programmers perspective, as "void*
> dosomething(void*, void*)". The fact that a cast occurs within the
> function itself is irrelevant from the perspective of any developer
> who is using this API. They cannot infer the expected types,
> arguments, or parameters. They cannot have any reliable guarantee on
> the error mode when things fail. Nor can they even proactively
> determine if something is supported, not implemented, broken,
> whatever.

Hmm, so you are saying that because the function name says "encrypt" and the normative text says that the operation to be performed is encryption, the fact that the AlgorithmParameters are completely open and that the result has "any" type means you could abuse this method for anything at all.

This seems to apply to all our methods, though I am not sure it is serious.

> 
> When we talk about device specific features, the end-user/developer
> needs to be at the forefront. They need to be able to easily detect if
> a feature is available. Whether this is
> "canvas.supportsContext('webgl')" or
> "navigator.{gamepad,battery,device}", it provides concrete objects and
> interfaces that can be used by developers, with strong guarantees
> enforced not by prose, but by the interface itself.

Ok, so if KeyStorage is no longer used for keys created with the WebCrypto API (they are stored in IndexedDB) and only for pre-provisioned keys, moving the keys attribute from Crypto to navigator would address this issue, right ?

> 
>> 
>> This might not be the best model. Indeed we have an ISSUE to be clearer about algorithm parameters vs. operation inputs, which if solved could lock things down ink a cleaner fashion.
> 
> I strongly believe the two issues are orthogonal, as expressed before.
> The needs for algorithms and the needs for key discovery, while
> similar conceptually similar, do not require nor necessarily benefit
> from shared paradigms.

Well, obviously: "require" and "*necessarily* benefit" are both rather strong conditions. But that doesn't mean that following the same paradigm isn't a reasonable thing to do.

> 
> As one specific example, key discovery is dependent on the UA the the
> parameters, whereas any cryptographic operation, it's dependent on the
> UA, the parameters, and the key object itself (and its
> implementation). It is this latter fact that resulted in the proposed
> API, which itself absolutely needs improvement and/or reworking.

This seems like a minor difference to me.

> 
>> 
>> For the issue of retrieving pre-existing keys, there is certainly a connection with hardware. And there is diversity in what is supported by devices, just as there is diversity in algorithm support. And there is no imperative to support everything day one (just as with algorithms). So I find it hard to understand why the existing model for optionality shouldn't apply here too.
> 
> As shown in DAP, as shown in WHATWG, as shown in WEBAPPS, the approach
> for such optionality has been accomplished by separate specifications.

There's a difference between essential independent blocks of functionality and the much more integrated situation we have here. We are talking about finding Key objects which are specified in our main draft. There are a variety of types of Key object that the UA/device supports, they may differ in the algorithms they support, in how they are created and in how they are discovered.

> Consider, for example, the Core Device interface [CORE-DEVICE], which
> is then extended by various specs [MESSAGING-API]. Or consider Web
> Intents, which defines a core API but *does not* specify what or how
> the intent should behave. Instead, that's left for specs like
> [PICK-MEDIA] or [CONTACTS].
> 
> As you can see, the web platform already has a number of ways to deal
> with this, and we arguably should not go create yet another one.

We have no choice with respect to algorithms.

> 
> I agree with your sentiment - we do not want further optionality.
> However, as you can see by the numerous examples I've provided,
> optionality has been approached by saying that implementers MUST
> implement every part of the interface, and defining that interface in
> an independent specification (GAMEPAD, CORE-DEVICE, MESSAGING-API). If
> a U-A doesn't implement the spec, obviously they don't implement the
> interface either, and developers can easily discover this.

I'm not opposed to separate specifications, but I'm having trouble understanding the criteria for drawing the line. Do you want a separate spec for each crypto algorithm ? Or should we define "families" of algorithms and have one spec for each "family". Is discovery of all kinds of pre-existing key a single capability, or are pre-provisioned origin-specific keys separate from keys on smart-cards ? (We certainly can't require devices that support one to support the other). Coarser-grained optionality is certainly better than fine-grained. When the grain is course enough to justify a separate spec, that is obviously the way to go.

> 
> In the few cases where extensible APIs are provided (CANVAS,
> WEB-INTENTS), the primary spec merely notes the normative behaviour of
> the extensible API, and it's up to some other spec to define how that
> extensible API behaves [WEBGL, PICK-MEDIA, CONTACTS].
> 
> Note that even in the case of something like [CANVAS], where the
> context is an extensible string identifier (arguably similar in
> concept, but not at all in implementation, to AlgorithmIdentifier),
> there still exists the fundamental means to query support, with as
> limited information as possible, from a user agent [CANVAS-SUPPORTS]

I certainly agree that straightforward capability discovery is good.

> 
> This is even true for APIs with double discoverability (CANVAS ->
> WEBGL, WEBGL -> WEBGL-EXTENSION), which exposes a DOM-friendly
> discovery API (getSupportedExtensions), which uses a separate registry
> [WEBGL-REGISTRY], and which uses concrete interface types with
> submethods for extension (eg: [DEBUG-SHADERS]).
> 
> As such, as stand by my objections to the previous proposal from Netflix:
> * The core spec (as to be implemented by all user agents) does not
> need to and should not reference features that are not universally
> implementable, beyond acknowledging they may exist. Arguably, this
> argument could (and eventually will have to) extend to Algorithms as
> well.

Yep, I don't see how you avoid that extension if that is your logic. It would be good to see a concrete proposal for how you would like to address that. If the group agrees then I'd be happy make my proposal align with that.

> * Extensibility of the DOM has historically been accomplished by
> providing concrete interfaces with concrete methods, easily queried by
> developers (to see if a user agent supports it), with as strict a type
> enforcement as possible (eg: methods with concrete signatures)

We could obviously ensure that the key discovery method (asynchronously) returns a Key object, if that helps. For the input params we have the same problem as algorithms.

> * APIs which are specific to a particular device class or category
> (such as [VIBRATION, BATTERY, LIGHTS, NETINFO, GAMEPAD]) have
> traditionally been incorporated within secondary specifications and
> semi-independent timelines.
> 
> My broader objections regarding "generic" key discovery are this.
> There are many needs for key discovery beyond the pre-provisioned ID
> case (for example, certificate based discovery). If we're going to
> propose a generic interface, then we MUST follow the "rule of three"
> of software design - discussing *at least* three discovery methods to
> make sure our API is actually going to be suitable for all them and
> behave in an expected way - for the web platform and for developers.

Are we applying this rule consistently ? Clearly it's desirable, but at some point we are contribution driven.

> 
> This is why I speced out so many algorithms - to try and enumerate the
> many different types and requirements (for example, GCM's
> authentication tag, PBKDF2's password input, DH's key agreement, HMAC
> verification), so that we can actually compare and contrast the API
> and its semantics. And these were "simple" exactly because it's
> universally agreed upon what the "RSA" algorithm means - which is not
> true at all for key discovery.

At least for the case we proposed (origin-specific named keys), its as simple as access to a set of ( name, key ) pairs. I described it in detail in my proposal, but I could add more detail.

Anyway, as I said on the call, I'd be happy to move KeyStorage to a new specification, with the intent that it be worked on (hopefully replaced with something substantially improved) there by those with interest, provided that was on the basis that people interested in that could make progress without encountering objections to the work per se. I think to execute that move we need to create a draft first, so we can see and discuss the exact scope of the new specification before moving material from the main one.

…Mark

> 
>> 
>> What I hope we can do is distinguish between arguments about optionality generally - and how we can reduce it in our specification - and arguments about retrieving pre-existing keys specifically.
>> 
>> …Mark
>> 
>> 
>> 
> 
> [GAMEPAD] http://www.w3.org/TR/gamepad/#navigator-interface-extension
> [CANVAS] http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-canvas-getcontext
> [CORE-DEVICE] http://dev.w3.org/2009/dap/device/
> [MESSAGING-API] http://www.w3.org/TR/messaging-api/
> [WEB-INTENTS] http://www.w3.org/TR/web-intents/
> [PICK-MEDIA] http://www.w3.org/TR/gallery/
> [CONTACTS] http://www.w3.org/TR/contacts-api/
> [CANVAS-SUPPORTS]
> http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-canvas-supportscontext
> [LIGHTS] http://www.w3.org/TR/ambient-light/
> [VIBRATION] http://www.w3.org/TR/vibration/
> [NETINFO] http://www.w3.org/TR/netinfo-api/
> [BATTERY] http://www.w3.org/TR/battery-status/
> [WEBGL] http://www.khronos.org/registry/webgl/specs/latest/
> [WEBGL-EXTENSION] http://www.khronos.org/registry/webgl/specs/latest/#5.14.14 /
> [WEBGL-REGISTRY] http://www.khronos.org/registry/webgl/extensions/
> [DEBUG-SHADERS]
> http://www.khronos.org/registry/webgl/extensions/WEBGL_debug_shaders/
> 

Received on Wednesday, 28 November 2012 03:43:53 UTC