All skills
simota avatar

/sentinel

@e307415
by shingo imotasimota/agent-skills85 stars
15

Analyzing code statically for security flaws: hardcoded secrets, SQL injection, input validation, security headers, dependency CVEs. Not for runtime exploit checks (Probe) or code review (Judge).

Use this Skill: https://skilld.dev/gh/simota/agent-skills/sentinel

This session only. Nothing lands on disk.

referencedefensive-controls.md

≈2k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Defensive Controls & False Positive Management

Purpose: Apply established defensive controls during SECURE, and manage false positives during FILTER. Covers headers, validation, secrets, rate limiting, confidence scoring, delta scanning, and SARIF output.


1. Security Headers

Header Purpose Priority
Content-Security-Policy Prevent XSS and injection Critical
Strict-Transport-Security Force HTTPS Critical
X-Content-Type-Options Prevent MIME sniffing High
X-Frame-Options Prevent clickjacking High
Referrer-Policy Control referrer leakage Medium
Permissions-Policy Disable unnecessary browser features Medium

Note: X-XSS-Protection is deprecated in modern browsers; CSP is the replacement.

Next.js

const securityHeaders = [
  {
    key: 'Content-Security-Policy',
    value: [
      "default-src 'self'",
      "script-src 'self'", // Avoid 'unsafe-inline' 'unsafe-eval' in production
      "style-src 'self' 'unsafe-inline'",
      "img-src 'self' data: https:",
      "font-src 'self'",
      "connect-src 'self' https://api.example.com",
      "frame-ancestors 'none'",
      "base-uri 'self'",
      "form-action 'self'",
    ].join('; '),
  },
  { key: 'Strict-Transport-Security', value: 'max-age=31536000; includeSubDomains; preload' },
  { key: 'X-Content-Type-Options', value: 'nosniff' },
  { key: 'X-Frame-Options', value: 'DENY' },
  { key: 'Referrer-Policy', value: 'strict-origin-when-cross-origin' },
  { key: 'Permissions-Policy', value: 'camera=(), microphone=(), geolocation=()' },
];

module.exports = {
  async headers() {
    return [{ source: '/:path*', headers: securityHeaders }];
  },
};

Express.js (helmet)

import helmet from 'helmet';
app.use(helmet());
app.use(
  helmet.contentSecurityPolicy({
    directives: {
      defaultSrc: ["'self'"], scriptSrc: ["'self'"],
      styleSrc: ["'self'", "'unsafe-inline'"], imgSrc: ["'self'", 'data:', 'https:'],
      connectSrc: ["'self'", 'https://api.example.com'], fontSrc: ["'self'"],
      objectSrc: ["'none'"], frameSrc: ["'none'"], upgradeInsecureRequests: [],
    },
  })
);

CSP Violation Reporting

// Use report-only mode during rollout, then switch to enforcing
{ key: 'Content-Security-Policy-Report-Only', value: "default-src 'self'; report-uri /api/csp-report" }

2. Input Validation

Boundary validation is mandatory. Prefer Zod when adding runtime schemas.

Zod Schema Examples

import { z } from 'zod';

const emailSchema = z.string().email().max(254);
const passwordSchema = z.string().min(8).max(128)
  .regex(/[A-Z]/).regex(/[a-z]/).regex(/[0-9]/).regex(/[^A-Za-z0-9]/);
const urlSchema = z.string().url().refine((url) => url.startsWith('https://'), 'Must use HTTPS');
const uuidSchema = z.string().uuid();

const userFormSchema = z.object({
  email: emailSchema,
  password: passwordSchema,
  name: z.string().min(1).max(100).trim(),
  age: z.number().int().min(13).max(120).optional(),
});

Express Validation Middleware

function validate(schema: ZodSchema) {
  return (req: Request, res: Response, next: NextFunction) => {
    const result = schema.safeParse({ body: req.body, query: req.query, params: req.params });
    if (!result.success) {
      return res.status(400).json({
        error: 'Validation failed',
        details: result.error.issues.map((i) => ({ path: i.path.join('.'), message: i.message })),
      });
    }
    req.validated = result.data;
    next();
  };
}

3. Secret Management

Never hardcode secrets. Prefer environment variables with schema validation, then move to managed secret stores for production.

Environment Variables

const envSchema = z.object({
  API_KEY: z.string().min(1),
  DATABASE_URL: z.string().url(),
  JWT_SECRET: z.string().min(32),
  NODE_ENV: z.enum(['development', 'production', 'test']),
});
const env = envSchema.parse(process.env);

.env Hygiene

# .gitignore
.env
.env.local
.env.*.local
*.pem
*.key

Secret Stores (Production)

  • AWS Secrets Manager: GetSecretValueCommand with region config
  • HashiCorp Vault: vault.read('secret/data/path')
  • Rotation: Use TTL-based cache (5min default) with lazy refresh

4. Rate Limiting

Use stricter limits on auth and expensive endpoints.

import rateLimit from 'express-rate-limit';

const limiter = rateLimit({ windowMs: 15 * 60 * 1000, max: 100, standardHeaders: true, legacyHeaders: false });
app.use(limiter);

const authLimiter = rateLimit({ windowMs: 60 * 60 * 1000, max: 5, skipSuccessfulRequests: true });
app.use('/api/auth/login', authLimiter);

For distributed systems, use Redis-backed stores (rate-limit-redis).


5. False Positive Management

Raw SAST alerts contain ~53% false positives. Without filtering, teams stop trusting the tool.

FP rate Assessment Developer trust
> 40% Harmful Very low
20-40% Needs work Low
10-20% Target range Medium-High
< 10% Excellent High

Framework-Aware Suppression

Suppress findings when framework-native protections are in place:

sanitizer_functions: [sanitizeHtml, escapeSQL, purifyInput]
auth_middleware: [requireAuth, requireRole, requireApiKey]
csrf_protection: "Next.js built-in CSRF protection"
rate_limiting: "Handled at API Gateway"

Delta Scanning

Mode Scope Use when
PR-level Changed files only Fast review and merge gates
Periodic Full repository Weekly or explicit full audits
Baseline Existing findings suppressed New scanner rollout on legacy code

Confidence Scoring

Factor Weight
Multi-engine consensus +30%
Known pattern match +20%
Data-flow reachability +25%
Framework mismatch -20%
Test or mock location -30%

Tiers: HIGH (≥80%) → include immediately · MEDIUM (50-79%) → report with note · LOW (<50%) → suppress unless exhaustive

Hybrid LLM+SAST Filtering

Approach Accuracy
Rules only (SAST) 35.7%
LLM only 65.5%
LLM + SAST (Hybrid) 89.5%

LLM excels at: cross-function data-flow reasoning, upstream validation recognition, exploit-feasibility assessment, framework security guarantee recognition.

Semgrep Assistant Memories achieves 85% FP reduction by learning from past triage decisions. SAST-Genius (Semgrep + fine-tuned LLM) achieves 91% FP reduction.


6. SARIF Output

Use SARIF when CI, GitHub Code Scanning, or IDE tooling needs machine-readable results.

{
  "$schema": "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/main/sarif-2.1/schema/sarif-schema-2.1.0.json",
  "version": "2.1.0",
  "runs": [{
    "tool": { "driver": { "name": "Sentinel", "version": "1.0" } },
    "results": [{
      "ruleId": "SECRET-001",
      "level": "error",
      "message": { "text": "Hardcoded API key detected" },
      "locations": [{
        "physicalLocation": {
          "artifactLocation": { "uri": "src/config.ts" },
          "region": { "startLine": 42 }
        }
      }],
      "properties": { "confidence": 0.92, "owasp": "A07:2025" }
    }]
  }]
}

Source: OWASP Top 10:2025 · Semgrep Assistant Memories · SAST-Genius (arXiv) · InfoWorld: SAST + AI FP Reduction

Source: SKILL.md on GitHub

1 alert13d5 checks · Risk SAFE
  • Gen Agent Trust Hub13d

    The 'sentinel' skill is a comprehensive, professional-grade static security auditor for code. It focuses on identifying hardcoded secrets, injection vulnerabilities, and supply chain risks using established security standards like OWASP Top 10:2025 and MASVS. The security analyzer has thoroughly evaluated the skill and confirmed that all identified code patterns, including those flagged by heuristic detectors, are legitimate defensive components, audit guidelines, or detection regexes rather than malicious payloads.

  • Socket13d

    No alerts

  • Snyk13d

    Risk: LOW · No issues

  • Runlayer6mo

    4/7 files flagged

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at e307415. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 2 days ago.

Activeupdated 2 weeks ago

README badge

README badge for simota/agent-skills/sentinel