Expand description
Secret swapping and streaming restoration for arbitrary byte payloads.
doppel intercepts secrets in outbound payloads, replaces them with
structurally-equivalent fakes, and restores the originals in streaming responses.
Three operations form the core workflow:
swap— scan a payload for secrets matching the suppliedPatterns, replace each with a fake, and return the swapped payload, encrypted entries, and a session key.- Transmit — send the swapped payload to the external service. Hold the entries and session key locally.
restore— stream the response through the restore function, which replaces fakes with originals using the session key and entries.
For repeated swap calls against the same fixed pattern set, use Detector to
pre-build the Aho-Corasick automaton once and reuse it across calls; this avoids
rebuilding the automaton on every request.
§Quick start
use doppel::{swap, restore, patterns};
// NOT real credentials — synthetic key matching the Anthropic structural pattern
let payload = b"Authorization: sk-ant-api03-w8bVJRHra9S96i3ios_XhbLgzEBjS6qjPUEgiPrWjN2OeICCY1lwhK3Z35Z_jM89STjqSOxHh6GWGkG2R7uv-AohQLmK9AA";
// 1. Swap: detect and replace the key before sending to an external service
// Note: `patterns::all()` uses ephemeral salts — two separate calls to `swap` with
// the same secret will produce different fakes. For stable fakes across calls,
// use `SecretsFile::to_patterns()`. The `restore` call always works correctly because
// fakes are embedded in the encrypted entries, independent of pattern salts.
let result = swap(payload, &patterns::all()).unwrap();
assert_eq!(result.entries.len(), 1); // one secret detected
assert_ne!(result.payload.as_slice(), payload as &[u8]); // key replaced with a fake
// result.payload — send to external service (key replaced with a fake)
// result.entries — keep locally; needed to restore secrets in the response
// result.session_key — keep locally; zeroized on drop
// 2. Restore: recover the original secret from the response stream
let mut response = result.payload.as_slice();
let mut restored = Vec::new();
restore(
&mut response,
&mut restored,
&result.entries,
&result.session_key,
)
.unwrap();
assert_eq!(restored, payload.as_slice());Re-exports§
pub use detector::Detector;pub use patterns::Pattern;pub use secrets_file::PatternEntry;pub use secrets_file::SecretsFile;pub use secrets_file::SecretsFileError;pub use types::Entry;pub use types::SessionKey;pub use types::SwapError;pub use types::SwapResult;
Modules§
- detector
- Pre-built detection context for high-throughput use cases.
- patterns
- Built-in structural patterns and per-call constructor functions.
- secrets_
file - Patterns file serialization and deserialization (TOML, version 3).
- segment
- Segment types for structural pattern definitions.
- types
- Core types:
SessionKey,Entry,SwapResult, and error enums.
Structs§
- Secret
Options - Options for registered secret registration.
Enums§
- Restore
Error - Errors returned by
restoreandrestore_stream(async feature). - Secret
Error - Errors returned by registration.
Functions§
- register
- Register an arbitrary secret with default options and produce a registered-secret Pattern.
- register_
with_ options - Register an arbitrary secret with explicit options.
- restore
- Stream
inputtooutputincrementally, replacing any fakes found inentrieswith their original plaintext, decrypted usingsession_key. - swap
- Scan
payloadfor secrets matchingpatterns, replace each with a structurally-equivalent fake, and return the swapped payload, encrypted entries, and a fresh session key.