github.com/cozy/cozy-stack@v0.0.0-20240603063001-31110fa4cae1/docs/registry.md (about)

     1  [Table of contents](README.md#table-of-contents)
     2  
     3  # Apps registry
     4  
     5  The apps registry is a place where developers can submit their applications,
     6  both web apps and konnectors. The applications metadata are stored and
     7  versioned. It can be used by a cozy to list applications to be installed, and
     8  for auto-updating the applications.
     9  
    10  We define the applications registry as an API. This should allow us to defer the
    11  real implementation of the registry storage and allow different store
    12  implementations.
    13  
    14  The stack itself implement the
    15  [querying part of the registry API](#apis-querying-registry), proxying the
    16  request to
    17  [the registries attached to the instance](#attaching-a-cozy-stack-to-a-registry-or-a-list-of-registries).
    18  
    19  ## Publishing on our official registries
    20  
    21  In order for you to publish on our official registries, please follow
    22  [this howto](./registry-publish.md) describing how to obtain a token and
    23  parameter you repository to automatically publish versions.
    24  
    25  ## Channels
    26  
    27  We differentiate three channels of release for each application:
    28  
    29  -   stable: for stable releases
    30  -   beta: for application that can be tested in advance
    31  -   dev: for the latest releases directly from the trunk of the repository
    32  
    33  For each of these channels, the version string has a different format which
    34  differentiate the version channel:
    35  
    36  -   stable: `X.Y.Z` where `X`, `Y` and `Z` are positive or null integers.
    37  -   beta: `X.Y.Z-beta.M` where `X`, `Y`, `Z` and `M` are positive or null
    38      integers
    39  -   dev: `X.Y.Z-dev.checksum` where `X`, `Y` and `Z` are positive or null
    40      integers and `checksum` is a unique identifier of the dev release (typically
    41      a shasum of the git commit)
    42  
    43  ## Version order
    44  
    45  TLDR: `1.0.0-dev._ < 1.0.0` and `1.0.0-beta._ < 1.0.0`, make sure you upgrade
    46  your app version after publishing stable.
    47  
    48  The order used to determine the latest version of a channel is the following:
    49  
    50      - `1.0.0-dev.*  < 1.0.0 (dev < stable)`
    51      - `1.0.0-beta.* < 1.0.0 (beta < stable)`
    52      - `1.0.0-beta.1 < 1.0.0-beta.2`
    53  
    54  To order beta and dev releases, we apply a sort by their creation date.
    55  
    56  ## Objects
    57  
    58  Two types of objects are managed in the registry: applications and versions.
    59  
    60  ### Application
    61  
    62  An application described a specific package. It is linked to multiple versions
    63  (releases) of the application.
    64  
    65  An application object is **mutable**.
    66  
    67  An application object contains the following fields:
    68  
    69  -   `slug`: the application slug (unique)
    70  -   `type`: the application type ("webapp" or "konnector")
    71  -   `editor`: the application editor name
    72  -   `versions`: an object containing all the channels versions
    73  -   `latest_version`: the latest available version
    74  -   `maintenance_activated`: boolean, true when the maintenance mode is
    75      activated on the application
    76  -   `maintenance_options`: present only if `maintenance_activated` is true,
    77      object with the following fields:
    78      -   `flag_infra_maintenance`: bool, true iff the maintenance is internal to
    79          the cozy infrastructure
    80      -   `flag_short_maintenance`: bool, true iff the maintenance is a short
    81          maintenance, waiting for a correction on our side
    82      -   `flag_disallow_manual_exec`: bool, true iff the maintenance will
    83          disallow the execution on the application, even when manually executed
    84      -   `messages`: a list of localized messages containing a short and long
    85          information messages explaining the maintenance state
    86  -   `label`: integer for a confidence grade from 0 to 5 (A to F), labelling the
    87      application from a user privacy standpoint. It is calculated from the
    88      `data_usage_commitment` and `data_usage_commitment_by` fields.
    89  -   `data_usage_commitment`: specify a technical commitment from the application
    90      editor:
    91      -   `user_ciphered`: technical commitment that the user's data is encrypted
    92          and can only be known by him.
    93      -   `user_reserved`: commitment that the data is only used for the user, to
    94          directly offer its service.
    95      -   `none`: no commitment
    96  -   `data_usage_commitment_by`: specify what entity is taking the commitment:
    97      -   `cozy`: the commitment is taken by cozy
    98      -   `editor`: the commitment is taken by the application's editor
    99      -   `none`: no commitment is taken
   100  
   101  Example:
   102  
   103  ```json
   104  {
   105      "slug": "drive",
   106      "type": "webapp",
   107      "editor": "cozy",
   108      "versions": {
   109          "stable": ["3.1.1"],
   110          "beta": ["3.1.1-beta.1"],
   111          "dev": ["3.1.1-dev.7a8354f74b50d7beead7719252a18ed45f55d070"]
   112      },
   113      "latest_version": {
   114          /* */
   115      }
   116  }
   117  ```
   118  
   119  ### Version
   120  
   121  A version object describe a specific release of an application.
   122  
   123  A version object is **immutable**.
   124  
   125  An application version object contains the following fields:
   126  
   127  -   `slug`: the application slug
   128  -   `type`: the application type (webapp, konnector, ...)
   129  -   `manifest`: the [entire](./apps.md#the-manifest)
   130      [manifest](./konnectors.md#the-manifest) defined in the package
   131  -   `created_at`: date of the release creation
   132  -   `url`: URL of the tarball containing the application at specified version
   133  -   `size`: the size of the application package (uncompressed) in bytes as
   134      string
   135  -   `sha256`: the sha256 checksum of the application content
   136  -   `tar_prefix`: optional tar prefix directory specified to properly extract
   137      the application content
   138  
   139  The version string should follow the channels rule.
   140  
   141  Example:
   142  
   143  ```json
   144  {
   145      "slug": "drive",
   146      "type": "webapp",
   147      "version": "3.1.2",
   148      "created_at": "2017-07-05T07:54:40.982Z",
   149      "url": "http://.../3.1.2",
   150      "size": "1000",
   151      "sha256": "466aa0815926fdbf33fda523af2b9bf34520906ffbb9bf512ddf20df2992a46f",
   152      "manifest": {
   153          /* ... */
   154      },
   155      "maintenance_activated": true,
   156      "maintenance_options": {
   157          "flag_infra_maintenance": true,
   158          "flag_short_maintenance": false,
   159          "flag_disallow_manual_exec": true,
   160          "messages": {
   161              "en": {
   162                  "long_message": "The app is currently in maintenance because of ....",
   163                  "short_message": "The app is currently in maintenance"
   164              },
   165              "fr": {
   166                  "long_message": "L'application est en cours de maintenance à cause de ...",
   167                  "short_message": "L'application est en cours de maintenance"
   168              }
   169          }
   170      }
   171  }
   172  ```
   173  
   174  ## APIs: Adding to registry
   175  
   176  These APIs can be used to add elements to the registry.
   177  
   178  ### POST /registry
   179  
   180  This route register or modify an application to the registry.
   181  The content of the request should be a json object of an application.
   182  
   183  #### Status codes
   184  
   185  -   201 Created, when the application has been successfully added
   186  -   409 Conflict, when an application with the same slug already exists
   187  -   400 Bad request, if the given application data is malformed (bad slug,
   188      missing editor, ...)
   189  
   190  #### Request
   191  
   192  ```http
   193  POST /registry HTTP/1.1
   194  Authorization: Token AbCdE
   195  ```
   196  
   197  ```json
   198  {
   199      "slug": "drive",
   200      "editor": "cozy",
   201      "name": {
   202          "en": "Drive",
   203          "fr": "Drive"
   204      },
   205      "description": {
   206          "en": "The drive application"
   207      },
   208      "repository": "https://github.com/cozy/cozy-drive"
   209  }
   210  ```
   211  
   212  ### POST /registry/:app
   213  
   214  This route adds a version of an already registered application to the
   215  registry to the specified channel (stable, beta or dev).
   216  
   217  The content of the manifest file extracted from the application data is used to
   218  fill the fields of the version. Before adding the application version to the
   219  registry, the registry should check the following:
   220  
   221  -   the `manifest` file contained in the tarball should be checked and have its
   222      fields checked against the application properties
   223  -   the application content should check the sha256 checksum
   224  
   225  Fields of the object sent to this request:
   226  
   227  -   **`url`**: the url where the application tarball is stored
   228  -   **`sha256`**: the sha256 checksum of the tarball
   229  -   **`version`**: the version value (should match the one in the manifest)
   230  -   `parameters?`: an optional json value (any) that will override the
   231      `parameters` field of the manifest
   232  -   `icon?`: an optional path to override the `icon` field of the manifest
   233  -   `screenshots?`: and optional array of path to override the `screenshots`
   234      field of the manifest
   235  
   236  #### Status codes
   237  
   238  -   201 Created, when the version has been successfully added to the registry
   239  -   409 Conflict, when the version already exists
   240  -   404 Not Found, when the application does not exist
   241  -   412 Precondition Failed, when the sent application data is invalid (could
   242      not fetch data URL, bad checksum, bad manifest in the tarball...)
   243  -   400 Bad request, when the request is invalid (bad checksum encoding, bad
   244      URL...)
   245  
   246  #### Request
   247  
   248  Request to add a stable release:
   249  
   250  ```http
   251  POST /registry/drive HTTP/1.1
   252  Authorization: Token AbCdE
   253  ```
   254  
   255  ```json
   256  {
   257      "version": "3.1.2",
   258      "url": "https://github.com/cozy/cozy-drive/archive/v3.1.2.tar.gz",
   259      "sha256": "466aa0815926fdbf33fda523af2b9bf34520906ffbb9bf512ddf20df2992a46f"
   260  }
   261  ```
   262  
   263  Request to add a development release:
   264  
   265  ```http
   266  POST /registry/drive HTTP/1.1
   267  Authorization: Token AbCdE
   268  ```
   269  
   270  ```json
   271  {
   272      "version": "3.1.2-dev.7a1618dff78ba445650f266bbe334cbc9176f03a",
   273      "url": "https://github.com/cozy/cozy-photos-v3/archive/7a1618dff78ba445650f266bbe334cbc9176f03a.zip",
   274      "sha256": "466aa0815926fdbf33fda523af2b9bf34520906ffbb9bf512ddf20df2992a46f"
   275  }
   276  ```
   277  
   278  Request to add a version with optional parameters:
   279  
   280  ```http
   281  POST /registry/drive HTTP/1.1
   282  Authorization: Token AbCdE
   283  ```
   284  
   285  ```json
   286  {
   287      "version": "3.1.2",
   288      "url": "https://github.com/cozy/cozy-photos-v3/archive/7a1618dff78ba445650f266bbe334cbc9176f03a.zip",
   289      "sha256": "466aa0815926fdbf33fda523af2b9bf34520906ffbb9bf512ddf20df2992a46f",
   290      "parameters": { "foo": "bar", "baz": 123 }
   291  }
   292  ```
   293  
   294  #### Response
   295  
   296  ```http
   297  HTTP/1.1 201 Created
   298  Content-Type: application/json
   299  Location: http://.../3.1.2
   300  ```
   301  
   302  ```json
   303  {
   304      "slug": "drive",
   305      "type": "webapp",
   306      "version": "3.1.2-dev.7a1618dff78ba445650f266bbe334cbc9176f03a",
   307      "created_at": "2017-07-05T07:54:40.982Z",
   308      "url": "http://.../7a1618dff78ba445650f266bbe334cbc9176f03a.zip",
   309      "size": "1000",
   310      "sha256": "466aa0815926fdbf33fda523af2b9bf34520906ffbb9bf512ddf20df2992a46f",
   311      "manifest": {
   312          /* ... */
   313      }
   314  }
   315  ```
   316  
   317  ## APIs: Querying registry
   318  
   319  These routes define the querying part of a registry to access to the available
   320  applications and versions. These APIs are also implemented directly by the
   321  cozy-stack.
   322  
   323  ### GET /registry
   324  
   325  Get the list of all applications.
   326  
   327  A pagination scheme is available via the `limit` and `cursor` query parameter.
   328  The `filter[???]` query parameters can be used to filter by fields values.
   329  
   330  Filtering is allowed on the following fields:
   331  
   332  -   `type`
   333  -   `editor`
   334  
   335  Sorting is allowed on the following fields:
   336  
   337  -   `slug`
   338  -   `type`
   339  -   `editor`
   340  -   `created_at`
   341  
   342  #### Query-String
   343  
   344  | Parameter            | Description                                              |
   345  | -------------------- | -------------------------------------------------------- |
   346  | cursor               | the cursor of the last application on the previous page  |
   347  | limit                | the maximum number of applications to show               |
   348  | filter[]             | a filter to apply on fields of the application           |
   349  | sort                 | name of the field on which to apply the sort of the list |
   350  | versionsChannel      | the channels from which we list the version numbers      |
   351  | latestChannelVersion | the channel from which we select the latest version      |
   352  
   353  #### Request
   354  
   355  ```http
   356  GET /registry?filter[category]=main&limit=20&sort=slug&versionsChannel=dev&latestChannelVersion=beta HTTP/1.1
   357  ```
   358  
   359  #### Response
   360  
   361  ```http
   362  HTTP/1.1 200 OK
   363  Content-Type: application/json
   364  ```
   365  
   366  ```json
   367  {
   368      "data": [
   369          {
   370              "slug": "drive",
   371              "type": "webapp",
   372              "editor": "cozy",
   373              "versions": {
   374                  "stable": ["3.1.1"],
   375                  "beta": ["3.1.1-beta.1"],
   376                  "dev": ["3.1.1-dev.7a8354f74b50d7beead7719252a18ed45f55d070"]
   377              },
   378              "latest_version": {
   379                  "slug": "drive",
   380                  "type": "webapp",
   381                  "version": "3.1.1-beta.1",
   382                  "url": "http://.../3.1.1-beta.1",
   383                  "sha256": "466aa0815926fdbf33fda523af2b9bf34520906ffbb9bf512ddf20df2992a46f",
   384                  "size": "1000",
   385                  "created_at": "2017-07-05T07:54:40.982Z",
   386                  "manifest": {
   387                      /* ... */
   388                  }
   389              }
   390          },
   391          {
   392              // ...
   393          }
   394      ],
   395      "meta": {
   396          "count": 2,
   397          "next_cursor": "..."
   398      }
   399  }
   400  ```
   401  
   402  ### GET /registry/:app
   403  
   404  Get an application object by slug.
   405  
   406  #### Request
   407  
   408  ```http
   409  GET /registry/drive HTTP/1.1
   410  ```
   411  
   412  #### Response
   413  
   414  ```http
   415  HTTP/1.1 200 OK
   416  Content-Type: application/json
   417  ```
   418  
   419  ```json
   420  {
   421      "slug": "drive",
   422      "editor": "cozy",
   423      "latest_version": {
   424          "slug": "drive",
   425          "type": "webapp",
   426          "version": "3.1.1",
   427          "url": "http://.../3.1.1",
   428          "sha256": "466aa0815926fdbf33fda523af2b9bf34520906ffbb9bf512ddf20df2992a46f",
   429          "size": "1000",
   430          "created_at": "2017-07-05T07:54:40.982Z",
   431          "manifest": {
   432              /* ... */
   433          }
   434      },
   435      "versions": {
   436          "stable": ["3.1.1"],
   437          "beta": ["3.1.1-beta.1"],
   438          "dev": ["3.1.1-dev.7a8354f74b50d7beead7719252a18ed45f55d070"]
   439      }
   440  }
   441  ```
   442  
   443  ### GET /registry/:app/icon
   444  
   445  Get the current application icon.
   446  
   447  #### Request
   448  
   449  ```http
   450  GET /registry/drive/icon HTTP/1.1
   451  ```
   452  
   453  #### Response
   454  
   455  ```http
   456  HTTP/1.1 200 OK
   457  Content-Type: image/svg+xml
   458  
   459  <svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64">
   460    <g fill="none" fill-rule="evenodd"></g>
   461  </svg>
   462  ```
   463  
   464  ### GET /registry/:app/partnership_icon
   465  
   466  Get the current application partnership_icon.
   467  
   468  #### Request
   469  
   470  ```http
   471  GET /registry/drive/partnership_icon HTTP/1.1
   472  ```
   473  
   474  #### Response
   475  
   476  ```http
   477  HTTP/1.1 200 OK
   478  Content-Type: image/svg+xml
   479  
   480  <svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64">
   481    <g fill="none" fill-rule="evenodd"></g>
   482  </svg>
   483  ```
   484  
   485  ### GET /registry/:app/screenshots/:filename
   486  
   487  Get the screenshot with the specified filename from the field `screenshots` of
   488  the application.
   489  
   490  #### Request
   491  
   492  ```http
   493  GET /registry/drive/screenshots/screen1.jpg HTTP/1.1
   494  ```
   495  
   496  #### Response
   497  
   498  ```http
   499  HTTP/1.1 200 OK
   500  Content-Type: image/jpeg
   501  
   502  ...
   503  ```
   504  
   505  ### GET /registry/:app/:version
   506  
   507  Get an application version.
   508  
   509  #### Request
   510  
   511  ```http
   512  GET /registry/drive/3.1.1 HTTP/1.1
   513  ```
   514  
   515  #### Response
   516  
   517  ```http
   518  HTTP/1.1 200 OK
   519  Content-Type: application/json
   520  ```
   521  
   522  ```json
   523  {
   524      "slug": "drive",
   525      "type": "webapp",
   526      "version": "3.1.1",
   527      "url": "http://.../3.1.1",
   528      "sha256": "466aa0815926fdbf33fda523af2b9bf34520906ffbb9bf512ddf20df2992a46f",
   529      "size": "1000",
   530      "created_at": "2017-07-05T07:54:40.982Z",
   531      "manifest": {
   532          /* ... */
   533      }
   534  }
   535  ```
   536  
   537  ### GET /registry/:app/:channel/latest
   538  
   539  Get the latest version available on the specified channel.
   540  
   541  #### Request
   542  
   543  ```http
   544  GET /registry/drive/dev/latest HTTP/1.1
   545  ```
   546  
   547  #### Response
   548  
   549  ```http
   550  HTTP/1.1 200 OK
   551  Content-Type: application/json
   552  ```
   553  
   554  ```json
   555  {
   556      "slug": "drive",
   557      "type": "webapp",
   558      "version": "3.1.1",
   559      "url": "http://.../3.1.1",
   560      "sha256": "466aa0815926fdbf33fda523af2b9bf34520906ffbb9bf512ddf20df2992a46f",
   561      "size": "1000",
   562      "created_at": "2017-07-05T07:54:40.982Z",
   563      "manifest": {
   564          /* ... */
   565      }
   566  }
   567  ```
   568  
   569  ### GET /registry/maintenance
   570  
   571  Get the list of applications (and konnectors) with maintenance mode activated.
   572  
   573  #### Request
   574  
   575  ```http
   576  GET /registry/maintenance HTTP/1.1
   577  ```
   578  
   579  #### Response
   580  
   581  ```http
   582  HTTP/1.1 200 OK
   583  Content-Type: application/json
   584  ```
   585  
   586  ```json
   587  [
   588      {
   589          "slug": "drive",
   590          "type": "webapp",
   591          "version": "3.1.1",
   592          "url": "http://.../3.1.1",
   593          "sha256": "466aa0815926fdbf33fda523af2b9bf34520906ffbb9bf512ddf20df2992a46f",
   594          "size": "1000",
   595          "created_at": "2017-07-05T07:54:40.982Z",
   596          "manifest": {
   597              /* ... */
   598          },
   599          "maintenance_activated": true,
   600          "maintenance_options": {
   601              "flag_infra_maintenance": true,
   602              "flag_short_maintenance": false,
   603              "flag_disallow_manual_exec": true
   604          }
   605      }
   606  ]
   607  ```
   608  
   609  ## Attaching a cozy-stack to a registry or a list of registries
   610  
   611  In the configuration file of a stack, a `registries` namespace is added. This
   612  namespace can contain a list of URL for the different registries attached to the
   613  stack.
   614  
   615  The stack itself implements the querying API of a registry. When querying this
   616  API, to ask for an application, the stack uses this hierarchy of registries to
   617  proxy or redirect the user.
   618  
   619  The hierarchy can also be contextualised to specify different registries to
   620  different contexts. The `default` context is applied lastly.
   621  
   622  ### Examples:
   623  
   624  ```yaml
   625  registries:
   626      - https://myregistry.home/
   627      - https://main.registry.cozy.io/
   628  ```
   629  
   630  ```yaml
   631  # In this example, a "context1" instance will have the equivalent of the
   632  # following list of registries:
   633  #
   634  #   - https://context1.registry.cozy.io/
   635  #   - https://myregistry.home/
   636  #   - https://registry.cozy.io/
   637  #
   638  
   639  registries:
   640      context1:
   641          - https://context1.registry.cozy.io/
   642  
   643      context2:
   644          - https://context2.registry.cozy.io/
   645  
   646      default:
   647          - https://myregistry.home/
   648          - https://registry.cozy.io/
   649  ```
   650  
   651  # Authentication
   652  
   653  The authentication is based on a token that allow you to publish applications
   654  and versions with for one specific editor name. This token is base64 encoded.
   655  
   656  In order to receive this token, please take a look at the page on
   657  [publication on the registry](./registry-publish.md).