# Configuration

Qtap can be managed locally with a `yaml` config file. This guide explains how to create, deploy, and maintain a local configuration file for Qtap.

{% hint style="info" %}
**New to Qtap?** Follow the [Complete Guide](https://docs.qpoint.io/guides/qtap-guides/getting-started/getting-started-complete-guide) for hands-on examples progressing from basic to production-ready configurations (4 levels, 50 minutes).
{% endhint %}

{% hint style="success" %}
**Want centralized management?** Check out [Qplane](https://docs.qpoint.io/getting-started/qplane) for cloud-based configuration with visual dashboards, automatic propagation to all agents, and advanced analytics. See the [POC Kick Off Guide](https://docs.qpoint.io/guides/qplane-guides/poc-kick-off-guide) to get started.
{% endhint %}

## Configuration File Structure

The `qpoint.yaml` file consists of three main sections:

1. [**Storage Configurations**](https://docs.qpoint.io/getting-started/qtap/configuration/storage-configuration) **(Where processed data goes)**
2. [**Stacks**](https://docs.qpoint.io/getting-started/qtap/configuration/traffic-processing-with-plugins) **(How data is processed)**
3. [**Traffic Capture Rules**](https://docs.qpoint.io/getting-started/qtap/configuration/traffic-capture-settings) **(What data is processed)**

Here's the basic structure:

```yaml
version: 2

services:
  event_stores:
    # Event storage configuration
  object_stores:
    # Object storage configuration

stacks:
  stack_1:
    plugins:
      # First plugin configuration
  stack_2:
    plugins:
      # Second plugin configurations (optional)

tap:
  # Global traffic capture settings
```

## Creating a Basic Configuration

Let's walk through creating a simple configuration file step by step.

### Step 1: Set Version

Start by setting the configuration version:

```yaml
version: 2
```

### Step 2: Configure Data Storage

Next, define where captured data will be stored:

{% tabs %}
{% tab title="Stdout" %}

```yaml
services:
  # For connection metadata (anonymized)
  event_stores:
    - id: console_stdout
      type: stdout
  # For actual request/response content
  object_stores:
    - id: console_stdout
      type: stdout
```

This configuration:

* Outputs events (connection metadata) to the console for debugging
* Outputs objects (request/response content) to the console for debugging
  {% endtab %}

{% tab title="S3 Endpoint" %}

```yaml
services:
  # For connection metadata (anonymized)
  event_stores:
    - id: console_stdout
      type: stdout
  
  # For actual request/response content
  object_stores:
    - id: minio
      type: s3
      endpoint: 127.0.0.1:9000
      bucket: qpoint
      region: us-east-1
      access_url: http://localhost:9000/{{BUCKET}}/{{DIGEST}}
      insecure: true
      access_key:
        type: env
        value: S3_ACCESS_KEY
      secret_key:
        type: env
        value: S3_SECRET_KEY
```

This configuration:

* Outputs events (connection metadata) to the console for debugging
* Stores objects (request/response content) in a locally running MinIO S3-compatible store
* Uses environment variables for S3 credentials (recommended for security)
  {% endtab %}
  {% endtabs %}

### Step 3: Set Up Processing Plugins

Define how captured data will be processed:

```yaml
stacks:
  default_stack: # Stack Name
    plugins:
      - type: access_logs
        config:
          mode: details # Default action (summary|details|full)
          format: console # (json|console)
          rules:
            - name: summary log example.com
              expr: request.host == "example.com"
              mode: summary
            - name: details log on anything above 400
              expr: response.status >= 400
              mode: full
```

This configuration:

* Creates a stack named "default\_stack"
* The access logs plugin provides summary-level debug information with specific capture definitions for example.com, or full payload capture for traffic with a status code above 400

### Step 4: Configure Traffic Capture

Finally, set up what traffic to capture and send to plugins:

```yaml
tap:
  direction: egress
  ignore_loopback: false
  audit_include_dns: true
  http:
    stack: default_stack
```

This configuration:

* Captures all outgoing (egress) traffic
* Includes loopback traffic
* Includes DNS information in audit logs
* Applies the default\_stack to HTTP traffic for processing

## Example

Putting it all together:

```yaml
version: 2

services:
  event_stores:
    - id: console_stdout
      type: stdout
  object_stores:
    - id: console_stdout
      type: stdout

stacks:
  default_stack: # Stack Name
    plugins:
      - type: access_logs
        config:
          mode: details # Default action (summary|details|full)
          format: console # (json|console)
          rules:
            - name: summary log example.com
              expr: request.host == "example.com"
              mode: summary
            - name: details log on anything above 400
              expr: response.status >= 400
              mode: full
          
tap:
  direction: egress
  ignore_loopback: true
  audit_include_dns: true
  http:
    stack: default_stack
```
