askill
tzurot-security

tzurot-securitySafety 100Repository

Security best practices for Tzurot v3 - Secret management, AI-specific security (prompt injection, PII scrubbing), Economic DoS prevention, Discord permission verification, microservices security, and supply chain integrity. Use when handling secrets, user input, or security-critical code.

0 stars
1.2k downloads
Updated 2/5/2026

Package Files

Loading files...
SKILL.md

Security Skill - Tzurot v3

Use this skill when: Handling secrets, user input, file uploads, AI providers, admin commands, or when security concerns arise.

Quick Reference

# Pre-commit secret check
git diff --cached | grep -iE '(password|secret|token|api.?key|postgresql://|redis://)'

# Audit dependencies
npm audit --audit-level=moderate

# View Railway secrets (values hidden)
railway variables --service <name>

🚨 Tier 1: Core Security (MUST FOLLOW)

1. Never Commit Secrets

Happened TWICE in this project. Always verify!

❌ NEVER Commitβœ… Use Instead
Database URLs with passwordsEnvironment variables
API keys/tokens.env.example with placeholders
Private keysRailway secrets management
Real user data in testsGeneric test data

If you commit a secret:

  1. Rotate immediately (regenerate in provider dashboard)
  2. Update Railway: railway variables --set "KEY=new-value"
  3. Consider git history rewrite if not shared

GitGuardian False Positives (Test Secrets)

GitGuardian CI checks scan for secrets. Test files with fake API keys can trigger false positives.

Solution Order of Preference:

  1. Use low-entropy fake keys (BEST - scanners naturally ignore these):

    // ❌ WRONG - High entropy, triggers GitGuardian
    const apiKey = 'sk-test-byok-key-abc123xyz789';
    const apiKey = 'test-byok-key-not-a-real-secret';
    
    // βœ… CORRECT - Low entropy, obviously fake
    const apiKey = 'user-test-key-12345';
    const apiKey = 'fake-key-00000';
    const apiKey = 'PLACEHOLDER_KEY';
    
  2. Exclude test patterns in .gitguardian.yaml (if format is strict):

    # .gitguardian.yaml
    secret:
      ignored-paths:
        - '**/*.test.ts'
        - '**/*.spec.ts'
        - '**/test/**'
        - '**/__mocks__/**'
    
  3. Inline ggignore comment (LAST RESORT - clutters code):

    const apiKey = 'must-be-this-exact-format-abc123'; // ggignore
    

Why low-entropy is best: GitGuardian uses Shannon entropy to detect secrets. Simple patterns like 12345 or 00000 have low entropy and don't trigger scans. This keeps code clean without config files or comments.

Reference: ggshield documentation

2. Environment Variable Management

// βœ… CORRECT - Fail fast if missing
const required = ['DISCORD_TOKEN', 'DATABASE_URL', 'REDIS_URL'] as const;
for (const v of required) {
  if (!process.env[v]) throw new Error(`Missing: ${v}`);
}

3. Security Logging (No PII)

// ❌ WRONG - Logs PII
logger.info({ user }, 'User authenticated');
logger.debug({ token }, 'Initializing');

// βœ… CORRECT - Log only safe identifiers
logger.info({ userId: user.id }, 'User authenticated');
logger.debug({ tokenPrefix: token.slice(0, 10) }, 'Initializing');

NEVER log: Emails, phones, IPs, usernames, message content, API keys Safe to log: User IDs, guild IDs, channel IDs, timestamps, error codes

4. Token Budgeting (Economic DoS Prevention)

AI APIs cost money. Implement per-user token limits:

// In Redis: token_budget:{userId} β†’ { tokensUsed, windowStart }
if (budget.tokensUsed + estimated > BUDGET_PER_HOUR) {
  return res.status(429).json({ error: 'Token budget exceeded' });
}

5. Discord Permission Verification

// ❌ WRONG - Trusts client-side
if (interaction.member.permissions.has('Administrator')) {
}

// βœ… CORRECT - Server-side with cache
const guild = await client.guilds.fetch(guildId);
const member = await guild.members.fetch(userId);
const hasAdmin = member.permissions.has(PermissionFlagsBits.Administrator);

6. Shell Command Safety (Command Injection Prevention)

This vulnerability has occurred multiple times. When executing shell commands with user-controlled or external data, NEVER use string interpolation.

import { execFileSync, execSync } from 'node:child_process';

// ❌ WRONG - Command injection via string interpolation
execSync(`railway variables --set "${key}=${value}"`);
// If value = 'foo"; rm -rf /; echo "' β†’ disaster!

// ❌ WRONG - Even with "trusted" variables, avoid habits
execSync(`git commit -m "${message}"`);

// βœ… CORRECT - Use execFileSync with array arguments
execFileSync('railway', ['variables', '--set', `${key}=${value}`]);

// βœ… CORRECT - Shell never interprets the arguments
execFileSync('git', ['commit', '-m', message]);

// βœ… OK - Static commands without interpolation
execSync('railway status');
execSync('git log --oneline -5');

Why execFileSync is safe:

  • Arguments are passed directly to the process, not through a shell
  • Shell metacharacters ("; $ \ ()`) are treated as literal strings
  • No possibility of command injection regardless of input

When to use which:

FunctionUse WhenSafety
execFileSync(cmd, args)Any external data in argsβœ… Safe
execSync(staticCmd)Fully static command stringβœ… Safe
execSync(\...${var}`)`❌ NEVER⚠️ Vulnerable

Test for this: Add tests with shell metacharacters in values:

const maliciousValue = 'test"; rm -rf /; echo "pwned';
// Verify your code passes this literally, not interprets it

πŸ›‘οΈ Tier 2: Important Security (SHOULD IMPLEMENT)

7. PII Scrubbing Before Embedding

Scrub emails, phones, SSNs before storing in pgvector:

const EMAIL_REGEX = /[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}/g;
const scrubbedText = text.replace(EMAIL_REGEX, '<EMAIL_REDACTED>');

8. Prompt Injection Detection

const JAILBREAK_PATTERNS = [
  /ignore (previous|all) (instructions|rules)/i,
  /dan mode/i,
  /developer mode/i,
  /forget (everything|all)/i,
];

if (JAILBREAK_PATTERNS.some(p => p.test(prompt))) {
  return { content: '⚠️ Prompt violates policies.', flagged: true };
}

9. Signed BullMQ Jobs (If Redis Compromised)

Sign jobs with HMAC to prevent injection:

const signature = crypto.createHmac('sha256', SECRET).update(JSON.stringify(payload)).digest('hex');
// Include signature in job, verify in worker

10. Content Validation for Attachments

Validate using magic numbers, not extensions:

import fileType from 'file-type';
const detected = await fileType.fromBuffer(buffer);
if (!ALLOWED_TYPES.includes(detected?.mime)) {
  /* reject */
}

11. Dependency Management

Before installing ANY package:

npm view <package>           # Exists?
npm audit                    # Vulnerabilities?

Pin exact versions in package.json (no ^ or ~)

Dependabot handles weekly updates. See .github/dependabot.yml.

12. Discord Markdown Injection Prevention

ALWAYS escape user-provided content before displaying in Discord embeds:

import { escapeMarkdown } from 'discord.js';

// βœ… CORRECT - Escape at display time
const displayName = escapeMarkdown(character.displayName);
embed.setTitle(`Character: ${displayName}`);

// ❌ WRONG - Raw user input in embed
embed.setTitle(`Character: ${character.displayName}`); // Vulnerable!

Fields to always escape:

  • Guild names, channel names, usernames
  • Character names, display names, persona fields
  • Personality names, config names, preset names
  • Any user-provided text in embeds

Pattern: Store raw values in data structures, escape at display time only.

Admin Endpoint Security

Current: X-Owner-Id header validation Future: HMAC signatures with INTERNAL_SERVICE_SECRET

# Rate limit admin endpoints
const adminRateLimiter = rateLimit({
  windowMs: 15 * 60 * 1000, max: 10
});

Red Flags - Consult This Skill When:

  • Committing changes with credentials
  • Handling user input to AI
  • Processing file uploads
  • Installing npm packages suggested by AI
  • Implementing admin/destructive commands
  • Logging anything with user data
  • Writing shell commands with execSync/spawn (use execFileSync with arrays!)

Related Skills

  • tzurot-observability - Security logging without PII
  • tzurot-types - Input validation with Zod schemas
  • tzurot-git-workflow - Pre-commit verification checks

References

Install

Download ZIP
Requires askill CLI v1.0+β–Ά

AI Quality Score

95/100Analyzed 2/9/2026

An exceptional security skill document that combines general best practices with project-specific context. It provides highly actionable code examples for common vulnerabilities like command injection and secret management.

100
100
75
95
100

Metadata

Licenseunknown
Version-
Updated2/5/2026
Publishermajiayu000

Tags

apici-cddatabasegithubgithub-actionsobservabilitypromptingsecuritytesting