Copyright © 2013 W3C® (MIT, ERCIM, Keio, Beihang), All Rights Reserved. W3C liability, trademark and document use rules apply.
This document specifies a runtime and security model for Web Applications. It describes how an application is defined through an application manifest, and how it can be installed, updated and packaged. It also specifies how such an application can put into the background, put back in the foreground or woken up. Finally, the document describes the security model for such applications. This includes the permission model and the different security rules that would apply.
This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at http://www.w3.org/TR/.
This document defines a runtime and security model for Web Applications, along with a manifest format and packaging model. The current draft covers the use of CSP policies for trusted packaged applications, and future drafts will extend this to trusted hosted applications.
This document was published by the System Applications Working Group as a First Public Working Draft. If you wish to make comments regarding this document, please send them to public-sysapps@w3.org (subscribe, archives). All comments are welcome.
Publication as a First Public Working Draft does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.
This document was produced by a group operating under the 5 February 2004 W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.
The EventHandler interface represents a callback used for event handlers as defined in [HTML5].
The concept of fire a simple event is defined in [HTML5].
The terms event handlers and event handler event types are defined in [HTML5].
The DOMError interface represents an error handling object as defined in [DOM4].
An application manifest is a JSON file describing an installable web application. This JSON file consists of a top-level object and several properties. The JSON grammar is described in [RFC4627].
{ "name": "The Example App", "description": "Exciting Open Web development action!", "launch_path": "/", "version": "1.0", "icons": { "16": "/img/icon_16.png", "48": "/img/icon_48.png", "128": "/img/icon_128.png" }, "developer": { "name": "Foo Corp.", "url": "http://sysapps.org/example" }, "appcache_path": "/cache.manifest", "locales": { "es": { "description": "¡Acción abierta emocionante del desarrollo del Web!", "developer": { "url": "https://sysapps.org/example/es-ES" } } }, "default_locale": "en", "screen_size": { "min_width": "600", "min_height": "300" }, "required_features": ["touch", "geolocation", "webgl"], "permissions": { "contacts": { "description": "Required for auto-completion in the share screen", "access": "read" } }, "fullscreen": "true", "relNotes": { "1.0": "Bugs fixed. New exciting effects. Ready for an official release!", "0.5": "First alpha version with still some bugs but already fun!" } }
Any new specification can add new properties to the application manifest. Those specifications MUST describe the new properties, the expected values and the expected behaviour. Implementations MUST implement the basic properties as describe below but SHOULD only implement any extented feature if they are implementing those specifications.
All leaf properties MUST contain a string value unless specified otherwise.
The following properties MUST be part of the application manifest:
        name and description. In
        addition, if locales is part of the application manifest,
        default_locale MUST be part of the application manifest. The other
        properties are optional.
min_height and
          min_width properties that describe the
          minimum height and width (in pixels) the application
          needs in order to render correctly. Those values are only
          hint for the UA and should not be considered as mandatory
          restrictions.Each specification MUST specify the new permissions that would be required to use the feature it is defining.
The application's origin is the origin of the application manifest. [ORIGIN]
An application manifest MUST be served from the same origin as the application.
When served as a static file, it is RECOMMENDED that the manifest is
      stored with the extension .webapp. The manifest
      MUST be served with a
      Content-Type header of
      application/x-web-app-manifest+json. It is
      RECOMMENDED that
      application manifests are served over SSL.
Application interfaceWeb Applications are represented by the Application interface.
interface Application {
    readonly    attribute DOMString     origin;
    readonly    attribute Object        manifest;
    readonly    attribute DOMString     installOrigin;
    readonly    attribute unsigned long installTime;
    readonly    attribute Object        parameters;
    DOMRequest      launch ();
    DOMRequest      uninstall ();
    readonly    attribute DOMString     updateState;
    readonly    attribute unsigned long downloadSize;
    DownloadRequest downloadUpdate ();
    readonly    attribute DOMString     state;;
    void            hide ();
    void            exit ();
                attribute EventHandler  onlaunch;
                attribute EventHandler  onpause;
                attribute EventHandler  onresume;
                attribute EventHandler  onterminate;
};
        downloadSize of type unsigned long,
            readonlyinstallOrigin of type DOMString, readonlyinstallTime of type unsigned long,
            readonlymanifest of type Object, readonlyonlaunch of type EventHandler,onpause
            of type EventHandler,onresume of type EventHandler,onterminate of type EventHandler,origin of
            type DOMString,
            readonlyparameters of type Object, readonlyinstall()
              in ApplicationRegistry.
            state; of
            type DOMString,
            readonlyrunning if the
              current application state is running. Otherwise, if the current
              application state is paused, it MUST return paused.
              Otherwise, it MUST return terminated.
            updateState of type DOMString, readonlyavailable, downloading,
            downloaded or installing,
            depending on the state of the application.installing.downloaded.downloading.available. Otherwise, the attribute
            MUST return the
            empty string.downloadUpdateDownloadRequest
              object and asynchronously run the following steps:
              InvalidState and abort these steps.
                DownloadRequest
              exitvoid
              hidevoid
              launchDOMRequest instance
              and then run the following steps asynchronously:
              error
                  event to the DOMRequest
                  object with the "NotAllowedError"
                  error code and exit those steps.
                success event to
                  the DOMRequest
                  object and set result to null.error event
                  to the DOMRequest
                  object with an error code that describes the
                  error.
                DOMRequest
              uninstallDOMRequest instance
              and then run the following steps asynchronously:
              error event to the DOMRequest object
                with the "NotInstalledError" error
                code and exit those steps.
                error event to the DOMRequest object
                with the "NotAllowedError" error code
                and exit those steps.
                success event
                to the DOMRequest object
                and set result to null.error event
                  to the DOMRequest
                  object with an error code that describes the
                  error.
                DOMRequest
              The following are the event handlers (and their corresponding
      event handler event types) that
      MUST be supported as
      attributes by the Application objects:
| event handler | event handler event type | 
|---|---|
onlaunch | 
            launch | 
          
onpause | 
            pause | 
          
onresume | 
            resume | 
          
onterminate | 
            terminate | 
          
DownloadRequest interface
interface DownloadRequest : DOMRequest {
    void cancel ();
                attribute double       progress;
                attribute EventHandler onprogress;
};
        onprogress of type EventHandler,progress of type double,error the
            attribute MUST
            return 0.0. Otherwise, if the current state is
            success, the attribute MUST return 1.0. Otherwise, the
            attribute SHOULD return the current progress of the
            download expressed between 0.0 and 1.0.cancelUserCancel.
              void
              When the caller start
        the download, the DownloadRequest SHOULD start downloading the
        resource.
If the resource fails to download, the UA MUST send an error message to the request.
If the resource succeed to download, the UA MUST send a success message to the request.
While the resource is downloading, which means as long
        as readyState is pending, the UA
        SHOULD regularly
        fire a simple event named
        progress on the object. The UA should note that
        sending too much events might have an impact on performance
        but sending too few of them might impact the user
        experince.
The following are the event handlers (and their corresponding
        event handler event types) that
        MUST be supported as
        attributes by the DOMRequest objects:
| event handler | event handler event type | 
|---|---|
onprogress | 
              progress | 
            
ApplicationRegistry
      interfaceThe ApplicationRegistry
        interface allows handling applications and query there
        status.
interface ApplicationRegistry {
    DOMRequest install (DOMString manifestUrl, [Optional] Object parameters);
    DOMRequest getSelf ();
    DOMRequest getInstalled ();
    DOMRequest checkInstalled (DOMString manifestURL);
                attribute ApplicationManagement management;
};
        management of type ApplicationManagement,ApplicationManagement
              object.
            checkInstalledDOMRequest object
              and asynchronously check if there is an installed
              application in the system with a manifest URL
              matching manifestURL.success event to the DOMRequest object
              and populate its result attribute with
              the boolean value true if there is an installed
              application fulfilling the condition, otherwise
              result should be set to false.
              | Parameter | Type | Nullable | Optional | Description | 
|---|---|---|---|---|
| manifestURL | 
                  DOMString | 
                  ✘ | ✘ | 
DOMRequest
              getInstalledDOMRequest object
              and asynchronously get all applications that have an
              origin matching the caller's origin. [ORIGIN]success event to the DOMRequest object
              and populate its request attribute with
              an array containing the applications.
              DOMRequest
              getSelfDOMRequest object
              and asynchronously get all applications that have an
              origin matching the caller's origin. [ORIGIN]success event to the DOMRequest object
              and populate its request attribute with
              an array containing the applications.
              DOMRequest
              installDOMRequest instance
              and then run the following steps asynchronously:
              error
                  event to the DOMRequest
                  object with the "NotAllowedError"
                  error code and exit those steps.
                manifestUrl.success event to
                  the DOMRequest
                  object and set result to null.error event
                  to the DOMRequest
                  object with an error code that describes the
                  error.
                The UA SHOULD verify at any moment before
              installing that manifestUrl points to a
              valid manifest. If this is not the case, the UA
              MUST fire an
              error event to the DOMRequest object
              with the "InvalidArgumentError" and exit
              the steps.
The UA SHOULD save the parameters
              if some are passed so they can later be retrieved by
              the parameters attribute on the Application
              interface.
| Parameter | Type | Nullable | Optional | Description | 
|---|---|---|---|---|
| manifestUrl | 
                  DOMString | 
                  ✘ | ✘ | |
| parameters | 
                  Object | 
                  ✘ | ✘ | 
DOMRequest
              ApplicationManagement
      interfaceThe ApplicationManagement
        interface allows access to all applications and is being
        informed any time an application is being installed or
        uninstalled. The intent of this interface is to be
        restricted to privileged callers.
interface ApplicationManagement {
    DOMRequest getAll ();
    [TreatNonCallableAsNull]
                attribute EventHandler oninstall;
    [TreatNonCallableAsNull]
                attribute EventHandler onuninstall;
    DOMRequest applyUpdate (Application application);
};
        oninstall of type EventHandler,AppObject of the application that was
            installed.onuninstall of type EventHandler,AppObject
            of the application that was uninstalled.applyUpdateInvalidState
                and abort these steps.
                Application object
                representing the updated application as a value.
                | Parameter | Type | Nullable | Optional | Description | 
|---|---|---|---|---|
| application |  | 
                  ✘ | ✘ | 
DOMRequest
              getAllDOMRequest object
              and asynchronously get all applications currently in
              the application registry.success event to the DOMRequest object
              and populate its request attribute with
              an array containing the applications.
              DOMRequest
              An install event MUST be fired on all ApplicationManagement
        instances as soon as an application is installed.
The uninstall event MUST be fired on all ApplicationManagement
        instances as soon as an application is uninstalled.
The following are the event handlers (and their corresponding
        event handler event types) that
        MUST be supported as
        attributes by the ApplicationManagement
        object:
| event handler | event handler event type | 
|---|---|
oninstall | 
              install | 
            
onuninstall | 
              uninstall | 
            
Application Events are sent when an event happen on the application level like an application being installed or uninstalled.
[Constructor(DOMString type, Application eventInitDict)]
interface ApplicationEvent : Event {
    readonly    attribute Application application;
};
        application of type Application,
            readonly
dictionary ApplicationEventInit : EventInit {
    Application application;
};
        ApplicationEventInit Membersapplication of type ApplicationApplicationEvent objects
      MUST contain a non-null
      application attribute representing the
      application on each the action happened.
      The application events are always sent asynchronously, do not
      buble and are not cancelable.
There are currently two types of Application Events:
application
        MUST represent the
        installed application.application
        MUST represent the
        uninstalled application.A packaged application is an application that is self-contained in a container. All resources that are commonly used by the application SHOULD be available in the container.
A hosted application is an application that is not a packaged application
This section is non-normative.
A packaged application would be useful in a few situations, amongst them:
An application manifest for the application MUST be present at the root of the container.
The container of a packaged application MUST be a ZIP file.
A file contained in a packaged application MUST have an URI with the following rules:
scheme of the URI MUST be app.authority of the URI MUST be an identifier unique
        for each applications. That means, two files from different
        applications can't share the same authority
        but two files from the same application will.path of the URI MUST be the file name.For more information about URI's, refer to [RFC3986].
For example, the URI of index.html from an application can be: app://e35b8412-7451-46e7-ab29-0cee24fd486a/index.html.
The URI of a packaged file is defined such as two files
      from the same packaged application MUST share the same origin.
      A file from a packaged application and any other resource
      outside of this application (an application or not, packaged
      or not) MUST not share
      the same origin. [ORIGIN]
A packaged application MUST have a copy of its application manifest outside of the package so it can be used for installation and updates purposes. As a consequence, that copy of the application manifest can be reduced to only a few properties: name, version and relNotes. In addition, a new property can be used only in the content a packaged application manifest: package that SHOULD contain an object with the following properties:
{ "name": "My Packaged App", "description": "This is my first packaged app!", "launch_path": "/", "version": "1.0", "developer": { "name": "Mozilla", "url": "https://mozilla.org/en-US" }, "package": { "url": "http://example.org/mypackagedapp.zip", "size": "1024", "sha256": "6df134b0cfd88d6d4f27a99e29b9923d50eb8b2c0d5289c60012de424c7a9d97" } }
An application SHOULD advertise an update by updating its application manifest.
The UA SHOULD regularly check if the application manifest of installed applications has not been updated. To know if the file has been updated, HTTP semantics apply.
For package applications, both application manifests (outside and inside the package) SHOULD be updated. However, the application manifest inside the package SHOULD always be checked to make sure the update (or the install) is genuine.
In the context of a running application, all usual rules for data isolation MUST apply: same-origin policy, same-domain policy, or whatever is used. However, between two applications, those rules no longer apply. Two applications MUST be fully isolated from each other in the sense that they SHOULD NOT be able to access data from each other. For example, if App1 accesses http://example.org and gets a cookie from it, App2 should not be able to see that cookie when accessing http://example.org even if the usual cookie sharing policy should allow this to happen.
This isolation SHOULD apply for all data storage like
    cookies, localStorage, IndexedDB, app
    cache and any other Web Platform mechanism that allows to
    store data and doesn't explicitly opts out from the application
    data isolation.
    The isolation SHOULD
    also apply to UA specifics data storage. For example, any
    permission granted or denied to a host/origin/domain should be
    isolated per-application or auto-fill and autocompletion
    features for forms.
System Messages are events sent by the system to an
    application which has registered for it before. Those events
    are different from DOM events in the sense that they are always
    originated by the system and that if the targeted application
    isn't currently running, it will be started.
    In addition, un-handled messages will stay in a queue.
This section is non-normative.
Some applications might be interested in getting some
      events even if they are not running and want to be woken up
      if such events is sent while they are asleep.
      In addition, when the application is being woken, it needs to
      know as soon as possible why it has been disturbed to be able
      to show the appropriate interface.
      Finally, the capability of being woken should be transparent
      to the application.
The type of system
      message identifies a category of system messages.
      Application are be able to register and handle system
      messages based on their types. There is no exhaustive list of
      system messages type. Any specification can create a new type
      of system message.
Each application has a pool
      of messages for each type of system message. Everytime a
      system message is sent to an application, if there is no
      handler for that message's type, the UA MUST add the message to the pool of
      messages used for that type.
      The UA MAY, for memory
      optimization, discard old messages if the pool becomes too
      big or if the messages are too old.
When a UA is required to fire a system message of a given type, it has to do one of these actions:
This section is non-normative.
Some API might allow the application to access sensitive parts of the hardware or sensitive information. To prevent applications to access them, some APIs might require one or more permissions. For example, for an application to be allowed to access your geolocation information, it has to be granted the geolocation permission.
An application SHOULD define all permissions it is going to use in the application manifest. The UA MAY automatically grant some permissions at install-time or ask the user to grant some applications. However, MAY, in addition or alternatively, ask the user to grant permissions at run-time.
The user MUST be able to revoke a granted permission or grant a denied permission at any time.
Specifications are expected to declare the permissions they will require for their feature to work. Altough, some basic permissions can't really go into a specific specification or a related to specifications that might be harder to change.
Thus, this specification is defining the following permissions:
| Permission Name | Permission Description | Access Type | 
|---|---|---|
desktop-notification | 
            Allow the application to use the Desktop Notification API. | N/A | 
geolocation | 
            Allow the application to access the Geolocation API. | N/A | 
storage | 
            Allow localStorage and IndexedDB without size limitations. | N/A | 
webapps-manage | 
            Allow access to the
            navigator.apps.management API to manage
            installed webapps. | 
            N/A | 
This section is non-normative.
Any application can be compromised. It just depends on how much effort the attacker wants to provide and how much efforts the author wants to dedicate making its application more secure. With an interesting enough outcome, attackers could easily double their efforts to beat the security in place. For example, an API allowing to send SMS, if it can be manipulated by the evil persons, could be used to send premium SMS and steal money from the users.
With a simple permission system, users could be tricked to install the application and accept to grant the application the relevant permissions. These kind of attacks are proven to be efficient.
An application is said to be a trusted application if the origin installing the application is trusted by the UA and the origin installing the application consider the application as trusty.
A UA SHOULD have the public key of all installation origin it is considering trusted.
A hosted application MUST be recognized as marked trusted by the installation origin if the application manifest is signed by the installation origin's private key.
A packaged application MUST be recognized as marked trusted by the installation origin if the package is signed by the installation origin's private key.
In both cases, the application SHOULD be considered as trusted by the UA if the UA considers the installation origin as trusted, following the chain of trust mentioned above.
This section is non-normative.
UA should keep in mind that a signed package is way more secure than a signed manifest. A correctly signed package can only be compromised if the private key has been compromised or the cryptographic algorithm. A UA should not trust an installation origin if it does not trust its ability to keep safe its private key.
On the other hands, a signed manifest only proves that the application is genuinly trusted (if the private key was not compromised nor the cryptographic algorithm). Anything else can be compromised given that it lives in the Internet. There is no need to list all possible attacks.
An important difference between a packaged application and a hosted application is the ability to review the code. Any permission granted to a packaged application will be granted to the code inside the package only. That means trusting such application is way easier after a code review, for example.
However, code review for packaged applications could be
        avoided if the installation origin trusts enough an
        application developer. Such developer could get all its
        packaged applications trusted
        without too much risk for the users.
        The same thing colud be done for hosted application except that it would
        be recommended to make sure that the developer has strong
        server security or would not risk any security flaw on
        their servers.
The following CSP policy MUST apply to all trusted applications
        [CSP]:
default-src *; script-src 'self'; object-src
        'none'; style-src 'self'
This puts the following restrictions on web pages part of a trusted application:
This does not restrict any of the following:
There is no way for trusted applications to relax this policy.
At any time, an application MUST be in one of the following states: running, paused, terminated.
An application is running when it has been launched by the UA and has not been put in paused. A running application can transition to paused or terminated states.
If a running application transitions to a
      paused state, the UA MUST fire a simple event named
      pause on the Application object before
      switching its state.
If a running application transitions to a
      terminated state, the UA MUST fire a simple event named
      terminate on the Application object before shutting
      down the application.
An application is paused when the UA stops the execution of an application without terminating it. A paused application SHOULD have all its scripts no longer running, such as rendering, parsing, processing media files and any action that requires CPU and memory or would distract the user. A paused application can transition to running or terminated states.
If a paused application transitions to a
      running state, the UA MUST fire a simple event named
      resume on the Application object after changing
      its state.
An application is terminated when the application has been stopped and is no longer loaded in the system. The state of a terminated application can only be changed to running if the application is launched again.
If a terminated application transitions to
      a runningstate, the UA MUST fire a simple event named
      launch on the Application object after the main
      browsing context is created but before the load
      and DOMContentLoaded events are fired.
The specification currently assumes that one will save important when paused so there is no terminate event when transitionning from pause to terminate.
Do we have real use cases for launch?
        Is firing before load a hard thing to do?
While an application is running, it can be part or fully hidden. The visibility events described in [PAGE-VISIBILITY] MUST be sent when the visibility status of the application changes.
In addition, when the application becomes fully hidden, the UA MAY put the application in a paused state.
DOMRequest interfaceThe DOMRequest interface is
        temporarily hosted by this specification. The Runtime
        and Security Model for Web Applications specificaton
        doesn't plan to keep that guest for ever, this is why it is
        currently staying in an appendix.
This section is non-normative.
Some methods want to return a value or do an action but
      can't do it synchronously, most of the time for performance
      reasons. In that case, most of those methods will use a
      callback mechanism to inform the caller of the success or the
      failure of the action.
      However, this callback mechanism makes the code barely
      readable and there is no common pattern used by all API in
      the Web Platform.
      DOMRequest intend to be used
      instead of those callbacks to make those APIs more
      developer-friendly and help code readability.
The DOMRequest interface is intented
      to be used by asynchronous methods that want to return
      something after performing an action or simply want to inform
      the caller that the action is done.
      It returned request can also be used to inform that an error
      happened during the operation.
A DOMRequest has three state. It is
      whether pending, success or
      error.
      The initial state of a DOMRequest MUST be pending.
      If a DOMRequest receives a
      success message while in the
      pending state, its state MUST change to success and
      SHOULD NOT change
      afterward.
      If a DOMRequest receives an
      error message while in the
      pending state, its state MUST change to error and
      SHOULD NOT change
      afterward.
      If a DOMRequest receives a
      success message or an error message while not in the
      pending state, the message MUST be ignored.
A success message
      SHOULD be sent to the
      DOMRequest when the
      operation is successfuly terminated. The message MAY contain a value which
      MUST be used by the
      result attribute. If the message does not
      contain a value, null MUST be used instead.
As soon as a success message is received,
      readyState MUST return done,
      result MUST return the received value or null as
      explained above and the object MUST NOT change its state and MUST, therefore, ignore all
      following success message and error message.
      Finally, the UA MUST
      fire a simple event named
      success on the object
An error message
      SHOULD be sent to the
      DOMRequest when the
      operation has failed. The message MAY contain a value which MUST be a DOMError object and MUST be used by the error
      attribute. If the message does not contain a value, the UA
      SHOULD find the most
      appropriate DOMError that represents the failure.
As soon as an error message is received,
      readyState MUST return done, error
      MUST return the
      received value the most appropriate error value as explained
      above and the object MUST NOT change its state and MUST, therefore, ignore all
      following success message and error message.
      Finally, the UA MUST
      fire a simple event named
      error on the object.
interface DOMRequest : EventTarget {
    readonly    attribute DOMString    readyState;
    readonly    attribute any          result;
    readonly    attribute DOMError?    error;
    [TreatNonCallableAsNull]
                attribute EventHandler onsuccess;
    [TreatNonCallableAsNull]
                attribute EventHandler onerror;
};
        error of
            type DOMError,
            readonly , nullableerror. Otherwise, it
              MUST return the
              value provided by by the error message. If there was
              no provided value, it SHOULD return the most appropriate
              DOMError that represents the
              failure.
            onerror
            of type EventHandler,onsuccess of type EventHandler,readyState of type DOMString, readonlypending if the
            current state is pending. Otherwise, it
            MUST return
            done.result of
            type any,
            readonlyundefined if the
              current state is not success. Otherwise,
              it MUST return
              the value provided by the success message or
              null if no value was sent with the
              message.
            The following are the event handlers (and their corresponding
        event handler event types) that
        MUST be supported as
        attributes by the DOMRequest objects:
| event handler | event handler event type | 
|---|---|
onerror | 
              error | 
            
onsuccess | 
              success | 
            
Thanks to the Samsung team, especially 金明(Ming Jin), Janusz Majnert and 송정기(Jungkee Song) for their work on the System Application Runtime: Execution and Security Model specification.
Special thanks to Anant Narayanan for his Web Application Manifest Format and Management APIs that this specification reuse shamlesly and to Jonas Sicking for being awesome, as always.