-
Notifications
You must be signed in to change notification settings - Fork 81
Multilayer API Private maps (draft)
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.
There are 3 kinds of access for maps, these permissions are different from table permissions names (public/private):
-
(A)
public
:- a table is public and can be accessed by the tiler and sql api (implemented)
-
(B)
private
:- a table is private and can be accessed only using api_key (implemented, used only by CartoDB UI)
-
(C)
protected
:- a table is private and can be accesed by the tiler only with some access token (!= api_key) (not implemented)
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:
- Anyone on Internet can see a visualization and access the data (public access)
- Anyone on Internet can see a visualization (public access)
- Only those with a link: Only those who receive the link. (public access)
- Only people with a link and a password: You will set a password (protected access)
- Only other users of your organization (protected access)
- Only you (private or protected access)
so all the proposed use cases are covered by the 3 access models.
In this section the API for using protected
(C) access is described. private
and public
access are
already described in https://github.com/CartoDB/Windshaft/wiki/Multilayer-API.
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.1.0",
// Variables not listed here are not substituted
// Required variable not provided at instantiation time trigger an error
// A default is required for optional variables
// Specifying a type serves the purpose of proper quoting, to avoid injections
"template_variables": {
color: { type:'string', default:'red' }, // required:false by default
cartodb_id: { type:'number', required:true, default: 1 } // default still required for map validation
},
"auth": {
tokens: [
'abcdef',
'123456',
'asdasd',
]
},
"layers": [{
"type": "cartodb",
"options": {
"cartocss_version": "2.1.1",
"cartocss": "#layer { polygon-fill: #FFF; line-color: <%= color %> }",
"sql": "select * from european_countries_e where cartodb_id = <%= cartodb_id %> }"
}
}]
}
to create the same call is used but api_key is needed (only https endpoint)
curl 'https://documentation.cartodb.com/tiles/layergroup/template?api_key=APIKEY' -d @layergroup.json
response:
{
"layergroupid":"jkjlkj3l4kj3j43kj4",
"last_updated":"2013-11-14T11:20:15.000Z"
}
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/jkjlkj3l4kj3j43kj4?token=12345&template_id=10'
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
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
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
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
The template language would support:
- numbers
- strings
there should be some escape mechanism there should be the same than the used for sql named queries (https://github.com/CartoDB/CartoDB-SQL-API/wiki/Named-Queries-API) it ideally should take care of sql injection issues
proposals:
- mustache way: {varname:type}
- python/printf way: "%type(varname)"
- underscore way: "<%= varname %>" (already used by both node apps)
- 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
- In order to validate the creation of a "named layergroup" we'll need default values for any template parameter (for a test instantiation)