Handling data privacy in serverless analytics APIs¶
Creating an analytics dashboard where each user is able to access only certain parts of the data is really easy with Tinybird. You don't need to build anything specific from scratch. Tinybird provides dynamic API Endpoints, including specific security requirements per-user.
The serverless approach to real-time analytics¶
Let's assume you have just two components - the simplest possible stack:
- A frontend application: Code that runs in the browser.
- A backend application: Code that runs in the server and manages both the user authentication and the authorization. Very probably, the backend will also expose an API from where the frontend fetches the information needed.
This guide covers the different workflows that will handle each user operation with the right permissions, by integrating your backend with Static Tokens in a very simple way.
Create Tokens on user sign-up¶
The only thing you need (to ensure that your users have the right permissions on your data) is a created Tinybird Static Token every time you create a new user in your backend.
Creating a Token with filter scope
TOKEN=<your_token> curl -H "Authorization: Bearer $TOKEN" \ -d "name=user_692851_token" \ -d "scope=PIPES:READ:ecommerce_example" \ -d "scope=DATASOURCES:READ:events:user_id=692851" \ https://api.tinybird.co/v0/tokens/
Use a Token with the right scope. Replace <your_token>
with a Token whose scope is TOKENS
or ADMIN
.
This Token will let a given user query their own transactions stored in an events
Data Source and exposed in an ecommerce_example
API Endpoint.
Some other noteworthy things you can see here:
- You can give a
name
to every Token you create. In this case, the name contains theuser_id
, so that it's easier to see what Token is assigned to each user. - You can assign as many scopes to each Token as you want, and
DATASOURCES:READ:datasource_name
andPIPES:READ:pipe_name
can take an optional SQL filter (like this example does) to restrict the rows that queries authenticated with the Token will have access to.
If everything runs successfully, your call will return JSON containing a Token with the specified scopes:
Creating a Token with filter scope: Response
{ "token": "p.eyJ1IjogImI2Yjc1MDExLWNkNGYtNGM5Ny1hMzQxLThhNDY0ZDUxMWYzNSIsICJpZCI6ICI0YTYzZDExZC0zNjg2LTQwN2EtOWY2My0wMzU2ZGE2NmU5YzQifQ.2QP1BRN6fNfgS8EMxqkbfKasDUD1tqzQoJXBafa5dWs", "scopes": [ { "type": "PIPES:READ", "resource": "ecommerce_example", "filter": "" }, { "type": "DATASOURCES:READ", "resource": "events", "filter": "user_id=692851" } ], "name": "user_692851_token" }
All the Tokens you create are also visible in your Workspace > Tokens page in the UI, where you can create, update and delete them.
Modify Tokens when user permissions are changed¶
Imagine one of your users is removed from a group, which makes them lose some permissions on the data they can consume. Once that is reflected in your backend, you can update the user admin Token accordingly as follows:
Modify an existing Token
TOKEN=<your_token> USER_TOKEN=<user_token> curl -X PUT \ -H "Authorization: Bearer $TOKEN" \ -d "name=user_692851_token" \ -d "scope=PIPES:READ:ecommerce_example" \ -d "scope=DATASOURCES:READ:events:user_id=692851 and event in ('buy', 'add_item_to_cart')" \ https://api.tinybird.co/v0/tokens/$USER_TOKEN
Pass the Token you previously created as a path parameter. Replace <user_token>
by the value of token
from the previous response, or copy it from the UI.
In this example you'd be restricting the SQL filter of the DATASOURCES:READ:events
scope to restrict the type of events the user will be able to read from the events
Data Source. This is the response you'd see from the API:
Modify an existing Token: Response
{ "token": "p.eyJ1IjogImI2Yjc1MDExLWNkNGYtNGM5Ny1hMzQxLThhNDY0ZDUxMWYzNSIsICJpZCI6ICI0YTYzZDExZC0zNjg2LTQwN2EtOWY2My0wMzU2ZGE2NmU5YzQifQ.2QP1BRN6fNfgS8EMxqkbfKasDUD1tqzQoJXBafa5dWs", "scopes": [ { "type": "PIPES:READ", "resource": "ecommerce_example", "filter": "" }, { "type": "DATASOURCES:READ", "resource": "events", "filter": "user_id=692851 and event in ('buy', 'add_item_to_cart')" } ], "name": "user_692851_token" }
Delete Tokens after user deletion¶
Whenever a user is removed from your system, you should also remove the Token from Tinybird. That will make things easier for you in the future.
Remove a token
TOKEN=<your_token> USER_TOKEN=<user_token> curl -X DELETE \ -H "Authorization: Bearer $TOKEN" \ https://api.tinybird.co/v0/tokens/$USER_TOKEN
If the Token is successfully deleted, this request will respond with no content and a 204 status code.
Refresh Tokens¶
It's a good practice to change Tokens from time to time, so you can automate this in your backend as well. Refreshing a Token requires executing this request for every one of your users:
Refresh a token
TOKEN=<your_token> USER_TOKEN=<user_token> curl -X POST \ -H "Authorization: Bearer $TOKEN" \ https://api.tinybird.co/v0/tokens/$USER_TOKEN/refresh
Next steps¶
- Learn more about the Tokens API.
- Understand the concept of Static Tokens.