<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head profile="http://www.w3.org/2006/03/hcard http://dublincore.org/documents/2008/08/04/dc-html/">
  <meta http-equiv="Content-Type" content="text/html; charset=us-ascii" />

  <title>OpenID Connect Native SSO for Mobile Apps 1.0 - draft 03</title>

  <style type="text/css" title="Xml2Rfc (sans serif)">
  /*<![CDATA[*/
          a {
          text-decoration: none;
          }
      /* info code from SantaKlauss at http://www.madaboutstyle.com/tooltip2.html */
      a.info {
          /* This is the key. */
          position: relative;
          z-index: 24;
          text-decoration: none;
      }
      a.info:hover {
          z-index: 25;
          color: #FFF; background-color: #900;
      }
      a.info span { display: none; }
      a.info:hover span.info {
          /* The span will display just on :hover state. */
          display: block;
          position: absolute;
          font-size: smaller;
          top: 2em; left: -5em; width: 15em;
          padding: 2px; border: 1px solid #333;
          color: #900; background-color: #EEE;
          text-align: left;
      }
          a.smpl {
          color: black;
          }
          a:hover {
          text-decoration: underline;
          }
          a:active {
          text-decoration: underline;
          }
          address {
          margin-top: 1em;
          margin-left: 2em;
          font-style: normal;
          }
          body {
          color: black;
          font-family: verdana, helvetica, arial, sans-serif;
          font-size: 10pt;
          max-width: 55em;
          
          }
          cite {
          font-style: normal;
          }
          dd {
          margin-right: 2em;
          }
          dl {
          margin-left: 2em;
          }
        
          ul.empty {
          list-style-type: none;
          }
          ul.empty li {
          margin-top: .5em;
          }
          dl p {
          margin-left: 0em;
          }
          dt {
          margin-top: .5em;
          }
          h1 {
          font-size: 14pt;
          line-height: 21pt;
          page-break-after: avoid;
          }
          h1.np {
          page-break-before: always;
          }
          h1 a {
          color: #333333;
          }
          h2 {
          font-size: 12pt;
          line-height: 15pt;
          page-break-after: avoid;
          }
          h3, h4, h5, h6 {
          font-size: 10pt;
          page-break-after: avoid;
          }
          h2 a, h3 a, h4 a, h5 a, h6 a {
          color: black;
          }
          img {
          margin-left: 3em;
          }
          li {
          margin-left: 2em;
          margin-right: 2em;
          }
          ol {
          margin-left: 2em;
          margin-right: 2em;
          }
          ol p {
          margin-left: 0em;
          }
          p {
          margin-left: 2em;
          margin-right: 2em;
          }
          pre {
          margin-left: 3em;
          background-color: lightyellow;
          padding: .25em;
          }
          pre.text2 {
          border-style: dotted;
          border-width: 1px;
          background-color: #f0f0f0;
          width: 69em;
          }
          pre.inline {
          background-color: white;
          padding: 0em;
          }
          pre.text {
          border-style: dotted;
          border-width: 1px;
          background-color: #f8f8f8;
          width: 69em;
          }
          pre.drawing {
          border-style: solid;
          border-width: 1px;
          background-color: #f8f8f8;
          padding: 2em;
          }
          table {
          margin-left: 2em;
          }
          table.tt {
          vertical-align: top;
          }
          table.full {
          border-style: outset;
          border-width: 1px;
          }
          table.headers {
          border-style: outset;
          border-width: 1px;
          }
          table.tt td {
          vertical-align: top;
          }
          table.full td {
          border-style: inset;
          border-width: 1px;
          }
          table.tt th {
          vertical-align: top;
          }
          table.full th {
          border-style: inset;
          border-width: 1px;
          }
          table.headers th {
          border-style: none none inset none;
          border-width: 1px;
          }
          table.left {
          margin-right: auto;
          }
          table.right {
          margin-left: auto;
          }
          table.center {
          margin-left: auto;
          margin-right: auto;
          }
          caption {
          caption-side: bottom;
          font-weight: bold;
          font-size: 9pt;
          margin-top: .5em;
          }
        
          table.header {
          border-spacing: 1px;
          width: 95%;
          font-size: 10pt;
          color: white;
          }
          td.top {
          vertical-align: top;
          }
          td.topnowrap {
          vertical-align: top;
          white-space: nowrap; 
          }
          table.header td {
          background-color: gray;
          width: 50%;
          }
          table.header a {
          color: white;
          }
          td.reference {
          vertical-align: top;
          white-space: nowrap;
          padding-right: 1em;
          }
          thead {
          display:table-header-group;
          }
          ul.toc, ul.toc ul {
          list-style: none;
          margin-left: 1.5em;
          margin-right: 0em;
          padding-left: 0em;
          }
          ul.toc li {
          line-height: 150%;
          font-weight: bold;
          font-size: 10pt;
          margin-left: 0em;
          margin-right: 0em;
          }
          ul.toc li li {
          line-height: normal;
          font-weight: normal;
          font-size: 9pt;
          margin-left: 0em;
          margin-right: 0em;
          }
          li.excluded {
          font-size: 0pt;
          }
          ul p {
          margin-left: 0em;
          }
        
          .comment {
          background-color: yellow;
          }
          .center {
          text-align: center;
          }
          .error {
          color: red;
          font-style: italic;
          font-weight: bold;
          }
          .figure {
          font-weight: bold;
          text-align: center;
          font-size: 9pt;
          }
          .filename {
          color: #333333;
          font-weight: bold;
          font-size: 12pt;
          line-height: 21pt;
          text-align: center;
          }
          .fn {
          font-weight: bold;
          }
          .hidden {
          display: none;
          }
          .left {
          text-align: left;
          }
          .right {
          text-align: right;
          }
          .title {
          color: #990000;
          font-size: 18pt;
          line-height: 18pt;
          font-weight: bold;
          text-align: center;
          margin-top: 36pt;
          }
          .vcardline {
          display: block;
          }
          .warning {
          font-size: 14pt;
          background-color: yellow;
          }
        
        
          @media print {
          .noprint {
                display: none;
          }
        
          a {
                color: black;
                text-decoration: none;
          }
        
          table.header {
                width: 90%;
          }
        
          td.header {
                width: 50%;
                color: black;
                background-color: white;
                vertical-align: top;
                font-size: 12pt;
          }
        
          ul.toc a::after {
                content: leader('.') target-counter(attr(href), page);
          }
        
          ul.ind li li a {
                content: target-counter(attr(href), page);
          }
        
          .print2col {
                column-count: 2;
                -moz-column-count: 2;
                column-fill: auto;
          }
          }
        
          @page {
          @top-left {
                   content: "Internet-Draft"; 
          } 
          @top-right {
                   content: "December 2010"; 
          } 
          @top-center {
                   content: "Abbreviated Title";
          } 
          @bottom-left {
                   content: "Doe"; 
          } 
          @bottom-center {
                   content: "Expires June 2011"; 
          } 
          @bottom-right {
                   content: "[Page " counter(page) "]"; 
          } 
          }
        
          @page:first { 
                @top-left {
                  content: normal;
                }
                @top-right {
                  content: normal;
                }
                @top-center {
                  content: normal;
                }
          }
  /*]]>*/
  </style>

  <link href="#rfc.toc" rel="Contents">
<link href="#rfc.section.1" rel="Chapter" title="1 Introduction">
<link href="#rfc.section.1.1" rel="Chapter" title="1.1 Requirements Notation and Conventions">
<link href="#rfc.section.1.2" rel="Chapter" title="1.2 Terminology">
<link href="#rfc.section.2" rel="Chapter" title="2 Abstract Flow">
<link href="#rfc.section.3" rel="Chapter" title="3 Native App Authorization Extensions">
<link href="#rfc.section.3.1" rel="Chapter" title="3.1 Authorization Request">
<link href="#rfc.section.3.2" rel="Chapter" title="3.2 Device Secret">
<link href="#rfc.section.3.3" rel="Chapter" title="3.3 Token Request">
<link href="#rfc.section.3.4" rel="Chapter" title="3.4 Token Response">
<link href="#rfc.section.4" rel="Chapter" title="4 Token Exchange Profile for Native SSO">
<link href="#rfc.section.4.1" rel="Chapter" title="4.1 OAuth2 Token Exchange Profile">
<link href="#rfc.section.4.2" rel="Chapter" title="4.2 Token Exchange Request">
<link href="#rfc.section.4.3" rel="Chapter" title="4.3 Native SSO Processing Rules">
<link href="#rfc.section.4.4" rel="Chapter" title="4.4 Token Exchange Response">
<link href="#rfc.section.5" rel="Chapter" title="5 Security Considerations">
<link href="#rfc.references" rel="Chapter" title="6 References">
<link href="#rfc.references.1" rel="Chapter" title="6.1 Normative References">
<link href="#rfc.references.2" rel="Chapter" title="6.2 Informative References">
<link href="#rfc.appendix.A" rel="Chapter" title="A Acknowledgements">
<link href="#rfc.appendix.B" rel="Chapter" title="B Document History">
<link href="#rfc.authors" rel="Chapter">


  <meta name="generator" content="xml2rfc version 2.23.0 - https://tools.ietf.org/tools/xml2rfc" />
  <link rel="schema.dct" href="http://purl.org/dc/terms/" />

  <meta name="dct.creator" content="Fletcher, G." />
  <meta name="dct.identifier" content="urn:ietf:id:draft-oidc-connect-nativesso-03" />
  <meta name="dct.issued" scheme="ISO8601" content="2019-07-03" />
  <meta name="dct.abstract" content="OpenID Connect 1.0 is a simple identity layer on top of the OAuth 2.0 protocol. It enables Clients to verify the identity of the End-User based on the authentication performed by an Authorization Server, as well as to obtain basic profile information about the End-User in an interoperable and REST-like manner.This document describes a mechanism that allows a mobile app to share the identity/authentication obtained by a different mobile app where both apps are issued by the same vendor.  " />
  <meta name="description" content="OpenID Connect 1.0 is a simple identity layer on top of the OAuth 2.0 protocol. It enables Clients to verify the identity of the End-User based on the authentication performed by an Authorization Server, as well as to obtain basic profile information about the End-User in an interoperable and REST-like manner.This document describes a mechanism that allows a mobile app to share the identity/authentication obtained by a different mobile app where both apps are issued by the same vendor.  " />

</head>

<body>

  <table class="header">
    <tbody>
    
        <tr>
<td class="left"></td>
<td class="right">G. Fletcher</td>
</tr>
<tr>
<td class="left"></td>
<td class="right">Verizon Media</td>
</tr>
<tr>
<td class="left"></td>
<td class="right">July 3, 2019</td>
</tr>

        
    </tbody>
  </table>

  <p class="title">OpenID Connect Native SSO for Mobile Apps 1.0 - draft 03<br />
  <span class="filename">draft-oidc-connect-nativesso-03</span></p>
  
  <h1 id="rfc.abstract"><a href="#rfc.abstract">Abstract</a></h1>
<p>OpenID Connect 1.0 is a simple identity layer on top of the OAuth 2.0 protocol. It enables Clients to verify the identity of the End-User based on the authentication performed by an Authorization Server, as well as to obtain basic profile information about the End-User in an interoperable and REST-like manner.</p>
<p>This document describes a mechanism that allows a mobile app to share the identity/authentication obtained by a different mobile app where both apps are issued by the same vendor.  </p>

  
  <hr class="noprint" />
  <h1 class="np" id="rfc.toc"><a href="#rfc.toc">Table of Contents</a></h1>
  <ul class="toc">

        <li>1.   <a href="#rfc.section.1">Introduction</a>
</li>
<ul><li>1.1.   <a href="#rfc.section.1.1">Requirements Notation and Conventions</a>
</li>
<li>1.2.   <a href="#rfc.section.1.2">Terminology</a>
</li>
</ul><li>2.   <a href="#rfc.section.2">Abstract Flow</a>
</li>
<li>3.   <a href="#rfc.section.3">Native App Authorization Extensions</a>
</li>
<ul><li>3.1.   <a href="#rfc.section.3.1">Authorization Request</a>
</li>
<li>3.2.   <a href="#rfc.section.3.2">Device Secret</a>
</li>
<li>3.3.   <a href="#rfc.section.3.3">Token Request</a>
</li>
<li>3.4.   <a href="#rfc.section.3.4">Token Response</a>
</li>
</ul><li>4.   <a href="#rfc.section.4">Token Exchange Profile for Native SSO</a>
</li>
<ul><li>4.1.   <a href="#rfc.section.4.1">OAuth2 Token Exchange Profile</a>
</li>
<li>4.2.   <a href="#rfc.section.4.2">Token Exchange Request</a>
</li>
<li>4.3.   <a href="#rfc.section.4.3">Native SSO Processing Rules</a>
</li>
<li>4.4.   <a href="#rfc.section.4.4">Token Exchange Response</a>
</li>
</ul><li>5.   <a href="#rfc.section.5">Security Considerations</a>
</li>
<li>6.   <a href="#rfc.references">References</a>
</li>
<ul><li>6.1.   <a href="#rfc.references.1">Normative References</a>
</li>
<li>6.2.   <a href="#rfc.references.2">Informative References</a>
</li>
</ul><li>Appendix A.   <a href="#rfc.appendix.A">Acknowledgements</a>
</li>
<li>Appendix B.   <a href="#rfc.appendix.B">Document History</a>
</li>
<li><a href="#rfc.authors">Author's Address</a>
</li>


  </ul>

  <h1 id="rfc.section.1">
<a href="#rfc.section.1">1.</a> <a href="#Introduction" id="Introduction">Introduction</a>
</h1>
<p id="rfc.section.1.p.1">OpenID Connect 1.0 is a simple identity layer on top of the OAuth 2.0 <a href="#RFC6749" class="xref">[RFC6749]</a> protocol. It enables Clients to verify the identity of the End-User based on the authentication performed by an Authorization Server, as well as to obtain basic profile information about the End-User in an interoperable and REST-like manner.  </p>
<p id="rfc.section.1.p.2">As the industry moves to a more mobile oriented environment, vendors need a way to share identity across the multiple mobile apps they deploy. While the current OAuth2 best practice allows for SSO across any mobile app by sharing the session cookies in the system browser, this has risks such as a user clearing their system browser of cookies (possibly as requested by a customer care agent) or using private browsing on iOS and Android. On most mobile platforms, mobile apps signed by the same vendor certs can share information via the system "keychain" (Account Manager on Android).  </p>
<p id="rfc.section.1.p.3">This document specifies a new scope, extends the token endpoint and profiles the <a href="#OAuth2.TokenExchange" class="xref">OAuth2 token exchange</a> spec allowing mobile apps to share identity (SSO) between apps produced and signed by the same vendor (i.e. signed with the same vendor certificate).  </p>
<h1 id="rfc.section.1.1">
<a href="#rfc.section.1.1">1.1.</a> <a href="#rnc" id="rnc">Requirements Notation and Conventions</a>
</h1>
<p id="rfc.section.1.1.p.1">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 <a href="#RFC2119" class="xref">RFC 2119</a>.</p>
<p id="rfc.section.1.1.p.2">In the .txt version of this specification, values are quoted to indicate that they are to be taken literally.  When using these values in protocol messages, the quotes MUST NOT be used as part of the value.  In the HTML version of this specification, values to be taken literally are indicated by the use of <samp>this fixed-width font</samp>.  </p>
<h1 id="rfc.section.1.2">
<a href="#rfc.section.1.2">1.2.</a> <a href="#Terminology" id="Terminology">Terminology</a>
</h1>
<p id="rfc.section.1.2.p.1">This specification uses the terms "Authorization Server", "Client", "Client Identifier", and "Redirection URI" defined by <a href="#RFC6749" class="xref">OAuth 2.0</a>, the term "User Agent" defined by <a href="#RFC7230" class="xref">RFC 7230</a>, the term "native app" defined by <a href="#RFC8252" class="xref">RFC 8252</a> and the terms defined by <a href="#OpenID.Core" class="xref">OpenID Connect Core 1.0</a>.  </p>
<p id="rfc.section.1.2.p.2">This specification also defines the following terms: </p>

<dl>
<dt>Device Secret</dt>
<dd style="margin-left: 8">
<br> Opaque value to the client, issued by the Authorization Server, that uniquely identifies the device instance and provides credentials for the device.  </dd>
<dt>Session ID</dt>
<dd style="margin-left: 8">
<br> Identifier for a Session.  </dd>
</dl>

<p> </p>
<h1 id="rfc.section.2">
<a href="#rfc.section.2">2.</a> <a href="#AbstractFlow" id="AbstractFlow">Abstract Flow</a>
</h1>
<pre>
+----------+     +----------+      +-----------+      +------------+
|  Native  |     |  Native  |      |  System   |      |            |
|  App     |     |  App     |      |  Browser  |      |    AS      |
|  #1      |     |  #2      |      |           |      |            |
+----+-----+     +----+-----+      +-----+-----+      +-----+------+
     |                |                  |                  |
     | [1] Start OIDC AuthN              |                  |
     +----------------+----------------> |                  |
     |                |                  | [2] /authorize   |
     |                |                  +----------------> |
     |                |                  |                  |
     |                |                  |   [3] authenticate
     |                |                  | <----------------|
     |                |                  |                  |
     |                |                  | [4] user creds   |
     |                |                  +----------------> |
     |                |                  |                  |
     |                |                  |  [5] callback    |
     |                |                  | <----------------+
     |  [6] callback with code           |                  |
     | <--------------+------------------+                  |
     |                |                  |                  |
     |  [7] exchange code for tokens     |                  |
     +----------------+-----------------------------------> |
     |                |                  |                  |
     |     [8] tokens (including device_secret)             |
     | <--------------+------------------+------------------+
     |                |                  |                  |
     |                |                  |                  |
     |                |                  |                  |
     +                +                  +                  +

                        </pre>
<p id="rfc.section.2.p.1">Steps [1] - [8] are the standard OpenID Connect authorization_code flow with the following extensions. In step 2, the <samp>device_sso</samp> scope is specified signifying that the client is requesting a <samp>device_secret</samp> to be returned when the code is exchanged for tokens.</p>
<pre>
+----------+     +----------+      +-----------+      +------------+
|  Native  |     |  Native  |      |  System   |      |            |
|  App     |     |  App     |      |  Browser  |      |    AS      |
|  #1      |     |  #2      |      |           |      |            |
+----+-----+     +----+-----+      +-----+-----+      +-----+------+
     |                |                  |                  |
     |                |                  |                  |
     |                | [9] token exchange                  |
     |                +------------------+----------------> |
     |                |                  |                  |
     |                |                  |                  |
     |                |    [10] refresh, access, [device_secret]
     |                | <----------------+------------------|
     |                |                  |                  |
     |                |                  |                  |
     |                |                  |                  |
     +                +                  +                  +

                        </pre>
<p id="rfc.section.2.p.2">Step [9] invokes the /token endpoint with the token exchange profile passing the id_token obtained from the shared device storage, the client_id and the device secret.</p>
<p id="rfc.section.2.p.3">Step [10] returns the SSO generated refresh and access tokens for Native App #2.</p>
<h1 id="rfc.section.3">
<a href="#rfc.section.3">3.</a> <a href="#AuthZExtensions" id="AuthZExtensions">Native App Authorization Extensions</a>
</h1>
<p id="rfc.section.3.p.1">The following sections describe the extensions required to the standard OIDC Authentication flow which will enable a second mobile app to share the authentication of the first mobile app where both mobile applications are signed by the same vendor certificates.  </p>
<h1 id="rfc.section.3.1">
<a href="#rfc.section.3.1">3.1.</a> <a href="#AuthZReq" id="AuthZReq">Authorization Request</a>
</h1>
<p id="rfc.section.3.1.p.1">This specification defines a new scope value that is used to convey to the Authorization Server that when the code is exchanged for a token, a new <samp>device_secret</samp> will be returned in addition to the other tokens identified as part of the authorization request.</p>
<p id="rfc.section.3.1.p.2">The new scope value is defined as <samp>device_sso</samp>.  When this scope is present on the authorization request, when the code is exchanged for tokens, a new device_secret will be returned.</p>
<h1 id="rfc.section.3.2">
<a href="#rfc.section.3.2">3.2.</a> <a href="#DeviceSecret" id="DeviceSecret">Device Secret</a>
</h1>
<p id="rfc.section.3.2.p.1">The device secret contains relevant data to the device and the current users authenticated with the device. The device secret is completely opaque to the client and as such the AS MUST adequately protect the value such as using a JWE if the AS is not maintaining state on the backend.</p>
<p id="rfc.section.3.2.p.2">In the context of this extension the device secret may be shared between mobile apps that can obtain the value via the shared security mechanism (e.g. keychain on iOS). If a mobile app requests a device secret via the <samp>device_sso</samp> scope and a <samp>device_secret</samp> exists, then the client MUST provide the <samp>device_secret</samp> on the request to the /token endpoint to exchange code for tokens. The client SHOULD provide the <samp>device_secret</samp> to the /token endpoint during refresh token requests so that the AS may rotate the device_secert as necessary.</p>
<p id="rfc.section.3.2.p.3">The exact construction of the <samp>device_secret</samp> is out of scope for this specification.</p>
<h1 id="rfc.section.3.3">
<a href="#rfc.section.3.3">3.3.</a> <a href="#TokenReq" id="TokenReq">Token Request</a>
</h1>
<p id="rfc.section.3.3.p.1">During a normal user authentication via the system browser, after the mobile app receives the code and state response from the Authorization Server, this spec defines the following additional parameters to the /token endpoint for the authorization_code grant_type.  </p>

<dl>
<dt>device_secret</dt>
<dd style="margin-left: 8">
<br> OPTIONAL. This token SHOULD be provided if the client requested the <samp>device_sso</samp> scope and the client already has a <samp>device_secret</samp> available. If no <samp>device_secret</samp> is specified and the refresh_token contains the <samp>device_sso</samp> scope, a new <samp>device_secret</samp> will be generated.  </dd>
</dl>

<p> </p>
<h1 id="rfc.section.3.4">
<a href="#rfc.section.3.4">3.4.</a> <a href="#TokenRsp" id="TokenRsp">Token Response</a>
</h1>
<p id="rfc.section.3.4.p.1">When the authorization server receives the <em>device_secret</em> value it MUST process the authorization_code grant type per the OIDC spec with the following additions applying to the id_token.  </p>

<ol>
<li>Add a ?ds_hash? claim to the id_token to represent a function of the device_secret.  <dl>
<dt>ds_hash</dt>
<dd style="margin-left: 8">
<br> REQUIRED. The ds_hash value provides a binding between the id_token and the issued device_secret. The exact binding between the ds_hash and device_secret is not specified by this profile. As this binding is managed solely by the Authorization Server, the AS can choose how to protect the relationship between the id_token and device_secret.  </dd>
</dl>
<p> </p>
</li>
<li>Add a session id to the id_token that represents the user?s current authentication session.  <dl>
<dt>sid</dt>
<dd style="margin-left: 8">
<br> REQUIRED. A string that uniquely identifies this user?s authentication ?session?. This value can be used in logout flows as well as the flow this spec is describing.  For mobile apps where there is no explicit ?browser authentication? this value SHOULD represent the underlying session associated with the refresh_token.  </dd>
</dl>
<p> </p>
</li>
</ol>

<p> </p>
<p id="rfc.section.3.4.p.2">Note that the implementation of this spec and the specification of the ds_hash and sid value MUST NOT leak any data that would provide a security advantage to an attacker who gains access to the id_token.</p>
<p id="rfc.section.3.4.p.3">When the authorization server receives the device_secret it must validate the token. If the token is invalid it must be discarded and the request processed as if no device_secret was specified.</p>
<p id="rfc.section.3.4.p.4">If the authorization request included the device_sso scope then the authorization server MUST return a device_secret in the response.  The device_secret is returned in the ?device_token? claim of the returned JSON data.</p>
<p id="rfc.section.3.4.p.5">If no devices_secret is specified, then the AS MUST generate the token. If a device_secret is specified and is valid, the AS MAY update the device_secret as necessary. Regardless a device_secret must be returned in the response.</p>
<h1 id="rfc.section.4">
<a href="#rfc.section.4">4.</a> <a href="#NativeSSOTX" id="NativeSSOTX">Token Exchange Profile for Native SSO</a>
</h1>
<p id="rfc.section.4.p.1">This section profiles the <a href="#OAuth2.TokenExchange" class="xref">OAuth2 Token Exchange</a> spec and describes the processing rules used to exchange a previous authentication for new refresh and access tokens requested by a mobile app created by the same vendor as the first mobile app and both apps signed by the same developer certificate.</p>
<h1 id="rfc.section.4.1">
<a href="#rfc.section.4.1">4.1.</a> <a href="#TXProfile" id="TXProfile">OAuth2 Token Exchange Profile</a>
</h1>
<p id="rfc.section.4.1.p.1">The client authenticates using its registered token endpoint endpoint client authentication method. This could range from HTTP Basic Authentication, to OIDC defined private_key_jwt. The AS must be able to obtain the client_id of the requesting mobile app (mobile app #2) from the client authentication method.  </p>
<p id="rfc.section.4.1.p.2">This profile defines the use of the following token exchange parameters.  </p>

<dl>
<dt>grant_type</dt>
<dd style="margin-left: 8">
<br> REQUIRED. The value MUST be urn:ietf:params:oauth:grant-type:token-exchange </dd>
<dt>audience</dt>
<dd style="margin-left: 8">
<br> REQUIRED. This parameter defines the logical purview of the returned tokens.  For the purposes of this profile, this value MUST be the issuer URI for the OpenID Provider that issued the id_token used in this profile.  </dd>
<dt>subject_token</dt>
<dd style="margin-left: 8">
<br> REQUIRED. This parameter MUST contain the id_token obtained by the first native app. The id_token is used in the same manner as id_token_hint to identify the user to SSO into the invoking native app.  </dd>
<dt>subject_token_type</dt>
<dd style="margin-left: 8">
<br> REQUIRED. This parameter MUST contain the value: urn:ietf:params:oauth:token-type:id_token </dd>
<dt>actor_token</dt>
<dd style="margin-left: 8">
<br> REQUIRED. This value defines the actor making the request which in this case is the device_secret issued to the device of the native application making the request. The device_secret MUST be presented per the definition of the urn:x-oath:params:oauth:token-type:device-secret token identifier described below.  </dd>
<dt>actor_token_type</dt>
<dd style="margin-left: 8">
<br> REQUIRED. This value MUST be: urn:x-oath:params:oauth:token-type:device-secret </dd>
<dt>scope</dt>
<dd style="margin-left: 8">
<br> OPTIONAL. The scopes required by the requesting native application.  </dd>
<dt>requested_token_type</dt>
<dd style="margin-left: 8">
<br> OPTIONAL. The desired token(s) to be returned. If no requested_token_type is defined, it is up to the AS to return the appropriate tokens for the requesting client. The full set of possible requested_token_type value is out of scope for this specification.  </dd>
</dl>

<p> </p>
<p id="rfc.section.4.1.p.3">This profile also defines the following token type identifiers.  </p>

<dl>
<dt>urn:x-oath:params:oauth:token-type:device-secret</dt>
<dd style="margin-left: 8">
<br> This token type identifier is used to describe the device_secret specified in the actor_token parameter.  </dd>
</dl>

<p> </p>
<h1 id="rfc.section.4.2">
<a href="#rfc.section.4.2">4.2.</a> <a href="#TXReq" id="TXReq">Token Exchange Request</a>
</h1>
<p id="rfc.section.4.2.p.1">When a mobile app wants to request ?native SSO? (i.e. obtain refresh and access tokens for an already signed in user) it makes a standard OAuth2 /token endpoint request following the profile for Token Exchange defined above.</p>
<p id="rfc.section.4.2.p.2">The following is a non-normative example</p>
<pre>
    POST /token HTTP/1.1
    Host: as.example.com
    Authorization: Basic ZGZhZGYyMzUyNDU0Og
    ...
    grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Atoken-exchange
    &audience=https%3A%3F%3Flogin.example.net&subject_token=<id_token>
    &subject_token_type=urn%3Aietf%3Aparams%3Aoauth%3Atoken-type%3Aid-token
    &actor_token=95twdf3w4y6wvftw35634t
    &actor_token_type=urn%3Ax-oath%3Aparams%3Aoauth%3Atoken-type%3Adevice-secret
              </pre>
<p id="rfc.section.4.2.p.3">The client_id in this request is sent via the HTTP Basic Authentication method using the HTTP Authorization header.</p>
<h1 id="rfc.section.4.3">
<a href="#rfc.section.4.3">4.3.</a> <a href="#TXRules" id="TXRules">Native SSO Processing Rules</a>
</h1>
<p id="rfc.section.4.3.p.1">When the authorization server receives a request at the token endpoint conforming to this profile it MUST perform the following checks before issuing any tokens.  </p>

<ol>
<li>Validate the device_secret to ensure the token is still valid. The format of this secret is defined by the Authorization server and is out of scope for this specification.</li>
<li>Verify that the binding between the id_token and the device_secret (as defined in the extension to the /token response) is valid.</li>
<li>Verify that the session id in the id_token (?sid? claim) is still valid. If the session is no longer valid, the AS MUST return an error of ?invalid_grant?. Note that in the case of a refresh_tokens issued with an offline_scope the 'sid' value SHOULD represent the offline "session" such that if the original refresh_token is revoked the 'ds_hash' value in the id_token is not longer valid.  </li>
<li>Validate that the client requesting native SSO is authorized to do so. The AS SHOULD maintain a list of client_ids that can share user authentications. For example, the AS MAY take the ?aud? claim from the id_token and the client_id from the token request and ensures that both client_ids are allowed to share user authentications.</li>
<li>The AS SHOULD verify that the scopes requested by the client in the token request (either default scopes or explicitly specified in the optional ?scope? parameter) do NOT require explicit user consent. If any requested scopes require explicit user consent the AS SHOULD fail the request and return an error of ?invalid_scope?.</li>
</ol>

<p> </p>
<p id="rfc.section.4.3.p.2">Based on the AS definition of the device_secret, the AS may perform addition checks to ensure the security of the request. Provided the above criteria is met, the AS will issue a normal Token Response object containing a refresh_token, access_token and id_token issued to the client_id of the mobile app making the request. The session associated with the new refresh_token SHOULD be the same as that used to verify the validity of the SSO exchange. If that session expires, all refresh_tokens associated with it MUST be invalidated.</p>
<h1 id="rfc.section.4.4">
<a href="#rfc.section.4.4">4.4.</a> <a href="#TXRsp" id="TXRsp">Token Exchange Response</a>
</h1>
<p id="rfc.section.4.4.p.1">The Token Exchange response for this profile has the following characteristics: </p>

<dl>
<dt>access_token</dt>
<dd style="margin-left: 8">
<br> REQUIRED. This response field contains the access token issued to the mobile client identified by the client_id sent in the Authorization header.  </dd>
<dt>issued_token_type</dt>
<dd style="margin-left: 8">
<br> REQUIRED. This value of this parameter MUST be: urn:ietf:params:oauth:token-type:access_token </dd>
<dt>token_type</dt>
<dd style="margin-left: 8">
<br> REQUIRED. The value of this parameter MUST be <samp>bearer</samp>.  </dd>
<dt>expires_in</dt>
<dd style="margin-left: 8">
<br> RECOMMENDED. Identifies when the access_token expires.  </dd>
<dt>scope</dt>
<dd style="margin-left: 8">
<br> OPTIONAL. Follows the token exchange spec definition.  </dd>
<dt>refresh_token</dt>
<dd style="margin-left: 8">
<br> OPTIONAL. By default the AS should return a refresh_token that the mobile app can use to obtain additional access_tokens when the access_token expires.  </dd>
<dt>id_token</dt>
<dd style="margin-left: 8">
<br> OPTIONAL. By default the AS should return an id_token that provides the mobile app with an identity assertion about the user.  </dd>
<dt>device_secret</dt>
<dd style="margin-left: 8">
<br> OPTIONAL. The AS MAY return an updated device_secret in the response.  </dd>
</dl>

<p> </p>
<p id="rfc.section.4.4.p.2">In the case of any errors, the AS MUST return a valid OAuth2 Error response as described in Section 2.2.2 of the Token Exchange spec.</p>
<p id="rfc.section.4.4.p.3">The following is a non-normative example</p>
<pre>
    HTTP/1.1 200 OK
    Content-Type: application/json;charset=UTF-8
    Cache-Control: no-store
    Pragma: no-cache

    {
      "access_token":"2YotnFZFEjr1zCsicMWpAA",
      "issued_token_type": "urn:ietf:params:oauth:token-type:access_token",
      "token_type":"Bearer",
      "expires_in":3600,
      "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
      "id_token":"<id_token>",
      "device_secret":"casdfgarfgasdfg"
    }
              </pre>
<h1 id="rfc.section.5">
<a href="#rfc.section.5">5.</a> <a href="#Security" id="Security">Security Considerations</a>
</h1>
<p id="rfc.section.5.p.1">Sufficient care must be made to protect the <samp>device_secret</samp>.  The device secret SHOULD be encrypted by the Authorization Service and periodically refreshed via the mechanisms described in this specification.  </p>
<h1 id="rfc.references">
<a href="#rfc.references">6.</a> References</h1>
<h1 id="rfc.references.1">
<a href="#rfc.references.1">6.1.</a> Normative References</h1>
<table><tbody>
<tr>
<td class="reference"><b id="IANA.JWT.Claims">[IANA.JWT.Claims]</b></td>
<td class="top">
<a>IANA</a>, "<a href="http://www.iana.org/assignments/jwt">JSON Web Token Claims</a>"</td>
</tr>
<tr>
<td class="reference"><b id="IANA.OAuth.Parameters">[IANA.OAuth.Parameters]</b></td>
<td class="top">
<a>IANA</a>, "<a href="http://www.iana.org/assignments/oauth-parameters">OAuth Parameters</a>"</td>
</tr>
<tr>
<td class="reference"><b id="OAuth2.TokenExchange">[OAuth2.TokenExchange]</b></td>
<td class="top">
<a title="Ping Identity">Campbell, B.</a>, "<a href="https://tools.ietf.org/html/draft-ietf-oauth-token-exchange-14">OAuth 2.0 Token Exchange</a>", June 2018.</td>
</tr>
<tr>
<td class="reference"><b id="OpenID.BackChannel">[OpenID.BackChannel]</b></td>
<td class="top">
<a title="Microsoft">Jones, M.</a> and <a title="Ping Identity">J. Bradley</a>, "<a href="http://openid.net/specs/openid-connect-backchannel-1_0.html">OpenID Connect Back-Channel Logout 1.0</a>", January 2017.</td>
</tr>
<tr>
<td class="reference"><b id="OpenID.Core">[OpenID.Core]</b></td>
<td class="top">
<a title="Nomura Research Institute, Ltd.">Sakimura, N.</a>, <a title="Ping Identity">Bradley, J.</a>, <a title="Microsoft">Jones, M.</a>, <a title="Google">de Medeiros, B.</a> and <a title="Salesforce">C. Mortimore</a>, "<a href="http://openid.net/specs/openid-connect-core-1_0.html">OpenID Connect Core 1.0</a>", November 2014.</td>
</tr>
<tr>
<td class="reference"><b id="OpenID.Discovery">[OpenID.Discovery]</b></td>
<td class="top">
<a title="Nomura Research Institute, Ltd.">Sakimura, N.</a>, <a title="Ping Identity">Bradley, J.</a>, <a title="Microsoft">Jones, M.</a> and <a title="Illumila">E. Jay</a>, "<a href="http://openid.net/specs/openid-connect-discovery-1_0.html">OpenID Connect Discovery 1.0</a>", November 2014.</td>
</tr>
<tr>
<td class="reference"><b id="OpenID.Registration">[OpenID.Registration]</b></td>
<td class="top">
<a title="Nomura Research Institute, Ltd.">Sakimura, N.</a>, <a title="Ping Identity">Bradley, J.</a> and <a title="Microsoft">M. Jones</a>, "<a href="http://openid.net/specs/openid-connect-registration-1_0.html">OpenID Connect Dynamic Client Registration 1.0</a>", November 2014.</td>
</tr>
<tr>
<td class="reference"><b id="OpenID.Session">[OpenID.Session]</b></td>
<td class="top">
<a title="Nomura Research Institute, Ltd.">Sakimura, N.</a>, <a title="Ping Identity">Bradley, J.</a>, <a title="Microsoft">Jones, M.</a>, <a title="Google">de Medeiros, B.</a>, <a title="Salesforce">Mortimore, C.</a> and <a title="Illumila">E. Jay</a>, "<a href="http://openid.net/specs/openid-connect-session-1_0.html">OpenID Connect Session Management 1.0</a>", January 2017.</td>
</tr>
<tr>
<td class="reference"><b id="RFC2119">[RFC2119]</b></td>
<td class="top">
<a>Bradner, S.</a>, "<a href="https://tools.ietf.org/html/rfc2119">Key words for use in RFCs to Indicate Requirement Levels</a>", BCP 14, RFC 2119, DOI 10.17487/RFC2119, March 1997.</td>
</tr>
<tr>
<td class="reference"><b id="RFC3986">[RFC3986]</b></td>
<td class="top">
<a>Berners-Lee, T.</a>, <a>Fielding, R.</a> and <a>L. Masinter</a>, "<a href="https://tools.ietf.org/html/rfc3986">Uniform Resource Identifier (URI): Generic Syntax</a>", STD 66, RFC 3986, DOI 10.17487/RFC3986, January 2005.</td>
</tr>
<tr>
<td class="reference"><b id="RFC6749">[RFC6749]</b></td>
<td class="top">
<a>Hardt, D.</a>, "<a href="https://tools.ietf.org/html/rfc6749">The OAuth 2.0 Authorization Framework</a>", RFC 6749, DOI 10.17487/RFC6749, October 2012.</td>
</tr>
<tr>
<td class="reference"><b id="RFC7230">[RFC7230]</b></td>
<td class="top">
<a>Fielding, R.</a> and <a>J. Reschke</a>, "<a href="https://tools.ietf.org/html/rfc7230">Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing</a>", RFC 7230, DOI 10.17487/RFC7230, June 2014.</td>
</tr>
<tr>
<td class="reference"><b id="RFC8252">[RFC8252]</b></td>
<td class="top">
<a>Denniss, W.</a> and <a>J. Bradley</a>, "<a href="https://tools.ietf.org/html/rfc8252">OAuth 2.0 for Native Apps</a>", BCP 212, RFC 8252, DOI 10.17487/RFC8252, October 2017.</td>
</tr>
</tbody></table>
<h1 id="rfc.references.2">
<a href="#rfc.references.2">6.2.</a> Informative References</h1>
<table><tbody>
<tr>
<td class="reference"><b id="JWT">[JWT]</b></td>
<td class="top">
<a title="Microsoft">Jones, M.</a>, <a title="Ping Identity">Bradley, J.</a> and <a title="Nomura Research Institute, Ltd.">N. Sakimura</a>, "<a href="https://tools.ietf.org/html/rfc7519">JSON Web Token (JWT)</a>", RFC 7519, DOI 10.17487/RFC7519, May 2015.</td>
</tr>
<tr>
<td class="reference"><b id="RFC7591">[RFC7591]</b></td>
<td class="top">
<a>Richer, J.</a>, <a>Jones, M.</a>, <a>Bradley, J.</a>, <a>Machulak, M.</a> and <a>P. Hunt</a>, "<a href="https://tools.ietf.org/html/rfc7591">OAuth 2.0 Dynamic Client Registration Protocol</a>", RFC 7591, DOI 10.17487/RFC7591, July 2015.</td>
</tr>
</tbody></table>
<h1 id="rfc.appendix.A">
<a href="#rfc.appendix.A">Appendix A.</a> <a href="#Acknowledgements" id="Acknowledgements">Acknowledgements</a>
</h1>
<p id="rfc.section.A.p.1">The OpenID Community would like to thank the following people for their contributions to this specification: </p>
<p></p>

<ul class="empty">
<li>Nat Sakimura, Nomura Reserach Institute, Ltd.</li>
<li>Nov Matake</li>
<li>Filip Skokan</li>
</ul>

<p> </p>
<h1 id="rfc.appendix.B">
<a href="#rfc.appendix.B">Appendix B.</a> <a href="#History" id="History">Document History</a>
</h1>
<p id="rfc.section.B.p.1">[[ To be removed from the final specification ]]</p>
<p id="rfc.section.B.p.2">-00 </p>

<ul>
<li>Initial Draft.  </li>
<li>Draft-03 - Applied updates from the community. Removed non-relevant IANA claims section.  </li>
</ul>

<p> </p>
<h1 id="rfc.authors"><a href="#rfc.authors">Author's Address</a></h1>
<div class="avoidbreak">
  <address class="vcard">
        <span class="vcardline">
          <span class="fn">George F. Fletcher</span> 
          <span class="n hidden">
                <span class="family-name">Fletcher</span>
          </span>
        </span>
        <span class="org vcardline">Verizon Media Group</span>
        <span class="adr">
          
          <span class="vcardline">
                <span class="locality"></span> 
                <span class="region"></span>
                <span class="code"></span>
          </span>
          <span class="country-name vcardline"></span>
        </span>
        <span class="vcardline">EMail: <a href="mailto:george.fletcher@verizonmedia.com">george.fletcher@verizonmedia.com</a></span>

  </address>
</div>

</body>
</html>