Skip to content

Redactor misses unassigned apikey_ credentials #147

Closed

Description

@sandeepsalwan1

Backpass 0.1.26 does not redact unassigned credentials that use the common apikey_<token> shape.

Minimal reproduction:

import { redact } from "./src/redact.js";

const fake = `apikey_${"a".repeat(64)}`;
console.log(redact(fake) === fake);

This prints true. If that shape appears in a user message rather than a KEY=value assignment, the full value is retained in the distilled analysis prompt and can be sent to the configured model.

Expected: replace the full value with a redaction label, with a regression test for both lowercase apikey_ and uppercase variants.

Observed locally: the unredacted value was also retained in the generated prompt cache. The affected cache entry was removed without changing the source transcript.

Activity

  1. kunchenguid commented on Sep 24, 2026

    @kunchenguid
    Owner

    Speaking as Kun's firstmate: confirmed on latest main 036e510.

    Finding: real, unhelped. src/redact.js patterns cover sk-ant- / sk-proj- / sk-or-v1- / bare sk-…, GitHub/Slack/AWS/JWT/private-key shapes, and KEY=value assignments whose name contains SECRET/TOKEN/PASSWORD/API_?KEY. There is no pattern for an unassigned apikey_<token> (or APIKEY_) value sitting alone in text. The minimal repro (apikey_ + 64 as) leaves the string unchanged on main, so that shape can reach a distilled analysis prompt.

    contract-class: restore — redaction already promises a coarse net over obvious secret shapes before traces reach a model; this is a missing common shape on an existing default path, not a new always-on surface.

    VISION per-rule:

    • Purpose / owns the backward pass — aligns (still transcripts → named surface; redaction sits on the distill path).
    • Evidence is the only currency — aligns (no quote/two-session change).
    • The human owns the weights — aligns (no write-gate change).
    • Nothing the model says is taken on faith — aligns (measurement unchanged).
    • The budget is the constraint — aligns (no file-growth change).
    • It reads what you already have — aligns ("Redaction is a coarse net and says so"; catching another obvious shape tightens the net without becoming a default block).
    • Failure is loud and named — aligns (fix names a gap; regression test should fail when the pattern is removed).
    • Scope — aligns (still not a harness/CI/provider).

    Labeled ready-for-pr. A PR should add the pattern (case-insensitive apikey_ + token length floor), cover uppercase, and add a regression that fails when the pattern is removed.

  2. kunchenguid commented on Oct 8, 2026

    @kunchenguid
    Owner

    Speaking as Kun's firstmate: stale-restamp on latest main 0268201.

    Still real and unhelped. src/redact.js still only catches API_?KEY inside a NAME=value / NAME: value assignment. I re-ran the repro against main: both apikey_ + 64 chars and APIKEY_ + 64 chars come back unchanged from redact(). None of the open PRs touch the redactor.

    contract-class: restore. Redaction already promises a coarse net over obvious secret shapes on the default distill path; this is a missing common shape, not a new surface.

    VISION per-rule:

    • Evidence is the only currency: aligns
    • The human owns the weights: aligns
    • Nothing the model says is taken on faith: aligns
    • The budget is the constraint, not a setting: aligns
    • It reads what you already have and owns nothing: aligns
    • Failure is loud and named: aligns
    • Scope: aligns (the fix tightens the stated coarse net; a regression test should fail when the pattern is removed).

    Leaving ready-for-pr. A PR should add a case-insensitive apikey_ pattern with a token length floor and a regression covering both cases.

  3. kunchenguid commented on Oct 22, 2026

    @kunchenguid
    Owner

    Speaking as Kun's firstmate: stale-restamp on latest main 2125624.

    Still real and unhelped. I re-ran the repro against main: both apikey_ + 64 chars and APIKEY_ + 64 chars come back unchanged from redact() in src/redact.js. No open PR touches the redactor.

    contract-class: restore. Redaction already promises a coarse net over obvious secret shapes on the default distill path; this is a missing common shape, not a new surface.

    VISION per-rule:

    • Evidence is the only currency: aligns
    • The human owns the weights: aligns
    • Nothing the model says is taken on faith: aligns
    • The budget is the constraint, not a setting: aligns
    • It reads what you already have and owns nothing: aligns (tightens the stated coarse net without a default block)
    • Failure is loud and named: aligns (a regression test should fail when the pattern is removed)
    • Scope: aligns

    Leaving ready-for-pr. A PR should add a case-insensitive apikey_ pattern with a token length floor and a regression covering both cases.

  4. kunchenguid commented on Oct 28, 2026

    @kunchenguid
    Owner

    Speaking as Kun's firstmate: fixed by #242, merged as 24f8283. Standalone apikey_ / APIKEY_ credentials of 16+ characters are now redacted before they reach the analysis prompt. Thanks @sandeepsalwan1 for the clear repro.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    ready-for-prIssue is in scope and ready for a PR

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions