Application Capability

Draft Community Group Report,

More details about this document
This version
https://example.org/app-capability
Latest published version
https://example.org/app-capability
History
Commit history
Editors
Sarven Capadisli (v0.3.1415)
Virginia Balseiro (v0.3.1415)
Published
Modified
Feedback
GitHub dokieli/application-capability (pull requests, new issue, open issues)
Language
English
Document Type
Specification
Version
0.3.1415
Policy
Rule
Offer
Unique Identifier
https://example.org/app-capability#document-policy-offer
Target
https://example.org/app-capability
Permission
Assigner
W3C Foo Bar Baz Group
Action

Abstract

Application Capability (AC) defines a structured description of an application's affordances: the actions it can perform, how to invoke them, and what it requires from the environment to function. Consumers, including servers, web user agents, and applications, can discover and process these descriptions to make informed decisions about accessing, presenting, and interacting with resources.

Status of This Document

This report was published by the Foo Bar Baz Group. It is not a W3C Standard nor is it on the W3C Standards Track. Please note that under the W3C Community Contributor License Agreement (CLA) there is a limited opt-out and other conditions apply. Learn more about W3C Community and Business Groups.

Introduction

This section is non-normative.

Web applications increasingly operate in decentralised environments where resources are stored and served independently of the applications that consume them. A server hosting a resource has no prior knowledge of which applications a user wishes to use to interact with in different ways. Applications and tools such as resource managers, catalogues, and authorisation agents face the same problem: no reliable mechanism exists to discover what an application supports, what resource types it handles, or what web user agent permissions it requires.

This specification addresses that gap by defining a structured description of an application's capabilities and requirements. An Application Capability Description allows an application to declare, at a discoverable location, the following kinds of information:

  • The media types, classes of resources, or shape of resources it can handle;
  • The actions it can perform on those resources, expressed in terms of established action vocabularies;
  • The invocation patterns used to trigger the application, such as a URI Template for opening a resource;
  • The web user agent level permissions and Content Security Policy directives it requires, so that server operators can make informed decisions about authorisation;
  • Descriptive information such as name, description, homepage, and repository, together with an inbox for receiving notifications about the outcome of a requirements review.

This specification is informed by, but distinct from, the following related efforts:

  • Web Application Manifest defines a JSON-based manifest for installed web apps, primarily for Progressive Web Applications (PWA) use cases; its file_handlers member declares media-type handling scoped to installed applications mediated by the browser or operating system;
  • Content Security Policy Level 3 defines the CSP header mechanism that servers use to restrict resource loading;
  • Permissions and Permissions Policy define browser permission models;
  • Data Privacy Vocabulary (DPV) provides vocabulary for expressing data processing purposes and policies;
  • Description of a Project (DOAP) provides vocabulary for describing software projects;
  • Hydra Core Vocabulary describes HTTP API operations and IRI templates in RDF;
  • Web of Things (WoT) Architecture defines a self-description model for network-connected entities, describing interaction affordances of the entity itself; this specification describes applications that act on third-party resources and negotiate host-origin Content Security Policy;
  • registerProtocolHandler (HTML) allows a web application to register as a handler for a custom URL scheme, enabling scheme-based invocation. It requires prior user-mediated browser registration and is scoped to named schemes rather than arbitrary https: IRIs, making it unsuitable as a general mechanism for invoking applications against HTTP resources;
  • Service Workers can intercept fetch requests before they reach the network, allowing query-string parameters to remain client-side and avoiding server disclosure. This requires the service worker to be registered in advance, introducing a bootstrapping dependency that general-purpose invocation cannot rely on.

Where terms from these vocabularies are appropriate, this specification reuses or references them.

Use cases:

  • Resource owner wants to set application-specific content security policies for servers so that users can bring their own applications to hosted resources without the browser blocking them, and without the server issuing overly permissive blanket policies.
  • End-user wants to use a specific application based on its affordances so that they can choose among applications whose declared actions match their intent, without hardcoded file associations.
  • Application developer wants their application's entry in catalogues to update automatically, by publishing one authoritative capability description that catalogues re-fetch, instead of submitting updates to each catalogue manually.

This specification is intended for:

  • Server and storage operators that want to make security and privacy-relevant decisions about which applications can access resources they serve, and to understand the permissions those applications declare they need.
  • Application developers that want to produce or consume structured capability descriptions from their applications so that they can be discovered and invoked by other consumers.

Terminology

This section is non-normative.

The Application Capability specification defines the following terms. These terms are referenced throughout this specification.

Application
A web application that operates on resources identified by IRIs. An application can be deployed at a fixed origin, embedded in markup-based host languages, or as a Web Extension. An application could act as a Sender, a Consumer, or both.
Sender
An implementation that publishes and, where applicable, delivers an Application Capability Description to a Receiver. Typically an application making its identity, capabilities, and requirements known.
Receiver
An implementation that accepts and processes capability descriptions or notifications referencing them. Typically an HTTP server that hosts resources, hosts an inbox, reviews declared requirements, and serves Content Security Policy headers accordingly.
Consumer
An implementation that reads and processes an Application Capability Description, obtained directly from the application's IRI or from a Receiver, in order to discover capabilities, prepare invocations, or inform authorisation decisions.
Capability
A declared affordance of an application: an action that can be triggered by an invocation.
Invocation
The act of triggering an application to perform processes, for example by navigating to a URI constructed from a URI Template. For invocations based on URI Templates, an invocation covers only the URL-loading step; subsequent user-activated operations or UI events within the application are out of scope, even though the capabilities do express these affordances.

Namespaces

The following prefixes and namespaces are used in this specification.

Prefixes and Namespaces
Prefix Namespace Description
rdf http://www.w3.org/1999/02/22-rdf-syntax-ns# [rdf-schema]
rdfs http://www.w3.org/2000/01/rdf-schema# [rdf-schema]
dcterms http://purl.org/dc/terms/ [DC-TERMS]
doap http://usefulinc.com/ns/doap# Description of a Project
hydra http://www.w3.org/ns/hydra/core# [Hydra Core Vocabulary
ldp http://www.w3.org/ns/ldp# [Linked Data Platform]
odrl http://www.w3.org/ns/odrl/2/ [ODRL Vocabulary & Expression 2.2]
dpv https://w3id.org/dpv# [Data Privacy Vocabulary]
ac https://www.w3.org/ns/ac# Application Capability (this specification)

Syntax

This specification uses JSON-LD [JSON-LD11] as the preferred data format, and https://www.w3.org/ns/ac.jsonld as a URI for the JSON-LD context and as a value of the profile parameter used for content negotiation.

Note: The JSON-LD context and the vocabulary outlined in this section are temporarily included here. Once the JSON-LD context document and the vocabulary are published, they will be the normative references.

JSON-LD context (https://www.w3.org/ns/ac.jsonld)
{
  "@context": {
    "@version": 1.1,
    "@protected": true,
    "ac":      "https://www.w3.org/ns/ac#",
    "as":      "https://www.w3.org/ns/activitystreams#",
    "dpv":     "https://w3id.org/dpv#",
    "ldp":     "http://www.w3.org/ns/ldp#",
    "odrl":    "http://www.w3.org/ns/odrl/2/",
    "id":   "@id",
    "type": "@type",
    "Accept": "as:Accept",
    "accept": "ac:accept",
    "action": {"@id": "ac:action", "@type": "@id"},
    "actor": {"@id": "as:actor", "@type": "@id"},
    "browserPermission": "ac:browserPermission",
    "Capability": "ac:Capability",
    "capability": {"@id": "ac:capability", "@type": "@id"},
    "cspDirective": "ac:cspDirective",
    "destination": {"@id": "ac:destination", "@type": "@id"},
    "inbox": {"@id": "ldp:inbox", "@type": "@id"},
    "Invocation": "ac:Invocation",
    "invocation": {"@id": "ac:invocation", "@type": "@id"},
    "login": {"@id": "ac:login", "@type": "@id"},
    "mapping": "ac:mapping",
    "object": {"@id": "as:object", "@type": "@id"},
    "open": {"@id": "ac:open", "@type": "@id"},
    "output": "ac:output",
    "property": {"@id": "ac:property", "@type": "@id"},
    "proxy": {"@id": "ac:proxy", "@type": "@id"},
    "Reject": "as:Reject",
    "Request": "ac:Request",
    "Requirement": "ac:Requirement",
    "requirement": {"@id": "ac:requirement", "@type": "@id"},
    "resourceType": {"@id": "ac:resourceType", "@type": "@id"},
    "search": "ac:search",
    "shape": {"@id": "ac:shape", "@type": "@id"},
    "summary": "as:summary",
    "template": "ac:template",
    "UriTemplateInvocation": "ac:UriTemplateInvocation",
    "variable": "ac:variable"
  }
}

When this context is combined with other JSON-LD contexts, for example ActivityStreams in request notifications, it is listed last so that its term definitions apply.

This context does not define a term for typing the application itself. A capability description subject can carry any type from its host vocabulary (for example as:Application, an OAuth client, a doap:Project, or a Web of Things Thing) or none at all; see Capability Description.

The ac vocabulary defines the following classes and properties. Terms mapped to other vocabularies, such as as and ldp, retain the semantics of their defining specifications.

Classes
Term IRI Description
Accept, Reject as:Accept, as:Reject Outcome notification types (Activity Vocabulary).
(none) ac:Application A web application that operates on resources identified by IRIs. Not aliased in the context: a capability description subject can use this class, a host vocabulary's type, or none at all.
Capability ac:Capability A declared affordance of an application: an action that can be triggered by an invocation. See Capability.
Invocation ac:Invocation An abstract class describing one mechanism by which a capability is triggered. See Invocation.
Request ac:Request A notification asking a Receiver to review information concerning an application and act on it. See Request Notification.
Requirement ac:Requirement A declaration of something the application needs from its environment. See Requirement.
UriTemplateInvocation ac:UriTemplateInvocation An Invocation by navigation to an IRI constructed from a URI Template. See URI Template Invocation.
Properties
Term IRI Description
accept ac:accept Media types a capability accepts as input.
action ac:action The action a capability affords, preferably from a controlled and shared vocabulary.
actor, object, summary as:actor, as:object, as:summary Properties used in request notifications (Activity Vocabulary).
browserPermission ac:browserPermission A browser permission name the application could request at runtime.
capability ac:capability Links an application to one or more Capability declarations.
cspDirective ac:cspDirective A CSP directive the host server ought to include with responses of resources the application creates, modifies, or opens.
destination ac:destination The IRI to deliver or save the result of an action to.
login, open, output, proxy, search ac:login, ac:open, ac:output, ac:proxy, ac:search Invocation variables parameterising the IRI used to invoke an application. See Invocation Variables.
inbox ldp:inbox The IRI of a Linked Data Notifications inbox associated with the application.
invocation ac:invocation Links a capability to one or more Invocations describing how to trigger it.
mapping ac:mapping Mapping nodes pairing a template variable with its defining property.
output ac:output Media types of the result produced by a capability's action.
property ac:property The property defining the semantics of a template variable.
requirement ac:requirement Links an application to one or more Requirement declarations.
resourceType ac:resourceType IRIs identifying the classes of resource a capability applies to.
shape ac:shape IRIs identifying shapes for a resource that a capability applies to.
template ac:template An RFC 6570 URI Template expressing the invocation-specific part of the IRI.
variable ac:variable The string name of a variable as used in a template.

Conformance

This section describes the conformance model of the Application Capability specification.

Normative and Informative Content

All assertions, diagrams, examples, and notes are non-normative, as are all sections explicitly marked non-normative. Everything else is normative.

The key words "MUST", "MUST NOT", "SHOULD", and "MAY" are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.

The key words "strongly encouraged", "strongly discouraged", "encouraged", "discouraged", "can", "cannot", "could", "could not", "might", and "might not" are used for non-normative content.

Specification Category

The Application Capability specification identifies the following Specification Category to distinguish the types of conformance: content/data (the capability description format), notation/syntax (the URI Template invocation syntax), and protocol (the discovery and notification interactions between Senders, Receivers, and Consumers). These categories correspond to the severable modules identified in the Status of This Document.

Classes of Products

The Application Capability specification identifies the following Classes of Products for conforming implementations.

A single implementation can fulfil more than one role simultaneously.

Capability Description
The structured document describing a web application's capabilities and requirements.
Receiver
An implementation (typically a responding agent such as a server) that accepts HTTP requests to provide a representation of a Capability Description. Receivers also accept notifications to their inbox about capability descriptions so that the needs of an application can be reviewed and processed, such as applying CSP headers or addressing authorisation needs.
Consumer
An implementation that reads and processes a Capability Description in order to discover application's capabilities and requirements, construct invocation instructions, or surface other application affordances.
Sender
An implementation that delivers a Capability Description to a Receiver's inbox.

Interoperability

This document can be subdivided into the following modules:

In this specification, interoperability occurs between the classes of products defined by this specification: Consumer–CapabilityDescription, Consumer–Receiver, and Sender–Receiver.

Consumer–Capability Description interoperability
Interoperability of implementations for Consumer and Capability Description is tested by evaluating the description's conformance to the data model and processing of descriptions.
Consumer–Receiver interoperability
Interoperability of implementations for Consumer and Receiver is tested by evaluating an implementation's ability to request and respond to HTTP messages.
Sender–Receiver interoperability
Interoperability of implementations for Sender and Receiver is tested by evaluating an implementation's ability to request and respond to HTTP messages.

Discovery

The starting point for discovery is a web resource containing a capability description. How the subject URI of an application is obtained is not constrained by this specification.

Capability Description is a subject of capability or requirement statements. A Consumer that obtains such a URI treats it as the subject of the capability description and dereferences it, directly or via redirect, requesting a format that carries the description, such as application/ld+json. In the case of a fragment URI, the Consumer fetches the document at the base IRI and locates the subject within it by matching the full URI. A Consumer can obtain a capability description from a Receiver that has accepted and stored it from a Sender.

Example: Discovery of a capability description resource.
GET https://app.example/
Accept: application/ld+json

HTTP/1.1 200 OK
Content-Type: application/ld+json

Capability Description Data Model

Capability Description

The following properties are defined by this specification for the discovery of an application's capabilities and requirements.

capability
Links the application to one or more Capability declarations.
requirement
Links the application to one or more requirement declarations.
inbox
The IRI of a Linked Data Notifications inbox to which a Receiver can deliver notifications about the outcome of a requirements review. Applications that wish to receive such notifications SHOULD publish this property.

The capability and requirement properties can be attached to any resource identifying an application; the Application type is not required for conformance. Consumers process these properties by subject, consistent with Discovery, which targets the subject of capability or requirement statements. See Embedding in Other Description Formats for usage alongside other vocabularies and within non-RDF formats.

Example: Application capability description in JSON-LD. One capability per action; capabilities can include their invocations. The type and descriptive properties come from host vocabularies (here ac:Application and as:name); neither is required.
{
  "@context": "https://www.w3.org/ns/ac.jsonld",
  "id": "https://app.example/#i",
  "type": "ac:Application",
  "as:name": "Example App",
  "inbox": "https://app.example/inbox/",
  "capability": [
    "https://app.example/#capability-view",
    "https://app.example/#capability-edit",
    "https://app.example/#capability-transform-html"
  ],
  "requirement": [
    "https://app.example/#requirement-scripts",
    "https://app.example/#requirement-styles",
    "https://app.example/#requirement-connect",
    "https://app.example/#requirement-notifications"
  ]
}

Capability

A Capability is a resource of type Capability that declares one action an application can perform, the media types (if any) the action applies to, and how to invoke it.

Because capabilities are identified by IRIs, they can be shared across applications. An application's capability description can reference a capability IRI published elsewhere (for example, a well-known capability defined by a community or standard) rather than defining its own. Multiple applications linking to the same capability IRI signal that they support the same action under the same terms.

accept
Zero or more media types (RFC 2046) that this capability accepts as input.
resourceType
Zero or more IRIs identifying the classes of resource (e.g., rdf:type) this capability applies to.
shape
Zero or more IRIs identifying shapes (e.g., SHACL) for a resource that this capability applies to. The interpretation of a shape is bound to the capability's action: for a display or edit action the shape describes the accepted input; for a transform action it describes the accepted source. Shape-based matching is stricter than accept or resourceType matching, and Consumers can fall back to the coarser criteria when shape validation is unavailable.
action
The action the application can perform per capability. Each capability declares an action. Recommended practice is to use values from a controlled and shared vocabulary (such as ODRL actions). An application that affords multiple actions declares multiple capabilities, which can share an invocation by reference.
invocation
Links the capability to one or more invocations describing how to trigger it.
destination
The IRI to deliver or save the result to. Used when the action produces an output.
output
Zero or more media types of the result produced by the action. An application that can produce multiple output formats declares a separate Capability for each format. Consumers match the desired output format against the declared output to select the appropriate Capability, then pass that format as the output invocation variable.

Matching semantics: a Consumer performing a given match never selects a capability that declares no criterion of that kind. A media-type match ignores capabilities without accept, an output-format match ignores capabilities without output, a resource-type match ignores capabilities without resourceType, and a shape match ignores capabilities without shape. Capabilities that declare none of these criteria are selected by action. Consumers SHOULD ignore capabilities whose declared action, accept, or resourceType they do not recognise rather than treat them as errors.

Note: action describes what the application affords once invoked. It is unrelated to the HTTP GET used for navigation and to the methods the application later uses to manipulate the resource, which are outside the scope of this specification.

Example: A capability that advertises what the application can do without declaring how to invoke it. Consumers can surface it in a UI (e.g. a catalogue entry) but cannot construct an invocation IRI from it.
{
  "@context": "https://www.w3.org/ns/ac.jsonld",
  "id": "https://app.example/#capability-open",
  "type": "Capability",
  "action": "odrl:display"
}
Example: An open capability with an invocation. No accept, output, or destination: the application opens any resource the Consumer provides.
{
  "@context": "https://www.w3.org/ns/ac.jsonld",
  "id": "https://app.example/#capability-open",
  "type": "Capability",
  "action": "odrl:display",
  "invocation": "https://app.example/#invoke-open"
}
Example: Two capabilities sharing one invocation by IRI reference. The Consumer selects by action (display versus modify), then follows the shared invocation IRI.
{
  "@context": "https://www.w3.org/ns/ac.jsonld",
  "id": "https://app.example/#capability-view",
  "type": "Capability",
  "accept": ["text/html", "text/markdown"],
  "action": "odrl:display",
  "invocation": "https://app.example/#invoke-open"
}
{
  "@context": "https://www.w3.org/ns/ac.jsonld",
  "id": "https://app.example/#capability-edit",
  "type": "Capability",
  "accept": ["text/html", "text/markdown"],
  "action": "odrl:modify",
  "invocation": "https://app.example/#invoke-open"
}
Example: A transform capability with all properties. The Consumer matches on accept and output format to select this capability, then invokes it with the resource to transform; the application delivers the result to the declared destination.
{
  "@context": "https://www.w3.org/ns/ac.jsonld",
  "id": "https://app.example/#capability-transform",
  "type": "Capability",
  "accept": "text/markdown",
  "action": "odrl:transform",
  "output": "text/html",
  "destination": "https://storage.example/output/",
  "invocation": "https://app.example/#invoke-transform"
}

Invocation

An Invocation is a resource describing one mechanism by which a capability is triggered. Invocation is an abstract class; every Invocation is typed with one of its subclasses. This specification defines UriTemplateInvocation. Other invocation kinds can be described by defining additional subclasses of Invocation; this specification does not constrain their form.

A capability can declare multiple invocations. A Consumer selects an invocation according to its own deployment context and not by document order. Consumers MUST ignore invocations of a type they do not recognise.

An application ultimately decides whether to carry out a given invocation and in which order invocations are processed. An error with one invocation could prevent related invocations from being fulfilled.

URI Template Invocation

A UriTemplateInvocation describes invocation by navigation: the Consumer expands the template, resolves the result against the application's deployment IRI, and navigates the user agent to it via HTTP GET. The user agent performs a GET request; any fragment portion of the URI is processed client-side by the loaded application and is not included in the request.

template
An RFC 6570 URI Template expressing the invocation-specific part of the IRI. The Consumer resolves the expanded result against the application's deployment IRI to obtain the full invocation IRI, allowing the same template to work regardless of where the application is deployed. Variable names in the template correspond to the property names defined in the Invocation Variables section; variables with other names require an explicit mapping entry. Variables MUST appear in name-bearing form, pairing each variable's name with its value explicitly (for example, #open={open}), so that the receiving application can identify each value and the invoked capability. Values produced by simple expansion are percent-encoded, satisfying the requirement that resource IRIs travel percent-encoded (RFC 3987).
mapping
Zero or more mapping nodes, each pairing a variable (the string name used in the template) with a property (the property that defines its semantics). For variables whose names match a property name defined in the Invocation Variables section, the mapping can be omitted. An explicit mapping is required for variables not defined in this specification; see Invocation Extension.

Encoding rules: in the expanded invocation IRI, & is the sole pair separator and = the sole name/value separator; receiving applications MUST NOT treat ; as a separator. Because simple expansion percent-encodes sub-delimiters within values, every unencoded & and = in the result is structural. Receiving applications parse fragment content with query-string semantics. A variable can carry multiple values; the canonical wire form repeats the name for each value (open=uri1&open=uri2). RFC 6570 simple expansion of a list ({open*}) produces comma-separated values without name repetition and is not name-bearing; templates that need a variable to carry multiple values are encouraged to use an expansion operator whose output is name-bearing.

Receiver rules: receiving applications MUST treat all invocation parameter values as untrusted input and validate or sanitise them before acting on them. A login value identifies who to authenticate as and never substitutes for authentication; open and other IRI-valued variables are untrusted IRIs to be retrieved with the user's own authorisation, with server-side receivers guarding against request forgery. Unknown variable names MUST be ignored and MUST NOT be treated as errors. Receipt of an invocation implies nothing about grants or permissions; it is a request.

Note: URI Fragment

Passing invocation parameters via the fragment identifier is a pragmatic convention rather than strict conformance with Fragment [RFC3986], which defines fragment semantics as determined by the media type of the retrieved representation. The convention is adopted here because fragment content is not included in HTTP request targets (RFC 9110), preventing the application host from learning the IRI of the resource being opened. In practice, the WHATWG HTML specification's hashchange event allows single-page applications to read fragment-encoded parameters client-side without a page reload. As noted in the Introduction, no existing specification defines a general-purpose mechanism for client-side application invocation via URI; this convention fills that gap and can be superseded by a more principled approach in future work.

Note: URI Query

A template can carry invocation variables in the query (?) component instead of the fragment (#) component, but the two are not equivalent. The query component is part of the data that identifies a resource (Query [RFC3986]), and it is included in the request target sent to the server (RFC 9110). Each expansion of a query-form template therefore identifies a distinct resource on the application's host, and the expanded values, including the IRI of the resource being opened, are disclosed to that host. A fragment, by contrast, identifies a secondary resource relative to the retrieved representation and is not transmitted in the request.

Applications are encouraged to use the fragment form so that invocation parameters are processed entirely client-side and, when the application is already loaded, without a further request to its host. Implementations that process invocations server-side can use the query form, accepting that the parameters become part of the request; see Threat Model for the associated disclosure.

Example: Fragment-form invocation and its expansion, opening a resource for viewing.
{
  "@context": "https://www.w3.org/ns/ac.jsonld",
  "id": "https://app.example/#invoke-open",
  "type": "UriTemplateInvocation",
  "template": "#open={open}"
}

Resolved against application IRI https://app.example/ with
     open = https://data.example/article :

https://app.example/#open=https%3A%2F%2Fdata.example%2Farticle
Example: Fragment-form invocation combining open and output: the Consumer selects the transform capability whose output matches the desired output value, then constructs the IRI with both variables.
{
  "@context": "https://www.w3.org/ns/ac.jsonld",
  "id": "https://app.example/#invoke-transform",
  "type": "UriTemplateInvocation",
  "template": "#open={open}&output={output}"
}

Resolved against application IRI https://app.example/ with
     open   = https://data.example/report.md
     output = text/html :

https://app.example/#open=https%3A%2F%2Fdata.example%2Freport.md&output=text%2Fhtml

Invocation Variables

This section defines properties in this vocabulary. Each property's local name is both the key for that property under the JSON-LD context and the canonical variable name in URI template expressions. For example, the ac: vocabulary property whose local name is open appears as the JSON-LD key open and as the URI template variable {open}. Applications SHOULD use these properties when the intended semantics match, so that Consumers can resolve variable meaning by property rather than by string convention alone. For variables not defined here, applications can declare a mapping that pairs the variable name used in the template with the defining property. A Consumer that encounters a variable whose property it does not recognise SHOULD still expand the template with the variables it does recognise.

The properties defined here parameterise the IRI used to invoke an application. They do not represent user-activated operations or UI events within the running application; those are the concern of the user agent and the relevant browser specifications.

open
The IRI of a resource to open. The application renders, displays, or edits the identified resource.
search
A query or search expression submitted to the application. The format and interpretation are application-defined: the value can be a freetext string, a structured query, or any other expression the application understands.
output
The media type of the desired output. Used when invoking a transform capability: its value ought to match the output declared by the selected Capability. A Consumer that wants HTML output selects the capability declaring output: text/html and passes output=text/html in the invocation IRI.
login
The IRI of a user profile (e.g. a WebID) identifying who to authenticate as. This is a hint, not authentication: the application remains responsible for authenticating the user.
proxy
The URL of a proxy through which the application is intended to route network requests. This variable has no effect on its own; when present alongside open or other variables that involve fetching a resource, the application uses the proxy URL for those requests.

Additional invocation variables can be introduced as described in Invocation Extension.

Requirement

A requirement is a resource of type Requirement that declares one environmental requirement an application has: a CSP directive the host server ought to include, or a browser permission the application can request at runtime. Where a Capability declares what an application can do, a Requirement declares what the environment needs to provide for the application to function. An application links to one or more Requirement declarations via requirement. Declaring requirements as discrete resources allows each requirement to carry its own purpose annotation and to be individually identified and referenced.

Application requirements serve two roles in this specification. As declarative self-description, they are readable by any Consumer: a catalogue ranking applications by permission footprint, a user agent presenting requirements to a user before invocation, or an authorisation agent reviewing access. As protocol input, they are delivered by a Sender to a Receiver, which reviews and acts on them by applying CSP headers or addressing declared authorisation needs; this active use is described in the Notifications section. The two roles are independent: a Consumer can read and act on declared requirements without any Sender–Receiver exchange having taken place.

cspDirective
One or more CSP directives (CSP Level 3 syntax) that the host server ought to include with responses of resources the application creates, modifies, or opens, so that the content of those resources functions as intended for any consumer of them.
browserPermission
One or more browser permission names (Permissions API) the application can request at runtime.
dpv:hasPurpose
Links to a DPV purpose class expressing why the application needs the declared permissions, supporting transparency and informed review.
Example: A requirement declaring a CSP directive, with its purpose annotation. One declaration per requirement; the application's other CSP requirements (styles, connect) follow the same pattern.
{
  "@context": "https://www.w3.org/ns/ac.jsonld",
  "id": "https://app.example/#requirement-scripts",
  "type": "Requirement",
  "cspDirective": "script-src 'self' https://app.example/scripts/app.js",
  "dpv:hasPurpose": { "id": "dpv:ServiceProvision" }
}

Note: Scope of CSP Requirements

A CSP directive governs the document it is served with. For example, an article created by the application that includes <script src="https://app.example/scripts/app.js"> depends on the script-src directive the Receiver serves with it, whichever application opens it; an embedded frame likewise depends on frame-src. Where a resource embeds the application, the application's own requirements are part of that content's needs: the embedded application depends on directives such as connect-src for the resources it reaches from within the article. The declaration can also inform a server that hosts, or is considering hosting, the application itself, where the application is the document. It does not concern resources that an application deployed at its own origin accesses through cross-origin requests: CSP served with a fetched resource has no effect on the fetching application; that interaction is governed by Cross-Origin Resource Sharing and access control.

Example: A requirement declaring a browser permission, with its purpose annotation.
{
  "@context": "https://www.w3.org/ns/ac.jsonld",
  "id": "https://app.example/#requirement-notifications",
  "type": "Requirement",
  "browserPermission": "notifications",
  "dpv:hasPurpose": { "id": "dpv:ServiceProvision" }
}

Embedding in Other Description Formats

This section is non-normative.

Because capability and requirement attach to any resource identifying an application, an application already described by another vocabulary, e.g., Application Manifest, Web Extensions Manifest, Description of a Project, Activity Vocabulary, schema.org, Web of Things, OAuth, can include these properties on its existing subject without restructuring:

Example: Capability and requirements statements on a subject described by another vocabulary.
{
  "@context": [
    "https://www.w3.org/ns/solid/oidc-context.jsonld",
    "https://www.w3.org/ns/ac.jsonld"
  ],
  "id": "https://app.example/#this",
  "client_name": "Example App",
  "capability": "https://app.example/#capability-open",
  "requirement": "https://app.example/#requirement-scripts"
}

Description formats that are not JSON-LD can carry a capability description as a self-contained member with their own reference, whose value is a JSON-LD object using this specification's context. Processors of the host format ignore the member; Consumers extract and process it as JSON-LD.

Example: Capability description embedded in a Web Application Manifest.
{
  "name": "Example App",
  "start_url": "/",
  "ac": {
    "@context": "https://www.w3.org/ns/ac.jsonld",
    "id": "https://app.example/#this",
    "capability": "https://app.example/#capability-open",
    "requirement": "https://app.example/#requirement-scripts"
  }
}

In both cases, Discovery is unaffected: the application IRI remains the subject of the capability and requirement statements.

Notifications

Consumers and Receivers can discover and act on a capability description entirely on their own. In addition, a Sender can proactively communicate with a Receiver about an application by delivering a notification to the Receiver's inbox. A notification of this kind expresses a request: it asks the Receiver to review information concerning an application and to act within its own authority, for example by serving the Content Security Policy headers an application requires, or by authorising an agent to access a resource.

The request notification is a general mechanism. This section describes two kinds of information a request can carry, a requirements review and an access request, but a request is not limited to these.

A Receiver that wishes to receive request notifications advertises an inbox IRI in its own resource description or in error responses (see Error Response Inbox Discovery).

Request Notification

A Sender uses a request notification to explain its needs to a Receiver. When the request concerns an application, the notification includes the application IRI, the subject of the application's capability description, which the Receiver can dereference (see Discovery). This specification does not constrain which property carries the application IRI; in the examples below it appears as object. When the request pertains to particular resources, the notification includes their IRIs. A request can include or reference one or more objects describing what is requested; this specification does not constrain the vocabulary of those objects.

Example: A request notification. The actor makes the request, the object identifies the application, and the target identifies the resource concerned. Objects describing what is requested vary by the kind of request; see Requirements Review and Access Request.
{
  "@context": [
    "https://www.w3.org/ns/activitystreams",
    "https://www.w3.org/ns/ac.jsonld"
  ],
  "type": "Request",
  "actor": "https://agent.example/#i",
  "object": "https://app.example/#i",
  "target": "https://example.org/article"
}

Note: Access control on the inbox, sender authentication, payload constraints, and abuse mitigation are orthogonal to this interaction and are handled by the underlying notification and access control mechanisms (see Security Considerations).

The Receiver's response to a delivery concerns the notification itself: accepting the HTTP request creates the notification in the inbox, independently of any decision about its contents. The Receiver then reviews the stored request, by operator decision or by automated policy, and records the outcome. The Receiver is encouraged to deliver a notification indicating the outcome to an inbox associated with the request: the inbox stated in the request notification if any, otherwise the inbox in the application's capability description. The outcome notification identifies the request notification so that the two can be correlated.

Example: Outcome notification. The object references the request notification resource created in the Receiver's inbox; Accept or Reject indicates the outcome.
{
  "@context": [
    "https://www.w3.org/ns/activitystreams",
    "https://www.w3.org/ns/ac.jsonld"
  ],
  "type": "Accept",
  "actor": "https://example.org/#i",
  "object": "https://example.org/inbox/d3aa37",
  "target": "https://example.org/article",
  "summary": "Requested access modes granted."
}

Requirements Review

An application embedded in or injected into an arbitrary HTML document depends on the server hosting that document to issue appropriate Content Security Policy (CSP) headers. Without server cooperation, the browser can block scripts, fetches, or other operations the application requires in order to function. A request can ask a Receiver to review the requirements declared in an application's capability description and act on them, for example by including approved CSP directives in responses served in the context of that application.

A Sender publishes a capability description in which the application links to one or more requirement declarations via requirement. The Receiver obtains the application IRI, whether at registration time, during policy setup, on first encounter with the application, or from a request notification, dereferences the capability description, and reviews the declared requirements as described in Request Notification. When serving responses in the context of that application, the Receiver includes CSP headers reflecting the approved requirements.

Example: A capability description declaring CSP requirements, and a server response reflecting the approved requirements in responses served in the context of the application.
{
  "@context": "https://www.w3.org/ns/ac.jsonld",
  "id": "https://app.example/#i",
  "type": "ac:Application",
  "inbox": "https://app.example/inbox/",
  "requirement": [
    {
      "id": "https://app.example/#requirement-scripts",
      "type": "Requirement",
      "cspDirective": "script-src 'self' https://app.example/scripts/app.js",
      "dpv:hasPurpose": { "id": "dpv:ServiceProvision" }
    },
    {
      "id": "https://app.example/#requirement-connect",
      "type": "Requirement",
      "cspDirective": "connect-src 'self' https:"
    }
  ]
}
HTTP/1.1 200 OK
Content-Type: text/html
Content-Security-Policy: script-src 'self' https://app.example/scripts/app.js;
                         connect-src 'self' https:

Access Request

A request can express that an agent seeks access to a resource. An access request identifies the agent for whom access is requested, the resource or resources concerned, and the operations desired. This specification does not require a particular authorisation or policy vocabulary for expressing the requested access; the Receiver evaluates the request and enacts the outcome through its own access control mechanism. The representation and enforcement of any resulting authorisation, and the review process itself, are outside the scope of this specification.

A common flow, continuing from Error Response Inbox Discovery: an agent using an application attempts an operation on a resource, receives a 403 response advertising an inbox, and delivers an access request to that inbox describing the access it needs. The review is decoupled from the inbox itself: any application authorised to act on the Receiver's behalf can process stored access requests and enact outcomes.

Example: Access request whose object expresses the desired authorisation using Web Access Control.
{
  "@context": [
    "https://www.w3.org/ns/activitystreams",
    "https://www.w3.org/ns/ac.jsonld",
    { "acl": "http://www.w3.org/ns/auth/acl#" }
  ],
  "type": "Request",
  "actor": "https://agent.example/#i",
  "target": "https://example.org/article",
  "object": {
    "type": "acl:Authorization",
    "acl:agent": { "id": "https://agent.example/#i" },
    "acl:accessTo": { "id": "https://example.org/article" },
    "acl:mode": [ { "id": "acl:Read" }, { "id": "acl:Write" } ]
  }
}
Example: Access request expressed as an ODRL Request policy. The purpose constraint uses the same DPV purposes as the application's requirement declarations.
{
  "@context": "http://www.w3.org/ns/odrl.jsonld",
  "type": "Request",
  "uid": "https://app.example/requests/e3b7",
  "permission": [{
    "assignee": "https://agent.example/#i",
    "target": "https://example.org/article",
    "action": ["read", "modify"],
    "constraint": [{
      "leftOperand": "purpose",
      "operator": "eq",
      "rightOperand": "https://w3id.org/dpv#ServiceProvision"
    }]
  }]
}

Error Response Inbox Discovery

When a Sender makes an HTTP request and receives a 4xx response, it can discover the Receiver's inbox from that response and send a notification referencing its capability description. This allows a Sender to inform the Receiver of its access modes, declared CSP directives, browser permissions, and processing purposes in response to a rejected request, rather than waiting for the Receiver to fetch the description independently.

A Receiver that wishes to advertise its inbox in a 4xx response MUST do exactly one of the following:

  • Include a Link header with a rel value of http://www.w3.org/ns/ldp#inbox.
  • Return a representation whose encoded graph contains a relation of type http://www.w3.org/ns/ldp#inbox, where the subject is the target resource and the object is the inbox IRI.

A Sender that receives a 4xx response SHOULD attempt to discover the inbox: first from the Link header; if no inbox is found there, from the response body parsed as an RDF representation. If an inbox is discovered, the Sender delivers a notification to that inbox conveying its application IRI. The Receiver can then dereference the capability description from that IRI and follow the review process described in Request Notification.

A Consumer that has obtained a Sender's capability description, whether directly from the Sender's IRI or via a Receiver, can use it to prepare invocations independently of whether the Sender–Receiver interaction has taken place.

Example: 403 response advertising an inbox. The Sender discovers the inbox and delivers a notification referencing its capability description.
PUT /article HTTP/1.1
Host: example.org
Content-Type: text/html;charset=utf-8

HTTP/1.1 403 Forbidden
Link: <https://example.org/inbox/>; rel="http://www.w3.org/ns/ldp#inbox"

Extensions

Extensions incorporate additional features beyond what is defined in this specification. Extensions MUST NOT contradict nor cause the non-conformance of functionality defined in this specification.

Invocation Extension

This section is non-normative.

Applications can introduce invocation variables beyond those defined in Invocation Variables by declaring a mapping that pairs the variable name used in the template with a property that defines its semantics. Consumers that do not recognise the property still expand the template with the variables they do recognise, and receiving applications treat extension variable values as untrusted input, per the receiver rules in URI Template Invocation.

The following variables illustrate invocation extensions:

graph
The IRI of an RDF dataset or named graph to load and render.
style
The IRI of a stylesheet to apply when rendering the resource.
state
An application-defined value encoding the UI state in which to open the application, such as which panels are active or the current view mode. The encoding and interpretation of this variable are not further specified.
Example: An extension variable declared via an explicit mapping. The application defines the property that gives the variable its semantics; Consumers that recognise the property can supply a value, and receiving applications treat it as untrusted input like any other variable.
{
  "@context": "https://www.w3.org/ns/ac.jsonld",
  "id": "https://app.example/#invoke-graph",
  "type": "UriTemplateInvocation",
  "template": "#graph={graph}",
  "mapping": [
    {
      "variable": "graph",
      "property": "https://vocab.example/graph"
    }
  ]
}

Considerations

This section details security, privacy, accessibility, internationalization considerations, and application considerations.

Some of the normative references with this specification point to documents with a Living Standard or Draft status, meaning their contents can still change over time. It is advised to monitor these documents, as such changes might have implications.

Security Considerations

This section is non-normative.

Threat Model

This threat analysis follows the framework of the W3C Threat Model for the Web and draws on terminology from the W3C Privacy Principles, including web origin boundary, user-mediated permissions, data minimization, purpose limitation, secondary uses, and disloyalty.

Feature Threat Mitigation
#discovery Description substitution. A web attacker at a different origin serves a capability description purporting to represent a Sender at another origin, causing Consumers or Receivers to act on a fraudulent description and potentially grant privileges to the wrong party. This attack exploits the gap between a description's claimed subject and its serving origin, crossing the web origin boundary that ordinarily separates content by origin. Verify that the description is served from an IRI consistent with the Sender's declared identity before acting on its contents. The serving IRI, not human-readable metadata, is the primary trust anchor.
#capability-description Application impersonation. A malicious application copies a legitimate application's human-readable metadata (name, description, homepage) to gain undeserved trust from Receivers and Consumers. Human-readable metadata is not a security invariant; the serving origin is. The IRI at which the description is served is the primary trust anchor. Receivers and Consumers verify the description origin, not merely its human-readable content.
#discovery Description tampering. A network attacker modifies a capability description in transit to expand declared CSP directives or browser permissions beyond what the Sender published, violating the integrity of the Sender's declared requirements. Fetch descriptions only over authenticated, encrypted transport (HTTPS) to preserve integrity in transit.
#requirement Permission inflation. A Sender declares broader CSP directives or browser permissions, or requests broader access, than its function requires, violating the principle of data minimization and attempting to acquire unnecessary access. If approved without scrutiny, this undermines the user-mediated permissions model: the user's expectation is that declared permissions reflect genuine need. Receivers treat declarations as input to operator review, not as automatic grants. Senders are strongly encouraged to declare only the minimum permissions necessary for their intended function.
#notifications Post-approval behavior change. A Sender presents minimal declarations during Receiver review, then changes its application to exploit the approved CSP headers, permissions, or access after trust is established. This is a form of disloyalty: the application acts against user interests under cover of legitimacy it has manufactured through the review process. Receivers re-fetch and re-review capability descriptions periodically. Any change to declared requirements ought to trigger renewed review rather than automatic acceptance.
#discovery Stale description. A Consumer or Receiver acts on a cached capability description that no longer reflects the Sender's current declared requirements, either because the Sender has reduced its claims (lower risk) or expanded them (higher risk). Apply standard HTTP caching controls. Receivers re-fetch before or after operator review and treat expired descriptions as requiring re-verification.
#discovery Capability description fetch as tracking. A Sender that logs requests to its capability description endpoint can observe which Consumers and Receivers are interested in its application, enabling cross-context recognition and surveillance of deployment and usage patterns. Fetching a capability description could itself constitute processing of personal data if the requesting party is identifiable. This is an instance of automation asymmetry: the Sender collects usage data automatically while the Consumer or Receiver has no corresponding visibility into what is logged. Consumers and Receivers are encouraged to use privacy-preserving fetching practices (no credentials, minimal request headers). Data minimization applies to the description itself: capability descriptions ought to disclose only what is necessary for discovery and invocation.
#uri-template-invocation Invocation IRI disclosure. This specification's convention is fragment-form templates, whose content is not transmitted in HTTP requests. If a Sender nevertheless declares a template that expands variables into the query component, the target resource IRI is disclosed to the application's host server. Because the resource IRI might identify personal data or reveal browsing behaviour, this is a privacy consideration for any capability description declaring such a template. Prefer fragment-form templates. Senders declaring query-form templates ought to document the disclosure and ensure it is acceptable given the application's context and the user's expectations.
#uri-template-invocation Open redirect via invocation. A server-side application using a query-form template can be exploited as an open redirect if it uses an invocation variable such as open as an unvalidated redirect target, enabling phishing attacks that leverage the trusted application's domain. A user following such a redirect can be deceived by the legitimate origin displayed in the address bar. Receiving applications validate all invocation parameter values before using them as redirect targets or in navigation. Redirect targets ought to be checked against an allowlist or restricted to expected origin patterns.
#uri-template-invocation, #invocation-extension Server-side request forgery via invocation. A server-side application that fetches the resource identified by an open parameter or another IRI-valued invocation variable might be directed to private network resources or internal addresses not publicly reachable, violating the web origin boundary that ordinarily prevents web content from accessing private network infrastructure. Receiving applications validate invocation IRIs against an allowlist or deny private and internal address spaces before fetching, consistent with the Private Network Access specification.
#error-response-inbox-discovery Inbox forgery. A Sender declares a third party's inbox as the Receiver's endpoint, misdirecting notifications across trust boundaries; or a network attacker forges approval notifications to deceive a Sender into believing its declared requirements have been acted on. Discover the Receiver's inbox from the Receiver's own responses (Link headers, response body), not from an untrusted source. Treat approvals as requiring out-of-band verification where the stakes are high.
#notifications Inbox flooding. Advertising an inbox invites unsolicited notifications: a hostile party can deliver bulk or junk request notifications, exhausting storage or flooding the operator review process, in effect a denial of service on the Receiver's attention. Inexpensive, disposable sender identities lower the cost of this abuse. Inboxes are ordinary resources: Receivers can require authenticated senders, restrict delivery through access control (e.g., append-only), rate limit per sender identity, validate payloads against expected shapes, apply allowlists or trust frameworks, segregate notifications from unrecognised senders, or provision short-lived or per-request inboxes. These mitigations layer on the inbox model without changing the interaction.
#requirements-review CSP allowlist scope creep. CSP directives approved for one application could contain origins or patterns broad enough to benefit other applications on the same host, or to enable cross-site scripting if an approved origin can serve attacker-controlled content, widening the attack surface of the entire Receiver origin. Receivers evaluate approved directives in the context of the full host document, not just the specific application. Prefer narrow, specific source expressions over broad origin patterns, consistent with the principle of least privilege.
#requirement Purpose mismatch. A Sender uses granted permissions for purposes inconsistent with its declared dpv:hasPurpose, a form of secondary use or disloyalty. For example, an application might use a storage-access permission granted for document editing to exfiltrate user data for profiling. Purpose specification via dpv:hasPurpose supports transparency and informed review. Enforcement depends on operator policy and legal mechanisms such as data protection law, which are outside the scope of this specification.
#uri-template-invocation, #invocation-extension Invocation parameter injection. A hostile party supplies invocation values (a forged login identity, or a script-injecting stylesheet IRI or application-state value supplied via extension variables) that a receiving application processes without validation. This is an injection attack: untrusted input crosses a trust boundary and is treated as trusted. Receiving applications treat all invocation parameters as untrusted input and validate or sanitise them before use, as required by the receiver rules in URI Template Invocation.
#capability-description Statement injection. A Consumer or Receiver that merges a fetched capability description into a shared store could pick up unrelated statements about other subjects, causing behaviour elsewhere to change based on untrusted input. Isolate processed capability descriptions from other trusted data, or restrict the accepted statements to those describing the description's declared IRI.

Consumers and Receivers are strongly encouraged to verify that a capability description is served from an IRI consistent with the Sender's declared identity before acting on its contents, in order to mitigate the risk of a third party substituting a fraudulent description.

Senders are strongly encouraged to publish capability descriptions at a location that is under the Sender's control and not publicly writable, so that Consumers and Receivers can rely on the serving IRI as a trust anchor.

Consumers and Receivers are strongly encouraged to fetch capability descriptions only over authenticated, encrypted transport (HTTPS), to mitigate tampering in transit.

Receivers are encouraged to re-fetch capability descriptions periodically and, when a Sender's declared requirements have changed since a prior review was recorded, to treat the change as requiring renewed review rather than continuing to act on the earlier decision.

Senders are strongly encouraged to declare only the minimum CSP directives and browser permissions necessary for their intended function. Overly broad declarations strongly discourage Receiver trust and increase the risk of misuse if permissions are granted.

Receivers are strongly encouraged to treat a capability description as informational input to a review rather than as a grant of permissions. The decision to apply declared CSP directives remains with the Receiver's operator, with human review before first use.

Receiving applications are strongly encouraged to treat all invocation parameters as untrusted input, as required by the receiver rules in URI Template Invocation.

Privacy Considerations

This section is non-normative.

Privacy is one of the ethical values that underpin the web. To empower people with needs to have strong privacy protections with respect to information flows, implementers as well as developers of specifications are encouraged to consider privacy-related design choices as per W3C Privacy Principles [PRIVACY-PRINCIPLES].

Applications that use the fragment (#) form for invocation parameters, as described in this specification, are encouraged to document this choice explicitly, noting that fragment content is not transmitted to the server and therefore does not disclose the target resource IRI to the host from which the application is loaded.

Senders are encouraged to apply the principle of data minimisation when publishing capability descriptions, disclosing only the information necessary for discovery, invocation, and policy review by Consumers and Receivers.

Accessibility Considerations

This section is non-normative.

Internationalization Considerations

This section is non-normative.

Security and Privacy Review

This section is non-normative.

These questions provide an overview of security and privacy considerations for this specification as guided by [SECURITY-PRIVACY-QUESTIONNAIRE].

Societal Impact Review

This section is non-normative.

These questions provide an overview of ethical considerations and societal impact as guided by [SOCIETAL-IMPACT-QUESTIONNAIRE].

Application Considerations

This section is non-normative.

This section describes considerations for applications that publish capability descriptions. These are not normative requirements but reflect the spirit of the trust relationship that this specification establishes between applications, servers, and users.

Senders are strongly encouraged to declare their permission needs accurately and completely. Understating requirements in order to gain access, or overstating them to acquire unnecessary capabilities, undermines the trust model on which this specification relies.

Senders are encouraged to use permissions granted by a Receiver exclusively in the interests of the user on whose behalf those permissions were granted, consistent with the declared purpose expressed via dpv:hasPurpose in the capability description.

Senders are encouraged to maintain stability in the URI Templates declared in their capability descriptions, since Consumers and catalogues can cache and rely on these patterns. Where changes are necessary, Senders could provide a transition period during which both the old and new patterns remain functional.

Changelog

Acknowledgements

The Community Group gratefully acknowledges the work that led to the creation of this specification, and extends sincere appreciation to those individuals that worked on technologies and specifications that deeply influenced our work.

The Community Group would like to thank the following individuals for their useful comments, both large and small, that have led to changes to this specification over the years:

  • elf Pavlik
  • Sarven Capadisli
  • Virginia Balseiro

References

Normative References

Informative References