W3C

Web Introducer

Editor's Draft 20 May 2011

Editors:
Tyler Close (Google)
Rajiv Makhijani (Google)
Mark Seaborn (Google)
Kenton Varda (Google)
Johan Apelqvist (Sony Ericsson)
Claes Nilsson (Sony Ericsson)
Mike Hanson (Mozilla Labs)

Abstract

An Introducer enables Web content to discover a user's personal resources, no matter where they are hosted, and gain permission to interact with them via a one-click user interaction.

Status of This Document

This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at http://www.w3.org/TR/.

This document is subject to change without notice. This document has no formal standing within W3C.

This document was produced by a group operating under the 5 February 2004 W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.

Table of Contents

1 Introduction

This section is non-normative.

Today's users have a great variety of personal resources beyond the files stored on their local computing device. Web sites maintain user collections of photos, email, contact information, documents, multimedia and other types of content. In addition to static content, Web sites also offer interactive resources such as discussion forums and event planning. The level of interactivity and personal data on the Web continues to increase. Today's computing devices are also typically equipped with many sensors, such as a camera, microphone and GPS. These sensors enable quick creation of new resources. In such a resource rich environment, Web content might want to support interaction with other resources without advance knowledge of where these resources are hosted or how they are created. To meet this need, we introduce a mechanism that enables:

Other specifications define how Web content then interacts with a service after the two are introduced. For example, a specification for a social bookmarking protocol defines how Web content transmits a bookmark to a bookmarking service. The Introducer addresses the orthogonal problems of how Web content discovers which bookmarking service to interact with and how the user grants permission for this interaction. The output of this introduction is a messaging channel that enables the Web content to interact with the user chosen service.

To ensure a lightweight user experience, no prior coordination between Web content and specific services is required. All coordination for discovery and user consent is accomplished through a single user gesture at the time Web content requests an introduction to a service. This user gesture occurs within the requesting Web content and does not require any page navigation.

Since a lightweight user experience is enabled, it is feasible for users to make fine grained resource sharing decisions and thereby maintain control and privacy. In simple data transfer scenarios, the user can easily enable Web content to interact with a service without granting any long-lived permissions.

2 Conformance Criteria

There are three distinct perspectives to this specification, that of: a service, a client of a service or a user-agent. A web application developer might approach this specification from either or both of the first two perspectives. This specification is written for both web application developers and user-agent implementers.

As well as sections and appendices marked as non-normative, all diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative.

In this specification, the terms MUST and MUST NOT are to be interpreted as described in [RFC2119].

Conformant Web content implements all the requirements listed in this specification that are applicable to Web content.

A conformant user-agent implements all the requirements listed in this specification that are applicable to user-agents.

3 Model

This section provides an overview of the interaction model and definitions of the various actors and artifacts involved in these interactions.

Client ↔ Introducer ↔ Service

Figure 1: The Introducer intermediates the introduction of a Client to a Service. After the introduction, the Client and the user chosen Service can exchange postMessage events.

We aim to facilitate user directed introduction of Web content to services. A Service is Web content that provides access to resources. A Client is Web content that asks to be introduced to a described Service. A Service is described by an intent list, each of which is a string identifying an interaction pattern between a Client and a Service. An Introducer is the part of a user-agent that intermediates an introduction to connect a Client to a user chosen Service.

A successful introduction follows the workflow depicted in Figure 1:

  1. A Client initiates an introduction by invoking introducer.connect(…) with a list of each intent that describes the requested Service.
  2. The Introducer presents a Chooser that lists each installed Service that is a match for any requested intent.
  3. The user chooses a Service from the options listed in the Chooser.
    1. The Introducer loads the user chosen Service in the Client specified [HTML] <iframe>.
    2. The Introducer creates an [HTML] MessageChannel for communication between the Client and the user chosen Service.
    3. The Service content loaded in the <iframe> invokes introducer.accept(…) to get the corresponding [HTML] MessagePort for sending messages to the Client.
    4. The Client content that invoked introducer.connect(…) is given the corresponding MessagePort for sending messages to the chosen Service.
  4. The Client and Service exchange an arbitrary number of messages, each closing their MessagePort when done.

When performing an introduction, the Introducer creates a communication channel between the Client and the user chosen Service, but does not reveal the Service's identity to the Client. A user's list of Services is confidential information to be withheld from Clients. A Client might similarly withhold its identity from a Service by initiating an introduction from a sandboxed [HTML] <iframe> without origin. The Introducer does not prevent either party from subsequently choosing to reveal its identity in exchanged message data.

Although there might exist a great number of Services, it is expected that any particular user will only install a small subset of them. Consequently, the list of Services an Introducer presents to a user during an introduction is expected to be relatively short. To keep this list short, a Service should declare a tight description of supported intents. This declaration enables the Introducer to omit listing a Service for an introduction the Service is not a match for.

4 Introducer API

Web content interacts with a user-agent's Introducer via an object accessed from the read-only introducer attribute of the window object.

[NoInterfaceObject]
interface WindowIntroducer {
  readonly attribute Introducer introducer;
};

DOMWindow implements WindowIntroducer;

The introducer object has the following interface:

[NoInterfaceObject]
interface Introducer {
  void install(
    in DOMString icon,
    in DOMString name,
    in DOMString home,
    in VoidCallback callback);
  void uninstall();
  void offer(
    in DOMString id,
    in DOMString label,
    in DOMStringList supports,
    in DOMString window,
    in DOMString? frame);
  void rescind(
    in DOMString id);
  void connect(
    in Element anchor,
    in Element frame,
    in DOMStringList wanted,
    in IntroducerConnectCallback callback);
  void accept(
    in DOMString installation,
    in IntroducerAcceptCallback callback);
};

[Callback=FunctionOnly, NoInterfaceObject]
interface IntroducerConnectCallback {
  boolean handleEvent(
    in MessagePort service,
    in DOMStringList agreed,
    in boolean framed);
};

[Callback=FunctionOnly, NoInterfaceObject]
interface IntroducerAcceptCallback {
  boolean handleEvent(
    in MessagePort client,
    in DOMString origin,
    in DOMStringList wanted);
};

Some of the attributes defined in the Introducer API have a URL value. This specification does not constrain the form of the URLs that are used. The URL space of each server is controlled by that server, and this protocol imposes no further constraints on that control. Further, there is no expectation that any URL is constrained to any particular [origin]. A Service might legitimately delegate any aspect of its functionality to a resource in some other [origin].

The API is described in detail in the following sections.

5 Service Installation

Web content invokes the Introducer's install method to create or update its [origin]'s installation. An installation associates a name and icon with an [origin] and enables it to offer Services.

For example, an installation is created with an invocation like:

introducer.install(
  'data:image/png;base64,iVBORw0KGgoAAAANSUhEU…'
  "Example Stuff",
  'https://service.example.com/home/#s=qwerqwer',
  function () {
    // We've been installed!
    introducer.offer(
      'bookmark',
      "Like it!",
      [ 'org.example.bookmark' ],
      'https://service.example.com/like/window#s=zxcvzxcv',
      'https://service.example.com/like/frame#s=zxcvzxcv');
    introducer.offer(
      'music',
      "My Music",
      [ 'org.example.link.mpeg', 'org.example.link.wav' ],
      'https://service.example.com/audio/#s=bnm7bnm7');
    introducer.offer(
      'voice',
      "My Voicemail",
      [ 'org.example.link.wav' ],
      'https://partner.example.net/voicemail/window',
      'https://partner.example.net/voicemail/frame');
  });

The first argument to install is a link to an image describing the caller's [origin]. The image should be a 16x16 pixel icon in a commonly supported format such as PNG.

The second argument to install is alternate text for the specified icon.

The third argument to install is a link to additional user interface for the installation. The referenced page might have a history of Client interactions with offered Services.

The fourth argument to install is a callback invoked if installation succeeds.

Each [origin] can have only a single installation. The install method is used both to create a new one and to update an existing one. When install is invoked, the specified icon is retrieved. If the retrieved image data and the specified name are identical to those in the caller's installation, the home link is replaced by the one specified in the install invocation and the callback is invoked. In all other cases where installation is supported, the Introducer creates a presentation that enables the user to approve the installation. If the user approves, the installation for the caller's [origin] is updated with the retrieved icon data, name and home link and the callback is invoked. If installation is not supported or is rejected or will not be acted upon, the callback is never invoked. The install method does not affect an installation's Service configuration.

Web content invokes the Introducer's offer method to update a Service in its [origin]'s installation. This update is completed silently without any presentation by the user-agent.

The first argument to offer is a character string identifier for the offered Service. This identifier MUST be unique within an installation. These identifiers are compared using the case-sensitive, simple string comparison, defined by [HTML].

If the installation for the caller's [origin] already includes a Service with the specified id, it is replaced by the one specified in the offer invocation; otherwise, a new Service is added. If there is no installation for the caller's [origin], the offer invocation is ignored.

The second argument to offer is a short, human meaningful name for the offered Service.

The remaining arguments to offer are described in the following sections.

Web content invokes the Introducer's rescind method to delete a Service in its [origin]'s installation.

The first argument to rescind is the id of the Service to delete. If there is no corresponding Service, the invocation has no effect.

Web content invokes the Introducer's uninstall method to delete its [origin]'s installation. When this method is invoked, the installation for the caller's [origin], including all installed Services, is deleted. If there is no corresponding installation, the invocation has no effect.

6 Connection

A Client invokes the Introducer's connect method to ask for a connection to a Service.

The first argument to connect is an element that serves as a positioning hint for any presentation made during handling of the request. The Chooser will be presented near to this element.

If the second argument to connect refers to an <iframe> that can be navigated by the caller according to the rules defined in [HTML], then the chosen Service is given the opportunity to load content there.

The Client should make use of the [HTML] sandbox attribute when allowing a Service to be loaded in an <iframe>.

The third argument to connect is a list of each intent that describes the kind of wanted Service.

The fourth argument to connect is a callback invoked after a successful connection has been made, or if there is no matching installed Service. This callback accepts the following three arguments:

  1. If the connection attempt was successful, the first callback argument is an [HTML] MessagePort open on the chosen Service. The Client should close() this port when done messaging with the Service. This argument will be null if there is no matching Service.
  2. The second argument to the callback is an array of each wanted intent that the chosen Service supports. The array has the same relative order as the wanted array.
  3. The third argument to the callback is true if the chosen Service was loaded in the provided <iframe>.

For example, a Client's request for an introduction to a social bookmarking Service looks like:

introducer.connect(anchor, frame, [ 'org.example.bookmark' ],
                   function (service, agreed, framed) {
    if (!service) {
      // Introduction failed, try using a partner site.
      …
      return;
    }

    if (framed) {
      // Service is using the provided IFRAME, so make it visible.
      frame.style.display = 'block';
    }

    // Listen for messages from the chosen Service.
    service.onmessage = function (event) {
      …

      service.close();
    };

    // Send a message to the chosen Service.
    var hello = …
    service.postMessage(hello);
  });

Successive calls to connect cause prior ones to be dismissed. In particular, a prior call's callback will never be invoked. However, a subsequent call to connect has no effect on a MessageChannel created by a prior successful introduction. Only a connect call that the user has not yet acted upon is affected by a successive call.

7 Service Filtering

In response to a connect invocation, the Introducer enables the user to choose any installed Service that supports at least one intent wanted by the Client.

The third argument to offer is a list of each supported intent. A Service is a candidate for being chosen in an introduction if at least one of these is the same as at least one of the entries in the third argument to the connect invocation. Entries are compared using the case-sensitive, simple string comparison, defined by [HTML].

8 Service Loading

If a Service is chosen for an introduction, it is loaded by the Introducer.

The fourth argument to offer is a URL for a top-level window opened for an introduction. The user-agent MUST NOT unload the Client when loading this Service window. The Service window has no opener browsing context, in the terminology of [HTML].

The fifth argument to offer is an optional URL used to navigate an <iframe> for an introduction.

Either the frame or the window is loaded for an introduction, not both. Loading in an <iframe> only happens if the Service specifies a frame URL and the Client provides an <iframe> in its connect invocation. In all other cases, the Service is loaded in a window.

When loading in an <iframe>, the size, position and visibility is determined by the Client. The Service might have expectations for the size of the <iframe> depending on the intent it is servicing. These expectations are defined by the specification of that intent.

Whether loaded in an <iframe> or a window, a Service begins by invoking the Introducer's accept method to enable messaging with the Client.

The first argument to accept is the [origin] of the Service's installation.

The second argument to accept is a callback invoked if the connection succeeds. The connection will fail if the first argument is not the same as the [origin] of the Service's installation. The callback has the following arguments:

The first callback argument is an [HTML] MessagePort open on the Client. The Service should close() this port when done messaging with the Client.

The second callback argument is the [origin] of the Client.

The third callback argument is a list of the Client's wanted intents.

For example, a Service should contain code like:

introducer.accept('https://service.example.com',
                  function (client, origin, wanted) {

    // Listen for messages from the Client.
    client.onmessage = function (event) {
      …
    };

    // Send a message to the Client.
    var hello = …
    client.postMessage(hello);

    …

    client.close();
  });

9 Security Considerations

This section offers advice to user-agent authors.

9.1 Service Phishing

A malicious Service might try to impersonate one of the user's other installed Services by copying its icon or name. If the attacker succeeds, the user might inadvertently direct a connection request to the wrong Service. To guard against this attack, a user-agent could present the offered icon and name during installation, along with those from current installations, and ask the user to only approve the installation if the offered identifiers are distinct and memorable. The user could also be given the opportunity to customize these identifiers, setting an icon or name of their choosing. This implementation ensures the identifiers presented during an introduction are the ones the user expects and are not vulnerable to phishing between Services.

9.2 Client Misattribution

When considering how to respond to an introduction, a user should take into account their relationship with the Client who will be accessing the Service. This consideration is only possible if the user can identify the Client. The Introducer MUST only present an introduction when the user can identify the corresponding Client. For example, [HTML] supports an <iframe> element where content from another origin can be presented but where there is typically no identification of the content's origin. Presenting a connect request from the content of a cross-origin <iframe> might be misleading for the user if it appears as if the introduction is for the top-level page. To guard against this misunderstanding, the Introducer should only support a connect request made from a cross-origin <iframe> if the presentation of the Chooser enables the user to understand what part of the page is making the request. This might be done by placing the Chooser near to the requesting content. A small handheld device with limited display space might be unable to use this technique and so should use some other technique or prohibit a connect request made from a cross-origin <iframe>.

9.3 Clickjacking

The Chooser offers the user a menu of Services to choose from. Whether or not to choose a Service and which one to choose, are decisions made by the user. Malicious content might attempt to force the user's hand in these decisions using a [clickjacking] attack. The user-agent MUST protect the Chooser against clickjacking attacks. For example, the user-agent should prevent a Client from controlling any transparency setting on the Chooser. Malicious content might also try to prime the user to click in the area where a Chooser will soon appear. To guard against this attack, a user-agent might require a different user gesture for choosing a Service, or impose a "cooling off" timeout before a choice can be made.

10 Resource Definition

This section is non-normative.

This section offers advice to resource authors.

10.1 Coordinate with a globally unique intent

Clients and Services coordinate expectations for MessageEvent exchange using an intent. There is no single, global registry of every intent and no intent is pre-defined. There is also no required syntax for the content of an intent. When making a new kind of resource available to Clients, a Service defines a new, globally unique intent. A globally unique intent might be generated using a UUID algorithm or a registry such as the DNS. A Service seeking to be compatible with existing connect requests lists the Client's wanted intent in its supports declaration. In this way, an intent might become widely recognized among Clients and Services.

10.2 Fine Grained Resources

When deciding how to provide access to some computer artifact, aiming for a finer granularity can often make access control issues more easily solved. For example, in the Examples section of this document, a design for populating a user's activity stream is presented. Rather than giving Web content full access to a user's activity stream, the presented design instead only allows the Web content to add a single bookmark. Since some user gesture is required for the user to signal that they want to bookmark an item, the Introducer uses that same gesture to determine the user's consent to add the item to a chosen social bookmarking site. By matching the granularity of the access grant to the granularity of the user action and intent there is no need for additional user interaction for security, such as a confirmation dialog. There is also no excess grant of permission that Web content might abuse to fill the user's activity stream with unwanted entries. Other kinds of computer artifacts can similarly be subdivided into fine grained resources that match the granularity of typical user interaction patterns.

10.3 Revocation

The Introducer sets up communication channels between windows in a user-agent. These communication channels are closed when the corresponding windows are closed, thus revoking a Client's access to a Service. A Service can give a Client more durable access by passing a URL in a message. The Client might then use this URL to re-establish communication with the Service at a later time. In this case, the Service should keep track of long-lived permissions granted to Clients and provide a user interface for reviewing and revoking outstanding permissions. This user interface should be accessible from the page referred to by the home attribute of the Service's installation.

10.4 Three Party Security

Typical Web page interactions are only two party client-server interactions between a user's browser and a visited Web site. In contrast, a complete Introducer interaction involves at least three parties: the user's browser, a Client and a Service. Scenarios involving more than two parties have security risks that are not present in simpler two party scenarios.

For example, a malicious Service could pass a URL for a provided resource to a Client. The URL identifies a resource the Client has permission to use, but the Service does not. If the Client sends requests including cookies to this URL, a Client resource might be unexpectedly modified at the direction of the malicious Service. To defend against this attack, the Client should not include its credentials in requests made using a URL received from a Service. Such requests should only be made using an API that conforms to the Uniform Messaging Policy [UMP].

The described attack cannot be defended against by inspecting the provided resource URL, since it might redirect to another URL. Clients should also keep in mind the Web's URI opacity good practice and so not infer any properties of the referenced resource based on the content of a provided resource URL.

10.5 Login / Logout

On a logout page, a site might replace its current installation with one where all services specify a login window. A login page then reverts the installation to its logged in state.

If a Service additionally wants to employ second-factor user authentication, this can be done before installation or using a Service's window property to refer to a page that prompts for the second factor.

10.6 User Interaction Without a Trusted Path

Any display made by a Service frame loaded for an introduction is vulnerable to tampering by the Client. The <iframe> can be moved around, resized, closed, made transparent, overlayed with other content or immitated by the Client's own content. There are very few interactions that can be safely completed within these constraints if the Client might be an attacker. A Service <iframe> presentation is only an option when the Client does not have an incentive to tamper with the presentation. When incentives do not align in this way, the Service should use a window for protected user interaction. For example, a Service that collects a user authentication credential should use a window. Collecting comment text from the user might be done in a frame.

10.7 Offline Use

The Web Introducer is designed to support offline introduction. To make use of this support, both the Client and the Service frame or window need to support offline use. The Service could then make use of local storage APIs supported by the user-agent to buffer data received from a Client until a network connection is again available.

Examples

This appendix is non-normative.

This section illustrates potential uses of the Introducer in a variety of scenarios.

Link Sharing

In this scenario, a Client adds a hyperlink to the user's link sharing service.

When the user's mouse hovers over a 'Like' button near presented content, the Client makes a connect invocation like:

introducer.connect(anchor, frame, [ 'org.example.bookmark' ],
                   function (service, agreed, framed) {
    if (!service) {
      // Introduction failed, try using a partner site.
      …
      return;
    }
    if (framed) {
      // Service is using the provided IFRAME, so make it visible.
      frame.style.display = 'block';
    }

    // Listen for messages from the chosen Service.
    service.onmessage = function (event) {
      …

      service.close();
    };

    // Send shared URL to the Service.
    service.postMessage({
      href: 'http://client.example.org/article123#comment45'
    });
  });

In response to this connect invocation, the Introducer presents a Chooser near the referenced anchor, listing each installed Service that supports the org.example.bookmark intent. The user clicks on one of the menu entries, which closes the menu and completes the user interaction in a single click.

The Introducer invokes the connect callback, enabling the Client to send the shared URL to the chosen link sharing Service.

The chosen Service receives the hyperlink using code like:

introducer.accept('https://service.example.com',
                  function (client, origin, wanted) {
    client.onmessage = function (event) {
      // Got the URL!
      var url = event.data.href;
      …

      // Optionally tell the client where the hyperlink was received.
      client.postMessage({
        receivedBy: 'service.example.com'
      });
      client.close();
    };
  });

SMS Events

In this scenario, a Client receives access to some of the user's inbound SMS messages.

To request a message stream, the Client makes a connect invocation like:

introducer.connect(anchor, null, [ 'org.example.sms' ],
                   function (service, agreed) {
    if (!service) {
      return;
    }

    // The Service sends a message event for each SMS message.
    service.onmessage = function (event) {

      // SMS message data is the event.data
      display(event.data);
    };
  });

In response to this connect invocation, the Introducer presents a Chooser of each candidate Service. The user chooses the local device Service. The Introducer opens a new window on the chosen Service's window URL. On this page, the user chooses contacts whose SMS messages will be forwarded to the Client. Whenever a new SMS message arrives, and its sender corresponds to one of the contacts chosen by the user, the Service forwards the message event to the Client.

File Chooser

In this scenario, a Client receives access to an audio file.

To request an audio clip, the Client asks for an introduction to an audio clip Service:

introducer.connect(anchor, null,
                   [ 'org.example.link.mpeg', 'org.example.link.wav' ],
                   function (service, agreed, framed) {
    if (!service) {
      return;
    }

    // Service sends a list of audio clip links after the
    // user has selected them.
    service.onmessage = function (event) {

      // Add each audio clip to our page.
      var clips = event.data;
      for (var i = 0; i !== clips.length; i += 1) {
        if (/^(https?|chrome):/i.test(clips[i].href)) {
          // play the audio clip
          var player = document.createElement('embed');
          player.setAttribute('src', clips[i].href);
          document.body.appendChild(player);
        }
      }
      service.close();
    };
  });

In response to this connect invocation, the Introducer presents a Chooser. The user chooses the 'music' Service. The Introducer opens a new window on the chosen Service's window URL. This page contains:

introducer.accept('https://service.example.com', function (client) {
    var okbutton = …
    okbutton.onclick = function () {
      // Send user selected links to the Client.
      var selections = …
      client.postMessage(selections);
      client.close();
    };
  });

In response to the accept invocation, the Introducer invokes the corresponding connect callback. At that point, Client and Service are connected by an [HTML] MessageChannel. The 'music' Service eventually sends the Client a list of user selected file links.

URI protocol handler

In this scenario, a Web application handles navigation to a mailto: URL. The functionality is similar to that of registerProtocolHandler.

An email Web application makes the following invocations to register handlers for the mailto: URL scheme.

introducer.offer(
  'account123',
  "Company Email",
  [ 'mailto' ],
  'https://service.example.com/mailto/account123');
introducer.offer(
  'account456',
  "Email to public mailing lists",
  [ 'mailto' ],
  'https://service.example.com/mailto/account456');

Another Web application from a different [origin] also registers a handler.

introducer.offer(
  'account123',
  "Family Email",
  [ 'mailto' ],
  'https://service.example.net/mailto/account123');

When the user clicks on a mailto: hyperlink, the Introducer presents a Chooser that lists an option for each of the three mailto Services. Each of the options is annotated with the corresponding icon for the installation. The user chooses their "Company Email" account, which causes a new browser tab to be opened on https://service.example.com/mailto/account123. This page contains:

introducer.accept('https://service.example.com',
                  function (client, origin) {
    // Auto-fill the From field.
    …

    // Auto-fill the To, Subject and Body based on the mailto URL.
    client.onmessage = function (event) {
      var url = event.data;
      …

      // Only expecting one message from the client.
      client.close();
    };
  });

The above Service is an email authoring page for sending an email from a specific account with content initially determined by a mailto: URL.

Federated Identity

In this scenario, a Web application, acting as a Relying Party, receives a signed assertion of a user's email address from an Identity Provider.

An Identity Provider makes the following invocations to register a Service for each managed user identity.

introducer.offer(
  'account123',
  "jekyll",
  [ 'org.example.idp', 'org.example.idp.ExampleCom' ],
  'https://service.example.com/idp/account123',
  'https://service.example.com/idp/account123');
introducer.offer(
  'create',
  "create a new identity",
  [ 'org.example.idp', 'org.example.idp.ExampleCom' ],
  'https://service.example.com/idp/create');

Another Identity Provider from a different [origin] also registers an identity.

introducer.offer(
  'account123',
  "hyde",
  [ 'org.example.idp', 'org.example.idp.ExampleNet' ],
  'https://service.example.net/idp/account123',
  'https://service.example.net/idp/account123');

The Relying Party is only willing to accept identity assertions from either example.com or example.net. On its login page, the Relying Party makes the following invocation in response to a click on the 'login' button.

introducer.connect(loginButton, hiddenFrame,
                   [ 'org.example.idp.ExampleCom', 'org.example.idp.ExampleNet' ],
                   function (service, agreed, framed) {
    if (!service) {
      // User does not have a federated identity that we trust.
      // Refer them to our preferred IDP.
      …
      return;
    }

    var challenge = …
    service.onmessage = function (event) {
      // Check signature on assertion and extract email address.
      var idp = agreed[0],
          assertion = event.data;
      …

      service.close();
    };
    service.postMessage(challenge);
  });

In response to this connect invocation, the Introducer presents a Chooser near the login button, listing each user identity offered by either example.com or example.net. The user chooses "jekyll" from example.com. The Relying Party immediately sends a challenge request to the selected IDP service. The IDP service immediately responds to this challenge with a signed assertion of the "jekyll@example.com" email address. The Relying Party verifies this assertion using the public key corresponding to the example.com IDP. If the verification succeeds, the Relying Party completes the login successfully. The complete UX consists of clicking on the 'login' button and then clicking on an identity in the Chooser. There's no other confirmation step, such as a redirect to the IDP site.

References

Normative References

[HTML]
HTML5, I. Hickson. W3C, 24 June 2010.
[origin]
The HTTP Origin Header (work in progress), A. Barth, C. Jackson, I. Hickson. IETF.
[RFC2119]
Key words for use in RFCs to Indicate Requirement Levels, S. Bradner. IETF, March 1997.

Non-normative References

[clickjacking]
Clickjacking, R. Hansen, J. Grossman. SecTheory, 12 September 2008.
[UMP]
Uniform Messaging Policy, Level One, T. Close, M. Miller. W3C, 2010.

Acknowledgments

This appendix is non-normative.

The editors thank Adam Barth, Anne van Kesteren, Arve Bersvendsen, Bryan Sullivan, David Gibson, Dirk Pranke, Frederick Hirsch, Ian Hickson, Mark Lentczner, Mark Miller, Max Froumentin, Robin Berjon, Thomas Roessler, Will Meyer.