Skip to content

Multilayer API Private maps (draft)

strk edited this page Nov 15, 2013 · 13 revisions

introduction

This document describes the API to access tiles of protected tables. Before that there is an overview of different access types and how they are used from CartoDB point of view.

access types from user point of view

There are 3 kinds of access:

  • (A) public:

    1. a table is public and can be accessed by the tiler and sql api (implemented)
    2. a table is private but can be accesed by the tiler (not implemented)
  • (B) private:

    1. a table is private and can be accessed only using api_key (implemented, used only by CartoDB UI)
  • (C) protected:

    1. a table is private and can be accesed by the tiler only with some access token (!= api_key) (not implemented)

Use cases from CartoDB perspective

CartoDB uses visualizations that allow cartodb user to publish the map. There are some usecases we want to provide and tiler should be able to manage with its API:

  1. Anyone on Internet can see a visualization and access the data (public access)
  2. Anyone on Internet can see a visualization (public access)
  3. Only those with a link: Only those who receive the link. (public access)
  4. Only people with a link and a password: You will set a password (protected access)
  5. Only other users of your organization (protected access)
  6. Only you (private or protected access)

so all the proposed use cases are covered by the 3 access models.

Implementation point of view

Currently we only support public (A.1) or private (B) access model to the table. When a table is public, there is an special database user called publicuser who is granted access to the table (read only).

When a table is private only database owner can access the data so you need to use an API_KEY in order to access private tables.

There are two cases not covered by that (marked as not implemented in the previous section), "public access when table is private" and "protected":

  • public access to a private table: there should be a new user, let's say tileuser, with the same permissions than publicuser. In this way we can fetch the data to render it.
  • protected: could we use tileuser for these layergroups ? no because if we grant access to tileuser to a table any user would be able to create layergroups with this table. So I propose to have a third tiler user called: tileuser_protected

both users are read only

Windshaft API

In this section the API for using protected(C) and public access to a private table(A.2) access are described. private and public access are already described in https://github.com/CartoDB/Windshaft/wiki/Multilayer-API.

public access to a private table (A.2)

it should be the same than the public access to a public table. The only difference is the database permissions for the table[s] are different, but from the API point of view it's described in the Multilayer-API document: https://github.com/CartoDB/Windshaft/wiki/Multilayer-API

protected layergroup (C)

A protected layergroup is a layergroup that is created with admin permissions and whose access is managed by access token. Let's call them 'named layergroups'

// layergroup.json 
{
  "version": "1.0.1",
  "name": "mymapname",
  "auth": {
      type: 'protected'
      tokens: [
        'abcdef',
        '123456',
        'asdasd',
      ]
  },
  "layers": [{
    "type": "cartodb",
    "options": {
      "cartocss_version": "2.1.1", 
      "cartocss": "#layer { polygon-fill: #FFF; }",
      "sql": "select * from european_countries_e"
    }
  }]
}

creating named layergroup

to create the same call is used but api_key is needed (only https endpoint)

curl 'https://documentation.cartodb.com/tiles/layergroup?api_key=APIKEY' -d @layergroup.json

response:

{
   "layergroupid":"name",
   "last_updated":"2013-11-14T11:20:15.000Z"
}

using named layergroup

Once it's created a client could get a layergroup to render tiles (notice no layergroup definition is sent):

curl -d '' 'https://documentation.cartodb.com/tiles/layergroup/:name?token=12345' 

response:

{
   "layergroupid":"c01a54877c62831bb51720263f91fb33:123456788",
   "last_updated":"2013-11-14T11:20:15.000Z"
}

to fetch a tile a valid token should be used:

curl 'https://documentation.cartodb.com/tiles/layergroup/c01a54877c62831bb51720263f91fb33:123456788/0/0/0.png?token=VALIDTOKEN'

probably this tiles should contain a Subrogate Key including the layergroup name and the token in case they need to be invalidated

updating

same request than is done to create it. At this point, if the tokens are modified, the layergroups created from this named layergroups should stop working

removing named layergroup

these named layergroups are persisted until are deleted:

curl -X DELETE 'https://documentation.cartodb.com/tiles/layergroup/name?api_key=APIKEY'

should return a 204 and the layergroups created from this named layergroups should stop working

listing

since named layergroups are persistent a listing API is needed

curl 'http://documentation.cartodb.com/tiles/layergroup'

returns a list of protected layergroups:

{
    layergroups: [ 
        { /* layer definition */ },
        { /* layer definition */ },
        { /* layer definition */ }
    ]
}

options

Option type Default Description
api_key string mandatory allow access to private layergroups
tables string array null return layergroups that use one of those tables

example

curl 'http://documentation.cartodb.com/tiles/layergroup?tables=table_a,table_b&api_key=APIKEY

some other notes

  • as layergroups need to be persistent we need to think where is the best place. I wouldn't discuss this at this point, we should think about what is the right API and then move to the implementation details.
  • named layergroups are also a nice way to create persistent maps (like basemaps)
  • I'm assuming that we will be able to invalidate CDN. If not we should set a reasonable ttl (i.e using max-age or expires) for CDN
  • I described the usecases for CartoDB but also covers the typical usecase where a third party wants to include a map for an auth user with private data in their web app.
  • I don't discuss the management of table permissions. They are managed by a third service (in our case CartoDB rails app). If the tiler does not have permissions to access a table, an error is reported (forbidden)
  • we know that a public map for a private table could be used to extract the data from the table using interactivity. We are ok with that, if the user want to keep his data as secret as possible he should use protected maps where the layergroup definition can't be changed
Clone this wiki locally