The apps registry is a place where developers can submit their applications, both web apps and konnectors. The applications metadata are stored and versioned. It can be used by a cozy to list applications to be installed, and for auto-updating the applications.
We define the applications registry as an API. This should allow us to defer the real implementation of the registry storage and allow different store implementations.
The stack itself implement the querying part of the registry API, proxying the request to the registries attached to the instance.
In order for you to publish on our official registries, please follow this howto describing how to obtain a token and parameter you repository to automatically publish versions.
We differentiate three channels of release for each application:
- stable: for stable releases
- beta: for application that can be tested in advance
- dev: for the latest releases directly from the trunk of the repository
For each of these channels, the version string has a different format which differentiate the version channel:
- stable:
X.Y.Z
whereX
,Y
andZ
are positive or null integers. - beta:
X.Y.Z-beta.M
whereX
,Y
,Z
andM
are positive or null integers - dev:
X.Y.Z-dev.checksum
whereX
,Y
andZ
are positive or null integers andchecksum
is a unique identifier of the dev release (typically a shasum of the git commit)
TLDR: 1.0.0-dev._ < 1.0.0
and 1.0.0-beta._ < 1.0.0
, make sure you upgrade
your app version after publishing stable.
The order used to determine the latest version of a channel is the following:
- `1.0.0-dev.* < 1.0.0 (dev < stable)`
- `1.0.0-beta.* < 1.0.0 (beta < stable)`
- `1.0.0-beta.1 < 1.0.0-beta.2`
To order beta and dev releases, we apply a sort by their creation date.
Two types of objects are managed in the registry: applications and versions.
An application described a specific package. It is linked to multiple versions (releases) of the application.
An application object is mutable.
An application object contains the following fields:
slug
: the application slug (unique)type
: the application type ("webapp" or "konnector")editor
: the application editor nameversions
: an object containing all the channels versionslatest_version
: the latest available versionmaintenance_activated
: boolean, true when the maintenance mode is activated on the applicationmaintenance_options
: present only ifmaintenance_activated
is true, object with the following fields:flag_infra_maintenance
: bool, true iff the maintenance is internal to the cozy infrastructureflag_short_maintenance
: bool, true iff the maintenance is a short maintenance, waiting for a correction on our sideflag_disallow_manual_exec
: bool, true iff the maintenance will disallow the execution on the application, even when manually executedmessages
: a list of localized messages containing a short and long information messages explaining the maintenance state
label
: integer for a confidence grade from 0 to 5 (A to F), labelling the application from a user privacy standpoint. It is calculated from thedata_usage_commitment
anddata_usage_commitment_by
fields.data_usage_commitment
: specify a technical commitment from the application editor:user_ciphered
: technical commitment that the user's data is encrypted and can only be known by him.user_reserved
: commitment that the data is only used for the user, to directly offer its service.none
: no commitment
data_usage_commitment_by
: specify what entity is taking the commitment:cozy
: the commitment is taken by cozyeditor
: the commitment is taken by the application's editornone
: no commitment is taken
Example:
{
"slug": "drive",
"type": "webapp",
"editor": "cozy",
"versions": {
"stable": ["3.1.1"],
"beta": ["3.1.1-beta.1"],
"dev": ["3.1.1-dev.7a8354f74b50d7beead7719252a18ed45f55d070"]
},
"latest_version": {
/* */
}
}
A version object describe a specific release of an application.
A version object is immutable.
An application version object contains the following fields:
slug
: the application slugtype
: the application type (webapp, konnector, ...)manifest
: the entire manifest defined in the packagecreated_at
: date of the release creationurl
: URL of the tarball containing the application at specified versionsize
: the size of the application package (uncompressed) in bytes as stringsha256
: the sha256 checksum of the application contenttar_prefix
: optional tar prefix directory specified to properly extract the application content
The version string should follow the channels rule.
Example:
{
"slug": "drive",
"type": "webapp",
"version": "3.1.2",
"created_at": "2017-07-05T07:54:40.982Z",
"url": "http://.../3.1.2",
"size": "1000",
"sha256": "466aa0815926fdbf33fda523af2b9bf34520906ffbb9bf512ddf20df2992a46f",
"manifest": {
/* ... */
},
"maintenance_activated": true,
"maintenance_options": {
"flag_infra_maintenance": true,
"flag_short_maintenance": false,
"flag_disallow_manual_exec": true,
"messages": {
"en": {
"long_message": "The app is currently in maintenance because of ....",
"short_message": "The app is currently in maintenance"
},
"fr": {
"long_message": "L'application est en cours de maintenance à cause de ...",
"short_message": "L'application est en cours de maintenance"
}
}
}
}
These APIs can be used to add elements to the registry.
This route register or modify an application to the registry. The content of the request should be a json object of an application.
- 201 Created, when the application has been successfully added
- 409 Conflict, when an application with the same slug already exists
- 400 Bad request, if the given application data is malformed (bad slug, missing editor, ...)
POST /registry HTTP/1.1
Authorization: Token AbCdE
{
"slug": "drive",
"editor": "cozy",
"name": {
"en": "Drive",
"fr": "Drive"
},
"description": {
"en": "The drive application"
},
"repository": "https://github.com/cozy/cozy-drive"
}
This route adds a version of an already registered application to the registry to the specified channel (stable, beta or dev).
The content of the manifest file extracted from the application data is used to fill the fields of the version. Before adding the application version to the registry, the registry should check the following:
- the
manifest
file contained in the tarball should be checked and have its fields checked against the application properties - the application content should check the sha256 checksum
Fields of the object sent to this request:
url
: the url where the application tarball is storedsha256
: the sha256 checksum of the tarballversion
: the version value (should match the one in the manifest)parameters?
: an optional json value (any) that will override theparameters
field of the manifesticon?
: an optional path to override theicon
field of the manifestscreenshots?
: and optional array of path to override thescreenshots
field of the manifest
- 201 Created, when the version has been successfully added to the registry
- 409 Conflict, when the version already exists
- 404 Not Found, when the application does not exist
- 412 Precondition Failed, when the sent application data is invalid (could not fetch data URL, bad checksum, bad manifest in the tarball...)
- 400 Bad request, when the request is invalid (bad checksum encoding, bad URL...)
Request to add a stable release:
POST /registry/drive HTTP/1.1
Authorization: Token AbCdE
{
"version": "3.1.2",
"url": "https://github.com/cozy/cozy-drive/archive/v3.1.2.tar.gz",
"sha256": "466aa0815926fdbf33fda523af2b9bf34520906ffbb9bf512ddf20df2992a46f"
}
Request to add a development release:
POST /registry/drive HTTP/1.1
Authorization: Token AbCdE
{
"version": "3.1.2-dev.7a1618dff78ba445650f266bbe334cbc9176f03a",
"url": "https://github.com/cozy/cozy-photos-v3/archive/7a1618dff78ba445650f266bbe334cbc9176f03a.zip",
"sha256": "466aa0815926fdbf33fda523af2b9bf34520906ffbb9bf512ddf20df2992a46f"
}
Request to add a version with optional parameters:
POST /registry/drive HTTP/1.1
Authorization: Token AbCdE
{
"version": "3.1.2",
"url": "https://github.com/cozy/cozy-photos-v3/archive/7a1618dff78ba445650f266bbe334cbc9176f03a.zip",
"sha256": "466aa0815926fdbf33fda523af2b9bf34520906ffbb9bf512ddf20df2992a46f",
"parameters": { "foo": "bar", "baz": 123 }
}
HTTP/1.1 201 Created
Content-Type: application/json
Location: http://.../3.1.2
{
"slug": "drive",
"type": "webapp",
"version": "3.1.2-dev.7a1618dff78ba445650f266bbe334cbc9176f03a",
"created_at": "2017-07-05T07:54:40.982Z",
"url": "http://.../7a1618dff78ba445650f266bbe334cbc9176f03a.zip",
"size": "1000",
"sha256": "466aa0815926fdbf33fda523af2b9bf34520906ffbb9bf512ddf20df2992a46f",
"manifest": {
/* ... */
}
}
These routes define the querying part of a registry to access to the available applications and versions. These APIs are also implemented directly by the cozy-stack.
Get the list of all applications.
A pagination scheme is available via the limit
and cursor
query parameter.
The filter[???]
query parameters can be used to filter by fields values.
Filtering is allowed on the following fields:
type
editor
Sorting is allowed on the following fields:
slug
type
editor
created_at
Parameter | Description |
---|---|
cursor | the cursor of the last application on the previous page |
limit | the maximum number of applications to show |
filter[] | a filter to apply on fields of the application |
sort | name of the field on which to apply the sort of the list |
versionsChannel | the channels from which we list the version numbers |
latestChannelVersion | the channel from which we select the latest version |
GET /registry?filter[category]=main&limit=20&sort=slug&versionsChannel=dev&latestChannelVersion=beta HTTP/1.1
HTTP/1.1 200 OK
Content-Type: application/json
{
"data": [
{
"slug": "drive",
"type": "webapp",
"editor": "cozy",
"versions": {
"stable": ["3.1.1"],
"beta": ["3.1.1-beta.1"],
"dev": ["3.1.1-dev.7a8354f74b50d7beead7719252a18ed45f55d070"]
},
"latest_version": {
"slug": "drive",
"type": "webapp",
"version": "3.1.1-beta.1",
"url": "http://.../3.1.1-beta.1",
"sha256": "466aa0815926fdbf33fda523af2b9bf34520906ffbb9bf512ddf20df2992a46f",
"size": "1000",
"created_at": "2017-07-05T07:54:40.982Z",
"manifest": {
/* ... */
}
}
},
{
// ...
}
],
"meta": {
"count": 2,
"next_cursor": "..."
}
}
Get an application object by slug.
GET /registry/drive HTTP/1.1
HTTP/1.1 200 OK
Content-Type: application/json
{
"slug": "drive",
"editor": "cozy",
"latest_version": {
"slug": "drive",
"type": "webapp",
"version": "3.1.1",
"url": "http://.../3.1.1",
"sha256": "466aa0815926fdbf33fda523af2b9bf34520906ffbb9bf512ddf20df2992a46f",
"size": "1000",
"created_at": "2017-07-05T07:54:40.982Z",
"manifest": {
/* ... */
}
},
"versions": {
"stable": ["3.1.1"],
"beta": ["3.1.1-beta.1"],
"dev": ["3.1.1-dev.7a8354f74b50d7beead7719252a18ed45f55d070"]
}
}
Get the current application icon.
GET /registry/drive/icon HTTP/1.1
HTTP/1.1 200 OK
Content-Type: image/svg+xml
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64">
<g fill="none" fill-rule="evenodd"></g>
</svg>
Get the current application partnership_icon.
GET /registry/drive/partnership_icon HTTP/1.1
HTTP/1.1 200 OK
Content-Type: image/svg+xml
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64">
<g fill="none" fill-rule="evenodd"></g>
</svg>
Get the screenshot with the specified filename from the field screenshots
of
the application.
GET /registry/drive/screenshots/screen1.jpg HTTP/1.1
HTTP/1.1 200 OK
Content-Type: image/jpeg
...
Get an application version.
GET /registry/drive/3.1.1 HTTP/1.1
HTTP/1.1 200 OK
Content-Type: application/json
{
"slug": "drive",
"type": "webapp",
"version": "3.1.1",
"url": "http://.../3.1.1",
"sha256": "466aa0815926fdbf33fda523af2b9bf34520906ffbb9bf512ddf20df2992a46f",
"size": "1000",
"created_at": "2017-07-05T07:54:40.982Z",
"manifest": {
/* ... */
}
}
Get the latest version available on the specified channel.
GET /registry/drive/dev/latest HTTP/1.1
HTTP/1.1 200 OK
Content-Type: application/json
{
"slug": "drive",
"type": "webapp",
"version": "3.1.1",
"url": "http://.../3.1.1",
"sha256": "466aa0815926fdbf33fda523af2b9bf34520906ffbb9bf512ddf20df2992a46f",
"size": "1000",
"created_at": "2017-07-05T07:54:40.982Z",
"manifest": {
/* ... */
}
}
Get the list of applications (and konnectors) with maintenance mode activated.
GET /registry/maintenance HTTP/1.1
HTTP/1.1 200 OK
Content-Type: application/json
[
{
"slug": "drive",
"type": "webapp",
"version": "3.1.1",
"url": "http://.../3.1.1",
"sha256": "466aa0815926fdbf33fda523af2b9bf34520906ffbb9bf512ddf20df2992a46f",
"size": "1000",
"created_at": "2017-07-05T07:54:40.982Z",
"manifest": {
/* ... */
},
"maintenance_activated": true,
"maintenance_options": {
"flag_infra_maintenance": true,
"flag_short_maintenance": false,
"flag_disallow_manual_exec": true
}
}
]
In the configuration file of a stack, a registries
namespace is added. This
namespace can contain a list of URL for the different registries attached to the
stack.
The stack itself implements the querying API of a registry. When querying this API, to ask for an application, the stack uses this hierarchy of registries to proxy or redirect the user.
The hierarchy can also be contextualised to specify different registries to
different contexts. The default
context is applied lastly.
registries:
- https://myregistry.home/
- https://main.registry.cozy.io/
# In this example, a "context1" instance will have the equivalent of the
# following list of registries:
#
# - https://context1.registry.cozy.io/
# - https://myregistry.home/
# - https://registry.cozy.io/
#
registries:
context1:
- https://context1.registry.cozy.io/
context2:
- https://context2.registry.cozy.io/
default:
- https://myregistry.home/
- https://registry.cozy.io/
The authentication is based on a token that allow you to publish applications and versions with for one specific editor name. This token is base64 encoded.
In order to receive this token, please take a look at the page on publication on the registry.