Skip to main content

Secrets Detection (Rust)

Rust-backed secrets detection and redaction for ContextForge and MCP Gateway.

Features

  • Detects likely credentials in prompt arguments, tool inputs, tool outputs, and resource content
  • Built-in detectors for AWS keys, Google API keys, GitHub tokens, Stripe keys, Slack tokens, and private key blocks
  • Optional broad detectors for generic API key assignments, JWT-like strings, long hex strings, and base64-like secrets
  • Blocking, redaction, or metadata-only reporting modes
  • Recursive scanning for nested dicts, lists, tuples, Pydantic-style objects, __dict__, and __slots__
  • Optional dotted field allowlist and denylist controls for structured payload scanning
  • Sanitized outward metadata that reports finding types and counts, not original secret values

Build

make install

Runtime Requirements

This plugin depends on cpex>=0.1.0,<0.2 and imports hook models from cpex.framework. The compiled Rust extension is mandatory; there is no Python fallback implementation.

Usage

The plugin scans these hooks:

  • prompt_pre_fetch: scans payload.args
  • tool_pre_invoke: scans tool invocation payloads before execution
  • tool_post_invoke: scans payload.result
  • resource_post_fetch: scans payload.content.text

Typical uses:

  • block requests that contain likely credentials before they reach tools or prompts
  • redact secrets from returned tool or resource payloads
  • surface sanitized findings metadata for observability and tuning

Detection Coverage

Enabled by default:

  • aws_access_key_id
  • aws_secret_access_key
  • google_api_key
  • github_token
  • stripe_secret_key
  • slack_token
  • private_key_block

Disabled by default because they are broader and more false-positive-prone:

  • generic_api_key_assignment
  • jwt_like
  • hex_secret_32
  • base64_24

The detectors are regex-based. They do not verify whether a credential is real, active, or revoked.

Configuration

config:
  enabled:
    aws_access_key_id: true
    aws_secret_access_key: true
    google_api_key: true
    github_token: true
    stripe_secret_key: true
    slack_token: true
    private_key_block: true
    generic_api_key_assignment: false
    jwt_like: false
    hex_secret_32: false
    base64_24: false
  redact: false
  redaction_text: "***REDACTED***"
  block_on_detection: true
  min_findings_to_block: 1
  field_allowlist: []
  field_denylist: []
Field Type Default Description
enabled dict built-in defaults Per-detector enable flags; unspecified detectors inherit defaults
redact bool false Replace matched secret values in returned payloads
redaction_text string "***REDACTED***" Replacement text used when redact=true
block_on_detection bool true Return a violation when enough findings are present
min_findings_to_block integer 1 Minimum finding count required before blocking
field_allowlist list[string] [] Dotted field paths eligible for scanning; empty means all structured fields are eligible
field_denylist list[string] [] Dotted field paths excluded from scanning; denylist entries take precedence over allowlist entries

Field Filtering

field_allowlist and field_denylist apply to structured scan targets:

  • prompt_pre_fetch: paths are relative to payload.args
  • tool_pre_invoke: paths are relative to payload.args
  • tool_post_invoke: paths are relative to payload.result

For example, accounts.credentials.token matches payload.args.accounts.credentials.token in pre-hooks and payload.result.accounts.credentials.token in tool_post_invoke.

Rules:

  • An empty field_allowlist scans all structured fields.
  • A non-empty field_allowlist scans only the listed paths and their descendants.
  • A field_denylist entry excludes that path and all descendants.
  • When both lists match, field_denylist wins.
  • Parent containers are still traversed to reach nested allowlisted paths.
  • Matching is segment-aware: layer1 does not match layer10.
  • Lists and tuples are transparent to field matching; numeric indices are not used.
  • Mapping keys themselves are not scanned.
  • Direct scalar scan targets, including payload.content.text in resource_post_fetch, retain current behavior and are not filtered by field paths.

Valid field paths use non-empty dot-separated segments. Empty paths, whitespace-only paths, leading or trailing dots, and empty segments such as layer1..token are rejected during plugin initialization.

Example:

config:
  field_allowlist:
    - "layer1"
    - "accounts.credentials"
  field_denylist:
    - "layer1.layer2.layer3"
    - "accounts.credentials.test_token"

Behavior Notes

  • Redaction preserves payload shape where possible instead of flattening everything to plain dicts.
  • aws_secret_access_key recognizes = and : assignments with optional single or double quotes around the value.
  • private_key_block detects whole PEM private key blocks for RSA, DSA, EC, OpenSSH, encrypted, and generic PKCS#8 keys. Redaction replaces the opening marker, key body, and matching closing marker with one replacement.
  • A private key block closes only at an end marker of the same key type. If that marker is missing, redaction extends to the end of the string. Blocks split across separate string values are not scanned as one block.
  • aws_secret_access_key, generic_api_key_assignment, and base64_24 use capture-group redaction so only the detected secret span is replaced; assignment labels, separators, quotes, and leading non-base64 boundary characters are preserved.
  • Broad detectors remain opt-in to reduce noisy matches on ordinary identifiers.
  • Binary resource bodies are not scanned; resource_post_fetch only scans text content exposed as payload.content.text.
  • The plugin does not decode archives, compressed data, or arbitrary encoded blobs before scanning.

Returned Metadata

prompt_pre_fetch, tool_pre_invoke, tool_post_invoke, and resource_post_fetch accept an optional extensions parameter carrying OpenTelemetry trace context. When a trace context is present (via extensions.request.trace_id), the plugin emits operational metrics on result.metadata["secrets_detection"] with the following schema:

result.metadata["secrets_detection"] = {
    "total_detections": 2,   # int — total number of findings in this call
    "total_masked": 2,       # int — number redacted (masking action taken)
    "total_blocked": 0,      # int — number that caused a block (blocking action taken)
    "secret_types": ["aws_access_key_id", "slack_token"],  # list[str] — distinct type names, sorted, deduped
}

total_masked and total_blocked are mutually exclusive per call: exactly one of them carries the finding count (the other is 0), depending on whether the redaction branch or the blocking branch executed. If neither redaction nor blocking is configured, both are 0 and only total_detections/secret_types are non-zero (findings-only reporting mode).

Gating: Metrics are only emitted when a valid trace_id is present in the trace context (extensions.request.trace_id). No trace context means no result.metadata write at all, regardless of any config flag — this keeps the untraced path byte-for-byte identical to before metrics existed.

Security Note (S1): The plugin never includes raw secret values in result.metadata, logs, or any other output. Only counts and type-category names (e.g. "aws_access_key_id") are reported.

tool_pre_invoke is in scope for this metrics contract on the same terms as the other 3 hooks: it accepts extensions and emits result.metadata["secrets_detection"] under the identical gating/schema once a valid trace_id is present.

Blocking responses use the SECRETS_DETECTED violation code.

Migration Note

Version 0.3.8 adds optional field filtering:

  • field_allowlist and field_denylist default to empty lists, so existing configurations keep scanning the same fields as before.
  • When configured, field filters affect detection counts, metadata, redaction, min_findings_to_block, and blocking decisions.
  • field_denylist entries take precedence over field_allowlist entries.

Version 0.3.7 is a breaking change for any existing consumer reading detection metadata:

  • The old flat result.metadata keys — secrets_redacted, count (redaction path) and secrets_findings, count (findings-only path) — have been removed entirely. There is no compatibility shim; code reading those keys will silently stop receiving data.
  • Detection/redaction/blocking metrics are now emitted on result.metadata["secrets_detection"] instead, with keys total_detections, total_masked, total_blocked, and secret_types (see Returned Metadata above for the full schema).
  • All 4 hooks — prompt_pre_fetch, tool_pre_invoke, tool_post_invoke, and resource_post_fetch — now accept a new optional extensions parameter carrying OpenTelemetry trace context. Emission to result.metadata["secrets_detection"] is gated solely on extensions.request.trace_id being present and valid — if no trace context is supplied, no metrics are written at all, regardless of any config flag.
  • Consumers that previously read result.metadata["secrets_redacted"] / result.metadata["secrets_findings"] unconditionally must migrate to reading result.metadata["secrets_detection"] and must pass a trace_id via extensions to receive metrics.
  • tool_pre_invoke previously never received extensions and could never emit metrics (a regression introduced earlier on this branch, since fixed) — it now follows the exact same contract as the other 3 hooks.

Security Notes

  • Outward-facing findings metadata and violation examples do not include original matched secret values.
  • Enable broad detectors only after testing against representative payloads.
  • The detector is best-effort pattern matching and should complement, not replace, upstream secret management controls.

Testing

make ci

Metadata

Release files for cpex-secrets-detection 0.3.16

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for cpex-secrets-detection 0.3.16
File Size Uploaded Provenance Actions
cpex_secrets_detection-0.3.16.tar.gz 60.5 kB With provenance Details for cpex_secrets_detection-0.3.16.tar.gz

Built distributions (wheels)

Table of built distributions (wheels) for cpex-secrets-detection 0.3.16
File Actions
cpex_secrets_detection-0.3.16-cp311-abi3-win_amd64.whl CPython 3.11 abi3 Windows x86-64 Details for cpex_secrets_detection-0.3.16-cp311-abi3-win_amd64.whl
cpex_secrets_detection-0.3.16-cp311-abi3-manylinux_2_34_x86_64.whl CPython 3.11 abi3 Linux glibc 2.34+ x86-64 Details for cpex_secrets_detection-0.3.16-cp311-abi3-manylinux_2_34_x86_64.whl
cpex_secrets_detection-0.3.16-cp311-abi3-manylinux_2_34_s390x.whl CPython 3.11 abi3 Linux glibc 2.34+ IBM System/390x Details for cpex_secrets_detection-0.3.16-cp311-abi3-manylinux_2_34_s390x.whl
cpex_secrets_detection-0.3.16-cp311-abi3-manylinux_2_34_ppc64le.whl CPython 3.11 abi3 Linux glibc 2.34+ PowerPC 64-le Details for cpex_secrets_detection-0.3.16-cp311-abi3-manylinux_2_34_ppc64le.whl
cpex_secrets_detection-0.3.16-cp311-abi3-manylinux_2_34_aarch64.whl CPython 3.11 abi3 Linux glibc 2.34+ ARM64 Details for cpex_secrets_detection-0.3.16-cp311-abi3-manylinux_2_34_aarch64.whl
cpex_secrets_detection-0.3.16-cp311-abi3-macosx_11_0_arm64.whl CPython 3.11 abi3 macOS 11.0+ ARM64 Details for cpex_secrets_detection-0.3.16-cp311-abi3-macosx_11_0_arm64.whl

Total release size: 5.1 MB

Release files / cpex_secrets_detection-0.3.16.tar.gz

Download URL cpex_secrets_detection-0.3.16.tar.gz
Size 60.5 kB
Tags Source
SHA-256 checksum
How to use checksums
27d6eda8ff09aba82c2cdce4bb59f179702fed1b8e6e4d789177a39f2c275e9b
BLAKE2b-256 checksum
How to use checksums
518b017f91110233b8fc4112e012137903f911c46ba68464da22160808d5a488
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 28, 2026.

Transparency log

Release files / cpex_secrets_detection-0.3.16-cp311-abi3-win_amd64.whl

Download URL cpex_secrets_detection-0.3.16-cp311-abi3-win_amd64.whl
Size 787.5 kB
Tags CPython 3.11 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
ce8690b53d70d93a92554de03d64af88c408a77e6cfce1a4a5b86284f1859ba8
BLAKE2b-256 checksum
How to use checksums
ea40e4d884914d0084a22536a68510b2d5c3aaffc1cafef975432c4b02da65f7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 28, 2026.

Transparency log

Release files / cpex_secrets_detection-0.3.16-cp311-abi3-manylinux_2_34_x86_64.whl

Download URL cpex_secrets_detection-0.3.16-cp311-abi3-manylinux_2_34_x86_64.whl
Size 860.1 kB
Tags CPython 3.11 Linux glibc 2.34+ x86-64 abi3
SHA-256 checksum
How to use checksums
f276d5a3fc12b0684eda3425076b8b5637637a122e070bbf0211248db82dba33
BLAKE2b-256 checksum
How to use checksums
2b0ec149ca79702c7f662aec8534d68c26374f84fb1f51cd0bc6b51a98dcc721
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 28, 2026.

Transparency log

Release files / cpex_secrets_detection-0.3.16-cp311-abi3-manylinux_2_34_s390x.whl

Download URL cpex_secrets_detection-0.3.16-cp311-abi3-manylinux_2_34_s390x.whl
Size 907.5 kB
Tags CPython 3.11 Linux glibc 2.34+ IBM System/390x abi3
SHA-256 checksum
How to use checksums
b26faa50c493dec78dff084d6ba13fa719fe307a51c04f716d27ea90cba260f1
BLAKE2b-256 checksum
How to use checksums
2a4a348385922ed3a12142e26476d3427703830107b6c94b0dd2d1a44e6f26f2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 28, 2026.

Transparency log

Release files / cpex_secrets_detection-0.3.16-cp311-abi3-manylinux_2_34_ppc64le.whl

Download URL cpex_secrets_detection-0.3.16-cp311-abi3-manylinux_2_34_ppc64le.whl
Size 888.1 kB
Tags CPython 3.11 Linux glibc 2.34+ PowerPC 64-le abi3
SHA-256 checksum
How to use checksums
b029348d8464cb4e6cb7a89bb576414fdefeee019d61c695c6ae9ca7a726b5c8
BLAKE2b-256 checksum
How to use checksums
0645a40accd47c4f3dfe06d2c31ddb14cbbae3787507727515f790d296fbf978
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 28, 2026.

Transparency log

Release files / cpex_secrets_detection-0.3.16-cp311-abi3-manylinux_2_34_aarch64.whl

Download URL cpex_secrets_detection-0.3.16-cp311-abi3-manylinux_2_34_aarch64.whl
Size 803.5 kB
Tags CPython 3.11 Linux glibc 2.34+ ARM64 abi3
SHA-256 checksum
How to use checksums
ba5c82c42840de9952d39b8bc63ff5ee48596a66a4ff4fddd843eecb786809a8
BLAKE2b-256 checksum
How to use checksums
9548e097905133a56d4c2d6818005b1d79b74e6fa6f666d7ef8835814e919056
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 28, 2026.

Transparency log

Release files / cpex_secrets_detection-0.3.16-cp311-abi3-macosx_11_0_arm64.whl

Download URL cpex_secrets_detection-0.3.16-cp311-abi3-macosx_11_0_arm64.whl
Size 751.6 kB
Tags CPython 3.11 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
4100f3baba45835ad4c1a6487428c03d5e424b48ff55970340576abc56ca667f
BLAKE2b-256 checksum
How to use checksums
c6d52775dfb63a792f569733c90d4df3f6a6c5e363f960ccfb3922a7cf2c201e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 28, 2026.

Transparency log

Security for cpex-secrets-detection 0.3.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 7 files in this release have been uploaded with provenance metadata.

Select from 7 files

Attestation for cpex_secrets_detection-0.3.16.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 28, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page