---
title: "Environments, Credentials & Variables"
id: "1918"
type: "page"
slug: "environments"
published_at: "2026-09-30T22:18:19+00:00"
modified_at: "2026-10-01T00:11:02+00:00"
url: "https://xedant.com/agents/test/docs/environments"
markdown_url: "https://xedant.com/agents/test/docs/environments.md"
excerpt: "The same checks must work on the staging stand, on production, and on a developer’s…"
---

# Environments, Credentials & Variables

[https://xedant.com/agents/test/docs/environments.md](https://xedant.com/agents/test/docs/environments.md)

The same checks must work on the staging stand, on production, and on a developer’s machine, while passwords and keys must never end up in project files. For that, Test Agent has **environments** — separate sets of addresses — and a protected vault for credentials.

Why this is needed: without environments, every action would carry a hard-coded address, and moving to another stand would mean rewriting all the files. And a password written straight into a file sooner or later lands in version control and becomes known to everyone with access to the code.

## Environments

A project has a list of environments — one row per stand. A row carries the base URL, a release label (a version or a date, for example), the sort order, and a “protected (production)” flag. An environment name is lowercase Latin letters, digits and hyphens.

One environment is the **default**. It is implicit: it has no separate row, its address comes from the project settings, and it cannot be deleted. All the other environments the team creates itself.

Actions read the stand address as `ctx.vars.BASE_URL`. This means the same scenario works on any stand: a run names the environment, and the address is substituted by itself. The environment’s own variable values, set in its row, are mixed over the project variables at the moment the run is handed out — the base address can be overridden from there too.

If a run names an environment that does not exist, it is rejected already at queueing. The other way around: an environment referenced by scheduled runs cannot be deleted — they must run first. A deleted environment stays in the history as a label.

## Comparing two environments

To compare a staging stand with production there is a separate build mode: the builds list (the Verify tab) gets a comparison build naming both environments.

An important detail: baselines are tied to an environment, and its label is part of their signature. That is why a snapshot from the staging stand is never compared with a production baseline, and the other way around — otherwise a quiet difference between the stands themselves would pass for a change in the application.

## Credentials

Passwords, tokens and headers are stored not in files but in a protected vault — **encrypted** (AES-256-GCM). The key lives on the server in the file `/apps/tests/keys/visual-creds.key`. A value is shown once, at the moment of saving; afterwards it cannot be read again — only replaced or deleted.

Credentials are injected into a run at the very moment the job is handed out, straight into the executor process. They never get into sources, logs, model requests, or exports. Actions read them as `ctx.vars.NAME`, and a credential and a variable cannot share a name. If the needed credential is missing, the action honestly fails with an error instead of running with an empty password.

There is value replacement, deletion, and **encryption key rotation**: a new key generation is created, and every stored value of every project is re-encrypted under it. Runs already in flight finish with the old key. A rotation cannot be undone.

Kinds of credentials: password, token, header, and custom — for the non-standard case.

## Variables

Variables are sets of plain values, not secrets: a test user’s name, for example. One set may carry several comma-separated values; the first one always acts, the rest are spares for manual rotation. The “first value wins” rule works strictly, so a run’s result never depends on chance.

When there are many entries, both kinds of values come in handy. But for everything that is a secret — a password, a key, a token — use credentials: only they are encrypted and never leave the product.

## Setup and cleanup

A project can define “before” and “after” actions for any test — signing in and signing out, for example. The former run before the test’s steps, the latter after them. Cleanup runs even when a test step failed: otherwise the next run would start from a dirty state.

If a test declares its own setup and cleanup lists, it fully replaces the project ones — they are not merged. An empty declared list is a deliberate refusal of the phase, not “take the project ones”. A test’s own lists live in its file and are edited in the test builder; saving the project-level lists requires the admin role.

## Production protection

The project settings can list **production hosts** — addresses the browser crawl will not touch without explicit permission. That way a crawl launched by mistake does not go wandering over the production site: the protection must be lifted consciously first.

Next: which humans can do what in a project — in [Users & Roles](/agents/test/docs/users)
.

[← Back to the documentation index](/agents/test/docs)
