# Best Practices for Running Strix in Production CI/CD Environments

> Master Strix production CI/CD best practices. Learn to use non interactive mode, deterministic exit codes, and Docker sandbox isolation for efficient security scanning.

- Repository: [Strix/strix](https://github.com/usestrix/strix)
- Tags: best-practices
- Published: 2026-03-26

---

**Run Strix in CI/CD pipelines using non‑interactive mode (`-n`), deterministic exit codes (`0` for clean, `2` for vulnerabilities), and Docker sandbox isolation via environment variables like `STRIX_LLM` and `STRIX_IMAGE`.**

Strix is engineered to operate head‑lessly inside automated build environments. The `usestrix/strix` repository provides a CLI that integrates with standard CI systems through deterministic exit codes and containerized isolation. Understanding the three architectural layers—CLI argument parsing, Docker runtime backend, and environment‑driven configuration—is essential for reliable production deployments.

## Strix Architecture for Automated Pipelines

Strix separates concerns across three layers that directly impact CI/CD reliability. Each layer has a specific implementation file in the source tree.

### CLI and Argument Parsing

The entry point resides in [`strix/tools/argument_parser.py`](https://github.com/usestrix/strix/blob/main/strix/tools/argument_parser.py), which handles the conversion of CLI flags into a non‑interactive execution context. The parser recognizes the `-n` or `--non-interactive` flag to disable TTY interactions and accepts `--scan-mode` with values `quick`, `standard`, or `deep`.

### Runtime Backend

The sandbox lifecycle is managed in [`strix/runtime/docker_runtime.py`](https://github.com/usestrix/strix/blob/main/strix/runtime/docker_runtime.py). The `DockerRuntime` class instantiates an isolated container, injects the tool‑server token via `DockerRuntime._register_agent`, and polls health through `DockerRuntime._wait_for_tool_server`. This guarantees that every CI job starts with a pristine filesystem and network namespace.

### Configuration Management

Runtime parameters are resolved in [`strix/config/config.py`](https://github.com/usestrix/strix/blob/main/strix/config/config.py). The `Config.get` method reads values from environment variables or a persisted [`cli-config.json`](https://github.com/usestrix/strix/blob/main/cli-config.json), ensuring that local developer settings and CI environments remain consistent.

## Why These Layers Matter in CI/CD

Three characteristics make Strix suitable for production automation:

- **Deterministic Execution**: The CLI exits with code `0` when no vulnerabilities are found, `2` when issues are detected, and `1` on runtime errors. This allows CI systems to gate merges automatically without parsing logs.
- **Isolation**: The Docker backend ([`strix/runtime/docker_runtime.py`](https://github.com/usestrix/strix/blob/main/strix/runtime/docker_runtime.py)) creates a fresh container per job via `DockerRuntime.create_sandbox`, preventing cross‑contamination of secrets or filesystem state between builds.
- **Config as Code**: Storing options in [`cli-config.json`](https://github.com/usestrix/strix/blob/main/cli-config.json) or environment variables eliminates drift between developer laptops and CI runners.

## Production‑Ready Configuration Settings

Configure the following environment variables in your CI secrets or pipeline environment:

- **`STRIX_IMAGE`**: Pin a specific sandbox image tag (e.g., `ghcr.io/usestrix/strix-sandbox:0.1.13`) to avoid breaking changes from floating tags.
- **`STRIX_RUNTIME_BACKEND`**: Set to `docker` (default) to enforce sandbox isolation.
- **`STRIX_SANDBOX_EXECUTION_TIMEOUT`**: Limit scan duration (recommended `120` seconds for PR jobs).
- **`STRIX_SANDBOX_CONNECT_TIMEOUT`**: Cap container startup time (recommended `10` seconds).
- **`STRIX_LLM`** and **`LLM_API_KEY`**: Pass these as encrypted CI secrets; never hard‑code them in pipeline definitions.
- **`STRIX_TELEMETRY`**: Set to `0` in sensitive environments to disable usage data transmission.

## Architectural Steps in a CI Job

A robust Strix integration follows four distinct phases:

1. **Install the CLI**  
   Execute the installer script to pull the latest binary and register the Docker image:
   ```bash
   curl -sSL https://strix.ai/install | bash
   ```

2. **Configure the Environment**  
   Export `STRIX_LLM`, `LLM_API_KEY`, and optionally `STRIX_IMAGE` if you require a custom sandbox version.

3. **Execute the Scan**  
   Run Strix in non‑interactive mode with an explicit scan target:
   ```bash
   strix -n -t ./ --scan-mode quick
   ```

   Internally, this invokes `DockerRuntime._create_container`, registers the agent, and waits for the tool server health endpoint.

4. **Interpret the Exit Code**  
   Fail the CI job when Strix returns exit code `2`. The method `DockerRuntime._wait_for_tool_server` raises `SandboxInitializationError` if the sandbox fails to start, which also produces a non‑zero exit.

## CI/CD Platform Examples

Below are production‑grade configurations for common platforms. Each example uses non‑interactive mode, secret injection, and exit‑code failure semantics.

### GitHub Actions (Pull‑Request Scans)

```yaml
name: Security Scan

on:
  pull_request:

jobs:
  strix-scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install Strix
        run: curl -sSL https://strix.ai/install | bash

      - name: Run Scan (quick)
        env:
          STRIX_LLM: ${{ secrets.STRIX_LLM }}
          LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
        run: strix -n -t ./ --scan-mode quick

```

*Reference*: `docs/integrations/github-actions.mdx` implements the secret handling pattern for GitHub’s encrypted variables.

### GitLab CI (Nightly Deep Scan)

```yaml
security-scan:
  image: docker:latest
  services:
    - docker:dind
  variables:
    STRIX_LLM: $STRIX_LLM
    LLM_API_KEY: $LLM_API_KEY
  script:
    - curl -sSL https://strix.ai/install | bash
    - strix -n -t ./ --scan-mode deep
  only:
    - schedules

```

*Reference*: `docs/integrations/ci-cd.mdx` lines 24‑37 provide the GitLab template with Docker‑in‑Docker service configuration.

### Jenkins (Declarative Pipeline)

```groovy
pipeline {
    agent any
    environment {
        STRIX_LLM = credentials('strix-llm')
        LLM_API_KEY = credentials('llm-api-key')
    }
    stages {
        stage('Security Scan') {
            steps {
                sh 'curl -sSL https://strix.ai/install | bash'
                sh 'strix -n -t ./ --scan-mode quick'
            }
        }
    }
}

```

*Reference*: `docs/integrations/ci-cd.mdx` lines 39‑55 demonstrate Jenkins credential binding.

### CircleCI (Docker‑in‑Docker)

```yaml
version: 2.1
jobs:
  security-scan:
    docker:
      - image: cimg/base:current
    steps:
      - checkout
      - setup_remote_docker
      - run:
          name: Install Strix
          command: curl -sSL https://strix.ai/install | bash
      - run:
          name: Run Scan
          command: strix -n -t ./ --scan-mode quick
workflows:
  scan:
    jobs:
      - security-scan

```

*Reference*: `docs/integrations/ci-cd.mdx` lines 60‑76 contain the CircleCI remote Docker setup.

## Additional Production Optimization Tips

Maximize reliability and performance with these practices:

- **Pin Image Versions**: Avoid floating tags in `STRIX_IMAGE`. The default implementation in [`strix/config/config.py`](https://github.com/usestrix/strix/blob/main/strix/config/config.py) line 44 references `ghcr.io/usestrix/strix-sandbox`, but production jobs should append explicit semver tags.
- **Cache Docker Layers**: Persist `/var/lib/docker` or the Strix sandbox image between jobs to reduce pull latency.
- **Resource Limits**: Override `STRIX_SANDBOX_EXECUTION_TIMEOUT` if your runners have constrained CPU or memory to prevent runaway scans.
- **Fail‑Fast on Sandbox Errors**: Ensure the CI step aborts immediately when `DockerRuntime` raises `SandboxInitializationError` during container creation.

## Summary

- Use `-n` or `--non-interactive` to run Strix without TTY dependencies in CI environments.
- Rely on exit codes (`0`, `1`, `2`) to gate merges rather than log parsing.
- Isolate scans via the Docker runtime ([`strix/runtime/docker_runtime.py`](https://github.com/usestrix/strix/blob/main/strix/runtime/docker_runtime.py)) to ensure clean environments per job.
- Store sensitive configuration (`STRIX_LLM`, `LLM_API_KEY`) as CI secrets, not in repository files.
- Pin the sandbox image version via `STRIX_IMAGE` to guarantee reproducible builds.
- Handle timeouts through `STRIX_SANDBOX_EXECUTION_TIMEOUT` and `STRIX_SANDBOX_CONNECT_TIMEOUT` defined in [`strix/config/config.py`](https://github.com/usestrix/strix/blob/main/strix/config/config.py).

## Frequently Asked Questions

### What exit codes does Strix return in CI/CD environments?

Strix returns `0` when no vulnerabilities are detected, `2` when vulnerabilities are found, and `1` when a runtime error occurs (such as a sandbox initialization failure). Configure your CI system to fail the build on exit code `2` to prevent merging vulnerable code.

### How do I handle Strix scan timeouts in production pipelines?

Set the `STRIX_SANDBOX_EXECUTION_TIMEOUT` environment variable (default managed in [`strix/config/config.py`](https://github.com/usestrix/strix/blob/main/strix/config/config.py) line 46) to limit total scan duration. For pull‑request jobs, `120` seconds is typically sufficient; nightly `deep` scans may require higher limits. If the timeout is exceeded, Strix exits with code `1` and the CI job fails.

### Can I run Strix without Docker in CI/CD?

While the default runtime specified in [`strix/config/config.py`](https://github.com/usestrix/strix/blob/main/strix/config/config.py) line 45 is `docker`, the architecture supports alternative backends through the runtime abstraction layer. However, Docker is strongly recommended for production CI/CD to ensure process isolation and prevent filesystem pollution between consecutive jobs.

### How should I manage LLM API keys for Strix in CI/CD?

Never commit API keys to version control. Instead, pass `STRIX_LLM` and `LLM_API_KEY` as encrypted environment variables or through your platform’s secret management system (e.g., GitHub Secrets, GitLab CI Variables, Jenkins Credentials). The [`strix/tools/argument_parser.py`](https://github.com/usestrix/strix/blob/main/strix/tools/argument_parser.py) module reads these values at runtime via the configuration layer in [`strix/config/config.py`](https://github.com/usestrix/strix/blob/main/strix/config/config.py).