Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
8294bc4
feat: proxy fails closed on unsupported upstream shapes; scope launch…
ppiankov Jul 13, 2026
62e46b1
fix: harden unsupported proxy shapes
ppiankov Jul 13, 2026
959fdb9
fix: allow gateway-prefixed /v1/messages paths in proxy shape guard (…
ppiankov Jul 13, 2026
fd6fd14
fix: harden launch env and shape guard tests
ppiankov Jul 13, 2026
744949c
test: guard launch gateway warning secrecy
ppiankov Jul 13, 2026
3be14e5
fix: close proxy shape guard gaps
ppiankov Jul 13, 2026
3b1eeff
fix: harden proxy shape guard follow-ups
ppiankov Jul 13, 2026
eafa2cd
fix: harden proxy launch edge cases
ppiankov Jul 13, 2026
e2883bb
fix: harden proxy guard follow-ups
ppiankov Jul 14, 2026
0f37a6c
fix: make proxy model identity advisory
ppiankov Jul 14, 2026
36e187e
fix: harden proxy batch advisory handling
ppiankov Jul 14, 2026
1072817
fix: close proxy shape guard review gaps
ppiankov Jul 14, 2026
faf17ac
fix: harden launch signal lifecycle
ppiankov Jul 14, 2026
f80c57c
test: make launch sockets portable
ppiankov Jul 14, 2026
b8d38b6
fix: contain deterministic proxy secrets
ppiankov Jul 15, 2026
69ccdf5
fix: preserve classic token classification
ppiankov Jul 15, 2026
d024c42
fix: surface unexpected socket failures
ppiankov Jul 15, 2026
ff5f8b2
fix: validate rotating Slack token shape
ppiankov Jul 15, 2026
550f57e
test: pin provider token boundaries
ppiankov Jul 15, 2026
cbb7d72
test: preserve classic GitHub token type
ppiankov Jul 15, 2026
241abab
fix: accept documented Docker token length
ppiankov Jul 15, 2026
4b8fbcf
fix: bind structured secret containment
ppiankov Jul 15, 2026
74c0312
fix: authorize secret mutation from evidence
ppiankov Jul 15, 2026
d029254
fix: separate provider token evidence
ppiankov Jul 15, 2026
17f17ec
fix: order sourced token detectors first
ppiankov Jul 15, 2026
c143b50
test: cover proxy mutation edge cases
ppiankov Jul 15, 2026
fc62131
fix: harden proxy evidence boundaries
ppiankov Jul 15, 2026
e1d77f6
docs: align mutation guarantee diagram
ppiankov Jul 15, 2026
70afb10
docs: name advisory token boundaries
ppiankov Jul 15, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Changed

- Mutation authorization now comes from intrinsic secret format, exact known-value
evidence, or an operator custom rule. Severity and request-field context affect
advisory reporting only; format-only DSN/JDBC and generic credential matches remain
visible without being rewritten.
- The Anthropic request scanner now covers tool contracts, input examples, message text,
tool inputs/results, and stop sequences, and rejects malformed tool/stop containers.
- Proxy replacement is documented as one-way. Reversible local restoration remains an
MCP read/write capability.

### Fixed

- Azure Storage connection-string detection no longer consumes bytes following the
base64 `AccountKey` value.

## [0.29.0] - 2026-07-12

### Added
Expand Down
74 changes: 40 additions & 34 deletions README.md

Large diffs are not rendered by default.

37 changes: 28 additions & 9 deletions Sources/Pastewatch/ClipboardMonitor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -117,18 +117,28 @@ final class ClipboardMonitor: ObservableObject {
guard config.enabled else { return }

// Scan for sensitive data
let matches = DetectionRules.scan(content, config: config)
let matches = DetectionRules.scan(
content,
config: config,
customRules: CustomRule.compileValid(config.customRules)
)

// No matches — nothing to do
guard !matches.isEmpty else { return }
let outcome = applyAuthorizedMutations(
to: content,
matches: matches,
site: .clipboard,
minAdvisorySeverity: .low
)
guard !outcome.mutated.isEmpty else { return }

// Obfuscate and replace clipboard content
let obfuscatedContent = Obfuscator.obfuscate(content, matches: matches)
let obfuscatedContent = outcome.text

// Create scan result
let result = ScanResult(
originalContent: content,
matches: matches,
matches: outcome.mutated,
obfuscatedContent: obfuscatedContent,
timestamp: Date()
)
Expand All @@ -143,7 +153,7 @@ final class ClipboardMonitor: ObservableObject {
// Update state
DispatchQueue.main.async { [weak self] in
self?.lastScanResult = result
self?.sessionObfuscationCount += matches.count
self?.sessionObfuscationCount += outcome.mutated.count
self?.onObfuscation?(result)
}
}
Expand All @@ -154,13 +164,22 @@ final class ClipboardMonitor: ObservableObject {
guard let content = NSPasteboard.general.string(forType: .string) else { return nil }
guard !content.isEmpty else { return nil }

let matches = DetectionRules.scan(content, config: config)
let obfuscatedContent = Obfuscator.obfuscate(content, matches: matches)
let matches = DetectionRules.scan(
content,
config: config,
customRules: CustomRule.compileValid(config.customRules)
)
let outcome = applyAuthorizedMutations(
to: content,
matches: matches,
site: .clipboard,
minAdvisorySeverity: .low
)

return ScanResult(
originalContent: content,
matches: matches,
obfuscatedContent: obfuscatedContent,
matches: outcome.mutated,
obfuscatedContent: outcome.text,
timestamp: Date()
)
}
Expand Down
2 changes: 1 addition & 1 deletion Sources/PastewatchCLI/GuardCommand.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ struct Guard: ParsableCommand {
$0.effectiveSeverity >= failOnSeverity
}
// WO-138: JSON output must preserve command context without echoing inline credential values.
let redactedCommand = Obfuscator.obfuscate(command, matches: commandDisplayMatches)
let redactedCommand = Obfuscator.redactForDisplay(command, matches: commandDisplayMatches)

if !commandFiltered.isEmpty {
shouldBlock = true
Expand Down
Loading
Loading