Application Capability
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
- 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
Copyright © 2024–9999 the Contributors to Application Capability, Version 0.3.1415, published by the Foo Bar Baz Group under the W3C Community Contributor License Agreement (CLA). A human-readable summary is available. All code snippets are in the public domain, CC0.
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_handlersmember 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.
| 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.
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.
| 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. |
| 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:
- Discovery together with the Capability Description Data Model
- Notifications
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.
GET https://app.example/Accept: application/ld+jsonHTTP/1.1 200 OKContent-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.
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 thanacceptorresourceTypematching, 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
outputto select the appropriate Capability, then pass that format as theoutputinvocation 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.
{
"@context": "https://www.w3.org/ns/ac.jsonld",
"id": "https://app.example/#capability-open",
"type": "Capability",
"action": "odrl:display"
}
{
"@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"
}
{
"@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"
}
{
"@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
mappingentry. 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 aproperty(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.
{
"@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
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
outputdeclared by the selected Capability. A Consumer that wants HTML output selects the capability declaringoutput: text/htmland passesoutput=text/htmlin 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
openor 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.
{
"@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.
{
"@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:
{
"@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.
{
"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.
{
"@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.
{
"@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.
{
"@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 OKContent-Type: text/htmlContent-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.
{
"@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" } ]
}
}
{
"@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
Linkheader with arelvalue ofhttp://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.
PUT /article HTTP/1.1Host: example.orgContent-Type: text/html;charset=utf-8HTTP/1.1 403 ForbiddenLink: <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.
{
"@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