Skip to content

Releases: redact-secret/redact-secret-adapters

Release train 2026.09.30.2

Choose a tag to compare

@github-actions github-actions released this 30 Sep 21:29
0344e22

Release train 2026.09.30.2. Every package is versioned independently; this train shipped:

@redact-secret/adapter-otel-trace 0.1.0

Added

  • The package, under a name that says what it covers: OpenTelemetry JS
    traces (#49). It is the code
    @redact-secret/adapter-otel 0.1.2 shipped, unchanged: the same
    createRedactingSpanProcessor, RedactingSpanProcessorWith,
    redactAttributesWith, options (policy, maxStringLength, onOutcome,
    and pii on the live factory) and outcome shape, and the same
    REDACT_SECRET_SPAN_DROPPED warning, whose message still begins
    @redact-secret/adapter-otel: so a filter written against it keeps
    matching. It protects spans only — the span name, attributes, events, status
    message and link attributes. OpenTelemetry Logs (LogRecords) pass through
    no code in this package.
  • Declares @opentelemetry/sdk-trace-base ^2.0.0 and @redact-secret/core
    ^0.1.0-beta.6, the ranges adapter-otel 0.1.2 declared, backed by the
    same real-host tests (test/otel-host.test.ts, test/otel-lifecycle.test.ts,
    test/outcome.test.ts, test/vault-token.test.ts), which CI runs at both
    ends of each range. test/exporter-bytes.test.ts adds the final OTLP JSON
    bytes an exporter would send, for the injected and the live factory, through
    both SimpleSpanProcessor and BatchSpanProcessor.

@redact-secret/adapter-otel 0.1.3

Deprecated

  • This package is now a compatibility re-export of
    @redact-secret/adapter-otel-trace, the same
    processor under a name that says what it covers: OpenTelemetry traces
    (a SpanProcessor), not OpenTelemetry Logs
    (#49). Every export keeps its name,
    signature and behavior — createRedactingSpanProcessor,
    RedactingSpanProcessorWith (the same class object, so instanceof still
    holds), redactAttributesWith and the option and outcome types — and each
    is marked @deprecated in the type declarations. Nothing is printed at
    import or call time. Migrate by changing the import specifier to
    @redact-secret/adapter-otel-trace; see the
    migration guide.
    test/compat-shim.test.ts checks that every export is identical to the new
    package's and that a real BasicTracerProvider span exports the same OTLP
    JSON bytes through either name.

Changed

  • Depends on @redact-secret/adapter-otel-trace ^0.1.0 instead of
    @redact-secret/adapter directly (the trace package brings it). The
    @opentelemetry/sdk-trace-base ^2.0.0 and @redact-secret/core
    ^0.1.0-beta.6 peer ranges are unchanged, backed by the same tests, now in
    packages/adapter-otel-trace/test.

Release train 2026.09.30

Choose a tag to compare

@github-actions github-actions released this 30 Sep 20:47
2072d32

Release train 2026.09.30. Every package is versioned independently; this train shipped:

@redact-secret/adapter-mcp 0.1.2

Changed

  • The optional peer @modelcontextprotocol/sdk range is raised from
    >=1.13.0 <=1.30.1 to >=1.26.0 <=1.30.1. Every 1.x release before 1.26.0
    carries at least one of three high-severity SDK advisories:
    GHSA-w48q-cv73-mx4w (DNS rebinding protection off by default, fixed in
    1.24.0), GHSA-8r9q-7v3j-jr4g (ReDoS in UriTemplate, fixed in 1.25.2) and
    GHSA-345p-7cg4-v4c7 (cross-client data leak on server or transport reuse,
    fixed in 1.26.0). None is reachable from this adapter's own code. With the
    SDK installed, npm now refuses an older one with ERESOLVE. The new range is
    backed by test/transport.test.ts, test/resources-transport.test.ts and
    test/e2e.test.ts, run at both endpoints (1.26.0 and 1.30.1) by CI
    range-endpoints. 1.26.0 negotiates protocol 2025-11-25, so 2025-06-18 is
    no longer negotiated at a tested endpoint (#83).

Fixed

  • With binaryContent: "pass", a binary field (an image or audio block's
    data, a resource's blob) is read once. Before, the boundary checked that
    the value was a string and then read it again while rebuilding the result.
    A getter could return a non-string, unscanned value on the second read, and
    it went out as ok. A getter that threw on the second read escaped
    sanitizeToolResult, sanitizeResourceResult and the wrapped handlers as an
    exception. The boundary now passes on the string it checked. Backed by
    test/boundary-edges.test.ts (#91).
  • A streamed-result step whose done or value getter throws is now
    tool_error, and the boundary aborts the session and closes the producer.
    Before, the getter's error escaped
    sanitizeStreamedToolResult and wrapStreamedToolHandler as a rejection
    carrying the producer's own error, and the session stayed open. Backed by
    test/boundary-edges.test.ts (#92).

@redact-secret/adapter 0.1.5

Added

  • maxNodes walk budget (default 20000) in Limits and DEFAULT_LIMITS
    (#87). walkValue, behind
    maskSecretsWith and maskLogValueWith, budgeted only string leaves, and it
    walks a shared reference once per path. An in-process graph of 8 levels, each
    holding 1000 references to the next, therefore cost about 1000^7 container
    visits before any string budget tripped (a probe: 10^8 paths took 8 s).
    Every visited value now counts, containers included, using the same rule as
    walkStrict's maxNodes. Past the budget, every value becomes
    [REDACTED:LIMIT_EXCEEDED] (counted limited). The default is four times
    maxTotalLeaves, so a string-heavy value still meets the leaf budget first.
    Invalid overrides fall back to the default through resolveLimit. Tested by
    "maxNodes counts every visit…" and "a shared-reference DAG is bounded by
    maxNodes…" in test/mask-secrets.test.ts, and the shared
    shared_reference_dag_is_bounded_by_max_nodes and
    tightened_max_nodes_bounds_a_shared_reference_dag cases in
    fixtures/bounded-traversal-cases.json.

redact-secret-adapters (PyPI) 0.1.2

Added

  • max_nodes walk budget (default 20000) in DEFAULT_LIMITS
    (#87). The walker behind
    mask_secrets_with, mask_log_value_with and extra_fields budgeted only
    string leaves, and it walks a shared reference once per path. An in-process
    graph of shared lists therefore cost exponential time before any string
    budget tripped (a probe: 10^8 paths took 85 s). Every visited value now
    counts, containers included, with the same rule and default as the
    TypeScript maxNodes. Past the budget, every value becomes
    [REDACTED:LIMIT_EXCEEDED] (counted limited). Invalid overrides fall back
    to the default through resolve_limit. Tested by
    test_max_nodes_counts_every_visit_once_per_path,
    test_a_shared_reference_dag_is_bounded_by_max_nodes_not_its_path_count, and
    the shared shared_reference_dag_is_bounded_by_max_nodes and
    tightened_max_nodes_bounds_a_shared_reference_dag cases.

Changed

  • An object the walker does not walk now fails closed to
    [REDACTED:ERROR]
    instead of passing through unchanged
    (#85). This covers a set, bytes, a
    dataclass, a datetime, or any other instance reached by
    mask_secrets_with, mask_log_value_with, or a RedactSecretFilter
    extra_fields entry. Before, a %(ctx)s format or a JSON formatter with
    default=str printed such a value unscanned. str, int, float,
    bool and None are unchanged, and dict, list, tuple and
    exceptions are still walked. To keep such a value, convert it to a
    dict or str before logging it. Tested by
    test_any_other_object_fails_closed_to_the_error_marker,
    test_a_non_container_object_extra_fails_closed_for_str_and_json_formatters,
    and the shared opaque_object_never_passes_its_secret_through case in
    fixtures/bounded-traversal-cases.json.

Fixed

  • A container whose read raises (a dict subclass whose __getitem__ or
    keys() raises, a list subclass whose slicing raises) no longer raises
    out of the walk, or out of logger.info() through RedactSecretFilter
    (#85). It becomes [REDACTED:ERROR] for that key alone, or for the whole
    container when it cannot be listed, as in the TypeScript walker. Tested by
    test_a_container_whose_read_raises_degrades_per_entry_and_never_raises,
    test_an_extra_whose_read_raises_never_raises_into_the_logging_call, and
    the shared throwing_entry_degrades_for_that_entry_alone case.
  • limits are validated like the TypeScript resolveLimit (#85): None,
    NaN, a negative number, a bool, or a non-number falls back to that
    key's default. Before, max_depth=None raised TypeError out of
    filter(), max_total_leaves=float("nan") never tripped, and
    max_array_length=-1 kept all but the last element. Tested by
    test_an_invalid_limit_falls_back_to_the_default_instead_of_disabling_it,
    test_invalid_limits_fall_back_to_the_defaults_instead_of_raising, and the
    shared invalid_*_limits_fall_back_to_the_defaults cases.

Release train 2026.09.29.4

Choose a tag to compare

@github-actions github-actions released this 29 Sep 19:33
646bbee

Release train 2026.09.29.4. Every package is versioned independently; this train shipped:

@redact-secret/adapter 0.1.4

Changed

  • The PII_ACTIVATION_CONFLICT documentation in activation.ts now shows the
    pii-context/v2 vocabulary that core 0.1.0-beta.11 reports. Documentation
    only; no behaviour change.

Release train 2026.09.29.3

Choose a tag to compare

@github-actions github-actions released this 29 Sep 16:08
53fc7fc

Release train 2026.09.29.3. Every package is versioned independently; this train shipped:

@redact-secret/adapter-ai-context 0.1.1

Fixed

  • The package README no longer calls the package a prerelease or tells the
    reader to install @alpha; 0.1.0 is stable and published as latest.

@redact-secret/adapter-mcp 0.1.1

Fixed

  • The package README no longer calls the package a prerelease or tells the
    reader to install @alpha; 0.1.0 is stable and published as latest.

Release train 2026.09.29.2

Choose a tag to compare

@github-actions github-actions released this 29 Sep 15:15
cf9be96

Release train 2026.09.29.2. Every package is versioned independently; this train shipped:

@redact-secret/adapter-ai-context 0.1.0

Changed

  • First stable release: published under the npm dist-tag latest. The code is
    that of 0.1.0-alpha.2 plus the scan reuse below.
  • sanitizeValue and buildContext scan each distinct text once per call
    (texts up to 1,024 code units), reusing the result for repeats such as a
    content envelope's type / text keys. Output, findings, onFinding
    (still once per occurrence), maxNodes counting and outcomes are
    unchanged. The ai-context-js workload drops from 28 to about 20 core
    calls per event (#107).

@redact-secret/adapter-mcp 0.1.0

Changed

  • First stable release: published under the npm dist-tag latest. The code is
    that of 0.1.0-alpha.2 plus the scan reuse below.
  • A tool result's repeated envelope strings reach the core once per crossing:
    the value scan reuses identical texts, and the key-context check skips a
    serialized part that already scanned with no findings. Outputs, findings and
    onFinding (once per occurrence) are unchanged (#107).

Release train 2026.09.29

Choose a tag to compare

@github-actions github-actions released this 29 Sep 08:57
f57bd4e

Release train 2026.09.29. Every package is versioned independently; this train shipped:

@redact-secret/adapter-ai-context 0.1.0-alpha.2

Added

  • pii on createAiContextBoundary, carried by
    AiContextBoundaryOptionsWithDefaults
    (#51). It activates core PII
    selectors for the whole process through @redact-secret/adapter's
    activateCore. The factory's contract of never rejecting is unchanged:
    a selection that cannot be shown to be active is an initialization
    failure like any other, so every operation fails closed as blocked /
    core_error with no code, rather than quietly building context with
    PII off. pii is read by property, so an activation inherited through a
    prototype survives, the same rule withDefaultLimits follows.

  • AI_CONTEXT_DEFAULT_LIMITS and withDefaultLimits(options?), and
    createAiContextBoundary(options?) now fills in any of the three limit sets
    a caller leaves out (#46). A new
    integration no longer has to invent four security numbers before its first
    sanitizeText. The values are the ones this repository has been exercising
    all along — the README example, the clean-install smoke test, and the core's
    conformance replay.

  • The AiContextLimits and AiContextBoundaryOptionsWithDefaults types.

Fixed

  • An application that had already run initialize({ pii }) got a boundary
    that blocked everything: the factory's own argument-free initialize()
    is a different selection to the core's one-shot cell and rejected with
    PII_ACTIVATION_CONFLICT, which this package maps to a fail-closed
    blocked / core_error — a silently blocked boundary rather than a
    visible error. That conflict now counts as success, since it means the
    core is already loaded under the application's own selection. Every
    other initialization failure still fails closed exactly as before.

  • withDefaultLimits reads policy, placeholderFormatter and onFinding
    by name rather than by spreading options, so an options object layered over
    a shared base (Object.create(defaults)) keeps them.
    createAiContextBoundaryWith destructures its options, which follows the
    prototype chain, so before this an inherited policy would have been
    silently dropped and the boundary would have run on the core's default
    policy — a quiet weakening, with no error. An inherited limit set is used
    rather than overwritten by the preset, and a key this helper does not know
    about is forwarded rather than dropped.

Changed

  • The declared @redact-secret/adapter range rises to ^0.1.3, the
    version that carries activateCore. The declared
    @redact-secret/core range is unchanged at ^0.1.0-beta.6.

  • The README leads with the short call and moves the limits below it, with a
    table of what each bound covers, and states next to the example that
    non-JSON values, binary content and encoded text are blocked rather than
    decoded, and that a cancelled operation is aborted.

Not changed, deliberately: limits are still mandatory and still finite.
AI_CONTEXT_DEFAULT_LIMITS is a frozen set of eight positive integers, not
an unbounded mode
and not a way to switch a bound off. A limit set that is
passed is used exactly as passed, never merged field by field with the preset,
because a half-specified set should be rejected by the core rather than
silently completed. createAiContextBoundaryWith, the injected API, still
requires all three sets and throws a TypeError without them — pass
withDefaultLimits() to hand it the preset. Every existing caller that passes
all three behaves exactly as it did. test/defaults.test.ts asserts against
the real core that each preset bound is enforced and fails closed as
limit_exceeded, that a streamed text agrees with sanitizeText at every
chunk partition under it, and that an override replaces rather than widens.

Documented

  • Activating PII is not the same as masking every PII value: under the
    core's default policy High-confidence PII redacts while Medium and
    Low resolve to warn, and a warn finding leaves the text alone, so
    an ok outcome can carry findings whose text was not changed and
    lower-confidence PII reaches the model as plaintext. Supply your own
    policy mapping those findings to redact if you need them masked.

@redact-secret/adapter-mcp 0.1.0-alpha.2

Added

  • pii on createMcpBoundary, forwarded to createAiContextBoundary the
    way the limits already are
    (#51). It activates core PII
    selectors for the whole process. The factory's contract of never
    rejecting is unchanged: a selection that cannot be shown to be active
    fails every operation closed as blocked / core_error, which maps to
    the fixed blocked result, rather than quietly sanitizing with PII off.

  • createMcpBoundary(options?) now fills in any of the three limit sets a
    caller leaves out, from @redact-secret/adapter-ai-context's
    AI_CONTEXT_DEFAULT_LIMITS (#46), so a
    host can start with await createMcpBoundary() and a checked outcome.
    binaryContent and onAudit compose with the defaults unchanged.

  • The CreateMcpBoundaryOptionsWithDefaults type.

Fixed

  • An application that had already run initialize({ pii }) got a boundary
    that blocked everything, because the AI-context factory's argument-free
    initialize() rejected with PII_ACTIVATION_CONFLICT against the
    core's one-shot selection cell and that mapped to a fail-closed
    blocked / core_error. That conflict now counts as success. Every
    other initialization failure still fails closed exactly as before.

Documented

  • Activating PII is not the same as masking every PII value: under the
    core's default policy High-confidence PII redacts while Medium and
    Low resolve to warn, and a warn finding leaves the text alone, so
    an ok outcome can carry findings whose text was not changed. Supply
    your own policy mapping those findings to redact if you need them
    masked.

Changed

  • The README leads with the short call, moves the limits below it, and states
    next to the example what refuses and why: a binary payload blocks by default
    because it cannot be scanned (binaryContent: "pass" passes a string
    payload unscanned at its original position), a content type no qualified
    protocol revision defines blocks, and a cancelled call is aborted with
    toCallToolResult returning null.
  • @redact-secret/adapter-ai-context range raised from ^0.1.0-alpha.1 to
    ^0.1.0-alpha.2, the version that carries the default limits this release
    relies on. Backed by this package's tests and the published-sibling
    combination job.

Not changed: there is no unbounded mode, the bounds still fail an oversized
result closed as blocked / limit_exceeded, and createMcpBoundaryWith over
a boundary the host built itself is untouched. test/defaults.test.ts asserts
the defaults, an override, the binary block, an unsupported content type, and
an aborted call on the real core.

@redact-secret/adapter-otel 0.1.2

Added

  • pii on createRedactingSpanProcessor, with the
    CreateRedactingSpanProcessorOptions type
    (#51). It activates core PII
    selectors for the whole process through @redact-secret/adapter's
    activateCore, and the factory rejects — with a fixed code
    (PII_ACTIVATION_NOT_ACTIVE, or PII_ACTIVATION_UNSUPPORTED against a
    core that reports no activation) and no selector, input or core message
    in the error — rather than return a processor that scans with PII
    silently off.

  • onOutcome, on both createRedactingSpanProcessor and
    RedactingSpanProcessorWith: one input-free summary per span
    (#45), carrying the six shared value
    counts and dropped. dropped is this processor's own decision — it did
    not hand the span to the next processor because a masked value would not
    write back. It does not mean the span was sampled out, and false does
    not mean the span was exported: whether the next processor kept it and
    whether an exporter succeeded are things this adapter never learns and does
    not report. The observer is called synchronously once the span has been
    forwarded or dropped; anything it throws is swallowed, never read, and
    never changes what is exported; it is re-entrancy- and thread-guarded; and
    no exporter or network client is created for it.

  • RedactingSpanProcessorOptions and OtelSpanOutcome types. The
    processor's third argument was already { policy, maxStringLength } and
    still accepts exactly that.

Fixed

  • An application that had already run initialize({ pii }) could not build
    this processor: the factory's own argument-free initialize() is a
    different selection to the core's one-shot cell and rejected with
    PII_ACTIVATION_CONFLICT. That conflict now counts as success, since it
    means the core is already loaded under the application's own selection.
    Every other initialization failure still rejects exactly as before.

  • A span's attribute values are now counted by the processor's own
    masker. They were redacted correctly...

Read more

Release train 2026.09.26

Choose a tag to compare

@github-actions github-actions released this 26 Sep 04:51
be3f2ad

Release train 2026.09.26. Every package is versioned independently; this train shipped:

@redact-secret/adapter-ai-context 0.1.0-alpha.1

Added

  • The resource boundary label (redact-secret/redact-secret#843), for the
    contents of an MCP resources/read result. Telemetry-only, like every
    label; a type-level addition to BoundaryLabel.

Changed

  • Contract change: key-aware sanitizeValue (redact-secret/redact-secret#842,
    redact-secret-adapters#32). A string leaf under an object key that its own
    scan does not redact is scanned once more, through the same
    scanAndRedact, in its key-context view {"<key>":"<leaf>"}; a finding
    there is redacted at the leaf, with leaf offsets. Only the immediate key
    counts (array elements, parent and sibling keys give none), a finding
    outside the leaf's span that would redact or block blocks as policy, and
    a view over maxInputBytes blocks as limit_exceeded. No key pattern or
    name list is added: the core decides. Migration: a leaf that passed in
    plaintext because only its key identified it ({"password": "<value>"})
    is now replaced by a placeholder and reported in ok.findings and
    telemetry; nothing previously redacted or blocked passes. Qualified by the
    core fixture vendored at the #842 commit
    (packages/adapter-ai-context/test/conformance.test.ts) at both core range
    endpoints.
  • Dependency range: @redact-secret/adapter ^0.1.1 → ^0.1.2
    (redact-secret-adapters#36). The key-aware sanitizeValue needs the
    walkStrict that hands each leaf its key, first shipped in
    @redact-secret/adapter 0.1.2. Against the published 0.1.1, which
    ^0.1.1 still allowed, the walker passes no key, so a key-identified leaf
    such as {"password": "<value>"} was blocked as policy instead of redacted
    in place. It failed closed, but it broke the contract above, and no in-repo
    test could see it because every one uses the workspace walker.
    scripts/check-published-combination.mjs now installs this package with the
    lowest registry version its range allows and runs the key-aware probe.

@redact-secret/adapter-mcp 0.1.0-alpha.1

Added

  • resources/read (redact-secret/redact-secret#843,
    redact-secret-adapters#33): sanitizeResourceResult,
    sanitizeResourceRead (host placement, around a client readResource),
    and wrapResourceReadHandler (a server read callback of either SDK line,
    McpServer.registerResource fixed URIs and URI templates, or a low-level
    resources/read handler). A ReadResourceResult is one AI-context
    sanitizeValue under the new resource label, then the same key-context
    backstop; entry text is scanned as text whatever its mimeType; an entry
    must be exactly one of text or blob, and a blob follows
    binaryContent. Failures map to fixed JSON-RPC errors (code -32603, a
    fixed message, no data) through toReadResourceResponse, and the wrapper
    throws them as McpResourceError; a read failure is the new read_error
    outcome, its error never read. The audit stage gains resource.
    Qualified by the core mcp-resources-read fixture and runner vendored at
    the #843 commit (test/conformance*.test.ts), replayed over real SDK
    clients and servers at both endpoints of both lines on stdio and
    Streamable HTTP (test/resources-transport.test.ts), and exercised at the
    host placement in test/e2e.test.ts. No declared range changes.

Changed

  • Dependency range: @redact-secret/adapter-ai-context ^0.1.0-alpha →
    ^0.1.0-alpha.1
    (redact-secret-adapters#36). The narrowed key-context
    backstop below relies on the key-aware sanitizeValue, which the published
    0.1.0-alpha does not have. Paired with it, a _meta.password leaf in a
    resources/read result was blocked as policy instead of redacted.
    scripts/check-published-combination.mjs guards the pairing.

  • Contract change: the key-context check is narrowed to a backstop
    (redact-secret/redact-secret#842, redact-secret-adapters#32). The
    AI-context sanitizeValue is now key-aware and redacts a leaf its own key
    identifies in place, so the serialized rescan no longer blocks such a
    result; it still blocks, as policy, on context only the serialization
    shows (a sibling or parent key). Migration: a result or argument set
    that was blocked / policy only through the key-context check is now
    ok, with that leaf replaced by a placeholder and its finding reported
    through onFinding; hosts that relied on the block should watch
    onFinding. Nothing previously redacted or blocked passes. Qualified by the
    core fixture vendored at the #842 commit
    (packages/adapter-mcp/test/conformance.test.ts,
    packages/adapter-mcp/test/transport.test.ts) at both SDK line endpoints.

@redact-secret/adapter 0.1.2

Added

  • walkStrict hands each string leaf's visitor a second argument, key:
    the object key the leaf sits directly under, or undefined for an array
    element and the root (redact-secret/redact-secret#842). Visitors that take
    one argument are unaffected. @redact-secret/adapter-ai-context uses it for
    its key-aware sanitizeValue.

Release train 2026.09.25

Choose a tag to compare

@github-actions github-actions released this 25 Sep 21:20
ea92c2a

Release train 2026.09.25. Every package is versioned independently; this train shipped:

@redact-secret/adapter-ai-context 0.1.0-alpha

First release, as a prerelease.

Added

  • The framework-neutral AI-context boundary (redact-secret/redact-secret#610,
    redact-secret-adapters#12): createAiContextBoundary(options) (live: loads
    and initializes @redact-secret/core on call) and
    createAiContextBoundaryWith(core, options) (injected), each returning
    sanitizeText, sanitizeValue, sanitizeToolResult, buildContext, and
    openStream. Every operation ends in a frozen ok / blocked / aborted
    outcome with a fixed reason set (BLOCK_REASONS); findings cross the
    boundary as allowlisted copies (SAFE_FINDING_FIELDS); initialization,
    callback, lifecycle and limit failures map to fixed, input-free outcomes.
    Nested values go through @redact-secret/adapter's walkStrict.
  • "tool-arguments" in BoundaryLabel, for the arguments of a tool call
    (the MCP boundary's opt-in argument sanitation, redact-secret/redact-secret#612).
    Telemetry only; it never changes an outcome.
  • AiContextStream.accepting: a read-only, input-free boolean that is true
    until the stream fails, is aborted, or is finalized, so a host can stop
    pulling from a producer whose output would be discarded unscanned
    (redact-secret/redact-secret#612).
  • Qualified by replaying the core's conformance/fixtures/ai-context-boundary.json,
    vendored at core commit 0e3ba9592b6fa80fafdea47639921987c36ba323
    (fixtures/core/pins.json), through the public API on the real core, before
    and after initialize().
  • Declared range: @redact-secret/core ^0.1.0-beta.6, as a required peer
    dependency, backed by the conformance replay and
    test/e2e.test.ts at both range endpoints in CI.
  • Depends on @redact-secret/adapter ^0.1.1, the first version that exports
    walkStrict. 0.1.0 lacks it, so the import failed against it.

@redact-secret/adapter-mcp 0.1.0-alpha

First release, as a prerelease.

Added

  • The supported MCP redaction boundary (redact-secret/redact-secret#612,
    redact-secret-adapters#13), as a thin specialization of
    @redact-secret/adapter-ai-context: createMcpBoundary(options) (live)
    and createMcpBoundaryWith(aiContextBoundary, options) (injected), each
    returning sanitizeToolResult, sanitizeToolArguments (opt-in, label
    tool-arguments), sanitizeToolCall, sanitizeStreamedToolResult,
    wrapToolHandler, and wrapStreamedToolHandler. The whole
    CallToolResult is one AI-context sanitizeValue, followed by the
    key-context check. Binary payloads block by default (binaryContent: "pass" to opt out), and unknown block types block. A streamed result
    stops pulling from its producer, and closes it, once the stream stops
    accepting. Tool and handler errors become tool_error and are never
    read. Every non-ok outcome maps to a fixed isError: true
    CallToolResult (toCallToolResult), never to a JSON-RPC error.
    Cancellation delivers nothing. onAudit receives one
    { stage, outcome, reason?, code? } record per crossing.
  • Qualified by replaying the core's conformance/fixtures/mcp-boundary.json
    with the core's own runner (conformance/mcp-boundary.mjs), both vendored
    at core commit 0e3ba9592b6fa80fafdea47639921987c36ba323
    (fixtures/core/pins.json), through the public API on the real core,
    before and after initialize() (test/conformance*.test.ts). The same
    fixture is replayed with real SDK clients and servers over stdio and
    Streamable HTTP (test/transport.test.ts), and end to end through a host's
    log, store and model context, including a real subprocess producer
    (test/e2e.test.ts).
  • Declared ranges: @redact-secret/core ^0.1.0-beta.6 (required peer), and as
    optional peers @modelcontextprotocol/sdk >=1.13.0 <=1.30.1 and
    @modelcontextprotocol/client / `@modelcontextprotocol/server

    =2.0.0 <=2.1.0. These are backed by test/transport.test.tsandtest/e2e.test.ts at both endpoints of every range in CI (range-endpoints`). 1.13.0 negotiates protocol 2025-06-18; 1.30.1, 2.0.0
    and 2.1.0 negotiate 2025-11-25.

  • Depends on @redact-secret/adapter-ai-context ^0.1.0-alpha (which pulls in
    @redact-secret/adapter ^0.1.1).

@redact-secret/adapter-otel 0.1.1

Changed

  • @redact-secret/adapter range raised from ^0.1.0 to ^0.1.1, the
    version with the fail-closed walker fixes this release relies on (a
    malformed scanner result, non-plain objects, throwing getters). Backed
    by this package's tests, which run against the workspace's
    @redact-secret/adapter 0.1.1, and by the npm install smoke test.
  • createRedactingSpanProcessor loads @redact-secret/core on call, like
    @redact-secret/adapter's createMaskSecrets, so importing the injected
    API never loads the native core. No API change.
  • MaskLeafOptions is re-exported for typing options.
  • @redact-secret/core ^0.1.0-beta.6 moves from dependencies to
    peerDependencies, same range. As a regular dependency, a core version in
    the application outside that range installed a second, separately
    initialized copy of the native core. Now there is exactly one. npm 7+ and
    pnpm install a required peer automatically. Backed by the same range-endpoint
    CI jobs, which already resolved the core range from either field.

Deprecated

  • RedactAttributesOptions, an alias of MaskLeafOptions that adds nothing.
    It still works and will be removed in a future major version.

Fixed

  • onEnd never throws into the SDK. A span whose fields do not take the
    masked write (for example, attributes frozen by an earlier processor) is
    dropped with a one-time REDACT_SECRET_SPAN_DROPPED process warning naming
    the field, never its value. Before, a frozen bag threw a TypeError out of
    span.end(). The status is now replaced rather than mutated.
  • The SDK's optional onEnding hook is now forwarded to the wrapped
    processor. Before, a wrapped processor that relied on it never saw it.
  • The span name, every event's name, the status message, and every link's
    attributes are now redacted; before, only span and event attributes were.
  • A string-array attribute with a null or undefined element is now
    redacted element by element, keeping the holes in place. Before, any
    non-string element made the whole array pass through unmasked.

@redact-secret/adapter-pino 0.1.1

Added

  • createRedactingStreamWrite / createRedactingStreamWriteWith, a pino
    hooks.streamWrite that masks every string value in the finished JSON line.
    hooks.logMethod never sees child-logger bindings (child(),
    setBindings()) or mixin() output, so with logMethod alone a secret in
    either reached the destination in plaintext. Install both hooks.

Changed

  • @redact-secret/adapter range raised from ^0.1.0 to ^0.1.1, the
    version with the fail-closed walker fixes this release relies on (a
    malformed scanner result, non-plain objects, throwing getters). Backed
    by this package's tests, which run against the workspace's
    @redact-secret/adapter 0.1.1, and by the npm install smoke test.
  • createRedactingLogMethod and createRedactingStreamWrite load
    @redact-secret/core on call, like @redact-secret/adapter's
    createMaskSecrets, so importing the injected API never loads the native
    core. No API change.
  • formatPinoMessage is marked @internal: still exported for
    compatibility, but not a supported API.
  • @redact-secret/core ^0.1.0-beta.6 moves from dependencies to
    peerDependencies, same range. As a regular dependency, a core version in
    the application outside that range installed a second, separately
    initialized copy of the native core. Now there is exactly one. npm 7+ and
    pnpm install a required peer automatically. Backed by the same range-endpoint
    CI jobs, which already resolved the core range from either field.

Fixed

  • logger.error(err, "custom") now logs "custom" as msg. Before, a leading
    Error was rewritten to [{ err }, err.message, ...rest], which replaced
    the caller's message with err.message and interpolated the caller's
    arguments into it. The hook now hands pino a masked copy of the error that
    keeps its prototype, so pino's own handling applies: the caller's message
    wins, and logger.error(err) still gets the masked err.message.
  • A masked Error keeps its class: pino's err serializer now logs
    type: "TypeError" (or whatever the class is) instead of "Object", for a
    leading Error and for one under a merging-object key, whatever the
    logger's errorKey is. Nothing in the hook assumes the key is err any
    more.
  • logger.info(undefined, fmt, ...values) (or null first) now joins the
    message with its values before scanning, as pino formats it; before, the
    parts were scanned separately and a secret split across them was missed.
  • A logger's msgPrefix is now scanned together with the message, so a
    prefix such as "api_key=" gives the core the context to detect the value
    that follows it.
  • The logMethod hook no longer throws into pino when an argument cannot be
    formatted (for example %d with a Symbol): pino logs [REDACTED:ERROR]
    instead of the raw arguments.

@redact-secret/adapter 0.1.1

Added

  • walkStrict(value, limits, visitors), the all-or-nothing variant of t...
Read more

Release train 2026.09.22

Choose a tag to compare

@github-actions github-actions released this 22 Sep 18:57
2368d8c

Release train 2026.09.22. Every package is versioned independently; this train shipped:

@redact-secret/adapter-otel 0.1.0

Initial release. Not yet published — this heading gains a release date once
the Release workflow first publishes this package.

Added

  • createRedactingSpanProcessor, wrapping any SpanProcessor-shaped object:
    redacts every string and string-array attribute on a span and its events in
    onEnd, before delegating. Attribute names are not allowlisted, so
    OpenInference and GenAI semantic-convention attributes are covered without
    hardcoding either convention.
  • Declared ranges: @redact-secret/core ^0.1.0-beta.6, peer
    @opentelemetry/sdk-trace-base ^2.0.0, verified by a real span passed
    through onEnd at both ends of the range, asserting the mutation actually
    took effect on the real span object.

@redact-secret/adapter-pino 0.1.0

Initial release. Not yet published — this heading gains a release date once
the Release workflow first publishes this package.

Added

  • createRedactingLogMethod, a hooks.logMethod integration: value-based
    redaction over the exact string pino would format from a message and its
    interpolation arguments, alongside — not instead of — pino's own
    path-based redact option.
  • Declared ranges: @redact-secret/core ^0.1.0-beta.6, peer pino ^10.0.0.
    pino ^10.0.0 is verified by a real pino logger writing to a captured
    stream at both ends of the range; pino 9.x is deliberately not declared —
    it may work, but it is untested, so it is not claimed.

@redact-secret/adapter 0.1.0

Initial release. Not yet published — this heading gains a release date once
the Release workflow first publishes this package.

Added

  • createMaskSecrets, and the lower-level maskLeafWith / maskLogValueWith
    / maskSecretsWith, the shared fail-closed masking primitives (L1 mask-leaf
    and L2 value-tree walker) every host adapter in this repository is built on.
  • The [REDACTED:BLOCKED], [REDACTED:ERROR], [REDACTED:LIMIT_EXCEEDED],
    and [REDACTED:CYCLE] markers, and DEFAULT_LIMITS, as public API.
  • Declared range: @redact-secret/core ^0.1.0-beta.6, as an optional
    peer dependency — scanAndRedact is injected, so this package works
    without the core installed.

redact-secret-adapters (PyPI) 0.1.0

Initial release. Not yet published — this heading gains a release date once
the Release workflow first publishes this package.

Added

  • RedactSecretFilter (redact_secret_adapters.logging_filter): a
    logging.Filter that redacts a record's msg, args, and exception info
    before any handler formats it. Python's standard library has no
    value-based redaction of its own.
  • mask_secrets_with / mask_leaf_with / mask_log_value_with
    (redact_secret_adapters): the shared fail-closed masking primitives,
    usable directly as a masking callback (e.g. Langfuse's mask=).
  • otel module (redact_secret_adapters.otel, requires the otel extra): a
    SpanProcessor wrapper equivalent to the JS adapter-otel package. Writes
    through BoundedAttributes' backing dict, since the Python OpenTelemetry
    SDK marks span and event attributes immutable once a span ends, before any
    processor hook fires.
  • Declared ranges: redact-secret>=0.1.0b6,<0.2; requires-python >=3.10
    for the stdlib logging integration; otel extra:
    opentelemetry-sdk>=1.16.0,<2, verified by a real span passed through a
    real TracerProvider at both ends of the range.