Problem
Currently, vault entry types (usernamePassword, sshKey, certificate, secretText) must be set manually via the type field inside structured dict entries. For existing vaults with many entries — especially those migrated from plain key-value vaults — there is no automated way to detect or suggest the correct type.
The detect_entry_type() function in types.py only reads the explicit type field from dict entries or falls back to secretText. It does not infer types from key names, field patterns, or value structure.
Goal: Provide tooling to automatically detect or suggest entry types for untyped vault entries, enabling bulk migration of legacy vaults to the structured type system.
Critical constraint: Secret values must NEVER leave the local machine or be exposed to external services.
Proposed Approaches
Approach 1: Local Heuristic Detection (AI-free)
A built-in command (vaultctl detect-types or vaultctl analyze) that runs entirely locally using rule-based heuristics.
Detection signals:
| Signal |
Example |
Inferred Type |
Key name contains _user, _pass, _password, _login |
db_user, db_password |
usernamePassword |
Key name contains _key, _ssh, _privkey |
deploy_ssh_key |
sshKey |
Key name contains _cert, _certificate, _pem, _crt |
tls_cert |
certificate |
Dict entry has username + password fields |
{username: ..., password: ...} |
usernamePassword |
Dict entry has private_key or key field |
{private_key: ..., public_key: ...} |
sshKey |
Dict entry has certificate or chain field |
{certificate: ..., chain: ...} |
certificate |
Value starts with -----BEGIN (PEM header) |
-----BEGIN RSA PRIVATE KEY----- |
sshKey or certificate |
Value starts with ssh-rsa, ssh-ed25519 |
ssh-ed25519 AAAA... |
sshKey |
Heuristic priority: Structure (dict fields) > Value patterns (PEM headers) > Key name patterns.
Output modes:
--dry-run (default): Show suggestions without modifying anything
--apply: Write detected types into vault entries and/or vault-keys.yml
--json: Machine-readable output for scripting
--confidence: Show confidence level (high/medium/low) for each suggestion
Advantages:
- Zero external dependencies
- Works offline / air-gapped
- Deterministic and auditable
- Fast execution
- No security concerns — everything stays local
Disadvantages:
- Limited to known patterns — cannot handle unusual naming conventions
- Requires maintenance of heuristic rules
- May produce false positives for ambiguous entries
Approach 2: AI-Assisted Detection (with Redaction)
An optional command (vaultctl detect-types --ai) that sends redacted vault structure to an LLM for analysis.
Redaction strategy:
All secret values are replaced BEFORE any external communication. Only structural metadata is transmitted.
# ORIGINAL (never sent)
db_credentials:
type: usernamePassword
username: admin
password: s3cr3t-p4ssw0rd!
# REDACTED (what gets sent)
db_credentials:
type: usernamePassword
username: "***REDACTED***"
password: "***REDACTED***"
For plain string entries:
# ORIGINAL
api_token: ghp_1234567890abcdef
# REDACTED
api_token: "***REDACTED***"
What IS transmitted:
- Key names (e.g.,
db_credentials, api_token)
- Dict field names (e.g.,
username, password, private_key)
- Explicit
type fields (non-sensitive metadata)
- Value type indicators (
string, multiline, dict)
What is NEVER transmitted:
- Actual secret values
- Passwords, tokens, keys, certificates
- File contents referenced by secrets
Safety controls:
--ai flag must be explicitly provided (never default behavior)
- Interactive confirmation showing exactly what will be sent
--show-payload to inspect the redacted payload without sending
- Audit log written to
.vaultctl-ai-audit.log with timestamp, hash of payload, and endpoint
- Configurable endpoint in
.vaultctl.yml (for self-hosted LLMs)
Advantages:
- Can handle unusual naming conventions and edge cases
- More nuanced suggestions with reasoning
- Can suggest types for ambiguous entries where heuristics fail
Disadvantages:
- Requires network access and API credentials
- Key names themselves may be sensitive in some environments
- Additional dependency on external service availability
- Cost per API call
- Requires user trust in redaction completeness
Implementation Plan
Phase 1: Local Heuristics (MVP)
- Add
redact module (src/vaultctl/redact.py) — deterministic value redaction utility
- Add heuristic detection engine to
types.py (or new detect.py module)
- Add
vaultctl detect-types CLI command with --dry-run, --apply, --json, --confidence
- Unit tests for all heuristic rules
- Integration test with sample vault containing mixed entry types
Phase 2: AI-Assisted (Optional Extension)
- Add
--ai flag to detect-types command
- Implement redaction pipeline with
--show-payload preview
- Add interactive consent prompt
- Add audit logging
- Add
.vaultctl.yml configuration for AI endpoint
- Tests for redaction completeness (fuzz testing for value leakage)
Security Requirements
These are non-negotiable constraints for both approaches.
Acceptance Criteria
Phase 1 (Local Heuristics)
Phase 2 (AI-Assisted)
Open Questions
- Should
detect-types also handle _previous backup keys (e.g., db_password_previous)? Probably skip them.
- Should we support custom type definitions beyond
KNOWN_TYPES? Extensibility via config?
- For Phase 2: Which LLM providers should be supported out of the box? OpenAI, Anthropic, Ollama?
- Should the redaction module be usable standalone (e.g.,
vaultctl redact for debugging/export)?
Problem
Currently, vault entry types (
usernamePassword,sshKey,certificate,secretText) must be set manually via thetypefield inside structured dict entries. For existing vaults with many entries — especially those migrated from plain key-value vaults — there is no automated way to detect or suggest the correct type.The
detect_entry_type()function intypes.pyonly reads the explicittypefield from dict entries or falls back tosecretText. It does not infer types from key names, field patterns, or value structure.Goal: Provide tooling to automatically detect or suggest entry types for untyped vault entries, enabling bulk migration of legacy vaults to the structured type system.
Critical constraint: Secret values must NEVER leave the local machine or be exposed to external services.
Proposed Approaches
Approach 1: Local Heuristic Detection (AI-free)
A built-in command (
vaultctl detect-typesorvaultctl analyze) that runs entirely locally using rule-based heuristics.Detection signals:
_user,_pass,_password,_logindb_user,db_passwordusernamePassword_key,_ssh,_privkeydeploy_ssh_keysshKey_cert,_certificate,_pem,_crttls_certcertificateusername+passwordfields{username: ..., password: ...}usernamePasswordprivate_keyorkeyfield{private_key: ..., public_key: ...}sshKeycertificateorchainfield{certificate: ..., chain: ...}certificate-----BEGIN(PEM header)-----BEGIN RSA PRIVATE KEY-----sshKeyorcertificatessh-rsa,ssh-ed25519ssh-ed25519 AAAA...sshKeyHeuristic priority: Structure (dict fields) > Value patterns (PEM headers) > Key name patterns.
Output modes:
--dry-run(default): Show suggestions without modifying anything--apply: Write detected types into vault entries and/orvault-keys.yml--json: Machine-readable output for scripting--confidence: Show confidence level (high/medium/low) for each suggestionAdvantages:
Disadvantages:
Approach 2: AI-Assisted Detection (with Redaction)
An optional command (
vaultctl detect-types --ai) that sends redacted vault structure to an LLM for analysis.Redaction strategy:
All secret values are replaced BEFORE any external communication. Only structural metadata is transmitted.
For plain string entries:
What IS transmitted:
db_credentials,api_token)username,password,private_key)typefields (non-sensitive metadata)string,multiline,dict)What is NEVER transmitted:
Safety controls:
--aiflag must be explicitly provided (never default behavior)--show-payloadto inspect the redacted payload without sending.vaultctl-ai-audit.logwith timestamp, hash of payload, and endpoint.vaultctl.yml(for self-hosted LLMs)Advantages:
Disadvantages:
Implementation Plan
Phase 1: Local Heuristics (MVP)
redactmodule (src/vaultctl/redact.py) — deterministic value redaction utilitytypes.py(or newdetect.pymodule)vaultctl detect-typesCLI command with--dry-run,--apply,--json,--confidencePhase 2: AI-Assisted (Optional Extension)
--aiflag todetect-typescommand--show-payloadpreview.vaultctl.ymlconfiguration for AI endpointSecurity Requirements
--aiflag; it is never the defaultprod_db_passwordreveals infrastructure details)Acceptance Criteria
Phase 1 (Local Heuristics)
vaultctl detect-typeslists all vault entries with suggested types and confidence levels--dry-run(default) shows suggestions without modifying files--applywrites detected types into vault entries (dict entries gettypefield) and updatesvault-keys.ymlmetadata--jsonoutputs machine-readable resultstypefield are skipped (or shown as "confirmed")KNOWN_TYPES:secretText,usernamePassword,sshKey,certificatehigh(multiple signals match),medium(single signal),low(name-only guess)Phase 2 (AI-Assisted)
--aiflag enables AI-assisted detection--show-payloadprints the redacted payload and exits (no network request)--yes).vaultctl.ymlOpen Questions
detect-typesalso handle_previousbackup keys (e.g.,db_password_previous)? Probably skip them.KNOWN_TYPES? Extensibility via config?vaultctl redactfor debugging/export)?