Connect your data
Set up Environments

Set up Environments

Environments let you map data models to different sets of database connections, depending on the user. This makes it easy to:

  • Test embeddable against different environments (e.g. prod, QA, staging).
  • Implement single-tenancy (database-level security) where each customer has their own database (or set of databases).

How It Works

Let's imagine you have a "prod" environment and a "staging" environment and each environment has two databases:

prod:
  primary_db: prod-postgres
  warehouse: prod-bigquery
 
staging:
  primary_db: staging-postgres
  warehouse: staging-bigquery

In this setup, your data models don't need to know about prod-postgres, staging-postgres, etc.

They just need to know that they can either connect to the primary_db or the warehouse. And then the chosen environment will automatically connect the model to the appropriate database.

Define Connections

Use the Connections API to create named database connections (e.g. "prod-postgres", "staging-postgres"). Each connection includes the credentials (host, port, user, etc.) for a particular database.

Assign data_source in Your Models

In your .cube.yml (or .cube.js) files, specify data_source for each model. If omitted, it defaults to "default":

cubes:
  - name: orders
    sql_table: public.orders
    data_source: primary_db

This tells Embeddable that the “orders” model should look for a data_source named "primary_db" in the chosen environment.

Create Environments

For each environment that you want to define (prod, staging, etc.) you should define an Environment using the Environments API.

Open APIs In Bruno

An environment is simply a mapping, mapping each data_source to a corresponding database connection.

Here is an example of how you could call the Environments API to create two environments (one for 'prod' and one for 'staging'):

// 
// create a 'prod' environment
// 
fetch('https://api.<region>.embeddable.com/api/v1/environments', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': `Bearer ${apiKey}`
  },
  body: JSON.stringify({
    name: 'prod',
    datasources: [
      { data_source: 'primary_db', connection: 'prod-postgres' },
      { data_source: 'warehouse', connection: 'prod-bigquery' }
    ]
  })
});
 
// 
// create a 'staging' environment
// 
fetch('https://api.<region>.embeddable.com/api/v1/environments', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': `Bearer ${apiKey}`
  },
  body: JSON.stringify({
    name: 'staging',
    datasources: [
      { data_source: 'primary_db', connection: 'staging-postgres' },
      { data_source: 'warehouse', connection: 'staging-bigquery' }
    ]
  })
});
  • name is a unique ID for the environment (e.g. "prod" or "microsoft").
  • datasources is a list mapping each model’s data_source to a named connection (e.g. in the above example, all models whose data_source is set to "primary_db" will use the connection named "prod-postgres").
💡

Important: every environment you create should have the same set of data_source keys. They can (and likely will) point to different connections, but the set of data_sources should be the same (so that every data model has a valid connection in every Environment).

  • Learn more about region here.

Use the Environment via Token API

When requesting a security token, supply the environment field:

{
  embeddableId: "<dashboard-id>",
  environment: "prod",
  // ...
}
  • Embeddable automatically routes each model’s data_source to the connections defined in your "prod" environment.
  • If environment is omitted, it uses the "default" environment (which is a special environment that always maps data_source names onto a connection of the same name).

CRUD Operations

The POST request above represents a CREATE action, but all CRUD operations are available.

  • POST /api/v1/environments
    Create a new environment.
  • GET /api/v1/environments
    List all environments.
  • PUT /api/v1/environments/{name}
    Update an existing environment.
  • GET /api/v1/environments/{name}
    Retrieve a specific environment’s details.
  • DELETE /api/v1/environments/{name}
    Delete the named environment.

Testing in the No-Code Builder

To preview environments before publishing, you can create or update your src/embeddable.com/presets/security-contexts.sc.yml (here (opens in a new tab)) with entries specifying the environment:

- name: Example customer 1
  environment: production
  securityContext:
    country: United States
 
- name: Example customer 2
  environment: staging
  securityContext:
    country: Germany

In the builder UI, you can then choose “View as” → “Example customer 2” to load the staging environment, verifying your data and filters. Switch back to “Example customer 1” to confirm production data.

Image 0

Advanced use-case: If you have multiple data models each with unique data_source values, you can define an environment that includes only the data sources you want for a particular user—offering fine-grained control over which models (and thus which databases) are active for that environment.

Deploying Versions

Once you have set up your environments, you can deploy versions of your dashboard that are specific to each environment. This allows you to test changes in a safe environment before promoting them to production. Learn more about deploying dashboard versions.