🛰️ Like free internet? Get one free month of Starlink!
Local security scanner for Home Assistant configurations.
SecretSentry scans your Home Assistant configuration directory for potential security issues, including exposed credentials, insecure settings, git hygiene problems, and missing security best practices.
SecretSentry is LOCAL ONLY. Your secrets never leave your system.
| Feature | Guarantee |
|---|---|
| Local Execution | All scanning runs locally on your HA instance |
| No Telemetry | Zero analytics, tracking, or data collection |
| No Outbound | No connections except optional external URL self-check (YOUR URL only) |
| Secret Masking | Raw secrets NEVER logged, stored, or displayed |
| Privacy Mode | Reports can mask private IPs and tokenize hostnames |
See SECURITY.md for complete security documentation.
- Log Scanning: Detect secrets leaked into log files
- Environment Hygiene: Scan .env and docker-compose.yml for secrets
- URL Userinfo Detection: Find credentials embedded in URLs (scheme://user:pass@host)
- Privacy Mode: Mask IPs and tokenize hostnames in exported reports
- Enhanced Self-Test: Verify masking in evidence, exports, and sanitised copies
- 20+ Security Rules: Comprehensive checks across 10 categories
- Delta Scanning: Track new and resolved findings between scans
- Repairs Integration: Findings appear in Home Assistant's Repairs dashboard
- Evidence Masking: All secrets are automatically masked in logs and reports
- Snapshot Scanning: Optionally scan backup archives for leaked secrets
- Git Hygiene Checks: Verify secrets aren't committed to repositories
- Secret Age Tracking: Detect old secrets that need rotation
- External URL Self-Check: Verify your own instance's HTTPS and auth status
- Built-in Self-Test: Verify the scanner is working correctly
- Sanitised Export: Create redacted copies of configuration for sharing
- Open HACS in Home Assistant
- Click on "Integrations"
- Click the three dots menu in the top right
- Select "Custom repositories"
- Add the repository URL and select "Integration" as the category
- Click "Add"
- Search for "SecretSentry" and install it
- Restart Home Assistant
- Go to Settings → Devices & Services → Add Integration → Search for "SecretSentry"
- Download the
custom_components/secretsentryfolder from this repository - Copy it to your Home Assistant
config/custom_components/directory - Restart Home Assistant
- Go to Settings → Devices & Services → Add Integration → Search for "SecretSentry"
- Scan Interval: Disabled, Daily, or Weekly
- Privacy Mode Reports: Mask private IPs and hostnames in exports (default: ON)
- Environment Hygiene: Scan .env and docker-compose files (default: ON)
- Log Scanning: Scan log files for leaked secrets (default: OFF)
- Scan Backup Archives: Scan .tar and .zip files in backup directories
- Enable Git Subprocess Checks: Check if secrets.yaml is tracked in git
- Check Secret Age Metadata: Detect old secrets based on date comments
- Enable External URL Self-Check: Check your own external URL for issues
- Maximum File Size: Skip files larger than this (default: 512KB)
- Maximum Total Scan Size: Stop scanning after this total (default: 50MB)
- Maximum Findings: Limit total findings per scan (default: 500)
- Maximum Log Size: Limit for log file scanning (default: 10MB)
- Maximum Log Lines: Stop after this many log lines (default: 50000)
| Rule | Severity | Description |
|---|---|---|
| R001 | HIGH | Inline secrets (api_key, token, password, etc.) |
| R002 | HIGH | JWT tokens in configuration |
| R003 | HIGH | PEM private key blocks |
| R004 | MED | Missing !secret references |
| R005 | MED | Duplicate secret values |
| R008 | HIGH | URL with credentials (user:pass@host) |
| Rule | Severity | Description |
|---|---|---|
| R010 | MED | Missing .gitignore |
| R011 | MED | Weak .gitignore (missing critical entries) |
| R012 | HIGH | secrets.yaml tracked in git |
| Rule | Severity | Description |
|---|---|---|
| R020 | MED | IP ban disabled |
| R021 | HIGH | Broad trusted proxies (0.0.0.0/0) |
| R022 | HIGH | CORS wildcard origin |
| R023 | LOW | External exposure hints |
| Rule | Severity | Description |
|---|---|---|
| R030 | MED | Short or predictable webhook IDs |
| Rule | Severity | Description |
|---|---|---|
| R040 | LOW | .storage directory advisory |
| Rule | Severity | Description |
|---|---|---|
| R050 | HIGH | Secrets in backup archives |
| Rule | Severity | Description |
|---|---|---|
| R060 | MED | Old secrets needing rotation |
| Rule | Severity | Description |
|---|---|---|
| R070 | HIGH | External URL not using HTTPS |
| R071 | HIGH | External API accessible without auth |
| Rule | Severity | Description |
|---|---|---|
| R080 | HIGH | Secrets leaked into log files |
| Rule | Severity | Description |
|---|---|---|
| R090 | LOW | .env file present (advisory) |
| R091 | MED/HIGH | Secrets in .env files |
| R092 | MED | Secrets in docker-compose.yml |
| R093 | LOW/MED | Add-on config export risk |
Triggers an immediate security scan.
Exports a masked JSON report to /config/secretsentry_report.json.
Creates a sanitised copy of configuration files with secrets replaced by ***REDACTED***. Output is saved to /config/secretsentry_sanitised/.
Runs internal self-tests to verify the scanner is working correctly. Tests include:
- All rule detection
- Secret masking in evidence
- Secret masking in exports
- Sanitised copy verification
sensor.secretsentry_total_findings
Attributes:
med_count: Medium severity countlow_count: Low severity countlast_scan: Timestamp of the last scanscan_duration_seconds: How long the scan tooknew_high_count: High findings since last scanresolved_count: Findings fixed since last scantop_findings: Top 5 most important findings
sensor.secretsentry_high_severity_findings
When privacy_mode_reports is enabled (default: ON), exported reports and sanitised copies will:
- Replace private IPs with tokens (
private_ip_1,private_ip_2, etc.) - Tokenize hostnames consistently within an export
- Preserve file paths and line numbers for debugging
- Maintain consistent tokens so relationships are visible
This allows sharing reports without exposing your network topology.
automation:
- alias: "Notify on new security findings"
trigger:
- platform: state
entity_id: sensor.secretsentry_high_severity_findings
condition:
- condition: template
value_template: >
{{ state_attr('sensor.secretsentry_total_findings', 'new_high_count') | int > 0 }}
action:
- service: notify.mobile_app
data:
title: "Security Alert"
message: >
SecretSentry found {{ state_attr('sensor.secretsentry_total_findings', 'new_high_count') }}
new high severity security issues.If clicking the gear icon (options) shows "Config flow could not be loaded: 500":
- Check Settings -> System -> Logs and search for "secretsentry" or "config_flow"
- Common cause is import errors in config_flow.py
- Try removing and re-adding the integration
- Restart Home Assistant after any updates
Use the secretsentry.run_selftest service to verify the scanner is working correctly. This tests all rules against known sample data and verifies masking is functioning.
- Check if the scan has completed (look at
last_scanattribute) - Verify file permissions allow Home Assistant to read config files
- Check Home Assistant logs for any scanner errors
- Run the self-test service to verify scanner functionality
Some findings may be intentional. You can:
- Acknowledge them in the Repairs dashboard
- Move the values to
secrets.yamleven if not strictly necessary
Contributions are welcome! Please see CONTRIBUTING.md if available.
Thanks to these awesome people for their contributions and feedback:
- @loryanstrant - Testing and feedback
This project is licensed under the MIT License - see the LICENSE file for details.
See CHANGELOG.md for version history and changes.
SecretSentry is a security scanning tool that helps identify potential issues but does not guarantee complete security. Always follow security best practices and regularly review your Home Assistant configuration.
