> ## Documentation Index
> Fetch the complete documentation index at: https://qodex.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Sensitive endpoints

> Use environment constraints to control where Qodex can run destructive, invasive, or high-volume security tests.

# Sensitive endpoints

Security tests can be powerful. Some probes are safe to run almost anywhere, such as header checks. Others can create data, send attack payloads, or generate traffic bursts. Sensitive endpoint controls tell Qodex what it is allowed to do in each environment.

Use these controls to keep production safe while still getting meaningful security coverage in staging or preview environments.

## The three environment constraints

Each environment can define three constraints. On the **Environments** page, edit an environment and use **Read-only (skip destructive tests)** and **Max requests / second**.

| Constraint | What it controls |
| - | - |
| `read_only` | Refuses every request except GET, HEAD, and OPTIONS to the environment's hosts, and skips scenarios tagged `destructive`. The only write still allowed is the login request the environment or its auth profiles are configured with. |
| `max_requests_per_second` | The request-rate cap you set for the target. |
| `allow_destructive_tests` | When `false`, scenarios tagged `destructive` are skipped. Ticking **Read-only** in the web app turns this off too. |

The constraints combine. For example, a production environment can be read-only, rate-limited, and destructive-test disabled. A dedicated QA environment can allow broader probes.

## How read-only is enforced

Read-only is enforced in three places, so it does not depend on the agent choosing to follow it:

* **In chat**, the agent is told the environment is read-only. If it still tries a write request, the request is refused. In a browser, a click or form submit that reads as destructive (for example delete or remove) on a read-only host is refused too.
* **During runs**, a scenario tagged `destructive` is skipped rather than run. It shows as skipped on the test run page with the reason `skipped: environment is read-only` (or `skipped: destructive tests are turned off for this environment`), and it never counts as a pass.
* **On redirects**, a write request is not followed through a redirect once any environment in the project is read-only, so a redirect cannot carry the write onto a protected host.

Only a person can change the switch. If you ask the agent to turn read-only off, it points you to the **Environments** page.

## Example configuration

```json theme={null}
{
  "name": "production",
  "hosts": {
    "api": "https://api.example.com",
    "ui": "https://app.example.com"
  },
  "variables": {
    "AUTH_EMAIL": "qa-bot@example.com"
  },
  "readOnly": true,
  "maxRequestsPerSecond": 5,
  "allowDestructiveTests": false
}
```

Qodex reads these settings before authoring and before execution. If a planned probe violates the environment, the agent skips it or keeps to the safe subset.

## Recommended defaults

| Environment | `read_only` | `max_requests_per_second` | `allow_destructive_tests` |
| - | - | - | - |
| Production | `true` | `5` | `false` |
| Staging mirror of production | `true` | `5` | `false` |
| Dedicated QA staging | `false` | `20` | `true` |
| Local development | `false` | `50` | `true` |
| Preview deployment | `false` | `20` | `true` |

Production should usually receive safe checks such as security-header audits, cookie audits, TLS checks, and read-only authorization probes. Write-side IDOR, mass assignment, injection, and high-volume rate-limit tests belong on staging or preview environments.

## What happens when a probe is blocked

When constraints block a probe, Qodex handles it in one of three ways:

| Outcome | What Qodex does |
| - | - |
| Probe is allowed | Authors and runs the scenario normally. |
| Probe is partly allowed | Keeps the safe steps and skips unsafe steps. |
| Probe is fully blocked | Skips the scenario and notes the reason in the run summary. |

For example, on a `read_only: true` environment, a BOLA check can still test `GET /api/orders/{id}` with the wrong user token, but Qodex should skip the PUT and DELETE versions.

Tag scenarios that delete data, deactivate accounts, or otherwise cannot be undone with `destructive`, so scheduled and CI runs skip them on protected environments. Chat security testing also keeps itself to at most 10 requests per second per target, whatever the environment allows.

## Checking constraints in chat

Before running a security sweep, you can ask:

```text theme={null}
What constraints are set on the production environment?
```

Qodex will report the active environment flags so you can decide whether to run the check there or switch to a less restricted target. To change a flag, edit the environment on the **Environments** page.

## When to tighten constraints

* The environment points to production or production data.
* The endpoint changes billing, permissions, users, or account state.
* The test includes brute-force, fuzzing, or burst behavior.
* The target is shared with customers or internal teams.
* You are not sure whether the endpoint has idempotent cleanup.

## Related

> [card] [Security scenarios](https://qodex.ai/docs/security-testing-scenarios.md)
>
> Learn how constraints shape the scenarios Qodex authors.

> [card] [OWASP API Top 10 in Qodex](https://qodex.ai/docs/security-testing-owasp-api-top-10.md)
>
> See which probes may need write access or higher rate limits.

> [card] [Inverted semantics](https://qodex.ai/docs/security-testing-inverted-semantics.md)
>
> Understand how security pass and fail states work.

> [card] [Auth profiles](https://qodex.ai/docs/api-testing-auth-profiles.md)
>
> Configure roles for BOLA, IDOR, and privilege-escalation tests.

## On the roadmap

> [!TIP]
>
> A dedicated `allow_security_testing` flag is planned. It will let teams block active attack payloads independently from destructive tests, so production mirrors can still run hygiene checks without receiving injection or SSRF probes.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.