OGP Authentication Draft 3

Open Grid Protocol: Authentication
:Draft 3
:September 2008
::Notice: This draft is for public comment. 
::Mark Lentczner (Zero Linden) Linden Lab zero.linden@secondlife.com
::Tess Chu (Tess Linden) Linden Lab tess@lindenlab.com
::Meadhbh Hamrick (Infinity Linden) Linden Lab infinity@lindenlab.com
::Copyright 2008, Linden Lab. All rights reserved. 
::This work is licensed under the Creative Commons Attribution-Share Alike 3.0 license. See http://creativecommons.org/licenses/by-sa/3.0/for details. 
::All contributions to this document must be contributed under the Second Life Project Contribution Agreement. See http://wiki.secondlife.com/wiki/Project:Contribution_Agreementfor details 
:Abstract
::Authentication in Open Grid Protocol establishes the connection between a viewer of a virtual world and an agent domain that manages an avatar account. 
:Status
::As of Summer 2008, this protocol is a work in progress. While the major structural elements have been designed, the specific elements for many needed resources have not. This work is being undertaken by Linden Lab and its community based Architecture Working Group. 
::This protocol is being defined in light of feature set of Second Life. For now, where this document is currently lacking details, familiarity with Second Life will be assumed. It is an express aim of this work to enable the live, gradual migration of Second Life to using this new protocol as the development proceeds. 
 discuss
== Agent Login (Resource Class) ==
 discuss
=== introduction ===
Authentication is the first step in associating a client application with the agent domain, and subsequently, one or more regions. Before a client application may interact with the agent domain, it must authenticate itself by presenting credentials proving it has the right to control the agent. Authentication is the process of presenting an "Identifier" and an "Authenticator" to the agent domain and receiving a "Capability" providing further access to system resources or an actionable error description. The protocol defines an identifier as an agent or account information, distinct from its related authenticator. 
Authentication begins by requesting the >>> code
agent_login resource; that is, POSTing the "LLSD" description of an identifier and an authenticator to a well-known URL. The agent domain managing this resource then makes an access control decision based on the verity of the credential and the state of the agent domain. The result of this authentication, whether success or failure, it is returned to the client application via a LLSD message. The content and form of these messages are provided below in "LLIDL format." 
The authentication process results in one of seven classes of response from the agent domain: 
* success 
* deferred success due to maintenance 
* authentication non-success due to missing secret 
* authentication failure 
* agent selection failure 
* "user intervention required" failure, and 
* "non-specified" failure. 
Responses to authentication requests are successes, non-successes and failures. A "success" indicates the client application should have enough information to progress past the authentication phase and begin using the service. A "deferred success" implies use of the system will continue after a "short" period. In either case, the agent domain does not expect the client application to re-submit the >>> code
agent_login request. Authentication "non-success" results from a client requesting per-agent or per-account authentication parameters. After sending a "non-success", the agent domain expects the client to resubmit the >>> code
agent_login request "shortly." Failures of all type indicate the agent domain believes a condition exists requiring explicit user intervention. In the case of an authentication failure, the user should either retry the authentication request or recover their password. A failure due to "user intervention required" indicates the agent domain believes the user's account is in a state that required "out of band" recovery. Reading and accepting the agent domain's Terms of Service or Critical Messages are examples of recovering from "user intervention required" failures. Non-Specified failures indicate a non-recoverable problem that is not defined in this specification. 
The section below on Processing Expectations provides more guidance. 
==== Account identifiers and Agent identifiers ====
Client applications may authenticate using an "Account Identifier" or an "Agent Identifier". Either type of identifier may be used for authentication. An agent domain MUST support one of the two types of identifiers, and MAY support both. Client applications SHOULD support both identifier types. 
An "Account" is an administrative object holding one or more references to an "Agent." This is advantageous in situations where: 
# the agent domain does not wish to use an agent first name and last name to identify a user, but wishes to use another identifier (such as an email address or account number,) or 
# the agent domain wishes to allow users with several agents to authenticate with the same authenticator, freeing them from the requirement of memorizing each individual agent authenticator.. 
Please note this spec does not imply a structure to the account identifier. Though an agent domain may use an email address as an account identifier, the protocol does not require it and treats the identifier simply as an opaque sequence of octets. 
==== Flexible Authentication ====
This revision of the Open Grid Protocol defines, but does not require the use of, two additional authentication schemes: challenge-response and PKCS#5 Key Derivation 2. 
 discuss
=== Service Location ===
Each Agent Domain MUST have a well known and published authentication URL. The Second Life agent domain authentication URL is: 
 https://login.agni.secondlife.com/cgi-bin/auth.cgi
 discuss
=== Inputs ===
LLIDL descriptions are provided below for both agent identifiers and account identifiers. Client applications may use either as the basis for authentication. 
==== Agent Identifier ====
An agent identifier contains the first and last name of an agent. 
==== Account Identifier ====
An account identifier must contain the >>> code
account_name key. This is the opaque sequence of octets used by the agent domain to identify the user. If an account is associated with multiple agents, the client application SHOULD include the >>> code
first_name and >>> code
last_name of the agent the user wishes to use. 
==== Hashed Password Authenticator ====
When a hashed password is used as an authenticator, the string '$1$' is prepended to the UTF-8 encoding of the password and processed with the MD5 cryptographic hash function. >>> bibref
This revision of the Open Grid Protocol specification requires the use of MD5 with the hashed password authenticator. It also requires the presence of the >>> code
algorithm key, and that the value of this key be the string 'md5'. Note that future versions of this specification may ALLOW or REQUIRE the use of other cryptographic hash functions. 
==== Challenge-Response Authenticator ====
The Challenge-Response scheme allows the agent domain to select a session specific "Salt" to be used in conjunction with the user's password to generate an authenticator. In this scheme the authenticator is the hash of the salt prepended to the hash of '$1$' prepended to the password. This revision of the Open Grid Protocol specification requires the use of SHA256 with the challenge-response authenticator. >>> bibref
It also requires the presence of the >>> code
algorithm key, and that the value of this key be the string 'sha256'. Note that future versions of this specification may ALLOW or REQUIRE the use of other cryptographic hash functions. 
To retrieve a session specific salt for use with the Challenge-Response authentication scheme from the agent domain, the client application sends a login request with a Challenge-Response authenticator without the secret item. If the agent domain supports this authenticator, it MUST respond with a 'key' condition including a salt and MAY include a duration in the response. If the duration is present, it denotes the number of seconds for which the salt will be valid. 
::Note: The Challenge-Response Authentication Scheme is not currently deployed on the Second Life Grid. 
==== PKCS#5 PBKDF2 Authenticator ====
The PKCS#5 PBKDF2 authenticator is an implementation of RSA Labs' Public Key Cryptographic Standards #5 v2.1 Password Based Key Derivation Function #2. >>> bibref
In this scheme, the hash of the string '$1$' prepended to the password is used in conjunction with a salt, iteration count and hash function to generate an authenticator. This revision of the Open Grid Protocol specification requires the use of SHA256 with the PKCS#5 PBKDS2 authenticator. It also requires the presence of the >>> code
algorithm key, and that the value of this key be the string 'sha256'. Note that future versions of this specification may ALLOW or REQUIRE the use of other cryptographic hash functions. 
As with the Challenge-Response authenticator, the agent domain MUST include the salt and iteration count in its response to an authentication request that is made without a secret item. Conforming agent domains may include a duration in their response indicating the number of seconds for which the salt and iteration count will be valid. 
::Note: The PKCS#5 PBKDF2 Authentication Scheme is not currently deployed on the Second Life Grid. 
 discuss
=== Response ===
The response to the agent login message is notice of one of seven "conditions": 
* authentication success 
* maintenance deferred success 
* authentication non-success 
* authentication failure 
* agent selection failure 
* "user intervention required" failure, and 
* "non-specific" failure. 
The specification recognizes three "non-failure" responses: 
==== Success ====
Upon success, the agent domain will respond with a message containing the "Agent Seed Capability". Receipt of this capability indicates authentication was successful. This capability is then used for further interactions with the system. 
==== Maintenance Deferred Success ====
This condition indicates per-agent (or per-account) login-time maintenance is being performed. It is not an error. The response includes a maintenance cap the client application should use to get information about currently executing maintenance. For more information about maintenance, see the Maintenance section below. 
==== Authentication Non-Success ====
Authentication Non-Success is the response given when a client queries the agent domain for agent-specific or account-specific authentication parameters. In that it is the expected response to such a query, it is not an error or exception. But it is not an indication of successful authentication. 
 discuss
=== Errors and Exceptions ===
==== Authentication Failure ====
An authentication failure indicates the client application did not provide enough information to authenticate the account or the agent. 
==== Agent Selection Failure ====
An agent selection failure occurs when an account authentication request is ambiguous. In other words, the account a user has attempted to use to log in is associated with more than one agent account and the client application did not specify which account to use. The response includes a list of first_name / last_name pairs. It is expected that the client application will present this list to the user and ask which agent to use. 
==== "User Intervention Required" Failure ====
This error indicates that the agent domain cannot authenticate the user for non-technical reasons. The protocol does not attempt to describe why, or imply remediation for this error. But an agent domain that returns this response MUST provide a URL containing a message describing the condition leading to the error and remediation, if known. 
==== "Non Specific" Failure ====
This error indicates some other error exists which does not fall into one of the previous six conditions. 
 discuss
=== Preconditions ===
==== Client Preconditions ====
It is generally assumed that before a user attempts to log into an agent domain, they will not be actively connected to that agent domain. 
It is also assumed that the user has registered their account and/or agent; user registration is outside the scope of this specification. 
The client application SHOULD present the agent domain's Terms of Service and Critical Messages and allow a user to accept or decline them prior to attempting to authenticate. 
==== Agent Domain Preconditions ====
If the agent domain requires users to read and agree to the Terms of Service or acknowledge receipt of Critical Messages prior to authentication, it must maintain a record of which accounts and agents have accepted and acknowledged these items. 
Agent domains that support the concept of "suspension" or "disablement" should also maintain a record of which accounts and agents are suspended or disabled. 
 discuss
=== Postconditions ===
==== Client Postconditions ====
Following successful authentication, the client application SHOULD note that the agent has been authenticated to the agent domain. The Open Grid Protocol is NOT stateless. 
==== Agent Domain Postconditions ====
After an agent (or account) is authenticated, a seed capability is allocated for the agent. The agent domain SHOULD maintain the association between agent credentials (first_name and last_name) and the seed capability so it may be re-used if the client attempts to re-authenticate the user. 
 discuss
=== Side Effects ===
The agent domain SHOULD maintain the "presence" state of an agent. This state should include the agent's seed capability. If a previously authenticated and "present" agent re-authenticates successfully, the agent domain MAY return the same seed capability. 
After successful authentication, it is expected that the client will issue another request against the seed capability. To defend against potential Denial of Service attacks against the agent domain, the agent domain MAY define a timeout period for the seed capability. If the timeout period expires without a request being made against the seed capability, that seed capability will expire. Successful authentication of an agent who is "not present" has the effect of starting this timer. 
The Challenge-Response Authenticator is intended to be used with a new, randomly generated salt for each authentication request. If the agent domain supports the Challenge-Response authentication scheme, it must maintain the "most recently generated salt" for some period of time (generally until the expiration of the duration period given in the authentication non-success response.) 
After the salt has "timed out" following an unsuccessful Challenge-Response authentication request, the agent domain MUST NOT allow the use of a previous or fixed salt value. That is, it is not correct, after the salt has expired, to use a null, fixed or previous salt. The agent domain MUST generate a new salt and return it to the client application. An unsuccessful authentication request with the Challenge-Response scheme also has the side effect of starting the salt duration timer. When this timer expires, the agent domain MUST not allow authentication with previously generated salts. 
 discuss
=== Sequence of Events ===
It is possible for an authentication request to occur in conditions where multiple errors or exceptions COULD be returned. As the protocol does not support reporting multiple failure conditions, the following sequence is provided to determine the priority of failure conditions. This sequence of events is motivated by the following principles: 
* The agent domain should leak no account status information to an unauthenticated user. 
* Maintenance should occur after successful authentication and before account status checking in case maintenance involves the representation of these states by the agent domain. 
* The agent domain should check for "administrative issues" after maintenance is complete. 
The sequence for authentication is as follows. At the first error, the system produces an appropriate error response. 
# If the authenticator provided is a Challenge-Response or PKCS#5 PBKDF2 type AND a secret is not included, the system returns an authentication non-success response. 
# The secret and optional authentication parameters are used to verify the client is in possession of the shared secret. If authentication is unsuccessful, an authentication failure response is returned. 
# If per-user login-time maintenance must be performed, the agent domain allocates a maintenance capability and returns it to the client application as a maintenance deferred success response. 
# If an account credential was used for authentication and the account "contains" two or more agents and the client application did not provide the first_name and last_name of the agent to log in as, generate a list of all agents associated with this account and return an agent selection failure response. 
# If an "administrative issue" exists such as the user is suspended, banned, must agree to the terms of service or read critical messages, the system returns a "user intervention required" response, providing a URL referencing a web resource explaining the administrative issue and describing remediation steps. 
# Check to see if the authenticated agent is associated with an agent seed capability already. If so, return a success response referencing that seed capability. 
# Start the seed capability timer. Allocate an agent seed capability and return it to the client application via a success response. 
 discuss
=== Interface (POST) ===
The following text describes the LLIDL description of the agent_login messages. 
 ; authenticators
 
 ; hashed password authenticator
 
 &authenticator = {
 type: 'hash', ; identifies this authenticator as a "hashed" type
 algorithm: 'md5', ;
 secret: binary ; hash of the salt prepended to the password;
 ; s = h( '$1$' | pw )
 }
 
 ; challenge response style authenticator
 
 &authenticator = {
 type: 'challenge', ; identifies this as a "challenge response" type
 algorithm: 'sha256', ; 
 salt: binary, ; optional - ( 0x24, 0x31, 0x24 ) used if not present
 secret: binary ; hash of the salt prepended to the password;
 ; s = h( salt | h( '$1$' | pw ) )
 }
 
 ; PKCS#5 PBKDF2 style authenticator
 
 &authenticator = {
 type: 'pkcs5pbkdf2', ; identifies this authenticator as a PKCS#5 PBKDF2
 algorithm: string, ; identifier for hash ('md5' or 'sha256') 
 salt: binary, ; optional - ( 0x24, 0x31, 0x24 ) used if not present
 count: integer, ; optional - 1 used if not present
 secret: binary ; hash of the salt prepended to the password;
 ; s = pbkdf2( h('$1$' | pw), salt, count, 128 )
 }
 
 ; identifier types
 
 ; account identifier
 
 &identifier = {
 type: 'account', ; identifies this as an "account identifier"
 account_name: string,
 first_name: string, ; optional - first_name and last_name identify
 last_name: string, ; agent to log in as for accounts with more than
 ; one agent
 }
 
 ; agent identifier
 
 &identifier = {
 type: 'agent', ; identifies this as an "agent identifier"
 first_name: string,
 last_name: string,
 }
 
 ; request
 
 &credential = {
 identifier: &identifier, ; account or agent identifier
 authenticator: &authenticator ; 'hash', 'challenge' or 'pkcs5pbkdf2'
 }
 
 ; response
 
 ; successful response
 
 &response = {
 condition: 'success',
 agent_seed_capability: uri ; URL of the agent seed cap
 }
 
 ; authentication failure
 
 &response = {
 condition: 'key',
 salt: binary, ; optional - salt for challenge and PKCS5 authenticators
 count: integer, ; optional - iteration count for PKCS5 authenticators
 duration: integer ; optional - the duration of the validity period of the salt
 ; and count values in seconds
 }
 
 ; maintenance "non success"
 
 &response = {
 condition: 'maintenance',
 maintenance_capability: uri, ; URL of the maintenance cap
 completion: integer ; an estimate for maintenance duration (in seconds)
 }
 
 ; agent select failure
 
 &response = {
 condition: 'select',
 agents: [ first_name: string, last_name: string ... ]
 }
 
 ; administrative failure
 
 &response = {
 condition: 'intervention',
 message: uri ; a URI with human-readable text explaining what
 ; the user must do to continue
 }
 
 ; non-specific error
 
 &response = {
 condition: 'nonspecific',
 message: string ; a string describing the failure
 
 ; resource definition
 
 %%agent_login
 ->&credential
 <-&response
 discuss
== Login-Time Maintenance (Resource Class) ==
An agent domain has the option of performing "per-user, login-time maintenance" as part of the authentication sequence. Performing maintenance after a user is authenticated and before an avatar is "rezzed" in a region has several advantages: 
* it reduces system-wide downtime 
* it distributes maintenance across time, and 
* it consumes computational resources only for those agents who use the system 
The agent domain signals it is performing maintenance by returning a "Maintenance Capability" instead of a seed capability following successful authentication. The maintenance capability represents a finite sequence of transactions performed by the agent domain on the user's behalf. It is expected that maintenance is a task that will complete in a "tractable" amount of time. 
The maintenance capability may be queried to retrieve information about the transactions that are occuring, including: 
* a textual description of the maintenance being performed 
* an estimate for how long the maintenance will take to complete 
 discuss
=== Service Location ===
The agent domain may provide a maintenance capability to the client application in response to successful authentication. This capability is communicated as an URL to a web based service that accepts LLSD queries. 
 'maintenance' capability from
 discuss
=== Verb ===
 GET
 discuss
=== Inputs ===
There are no parameters to a maintenance capability request. 
 discuss
=== Response ===
There are three responses to a maintenance capability: a description of ongoing maintenance, a new maintenance capability describing another sequence of maintenance transactions, or a seed capability. These responses are identified with the condition items: 'ongoing', 'next' and 'complete'. 
The 'ongoing' response to a maintenance capability request includes a simple textual description of the maintenance performed, an estimate for how long the maintenance is expected to take, and a validity duration for the capability. The estimate for how long maintenance will take is provided so client applications may provide feedback to the user. The validity duration gives the viewer a minimim time period the agent domain will maintain the maintenance capability. 
When the agent domain returns a 'next' response, it indicates that the current maintenance is complete, but a new maintenance must be performed before the agent may be placed into a region. The 'next' response includes the URL of the next maintenance capability as well as an integer describing the minimum time period the agent domain will maintain the maintenance capability. 
When an agent domain returns a 'complete' response, it indicates that all maintenance is complete. The response includes the agent seed capability that may be used to place the user's avatar in a region. It also includes an item describing the validity period for the current maintenance capability. 
 discuss
=== Interface (GET) ===
The following text describes the LLIDL description of the agent_login messages. 
 &response = {
 condition: 'ongoing',
 description: string,
 duration: integer, ; how many seconds before maintenance is complete
 validity: integer ; how many seconds before this capability expires
 }
 
 &response = {
 condition: 'next',
 description: string,
 maintenance_capability: uri ; the URL for the next maintenance capability
 validity: integer ; how many seconds before this capability expires
 }
 
 &response = {
 condition: 'complete',
 agent_seed_capability: uri ; the agent's seed cap
 validity: integer ; how many seconds before this capability expires
 }
 
 %%maintenance
 ->undef
 <-&response
 discuss
== References ==
 >>> blist
 >>> bibl
Rivest, R. "The MD5 Message-Digest Algorithm" <http://tools.ietf.org/html/rfc1321> >>> bibl
"Federal Information Processing Standards Publication 180-2 (+ Change Notice to include SHA-224) <http://csrc.nist.gov/publications/fips/fips180-2/fips180-2withchangenotice.pdf> >>> bibl
Kaliski, B. "PKCS #5: Password-Based Cryptography Specification Version 2.0" <http://tools.ietf.org/html/rfc2898>