Skip to content

Secret Redaction

Daniel Nevoigt edited this page Oct 12, 2026 · 2 revisions

Secret redaction / Geheimnisse schwärzen

English · Deutsch

English

The local draft store removes recognizable credential values and keeps useful locations. It uses technical binding names, provider prefixes, private-key blocks, URL userinfo and opaque strings. It does not use natural-language password word lists. Existing [REDACTED] placeholders are idempotent.

Paths and $NAME / ${NAME} references remain visible. Draft fields are clipped before redaction (quote: 600 characters; context: 160; other fields: 160 or 200). Where a whitespace boundary exists, a token crossing the bound is discarded. Without whitespace, clipping returns a shortened prefix and never splits a surrogate pair. The same character-boundary check applies after redaction. Nested bindings are scanned without repeatedly parsing the same neutral wrapper. Query and flag scans skip already processed value spans.

URL userinfo is separated from its host before considering later @ characters in paths or queries. Quoted authorization headers stop at their enclosing quote; Digest parameters inside that quote are removed together. Code-symbol shape exemptions include PascalCase and acronyms. Named command/field contexts can retain technical identifiers; those exemptions never suppress an explicit credential binding.

Network credentials

Explicit password positions also redact word-only values: nmcli dev|device wifi connect … password, networksetup -setairportnetwork, netsh's Key Content: field, quoted WiFi.begin password literals and #define WIFI_PSK literals, Fortinet set psksecret, VyOS set vpn ipsec … authentication pre-shared-secret, uci set wireless.…key=, <pre-shared-key>, psk_old= / PSK_GUEST= (PSK bindings with underscore suffixes), flat JSON "psks" string arrays, Cisco crypto isakmp key … address, OpenWrt option key, and a complete Wi-Fi QR with SSID and P:. SSIDs, devices, addresses and surrounding quotes remain. Curl user arguments include attached bundles such as -sufixture:pw; HTTPie http -a user:pw is also recognized. Existing path/variable-reference exemptions and idempotent placeholders apply. This recognizes these scalar grammars, not arbitrary shell/C evaluation; word-only PSK values in ordinary prose keep their existing readable boundary. Unquoted WiFi.begin password values and other vendor grammars can remain visible.

Suggestion relay

The pending suggestion relay uses this same filter on its text blocks before storage, including retained legacy rows on every write. It also cleans old rows before delivery. Its file remains the same JSON array, now written with mode 0600 like drafts.json; no migration runs. Bounds apply before and after redaction, using the draft character/placeholder boundary. Dedupe compares the safe relay text; credential-only differences therefore do not stack identical visible suggestions, as with draft fingerprints. The harvest's already-stored vault comparison still sees the original quote before relay storage. Provisional withdrawal compares safe text and returns the original caller strings.

Known limits, with examples

This is a heuristic, not a guarantee that a conversation contains no secrets. Avoid placing actual credentials in conversations.

Ambiguity or unsupported form Example and current behavior
Slash-leading password / path --password=/Sommer2024! stays visible: it is also a valid absolute filename. Filesystem checks would lose remote or planned paths. Slash-leading Base64 shares this ambiguity.
Numeric password with literal URL delimiter https://user:12?34@host.internal/x stays visible because user:12 can be a host/port preceding a query.
Ordinary prose, short PIN the password is tiny123, die PIN ist 482913 stay visible. No language-specific interpretation is attempted.
Word-only PSK passphrase in prose Der PSK lautet kartoffelsalat, the PSK is blauer elefant tanzt, : PSK kartoffelsalat stay visible. Prose and non-positional forms without = only redact a quoted value or a single secret-shaped token; explicitly named password positions above also redact plain words; psk=… assignments still redact to the end of the value. Details in hooks.md.
Credential name outside the recognized syntax secret_key_base: abc999xyz, pw=hunter2, credentials: hunter2 can stay visible.
Other command grammars mysqldump -phunter2, /usr/bin/mysql -ppw1, redis-cli -a hunter2, netrc prose, scp-like me:password@host can stay visible.
Other encoded/signature fields A short JSON auth Base64 value, a non-JWT dotted token, URL sig= / X-Amz-Signature= may stay visible.
Short bare opaque values Unqualified Base62 of 20 characters and lowercase/digit strings of 16 characters may stay visible. Hex values shaped like 40/64-character public hashes survive unqualified contexts.
Symbol or path shaped opaque values A value conforming to a code-symbol or locator exemption can stay visible; explicit credential bindings still take priority except for paths/references.
Bare key/resource/prose labels key: value, secret: db-credentials, max token: 4000, Token: see the vault are conservatively redacted. A short credential under the same syntax must not gain a new exemption.
More complex variable/code references ${{ secrets.GITHUB_TOKEN }}, process.env.OPENAI_API_KEY, os.environ['GH_TOKEN'] and password: !vault | can be damaged. Only $NAME / ${NAME} are recognized as variable references.
User-only URL authority ssh://deploy@build-box.internal:2222/srv/app loses the user, since a username and a token-only credential have the same form. The host remains.
Standalone technical identifiers aarch64-unknown-linux-gnu, srv_db01_prod_euc1_replica02, some EC2/VPC/runner names, base64EncodedStringWithOptions, kCFStreamPropertyHTTPProxyHost can be redacted outside a recognized context.
Public hashes, versions and request IDs md5 d41d8cd98f00b204e9800998ecf8427e, a trace_id, a sha512- value, v1.0.1-rc.2+build.20261007 or a request ID can trigger opaque-value heuristics.

The filter can also leave password=$ecr3t (variable-reference syntax), redis://:12?34@cache.internal:6379 (numeric password/query ambiguity), jwt_eyJ… (underscore-prefixed JWT) and echo S3cret | docker login --password-stdin (stdin value) readable. curl -H "Authorization: Bearer abc123" … has its credential redacted.

Full coverage and technical details: secret-redaction guide.

Deutsch

Der lokale Entwurfspeicher entfernt erkennbare Zugangswerte und erhält nützliche Ortsangaben. Er erkennt technische Bindungsnamen, Anbieterpräfixe, Private-Key-Blöcke, URL-Zugangsdaten und opake Zeichenfolgen. Er verwendet keine natürlichsprachigen Passwort-Wortlisten. Vorhandene [REDACTED]-Platzhalter sind idempotent: erneutes Schwärzen verändert sie nicht.

Pfade sowie $NAME-/${NAME}-Referenzen bleiben sichtbar. Entwurfsfelder werden vor dem Schwärzen gekürzt (Zitat: 600 Zeichen; Kontext: 160; andere Felder: 160 oder 200). Gibt es eine Leerzeichengrenze, wird ein über die Grenze reichendes Token verworfen. Ohne Leerzeichen bleibt ein gekürzter Präfix stehen, ohne ein Surrogatpaar zu teilen. Dieselbe Zeichengrenzenprüfung gilt nach dem Schwärzen. Verschachtelte Bindungen werden ohne wiederholtes Parsen desselben neutralen Wrappers geprüft. Query- und Flag-Prüfungen überspringen bereits verarbeitete Wertbereiche.

URL-Zugangsdaten werden vom Host getrennt, bevor spätere @-Zeichen in Pfaden oder Queries betrachtet werden. Quotierte Authorization-Header enden an ihrem umschließenden Anführungszeichen; darin enthaltene Digest-Parameter werden gemeinsam entfernt. Ausnahmen für Code-Symbole umfassen PascalCase und Akronyme. Benannte Befehls-/Feldkontexte können technische Bezeichner erhalten; diese Ausnahmen unterdrücken nie eine explizite Zugangsdaten-Bindung.

Netzwerk-Zugangsdaten

Explizite Passwortpositionen schwärzen auch reine Wörter: nmcli dev|device wifi connect … password, networksetup -setairportnetwork, netshs Feld Key Content:, Passwort-Stringliterale in WiFi.begin und #define WIFI_PSK, Fortinets set psksecret, VyOS set vpn ipsec … authentication pre-shared-secret, uci set wireless.…key=, <pre-shared-key>, psk_old= / PSK_GUEST= (PSK-Bindungen mit Unterstrich-Suffixen), flache JSON-Stringarrays "psks", Cisco crypto isakmp key … address, OpenWrt option key und vollständige WLAN-QR-Texte mit SSID und P:. SSIDs, Geräte, Adressen und umgebende Anführungszeichen bleiben. Angehängte curl-Bündel wie -sufixture:pw sowie HTTPie http -a user:pw werden erkannt. Die bisherigen Pfad-/Variablenreferenzen und Platzhalter bleiben erhalten. Erkannt werden diese skalaren Grammatiken, keine beliebige Shell-/C-Ausführung; reine Wort-Passphrasen in gewöhnlicher PSK-Prosa bleiben wie bisher lesbar. Unquotierte WiFi.begin-Passwortwerte und andere Hersteller-Grammatiken können lesbar bleiben.

Vorschlags-Relay

Der Pending-Relay nutzt denselben Filter für seine Textblöcke vor dem Speichern, auch für verbliebene alte Zeilen bei jedem Schreiben. Alte Zeilen werden ebenso vor der Auslieferung geschwärzt. Die Datei bleibt dasselbe JSON-Array und wird wie drafts.json mit Rechten 0600 geschrieben; es läuft keine Migration. Grenzen gelten vor und nach der Schwärzung, mit derselben Zeichen-/Platzhaltergrenze wie bei Entwürfen. Die Dublettensuche vergleicht den sicheren Relay-Text; Unterschiede nur in Zugangsdaten stapeln deshalb keine gleich sichtbaren Vorschläge, wie bei Entwurfs-Fingerprints. Der Harvester-Abgleich „schon im Vault“ sieht weiterhin das ursprüngliche Zitat vor der Relay-Speicherung. Die vorläufige Rücknahme vergleicht sicheren Text und gibt die ursprünglichen Aufrufer-Strings zurück.

Bekannte Grenzen mit Beispielen

Das ist eine Heuristik, keine Garantie für ein Gespräch ohne Zugangsdaten. Echte Zugangsdaten nicht in Gespräche schreiben.

Mehrdeutigkeit oder nicht unterstützte Form Beispiel und aktuelles Verhalten
Slashbeginnendes Passwort / Pfad --password=/Sommer2024! bleibt sichtbar: Das ist auch ein gültiger absoluter Dateiname. Dateisystemprüfungen würden entfernte oder geplante Pfade verlieren. Slashbeginnendes Base64 ist ebenso mehrdeutig.
Numerisches Passwort mit wörtlichem URL-Trennzeichen https://user:12?34@host.internal/x bleibt sichtbar, weil user:12 ein Host/Port vor einer Query sein kann.
Gewöhnliche Prosa, kurze PIN the password is tiny123, die PIN ist 482913 bleiben sichtbar. Es gibt keine sprachspezifische Interpretation.
PSK-Passphrase nur aus Wörtern in Prosa Der PSK lautet kartoffelsalat, the PSK is blauer elefant tanzt, : PSK kartoffelsalat bleiben sichtbar. Prosa und nicht positionale Formen ohne = schwärzen nur quotierte Werte oder ein einzelnes Token mit Geheimnisform; die oben ausdrücklich benannten Passwortpositionen schwärzen auch reine Wörter. psk=…-Zuweisungen schwärzen weiterhin bis zum Wertende. Details in hooks.md.
Credential-Name außerhalb erkannter Syntax secret_key_base: abc999xyz, pw=hunter2, credentials: hunter2 können sichtbar bleiben.
Andere Befehlsgrammatiken mysqldump -phunter2, /usr/bin/mysql -ppw1, redis-cli -a hunter2, netrc-Prosa und scp-artiges me:password@host können sichtbar bleiben.
Andere kodierte Felder / Signaturfelder Ein kurzer JSON-auth-Base64-Wert, ein gepunktetes Token ohne JWT-Form sowie URL-sig= / X-Amz-Signature= können sichtbar bleiben.
Kurze nackte opake Werte Nicht näher bezeichnetes Base62 mit 20 Zeichen sowie Zeichenfolgen aus Kleinbuchstaben/Ziffern mit 16 Zeichen können sichtbar bleiben. Hexwerte in Form öffentlicher 40-/64-Zeichen-Hashes bleiben ohne Credential-Kontext erhalten.
Opake Werte in Symbol- oder Pfadform Ein Wert, der eine Code-Symbol- oder Ortsausnahme erfüllt, kann sichtbar bleiben; explizite Credential-Bindungen haben weiterhin Vorrang, außer bei Pfaden/Referenzen.
Nackte Key-/Ressourcen-/Prosa-Labels key: value, secret: db-credentials, max token: 4000, Token: see the vault werden vorsichtig geschwärzt. Ein kurzer Zugangswert in derselben Syntax darf keine neue Ausnahme erhalten.
Komplexere Variablen-/Code-Referenzen ${{ secrets.GITHUB_TOKEN }}, process.env.OPENAI_API_KEY, os.environ['GH_TOKEN'] und password: !vault | können beschädigt werden. Nur $NAME / ${NAME} werden als Variablenreferenzen erkannt.
URL-Authority nur mit Nutzername ssh://deploy@build-box.internal:2222/srv/app verliert den Nutzer, weil Nutzername und Token-Zugang dieselbe Form haben. Der Host bleibt.
Alleinstehende technische Bezeichner aarch64-unknown-linux-gnu, srv_db01_prod_euc1_replica02, manche EC2-/VPC-/Runner-Namen, base64EncodedStringWithOptions, kCFStreamPropertyHTTPProxyHost können außerhalb eines erkannten Kontexts geschwärzt werden.
Öffentliche Hashes, Versionen und Request-IDs md5 d41d8cd98f00b204e9800998ecf8427e, eine trace_id, ein sha512--Wert, v1.0.1-rc.2+build.20261007 oder eine Request-ID können die Heuristik für opake Werte auslösen.
Auch password=$ecr3t (Syntax einer Variablenreferenz), redis://:12?34@cache.internal:6379 (mehrdeutiges numerisches Passwort/Query), jwt_eyJ… (JWT mit Unterstrich-Präfix) und `echo S3cret docker login --password-stdin(Wert über stdin) können lesbar bleiben. Incurl -H "Authorization: Bearer abc123" …` wird der Zugangswert geschwärzt.

Vollständige Abdeckung und technische Details: Schwärzungsanleitung.

Clone this wiki locally