<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE rfc PUBLIC "-//IETF//DTD RFC 2629//EN" "http://xml2rfc.tools.ietf.org/authoring/rfc2629.dtd">

<?rfc compact="yes" ?>
<?rfc strict="yes" ?>
<?rfc subcompact="no" ?>
<?rfc symrefs="yes"?>
<?rfc toc="yes"?>
<?rfc tocdepth="4"?>
<?rfc tocindent="yes"?>
<?rfc tocompact="yes"?>

<rfc ipr="*trust200902" docName="draft-ideskog-assisted-token-03" version="4" category="info" submissionType="independent" sortRefs="true">
    <link rel="working-copy" href="https://github.com/curityio/rfc/blob/master/draft-ideskog-assisted-token/draft-ideskog-assisted-token-03.xml"/>
    <front>
        <title abbrev="Assisted Token">OAuth 2.0 Assisted Token</title>

        <seriesInfo name="Internet-Draft" value="draft-ideskog-assisted-token-03" stream="independent" status="informational"/>

        <author fullname="Jacob Ideskog" initials="J." surname="Ideskog">
            <organization>Curity AB</organization>

            <address>
                <email>jacob@curity.io</email>
            </address>
        </author>

        <author fullname="Travis Spencer" initials="T." surname="Spencer">
            <organization>Curity AB</organization>

            <address>
                <email>travis@curity.io</email>
            </address>
        </author>

        <date day="04" month="Jan" year="2021"/>

        <area>sec</area>
        <workgroup>Independent Submission</workgroup>

        <keyword>OAuth</keyword>
        <keyword>JavaScript</keyword>
        <keyword>SPA</keyword>
        <keyword>Single Page Application</keyword>

        <abstract>
            <t>
                This document extends the OAuth 2.0 framework to include an additional authorization flow for single page applications called the assisted
                token flow. It enables OAuth clients written in scripting languages, like
                JavaScript, to request user authorization using a simplified method compared to other flows. Communication does
                not rely on redirection of the user agent, but instead leverages HTML's iframe element, child windows, 
                and the postMessage interface. This communication is done using an additional endpoint, the assisted 
                token endpoint.
            </t>
        </abstract>

        <note removeInRFC="true">
            <t>
                To contribute to this draft, please feel free to create a pull request from the original source
                available at <eref target="https://bitbucket.org/curity/rfc/">https://bitbucket.org/curity/rfc/</eref>
                or email the authors.
            </t>
        </note>
    </front>

    <middle>
        <section title="Introduction" anchor="introduction">
            <t>
                The OAuth 2.0 protocol flow for Single-page Applications (SPA) defined in this memo, often referred to as the assisted token
                flow, provides clients written in scripting languages, like JavaScript, with a simplified integration
                (compared to the implicit or authorization code flow) and ensures that end users are not redirected away from the
                current page in order to obtain authorization from the resource owner. The communication between the
                client and the authorization server takes place within an HTML iframe element or child window that is
                only displayed when interactive user interaction is required; this is the case when authentication
                and/or authorization are necessary. To communicate the result from this iframe or child window to the
                client application, HTML's postMessage interface is used instead of the redirection endpoint defined in
                <xref section="3.1.2" target="RFC6749"/>. This difference is important for many SPAs
                which take time to reload and may not be able to recreate the same state prior to the user being 
                redirected to the authorization server.
            </t>

            <t>
                Another goal of the assisted token flow is to simplify integration of the client with the authorization
                server. Though <xref target="RFC6749"/> resulted in a much simpler integration for client applications
                compared to its predecessor, <xref target="RFC5849"/>, developers still struggle with the many inputs
                required to perform the various OAuth flows. For this reason, the assisted token flow introduces a new
                endpoint called the assisted token endpoint rather than extending and reusing the token endpoint
                defined in <xref target="RFC6749" section="3.2"/>. As a result, client developers do not need to specify
                a response_type parameter in the authorization request. This coupled with the use of HTML's postMessage
                interface for communication between the client and the authorization server means that the redirect_uri
                and state parameters are also unnecessary. Consequently, client developers only need to provide a
                client_id, create a dynamic iframe or open a child window, and handle the postMessage that is fired by
                the authorization server in order to implement OAuth.
            </t>

            <t>This interaction is shown in <xref target="assisted-token-flow"/>.</t>

            <figure title="Assisted Token Flow" anchor="assisted-token-flow">
                <artwork type="ascii-art"><![CDATA[
+----------------------------+                      +---------------+
|           Client           |                      | Authorization |
| +--------------------------+                      |     Server    |
| |              +-----------+                      |               |
| |--(A)-------->|           |--(B)-- Client ------>|               |
| |              |           |        Identifier    |               |
| |              |  Hidden   |                      |               |
| |              |  iframe   |<-(C)-- HTML with ----|               |
| |<-(D)- Token -|           |        postMessage   |               |
| |       or     |           |        including     |               |
| |       error  +-----------+        access token  |               |
| +--------------------------+        or error      |               |
|                            |                      |               |
+----------------------------+                      +---------------+
]]>
                </artwork>
            </figure>

            <t>
                The assisted token flow illustrated in <xref target="assisted-token-flow"/> includes the following steps:
            </t>

            <ol type="(%C)">
                <li>The client creates a hidden iframe element using a scripting language like JavaScript. The
                    src attribute of this iframe is the URL of the assisted token endpoint of the authorization server.</li>

                <li>The query string of the src attribute on the iframe includes, at a minimum, the client
                    identifier.</li>

                <li anchor="assisted_token_flow_3">If the user is already logged in and has granted consent to the client, the authorization
                    server immediately returns an HTML document that includes a script that is executing; this
                    fires an event which is communicated to the client using an HTML window.postMessage.</li>

                <li anchor="assisted_token_flow_4">The client handles this event -- the payload of which is either an access token or an error;
                    the client then closes the dynamic iframe without revealing it to the user.</li>
            </ol>

            <t>
                If the resource owner has not authenticated or has not authorized the client, then interaction between
                the resource owner and the authorization server is required to obtain these. In such a case, the HTML in
                step <xref target="assisted_token_flow_3" format="counter"/> of <xref target="assisted-token-flow"/> will include an error indicating that user
                involvement is required. This will be handled by the client in step <xref target="assisted_token_flow_4" format="counter"/> and login and/or consent will
                commence. This process is illustrated in <xref target="assisted-token-login-consent-flow"/>.
            </t>

            <figure title="Assisted Token Login and/or Consent Flow" anchor="assisted-token-login-consent-flow">
                <artwork type="ascii-art"><![CDATA[
+----------------------------+                      +---------------+
|           Client           |                      | Authorization |
| +--------------------------+                      |     Server    |
| |              +-----------+        Client        |               |
| |--(E)-------->|           |--(F)-- Identifier -->|               |
| |              |  Visible  |                      |               |
| |              |  iframe   |--(G)-- User -------->|               |
| |              |  or child |        authenticates |               |
| |<-(I)- Token -|  window   |                      |               |
| |              |           |<-(H)-- HTML with ----|               |
| |              +-----------+        postMessage   |               |
| +--------------------------+        including     |               |
|                            |        access token  |               |
+----------------------------+                      +---------------+
]]>
                </artwork>
            </figure>

            <t>
                The flow shown in <xref target="assisted-token-login-consent-flow"/> includes the following steps:
            </t>

            <ol type="(%C)" start="5">
                <li>The client creates a <tt>visible</tt> iframe or pops open a child window after
                    receiving an indication from the authorization server that user interaction is required. As in
                    the previous flow, the src attribute value of this iframe or the input to the open method of
                    the user agents's window object is the URL of the authorization server's assisted token
                    endpoint.</li>

                <li>The query string of this URL includes, at a minimum, the client identifier.</li>

                <li>The authorization server prompts the resource owner to authenticate and/or authorize the
                    client.</li>

                <li>The authorization server returns an HTML document that includes a script that is executed;
                    this fires an event which is communicated to the client using an HTML window.postMessage.</li>

                <li>The client handles this event -- the payload of which is an access token; the client then
                    closes the iframe or child window that it previously opened to facilitate user interaction.</li>
            </ol>
        </section>

        <section title="Terminology" anchor="terminology">
            <t>
                The key words "<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>",
                "<bcp14>REQUIRED</bcp14>", "<bcp14>SHALL</bcp14>", "<bcp14>SHALL NOT</bcp14>",
                "<bcp14>SHOULD</bcp14>", "<bcp14>SHOULD NOT</bcp14>",
                "<bcp14>RECOMMENDED</bcp14>", "<bcp14>NOT RECOMMENDED</bcp14>",
                "<bcp14>MAY</bcp14>", and "<bcp14>OPTIONAL</bcp14>" in this document are to be
                interpreted as described in BCP&nbsp;14 <xref target="RFC2119"/> <xref
                    target="RFC8174"/> when, and only when, they appear in all capitals, as
                shown here.
            </t>

            <dl newline="true" indent="8">
                <dt>Handle Token</dt>
                <dd>
                    An opaque token that refers to internal data of the authorization server (e.g., the user
                    ID, scope of the token, etc.) as described in <xref target="RFC6819" section="3.1"/>.
                </dd>
            </dl>

            <t>
                All other terms used in this document are as defined in <xref target="RFC6749"/>. Unless otherwise
                noted, all the protocol parameter names and values are case sensitive.
            </t>
        </section>

        <section title="Assisted Token Endpoint" anchor="assisted-token-endpoint">
            <t>
                The means through which the client obtains the location of the assisted token endpoint is either by
                using the authorization server's metadata as set forth in <xref target="authorization-server-metadata"/>,
                the service documentation, or some other method that is beyond the scope of this specification.
            </t>

            <t>
                The endpoint URI <bcp14>MAY</bcp14> include an <tt>application/x-www-form-urlencoded</tt> formatted (per
                <xref target="RFC6749" section="B"/>) query component (see <xref target="RFC3986" section="3.4"/>), which 
                <bcp14>MUST</bcp14> be
                retained when adding additional query parameters. The endpoint URI <bcp14>MUST NOT</bcp14> include a fragment
                component.
            </t>

            <t>
                Since requests to the assisted token endpoint result in the transmission of clear-text credentials (in
                the HTTP request and response), the authorization server <bcp14>MUST</bcp14> require the use of TLS as described in
                <xref target="RFC6749" section="1.6"/> when sending requests to the assisted token endpoint.
            </t>

            <t>The client <bcp14>MUST</bcp14> use the HTTP <tt>GET</tt> method when making access token requests to this endpoint.</t>

            <t>
                Parameters sent without a value <bcp14>MAY</bcp14> be treated as if they were omitted from the request. The
                authorization server <bcp14>MUST</bcp14> ignore unrecognized request parameters. Request and response parameters
                <bcp14>MUST NOT</bcp14> be included more than once.
            </t>

            <t>
                After completing its interaction with the resource owner, the authorization server will fire an event
                using the HTML postMessage interface. This message <bcp14>MUST NOT</bcp14> be posted to all origins, denoted by
                <tt>*</tt>. Instead, the authorization server <bcp14>MUST</bcp14> post this message only  to the client's allowed origin(s)
                previously established with the authorization server during the client registration process.
            </t>

            <section title="Access Token Scope" anchor="access-token-scope">
                <t>
                    Like the authorization and token endpoints, the assisted token endpoint allows the client to
                    specify the scope of the access request using the <tt>scope</tt> request parameter. In turn, the
                    authorization server uses the <tt>scope</tt> response parameter to inform the client of the scope of
                    the access token issued. Unlike the typical behavior of those endpoints, however, access tokens
                    issued by the authorization server using the assisted token endpoint <bcp14>MUST</bcp14> use the client's
                    pre-configured scope or the authorization server's pre-defined default if none have been configured
                    for the client.
                </t>

                <t>
                    If the client did not include a <tt>scope</tt> request parameter or if the issued access token scope is
                    different from the one requested by the client, the authorization server <bcp14>MUST</bcp14> include the
                    <tt>scope</tt> response parameter to inform the client of the actual scope granted. Even when the scope of the
                    issued access token is the same as the one requested by the client, the authorization server
                    <bcp14>SHOULD</bcp14>
                    include the <tt>scope</tt> response parameter.
                </t>

                <t>
                    The format, constraints, and grammar of the scope parameter value is as defined in
                    <xref target="RFC6749" section="3.3"/>.
                </t>

                <t>
                    The authorization server <bcp14>SHOULD NOT</bcp14> return an error if a scope has not been pre-configured for the
                    client; only if the authorization server does not have a pre-defined default scope.
                </t>
            </section>

            <section anchor="cross-orgin-suport" title="Cross-Origin Support">
                <t>
                    The assisted token endpoint <bcp14>MAY</bcp14> support CORS as defined in <xref target="W3C.WD-cors-20120403"/>.
                </t>
            </section>
        </section>

        <section title="Protocol" anchor="protocol">
            <section title="Assisted Token Request" anchor="assisted-token-request">
                <t>The assisted token request is an HTTP GET request constructed by the client with the following
                    parameters provided on the query string:
                </t>

                <dl newline="true" indent="8">
                    <dt>client_id</dt>
                    <dd>
                        <bcp14>REQUIRED</bcp14>. The client identifier as described in <xref target="RFC6749" section="2.2"/>.
                    </dd>

                    <dt>for_origin</dt>
                    <dd>
                        <bcp14>OPTIONAL</bcp14>. The origin of the client in case multiple allowed origins are
                        configured with the authorization server and support for user agents that do not support
                        <xref target="CSP-2"/> but only <tt>X-Frame-Options</tt> (as defined in <xref target="RFC7034"/>). See
                        <xref target="framing"/> for details.
                    </dd>

                    <dt>prompt</dt>
                    <dd>
                        <t>
                            <bcp14>OPTIONAL</bcp14>. Space delimited, case sensitive list of <xref target="ASCII"/> string
                            values that can be used to determine the login state of the resource owner at the
                            authorization server. The defined values are:
                        </t>

                        <dl newline="true" indent="8">
                            <dt>none</dt>
                            <dd>
                                The authorization server <bcp14>MUST NOT</bcp14> display any authentication or consent user
                                interface pages. An error is returned if the user is not already authenticated or if
                                the client has not received consent (either explicitly by the resource owner or by
                                the authorization server's configuration of the client) or if the authorization
                                server cannot fulfill other conditions for processing. This can be used as a method
                                to probing for existing authentication and/or consent.
                            </dd>

                            <dt>consent</dt>
                            <dd>
                                The authorization server <bcp14>SHOULD</bcp14> prompt the user for consent before returning
                                information to the client. If it cannot obtain consent, it <bcp14>MUST</bcp14> return an error.
                            </dd>
                        </dl>

                        <t>
                            Other values may be provided in this list; the authorization server <bcp14>MUST</bcp14> ignore them
                            without producing an error if it cannot understand them.
                        </t>
                    </dd>

                    <dt>scope</dt>
                    <dd>
                        <bcp14>OPTIONAL</bcp14>. The scope of the access request as described in <xref target="access-token-scope"/>.
                    </dd>
                </dl>
            </section>

            <section title="Assisted Token Response" anchor="assisted-token-response">
                <t>The response from the assisted token endpoint is an HTML document that executes a script which
                    invokes the HTML postMessage interface to send a message to either the parent window (in the case shown in
                    <xref target="assisted-token-flow"/>) or the opener (in the case illustrated in
                    <xref target="assisted-token-login-consent-flow"/>). The origin that this event is posted to is
                    that of the client. The contents of this message is a JSON object with the following fields:
                </t>

                <dl newline="true" indent="8">
                    <dt>access_token</dt>
                    <dd>
                        <bcp14>REQUIRED</bcp14>. The access token issued by the authorization server.
                    </dd>

                    <dt>expires_in</dt>
                    <dd>
                        <bcp14>RECOMMENDED</bcp14>. The lifetime in seconds of the access token.
                    </dd>

                    <dt>scope</dt>
                    <dd>
                        <bcp14>REQUIRED</bcp14>. The scope of the access token as described in <xref target="access-token-scope"/>.
                    </dd>

                    <dt>sub</dt>
                    <dd>
                        <bcp14>RECOMMENDED</bcp14>. A locally unique and never reassigned identifier within the authorization
                        server for the user, which is intended to be consumed by the client. The sub value is
                        a case sensitive string.
                    </dd>

                    <dt>token_type</dt>
                    <dd>
                        <bcp14>REQUIRED</bcp14>. The type of the token issued as described in
                        <xref target="RFC6749" section="7.1"/>. Value is case insensitive.
                    </dd>
                </dl>

                <t>
                    This JSON object <bcp14>MAY</bcp14> contain additional fields. If the client does not 
                    understand or recognize such additional fields, it <bcp14>MUST</bcp14> ignore them.
                </t>
            </section>

            <section title="Error Response" anchor="error-response">
                <t>As with a successful response, an error is returned to the client using an the HTML postMessage
                    interface. Such an error is returned whenever the resource owner denies the access request or
                    whenever the request fails for reasons other than the origin of the client being disallowed to
                    frame the assisted token endpoint. The error message includes a JSON object with the following
                    fields:
                </t>

                <dl newline="true" indent="8">
                    <dt>error</dt>
                    <dd>
                        <t>
                            <bcp14>REQUIRED</bcp14>. A single <xref target="ASCII"/> error code from the following:
                        </t>

                        <dl newline="true" indent="8">
                            <dt>invalid_request</dt>
                            <dd>
                                The request is missing a required parameter, includes an
                                invalid parameter value, includes a parameter more than
                                once, or is otherwise malformed.
                            </dd>

                            <dt>unauthorized_client</dt>
                            <dd>
                                The client is not authorized to request an access token using this method.
                            </dd>

                            <dt>access_denied</dt>
                            <dd>
                                The resource owner or authorization server denied the request.
                            </dd>

                            <dt>consent_required</dt>
                            <dd>
                                The client includes a prompt value of consent, but consent by the resource owner
                                was required.
                            </dd>

                            <dt>interaction_required</dt>
                            <dd>
                                The client included a prompt value of none, but either the user needed to
                                authenticate or consent to the client's access or some other requirement of the
                                authorization server prevented it from providing access without some form of user
                                interaction.
                            </dd>

                            <dt>unsupported_response_type</dt>
                            <dd>
                                The authorization server does not support obtaining an access token using this
                                method.
                            </dd>

                            <dt>invalid_scope</dt>
                            <dd>
                                The requested scope is invalid, unknown, or malformed.
                            </dd>

                            <dt>server_error</dt>
                            <dd>
                                The authorization server encountered an unexpected condition that prevented it
                                from fulfilling the request. (This error code is needed because a 500 Internal
                                Server Error HTTP status code cannot be returned to the client directly in the
                                child frame.)
                            </dd>

                            <dt>temporarily_unavailable</dt>
                            <dd>
                                The authorization server is currently unable to handle the request due to a
                                temporary overloading or maintenance of the server. (This error code is needed
                                because a 503 Service Unavailable HTTP status code cannot be returned to the client
                                directly in the child frame.)
                            </dd>
                        </dl>

                        <t>
                            Values for the <tt>error</tt> parameter <bcp14>MUST NOT</bcp14> include characters outside the set %x20-21 /
                            %x23-5B / %x5D-7E.
                        </t>
                    </dd>

                    <dt>error_description</dt>
                    <dd>
                        <bcp14>OPTIONAL</bcp14>. Human-readable <xref target="ASCII"/> text providing additional
                        information, used to assist the client developer in understanding the error that occurred.
                        Values for the <tt>error_description</tt> parameter <bcp14>MUST NOT</bcp14> include characters outside the set
                        %x20-21 / %x23-5B / %x5D-7E.
                    </dd>

                    <dt>error_uri</dt>
                    <dd>
                        <bcp14>OPTIONAL</bcp14>. A URI identifying a human-readable web page with information about the error,
                        used to provide the client developer with additional information about the error. Values
                        for the <tt>error_uri</tt> parameter <bcp14>MUST</bcp14> conform to the URI-reference syntax and thus
                        <bcp14>MUST NOT</bcp14>
                        include characters outside the set %x21 / %x23-5B / %x5D-7E.
                    </dd>
                </dl>
            </section>
        </section>

        <section title="Client Metadata" anchor="client-metadata">
            <t>
                The authorization server <bcp14>MAY</bcp14> allow dynamic clients to request the use of the assisted token flow when
                registering. Such a client may indicate that it will interact with the authorization server using the
                assisted token flow by including the string element
                <tt>urn:ietf:params:oauth:grant-type:assisted_token</tt> in the array associated with the
                <tt>grant_types</tt> metadata field sent to the client registration endpoint (as defined in
                <xref target="RFC7591" section="3"/>). If the authorization server allows the client to register with this grant
                type, the <tt>grant_types</tt> included in the response <bcp14>MUST</bcp14> include the value
                <tt>urn:ietf:params:oauth:grant-type:assisted_token</tt>. The inclusion of this value in the
                <tt>grant_types</tt> field is done despite the fact that the client will not use this grant type at the token endpoint but
                rather the assisted token endpoint (see <xref target="assisted-token-endpoint"/>).
            </t>

            <t>
                The following client metadata field is defined by this specification. It <bcp14>MAY</bcp14> be included in a
                registration request, as set forth in <xref target="RFC7591" section="2"/>.
            </t>

            <dl newline="true" indent="8">
                <dt>allowed_origins</dt>
                <dd>
                    Array of origin strings for use in sending messages from the authorization server to the
                    client using the HTML's postMessage interface.
                </dd>
            </dl>
        </section>

        <section title="Authorization Server Metadata" anchor="authorization-server-metadata">
            <t>
                Support for the assisted token flow <bcp14>SHOULD</bcp14> be declared in the authorization server's metadata
                (as defined in <xref target="RFC8414"/>) with the following metadata:
            </t>

            <dl newline="true" indent="8">
                <dt>assisted_token_endpoint</dt>
                <dd>
                    <bcp14>RECOMMENDED</bcp14>.
                    URL of the authorization server's assisted token endpoint defined in
                    <xref target="assisted-token-endpoint"/>.
                </dd>

                <dt>grant_types_supported</dt>
                <dd>
                    <bcp14>RECOMMENDED</bcp14>.
                    A JSON array specified in
                    <xref target="RFC8414" section="2"/>
                    which should contain the value <tt>urn:ietf:params:oauth:grant-type:assisted_token</tt> as defined in
                    <xref target="client-metadata"/>.
                </dd>
            </dl>
        </section>

        <section title="IANA Considerations" anchor="iana-considerations">
            <section anchor="URIReg" title="OAuth URI Registration">
                <t>
                    This specification registers the following values in the
                    <eref target="https://www.iana.org/assignments/oauth-parameters/oauth-parameters.xhtml#uri">IANA "OAuth URI" registry</eref>
                    <xref target="IANA.OAuth.Parameters"/> established by <xref target="RFC6755"/>.
                </t>

                <section title="Registry Contents" anchor="URIContents">
                    <ul>
                        <li>URN: urn:ietf:params:oauth:grant-type:assisted_token</li>
                        <li>Common Name: Assisted token flow grant type for OAuth 2.0</li>
                        <li>Change controller: IESG</li>
                        <li>Specification Document: <xref target="client-metadata"/> of [[ this specification ]]</li>
                    </ul>
                </section>
            </section>

            <section anchor="parametersReg" title="OAuth Parameters">
                <t>
                    This specification registers the following values in the
                    <eref target="https://www.iana.org/assignments/oauth-parameters/oauth-parameters.xhtml#parameters">IANA "OAuth Parameter" registry</eref>
                    <xref target="IANA.OAuth.Parameters"/> established by <xref target="RFC6749"/>.
                </t>

                <section title="Registry Contents" anchor="parameters">
                    <ul>
                        <li>for_origin</li>
                        <li>Parameter usage location: authorization request</li>
                        <li>Change controller: IESG</li>
                        <li>Specification Document: <xref target="protocol"/> of [[ this specification ]]</li>
                    </ul>
                </section>
            </section>

            <!-- The IANA register needs to be updated to have error messages that can eb returned from the assisted
            token endpoint and not only the authorization endpoint

            TODO: for_origin in the request needs to be defined as well.
            -->

            <section title="OAuth 2.0 Authorization Server Metadata" anchor="MetadataReg">

                <t>
                    This specification registers the following values in the
                    <eref target="https://www.iana.org/assignments/oauth-parameters/oauth-parameters.xhtml#authorization-server-metadata">IANA "OAuth 2.0 Authorization Server
                    Metadata" registry</eref> <xref target="IANA.OAuth.Parameters"/> established by
                    <xref target="RFC8414"/>.
                </t>

                <section title="Registry Contents" anchor="MetadataContents">
                    <ul>
                        <li>Metadata name: assisted_token_endpoint</li>
                        <li>Metadata Description: The Assisted Token Endpoint.</li>
                        <li>Change controller: IESG</li>
                        <li>Specification Document: <xref target="authorization-server-metadata"/>
                            of [[ this specification ]]</li>
                    </ul>
                </section>
            </section>
        </section>

        <section title="Security Considerations" anchor="security-considerations">
            <t>
                In addition to all the security considerations discussed in <xref target="RFC6819"/>,
                the following security considerations <bcp14>SHOULD</bcp14> be taken into account.
            </t>

            <section title="Framing" anchor="framing">
                <t>
                    Due to the use of an iframe to host the assisted token endpoint, the authorization server 
                    <bcp14>MUST</bcp14> take
                    precautions to ensure that only trusted origins are allowed to frame it. The authorization server
                    <bcp14>MUST</bcp14> prevent any origin from framing the assisted token endpoint except ones that an administrator
                    has explicitly allowed. It may do this in any manner that is available to the application.
                </t>

                <t>
                    One such mechanism that <bcp14>MAY</bcp14> be deployed is <xref target="CSP-2">Content Security Policy</xref>. This
                    protocol <bcp14>SHOULD</bcp14> be used on the assisted token endpoint (and, if applicable, other endpoints used to
                    authenticated the user in a specific deployment) to prevent framing from unauthorized origins. Using
                    CSP allows the authorization server to specify multiple origins in a single response header field
                    and to constrain these using flexible patterns (see <xref target="CSP-2"/> for details). This
                    standard provides a robust mechanism for protecting against click-jacking by using policies
                    that restrict the origin of frames (using <tt>frame-ancestors</tt>) together with those that restrict the sources of scripts allowed to execute on an HTML page (by using
                    <tt>script-src</tt>). A non-normative example of such a policy is shown in the following listing:
                </t>
                <figure anchor="csp-x-f-o-example" title="Example CSP that will help protect against click-jacking">
                    <sourcecode type="html">
                        <![CDATA[
HTTP/1.1 200 OK
Content-Security-Policy: frame-ancestors https://a.example.org:8000
Content-Security-Policy: script-src 'self'
X-Frame-Options: ALLOW-FROM https://a.example.org:8000
...]]>
                    </sourcecode>
                </figure>
                <t>
                    Because some user agents do not support <xref target="CSP-2"/>, this technique <bcp14>SHOULD</bcp14> be combined with
                    others. In particular, the authorization server <bcp14>SHOULD</bcp14> return an <tt>X-Frame-Options</tt> response header
                    on the assisted token endpoint (and, if applicable, other endpoints used to authenticate the user
                    in a specific deployment). As defined in <xref target="RFC7034"/>, this header will cause user
                    agents that support it (but not CSP) to block framing from any origin that is not
                    specified in this header's value. Because this header's value can only include one origin, the
                    framer should use the <tt>for_origin</tt> parameter (as specified in
                    <xref target="assisted-token-request"/>) to include its own origin.
                </t>

                <t>
                    Some user agents do not support <xref target="RFC7034"/> nor
                    <xref target="CSP-2"/>. Therefore, the authorization server <bcp14>SHOULD</bcp14> include a frame-busting script
                    like that shown in Figure 7 of <xref target="FRAME-BUSTING"/>. Such a script would use JavaScript
                    to break out of any unauthorized origin that is framing the assisted token endpoint. The
                    authorization server <bcp14>MAY</bcp14> simply break out of all frames in case <xref target="RFC7034"/>
                    and <xref target="CSP-2"/> are unsupported by the user agent, though this
                    would render the assisted token flow non-functional. The choice of whether or not this drastic
                    countermeasure should be employed depends on the user agents being targetted in a certain
                    deployment.
                </t>
            </section>

            <section title="Handle Tokens" anchor="handle-token">
                <t>
                    Because the client applications that use the assisted token flow are written in scripting languages
                    like JavaScript and are hosted in Web pages, users may keep such applications open in their user
                    agents for a prolonged period of time. During such period, the token issued to the client may
                    expire or be revoked. To ensure that such expired tokens left remnant in the user agent are benign,
                    a Handle Token <bcp14>SHOULD</bcp14> always be issued by the assisted token endpoint. This ensures that no identity
                    data is exposed (even when the token is not yet expired) and that a revoked token does not increase
                    risks.
                </t>
            </section>

            <section title="Warning Against Untrusted Scripts" anchor="warning-against-untrusted-script">
                <t>
                    As admitted in <xref target="RFC6454" section="8"/>, preventing exfiltration of cookies, tokens,
                    and other such credentials in web browsers has historically proven difficult to implement. Instead,
                    the same-origin policy has emerged as the cornerstone of security for such user agents. Using this
                    security model, it is not possible to prevent access to a token issued to a client if that client
                    includes nefarious scripts from untrustworthy sources that have access to the Document Object
                    Model (DOM) where the token is stored. For this reason, the authorization server <bcp14>MUST</bcp14> warn client
                    application developers who interact with the assisted token endpoint <em>not</em> to use
                    untrusted scripts in their applications. This warning <bcp14>SHOULD</bcp14> at least be conveyed through the
                    documentation but <bcp14>MAY</bcp14> also be provided through other mechanisms.
                </t>
            </section>

            <section title="Origin of Event and Authorization Server" anchor="origin-of-event-and-authorization-server">
                <t>
                    As described in <xref target="assisted-token-request"/>, the authorization server will return an
                    access token to the client using HTML's postMessage interface. The receiver of this message is
                    provided with an event object that contains an origin property. A client application <bcp14>MUST</bcp14> compare
                    this with that of the authorization server before consuming the message. Otherwise, it runs the
                    risk of processing messages posted from untrusted origins. An example of a proper message handler
                    is shown in the following non-normative, JavaScript listing:
                </t>
                <figure anchor="f_arwmwmrm" title="Comparing the origin of the postMessage event with that of the authorization server">
                    <sourcecode type="html">
                        <![CDATA[
<script type="text/javascript">
    window.addEventListener("message", function(evt) {
        if (evt.origin !== "https://oauth-server.example.com")
            return; // Ignore event from untrusted source

        ...
    });
</script>]]>
                    </sourcecode>
                </figure>
            </section>

            <section title="Token Storage" anchor="token-storage">
                <t>
                    Most client applications that use the assisted token flow will maintain the access token issued by
                    the authorization server in a persisted state; this will commonly be an HTTP cookie or local
                    storage. This is necessary, for instance, to create a pleasing user experience when a user navigates
                    away from the application in their web browser and then returns. To ensure that the token is stored
                    safely, the authorization server <bcp14>MAY</bcp14> provide application developers with guidance in the
                    accompanying documentation on how to safely persist tokens. The authorization server <bcp14>MAY</bcp14> also
                    provide script libraries that perform this action according to best common practices. The
                    authorization server <bcp14>MAY</bcp14> also store the token in an HTTP cookie in its own DNS domain (rather than
                    that of the client) using the assisted token endpoint's path. In some cases, this would elevate any
                    storage requirements from the client application developer. Besides simplifying the programming
                    model for developers, this technique allows the authorization server to check the validity of the
                    token and determine if the token has expired or if the associated grant has been revoked in
                    subsequent requests to the assisted token endpoint; this will be possible because the requests will
                    include the token in the HTTP Cookie request header. In such cases, the authorization server can
                    take the appropriate action, such as authenticating the user anew or request consent, before
                    issuing a new token. If the token is stored by the application, however, this kind of verification
                    cannot be performed by the authorization server without an explicit request to validate a stored
                    token.
                </t>
            </section>

            <section title="Visibility of User Agent's Address Bar" anchor="visibility-of-user-agents-address-bar">
                <t>
                    When the authorization server and client are provided by separate parties, it is important that the
                    resource owner is able to distinguish the two. The only safe way of doing so is by examination of
                    the user agent's address bar where the validity of the certificate and location can be made. In
                    such situations, whenever user interaction is required, the client <bcp14>SHOULD</bcp14> open the assisted token
                    endpoint in a new browser window rather than a hidden iframe. The authorization serer <bcp14>MAY</bcp14> take any
                    measures deemed appropriate in a deployment to ensure that the client has not framed the user's
                    manual interaction; however, the necessity for interactive user authentication and/or consent
                    <bcp14>SHOULD</bcp14> be possible for the client to determine in a hidden iframe.
                </t>
            </section>
        </section>

        <section anchor="privacy-considerations" title="Privacy Considerations">
            <t>
                In some deployments, the assisted token endpoint may be served from a distinct domain from that of the
                client. In such cases, the client will be a third-party domain, and the resource owner's user agent may
                prevent the authorization server from storing any third-party cookies. If the authorization server
                requires state to be persisted when performing the assisted token flow, it
                <bcp14>SHOULD</bcp14>
                provide a privacy-preserving mechanism to store and retrieve its state even when the assisted token
                endpoint is hosted on a distinct domain from that of the client. The technical details of how to
                accomplish this are implementation specific, and are beyond the scope of this specification. If the
                authorization server does not support clients that are hosted from a third-party domain, it
                <bcp14>MUST</bcp14>
                indicate this to the client through some mechanism (e.g., its associated documentation).
            </t>
        </section>
    </middle>

    <back xmlns:xi="http://www.w3.org/2001/XInclude">
        <references title="Normative References">
            <reference anchor="ASCII">
                <front>
                    <title>Coded Character Set -- 7-bit American Standard Code for Information Interchange</title>
                    <author>
                        <organization>American National Standards Institute</organization>
                    </author>
                    <date year="1986"/>
                </front>
                <seriesInfo name="ANSI" value="X3.4"/>
            </reference>
            <reference anchor="IANA.OAuth.Parameters" target="http://www.iana.org/assignments/oauth-parameters">
                <front>
                    <title>OAuth Parameters</title>
                    <author>
                        <organization>IANA</organization>
                    </author>
                    <date/>
                </front>
            </reference>
            <xi:include href="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.2119.xml"/>
            <xi:include href="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.3986.xml"/>
            <xi:include href="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.6749.xml"/>
            <xi:include href="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.7591.xml"/>
            <xi:include href="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.8174.xml"/>
            <xi:include href="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.8414.xml"/>
        </references>

        <references title="Informative References">
            <reference target="https://www.w3.org/TR/CSP2" anchor="CSP-2">
                <front>
                    <title>Content Security Policy Level 2</title>
                    <author initials="M." surname="West"/>
                    <author initials="A." surname="Barth"/>
                    <author initials="D." surname="Veditz"/>
                    <date month="July" year="2015"/>
                </front>
            </reference>
            <reference anchor="FRAME-BUSTING" target="http://seclab.stanford.edu/websec/framebusting/framebust.pdf">
                <front>
                    <title>Busting frame busting: a study of clickjacking vulnerabilities at popular sites</title>
                    <author initials="G." surname="Rydstedt">
                        <organization>Stanford Web Security Research</organization>
                    </author>
                    <author initials="E." surname="Bursztein">
                        <organization>Stanford Web Security Research</organization>
                    </author>
                    <author initials="D." surname="Boneh">
                        <organization>Stanford Web Security Research</organization>
                    </author>
                    <author initials="C." surname="Jackson">
                        <organization>Stanford Web Security Research</organization>
                    </author>
                    <date year="2010" month="July"/>
                </front>
            </reference>
            <xi:include href="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.5849.xml"/>
            <xi:include href="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.6454.xml"/>
            <xi:include href="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.6755.xml"/>
            <xi:include href="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.6819.xml"/>
            <xi:include href="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.7034.xml"/>
            <reference anchor='W3C.WD-cors-20120403' target='http://www.w3.org/TR/2012/WD-cors-20120403'>
                <front>
                    <title>Cross-Origin Resource Sharing</title>
                    <author initials='A.' surname='Kesteren' fullname='Anne van Kesteren'/>
                    <date month='April' day='3' year='2012' />
                </front>

                <seriesInfo name='World Wide Web Consortium LastCall' value='WD-cors-20120403' />
                <format type='HTML' target='http://www.w3.org/TR/2012/WD-cors-20120403' />
            </reference>
        </references>

        <section anchor="Acknowledgements" title="Acknowledgements">
            <t>
                The following individuals contributed ideas, feedback, and wording to this specification:
            </t>

            <t>
                Mark Dobrinic, Karl McGuinness, Renato Athaydes, Daniel Lindau
            </t>
        </section>

        <section title="Document History" anchor="document-history" removeInRFC="true">
            <t>
                [[ to be removed by the RFC editor before publication as an RFC ]]
            </t>
            <t>-03</t>
            <ul>
                <li>
                    Updated repository links.
                </li>
            </ul>

            <t>-02</t>
            <ul>
                <li>
                    Updated section 8.1 with regards to the CSP headers.
                </li>
                <li>
                    Updated authorization server metadata in section 6.
                </li>
                <li>
                    Updated IANA Considerations section 7.
                </li>
            </ul>

            <t>-01</t>
            <ul>
                <li>
                    Updated to v. 3 XML format
                </li>
            </ul>

            <t>-00</t>
            <ul>
                <li>
                    Initial draft.
                </li>
            </ul>
        </section>
    </back>
</rfc>