Skip to content

Add SSH key anonymization with --anonymize-ssh-keys flag#248

Open
manonfgoo wants to merge 2 commits into
intentionet:masterfrom
manonfgoo:feature/ssh-key-anonymization
Open

Add SSH key anonymization with --anonymize-ssh-keys flag#248
manonfgoo wants to merge 2 commits into
intentionet:masterfrom
manonfgoo:feature/ssh-key-anonymization

Conversation

@manonfgoo

@manonfgoo manonfgoo commented Mar 23, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds a new --anonymize-ssh-keys flag that anonymizes SSH public key blobs in network device configurations. This complements the existing --anonymize-passwords (-p) flag, which previously scrubbed SSH key lines entirely (replacing the whole line with SCRUBBED).

Key design decisions:

  • Replace, not scrub: Key blobs are replaced with deterministic, length-preserving replacements rather than scrubbing the entire line. This preserves the surrounding configuration context for analysis.
  • Separate from -p: SSH key anonymization is opt-in via its own flag. The old ssh-(rsa|dsa) regex in the -p password regexes has been commented out to avoid double-processing.
  • Wire format preserved: The SSH wire format key type header (first field) is preserved, so the output still looks like a valid SSH key of the correct type.
  • Deterministic from --salt: Uses HMAC-SHA256 keyed by the salt, so the same key always maps to the same replacement across runs.

Supported formats

  • Authentication keys: ssh-rsa, ssh-dsa, ssh-ecdsa, ssh-ed25519, and bare ecdsa-sha2-nistp* (NX-OS/Arista)
  • Known hosts keys: rsa-key, dsa-key, ed25519-key, ecdsa-sha2-nistp*-key
  • Cisco IOS key hashes: key-hash ssh-rsa <32-hex-MD5>

Files changed

File Change
netconan/ssh_key_anonymization.py New module: blob anonymization, regex matching, key hash anonymization
netconan/anonymize_files.py Wire in anon_ssh_keys param and call replace_ssh_keys() in the processing pipeline
netconan/netconan.py Add --anonymize-ssh-keys CLI argument
netconan/default_pwd_regexes.py Comment out old ssh-(rsa|dsa) scrub regex (now handled by the new module)
README.rst Document the new flag in features list and usage
.github/workflows/test.yml Add passlib to CI deps (already a project dependency, needed for test environment)
tests/unit/test_ssh_key_anonymization.py 518 lines: unit tests for blob anonymization, regex matching, key replacement
tests/end_to_end/test_e2e_ssh_keys.py 148 lines: e2e tests for all key types, determinism, and interaction with other flags

Test plan

  • Unit tests cover all 4 key types (RSA, DSA, ECDSA, Ed25519) across auth and known-hosts formats
  • Tests verify length preservation, key type header preservation, determinism, and lookup consistency
  • E2e tests verify full pipeline: input file → main() → output file with anonymized keys
  • E2e tests verify -p no longer scrubs SSH key lines
  • E2e tests verify --anonymize-ssh-keys works both alone and combined with -p and -a

This change is Reviewable

Add support for anonymizing SSH public key blobs in authentication and
known-hosts lines. Supports RSA, DSA, ECDSA, and Ed25519 key types.
Replacement is deterministic from --salt and length-preserving while
maintaining the SSH wire format key type header.
Fixes mypy no-untyped-def errors for all 5 functions in the module.
Also corrects the ssh_key_regexes type hint in FileAnonymizer from
tuple[Pattern, int] to tuple[Pattern, str] to match the actual
group name strings returned by generate_ssh_key_regexes().
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant