Any time a user tries to access an Embeddable dashboard in your website, you should use our tokens API to retrieve a fresh security token for their session.

// for security reasons, this must *never* be called from your client-side
fetch('<https://api.embeddable.com/api/v1/security-token>', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json',
        'Accept': 'application/json',
        'Authorization': `Bearer ${apiKey}` /* keep your API Key secure */
    },
    body: JSON.stringify({
        embeddableId: embeddableId, /* the dashboard to load */
        expiryInSeconds: 60*60*24*7, /* token expiry */
        securityContext: { /* any context you want to provide to the SQL data models */
            userId: '9sZSJ9LHsiYXR0cmlidXRlIjoiZ2VvaXBf',
            regions: ['us-east', 'eu-west']
        },
        user: '[email protected]', // unique key representing current user
        environment: 'prod' // each environment defines which databases to connect to
    })
});

Response:
{ 'token': 'eyJhbGciOiJIUzI1NiJ9.eyJzZWN1cml0eVRva2VuSWQiOiI1OGE1NGYwMi0xNTJmLTQxMjgtYWZmZC0zMDhhYzI0NTE5ZGQiLCJpYXQiOjE3MDczMTU1NDUsImV4cCI6MTcwNzkyMDM0NX0.lnovN0xTMCjLcxGTIfzFD9cYRIAZjn6S7sew-ih11lM' }

The retrieved token should be injected into the Web Component (described here).

The securityContext in your request is an arbitrary javascript object that will be passed to your data models. This will allow your data models to apply row, table or schema level security, for example, like so:

name: Orders
sql: >
	SELECT user_id, created_at 
	FROM public.orders 
	WHERE user_id = '{ COMPILE_CONTEXT.securityContext.userId }'
	
	{% if COMPILE_CONTEXT.securityContext.regions %}
	   AND region IN {{ list(COMPILE_CONTEXT.securityContext.regions) }}
	{% endif %}

...

The user parameter allows us to store (anonymous) session metadata against each user automatically so that customisations / preferences applied by the user to their Embeddable dashboard will automatically be remembered for their next session. This doesn’t need to be an email, just a unique identifier for that user.

The environment parameter is optional (defaults to “default”), but can be used to tell Embeddable which environment to retrieve data from (see Environments API). This allows you to achieve things like:

Testing security contexts

Once you start using securityContext in your data models, you will want a way to test them in Embeddable’s no-code builder. You can do this by defining a set of preset security contexts.

Create a file named src/presets/security-contexts.sc.yml in your code repository:

- name: Nike
  securityContext:
    orgId: org5
    userId: YXR0cmlidXRlIjoiZ2VvaXBf9sZSJ9LHsi
- name: Adidas
  securityContext:
    orgId: org29
    userId: cmlidXRlIjoiZ2VvaXBf9sZSJ9LHsiYXR0

Each item in this file will appear as a “View as” option in the top right corner of the no-code builder:

Screenshot 2024-02-07 at 18.10.43.png

This allows you to preview your dashboard in the no-code builder as if you were a particular end-user (AKA view the dashboard filtered to the data that they will see).