---
url: /en/workspaces/personal-envs.md
description: >
  Describes the personal environment variables for Workspaces, which inject your
  own secret files into cloud-native development environments per a repository
  allowlist (use_in_slugs), reusing the imports fetching and authorization
  mechanism to securely share personal secrets across repositories.
---
`Personal Environment Variables` is a user-level configuration that automatically injects the secret
files you specify as environment variables when starting a `Workspace` (cloud-native development)
environment.

Unlike configuring [imports](../build/grammar.md#pipeline-imports) per repository in `.cnb.yml`,
personal environment variables take effect at your individual user level, and use a `use_in_slugs`
allowlist to control which repositories they can be injected into. This makes them ideal for
reusing your personal development secrets across multiple repositories.

::: tip
Personal environment variables only take effect in `Workspace` environments and do not affect
regular `Builds`.
:::

## Where to Configure

On the [Profile > Workspaces](https://cnb.cool/profile/workspaces) page,
find `Personal Environment Variables`, fill it in as YAML, and save.

## Format

The configuration is a YAML array. Each item contains two fields (`imports` uses the same syntax
as pipeline [imports](../build/grammar.md#pipeline-imports)):

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `imports` | `String` | `Array<String>` | Yes | Secret file addresses |
| `use_in_slugs` | `String` | `Array<String>` | Yes | Repositories allowed to receive these secrets, supports Glob |

::: warning use\_in\_slugs is required
If an item has no `use_in_slugs`, or the current workspace's repository does not match it,
that item **will not be injected**, preventing your personal secrets from leaking into
untrusted repositories.
:::

**Example:**

```yaml
- imports: https://cnb.cool/<your-secret-repo-slug>/-/blob/main/npm.yml
  use_in_slugs:
    - your-group/**
- imports:
    - https://cnb.cool/<your-secret-repo-slug>/-/blob/main/docker.yml
    - https://cnb.cool/<your-secret-repo-slug>/-/blob/main/k8s.yml
  use_in_slugs:
    - your-group/project-a
    - your-group/project-b
```

In the example above:

* `npm.yml` from the first item is injected into the workspace of every repository under
  `your-group/`;
* `docker.yml` and `k8s.yml` from the second item are injected only into
  `your-group/project-a` and `your-group/project-b`.

## Scope and Precedence

* **Scope**: only the `Workspace` environments started by the current user.
* **Precedence**: personal environment variables are injected after the repository pipeline
  `imports`, so when variable names collide, **personal environment variables override** the
  same-named variables from the repository `imports`. Variables explicitly declared in `env`
  of `.cnb.yml` still have the highest precedence.

## Security and Authorization

Personal environment variables reuse the full [imports](../build/grammar.md#pipeline-imports)
authorization chain. Before injection, **all** of the following conditions must be met:

1. **Injection allowlist**: the current repository matches the item's `use_in_slugs`
   (controls injection targets at the user level).
2. **Reference authorization**: before injection, the system checks whether the repository
   where the current workspace is started is allowed to read the secret file. The rules
   are the same as pipeline [imports](../build/grammar.md#pipeline-imports):

   * The secret file resides in the current repository, or its repository is public —
     pass directly;
   * Cross-repo reference, and the secret file's **content** declares fields such as
     `allow_slugs` (written inside the yml/json file to specify which repositories are
     allowed to reference it) — checked against those declarations;
   * Cross-repo reference, and the file content declares no `allow_*` at all — you must
     have read (pull) permission on the secret file's repository.

   See [Configuration File Reference Authorization](../build/file-reference.md#permission-checks)
   for the full rules.

::: tip
It is recommended to store secret files in a dedicated [secret repository](../repo/secret.md)
for higher security and reference auditing.
The format and parsing rules of secret files are the same as pipeline imports.
See [File Parsing Rules](../build/grammar.md#file-parsing-rules).
:::

## Notes

* The total length of the configuration is limited (currently up to 2000 characters);
  do not store overly long content.
* `imports` only supports CNB in-site file addresses, or relative paths (which are resolved
  to a file in the repository where the current workspace is started, e.g. `./.cnb/env.yml`);
  external addresses will not be loaded.
* Invalid items (e.g. malformed YAML, missing `use_in_slugs`) are ignored and do not affect
  normal startup of the development environment.
* However, **secret file addresses must be accessible**: wrong paths, missing files, or
  failed authorization will cause the workspace to **fail to start**.

## Security Notes

::: warning Read inside the container — please follow these recommendations

Personal environment variables are injected into the workspace as environment variables
and can be read by any script inside the container (e.g. `env`, `echo $XXX`).
It is recommended to:

* **Only inject into groups or repositories you trust**: `use_in_slugs` must scope to a
  group or specific repositories you trust, and **avoid broad wildcards like `**`**;
  injecting into untrusted repositories risks secret theft — for example, anyone with
  write permission on those repositories can exfiltrate your injected environment variables
  in `.cnb.yml` in many ways (such as `curl` to an external server, printing to build
  logs, etc.);
* **Store secret files in a dedicated [secret repository](../repo/secret.md)**, and
  **never put secret files in public repositories**; if you configure `allow_slugs` inside
  the secret file, note that it means "allow these repositories to reference this file" —
  setting it too broadly (e.g. `**`) will let others reference your secret file too,
  so keep it as narrow as possible; if the file is for your own use only, you may omit
  `allow_slugs` and rely on the pull permission check.

:::
