For AI agents: the complete documentation index is available at /llms.txt, the full documentation bundle is available at /llms-full.txt, and this page is available as Markdown at /schedules/environments.md.

Environments

What is an environment?

An environment is a named set of secrets and configuration held by an organization. A loop can use it only when the loop's project is bound to it. See Bind projects to an environment. (Any environment that a workspace still holds is usable by every project in that workspace.) A loop uses its environment for API keys, webhook URLs, and other credentials.

A loop references an environment by name in its configuration and uses the secrets stored there.

A loop defined in tessl.json names its environment by name, not by ID, in its action configuration:

{
  "schedules": {
    "weekly-changelog": {
      "action": {
        "skill": "tessl/changelog-writer",
        "environment": "production"
      },
      "cron": "0 9 * * 5"
    }
  }
}

The environment ID resolves only within the organization or workspace that holds it, so a committed file names the environment and Tessl looks it up by name each time a loop starts. If the project's organization (or the workspace, for an environment a workspace still holds) has no environment of that name, or the project isn't bound to the organization environment of that name, the loop doesn't start; its configuration stays in place, and the loop can start normally once the environment exists and, for an organization environment, the project is bound to it. Tessl doesn't create the environment for you.

What goes in an environment

An environment holds any secrets or API keys your plugin needs at runtime.

GitHub access for loops. Each loop gets a GitHub token scoped to your repository, at the access level its environment sets: none, read, pull-requests, or write. The default is read, and a loop with no environment also gets read, which can check out your repo but can't push. A plugin that opens pull requests needs an environment with pull-requests or write access, or one set to none that holds its own GITHUB_TOKEN (or GH_TOKEN). Tessl rejects an environment that holds one of those tokens at any level other than none, and an environment set to none that holds no token can't start a loop. See Least privilege for environments for what each level allows. Set the level with tessl env create --github-access.

Other common values to include:

  • A Linear API key (if the plugin reads or writes Linear issues)
  • A Slack webhook URL (if the plugin posts notifications)
  • Any other third-party service credential the plugin needs

How to create one

From the CLI

Create the environment and supply its secrets in one step using a .env file:

# Create a .env file with your secrets
cat > production.env << 'EOF'
GITHUB_TOKEN=ghp_your_token_here
LINEAR_API_KEY=your_linear_key_here
EOF

# Create the environment from the file
tessl env create production --env-file production.env --github-access none

--github-access none is required here because the file holds a GITHUB_TOKEN. Tessl refuses a token at any other access level. If the file holds no GitHub token, leave the flag off and runs get the default read access.

To update an existing environment later, use tessl env update:

tessl env update production --env-file production.env

Note: update replaces the entire environment value. Include all keys you want to keep, not just the changed ones.

From the web app

  1. Open your organization's settings and go to Environments.
  2. Click Create environment, enter a name and the variables, and save.
  3. On the environment's page, click Edit to change its values, and save.

Note: saving an edit changes only the variables you add, change, or remove. Variables you leave alone keep their values.

A new environment from the web app is bound to no project. Bind a project to it, as described next.

Bind projects to an environment

A loop can use an organization environment only when the loop's project is bound to it. A loop in an unbound project that names the environment is refused.

A new project is not bound to any existing environment. Someone with admin access to the organization must bind it before its loops can use the environment.

To bind or unbind a project in the web app:

  1. Open your organization's settings and go to Environments.
  2. Open the environment.
  3. In the Bound projects card, click Bind a project and choose a project. To remove one, click Unbind beside its name.

To bind one project when you create the environment, pass --project to tessl environment create. Without it, the command binds the project the current directory is linked to. See tessl environment create.

To bind or unbind a project from the CLI, run tessl environment bind or tessl environment unbind with the environment's name. Both act on the project given by --project, else on the project the current directory is linked to. See tessl environment bind and tessl environment unbind.

$ tessl environment bind production --project engteam/web-app
$ tessl environment unbind production --project engteam/web-app

Workspace-held environments became organization environments, each bound to the projects its former workspace held at the time of the move, not counting deleted ones, or to no project if it held none. Projects created after the move start unbound.