---
title: "loki.secretfilter | Grafana Alloy documentation"
description: "Learn about loki.secretfilter"
---

# `loki.secretfilter`

> **EXPERIMENTAL**: This is an [experimental](/docs/release-life-cycle/) component. Experimental components are subject to frequent breaking changes, and may be removed with no equivalent replacement. To enable and use an experimental component, you must set the `stability.level` [flag](/docs/alloy/latest/reference/cli/run/) to `experimental`.

`loki.secretfilter` receives log entries and redacts detected secrets from the log lines. The detection relies on regular expression patterns, defined in the Gitleaks configuration file embedded within the component. `loki.secretfilter` can also use a [custom configuration file](#arguments) based on the [Gitleaks configuration file structure](https://github.com/gitleaks/gitleaks/blob/master/config/gitleaks.toml).

> Caution
> 
> Personally Identifiable Information (PII) isn’t currently in scope and some secrets could remain undetected. This component may generate false positives or redact too much. Don’t rely solely on this component to redact sensitive information.

> Note
> 
> This component operates on log lines and doesn’t scan labels or other metadata.

> Caution
> 
> Detecting secrets can be resource-intensive and can increase CPU usage significantly. Roll out this component gradually and monitor resource usage. Place `loki.secretfilter` after components that reduce log volume so it processes fewer lines.

## Usage

Alloy ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```alloy
loki.secretfilter "<LABEL>" {
    forward_to = <RECEIVER_LIST>
}
```

## Arguments

You can use the following arguments with `loki.secretfilter`:

Expand table

| Name                 | Type                 | Description                                                                                                                 | Default | Required |
|----------------------|----------------------|-----------------------------------------------------------------------------------------------------------------------------|---------|----------|
| `forward_to`         | `list(LogsReceiver)` | List of receivers to send log entries to.                                                                                   |         | yes      |
| `drop_on_timeout`    | `bool`               | When true, drop entries that exceed `processing_timeout` instead of forwarding them unredacted.                             | `false` | no       |
| `gitleaks_config`    | `string`             | Path to a custom Gitleaks TOML config file. If empty, the default Gitleaks config is used.                                  | `""`    | no       |
| `label_timed_out`    | `bool`               | When true, adds `secretfilter="timed-out"` to entries forwarded after a processing timeout.                                 | `false` | no       |
| `origin_label`       | `string`             | Loki label to use as the `origin` dimension in `secrets_redacted_by_category_total`.                                        | `""`    | no       |
| `processing_timeout` | `duration`           | Maximum time allowed to process a single log entry. `0` disables the timeout.                                               | `0`     | no       |
| `rate`               | `float`              | Entry sampling rate in `[0.0, 1.0]` where `1` processes all entries. Unsampled entries are forwarded unchanged.             | `1.0`   | no       |
| `redact_percent`     | `uint`               | When `redact_with` is not set: percent of the secret to redact (1–100), where 100 is full redaction.                        | `80`    | no       |
| `redact_with`        | `string`             | Template for the redaction placeholder. Use `$SECRET_NAME` and `$SECRET_HASH`, for example, `"<$SECRET_NAME:$SECRET_HASH>"` | `""`    | no       |

The `gitleaks_config` argument is the path to a custom [Gitleaks TOML config file](https://github.com/gitleaks/gitleaks/blob/master/config/gitleaks.toml). The file supports the standard Gitleaks structure (rules, allowlists, and `[extend]` to extend the default config). If `gitleaks_config` is empty, the component uses the default Gitleaks configuration [embedded in the component](https://github.com/grafana/alloy/blob/v1.16.1/internal/component/loki/secretfilter/gitleaks.toml).

> Note
> 
> The default configuration may change between Alloy versions. For consistent behavior, use an external configuration file via `gitleaks_config`.

If you leave `origin_label` empty, the component sets the origin label on `secrets_redacted_by_category_total` to `""`.

**Redaction behavior:**

- If `redact_with` is set, it is used as the replacement string for every detected secret. The supported placeholders are `$SECRET_NAME` (rule ID) and `$SECRET_HASH` (SHA1 hash of the secret).
- If `redact_with` is not set, redaction is percentage-based (Gitleaks-style). `redact_percent` controls how much of the secret is redacted. For example, `80` shows the first 20% of the secret followed by `"..."`. `100` replaces the entire secret with `"REDACTED"`. When `redact_percent` is 0 or unset, 80% redaction is used.

**Sampling:** The `rate` argument controls what fraction of log entries are processed by the secret filter. Entries that Alloy does not select based on the sampling rate pass through unchanged, with no detection or redaction applied. Use a value below `1.0`, for example, `0.1` for 10%, to reduce CPU usage when processing high-volume logs. Monitor `loki_secretfilter_entries_bypassed_total` to observe how many entries were skipped.

**Origin metric:** The `origin_label` argument specifies the Loki label the component uses as the origin dimension in `secrets_redacted_by_category_total`. You can track how many secrets were redacted per source or environment. When `origin_label` isn’t set, the `origin` label on `secrets_redacted_by_category_total` defaults to an empty string.

**Processing timeout:** The `processing_timeout` argument sets a maximum duration for processing each log entry. When the timeout is exceeded, the `loki_secretfilter_lines_timed_out_total` metric is incremented. By default (`drop_on_timeout = false`), the original unredacted entry is forwarded so no log lines are lost. When `drop_on_timeout = true`, entries that exceed the timeout are dropped and the `loki_secretfilter_lines_dropped_total` metric is incremented.

Set `label_timed_out = true` to add `secretfilter="timed-out"` to any entry that Alloy forwards after a timeout. You can then query timed-out lines in Loki, for example, with `{secretfilter="timed-out"}`. Alloy applies this label only to forwarded entries. It doesn’t label dropped entries when `drop_on_timeout = true`.

> Caution
> 
> Setting `drop_on_timeout = true` means log lines can be silently dropped. A dropped line can’t be recovered, whereas an unredacted line containing a secret can still be detected and mitigated later. Use this option only when dropping lines is preferable to forwarding potentially unredacted data.

## Blocks

The `loki.secretfilter` component doesn’t support any blocks. You can configure this component with arguments.

## Exported fields

The following fields are exported and can be referenced by other components:

Expand table

| Name       | Type           | Description                                                   |
|------------|----------------|---------------------------------------------------------------|
| `receiver` | `LogsReceiver` | A value that other components can use to send log entries to. |

## Component health

`loki.secretfilter` is only reported as unhealthy if given an invalid configuration.

## Debug metrics

`loki.secretfilter` exposes the following Prometheus metrics:

Expand table

| Name                                                   | Type    | Description                                                                                                                                                                  |
|--------------------------------------------------------|---------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `loki_secretfilter_entries_bypassed_total`             | Counter | Total number of entries forwarded without processing due to sampling.                                                                                                        |
| `loki_secretfilter_lines_dropped_total`                | Counter | Total number of log lines dropped due to processing timeout, when `drop_on_timeout` is `true`.                                                                               |
| `loki_secretfilter_lines_timed_out_total`              | Counter | Total number of log lines that exceeded the processing timeout, whether dropped or forwarded.                                                                                |
| `loki_secretfilter_processing_duration_seconds`        | Summary | Time taken to process and redact logs, in seconds.                                                                                                                           |
| `loki_secretfilter_secrets_redacted_total`             | Counter | Total number of secrets redacted.                                                                                                                                            |
| `loki_secretfilter_secrets_redacted_by_category_total` | Counter | Number of secrets redacted, partitioned by rule name and origin label value. The `origin` label is empty when `origin_label` is not set or the label is absent on the entry. |

## Example

This example uses `loki.secretfilter` to redact secrets from log lines before forwarding them to a Loki receiver. It uses a custom redaction template with `$SECRET_NAME` and `$SECRET_HASH`.

Alternatively, you can:

- Omit `redact_with` to use percentage-based redaction, which defaults to 80% redacted.
- Set `redact_percent` to `100` for full redaction.
- Set `gitleaks_config` to point to a custom Gitleaks TOML configuration file.
- Set `rate` to a value below `1.0` to sample entries and reduce CPU usage; entries not selected are forwarded unchanged.

Alloy ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```alloy
local.file_match "local_logs" {
    path_targets = "<PATH_TARGETS>"
}

loki.source.file "local_logs" {
    targets    = local.file_match.local_logs.targets
    forward_to = [loki.secretfilter.secret_filter.receiver]
}

loki.secretfilter "secret_filter" {
    forward_to  = [loki.write.local_loki.receiver]
    redact_with = "<ALLOY-REDACTED-SECRET:$SECRET_NAME:$SECRET_HASH>"
    // optional: gitleaks_config = "/etc/alloy/gitleaks.toml"
    // optional: redact_percent = 100  // use when redact_with is not set
}

loki.write "local_loki" {
    endpoint {
        url = "<LOKI_ENDPOINT>"
    }
}
```

Replace the following:

- *`<PATH_TARGETS>`* : The paths to the log files to monitor.
- *`<LOKI_ENDPOINT>`* : The URL of the Loki instance to send logs to.

## Compatible components

`loki.secretfilter` can accept arguments from the following components:

- Components that export [Loki `LogsReceiver`](../../../compatibility/#loki-logsreceiver-exporters)

`loki.secretfilter` has exports that can be consumed by the following components:

- Components that consume [Loki `LogsReceiver`](../../../compatibility/#loki-logsreceiver-consumers)

> Note
> 
> Connecting some components may not be sensible or components may require further configuration to make the connection work correctly. Refer to the linked documentation for more details.
