ha-inlite

Home Assistant integration for in-lite
git clone https://git.stephank.nl/ha-inlite
Log | Files | Refs | README | LICENSE | ZIP

SKILL.md (7747B)


      1 ---
      2 name: secret-handling
      3 description: Never read .env files or write secrets to .squad/ committed files
      4 domain: security, file-operations, team-collaboration
      5 confidence: high
      6 source: earned (issue #267 — credential leak incident)
      7 ---
      8 
      9 ## Context
     10 
     11 Spawned agents have read access to the entire repository, including `.env` files containing live credentials. If an agent reads secrets and writes them to `.squad/` files (decisions, logs, history), Scribe auto-commits them to git, exposing them in remote history. This skill codifies absolute prohibitions and safe alternatives.
     12 
     13 ## Patterns
     14 
     15 ### Prohibited File Reads
     16 
     17 **NEVER read these files:**
     18 - `.env` (production secrets)
     19 - `.env.local` (local dev secrets)
     20 - `.env.production` (production environment)
     21 - `.env.development` (development environment)
     22 - `.env.staging` (staging environment)
     23 - `.env.test` (test environment with real credentials)
     24 - Any file matching `.env.*` UNLESS explicitly allowed (see below)
     25 
     26 **Allowed alternatives:**
     27 - `.env.example` (safe — contains placeholder values, no real secrets)
     28 - `.env.sample` (safe — documentation template)
     29 - `.env.template` (safe — schema/structure reference)
     30 
     31 **If you need config info:**
     32 1. **Ask the user directly** — "What's the database connection string?"
     33 2. **Read `.env.example`** — shows structure without exposing secrets
     34 3. **Read documentation** — check `README.md`, `docs/`, config guides
     35 
     36 **NEVER assume you can "just peek at .env to understand the schema."** Use `.env.example` or ask.
     37 
     38 ### Prohibited Output Patterns
     39 
     40 **NEVER write these to `.squad/` files:**
     41 
     42 | Pattern Type | Examples | Regex Pattern (for scanning) |
     43 |--------------|----------|-------------------------------|
     44 | API Keys | `OPENAI_API_KEY=sk-proj-...`, `GITHUB_TOKEN=ghp_...` | `[A-Z_]+(?:KEY|TOKEN|SECRET)=[^\s]+` |
     45 | Passwords | `DB_PASSWORD=super_secret_123`, `password: "..."` | `(?:PASSWORD|PASS|PWD)[:=]\s*["']?[^\s"']+` |
     46 | Connection Strings | `postgres://user:pass@host:5432/db`, `Server=...;Password=...` | `(?:postgres|mysql|mongodb)://[^@]+@|(?:Server|Host)=.*(?:Password|Pwd)=` |
     47 | JWT Tokens | `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...` | `eyJ[A-Za-z0-9_-]+\.eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+` |
     48 | Private Keys | `-----BEGIN PRIVATE KEY-----`, `-----BEGIN RSA PRIVATE KEY-----` | `-----BEGIN [A-Z ]+PRIVATE KEY-----` |
     49 | AWS Credentials | `AKIA...`, `aws_secret_access_key=...` | `AKIA[0-9A-Z]{16}|aws_secret_access_key=[^\s]+` |
     50 | Email Addresses | `user@example.com` (PII violation per team decision) | `[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}` |
     51 
     52 **What to write instead:**
     53 - Placeholder values: `DATABASE_URL=<set in .env>`
     54 - Redacted references: `API key configured (see .env.example)`
     55 - Architecture notes: "App uses JWT auth — token stored in session"
     56 - Schema documentation: "Requires OPENAI_API_KEY, GITHUB_TOKEN (see .env.example for format)"
     57 
     58 ### Scribe Pre-Commit Validation
     59 
     60 **Before committing `.squad/` changes, Scribe MUST:**
     61 
     62 1. **Scan all staged files** for secret patterns (use regex table above)
     63 2. **Check for prohibited file names** (don't commit `.env` even if manually staged)
     64 3. **If secrets detected:**
     65    - STOP the commit (do NOT proceed)
     66    - Remove the file from staging: `git reset HEAD <file>`
     67    - Report to user:
     68      ```
     69      🚨 SECRET DETECTED — commit blocked
     70      
     71      File: .squad/decisions/inbox/river-db-config.md
     72      Pattern: DATABASE_URL=postgres://user:password@localhost:5432/prod
     73      
     74      This file contains credentials and MUST NOT be committed.
     75      Please remove the secret, replace with placeholder, and try again.
     76      ```
     77    - Exit with error (never silently skip)
     78 
     79 4. **If no secrets detected:**
     80    - Proceed with commit as normal
     81 
     82 **Implementation note for Scribe:**
     83 - Run validation AFTER staging files, BEFORE calling `git commit`
     84 - Use PowerShell `Select-String` or `git diff --cached` to scan staged content
     85 - Fail loud — secret leaks are unacceptable, blocking the commit is correct behavior
     86 
     87 ### Remediation — If a Secret Was Already Committed
     88 
     89 **If you discover a secret in git history:**
     90 
     91 1. **STOP immediately** — do not make more commits
     92 2. **Alert the user:**
     93    ```
     94    🚨 CREDENTIAL LEAK DETECTED
     95    
     96    A secret was found in git history:
     97    Commit: abc1234
     98    File: .squad/decisions/inbox/agent-config.md
     99    Pattern: API_KEY=sk-proj-...
    100    
    101    This requires immediate remediation:
    102    1. Revoke the exposed credential (regenerate API key, rotate password)
    103    2. Remove from git history (git filter-repo or BFG)
    104    3. Force-push the cleaned history
    105    
    106    Do NOT proceed with new work until this is resolved.
    107    ```
    108 3. **Do NOT attempt to fix it yourself** — secret removal requires specialized tools
    109 4. **Wait for user confirmation** before resuming work
    110 
    111 ## Examples
    112 
    113 ### ✓ Correct: Reading Config Schema
    114 
    115 **Agent needs to know what environment variables are required:**
    116 
    117 ```
    118 Agent: "What environment variables does this app need?"
    119 → Reads `.env.example`:
    120     OPENAI_API_KEY=sk-...
    121     DATABASE_URL=postgres://user:pass@localhost:5432/db
    122     REDIS_URL=redis://localhost:6379
    123 
    124 → Writes to .squad/decisions/inbox/river-env-setup.md:
    125     "App requires three environment variables:
    126     - OPENAI_API_KEY (OpenAI API key, format: sk-...)
    127     - DATABASE_URL (Postgres connection string)
    128     - REDIS_URL (Redis connection string)
    129     See .env.example for full schema."
    130 ```
    131 
    132 ### ✗ Incorrect: Reading Live Credentials
    133 
    134 **Agent needs to know database schema:**
    135 
    136 ```
    137 Agent: (reads .env)
    138     DATABASE_URL=postgres://admin:super_secret_pw@prod.example.com:5432/appdb
    139 
    140 → Writes to .squad/decisions/inbox/river-db-schema.md:
    141     "Database connection: postgres://admin:super_secret_pw@prod.example.com:5432/appdb"
    142     
    143 🚨 VIOLATION: Live credential written to committed file
    144 ```
    145 
    146 **Correct approach:**
    147 ```
    148 Agent: (reads .env.example OR asks user)
    149 User: "It's a Postgres database, schema is in migrations/"
    150 
    151 → Writes to .squad/decisions/inbox/river-db-schema.md:
    152     "Database: Postgres (connection configured in .env). Schema defined in db/migrations/."
    153 ```
    154 
    155 ### ✓ Correct: Scribe Pre-Commit Validation
    156 
    157 **Scribe is about to commit:**
    158 
    159 ```powershell
    160 # Stage files
    161 git add .squad/
    162 
    163 # Scan staged content for secrets
    164 $stagedContent = git diff --cached
    165 $secretPatterns = @(
    166     '[A-Z_]+(?:KEY|TOKEN|SECRET)=[^\s]+',
    167     '(?:PASSWORD|PASS|PWD)[:=]\s*["'']?[^\s"'']+',
    168     'eyJ[A-Za-z0-9_-]+\.eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+'
    169 )
    170 
    171 $detected = $false
    172 foreach ($pattern in $secretPatterns) {
    173     if ($stagedContent -match $pattern) {
    174         $detected = $true
    175         Write-Host "🚨 SECRET DETECTED: $($matches[0])"
    176         break
    177     }
    178 }
    179 
    180 if ($detected) {
    181     # Remove from staging, report, exit
    182     git reset HEAD .squad/
    183     Write-Error "Commit blocked — secret detected in staged files"
    184     exit 1
    185 }
    186 
    187 # Safe to commit
    188 git commit -F $msgFile
    189 ```
    190 
    191 ## Anti-Patterns
    192 
    193 - ❌ Reading `.env` "just to check the schema" — use `.env.example` instead
    194 - ❌ Writing "sanitized" connection strings that still contain credentials
    195 - ❌ Assuming "it's just a dev environment" makes secrets safe to commit
    196 - ❌ Committing first, scanning later — validation MUST happen before commit
    197 - ❌ Silently skipping secret detection — fail loud, never silent
    198 - ❌ Trusting agents to "know better" — enforce at multiple layers (prompt, hook, architecture)
    199 - ❌ Writing secrets to "temporary" files in `.squad/` — Scribe commits ALL `.squad/` changes
    200 - ❌ Extracting "just the host" from a connection string — still leaks infrastructure topology