Initial Author of this Specification was Ian Hickson, Google Inc., with the following copyright statement:
© Copyright 2004-2011 Apple Computer, Inc., Mozilla Foundation, and Opera Software ASA. You are granted a license to use, reproduce and create derivative works of this document.
All subsequent changes since 26 July 2011 done by the W3C WebRTC Working Group are under the followingCopyright:
© 2011-2021W3C® (MIT,ERCIM,Keio,Beihang<\/a>).Document use rules apply.
For the entire publication on the W3C site theliability andtrademark rules apply.
This document defines a set of ECMAScript APIs in WebIDL to allow and application using WebRTC to assert an identity, and to mark media streams as only viewable by another identity. This specification is being developed in conjunction with a protocol specification developed by the IETF RTCWEB group.
While the specification is feature complete and is expected to be stable, there are also a number ofknown substantive issues on the specification that will be addressed during the Candidate Recommendation period based on implementation experience feedback.
It might also evolve based on feedback gathered as itsassociated test suite evolves. This test suite will be used to build animplementation report of the API.
To go into Proposed Recommendation status, the group expects to demonstrate implementation of each feature in at least two deployed browsers, and at least one implementation of each optional feature. Mandatory feature with only one implementation may be marked as optional in a revised Candidate Recommendation where applicable.
This document specifies APIs used for identity in WebRTC.
This specification is being developed in conjunction with a protocol specification developed by theIETF RTCWEB group and an API specification to get access to local media devices [[GETUSERMEDIA]]. An overview of the system can be found in [[RTCWEB-OVERVIEW]] and [[RTCWEB-SECURITY]].
This specification defines conformance criteria that apply to a single product: theuser agent that implements the interfaces that it contains.
Conformance requirements phrased as algorithms or specific steps may be implemented in any manner, so long as the end result is equivalent. (In particular, the algorithms defined in this specification are intended to be easy to follow, and not intended to be performant.)
Implementations that use ECMAScript to implement the APIs defined in this specification MUST implement them in a manner consistent with the ECMAScript Bindings defined in the Web IDL specification [[!WEBIDL]], as this specification uses that specification and terminology.
The termmedia description is defined in [[!RFC4566]].
The termmedia transport is defined in [[!RFC7656]].
The termgeneration is defined in [[!TRICKLE-ICE]] Section 2.
The termssettled used in the context of Promises are defined in [[ECMASCRIPT-6.0]].
The termsbundle,bundle-only andbundle-policy are defined in [[!JSEP]].
TheOAuth Client andAuthorization Server roles are defined in [[!RFC6749]] Section 1.1.
WebRTC offers and answers (and hence the channels established by {{RTCPeerConnection}} objects) can be authenticated by using a web-based Identity Provider (IdP). The idea is that the entity sending an offer or answer acts as the Authenticating Party (AP) and obtains an identity assertion from the IdP which it attaches to the session description. The consumer of the session description (i.e., the {{RTCPeerConnection}} on whichsetRemoteDescription is called) acts as the Relying Party (RP) and verifies the assertion.
The interaction with the IdP is designed to decouple the browser from any particular identity provider; the browser need only know how to load the IdP's JavaScript, the location of which is determined by the IdP's identity, and the generic interface to generating and validating assertions. The IdP provides whatever logic is necessary to bridge the generic protocol to the IdP's specific requirements. Thus, a single browser can support any number of identity protocols, including being forward compatible with IdPs which did not exist at the time the browser was written.
An IdP is used to generate an identity assertion as follows:
setIdentityProvider() method has been called, the IdP provided shall be used.setIdentityProvider() method has not been called, then the user agent MAY use an IdP configured into the browser.In order to verify assertions, the IdP domain name and protocol are taken from thedomain andprotocol fields of the identity assertion.
In order to communicate with the IdP, the user agent loads the IdP JavaScript from the IdP. The URI for the IdP script is a well-known URI formed from thedomain
andprotocol
fields, as specified in [[!RTCWEB-SECURITY-ARCH]].
The IdP MAY generate an HTTP redirect to another "https" origin, the browser MUST treat a redirect to any other scheme as a fatal error.
The user agent instantiates an isolated interpreted context, a JavaScript realm that operates in the origin of the loaded JavaScript. Note that a redirect will change the origin of the loaded script.
Therealm is populated with a global that implements both theRTCIdentityProviderGlobalScope and {{WorkerGlobalScope}} interfaces.
The user agent provides an instance ofRTCIdentityProviderRegistrar namedrtcIdentityProvider in the global scope of therealm. This object is used by the IdP to interact with the user agent.
[Global=(Worker,RTCIdentityProvider), Exposed=RTCIdentityProvider]interface RTCIdentityProviderGlobalScope : WorkerGlobalScope { readonly attribute RTCIdentityProviderRegistrar rtcIdentityProvider;};rtcIdentityProvider of typeRTCIdentityProviderRegistrar, readonlyRTCIdentityProvider instance with the browser.An environment that mimics the identity provider realm can be provided by any script. However, only scripts running in the origin of the IdP are able to generate an identical environment. Other origins can load and run the IdP proxy code, but they will be unable to replicate data that is unique to the origin of the IdP.
This means that it is critical that an IdP use data that is restricted to its own origin when generating identity assertions. Otherwise, another origin could load the IdP script and use it to impersonate users.
The data that the IdP script uses could be stored on the client (for example, in [[INDEXEDDB]]) or loaded from servers. Data that is acquired from a server SHOULD require credentials and be protected from cross-origin access.
There is no risk to the integrity of identity assertions if an IdP validates an identity assertion without using origin-private data.
An IdP proxy implements theRTCIdentityProvider methods, which are the means by which the user agent is able to request that an identity assertion be generated or validated.
Once instantiated, the IdP script is executed. The IdP MUST call theregister() function on theRTCIdentityProviderRegistrar instance during script execution. If an IdP is not registered during this script execution, the user agent cannot use the IdP proxy and MUST fail any future attempt to interact with the IdP.
[Exposed=RTCIdentityProvider]interface RTCIdentityProviderRegistrar { undefined register (RTCIdentityProvider idp);};registerThis method is invoked by the IdP when its script is first executed. This registersRTCIdentityProvider methods with the user agent.
The callback functions inRTCIdentityProvider are exposed by identity providers and is called byRTCPeerConnection to acquire or validate identity assertions.
dictionary RTCIdentityProvider { required GenerateAssertionCallback generateAssertion; required ValidateAssertionCallback validateAssertion;};generateAssertion of typeGenerateAssertionCallback, requiredA user agent invokes this method on the IdP to request the generation of an identity assertion.
The IdP provides a promise thatresolves to anRTCIdentityAssertionResult to successfully generate an identity assertion. Any other value, or a [= reject | rejected =] promise, is treated as an error.
validateAssertion of typeValidateAssertionCallback, requiredA user agent invokes this method on the IdP to request the validation of an identity assertion.
The IdP returns a Promise thatresolves to anRTCIdentityValidationResult to successfully validate an identity assertion and to provide the actual identity. Any other value, or a [= reject | rejected =] promise, is treated as an error.
callback GenerateAssertionCallback = Promise<RTCIdentityAssertionResult> (DOMString contents, DOMString origin, optional RTCIdentityProviderOptions options = {});contents of type {{DOMString}}contents as opaque string. A successful validation of the provided assertion MUST produce the same string.origin of type {{DOMString}}RTCPeerConnection and therefore can be trusted to be correct.options of typeRTCIdentityProviderOptionssetIdentityProvider. Though the dictionary is an optional argument tosetIdentityProvider, default values are used as necessary when passing the value to the identity provider; see the definition ofRTCIdentityProviderOptions for details.callback ValidateAssertionCallback = Promise<RTCIdentityValidationResult> (DOMString assertion, DOMString origin);
assertion of type {{DOMString}}a=identity in the session description; that is, the value that was part of theRTCIdentityAssertionResult provided by the IdP that generated the assertion.origin of type {{DOMString}}dictionary RTCIdentityAssertionResult { required RTCIdentityProviderDetails idp; required DOMString assertion;};idp of typeRTCIdentityProviderDetails, requiredAn IdP provides these details to identify the IdP that validates the identity assertion. This struct contains the same information that is provided to {{RTCPeerConnection/setIdentityProvider}}.
assertion of type {{DOMString}}, requiredAn identity assertion. This is an opaque string that MUST contain all information necessary to assert identity. This value is consumed by the validating IdP.
dictionary RTCIdentityProviderDetails { required DOMString domain; DOMString protocol = "default";};domain of type {{DOMString}}, requiredThe domain name of the IdP that validated the associated identity assertion.
protocol of type {{DOMString}}, defaulting to"default"The protocol parameter used for the IdP. The string MUST NOT include the character'/' or'\'.
dictionary RTCIdentityValidationResult { required DOMString identity; required DOMString contents;};identity of type {{DOMString}}, requiredThe validated identity of the peer.
contents of type {{DOMString}}, requiredThe payload of the identity assertion. An IdP that validates an identity assertion MUST return the same string that was provided to the original IdP that generated the assertion.
The user agent uses thecontents string to determine if the identity assertion matches the session description.
The identity assertion request process is triggered by a call tocreateOffer,createAnswer, orgetIdentityAssertion. When these calls are invoked and an identity provider has been set, the following steps are executed:
TheRTCPeerConnection instantiates an IdP as described inIdentity Provider Selection andRegistering an IdP Proxy. If the IdP cannot be loaded, instantiated, or the IdP proxy is not registered, this process fails.
If theRTCPeerConnection was not constructed with a set of certificates, and one has not yet been generated, wait for it to be generated.
TheRTCPeerConnection invokes thegenerateAssertion method on theRTCIdentityProvider methods registered by the IdP.
TheRTCPeerConnection generates thecontents parameter to this method as described in [[!RTCWEB-SECURITY-ARCH]]. The value ofcontents includes the fingerprint of the certificate that was selected or generated during the construction of theRTCPeerConnection. Theorigin parameter contains the origin of the script that calls theRTCPeerConnection method that triggers this behavior. TheusernameHint value is the same value that is provided tosetIdentityProvider, if any such value was provided.
The IdP proxy returns a Promise to theRTCPeerConnection. The IdP proxy is expected to generate the identity assertion asynchronously.
If the user has been authenticated by the IdP, and the IdP is able to generate an identity assertion, the IdPresolves the promise with an identity assertion in the form of anRTCIdentityAssertionResult.
This step depends entirely on the IdP. The methods by which an IdP authenticates users or generates assertions is not specified, though they could involve interacting with the IdP server or other servers.
If the IdP proxy produces an error or returns a promise that does notresolve to a validRTCIdentityAssertionResult (see), then assertion generation fails.
TheRTCPeerConnection MAY store the identity assertion for use with future offers or answers. If a fresh identity assertion is needed for any reason, applications can create a newRTCPeerConnection.
If the identity request was triggered by acreateOffer() orcreateAnswer(), then the assertion is converted to a JSON string, base64-encoded and inserted into ana=identity attribute in the session description.
If assertion generation fails, then the promise for the corresponding function call is [= reject | rejected =] with a newly [= exception/created =]OperationError.
An IdP MAY reject an attempt to generate an identity assertion if it is unable to verify that a user is authenticated. This might be due to the IdP not having the necessary authentication information available to it (such as cookies).
Rejecting the promise returned bygenerateAssertion will cause the error to propagate to the application. Login errors are indicated byrejecting the promise with an {{RTCError}} witherrorDetail set to "idp-need-login".
The URL to login at will be passed to the application in theidpLoginUrl attribute of theRTCPeerConnection.
An application can load the login URL in an IFRAME or popup window; the resulting page then SHOULD provide the user with an opportunity to enter any information necessary to complete the authorization process.
Once the authorization process is complete, the page loaded in the IFRAME or popup sends a message usingpostMessage [[!webmessaging]] to the page that loaded it (through the window.opener attribute for popups, or through window.parent for pages loaded in an IFRAME). The message MUST consist of theDOMString "WEBRTC-LOGINDONE". This message informs the application that another attempt at generating an identity assertion is likely to be successful.
Identity assertion validation happens when {{RTCPeerConnection/setRemoteDescription()}} is invoked on {{RTCPeerConnection}}. The process runs asynchronously, meaning that validation of an identity assertion might not block the completion ofsetRemoteDescription.
The identity assertion request process involves the following asynchronous steps:
TheRTCPeerConnection awaits any prior identity validation. Only one identity validation can run at a time for anRTCPeerConnection. This can happen because the resolution ofsetRemoteDescription is not blocked by identity validation unless there is atarget peer identity.
TheRTCPeerConnection loads the identity assertion from the session description and decodes the base64 value, then parses the resulting JSON. Theidp parameter of the resulting dictionary contains adomain and an optionalprotocol value that identifies the IdP, as described in [[!RTCWEB-SECURITY-ARCH]].
If the identity assertion is malformed, or ifprotocol includes the character'/' or'\', this process fails.
TheRTCPeerConnection instantiates the identified IdP as described in and. If the IdP cannot be loaded, instantiated or the IdP proxy is not registered, this process fails.
TheRTCPeerConnection invokes thevalidateAssertion method registered by the IdP.
Theassertion parameter is taken from the decoded identity assertion. Theorigin parameter contains the origin of the script that calls theRTCPeerConnection method that triggers this behavior.
The IdP proxy returns a promise and performs the validation process asynchronously.
The IdP proxy verifies the identity assertion using whatever means necessary. Depending on the authentication protocol this could involve interacting with the IdP server.
If the IdP proxy produces an error or returns a promise that does notresolve to a validRTCIdentityValidationResult (see), then identity validation fails.
Once the assertion is successfully verified, the IdP proxyresolves the promise with anRTCIdentityValidationResult containing the validated identity and the original contents that are the payload of the assertion.
TheRTCPeerConnection decodes thecontents and validates that it contains a fingerprint value for everya=fingerprint attribute in the session description. This ensures that the certificate used by the remote peer for communications is covered by the identity assertion.
Auser agent is required to fail to communicate with peers that offer a certificate that doesn't match ana=fingerprint line in the negotiated session description.
The user agent decodescontents using the format described in [[!RTCWEB-SECURITY-ARCH]]. However the IdP MUST treatcontents as opaque and return the same string to allow for future extensions.
TheRTCPeerConnection validates that the domain portion of the identity matches the domain of the IdP as described in [[!RTCWEB-SECURITY-ARCH]]. If this check fails then the identity validation fails.
TheRTCPeerConnection resolves thepeerIdentity attribute with a new instance ofRTCIdentityAssertion that includes the IdP domain and peer identity.
Theuser agent MAY display identity information to a user in its UI. Any user identity information that is displayed in this fashion MUST use a mechanism that cannot be spoofed by content.
If identity validation fails, thepeerIdentity promise is [= reject | rejected =] with a newly [= exception/created =]OperationError if it is notsettled. Then, if there is notarget peer identity, setpeerIdentity to a new unresolved promise. This permits the use of renegotiation (or a subsequent answer, if the session description was a provisional answer) to resolve or reject the identity.
If identity validation fails and there is atarget peer identity for theRTCPeerConnection, the promise returned bysetRemoteDescription is [= reject | rejected =] with the sameDOMException.
Errors in IdP processing will - in most cases - result in the failure of the procedure that invoked the IdP proxy. This will result in the [= reject | rejection =] of the promise returned by {{RTCPeerConnection/getIdentityAssertion()}}, {{RTCPeerConnection/createOffer()}}, or {{RTCPeerConnection/createAnswer()}}. An IdP proxy error causes a {{RTCPeerConnection/setRemoteDescription()}} promise to be [= reject | rejected =] if there is atarget peer identity; IdP errors in calls to {{RTCPeerConnection/setRemoteDescription()}} where there is notarget peer identity cause the {{RTCPeerConnection/peerIdentity}} promise to be [= reject | rejected =] instead.
If an error occurs these promises are [= reject | rejected =] with an {{RTCError}} if an error occurs in interacting with the IdP proxy. The following scenarios result in errors:
AnRTCPeerConnection might be configured with an identity provider, but loading of the IdP URI fails. Any procedure that attempts to invoke such an identity provider and cannot load the URI fails with an {{RTCError}} witherrorDetail set to "idp-load-failure" and the httpRequestStatusCode attribute of the error set to the HTTP status code of the response.
If the IdP loads fails due to the TLS certificate used for the HTTPS connection not being trusted, it fails with an {{RTCError}} witherrorDetail set to "idp-tls-failure". This typically happens when the IdP uses certificate pinning and an intermediary such as an enterprise firewall has intercepted the TLS connection.
If the script loaded from the identity provider is not valid JavaScript or does not implement the correct interfaces, it causes an IdP failure with an {{RTCError}} witherrorDetail set to "idp-bad-script-failure".
An apparently valid identity provider might fail in several ways. If the IdP token has expired, then the IdP MUST fail with an {{RTCError}} witherrorDetail set to "idp-token-expired". If the IdP token is not valid, then the IdP MUST fail with an {{RTCError}} witherrorDetail set to "idp-token-invalid". If an identity provider throws an exception or returns a promise that is ultimately [= reject | rejected =], then the procedure that depends on the IdP MUST also fail. These types of errors will cause an IdP failure with an {{RTCError}} witherrorDetail set to "idp-execution-failure".
Theuser agent SHOULD limit the time that it allows for an IdP to 15 seconds. This includes both the loading of theIdP proxy and the identity assertion generation or validation. Failure to do so potentially causes the corresponding operation to take an indefinite amount of time. This timer can be cancelled when the IdP proxy produces a response. Expiration of this timer cases an IdP failure with an {{RTCError}} witherrorDetail set to "idp-timeout".
If the identity provider requires the user to login, the operation will fail {{RTCError}} witherrorDetail set to "idp-need-login" and theidpLoginUrl attribute of the error set to the URL that can be used to login.
Even when the IdP proxy produces a positive result, the procedure that uses this information might still fail. Additional validation of anRTCIdentityValidationResult value is still necessary. The procedure forvalidation of identity assertions describes additional steps that are required to successfully validate the output of the IdP proxy.
Any error generated by the IdP MAY provide additional information in theidpErrorInfo attribute. The information in this string is defined by the IdP in use.
The Identity API extends the {{RTCPeerConnection}} interface as described below.
partial interface RTCPeerConnection { undefined setIdentityProvider (DOMString provider, optional RTCIdentityProviderOptions options = {}); Promise<DOMString> getIdentityAssertion (); readonly attribute Promise<RTCIdentityAssertion> peerIdentity; readonly attribute DOMString? idpLoginUrl; readonly attribute DOMString? idpErrorInfo;};peerIdentity of typePromise<RTCIdentityAssertion>, readonlyA promise thatresolves with the identity of the peer if the identity is successfully validated.
This promise is [= reject | rejected =] if an identity assertion is present in a remote session description and validation of that assertion fails for any reason. If the promise is [= reject | rejected =], a new unresolved value is created, unless atarget peer identity has been established. If this promise successfullyresolves, the value will not change.
idpLoginUrl of type {{DOMString}}, readonly, nullableThe URL that an application can navigate to so that the user can login to the IdP, as described in.
idpErrorInfo of type {{DOMString}}, readonly, nullableAn attribute that the IdP can use to pass additional information back to the applications about the error. The format of this string is defined by the IdP and may be JSON.
setIdentityProviderSets the identity provider to be used for a givenRTCPeerConnection object.
When thesetIdentityProvider method is invoked, the user agent MUST run the following steps:
If the {{RTCPeerConnection}} object's {{RTCPeerConnection/[[IsClosed]]}} slot istrue, [= exception/throw =] anInvalidStateError.
Ifoptions.protocol includes the the character'/' or'\', throw aSyntaxError.
Set the current identity provider values to the tuple (provider,options).
If any identity provider value has changed, discard any stored identity assertion.
Identity provider information is not used until an identity assertion is required, either in response to a call togetIdentityAssertion, or a session description is requested with a call to eithercreateOffer orcreateAnswer.
getIdentityAssertionInitiates the process of obtaining an identity assertion. Applications need not make this call. It is merely intended to allow them to start the process of obtaining identity assertions before a call is initiated. If an identity is needed and an identity provider has been set using the {{RTCPeerConnection/setIdentityProvider}} method, then an identity will be automatically requested when an offer or answer is created.
WhengetIdentityAssertion is invoked, queue a task to run the following steps:
If the {{RTCPeerConnection}} object's {{RTCPeerConnection/[[IsClosed]]}} slot istrue, [= exception/throw =] anInvalidStateError.
Request an identity assertion from the IdP.
Resolve the promise with the base64 and JSON encoded assertion.
This spec extends theRTCConfiguration dictionary with the following parameter.
partial dictionary RTCConfiguration { DOMString peerIdentity;};peerIdentity of type {{DOMString}}Sets thetarget peer identity for the {{RTCPeerConnection}}. The {{RTCPeerConnection}} will not establish a connection to a remote peer unless it can be successfully authenticated with the provided name.
dictionary RTCIdentityProviderOptions { DOMString protocol = "default"; DOMString usernameHint; DOMString peerIdentity;};protocol of type {{DOMString}}The name of the protocol that is used by the identity provider. This MUST NOT include '/' (U+002F) or '\' (U+005C) characters. This value defaults to "default" if not provided.
usernameHint of type {{DOMString}}A hint to the identity provider about the identity of the principal for which it should generate an identity assertion. If absent, the valueundefined is used.
peerIdentity of type {{DOMString}}The identity of the peer. For identity providers that bind their assertions to a particular pair of communication peers, this allows them to generate an assertion that includes both local and remote identities. If this value is omitted, but a value is provided for thepeerIdentity member ofRTCConfiguration [[!WEBRTC]], the value fromRTCConfiguration is used.
[Exposed=Window]interface RTCIdentityAssertion { constructor(DOMString idp, DOMString name); attribute DOMString idp; attribute DOMString name;};idp of type {{DOMString}}The domain name of the identity provider that validated this identity.
name of type {{DOMString}}An RFC5322-conformant [[RFC5322]] representation of the verified peer identity. This identity will have been verified via the procedures described in [[!RTCWEB-SECURITY-ARCH]].
Whenever theset a configuration algorithm is invoked, run the following steps instead:
Letconfiguration be theRTCConfiguration dictionary to be processed.
Ifconfiguration.peerIdentity is set and its value differs from thetarget peer identity, [= exception/throw =] anInvalidModificationError.
Return the result of running the originalset a configuration algorithm.
Consider anRTCPeerConnection's currently configured identity provider (or lack of one) to be part of the offerer's system state.
Whenever thecreate an offer algorithm is invoked, run the following steps instead:
Ifconnection's signaling state is neither"stable" nor"have-local-offer", return a promise [= reject | rejected =] with a newly [= exception/created =]InvalidStateError.
Ifconnection is configured with an identity provider, then begin the identity assertion request process if it has not already begun.
Return the result of running the originalcreate an offer algorithm.
Whenever the in-parallel steps to create an offer algorithm is invoked, run the following steps instead:
Ifconnection was not constructed with a set of certificates, and one has not yet been generated, wait for it to be generated.
Letprovider beconnection's currently configured identity provider if one has been configured, ornull otherwise.
Ifprovider is non-null, wait forthe identity assertion request process to complete.
Ifprovider was unable to produce an identity assertion,rejectp with a newly [= exception/created =]NotReadableError and abort these steps.
Return the result of running the original in-parallel steps to create an offer algorithm.
Whenever the final steps to create an offer algorithm is invoked, include the identity assertion fromprovider (if non-null) when generating the SDP offersdpString, as described in[[!JSEP]] (section 5.2.).
Consider anRTCPeerConnection's currently configured identity provider (or lack of one) to be part of the answerer's system state.
If theRTCPeerConnection is configured to generate Identity assertions by callingsetIdentityProvider(), then the session description SHALL contain an appropriate assertion.
Whenever thecreate an answer algorithm is invoked, run the following steps instead:
Ifconnection's signaling state is neither"have-remote-offer" nor"have-local-pranswer", return a promise [= reject | rejected =] with a newly [= exception/created =]InvalidStateError.
Ifconnection is configured with an identity provider, then begin the identity assertion request process if it has not already begun.
Return the result of running the originalcreate an answer algorithm.
Whenever the in-parallel steps to create an answer algorithm is invoked, run the following steps instead:
Ifconnection was not constructed with a set of certificates, and one has not yet been generated, wait for it to be generated.
Letprovider beconnection's currently configured identity provider if one has been configured, ornull otherwise.
Ifprovider is non-null, wait forthe identity assertion request process to complete.
Ifprovider was unable to produce an identity assertion,rejectp with a newly [= exception/created =]NotReadableError and abort these steps.
Return the result of running the original in-parallel steps to create an answer algorithm.
Whenever the final steps to create an answer algorithm is invoked, include the identity assertion fromprovider (if non-null) when generating the SDP answersdpString, as described in[[!JSEP]] (section 5.3.).
Whenever the {{RTCPeerConnection/setRemoteDescription()}} method is called, in addition to its regular steps, a remote description is processed to determine and verify the identity of the peer.
If ana=identity attribute is present in the session description, the browser validates the identity assertion..
If thepeerIdentity configuration is applied to the {{RTCPeerConnection}}, this establishes atarget peer identity of the provided value. Alternatively, if the {{RTCPeerConnection}} has previously authenticated the identity of the peer (that is, thepeerIdentity promise isresolved), then this also establishes atarget peer identity.
Thetarget peer identity cannot be changed once set.
If atarget peer identity is set, then theidentity validation MUST be completed before the promise returned by {{RTCPeerConnection/setRemoteDescription()}} isresolved, and the promise returned by {{RTCPeerConnection/setRemoteDescription()}} MUST be [= reject | rejected =] ifidentity validation fails.
However, if there is notarget peer identity, thensetRemoteDescription MUST NOT await the completion of identity validation, and whetheridentity validation fails or not MUST NOT influence whether the promise returned by {{RTCPeerConnection/setRemoteDescription()}} is rejected.
partial interface RTCError { readonly attribute long? httpRequestStatusCode;};httpRequestStatusCode of typelong, readonly, nullableIferrorDetail is"idp-load-failure" this is the HTTP status code of the IdP URI response.
partial dictionary RTCErrorInit { long httpRequestStatusCode;};ThehttpRequestStatusCode member ofRTCErrorInit has the same definition as the attribute of the same name of {{RTCError}}.
httpRequestStatusCode of typelongSee {{RTCError}}'shttpRequestStatusCode.
RTCErrorDetailTypeIdp Enum// This is an extension of RTCErrorDetailType from [[WEBRTC-PC]]// Unfortunately, WebIDL does not support partial enums (yet).//// partial enum RTCErrorDetailType {enum RTCErrorDetailTypeIdp { "idp-bad-script-failure", "idp-execution-failure", "idp-load-failure", "idp-need-login", "idp-timeout", "idp-tls-failure", "idp-token-expired", "idp-token-invalid",};These enum values are extensions of the RTCErrorDetailType enum. They are defined in this way because enums in WebIDL can currently be described in one place only. This can be simplified should partial enum support materialize in WebIDL.
| RTCErrorDetailTypeIdp Enumeration description | |
|---|---|
idp-bad-script-failure | The script loaded from the identity provider is not valid JavaScript or did not implement the correct interfaces. |
idp-execution-failure | The identity provider has thrown an exception or returned a [= reject | rejected =] promise. |
idp-load-failure | Loading of the IdP URI has failed. ThehttpRequestStatusCode attribute is set to the HTTP status code of the response. |
idp-need-login | The identity provider requires the user to login. TheidpLoginUrl attribute is set to the URL that can be used to login. |
idp-timeout | The IdP timer has expired. |
idp-tls-failure | The TLS certificate used for the IdP HTTPS connection is not trusted. |
idp-token-expired | The IdP token has expired. |
idp-token-invalid | The IdP token is invalid. |
A MediaStream acquired usinggetUserMedia() is, by default, accessible to an application. This means that the application is able to access the contents of tracks, modify their content, and send that media to any peer it chooses.
WebRTC supports calling scenarios where media is sent to a specifically identified peer, without the contents of media streams being accessible to applications. This is enabled by use of thepeerIdentity parameter togetUserMedia().
An application willingly relinquishes access to media by including apeerIdentity parameter in theMediaStreamConstraints. This attribute is set to aDOMString containing the identity of a specific peer.
TheMediaStreamConstraints dictionary is expanded to include thepeerIdentity parameter.
partial dictionary MediaStreamConstraints { DOMString peerIdentity;};peerIdentity of type {{DOMString}}If set,peerIdentity isolates media from the application. Media can only be sent to the identified peer.
A user that is prompted to provide consent for access to a camera or microphone can be shown the value of thepeerIdentity parameter, so that they can be informed that the consent is more narrowly restricted.
When thepeerIdentity option is supplied togetUserMedia(), all of theMediaStreamTracks in the resultingMediaStream are isolated so that content is not accessible to any application. IsolatedMediaStreamTracks can be used for two purposes:
Displayed in an appropriate media tag (e.g., a video or audio element). The browser MUST ensure that content is inaccessible to the application by ensuring that the resulting content is given the same protections as content that is CORS cross-origin, as described in the relevant Security and privacy considerations section of [[HTML51]].
Used as the argument to {{RTCPeerConnection/addTrack()}} on an {{RTCPeerConnection}} instance, subject to the restrictions inisolated streams and RTCPeerConnection.
AMediaStreamTrack that is added to anotherMediaStream remains isolated. When an isolatedMediaStreamTrack is added to aMediaStream with a different peerIdentity, theMediaStream gets a combination of isolation restrictions. AMediaStream containingMediaStreamTrack instances with mixed isolation properties can be displayed, but cannot be sent using {{RTCPeerConnection}}.
AnypeerIdentity property MUST be retained on cloned copies ofMediaStreamTracks.
MediaStreamTrack is expanded to include anisolated attribute and a corresponding event. This allows an application to quickly and easily determine whether a track is accessible.
partial interface MediaStreamTrack { readonly attribute boolean isolated; attribute EventHandler onisolationchange;};isolated of type {{boolean}}, readonlyAMediaStreamTrack is isolated (and the correspondingisolated attribute set totrue) when content is inaccessible to the owning document. This occurs as a result of setting thepeerIdentity option. A track is also isolated if it comes from a cross origin source.
onisolationchange of type {{EventHandler}}This event handler, of typeisolationchange, is fired when the value of theisolated attribute changes.
AMediaStreamTrack with apeerIdentity option set can be added to any {{RTCPeerConnection}}. However, the content of an isolated track MUST NOT be transmitted unless all of the following constraints are met:
AMediaStreamTrack from a stream acquired using thepeerIdentity option can be transmitted if the {{RTCPeerConnection}} has successfullyvalidated the identity of the peer AND that identity is the same identity that was used in thepeerIdentity option associated with the track. That is, thename attribute of thepeerIdentity attribute of the {{RTCPeerConnection}} instance MUST match the value of thepeerIdentity option passed togetUserMedia().
Rules for matching identity are described in [[!RTCWEB-SECURITY-ARCH]].
The peer has indicated that it will respect the isolation properties of streams. That is, a DTLS connection with a promise to respect stream confidentiality, as defined in [[!RTCWEB-ALPN]] has been established.
Failing to meet these conditions means that no media can be sent for the affectedMediaStreamTrack. Video MUST be replaced by black frames, audio MUST be replaced by silence, and equivalently information-free content MUST be provided for other media types.
Remotely sourcedMediaStreamTracks MUST be isolated if they are received over a DTLS connection that has been negotiated with track isolation. This protects isolated media from the application in the receiving browser. These tracks MUST only be displayed to a user using the appropriate media element (e.g., <video> or <audio>).
AnyMediaStreamTrack that has thepeerIdentity option set causes all tracks sent using the same {{RTCPeerConnection}} to be isolated at the receiving peer. All DTLS connections created for an {{RTCPeerConnection}} with isolated local streams MUST be negotiated so that media remains isolated at the remote peer. This causes non-isolated media to become isolated at the receiving peer if any isolated tracks are added to the same {{RTCPeerConnection}}.
Tracks that are not bound to a particularpeerIdentity do not cause other streams to be isolated, these tracks simply do not have their content transmitted.
If a stream becomes isolated after initially being accessible, or an isolated stream is added to an active session, then media for that stream is replaced by information-free content (e.g., black frames or silence).
Media isolation ensures that the content of aMediaStreamTrack is not accessible to web applications. However, to ensure that media with apeerIdentity option set can be sent to peers, some meta-information about the media will be exposed to applications.
Applications will be able to observe the parameters of the media that affect session negotiation and conversion into RTP. This includes the codecs that might be supported by the track, the bitrate, the number of packets, and the current settings that are set on theMediaStreamTrack.
In particular, thestatistics [[!WEBRTC]] that {{RTCPeerConnection}} records are not reduced in capability. New statistics that might compromise isolation MUST be avoided, or explicitly suppressed for isolated streams.
Most of these data are exposed to the network when the media is transmitted. Only the settings for theMediaStreamTrack present a new source of information. This can includes the frame rate and resolution of video tracks, the bandwidth of audio tracks, and other information about the source, which would not otherwise be revealed to a network observer. Since settings don't change at a high frequency or in response to changes in media content, settings only reveal limited reveal information about the content of a track. However, any setting that might change dynamically in response to the content of an isolatedMediaStreamTrack MUST have changes suppressed.
The identity system is designed so that applications need not take any special action in order for users to generate and verify identity assertions; if a user has configured an IdP into their browser, then the browser will automatically request/generate assertions and the other side will automatically verify them and display the results. However, applications may wish to exercise tighter control over the identity system as shown by the following examples.
This example shows how to configure the identity provider.
pc.setIdentityProvider('example.com');This example shows how to configure the identity provider with all the options.
pc.setIdentityProvider('example.com', { usernameHint: 'alice@example.com', peerIdentity: 'bob@example.net'});This example shows how to consume identity assertions inside a Web application.
async function consumeIdentityAssertion() { const identity = await pc.peerIdentity; console.log('IdP = ', identity.idp, 'identity =', identity.name);}The following events fire on {{MediaStreamTrack}} objects:
| Event name | Interface | Fired when... |
|---|---|---|
isolationchange | {{Event}} | A newEvent is dispatched to the script when theisolated attribute on aMediaStreamTrack changes. |
This section is non-normative; it specifies no new behaviour, but instead summarizes information already present in other parts of the specification. The overall security considerations of the general set of APIs and protocols used in WebRTC Identity are described in [[RTCWEB-SECURITY-ARCH]].
ThepeerIdentity mechanism loads and executes JavaScript code from a third-party server acting as an identity provider. That code is executed in a separate JavaScript realm and does not affect the protections afforded by the same origin policy.
The fact that communication is taking place cannot be hidden from adversaries that can observe the network, so this has to be regarded as public information.
A mechanism,peerIdentity, is provided that gives Javascript the option of requesting media that the same javascript cannot access, but can only be sent to certain other entities.
This section will be removed before publication.
The editors wish to thank the Working Group chairs and Team Contact, Harald Alvestrand, Stefan Håkansson, Erik Lagerway and Dominique Hazaël-Massieux, for their support. Substantial text in this specification was provided by many people including Martin Thomson, Harald Alvestrand, Justin Uberti, Eric Rescorla, Peter Thatcher, Jan-Ivar Bruaroey and Peter Saint-Andre. Dan Burnett would like to acknowledge the significant support received from Voxeo and Aspect during the development of this specification.