con un clic
distribution-security
Defense-in-depth, PII protection, secrets scanning, and secure packaging for distributed software
Menú
Defense-in-depth, PII protection, secrets scanning, and secure packaging for distributed software
Systematic testing for confidence without over-testing — the right test at the right level
Generate consistent visual character references across multiple scenarios using Flux and nano-banana-pro on Replicate
Create professional ultra-wide cinematic banners for GitHub READMEs using Flux and Ideogram models with typography options
Generate professional presentations using the Gamma API with expert storytelling consulting based on Duarte methodology.
Intelligent project persona identification using priority chain detection with LLM and heuristic fallback
Reusable patterns for VS Code extension development.
| name | distribution-security |
| description | Defense-in-depth, PII protection, secrets scanning, and secure packaging for distributed software |
| metadata | {"inheritance":"inheritable"} |
Multi-layer security for software that ships to users — secrets scanning, permission minimization, and secure UI patterns.
Scope: Inheritable skill. Covers defense-in-depth architecture, PII protection, secrets scanning, permission minimization, CSP patterns, and secure WebView communication.
Every distributed application needs four independent security layers:
| Layer | Function | Failure Mode |
|---|---|---|
| 1. Authentication | Verify identity (OAuth, MSAL, API keys) | Unauthorized access |
| 2. Authorization | Role-based access control (RBAC) | Privilege escalation |
| 3. Secrets Scanning | Detect leaked credentials in source | Data breach |
| 4. Audit Logging | Record all security-relevant events | Undetected compromise |
Rule: Each layer must work independently. A failure in Layer 1 should not cascade — Layer 2 still blocks unauthorized actions, Layer 3 still catches leaked keys, Layer 4 still records the attempt.
For projects that package and distribute source files:
| Layer | Implementation | Catches |
|---|---|---|
1. .gitignore | Exclude from version control | Personal config, local data |
2. .vscodeignore / build exclusions | Exclude from package | Dev-only files, test data |
| 3. Build pipeline scan | Regex validation gate | Anything layers 1-2 missed |
| Location | Allowed? | Alternative |
|---|---|---|
| Source code headers | No | Use team/org name |
package.json author | Org name only | "author": "Team Name" |
| README credits | Generic unless opted in | "Created by the team" |
| Error messages | No PII ever | Use error codes |
| Telemetry | No PII without consent | Anonymized identifiers |
Rationale: Users installing software see package.json and source headers. Personal names create trust concerns and privacy issues.
| Pattern | Regex | Severity |
|---|---|---|
| API keys | /[A-Za-z0-9_\-]{32,}/ | High |
| Connection strings | /Server=.*;[P]assword=.*/i | Critical |
| JWT tokens | /eyJ[A-Za-z0-9_-]+\.eyJ[A-Za-z0-9_-]+/ | Critical |
| Private keys | /-----BEGIN.*PRIVATE KEY-----/ | Critical |
| Azure keys | /[A-Za-z0-9+/]{86}==/ | High |
Naive regex scanning floods developers with noise. Filter these contexts:
| Context | Example | Action |
|---|---|---|
| Import statements | import { KEY_LENGTH } from... | Skip |
| Comments explaining patterns | // API keys look like: abc123... | Skip |
| Env variable definitions | const API_KEY = process.env.KEY | Skip (value is reference) |
| Test fixtures with dummy data | const testKey = "test-key-1234" | Skip if in test folder |
| Actual hardcoded secrets | const key = "sk-live-abc123..." | ALERT |
Rule: Only alert on literal string values that match secret patterns outside of comments, imports, and environment variable references.
When security audits surface findings, triage with this matrix:
| Priority | Criteria | SLA |
|---|---|---|
| P0 | Active secret exposure, data breach | Immediate (hours) |
| P1 | Vulnerability in auth/authz layer | 24 hours |
| P2 | Missing security control (no CSP, etc.) | Sprint |
| P3 | Best practice gap (logging format, etc.) | Backlog |
Request ONLY the permissions your software actually uses:
| Anti-pattern | Problem | Fix |
|---|---|---|
Request Mail.Send for reading contacts | Users fear email spam | Request Contacts.Read only |
| Request admin scopes "for future use" | Over-privileged from day one | Request when feature ships |
Broad * scopes | No granular control | Request specific sub-scopes |
Rule: Users evaluate trust based on the scariest permission requested. One unnecessary permission can tank adoption.
For every capability that requires a permission:
For WebViews, panels, and embedded web content:
| Anti-pattern | Problem | Secure Alternative |
|---|---|---|
onclick="handler()" | Inline scripts violate CSP | data-cmd attribute + delegated listener |
eval() | Code injection vector | Pre-compiled templates |
innerHTML = userInput | XSS vulnerability | textContent or sanitized HTML |
<script src="cdn"> | External dependency risk | Bundle locally |
Replace inline event handlers with data attributes:
<!-- Anti-pattern: inline handler (blocked by CSP) -->
<button onclick="doThing()">Click</button>
<!-- Secure: data-cmd + delegated listener -->
<button data-cmd="do-thing">Click</button>
<script>
document.addEventListener('click', (e) => {
const cmd = e.target.closest('[data-cmd]')?.dataset.cmd;
if (cmd) handleCommand(cmd);
});
</script>
WebViews run in sandboxed iframes. Communication must use message passing:
| Direction | Method | Example |
|---|---|---|
| Extension → WebView | webview.postMessage(data) | Send state updates |
| WebView → Extension | vscode.postMessage(data) | Report user actions |
| WebView → External URL | BLOCKED | window.open() silently fails |
| WebView → Local files | Via extension only | Request through message |
Critical: window.open() silently fails in WebViews. Links that need to open externally must send a message to the extension, which calls vscode.env.openExternal().
Always validate messages on both sides:
// Extension side - validate WebView messages
panel.webview.onDidReceiveMessage((msg) => {
if (!msg.type || typeof msg.type !== 'string') return;
switch (msg.type) {
case 'save': handleSave(msg.data); break;
case 'navigate': handleNavigate(msg.url); break;
// Ignore unknown message types
}
});
For operations that could cause irreversible damage:
| Layer | Implementation | Purpose |
|---|---|---|
| 1. Marker file | Presence of protection file blocks operation | Static guard |
| 2. Confirmation dialog | "Are you sure?" prompt | User intent validation |
| 3. Typed confirmation | User must type exact phrase | Prevent accidental clicks |
| 4. Cooldown timer | Wait N seconds before enabling action | Prevent impulse actions |
| 5. Audit log | Record who triggered what and when | Post-incident analysis |
Rule: The confirmation dialog ("I Understand" button) must STILL block the destructive action even if earlier layers fail. Each layer is independent.
When adding test coverage to security-critical code:
| Tier | Coverage Target | What to Test |
|---|---|---|
| 1. Auth/AuthZ | 80%+ first | Token validation, role checks, permission gates |
| 2. Input validation | 80%+ next | Sanitization, bounds, injection prevention |
| 3. Secrets handling | Full coverage | No secrets in logs, proper encryption |
| 4. UI/cosmetic | After security | Layout, theming, preferences |
Rule: Achieve 80%+ coverage on Tier 1 before touching Tier 4. In a resource-constrained sprint, security tests win over UI tests every time.
Security audits must scan the full subscription, not just infrastructure-as-code:
| Method | Covers | Misses |
|---|---|---|
| IaC scanning (Bicep/Terraform) | Declared resources | Manually created resources |
az resource list --subscription X | All resources | Config drift within resources |
| Azure Policy + Defender | Compliance posture | Application-level vulns |
Rule: Always combine IaC scanning with live subscription scanning. Manual portal clicks create resources that IaC scans will never find.