Labs/Weave/Identity/Account Manager/Spec/3
Warning: This document is a DRAFT
- HTTP Extensions for Account Management and Session Identification
Draft Version 2 Authors: Michael Hanson and Dan Mills, Mozilla Labs
WikiMedia tip: If you aren't seeing numbered section headings in the body of this document, you need to login and click the "My preferences" link, at left, and select "Auto-number headings"
Contents
Introduction
This document specifies a set of extensions to the HTTP client/server message exchange that allow a server to describe an account-based user identification process in terms that a user-agent can understand. It is intended to complement existing practices around HTTP and cookie-based user identification, and to provide a graceful roadmap for adoption of new technologies over time.
Mozilla Labs is implementing client support for this protocol in the Account Manager browser extension.
This is an early draft and frequent changes are expected.
Informally, here's a VERY high-level overview of what we're trying to enable:
A web browser visits a new site. The site advertises to the browser that account management features are available. The browser user requests "connection" to the site. The browser negotiates account setup, possibly disclosing some personal information about the user, and learns a userid-credential pair. On a subsequent visit, the browser notices that it does not have an active session, and automatically establishes one. When the user requests "disconnection" from the site, the browser terminates the session. When the user views a "my accounts" page in his browser, she sees what information the site is storing about her.
Overview
The Account Management protocol provides mechanisms for a server to indicate to a client:
- Machine-readable direction as to how a user can create an account, log in to a session using an account identifier, log out of a session, collect information about an account, and/or change information about an account. A profile-based scheme is proposed to support various styles of account registration, including site-specific and federated identities, and various styles of authentication, such as username/password.
- A specific restricted-vocabulary indication of a user-agent's current session status with regard to a particular server or domain. This allows a server to signal to a user-agent that it is currently logged in with an affirmative identity, passively identified with a non-session-based identity, or anonymous to a server.
This proposal is NOT an attempt to deal with disclosure of per-user tracking technology that may be deployed by a server. The intent is only to provide a channel for a server to provide information that it chooses to disclose to the user-agent.
Account Management Realms
This proposal defines an "Account Management Realm" to be a set of HTTP(S)-addressed resources that are subject to a single account and session management control authority. In common practice, this means that they share a user session cookie.
In many cases, a realm is the same as a site. For large web properties, however, a realm could include some number of content properties, which may or may not share a primary domain name.
It is an explicit goal of this protocol to support the description of user session status across an entire realm, even when not every URL or server in the realm participates in the protocol message exchange. This is intended to support large web properties, where a single host (e.g. "login.host.com") is responsible for issuing and clearing user session cookies.
Protocol Summary
On visiting a URL as the top-level document of a browser, a user-agent makes an "Account Management Status" determination for the page. This determination has three steps:
- The user-agent must determine what the Account Management Realm for the page is.
- The user-agent must access an Account Management Control Document for that realm.
- The user-agent must determine the Account Session Status for the page
The interpretation of the Control Document and the Session Status follows this message exchange overview.
Determining the Account Management Realm
The user-agent must follow this set of checks to determine an Account Management Realm on retrieving a resource:
1. HTTP response header. If the HTTP response has a "Link" HTTP header with a "rel" attribute of "acct-mgmt", the realm is the link-value of this header. Note that the interpretation of Link headers is defined by the Web Linking standard, which, means that the value will be delimited with angle brackets, as follows:
Link: <http://site.com/meta/amcd.json>; rel="acct-mgmt"
2. Host Metadata link element. If there is no Link header with a "rel" attribute, the browser SHOULD discover the Host Metadata for the domain of the resource. (as of this writing, this involves making an HTTP request to /.well-known/host-meta (e.g. [1]), or perhaps a DNS-based system TBD). The user-agent may apply standard HTTP caching practices to this metadata file. The Host Metadata file may contain one or more Link elements with a "rel" attribute set to "acct-mgmt", which should be evaluated in order to determine if they apply to the original resource by comparing the original resource's path to the optional "path" attribute of the Link elements. Paths are inclusive of all subpaths, and if the "path" attribute is omitted the default is "/" (all paths). For example:
<Link rel="acct-mgmt" path="/area1" href="/meta/amcd-area1"/>
<Link rel="acct-mgmt" href="/meta/amcd-default"/>
Note that a Link element in the Host Metadata without a "path" attribute means that an Account Management Realm defined in the Host Metadata applies to all resources on the host that do not provide an acct-mgmt Link header or are otherwise matched by an earlier Link element.
Note also these are not HTML link elements. Only the Host Meta XRD is used - no content from HTML (or Atom or any other page content) is used.
See also the discussion in Security Considerations, below.
Determining the Account Management Control Document
The Realm MUST be a URL using the http or https scheme. The user-agent will retrieve the document by following the URL. The user-agent may cache this document according to standard HTTP cache control practices.
Determining the Account Session Status
The user-agent determines the account session status by following this set of steps:
- If the HTTP response for the resource has an "X-Account-Management-Status" HTTP header, the session status is the value of this header.
- If the HTTP response for the resource has a status that will cause a redirection (e.g., 303), the redirect MUST be followed and steps 1 and 2 repeated for the redirected-to resource. In the event that the redirected-to resource has no X-Account-Management-Status header, or it has a different value, the last resource to be loaded with the header will be used to determine the session status.
- If a session status was previously provided, the user-agent MAY stop and report the last-reported status. The user agent MAY also alternatively invoke the sessionstatus method defined for the realm to determine the session status.
The server is responsible for notifying the client of any changes to the current status of the session.
The user-agent MAY use the sessionstatus method to request the current status at any time. The user-agent SHOULD use it after a client restart. User-agents SHOULD NOT request the status using the sessionstatus method on a page view, if the page contained the account status in the header. The server should be prepared to answer to the sessionstatus method at any time, but user agents are encouraged to use the last-reported value unless there is reason to believe that it is no longer correct, e.g. after a browser restart or processing a Set-Cookie header.
Interpretation of the Account Session Status
The account session status value is a semicolon-delimited string. The first term of the status must be one of the values active, passive, or none. Following terms of the status are key-value pairs in the form <name>=<value>. The value may optionally be quoted with single or double quotes; if it is, the value may contain semicolons. If the value is not quoted, and semicolon in the value MUST be interpreted as a field delimiter.
These status values should be interpreted by a user-agent as follows:
active: The server is maintaining a session with the user-agent in the positive belief that it is interacting with the user associated with the account. No further credentials will be required to interact with the account. (NB that some applications, i.e. financial transactions, may require additional verification steps during a session. See Security Considerations, below).
passive: The server is maintaining a session with the user-agent according to some token other than a positive exchange of credentials, e.g. a long-duration cookie. The server may require the user to present additional credentials before taking action with the account.
none: The server is not maintaining a session with the user. It is up to the user-agent to render additional user interface elements if the user-agent believes that it has credentials that would allow a session to be established.
Legal keys in the attribute list are:
name: A human-readable label for the current session. The entire text of the string SHOULD be presented to the user as the current session identifier. In common practice, this will be the username, display name, or given name of the current user.
id: The server's primary identifier for the current session. The identifier given here should match that submitted by the user-agent when a session was established.
Example:
X-Account-Management-Status: active; name="Joe User"; id="joe@domain.com"
Interaction of Account Session Status with Caching Proxies
Servers should set Cache-Control headers on responses that include an X-Account-Management-Status to ensure that the response will not be cached in a way that allows cross-user access or past the expected expiry window of the user's session.
Servers are strongly encouraged to assume that clients will use the last-reported value of X-Account-Management-Status, and are therefore free to omit the header for responses that do not change the state of the client (i.e. do not include a Set-Cookie header). The use of the features described here is not intended to supersede any of the existing cache-control mechanisms described by HTTP.
Contents of the Account Management Control Document
The Account Management Control Document (AMCD) is a static document an Account Management Realm uses to advertise to a user-agent what account-related capabilities it supports, and details around how the user-agent may access them. These include specific methods, endpoints, schemas expected, and so on.
It is the responsibility of resources to refer to the AMCD. A single web host may contain multiple realms, and therefore multiple AMCDs. An Account Management Realm may span multiple web hosts. This feature of the protocol means that the contents of the AMCD are sensitive and require secure handling; see the Security Considerations section, below, for more detail.
The Control Document is a JSON document. It must be valid JSON; if any syntax errors are encountered during the processing of the document, the user-agent will discard the document and proceed as through the realm has no account management features. A server may provide localized versions of the document; user-agents should respect standard HTTP content negotiation practices (e.g. Accept headers) and standard HTTP content encoding principles apply for international text.
Top-level Attributes of the Document
methods: An object mapping profile names to objects. Each profile object maps method names to Method Descriptions (see section 4.2 below). The profile names are drawn from the list of Supported Account Managment Profiles; each profile defines a list of supported methods.
applicable-domains: (optional) A list of fully-qualified URLs, excluding the path component, or the wildcard character '*'. If this attribute is not present, user-agents must only use the document to perform account management functions on the same scheme and domain as the AMCD itself. If the attribute is present, the list may define additional schemes and domains, including any page by using the wildcard character.
Method Descriptions
Each <profile name> element may contain any number of these method descriptions. Each method description must contain these properties:
method: One of the HTTP methods, e.g. GET or POST
path: An absolute path, which will be combined with the scheme and net-location provided in the domain attribute of the document to produce a URL. The path may contain the "?", "=", and "&" characters; it must not contain the "#" character, and if it does, the "#" character and all characters after it MUST be removed by the user-agent.
params: A dictionary of name-value pairs. The names that are legal here are defined by each method description; the value of each pair defines the name that will be used to submit that value. For example, in the connect method description, a dictionary entry of "username":"un" indicates that the username associated with the connection will be submitted as the "un" parameter.
The meaning of each method is determined by each profile. For the Username-Password Form Profile, see section 5.1 below.
Method status actions
Some methods allow customizable actions depending on success or failure. These actions are specified by onsuccess or onfailure objects. Both support the same properties, which vary depending on the chosen action:
action: One of "none", "reload", "load-url", or"js-event".
- url: If action is load-url, this property specifies which URL to load.
For example, in an onsuccess handler in the connect method:
onsuccess: {action: "load-url", url: "/logged-in.html"}
Profiles
Username-Password Form Profile
The Username-Password Form Profile is used for domains that maintain user records keyed on username, with a single password used as the credential for access. The profile is appropriate for domains that are keyed on unique user identifiers other than free-form passwords; in particular, it is appropriate for an email-address-and-password domain.
The profile name identifier for the Username-Password Form Profile is username-password-form.
The methods allowed in this profile are connect, disconnect, register, changepassword, sessionstatus, accountstatus. See the sections below for a definition of each method.
connect
Used to establish a user session with the domain. In common usage, submitting the request to the defined endpoint will cause a cookie to be set on the user-agent.
- Required properties
- params:
- username: Parameter name for the user's username.
- password: Parameter name for the user's password.
- Optional properties
- onsuccess: status-action
- onfailure: status-action
- Response interpretation
- The user-agent MUST verify the session status as specified in section 3.3.
- If the status could not be determined or is not active, or in the event of any 4xx or 5xx response or transport-level error, the user-agent MUST execute the onfailure action if specified. If not present, the user-agent SHOULD reload the current page.
- Otherwise, the user-agent MUST execute the onsuccess action if specified. If not present, the user-agent SHOULD reload the current page.
disconnect
Terminates an existing user session with the domain. In common usage, submitting the request to the defined endpoint will cause a cookie to be cleared on the user-agent.
- Required properties
- None.
- Optional properties
- onsuccess: status-action
- onfailure: status-action
- Response interpretation
- The user-agent MUST verify the session status as specified in section 3.3.
- If the status could not be determined or is not none, or in the event of any 4xx or 5xx response or transport-level error, the user-agent MUST execute the onfailure action if specified. If not present, the user-agent SHOULD reload the current page.
- Otherwise, the user-agent MUST execute the onsuccess action if specified. If not present, the user-agent SHOULD reload the current page.
register
Establishes a new ID and secret with the domain. Both usernames and email addresses are supported ID types.
- Required properties
- id-type: Type of identifier to use. Supported types are username and email.
- Optional properties
- params:
- id: The parameter name to send the ID in. Defaults to id.
- secret: The parameter name to send the secret in. Defaults to secret.
- id-maxlength: How many characters long the id can be. Default is 16.
- secret-type: Type of secret to use. The only supported type at this time is random, which is the default.
- secret-minlength: Minimum number of characters long the secret is allowed to be.
- secret-maxlength: How many characters long the secret should be. Defaults to 16.
- onsuccess: status-action
- onfailure: status-action
- Response interpretation
- A 2xx response is a success, the user agent SHOULD save the ID and secret for future use, and it MUST execute the onsuccess status action, if present.
- A 4xx response is a verification failure; see the section Verification error handling below. The user agent SHOULD, if possible, address the problem and retry the query. Note that the onfailure status action should not be executed in this case.
- Any other response, or upon any 4xx response that the user agent cannot correct, the user agent MUST execute the onfailure status action, if present. If onfailure is not present, it SHOULD reload the current page.
Note that it is possible for the user agent to prompt the user after receiving a 4xx response. In the event that the user cancels the operation, that shall be considered a failure and the user agent SHOULD execute the onfailure action.
Verification error handling
The server may reject an id/secret pair for a variety of reasons. Upon failing to verify the id or secret, the server MUST return status code 400 in its response. The body of the response MUST be a JSON-formatted object with at least one of the following properties:
- id-error: One of the literal strings "invalid-character", "over-max-length", "under-min-length", "id-already-in-use"
- secret-error: One of the literal strings "invalid-character", "over-max-length", "under-min-length"
For example:
{ "id-error": "over-max-length", "secret-error": "invalid-character" }
changepassword
Used to change the password associated with a username.
- Required properties
- username: Parameter name for the username.
- old_password: Parameter name for the old password.
- new_password: Parameter name for the new password.
- Optional properties
- new_password_verify: If present, the new password will also be submitted using this parameter name.
- Response interpretation
(fixme)
sessionstatus
Defines a way for a user-agent to determine its current session status.
- Required properties
- None.
- Optional properties
- onfailure: status-action
- Response interpretation
- The user-agent MUST verify the session status as specified in section 3.3.
- If the status could not be determined, or in the event of any 4xx or 5xx response or transport-level error, the user-agent MUST execute the onfailure action if specified. If not present, the user-agent SHOULD reload the current page. Regardless of the onfailure action, the user-agent SHOULD act as though the user is not logged in, but MAY, if it has a mechanism for doing so, indicate that the user's session status is in an error state.
accountstatus
Defines an endpoint used by the user-agent to retrieve the status of the account bound to the current session. The user-agent SHOULD NOT invoke the accountstatus method until it has successfully executed a connect method. The intent of accountstatus is to provide a machine readable rendering of data that is stored or generated by the server. Expected use cases include:
- Displaying account and contact information for the user
- Reporting access histories (to allow the user-agent to check for unexpected access patterns)
- Required properties
- None
- Optional properties
- None
- Response interpretation
A 2xx response may be interpreted by the user-agent to produce a report of user data. The format of this data is not yet determined; HCard microformat data is one possibility but further discussion is needed. Any 4xx or 5xx response will be interpreted as an error.
It is intended that the accountstatus page could, at the server's discretion, also be a human-readable page of HTML. The use of microformats is indicated as a way to provide machine-readable markup that is not perceptible to the human user.
Servers should return a 403 error if they expected a session for the accountstatus page and the user-agent failed to establish one.
OpenID Profile
The OpenID Profile is used for domains that are OpenID Relying Parties. The profile is appropriate for domains that support a list of OpenID Providers or allow a user to assert any Provider. This profile requires OpenID 2.0 support by both the OP and the RP.
The profile name identifier for the OpenID Profile is openid.
The only method allowed in this profile is connect. See the below for a definition of the method.
User Interface Requirements
The OpenID Profile requires that the User Agent perform a number of background network requests, several of which may require the user to interact with the OP site.
The OpenID Profile requires that the User Agent support an HTML-based dialog interaction during the authentication process. This interaction SHOULD be performed in a way that links the authentication flow to the page being interacted with, i.e. through a tab-modal dialog box or sheet. This dialog will be referred to in this document as the OP Dialog.
connect
Used to establish a user session with the domain by asserting an existing identity preference. The UA will make a request to the defined endpoint, including the identity string as an argument. It is expected that the server will perform an association with the endpoint (if needed) and return a redirection to the OP for an openid.mode of checkid_setup or checkid_immediate.
The UA MUST parse the Location URL of the redirection returned by the RP to extract the openid_returnto parameter. The user-agent will then begin an interaction with the OP in the OP Dialog; the UA MUST observe all Location headers on 300-level responses until it observes the URL defined by the openid_returnto parameter.
The user-agent SHOULD not visually present the OP Dialog until a 200-level response is returned by the OP.
The user-agent MUST load the URL defined by the openid_returnto in the original document frame and dismiss the OP Dialog automatically when the final 300-level response containing the openid_returnto value in the Location header is returned by the OP.
The user-agent will trigger the onfailure callback of the connect method if any 400- or 500-level response is returned by the OP during the OP Dialog, or if the OP Dialog is dismissed by the user (e.g. by clicking a cancel button).
The user-agent SHOULD perform perform automated authentication, as defined by the OP's Account Management Realm, if such data is available and the user has established an account with the OP.
The user-agent MUST NOT invoke the onfailure handler if the OP returns an openid.mode of cancel or setup_needed. Those modes should be delivered to the RP, who is responsible for handling them normally.
Sites are strongly encouraged to use checkid_setup rather than checkid_immediate for this profile. The immediate flow could lead to a scenario where the user clicks to login but is shown a login failure or identity selection page.
- Required properties
- params:
- identity: Parameter name for the user's identity. This parameter can contain either a Claimed ID, or an email address. The RP is expected to perform Webfinger/LRDD-based discovery on email addresses to discover the user's OP.
- Optional properties
- onfailure: status-action
- Response interpretation
- The user-agent MUST verify the session status as specified in section 3.3.
- If the status could not be determined or is not active, or in the event of any 4xx or 5xx response or transport-level error, the user-agent MUST execute the onfailure action if specified. If not present, the user-agent SHOULD reload the current page.
- The authentication is considered to have completed successfully when the OP returns a 300-level response with a Location that matches the openid.return_to value. The UA must load this Location in the document frame; there is no onsuccess action.
Implementation Considerations
- Embedded Resources
The user-agent MUST NOT take Account Management steps for resources that are embedded in a document. This includes IFRAMEs, scripts, CSS stylesheets, images, and data retrieved by plugins.
- Respect for AUTOCOMPLETE=FALSE
It is conventional for websites to indicate that they wish to disable autocompletion of forms by placing the AUTOCOMPLETE attribute with a value of FALSE into the FORM element.
User-agents that implement Account Management features SHOULD respect this value as an indication by a website that it wishes not to participate in implementations of this protocol.
- HTTP Basic/Digest Access Authentication
Most common browser implementations of HTTP Access Authentication (RFC 2617) do not include the ability for the user to disconnect (stop sending the Authentication header). Since connect/disconnect are central metaphors to this specification, user agents SHOULD perform an HTTP method call for disconnect if it is so defined (see section 5.2.2).
Security Considerations
Additional Verification Steps Allowed
Nothing in this specification should be taken to forbid additional verification or authorization steps that might be performed in content.
Threat Modeling
Information Disclosure Threat: User asks to create an account on Alice, but attacker gets them to create an account with Bob, phishing Alice-domain data.
How: Inject an AccountManagement header, or compromise Alice's HostMeta, or poison DNS on a non-SSL URL. When user requests account, Bob phishes Alice-domain data.
Countermeasures:
- Don't allow cross-domain AM realm (problem: Large, multi-domain sites want it)
- Require strict hierarchical AM realm (problem: nobody with a content.host.com runs logins on host.com)
- Sign AMCD - but for what signing authority? If you can inject an AM header, you can lie there.
Sounds like the only safe approach is to require additional security if you want a cross-domain AM realm - forbid by default. But if we're putting something on both ends of the transaction, the attacker could do the same. We can perform piece-wise countermeasures - e.g. disable header-based AM discovery.
Variant attack - same site: Alice and Bob are on the same domain, and we're counting on HTTP headers to indicate which realm we're in. e.g. http://host.com/~alice and http://host.com/~bob - Bob hacks Alice and sets her AM to http://host.com/~bob/account_mgmt.
Credential Theft Threat: Similar to the registration attack - user asks to log into Alice, but actually sends their credentials to Bob, through direct man-in-the-middle on login request.
Site Masquerade Threat: Bob advertises account management details for Alice; the user sees his Alice account information in the browser chrome and feels more comfortable. Bob then phishes additional details in content.
This threat is intended to be addressed by the applicable-domain property of the AMCD. The strongest version would be to require an applicable-domain property for any cross-domain usage.
How to handle periodic credential challenges: Some websites (e.g. commerce and financial applications) require additional credential challenges, even after a user correctly responds to a session-establishment challenge.
Appendix A: Account Management Control Document Example
{ "methods": { "http-auth": { "connect": { "method": "GET", "path": "/signin/" }, "disconnect": { "method": "GET", "path": "/signout/" } }, "username-password-form": { "connect": { "method":"POST", "path":"/signin/", "params": { "username":"unam", "password":"pwd" } }, "disconnect": { "method":"POST", "path":"/signout/" }, "register": { "method":"POST", "path":"/register/", "type": "email" }, "changepassword": { "method":"POST", "path":"/changepass/", "params": { "username":"unam", "old_password":"old_pwd", "password":"pwd", "password_verify":"pwd2" } }, "sessionstatus": { "method":"GET", "path":"/sessionstatus" }, "accountstatus": { "method":"GET", "path":"/account_status" } } } }
Appendix B: Host-meta example
<?xml version='1.0' encoding='UTF-8'?> <XRD xmlns='http://docs.oasis-open.org/ns/xri/xrd-1.0'> <Link rel='http://services.mozilla.com/amcd/0.1' href='/path/to/your/amcd'/> </XRD>
The host-meta file needs to be located in the document root in the folder .well-known/host-meta