An identity is a description of a particular entity such as a person, software agent, or organization. A credential is a qualification, achievement, quality, or information about an identity's background such as a name, government ID, home address, or university degree. This specification describes mechanisms for reading credentials from and writing credentials to an identity while ensuring that the information is only accessible to authorized applications.

This is a highly experimental specification that is attempting to unify the work performed in the the Web Payments Community Group, the Linked Data community, the WebID Community Group, and the Mozilla Persona team. As such, the specification borrows a number of concepts from each group and attempts to sythesize these concepts into a solution that would be easily implemented and deployed by Web developers in order to provide an elegant readable and writable identity mechanism for the Web.

Introduction

An identity is a set of information that can be used to identify a particular entity such as a person, software agent, animal, or organization. We typically associate credentials with identities to access many services throughout our lives. For example, we use email addresses to identify ourselves to online services, driver's licenses to prove that we are capable of operating a motor vehicle, and government issued passports to travel between countries. It is the goal of this specification to provide an easy way of expressing all of this identity and credential information on the Web.

There are a number of design principles that have gone into the creation of this specification. The following is a brief list of these requirements:

This specification enables secure, decentralized, discoverable, controlled access to arbitrary machine-readable information associated with an identity. Since it's useful to associate varying degrees of sensitive information with a particular identity, the specification ensures that a single entity can associate themselves with multiple identities. For example, one may want to use one identity to access banking services while another identity could be used to play online games.

In order to store the breadth of information that is typically associated with an identity, a simple but extensible data model is utilized. The specification uses a data storage and expression approach called Linked Data. It is a way of expressing information on the Web that is both simple and extensible. Specifically, the Linked Data technology used by this specification is JSON-LD [[!JSON-LD]].

Terminology

identity
A set of information that can be used to identify a particular entity such as a person, software agent, or organization. An entity may have multiple identities associated with it.
identity document
A Web-based document that contains statements about a particular identity. Identity documents MUST be accessible in JSON-LD [[!JSON-LD]] format and MAY be accessible in other RDF-compatible formats.
identity document URL
An identity document URL consists of an HTTP or HTTPS scheme and denotes an identity. For example: https://example.org/identities/manu.
credential
A qualification, achievement, personal quality, aspect of an entity's background, or verifiable statement by an entity about another entity. Credentials may be stored in identity documents.
identity owner
An entity that is in control of a particular identity document.
identity provider
A website providing access to one or more identity documents.
requestor
An entity that is requesting to access and/or modify an identity document.

The Identity

An entity may have one or more identities associated with it. These can be anonymous identities, pseudo-anonymous identities, protected identities, and public identities. The creation of these identities is out of scope for this document, but typically result in the creation of a long-lived identity document URL. For example, https://example.com/identities/john is an example of a long-lived identity document URL.

A Basic Identity

A basic identity contains at least the type information for the identity.

@context
The value https://w3id.org/identity/v1, or an equivalent JSON-LD Context [[!JSON-LD]] expressing the terminology necessary for the expression of the data.
type
The value Identity. Note that this field usually contains more specific type information in addition to Identity such as Person or Organization.

A Typical Identity

A typical identity will have a mix of public and private data associated with it. For example:

{
  "@context": "https://w3id.org/identity/v1",
  "id": "https://example.com/identities/bob",
  "type": ["Identity", "Person"],
  "name": "Bob Bobman",
  "governmentId": "123-45-6789",
  "birthdate": "1985-12-14",
  "email": "bbob@example.com",
  "mobileNumber": "12345678910",
  "shippingAddress": {
    "street": "372 Sumter Lane",
    "city": "Blackrock",
    "region": "Nevada",
    "postalCode": "237842"
  },
  "credential": [{
    "id": "http://ssa.us.gov/credentials/3732",
    "type": "PassportCredential",
    "claim": {
      "id": "https://example.com/identities/bob",
      "name": "Bob Bobman",
      "birthdate": "1985-12-14",
      "governmentId": "123-45-6789"
    },
    "expires": "2018-01-01",
    "signature": {
       "type": "GraphSignature2012",
       "creator": "https://ssa.us.gov/keys/27",
       "signature": "3780eyfh3q0fhhfiq3q9f8ahsidfhf29rhaish"
    }
  }, ... ]
}

The example above contains a mix of public and private information. For example, the identity owner may be comfortable with making their name publicly readable and would do so using the identity provider's website interface. Other information, such as governmentId and email would be marked as private, and would only be shared after the request for that particular information has been approved by the identity owner.

Information can be asserted, via a credential, by a trusted third party and written to the identity using the mechanism described in Section 4: Writing Data to the Identity. Not all information needs to be placed into a credential. For example, shippingAddress above is not in a credential and is thus unverifiable. A requestor would have to trust that the shippingAddress information provided by the identity owner is trustworthy. Other information, such as name, birthdate, and governmentId have been asserted via a credential by a 3rd party. In this particular case, the information has been asserted by the Social Security Administration of the United States government.

Accessing the Identity

There are two mechanisms that allow a 3rd party to read protected information from an identity. The first is an HTTP Signature [[!HTTP-SIGNATURES]] based mechanism that allows any authorized client to access data that has been pre-approved by the entity that controls access to the identity information. The second is to use a browser-based mechanism that POSTs a request to an identity, allowing the identity owner to interactively decide what data access to allow or disallow.

The table below summarizes the HTTP Signatures-based [[!HTTP-SIGNATURES]] mechanism of accessing and modifying an identity:

HTTP Method Description of Action
GET Read all of the information that is available to the requestor. Note: This may only be a subset of all of the information based on the level of access the requestor has to certain attributes in the resource.
POST Used to perform operations on the identity for applications that are not capable of using HTTP Signatures [[!HTTP-SIGNATURES]] or to perform specific queries on the identity data.
PATCH Modify information in the identity using the JSON Patch [[!JSON-PATCH]] protocol.
PUT Replace the entire identity with the provided identity document. This operation SHOULD only be accessible to the owner of the identity.
DELETE Deletes the identity. This operation SHOULD only be accessible to the owner of the identity.

It's arguable that having a PUT or DELETE mechanism is useful. Both can be highly destructive and providing a common way to delete identities may be a bad thing if one experiences a security breach. In many cases, the identity document wouldn't be deleted, just merely marked as deleted in order to undelete it in the event of a mistake.

Not every Web application is capable of pre-arranging access to an identity, performing HTTP Signatures [[!HTTP-SIGNATURES]], or executing HTTP PATCH requests. In these cases, a regular HTTP POST mechanism is provided for Web applications to read, write, and query information about the identity.

POST Parameter Description of Action
action=query Performs a query on the identity given a JSON-LD Frame in the POST body.
action=patch Modify information in the identity using the JSON Patch [[!JSON-PATCH]] protocol.

Reading Identity Information

Reading identity information can be performed in 3 different ways depending on the sensitivity of the information being accessed. An identity provider SHOULD ensure that sensitive information is always transmitted and received over a secure channel, such as TLS [[!TLS]].

An identity can be accessed using a regular HTTP GET on the identity URL:

GET /identities/alice HTTP/1.1
Host: example.org
Date: Tue, 07 Jun 2013 20:51:35 GMT
        

If the Content-Type HTTP Header is not specified, a response using the application/ld+json content type must be provided. Other content types MAY be negotiated for between the client and server. The application/ld+json content type is the only content type that MUST be supported for all requests in this specification.

The result of the GET request SHOULD be information deemed to be public by the identity owner:

{
  "@context": "https://w3id.org/identity/v1",
  "id": "https://example.org/identities/alice",
  "type": ["Identity", "Person"],
  "name": "Alice Smith"
  "publicKey": [{ "id": "https://example.org/identities/alice/keys/1" }]
}
        

As the response above shows, the only information that the identity owner has specified as being public is their name and a reference to their publicKey.

In order to access identity information that is not public, the request SHOULD be authenticated and authorized against a known identity. The HTTP Signatures [[!HTTP-SIGNATURES]] specification is used to digitally sign the request:

GET /identities/alice HTTP/1.1
Host: example.org
Date: Tue, 07 Jun 2013 20:52:12 GMT
Content-Type: application/ld+json
Authorization: Signature 
  keyId="http://example.org/identities/bob/keys/4",
  algorithm="rsa-sha256",
  headers="(request-line) host date content-type",
  signature="Gm7W/r+e90REDpWyt.../VebAsNUtvQMe6cTjnDY="
        

The result of the GET request will now include information that the requestor has been pre-authorized to read by the identity owner:

{
  "@context": "https://w3id.org/identity/v1",
  "id": "https://example.org/identities/alice",
  "type": ["Identity", "Person"],
  "name": "Alice Smith",
  "email": "asmith@example.com",
  "mobileNumber": "4424672637162",
  "publicKey": [{ "id": "https://example.org/identities/alice/keys/1" }]
}
        

As the response above shows, in addition to the public information, the identity owner has authorized the requestor to access their email and mobileNumber as well.

In the event that the requestor has not authorized itself prior to the request, or if it is not capable of performing an HTTP Signature [[!HTTP-SIGNATURES]], it may utilize a POST-and-callback-based approach. The following diagram provides an overview of how the POST-and-callback-based approach works:

Once the requestor has tried to access a protected resource, the website can request a particular set of credentials from the customer:

POST /query?credentials=true&callback=https://flights.example.org/verify?session=7f8nddn HTTP/1.1
Host: login-hub.com
Date: Tue, 07 Jun 2013 20:52:12 GMT
Content-Type: application/ld+json

{
  "@context": "https://w3id.org/identity/v1",
  "id": "",
  "name": "",
  "governmentId": "",
  "birthdate": ""
}

The result of the POST request will be a dialog that the identity provider displays to the identity owner asking them to verify the information that will be transmitted to the requestor. The mechanism used to present this dialog to the identity owner is outside of the scope of this specification. The result of a successful interaction with the verification dialog will be a POST back to the callback URL provided by the requestor:

POST /verify?session=7f8nddn HTTP/1.1
Host: flights.example.org
Date: Tue, 07 Jun 2013 20:53:28 GMT
Content-Type: application/ld+json

{
  "@context": "https://w3id.org/identity/v1",
  "id": "https://example.org/identities/alice",
  "type": ["Identity", "Person"],
  "name": "Alice Smith",
  "birthdate": "1988-11-02",
  "governmentId": "321-54-9876"
  "credential": [{
    "id": "http://ssa.us.gov/credential/8273",
    "type": "PassportCredential",
    "claim": {
      "id": "https://example.org/identities/alice",
      "name": "Alice Smith",
      "birthdate": "1988-11-02",
      "governmentId": "321-54-9876"
    },
    "expires": "2017-02-04",
    "signature": {
       "type": "GraphSignature2012",
       "creator": "https://ssa.us.gov/keys/27",
       "signature": "fhhfiq3q9f8ahfh3q029rhaishsidfhf3780ey"
    }
  }]
}
        

As the response above shows, the identity owner accepted the request for information and the identity provider has performed a POST to the callback URL provided by the requestor via the identity owner's web browser. Since the request included the credentials=true flag, the credentials for the information requested have been included so that the requestor may validate the information against the 3rd party credentials.

Credentials and Claims

It is possible for a 3rd party to provide digitally signed credentials to be stored with an identity. For example, if an individual would like to store digitally signed credentials verifiying their citizenship information, they would go through the following process:

  1. Go to a government website and start the verification process.
  2. Provide their identity URL to the government website.
  3. The government website would digitally sign a credential and attempt to write it to the provided identity.
  4. The individual would be provided with a dialog to authorize the write of the credential to their identity.
  5. If the authorization is successful, the digitally signed credential is written to the identity and will be returned in future queries for such a credential.

Writing Data to the Identity

There are two mechanisms that allow a 3rd party to write information to an identity document. The first is an HTTP Signature [[!HTTP-SIGNATURES]] based mechanism that allows any authorized client to write data that has been pre-approved by the entity that controls access to the identity information. The second is to use a browser-based mechanism that POSTs a patch request to an identity document, allowing the identity owner to interactively decide what data to write to the identity document.

The example below demonstrates a digitally signed request to write information to a specific identity document using an HTTP Signature:

POST /identities/alice?action=patch HTTP/1.1
Host: example.org
Date: Tue, 07 Jun 2013 20:52:12 GMT
Content-Type: application/json-patch+json
Authorization: Signature 
  keyId="https://ssa.us.gov/keys/27",
  algorithm="rsa-sha256",
  headers="(request-line) host date content-type",
  signature="Gm7W/r+e90REDpWyt.../VebAsNUtvQMe6cTjnDY="

{
  "op": "add",
  "path": "https://w3id.org/identity#credential",
  "value": {
    "@context": "https://w3id.org/identity/v1",
    "id": "http://ssa.us.gov/credential/8273",
    "type": "PassportCredential",
    "claim": {
      "id": "https://example.org/identities/alice",
      "name": "Alice Smith",
      "birthdate": "1988-11-02",
      "governmentId": "321-54-9876"
    },
    "expires": "2017-02-04",
    "signature": {
       "type": "GraphSignature2012",
       "creator": "https://ssa.us.gov/keys/27",
       "signature": "r+e90REDpW....bAsNUtvQM"
    }
  }
}
        

The example below demonstrates an unsigned request to write information to a specific identity document. Since the request is unsigned, the identity provider would initiate an interactive authorization where the identity owner would verify that the information to be written is acceptable. The specifics of the interactive authorization flow are outside the scope of this document, but are roughly outlined in the diagram below:

The data that is sent back and forth is outlined below:

POST /create?action=patch HTTP/1.1
Host: login-hub.com
Date: Tue, 07 Jun 2013 20:52:12 GMT
Content-Type: application/json-patch+json
{
  "op": "add",
  "path": "https://w3id.org/identity#credential",
  "value": {
    "@context": "https://w3id.org/identity/v1",
    "id": "http://ssa.us.gov/credential/8273",
    "type": "PassportCredential",
    "claim": {
      "id": "https://example.org/identities/alice",
      "name": "Alice Smith",
      "birthdate": "1988-11-02",
      "governmentId": "321-54-9876"
    },
    "expires": "2017-02-04",
    "signature": {
       "type": "GraphSignature2012",
       "creator": "https://ssa.us.gov/keys/27",
       "signature": "r+e90REDpW....bAsNUtvQM"
    }
  }
}
        

The format for the message above is JSON-PATCH where the path value is the complete URL for JSON-LD property to add to the identity document.

Web Credential-based Login

It is possible to use the mechanism described in this specification to login to a website in much the same way that Persona enables a verified email login. The process is described below:

  1. Go to a website that requires a valid email address for login.
  2. The website requests the email address for login.
  3. A document is fetched from the domain of the email address checking for a Web Identity endpoint and identity service URL.
  4. The user agent is instructed to retrieve the credential information from the Web Identity endpoint and send it to the website requiring login.
  5. The website that requires the valid email address for login checks the credentials posted by the user agent, verifies the signatures, and creates a session for the user.

The diagram below outlines the basic login flow described above.

Detailed Flow for Credential-based Login

While the credential-based login mechanism below relies on an email provider to be the identity provider, a distributed identity mechanism using Telehash or some other Kademlia-based Distributed Hash Table algorithm could be utilized to allow any identity provider to vouch for any email address. This would result in two advantages over Persona. The first is that a centralized infrastructure for email address to identity provider mapping wouldn't be necessary. The second is that any identity provider could vouch for any email address. The details of this proposal can be found here: A Proposal for Credential-based Login.

In the following example, a login prompt is provided on store.example.org where the person that is logging in provides the asmith@example.com email address. The first step constitutes store.example.org fetching the identity endpoint information from example.com:

GET /.well-known/identity HTTP/1.1
Host: example.com
Date: Wed, 08 Jun 2013 22:54:42 GMT
Content-Type: application/ld+json
        

A successful retrieval of the identity service endpoint will result in the following document:

HTTP/1.1 200 OK
Content-Type: application/ld+json
Content-Length: 34
Date: Wed, 08 Jun 2013 22:54:43 GMT

{
  "@context": "https://w3id.org/identity/v1",
  "identityService": "https://example.com/identities"
}
        

The store.example.org software may then construct the proper query to the identity service:

POST /identities?action=query&credentials=true&callback=https://store.example.org/verify?session=8d73j320s HTTP/1.1
Host: example.com
Date: Wed, 08 Jun 2013 22:54:44 GMT
Content-Type: application/ld+json

{
  "@context": "https://w3id.org/identity/v1",
  "email": "asmith@example.com"
}
        

After a UI interaction with Alice on example.com verifies that the email information should be sent to store.example.org, the following message is transmitted from Alice's user agent to store.example.org:

POST https://store.example.org/verify?session=8d73j320s HTTP/1.1
Host: example.org
Date: Wed, 08 Jun 2013 22:55:15 GMT
Content-Type: application/ld+json

{
  "@context": "https://w3id.org/identity/v1",
  "id": "https://example.com/identities/asmith",
  "type": "Identity",
  "email": "asmith@example.com",
  "credential": [{
    "id": "http://example.com/credentials/23894",
    "type": "EmailCredential",
    "claim": {
      "id": "https://example.com/identities/asmith",
      "email": "asmith@example.com",
    },
    "expires": "2015-02-04",
    "signature": {
       "type": "GraphSignature2012",
       "creator": "https://example.com/keys/24",
       "signature": "jf48901fu41...23908aszfhdk23h9f"
    }
  }]
}
        

Note that for the purposes of simplicity in the example above, there is no tracking protection to prevent example.com from knowing which website Alice is logging in to. Tracking protection is easily implemented by adding a trusted 3rd party, such as the browser UI or a 3rd party mixer service, that decouples the identity provider from the relying party.

Compatibility with other Login Mechanisms

This identity mechanism is designed to be compatible with other identity mechanisms in use today such as OpenID, Facebook Connect, and Firefox ID.

Integration with Mozilla Persona / Firefox ID

The identity mechanism is such that it can be returned in a Mozilla Persona or FxID-based login. The assertion returned to the FxID-enabled website would contain an identity URL which would be compatible with this specification. This allows both the basic email address to the validated, and extension information (such as citizenship information, age assertions) to be discoverable after the login.

{
  "public-key": {
    "algorithm": "DS",
    "y": "8e65e949e2e...1263ea6",
    "p": "ff600483dab...7fc26d0",
    "q": "e21e04f91d1...ecaab3b",
    "g": "c52a4a0ff34...233397a"
  },
  "principal": {
    "@context": "https://w3id.org/identity/v1",
    "email": "asmith@example.org",
    "identity": "https://example.org/identities/alice"   <--- This bootstraps the identity assertion discovery process
  },
  "iat": 1392697368513,
  "exp": 1392783768513,
  "iss": "example.org"
}

Integration with OpenID, OAuth1, and OAuth2

The mechanism should be able to be used via OpenID, OpenID Connect, and possibly both versions of OAuth. This section should elaborate how one can provide pointers to the identity assertion URL using those methods.