--- Downloads/index.markdown	2010-05-16 11:47:22.000000000 -0700
+++ /Volumes/s75344.gridserver.com/domains/openidconnect.com/html/index.markdown	2010-05-19 00:48:06.000000000 -0700
@@ -33,11 +33,11 @@
 
 This information is either obtained by the client developer having read the server's documentation and pre-registered their application, or by performing [Discovery](#discovery) and a [Dynamic Association](#associations).
 
-The client constructs a regular [OAuth 2.0](http://tools.ietf.org/html/draft-ietf-oauth-v2) request to obtain an access token. If the client is making an immediate mode request, it can include a `user_id` parameter set to the identifier of the currently signed in user. If this parameter is included and the user signed into the server differs from the user signed into the client, the server MUST return an error.
+The client constructs a regular [OAuth 2.0](http://tools.ietf.org/html/draft-ietf-oauth-v2) request to obtain an access token.
 
-To turn an OAuth 2.0 request into an OpenID Connect request, simply include `openid` as one of the requested scopes. The `openid` scope means that the client is requesting an identifier for the user as well as the user's profile URL, name, and picture. The server (and user) may choose to make more or less profile information available to the client.
+To turn an OAuth 2.0 request into an OpenID Connect request, simply include `openid` as one of the requested scopes. The `openid` scope means that the client is requesting an identifier for the user as well as the user's profile URL, name, and picture. The server (and user) may choose to make more or less profile information available to the client. If the client also wants the user's email address, it should include the scope `email`.
 
-If the client also wants the user's email address, it should include the scope `email`.
+The client MAY include a `user_id` parameter set to the normalized user input or the user identifier of the currently logged in user (when using immediate mode). If this parameter is included and the user signed into the server differs from the user signed into the client, the server MUST return an error when using immediate mode.
 
 For example (line breaks added for display purposes):
 
@@ -52,35 +52,34 @@
 -----
 Receiving an OpenID Connect response
 --
-Assuming the user authorized the client's request, the following additional parameters are included in the OAuth 2.0 access token response from the server:
+Assuming the user authorized the client's request, the following additional parameters are included in the [OAuth 2.0 access token response](http://tools.ietf.org/html/draft-ietf-oauth-v2-05#section-3.3.2) from the server:
 
- * `user_id` - A unique URI for a user. If it is a URL, it MUST be HTTPS. e.g. "acct:recordond@gmail.com" or "https://graph.facebook.com/24400320"
+ * `user_id` - A unique HTTPS URI of the currently signed in user. e.g. "https://example-server.com/08lnwon1n21" or "https://graph.facebook.com/24400320"
  * `issued_at` - A unix timestamp of when this signature was created.
- * `signature` - HMAC-SHA256 with the key being the client Secret and the text being the access token, issued at, and user identifier.
+ * `signature` - HMAC-SHA256 with the key being the client Secret and the text being the access token, expires in, issued at, and user identifier.
 
 Note that unlike OpenID 1.0 and 2.0, the user identifier is different from the user's profile URL. This allows the identifier (and thus discovery) to be over SSL while not requiring that profile pages also be hosted via SSL.
 
-The client SHOULD then verify the signature. Doing so confirms the binding between the given access token and user identifier in addition to the response coming from the expected server. (If the client happened to get one of them wrong, the signature wouldn't validate.) If the client does not verify the signature, it MUST make a User Info API request and include its client identifier when doing so.
+The client MUST verify that the server's token endpoint is authoritative to issue assertions about the user identifier. If the domain (including sub-domain) of the user identifier matches the domain of the server's token endpoint URI then this verification is complete. If they do not match, the client MUST verify the assertion via [Discovery](#discovery).
 
-If the client made an immediate mode request, it MUST verify that the returned user identifier is the same as the logged in user. If not, the user that originally logged into the client no longer has an active session with the server.
-
-The client MUST perform discovery on the user identifier to verify that this server is authoritative for it. *This data should mainly be cached already. The chain to verify is that discovery on the returned user identifier points to the token endpoint URL which issued this OpenID response (or that the token endpoint URL then points to the user endpoint URL in the case of the User-Agent flow). Make sense?*
+The client SHOULD verify the signature. If the client does not verify the signature, it MUST make a [User Info API](#API) request and include its client identifier when doing so.
 
 *(Code sample goes here!)*
 
 <a name="API"></a>
 
 -----
-Accessing the User Info API
+Accessing user information
 --
-OpenID Connect defines a basic JSON-based API to access a user's profile data. This API is an OAuth 2.0 protected resource. The client constructs a HTTPS "GET" request to the `user_info_api_url` returned in the OpenID response and includes the access token as a parameter (or header).
+OpenID Connect user identifiers return a basic JSON document when fetched via HTTP. They are OAuth 2.0 protected resources which means that more information is included in the response when the client presents an access token. The client constructs a HTTPS "GET" request to the user identifier returned in the OpenID response and includes the access token as a parameter (or header).
 
-Clients can optionally include a `client_id` parameter and MUST if they do not verify the signature within the [response](#response). If this parameter is included and the access token was issued to a different client, the server MUST return an error.
+Clients SHOULD include a `client_id` parameter and MUST do so if they do not verify the signature within the [response](#response). If this parameter is included and the access token was issued to a different client, the server MUST return an error.
 
 The response is a JSON object which contains some (or all) of the following reserved keys:
 
  * `user_id` - e.g. "https://graph.facebook.com/24400320"
- * `url` - e.g. "http://www.facebook.com/davidrecordon"
+ * `asserted_user` - true if the access token presented was issued by this user, false if it is for a different user
+ * `profile_urls` - an array of URLs that belong to the user
  * `display_name` - e.g. "David Recordon"
  * `given_name` - e.g. "David"
  * `family_name` - e.g. "Recordon"
@@ -91,6 +90,8 @@
 
 For example, the [Simple Registration extension](http://openid.net/specs/openid-simple-registration-extension-1_0.html) could be updated to define a new scope to request birthday, gender, postal code, language, etc as well as the parameter names for this API. (It could also make sense to define a list of links which servers can populate with things such as the user's Activity Streams endpoint, but this information might fit better within the discovery process.)
 
+*We should add some sort of `openid2_url` field to this response to provide an upgrade path from non-SSL identifiers.*
+
 <a name="discovery"></a>
 
 -----
@@ -121,18 +122,11 @@
 <script src="http://gist.github.com/398238.js"></script>
 <br />
 
-**3)** Extract the domain and query its LRDD processor based on a well known location. The client should first make a SSL request and then fall back to HTTP if it failed. The client must not fallback to HTTP if the user inputed scheme was "https" or if the SSL request resulted in a certificate error. Cache the resulting document.
+**3)** Extract the domain and fetch it's host-meta file looking for the OpenID token endpoint URI. The client should first make a SSL request and then fall back to HTTP if it failed. The client must not fallback to HTTP if the user inputed scheme was "https" or if the SSL request resulted in a certificate error. Cache the resulting document.
 
-<pre><code>  GET /.well-known/lrdd?format=json&uri=https%3A%2F%2Fdavid.server.com%2F HTTP/1.1
+<pre><code>  GET /.well-known/host-meta?format=json HTTP/1.1
   Host: david.server.com</code></pre>
 
-If you're worried about making your LRDD processor URL dynamic, Apache's mod_rewrite can help within a .htaccess file:
-
-<pre><code>  RewriteEngine on
-  RewriteRule lrdd lrdd.php</code></pre>
-
-*A LRDD processor is a new concept that takes a URI and performs LRDD discovery on it. It then returns the resulting [LRDD resource descriptor](http://tools.ietf.org/html/draft-hammer-discovery-05#section-3). It allows clients to make a single HTTP request while preserving the ability to use headers and HTML tags to OpenID enable your URL. LRDD can be a long process and include many HTTP requests. Instead of forcing the client to implement it (it still can if it wants), we are proposing to move the burden to the server.* 
-
 **3b)** Parse the returned [JRD document](http://hueniverse.com/2010/05/jrd-the-other-resource-descriptor/). (Assuming a JSON format was requested)
 
 Look for a `link` array, find the element with a `rel` value of `openid`, and extract the value of `href`. This is the server's token endpoint URL. If you're familiar with OAuth 2.0, you'll know that it also has an end-user endpoint. The server tells the client about the end-user endpoint and User Info API during the dynamic association response.
@@ -144,20 +138,15 @@
 
 Note that HTML based discovery hasn't gone away, but is just encompassed within the [LRDD](http://tools.ietf.org/html/draft-hammer-discovery) spec. To simplify OpenID Connect client implementations, the server's LRDD processor takes care of both host-meta and HTML based discovery.
 
-URLs to look at:
-
- * http://www.davidrecordon.com/.well-known/lrdd?uri=http%3A%2F%2Fdavidrecordon.com%2F
- * http://www.davidrecordon.com/id.php
-
 Changes from host-meta and LRDD:
 
  * Uses a simple JSON document ("JRD") version of XRD
- * Adds a LRDD processor endpoint for bypassing the full LRDD resource description construction by clients.
 
 Changes from OpenID 2.0 discovery:
 
  * Much simpler technically. Places the work on the server versus the client having to try multiple different URLs, parse HTML, etc.
  * Requires that the domain support OpenID. Given that OpenID Connect separates the user identifier from the user's profile URL this should be okay. I could use MyOpenID as my OpenID server with a user identifier on their domain, but have my profile URL set to http://david.mybloghost.com/.
+ * Only allows one OpenID server per domain (or sub-domain).
 
 <a name="associations"></a>
 
@@ -188,7 +177,6 @@
  * `expires_in` - The number of seconds that this id and secret are good for or "0" if it does not expire.
  * `flows_supported` - A comma separated list of the OAuth 2.0 flows which this server supports. The server MUST support the Web server (`web_server`) and User-Agent (`user_agent`) flows.
  * `user_endpoint_url` - The URL of the server's user endpoint.
- * `user_info_api_url` - The URL of the server's User Info API endpoint.
 
 The client should store their dynamic associations based off of the server's token endpoint URL. With each dynamic association the client will store the client identifier, client secret, expiration time, user endpoint URL, supported flows, and User Info API endpoint URL. The expiration time should be stored as an absolute time or null if it lasts forever.
 
@@ -215,9 +203,7 @@
 
 **Q: What about delegation?**
 
-A: The original need for delegation was in 2005 when identity on the web was only starting. There wasn't buy in from email providers, ISPs, let alone social providers. I think that a form of delegation could be supported, but not in the sense that your blog URL becomes the identifier itself. Rather delegation creates a link between your blog URL and identifier.
-
-For example, http://www.davidrecordon.com/ has a link tag to https://server.myopenid.com/ and a link rel-me tag with a value of https://david.myopenid.com/. Thus OpenID Connect is performed against MyOpenID and MyOpenID returns a user identifier of https://david.myopenid.com/. If you wanted a bidirectional link then the OpenID Connect User Info API could also set the user's profile URL to http://www.davidrecordon.com/.
+A: The original need for delegation was in 2005 when identity on the web was only starting. There wasn't buy in from email providers, ISPs, let alone social providers. I think that a form of delegation could be supported, but not in the sense that your blog URL becomes the identifier itself. Rather delegation today allows you to have an OpenID server directly assert a domain you own as your user identifier.
 
 **Q: Why a scope of "openid" versus something more generic like "identity"?**
 
@@ -243,10 +229,6 @@
 
 A: Hopefully this will make it into OAuth 2.0 itself. If not, we'll add it here.
 
-**Q: Why have a separate User Info API endpoint versus just making the user identifier the endpoint?**
-
-A: It's unclear that separating them is the right answer, but we have to start somewhere. Having a separate endpoint gives services more flexibility in how they run their architecture. While user identifiers may be issued on one domain, the User Info API could run on another. It's also unclear how an email address would act as an API endpoint.
-
 **Q: Why not build this off of Public/Private key pairs? Wouldn't that eliminate the need for the association request?**
 
 A: We are still discussing the idea of using asymmetric secrets for signing request, similar to the Salmon protocol proposal. However, experience has shown that using cryptography is hard to develop and easy to get wrong. We feel it is better to start with something simpler (if possible).
