Aller au contenu
Bastide Connexion Créer un compte
Press / to search

Environments and variables

FrançaisMarkdownv0.3.0

A Bastide project serves its application in one or more environments, and each one receives its own environment variables. This page explains the kinds of environment, the difference between a visible variable and a secret, and how to write them from the console, an agent, the command line or the API.

Environments

An environment is a place where the application is served: it has its address, its deployments and its variables. The model knows four kinds.

KindValue in the APIHow it comes into being
ProductionproductionWith the project, always, and only one per project.
PreviewpreviewWhen a branch is pushed, or on demand: see Previews.
StagingstagingNot yet available: no operation creates this environment today.
CustomcustomNot yet available: no operation creates this environment today.

The price list provides custom environments from the Standard tier upwards (2 on Standard, 10 on Pro and Sovereign). Until their creation is served, a project works with its production and its previews.

Every environment has an env_… identifier. Reading variables, deploying and restoring all require it, and the only way to learn it is to list the project's environments.

Environment states

The “Environnements” (Environments) card on the project's “Vue d'ensemble” (Overview) shows, for each environment, the commit it serves and its state.

  • Épinglé (pinned): the environment serves a restored version and no longer follows pushes. See Restore.
  • Isolé · bifurcation (isolated, fork): a preview opened from a fork of the repository. It receives no sensitive variable.
  • En veille (asleep): the environment is idle for lack of traffic and wakes on the next request.
  • supprimé le … (removed on …): the date on which a preview will be removed.

Unpinning puts the last healthy deployment back into service and makes the environment follow pushes again. It is a promotion, reserved for the Maintainer rank: open the row's “⋯” menu, then Lever l'épinglage (Unpin), or use the environment_unpin tool.

Variables and secrets

A variable has a name, a value and a sensitivity.

  • Visible: the value can be read back by anyone with a sufficient rank (see the table below).
  • Secret: the value is encrypted when written and is never read back, not in the console, not through the API, not by an agent, whatever the rank. A secret is replaced: you write a new value under the same name.

By default, a variable written to production is a secret; elsewhere, it is visible. You can choose the other setting on each write.

The secret.reveal operation exists in the registry so that the request is refused by name and logged: no role is allowed it. A read that names a secret receives the secret_never_read refusal.

When a variable takes effect

A change takes effect on the environment's next deployment. The live version keeps the set of variables it was built with until then. After writing a variable, redeploy: see Deploy.

Allowed names

A name starts with an uppercase letter, then contains only uppercase letters, digits and underscores, 64 characters at most. It is read as is in code, for example process.env.NEXT_PUBLIC_SITE_URL.

Some names are refused on write, because the interpreter or the dynamic linker reads them before the program and they would change the behaviour of the image without leaving a trace in the build plan:

BASH_ENV  DYLD_INSERT_LIBRARIES  DYLD_LIBRARY_PATH  ENV  GIT_EXTERNAL_DIFF
GIT_SSH_COMMAND  IFS  LD_AUDIT  LD_LIBRARY_PATH  LD_PRELOAD  NODE_EXTRA_CA_CERTS
NODE_OPTIONS  PATH  PERL5OPT  PYTHONPATH  PYTHONSTARTUP  RUBYOPT  SHELL  SSL_CERT_FILE

A variable bearing one of these names can still be deleted.

Inheritance

A preview inherits the variables of the project's staging environment, when there is one: a variable of the preview's own hides an inherited variable of the same name. Production, staging and custom environments inherit nothing. The inventory says, for each variable, whether it belongs to the environment or is inherited, and from which environment.

Variables set by the platform

  • PORT: the port the application must listen on, set in the container.
  • NODE_ENV: set to production in the Node.js images the platform builds.
  • DATABASE_URL and DIRECT_URL: when the project has its PostgreSQL database, the platform sets them on the environment before the build. DATABASE_URL goes through the connection pooler in transaction mode; DIRECT_URL in session mode, with a single connection, for migration tools such as prisma migrate. The inventory marks them “Fournie par Bastide” (provided by Bastide).

Your own value always wins. If you write DATABASE_URL, the variable becomes yours and the platform no longer touches it. A repository configured for SQLite keeps its DATABASE_URL, and an isolated preview receives neither address.

Variables required by the repository

If the repository contains a .env.example file, every variable it declares must exist in the environment before the build. Otherwise the deployment is refused with variables_requises_manquantes, and the report lists them. A variable that the file's comments call optional (“optional”, “facultatif”, “leave empty”…), or that carries an example value without having a secret's name, only produces a warning in the build log.

From the console

Open “Variables” in the project menu. The tabs at the top choose the environment; the inventory shows each variable's name, sensitivity, origin, revision and date, never its value.

  1. In the Ajouter une variable (Add a variable) panel, enter the name and the value, then choose Secret or Visible.
  2. Tick one or more environments: one write goes to each.
  3. Click Enregistrer (Save). A banner confirms and offers Défaire (Undo) for 5 minutes.

Modifier (Edit) reads back a visible variable's value before replacing it. Remplacer (Replace) on a secret opens an empty field: the old value is not shown. Remplacer ici (Replace here) on an inherited variable creates a variable of the environment's own that hides it. The bin icon deletes a variable of the environment's own; the live version keeps it until the next deployment.

Importing a .env file

Importer un .env (Import a .env) opens a window where you paste the content or choose a file; you can also drop the file onto the page. The file is read in the browser, its content is not displayed, and each variable is then sent as a separate write.

  • A blank line, or one starting with #, is ignored; a leading export is tolerated.
  • Between double quotes, \n, \t, \" and \\ are interpreted and the value may span several lines, which lets you paste a PEM key. Between single quotes, the value is literal.
  • A key defined twice keeps the last value, with a warning.
  • ${OTHER} is not substituted: the value is sent as is, with a warning.
  • A file larger than 1 MB is not read.

Before sending, the window says what will happen to each variable (added, replaces the current value, will hide the inherited one) and lets you tick Secret row by row. A refused write does not stop the others. Défaire l'import (Undo the import) reverts every write for 5 minutes.

Writing to production, writing elsewhere

Production has its own operations, separate from those of the other environments, with a higher rank.

ActionOutside productionProductionMinimum rank
List the names, without valuesenv_listenv_listDeveloper
Read the visible valuesenv_pull_nonproductionenv_pull_productionDeveloper / Maintainer
Writeenv_write_nonproductionenv_write_productionDeveloper / Maintainer
Deleteenv_delete_nonproductionenv_delete_productionDeveloper / Maintainer

A non-production operation called on production is refused (production_environment or wrong_operation), and the message names the operation to use. Production operations take no environment identifier: there is only one per project.

A write or a deletion returns an undoToken: the action_undo tool reverts it within five minutes, once, for the same account. A service account can neither write nor delete a variable.

Through an agent

The variable tools are marked destructive: your MCP client asks for your consent before each write or deletion. An agent never receives the value of a secret.

  1. environment_list returns the environments and their identifiers.
  2. env_list returns an environment's inventory, with the counters to compare against the caps.
  3. env_write_nonproduction or env_write_production writes the variable.
{
  "projectId": "prj_01JQ8ZK4M7NP2RSTVWXYZ34567",
  "environmentId": "env_01JQ8ZK4M7NP2RSTVWXYZ34567",
  "key": "NEXT_PUBLIC_API_URL",
  "value": "https://api.preview.example.com",
  "sensitive": false,
  "idempotencyKey": "preview-api-variable-2026-09-14"
}

env_pull_nonproduction and env_pull_production return the visible values. Each value arrives wrapped and marked as untrusted data, and sensitive variables are named in clesOmises rather than silently left out: a caller thus knows they exist and does not overwrite them by mistake.

{
  "variables": {
    "NEXT_PUBLIC_API_URL": {
      "untrusted": true,
      "source": "variable-d-environnement",
      "content": "https://api.preview.example.com"
    }
  },
  "clesOmises": ["PAYMENT_SECRET_KEY"]
}

From the command line

bastide environment list --project-id prj_01JQ8ZK4M7NP2RSTVWXYZ34567
bastide env list --project-id prj_01JQ8ZK4M7NP2RSTVWXYZ34567 --environment-id env_01JQ8ZK4M7NP2RSTVWXYZ34567
bastide env write production --project-id prj_01JQ8ZK4M7NP2RSTVWXYZ34567 --key PAYMENT_SECRET_KEY --value '<key>'
bastide env pull nonproduction --project-id prj_01JQ8ZK4M7NP2RSTVWXYZ34567 --environment-id env_01JQ8ZK4M7NP2RSTVWXYZ34567

env pull prints the visible values; it does not write a file. Writes and deletions ask for confirmation unless you pass --yes. In a directory linked with bastide link, --project-id can be left out.

bastide doctor compares the names in your machine's .env files with those of the deployed environment, without ever reading a value, and suggests the command that brings the two sides together.

Tip. A value passed with --value stays in your shell history. For a secret, prefer the console, or remove the line from your history afterwards.

Through the API

curl -X PUT https://api.bastide.app/v1/projects/prj_01JQ8ZK4M7NP2RSTVWXYZ34567/env/production \
  -H "Authorization: Bearer <your-token>" \
  -H "Content-Type: application/json" \
  -d '{"key": "PAYMENT_SECRET_KEY", "value": "<key>", "idempotencyKey": "payment-secret-2026-09-14"}'

The other routes are GET /v1/projects/{projectId}/env (inventory), GET …/env/pull and …/env/pull/production (visible values), and PUT and DELETE on …/env (outside production) and …/env/production. See the API reference.

Limits

They are the same on every tier.

LimitValue
Variables per environment1,000
Combined size of an environment's values256 KB (262,144 bytes)
Size of one value64 KB (65,536 bytes)
Length of a name64 characters
Window to undo a write5 minutes

Common errors

CodeCauseRemedy
production_environment, wrong_operationA non-production operation targeted production.Use env_write_production, env_pull_production or env_delete_production, with the Maintainer rank.
secret_never_readThe read named a sensitive variable.Replace the secret with a new value; it cannot be read back.
quota_exceeded1,000 variables or 256 KB reached.Delete unused variables, or combine values.
invalid_requestName outside the grammar, refused name (LD_PRELOAD…) or value over 64 KB.Fix the name or the value; the message names the rule.
secret_store_unavailableThe secret store cannot be reached.Try again later; nothing was written.
variables_requises_manquantesThe repository's .env.example declares a missing variable.Write the variable, or mark it optional in .env.example, then redeploy.

See also

Report a mistake on this page