<?xml version="1.0" encoding="US-ASCII"?>
<!DOCTYPE rfc SYSTEM "rfc2629.dtd">
<?rfc toc="yes"?>
<?rfc tocompact="yes"?>
<?rfc tocdepth="2"?>
<?rfc tocindent="yes"?>
<?rfc symrefs="yes"?>
<?rfc sortrefs="no"?>
<?rfc comments="yes"?>
<?rfc inline="yes"?>
<?rfc compact="yes"?>
<?rfc subcompact="no"?>
<rfc category="std" docName="draft-wdenniss-oauth-incremental-auth-01"
    ipr="trust200902">

  <front>

    <title abbrev="OAuth 2.0 Incremental Auth">OAuth 2.0 Incremental Authorization</title>

    <author fullname="William Denniss" initials="W." surname="Denniss">
      <organization>Google</organization>
      <address>
        <postal>
          <street>1600 Amphitheatre Pkwy</street>
          <city>Mountain View</city>
          <region>CA</region>
          <code>94043</code>
          <country>USA</country>
        </postal>
        <facsimile/>
        <email>wdenniss@google.com</email>
        <uri>http://wdenniss.com/incremental-auth</uri>
      </address>
    </author>

    <date day="5" month="March" year="2018"/>
    <area>Security</area>
    <workgroup>OAuth Working Group</workgroup>

    <abstract>
      <t>
        OAuth 2.0 authorization requests that include every scope the client
        might ever need can result in over-scoped authorization and a sub-optimal
        end-user consent experience. This specification enhances the OAuth 2.0 authorization
        protocol by adding incremental authorization, the ability to request specific
        authorization scopes as needed, when they're needed, removing the requirement
        to request every possible scope that might be needed upfront.
      </t>
    </abstract>
  </front>

  <middle>
    <section title="Introduction" anchor="intro">
      <t>
        OAuth 2.0 clients may offer multiple features that requiring user authorization,
        but commonly not every user will use each feature.
        Without incremental authentication, applications need to either
        request all the possible scopes they need upfront, potentially resulting in a bad user
        experience, or track each authorization grant separately, complicating development.
      </t>
      <t>
        The goal of incremental authorization is to allow clients to request just the scopes
        they need, when they need them, while allowing them to store a single authorization grant
        for the user that contains the sum of the scopes granted. Thus, each new authorization
        request increments the scope of the authorization grant, without the client needing
        to track a separate authorization grant for each group of scopes. 
      </t>
    </section>
    <section title="Notational Conventions" anchor="NotationalConventions">
      <t>
        The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
        "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY",
        and "OPTIONAL" in this document are to be interpreted as described in
        Key words for use in RFCs to Indicate Requirement Levels
        <xref target='RFC2119' />. If these words are used without being spelled
        in uppercase then they are to be interpreted with their normal natural
        language meanings.
      </t>
    </section>

    <section title="Terminology" anchor="terminology">
      <t>
        In addition to the terms defined in referenced specifications, this
        document uses the following terms:
      </t>
      <t>
        <list style="hanging">
          <t hangText='"OAuth"'>
            In this document, OAuth refers to 
            <xref target="RFC6749">OAuth 2.0</xref>.
          </t>
        </list>
      </t>
    </section>
    
    <section title="Incremental Auth for Confidential Clients" anchor="Confidential">
      <t>
        For confidential clients, such as web servers that can keep secrets,
        the authorization endpoint SHOULD treat scopes that the user
        already granted differently on the consent user interface. Typically
        such scopes are hidden for new authorization requests, or at least
        there is an indication that the user already approved them.
      </t>
      <t>
        By itself, this property of the authorization endpoint enables incremental authorization.
        The client can track every scope they've ever requested, and include those
        scopes on every new authorization request.
      </t>
      <t>
        To avoid the need for confidential clients to re-request already authorized scopes,
        authorization servers MAY support an additional "include_granted_scopes" parameter in the authorization request.
        This parameter, enables the client to request tokens during the authorization grant
        exchange that represent the full scope of the user's grant to the application
        including any previous grants, without the app needing to track the scopes directly.
      </t>
      <t>
        The client indicates they wish the new authorization grant to include
        previously granted scopes by sending the following additional parameter 
        in the OAuth 2.0 Authorization Request (Section 4.1.1 of <xref target="RFC6749"/>.)
        using the following additional parameter:
      </t>
      <t>
        <list style="hanging">
          <t hangText="include_granted_scopes">OPTIONAL. Either "true" or "false". When "true", the authorization server
          SHOULD include previously granted scopes for this client in the new authorization grant.</t>
        </list>
      </t>

    </section>
    
    <section title="Incremental Auth for Public Clients" anchor="Public">
      <t>
        Unlike with confidential clients, it is NOT RECOMMEND to 
        automatically approve OAuth requests for public clients without user consent
        (see Section 10.2 of <xref target="RFC6749">OAuth 2.0</xref>, and 
        Section 8.6 of <xref target="RFC8252">OAuth 2.0</xref>), thus 
        authorization grants shouldn't contain previously authorized scopes in the
        manner described above for confidential clients.
      </t>
      <t>
        Public clients (and confidential clients using this technique) should instead
        track the scopes for every authorization grant, and only request yet to be granted
        scopes during incremental authorization. In the past, this would
        result in multiple discrete authorization grants that would need to be tracked.
        To enable incrementing a single authorization grant for public clients,
        the client supplies their existing refresh token during the authorization
        code exchange, and receives new authorization tokens with the scope of
        the previous and current authorization grants.
      </t>
      <t>
        The client sends the previous refresh token in the OAuth 2.0 Access Token Request (Section 4.1.3 of <xref target="RFC6749"/>.) using the following additional parameter:
      </t>
      <t>
        <list style="hanging">
          <t hangText="existing_grant">OPTIONAL. The refresh token from the existing authorization grant.</t>
        </list>
      </t>
      <t>
        When processing the token exchange, in addition to the normal processing of such a request,
        the token endpoint MUST verify that token provided in 
        the "existing_grant" parameter is unexpired and unrevoked,
        and was issued to the same client id and relates to the same user as the current authorization grant. If this verification
        succeeds, the new refresh token issued in the Access Token Response (Section 4.1.4 of ) SHOULD include
        authorization for the scopes in the previous grant.
      </t>
    </section>

    <section title="Usability Considerations" anchor="Usability">
      <section title="Handling Denials" anchor="Denials">
        <t>
          A core principle of OAuth is that users may deny authorization requests for
          any reason. This remains true for incremental authorization requests.
          In the case of incremental authorization, clients may already have a
          valid authorization and receive a denial for an incremental
          authorization request (that is, an "access_denied" error code as defined
          in Section 4.1.2.1 of <xref target="RFC6749">OAuth 2.0</xref>). Clients
          should SHOULD handle such errors gracefully and not discard any existing
          authorization grants if the user denies an incremental authorization
          request. Clients SHOULD NOT immediately request the same incremental
          authorization again, as this may result in an
          infinite denial loop (and the end-user feeling badgered).
        </t>
      </section>
    </section>

    <section title="Alternative Approaches" anchor="Alternatives">
      <section title="Alternative for Public Clients" anchor="AlternativePublic">
        <t>
          It is possible for OAuth clients
          to maintain multiple authorizations per user for feature-specific scopes
          without needing the feature documented in this specification.
          For example, an app could maintain an authorization for the contacts
          and one for calendar, and store them separately.
        </t>
        <t>
          This specification offers a convenience that a single authorization
          grant can be managed that represents all the scope granted so far,
          rather than needing to maintain multiple, however it does require
          that all grants are made from a single end-user account (as
          authorization servers cannot typically combine grants from multiple
          users). Apps where users may wish to authorize separate end-user
          accounts for different features should consider using the alternative
          documented above.
        </t>
      </section>
      <section title="Alternative for Confidential Clients" anchor="AlternativeConfidential">
        <t>
          An alternative incremental auth design for confidential clients is to
          ask for authorization scopes as they are needed and keep a running
          record of all granted scopes. In this way each incremental
          authorization request would include all scopes granted so far, plus
          the new scope needed. Authorization servers can see the existing scopes
          and only display the new scopes for approval (and likely to inform the user of the existing grants).
          This approach can be performed using RFC 6749 without additions, but
          requires the client to keep track of every authorization grant.
        </t>
        <t>
         Confidential clients can also use the alternative documented for public
         clients in <xref target="AlternativePublic" />.
        </t>
      </section>
    </section>

    <section title="Privacy Considerations" anchor="Privacy">
      <section title="Requesting Authorization In Context" anchor="InContext">
        <t>
          The goal of incremental authorization is to enhance end-user privacy
          by allowing clients to request only the authorization scopes needed in
          the context of a particular user action, rather than asking for 
          ever possible scope upfront. For example, an app may offer calendar
          and contacts integration, and an extension of OAuth like OpenID Connect
          for sign-in. Such an app should first sign the user in with just the
          scopes needed for that. If later the user interacts with the calendar or
          contacts features then, and only then, should the requires scopes be requested. 
          By using this specification, apps can improve the privacy choices of
          end-users by only requesting the scopes they need in context.
        </t>
        <t>
          Clients authorizing the user with an authorization server that
          supports incremental auth SHOULD ask for the minimal authorization
          scope for the user's current context, and use this specification
          to add authorization scope as required.
        </t>
      </section>
      <section title="Preventing Overbroad Authorization Requests" anchor="KitchenSink">
        <t>
          When this specification is implemented, clients should have no
          technical reason to make overbroad authorization requests (i.e. 
          requesting every possible scope, even ones they don't immediately need).
          It is therefore RECOMMENDED for authorization servers to limit the
          authorization scope that can be requested in a single authorization
          to what would reasonably be needed by a single feature.
        </t>
      </section>
      <section title="Authorization Correlation" anchor="Correlation">
        <t>
          Incremental authorization is designed for use-cases where it's the
          same user authorizing each request, and thus all incremental
          authorization grants are correlated to that one user (by being
          merged into a single authorization grant).
          For applications where users may wish to connect different user
          accounts for different features (e.g. contacts from one account, and
          calendar from another) it is RECOMMENDED to instead allow multiple
          unrelated authorizations, as documented in
          <xref target="AlternativePublic" />.
        </t>
        <t>
          The goal of this specification is to improve end-user privacy
          by giving them more choice over which scopes they grant access to.
          Previously many apps would request an overly large number of scopes
          upfront (typically for all the features of the app, rather than
          the subset that the user is currently wishing to use). The scopes
          in such authorization grants are necessarily correlated with the
          same user as they are contained in a single authorization grant. Implementing this
          specification doesn't change that attribute, but it does improve
          user privacy overall by empowering the user to grant access in a more
          granular way.
        </t>
      </section>
    </section>

    <section title="Security Considerations" anchor="Security">
        <section title="Public Client Impersonation" anchor="Sec-public">
          <t>
            As documented in Section 8.6 of <xref target="RFC8252">RFC 8252</xref>, some
            public clients are susceptible to client impersonation, depending
            on the type of redirect URI used. If the "include_granted_scopes"
            feature documented in <xref target="Confidential" /> is used by
            an impersonating client, it may receive a greater authorization
            grant than the user specifically approved for that client. For this
            reason, the "include_granted_scopes" feature MUST NOT be enabled for such
            public client requests.
          </t>
          <t>
            Note that there is no such restriction on the use of "existing_grant"
            feature documented in <xref target="Public" />. While it is
            designed for public clients, it MAY be supported for all client
            types.
          </t>
      </section>
    </section>

    <section anchor="IANA" title="IANA Considerations">
      <t>This specification makes a registration request as follows:</t>

      <section title="OAuth Parameters Registry" anchor="reg">
        <t>This specification registers the following parameters in the IANA
        OAuth Parameters registry defined in <xref target="RFC6749">OAuth
        2.0</xref>.</t>

        <t>
          <list style="symbols">
            <t>Parameter name: include_granted_scopes</t>

            <t>Parameter usage location: authorization request</t>

            <t>Change controller: IESG</t>

            <t>Specification document(s): this document</t>
          </list>
        </t>
        <t>
          <list style="symbols">
            <t>Parameter name: existing_grant</t>

            <t>Parameter usage location: token request</t>

            <t>Change controller: IESG</t>

            <t>Specification document(s): this document</t>
          </list>
        </t>
      </section>
    </section>
  </middle>

  <back>

    <references title="Normative References">
      <?rfc include='reference.RFC.2119'?>
      <?rfc include='reference.RFC.6749'?>
      <?rfc include='reference.RFC.8252'?>
    </references>

<!--
    <references title="Informative References">
    </references>
-->

    <section title="Acknowledgements" anchor="Acknowledgements">
      <t>
        The following individuals contributed ideas, feedback, and wording
        that shaped and formed the final specification:
      </t>
      <t>
        Yanna Wu, Marius Scurtescu, Jason Huang, Nicholas Watson, and Breno de Medeiros.
      </t>
    </section>

    <section anchor="History" title="Document History">
      <t>[[ to be removed by the RFC Editor before publication as an RFC ]]</t>
      <t>
    	-01
        <list style="symbols">
        <t>
          Added usability, privacy, and security considerations.
        </t>
        <t>
          Documented alternative approaches.
        </t>
      </list>
      </t>
      <t>
    	-00
        <list style="symbols">
        <t>
          Initial draft based on the implementation of incremental and "appcremental" auth at Google.
        </t>
      </list>
      </t>
    </section>

  </back>
</rfc>
