Application interoperability
Solid Application Interoperability
Added in: activitypods@2.0
Solid Application Interoperability is a complex specification which is not yet complete. We’ve implemented everything we can at the moment and are waiting to see how it evolves before implementing the remaining parts.
We’re following the proposed ontology closely. On the other hand, application registration is done via ActivityPub, as this was the simplest method for us (applications are ActivityPub actors). We’ve also decided not to use ShapeTrees for the time being, as we don’t think they add anything to our triplestore-based architecture: instead, applications just declare the classes they want to manage.
What we implement
- Applications declare their needs through
AccessNeedGroups
andAccessNeeds
, which are displayed on an authorization screen. - Before registration,
AccessGrants
andDataGrants
are created on the user’s Pod. - The
ApplicationRegistration
resource is created on the user’s Pod and sent to the application through aCreate
activity. - If the
ApplicationRegistration
is correct, it is saved on the application instance, as well as the corresponding grants. It returns anAccept
activity. - Whenever the user connects again to the application, we check that the
AccessNeeds
haven’t changed. If needed, we show an authorization screen again andApplicationRegistration
is updated (with aUpdate
activity). - If the user wants to uninstall the application, we delete the
ApplicationRegistration
(and corresponding grants) and send aDelete
activity to the application.
What we don’t implement yet
- Authorization flow is handled using ActivityPub. The application is an ActivityPub actor.
- We only handle registration with
Applications
, not with otherSocialAgents
(we continue to use WAC permissions for the latter) - Pods don’t declare an
AuthorizationAgent
. It is handled internally. - Pods don’t declare a
DataRegistry
. This registry is only used to list ShapeTrees. TypeIndex can be used instead. - Applications don’t declare
AccessNeedDescription
. On the other hand, in theAccessDescriptionSet
it is possible to declareClassDescriptions
. - Pods only create
AccessGrants
andDataGrants
, notAccessAuthorizations
andDataAuthorizations
. Grants can be shared with the registered application, while Authorizations cannot. The only difference between them is agrantedWith
predicate inAccessAuthorizations
that indicates which app was used to manage authorizations (but we manage that internally anyway). - Pods don’t declare
RegistrySet
,ApplicationRegistry
,AuthorizationRegistry
as they are not visible from the outside. We just readApplicationRegistrations
,AccessGrants
andDataGrants
in their dedicated containers.
Class descriptions
Added in: activitypods@2.0
Applications can describe the types of resources (classes) they use. This enables user-friendly information to be displayed on the authorization screen, as well as on the data browser.
{ "@type": "apods:ClassDescription", "apods:describedClass": "https://www.w3.org/ns/activitystreams#Event", "apods:describedBy": "https://welcometomyplace.org", "skos:prefLabel": "Events", "apods:labelPredicate": "https://www.w3.org/ns/activitystreams#name", "apods:openEndpoint": "https://welcometomyplace.org/r", "apods:icon": "https://welcometomyplace.org/logo192.png"}
The following predicates are used:
skos:prefLabel
: A human-readable label of the resource typeapods:labelPredicate
: The predicate used to label the resourceapods:openEndpoint
: An URL that can be used to open the resourcesapods:icon
: An image to describe the resource type
Class descriptions are located in the interop:AccessDescriptionSet
{ "@type": "interop:AccessDescriptionSet", "interop:usesLanguage": "en", "apods:hasClassDescription": "https://mypod.store/alice/data/eba0227a-3bbb-4582-b879}
Type Indexes
Added in: activitypods@2.0
TypeIndexes are Solid’s recommended method to discover in what LDP containers the resources are being stored. In ActivityPods, we have implemented a public TypeIndex, that is linked to the WebID with the solid:publicTypeIndex
predicate.
Since we don’t support yet RDF documents (planned for version 3.0), we use a custom solid:hasTypeRegistration
predicate to link the solid:TypeIndex
with the various solid:TypeRegistration
, and we dereference them for easier handling. See this issue for more details.
{ "id":"https://mypod.store/sro/data/9abafd71-39d9-47f2-8a1d-a50cb6a0a5c6", "type":[ "solid:TypeIndex", "solid:ListedDocument"], "solid:hasTypeRegistration":[ { "id":"https://mypod.store/sro/data/da9c1935-1c9d-4660-81de-183657c2a7a7", "type":"solid:TypeRegistration", "solid:forClass":"vcard:Group", "solid:instanceContainer":"https://mypod.store/sro/data/vcard/group" }, ... ]}
In addition to the solid:forClass
and solid:instanceContainer
predicates used by TypeRegistrations to indicate, respectively, the types and their container’s URI, we are also persisting predicates that are used by the Pod provider’s data browser. They are the same as the ClassDescription.
skos:prefLabel
: A human-readable label of the resource typeapods:labelPredicate
: The predicate used to label the resourceapods:openEndpoint
: An URL that can be used to open the resourcesapods:icon
: An image to describe the resource type
Additionaly, two predicates are used in relation with apps registration:
apods:defaultApp
: The default app with which to open the resource typeapods:availableApps
: All the apps that are able to handle this resource type