MCPInstall

security engineer

Implement security best practices across the application stack. Use when securing APIs, implementing authentication, preventing vulnerabilities, or conducting security reviews. Covers OWASP Top 10, auth patterns, input validation, encryption, and security monitoring.

Installs
210
Last 24h
—
Trending rank
—
Security
Not audited

Install

Works with every agent the skills CLI supports.

npx skills add https://github.com/daffy0208/ai-dev-standards --skill security-engineer
  1. 01

    Install

    Run the command in your project. The CLI asks which agents to install for.

  2. 02

    Describe the task

    Ask your agent for something this skill covers. It loads security engineer automatically when relevant.

  3. 03

    Review the result

    The agent follows the SKILL.md steps, scripts and references bundled with the skill.

SKILL.md

The instructions your agent reads when the skill is triggered.

Security Engineer

Security is not optional - build it in from day one.

Core Principle

Security is built-in, not bolted-on.

Every feature, every endpoint, every data flow must consider security implications. Security vulnerabilities cost 10x more to fix in production than during development.

5 Security Pillars

Pillar 1: Authentication & Authorization 🔐

Authentication: Who are you? Authorization: What can you do?

Authentication Strategies

JWT (JSON Web Tokens):

  • When: Stateless APIs, mobile apps, microservices
  • How: Sign tokens with secret, store in httpOnly cookies or Authorization header
  • Security: Use RS256 (not HS256), short expiry (15min access, 7d refresh)
// Example: Next.js API with JWT
import { SignJWT, jwtVerify } from 'jose'

const secret = new TextEncoder().encode(process.env.JWT_SECRET!)

export async function createToken(userId: string) {
  return await new SignJWT({ userId })
    .setProtectedHeader({ alg: 'HS256' })
    .setExpirationTime('15m')
    .sign(secret)
}

export async function verifyToken(token: string) {
  const { payload } = await jwtVerify(token, secret)
  return payload
}

Session-Based:

  • When: Traditional web apps, server-side rendering
  • How: Server stores session ID in encrypted cookie
  • Security: HttpOnly, Secure, SameSite=Strict cookies

OAuth 2.0 / OIDC:

  • When: Social login, third-party integrations
  • How: Use NextAuth.js, Passport.js, or Auth0
  • Security: Validate state parameter, use PKCE for mobile

Authorization Patterns

RBAC (Role-Based Access Control):

// Define roles
enum Role {
  ADMIN = 'admin',
  USER = 'user',
  GUEST = 'guest'
}

// Check permissions
function requireRole(allowedRoles: Role[]) {
  return (req, res, next) => {
    if (!allowedRoles.includes(req.user.role)) {
      return res.status(403).json({ error: 'Forbidden' })
    }
    next()
  }
}

// Usage
app.delete('/api/users/:id', requireRole([Role.ADMIN]), deleteUser)

ABAC (Attribute-Based):

  • More granular: user can edit resource if they created it
  • Example: User can delete post only if post.authorId === user.id

Key Principles:

  • ✅ Always verify authentication before authorization
  • ✅ Default deny (whitelist, not blacklist)
  • ✅ Check permissions on server, never trust client
  • ✅ Re-verify permissions before critical actions

Pillar 2: Input Validation & Sanitization 🛡️

Never trust user input - validate, sanitize, escape everything.

Prevent SQL Injection

❌ Bad (Vulnerable):

// DON'T DO THIS!
const query = `SELECT * FROM users WHERE email = '${userInput}'`
db.query(query) // SQL injection vulnerability!

✅ Good (Parameterized Queries):

// Always use parameterized queries
const query = 'SELECT * FROM users WHERE email = ?'
db.query(query, [userInput]) // Safe - parameterized

// With Prisma
const user = await prisma.user.findUnique({
  where: { email: userInput } // Safe - ORM handles it
})

Prevent XSS (Cross-Site Scripting)

❌ Bad (Vulnerable):

// DON'T DO THIS!
<div dangerouslySetInnerHTML={{ __html: userInput }} />

✅ Good (Escaped):

// React automatically escapes
;<div>{userInput}</div> // Safe

// If you must render HTML, sanitize first
import DOMPurify from 'isomorphic-dompurify'
;<div dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(userInput) }} />

Input Validation with Zod

import { z } from 'zod'

const UserSchema = z.object({
  email: z.string().email().max(255),
  password: z.string().min(8).max(100),
  age: z.number().int().min(13).max(120),
  website: z.string().url().optional()
})

// Validate
const result = UserSchema.safeParse(req.body)
if (!result.success) {
  return res.status(400).json({ errors: result.error.issues })
}

const validData = result.data // Type-safe!

File Upload Security

import multer from 'multer'

const upload = multer({
  limits: {
    fileSize: 5 * 1024 * 1024 // 5MB max
  },
  fileFilter: (req, file, cb) => {
    // Whitelist file types
    const allowedTypes = ['image/jpeg', 'image/png', 'image/webp']
    if (!allowedTypes.includes(file.mimetype)) {
      return cb(new Error('Invalid file type'))
    }
    cb(null, true)
  }
})

// Generate random filenames (don't trust user input)
const filename = crypto.randomUUID() + path.extname(file.originalname)

Key Principles:

  • ✅ Validate on server (never trust client validation)
  • ✅ Use schema validation libraries (Zod, Yup, Joi)
  • ✅ Whitelist allowed values, don't blacklist
  • ✅ Escape output based on context (HTML, URL, JS)

Pillar 3: Secure Configuration 🔧

Environment Variables

Never commit secrets:

# .env (add to .gitignore!)
DATABASE_URL="postgresql://user:pass@localhost:5432/db"
JWT_SECRET="generate-with-openssl-rand-base64-32"
OPENAI_API_KEY="sk-..."

Access in code:

// Validate env vars on startup
if (!process.env.JWT_SECRET) {
  throw new Error('JWT_SECRET is required')
}

const config = {
  jwtSecret: process.env.JWT_SECRET,
  databaseUrl: process.env.DATABASE_URL
}

Secret Management (Production):

  • AWS Secrets Manager
  • Vercel Environment Variables
  • HashiCorp Vault
  • Doppler

Security Headers

// Next.js middleware
export function middleware(request: NextRequest) {
  const response = NextResponse.next()

  // Prevent clickjacking
  response.headers.set('X-Frame-Options', 'DENY')

  // Prevent MIME sniffing
  response.headers.set('X-Content-Type-Options', 'nosniff')

  // XSS Protection
  response.headers.set('X-XSS-Protection', '1; mode=block')

  // Content Security Policy
  response.headers.set(
    'Content-Security-Policy',
    "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'"
  )

  // HTTPS only
  response.headers.set('Strict-Transport-Security', 'max-age=31536000; includeSubDomains')

  return response
}

CORS Configuration

// Configure CORS properly
app.use(
  cors({
    origin:
      process.env.NODE_ENV === 'production' ? 'https://yourdomain.com' : 'http://localhost:3000',
    credentials: true, // Allow cookies
    methods: ['GET', 'POST', 'PUT', 'DELETE'],
    allowedHeaders: ['Content-Type', 'Authorization']
  })
)

Key Principles:

  • ✅ Use environment variables for all secrets
  • ✅ Different secrets per environment (dev, staging, prod)
  • ✅ Rotate secrets regularly
  • ✅ Set security headers on all responses
  • ✅ Configure CORS restrictively

Pillar 4: Data Protection 🔒

Password Hashing

❌ Never store passwords in plain text or use MD5/SHA1!

✅ Use bcrypt or argon2:

import bcrypt from 'bcrypt'

// Hash password (on signup)
const saltRounds = 12
const hashedPassword = await bcrypt.hash(password, saltRounds)
await db.user.create({
  email,
  password: hashedPassword // Store hash, never plain text
})

// Verify password (on login)
const user = await db.user.findUnique({ where: { email } })
const isValid = await bcrypt.compare(password, user.password)
if (!isValid) {
  throw new Error('Invalid credentials')
}

Encryption at Rest

Sensitive data should be encrypted:

import crypto from 'crypto'

const algorithm = 'aes-256-gcm'
const key = Buffer.from(process.env.ENCRYPTION_KEY!, 'hex')

function encrypt(text: string) {
  const iv = crypto.randomBytes(16)
  const cipher = crypto.createCipheriv(algorithm, key, iv)
  const encrypted = Buffer.concat([cipher.update(text, 'utf8'), cipher.final()])
  const authTag = cipher.getAuthTag()
  return {
    iv: iv.toString('hex'),
    encryptedData: encrypted.toString('hex'),
    authTag: authTag.toString('hex')
  }
}

function decrypt(encrypted: any) {
  const decipher = crypto.createDecipheriv(algorithm, key, Buffer.from(encrypted.iv, 'hex'))
  decipher.setAuthTag(Buffer.from(encrypted.authTag, 'hex'))
  return decipher.update(encrypted.encryptedData, 'hex', 'utf8') + decipher.final('utf8')
}

// Encrypt sensitive fields
const ssn = encrypt(user.ssn)
await db.user.update({ where: { id }, data: { ssnEncrypted: JSON.stringify(ssn) } })

Encryption in Transit

Always use HTTPS:

  • Development: mkcert for local HTTPS
  • Production: Let's Encrypt, Cloudflare, Vercel (auto HTTPS)

Verify external API certificates:

// Don't disable SSL verification in production!
fetch(url, {
  // DON'T: agent: new https.Agent({ rejectUnauthorized: false })
})

Key Principles:

  • ✅ Hash passwords with bcrypt (12+ rounds) or argon2
  • ✅ Encrypt PII (SSN, credit cards, health data)
  • ✅ Use HTTPS everywhere (enforce with HSTS header)
  • ✅ Encrypt database backups

Pillar 5: Monitoring & Response 📊

Rate Limiting

Prevent brute force and DDoS:

import rateLimit from 'express-rate-limit'

// Global rate limit
const limiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 minutes
  max: 100, // 100 requests per window
  message: 'Too many requests from this IP'
})
app.use(limiter)

// Stricter limit for auth endpoints
const authLimiter = rateLimit({
  windowMs: 15 * 60 * 1000,
  max: 5, // Only 5 login attempts per 15min
  skipSuccessfulRequests: true
})
app.post('/api/auth/login', authLimiter, loginHandler)

Audit Logging

Log all security-relevant events:

async function auditLog(event: {
  userId?: string
  action: string
  resource: string
  ip: string
  userAgent: string
  success: boolean
  metadata?: any
}) {
  await db.auditLog.create({
    data: {
      ...event,
      timestamp: new Date()
    }
  })
}

// Usage
await auditLog({
  userId: user.id,
  action: 'LOGIN',
  resource: 'auth',
  ip: req.ip,
  userAgent: req.headers['user-agent'],
  success: true
})

Error Handling

Don't leak sensitive info in errors:

❌ Bad:

// Exposes database structure!
catch (error) {
  res.status(500).json({ error: error.message })
}

✅ Good:

catch (error) {
  // Log full error server-side
  console.error('Error:', error)

  // Send generic message to client
  res.status(500).json({
    error: 'Internal server error',
    requestId: generateRequestId() // For support
  })
}

Security Monitoring

Tools to integrate:

  • Sentry: Error tracking, security alerts
  • Datadog: APM, anomaly detection
  • CloudWatch: AWS infrastructure monitoring
  • OWASP ZAP: Automated security scans

Key Principles:

  • ✅ Rate limit all public endpoints
  • ✅ Log authentication attempts, authorization failures
  • ✅ Never expose sensitive data in errors
  • ✅ Set up alerts for suspicious patterns
  • ✅ Regular security audits

OWASP Top 10 Quick Reference

#VulnerabilityPrevention
1Broken Access ControlVerify permissions server-side, default deny
2Cryptographic FailuresUse TLS, hash passwords (bcrypt), encrypt PII
3InjectionParameterized queries, input validation
4Insecure DesignThreat modeling, security requirements
5Security MisconfigurationSecure defaults, remove unused features
6Vulnerable ComponentsKeep dependencies updated, use Dependabot
7Auth & Session IssuesStrong passwords, MFA, secure session mgmt
8Software & Data IntegrityVerify dependencies, sign releases
9Logging & Monitoring FailuresLog security events, set up alerts
10SSRFValidate URLs, whitelist allowed domains

Security Checklist (Pre-Deployment)

Authentication

  • Passwords hashed with bcrypt (12+ rounds)
  • JWT tokens use RS256, short expiry
  • Session cookies are HttpOnly, Secure, SameSite
  • Rate limiting on login endpoints (5 attempts/15min)
  • Password reset uses secure tokens (expires 1 hour)

Authorization

  • All routes check authentication
  • Permissions verified server-side
  • Default deny (whitelist approach)
  • No sensitive operations allowed without re-authentication

Input Validation

  • All user input validated with schema (Zod)
  • SQL queries use parameterized queries/ORM
  • File uploads whitelist types and size limits
  • Output escaped based on context

Configuration

  • No secrets in code or version control
  • Environment variables for all config
  • Security headers set (CSP, HSTS, X-Frame-Options)
  • CORS configured restrictively
  • HTTPS enforced in production

Data Protection

  • PII encrypted at rest
  • TLS/HTTPS for all connections
  • Database backups encrypted
  • Secure secret management (Vault, AWS Secrets)

Monitoring

  • Audit logging for security events
  • Error tracking configured (Sentry)
  • Rate limiting on all public endpoints
  • Alerts for failed login attempts, 5xx errors

Dependencies

  • All dependencies up to date
  • Dependabot enabled
  • No known vulnerabilities (run npm audit)
  • Minimal dependencies (remove unused)

Common Security Mistakes

Mistake 1: Client-Side Authorization

❌ Wrong:

// Hiding UI doesn't prevent access!
{
  user.role === 'admin' && <DeleteButton />
}

✅ Right:

// Always verify on server
app.delete('/api/users/:id', requireAdmin, deleteUser)

Mistake 2: Trusting Client Data

❌ Wrong:

// User can manipulate userId in request!
const userId = req.body.userId
await db.order.create({ data: { userId } })

✅ Right:

// Get userId from authenticated session
const userId = req.user.id // From JWT/session
await db.order.create({ data: { userId } })

Mistake 3: Weak Password Requirements

❌ Wrong:

if (password.length < 6) throw new Error('Too short')

✅ Right:

const passwordSchema = z
  .string()
  .min(8, 'At least 8 characters')
  .regex(/[A-Z]/, 'Needs uppercase')
  .regex(/[a-z]/, 'Needs lowercase')
  .regex(/[0-9]/, 'Needs number')

Mistake 4: Insecure Direct Object References

❌ Wrong:

// User can access any document by changing ID!
const doc = await db.document.findUnique({ where: { id: req.params.id } })
return res.json(doc)

✅ Right:

// Verify ownership
const doc = await db.document.findFirst({
  where: {
    id: req.params.id,
    userId: req.user.id // Ensure user owns this document
  }
})
if (!doc) return res.status(404).json({ error: 'Not found' })
return res.json(doc)

Framework-Specific Guidance

Next.js Security

// middleware.ts - Protect routes
export function middleware(request: NextRequest) {
  const token = request.cookies.get('token')

  // Redirect to login if no token
  if (!token && request.nextUrl.pathname.startsWith('/dashboard')) {
    return NextResponse.redirect(new URL('/login', request.url))
  }

  return NextResponse.next()
}

export const config = {
  matcher: ['/dashboard/:path*', '/api/private/:path*']
}

Express Security

import helmet from 'helmet'
import mongoSanitize from 'express-mongo-sanitize'

app.use(helmet()) // Security headers
app.use(express.json({ limit: '10mb' })) // Prevent large payloads
app.use(mongoSanitize()) // Prevent NoSQL injection

FastAPI Security

from fastapi import Depends, HTTPException
from fastapi.security import HTTPBearer

security = HTTPBearer()

async def get_current_user(token: str = Depends(security)):
    try:
        payload = verify_token(token.credentials)
        return payload['user_id']
    except:
        raise HTTPException(status_code=401, detail="Invalid token")

@app.get("/protected")
async def protected_route(user_id: str = Depends(get_current_user)):
    return {"user_id": user_id}

Security Testing

Automated Tools

  • OWASP ZAP: Web vulnerability scanner
  • Snyk: Dependency vulnerability scanning
  • npm audit: Check for known vulnerabilities
  • Lighthouse: Security audit in Chrome DevTools

Manual Testing

  1. Try SQL injection: ' OR '1'='1
  2. Try XSS: <script>alert('XSS')</script>
  3. Try CSRF: Submit form from different origin
  4. Try path traversal: ../../etc/passwd
  5. Try auth bypass: Access admin routes without token

When to Use This Skill

Use security-engineer skill when:

  • ✅ Implementing authentication/authorization
  • ✅ Building API endpoints
  • ✅ Handling sensitive data (PII, payments, health)
  • ✅ Reviewing code for vulnerabilities
  • ✅ Deploying to production
  • ✅ Conducting security audits

Related Resources

Skills:

  • api-designer - API design patterns (pairs with security)
  • testing-strategist - Security testing strategies
  • deployment-advisor - Production security configuration

Patterns:

  • /STANDARDS/architecture-patterns/authentication-patterns.md
  • /STANDARDS/best-practices/security-best-practices.md

External:


Security is everyone's responsibility. Build it in from day one. 🔒

FAQ

What does the security engineer skill do?

Implement security best practices across the application stack. Use when securing APIs, implementing authentication, preventing vulnerabilities, or conducting security reviews. Covers OWASP Top 10, auth patterns, input validation, encryption, and security monitoring.

How do I install security engineer?

Run npx skills add https://github.com/daffy0208/ai-dev-standards --skill security-engineer in your project. The skills CLI detects the agents you use and copies the skill into the right folder. For Claude Code you can also place the skill folder at ~/.claude/skills/security-engineer/ (personal) or .claude/skills/security-engineer/ (project).

Which AI agents can use security engineer?

Any agent that supports the open Agent Skills format (a folder with a SKILL.md file), including Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Windsurf, Cline, OpenCode and more.

Is security engineer safe to install?

No partner security audit is available yet. Skills can run commands and scripts, so read the SKILL.md and any bundled files before installing.

Who maintains security engineer?

It is published by daffy0208 in daffy0208/ai-dev-standards. It has 210 recorded installs.

More from daffy0208/ai-dev-standards

View all →

animation-designer

daffy0208/ai-dev-standards

Expert in web animations, transitions, and motion design using Framer Motion and CSS

Frontend & Design1.9K installs

brand-designer

daffy0208/ai-dev-standards

Expert in brand identity, logo design, and visual brand systems

Marketing & SEO1.3K installs

3d-visualizer

daffy0208/ai-dev-standards

Expert in Three.js, 3D graphics, and interactive 3D visualizations

Media & Creative665 installs

data-visualizer

daffy0208/ai-dev-standards

Expert in creating charts, dashboards, and data visualizations using modern libraries

572 installs

video-producer

daffy0208/ai-dev-standards

Expert in video playback, streaming, and video player customization

Media & Creative449 installs

knowledge base manager

daffy0208/ai-dev-standards

Open the skill to read its SKILL.md instructions.

438 installs

Popular security skills

View category →

azure-compliance

microsoft/azure-skills

Run Azure compliance and security audits with azqr plus Key Vault expiration checks. Covers best-practice assessment, resource review, policy/compliance validation, and security posture checks. WHEN: compliance scan, security audit, BEFORE running azqr (compliance cli tool), Azure best practices, Key Vault expiration check, expired certificates, expiring secrets, orphaned resources, compliance assessment.

OfficialSecurity567K installs

minimal-run-and-audit

lllllllama/rigorpilot-skills

Rigor Run skill for README-first deep learning repo reproduction. Use when the task is specifically to capture or normalize evidence from the selected smoke test or documented inference or evaluation command and write standardized reprooutputs/ files, including patch notes when repository files changed. Do not use for training execution, initial repo intake, generic environment setup, paper lookup, target selection, hidden scientific-meaning changes, or end-to-end orchestration by itself.

Security477.4K installs

seo-audit

coreyhaines31/marketingskills

When the user wants to audit, review, or diagnose SEO issues on their site. Also use when the user mentions "SEO audit," "technical SEO," "why am I not ranking," "SEO issues," "on-page SEO," "meta tags review," "SEO health check," "my traffic dropped," "lost rankings," "not showing up in Google," "site isn't ranking," "Google update hit me," "page speed," "core web vitals," "crawl errors," "indexing issues," "stuck on page 2," "striking distance keywords," "title tag rewrite," "low CTR," "local SEO," "Google Business Profile," or "map pack." Use this even if the user just says something vague like "my SEO is bad" or "help with SEO" — start with an audit. For building pages at scale to target keywords, see programmatic-seo. For adding structured data, see schema. For AI search optimization, see ai-seo.

Security238.7K installs

firebase-security-rules-auditor

firebase/agent-skills

Audits Firebase (Firestore, Cloud Storage) security rules for vulnerabilities, privilege escalation, role bypasses, create vs update inconsistencies, resource exhaustion, type safety, size limits, and hasOnly ownership checks. Use when auditing/reviewing rules, running red-team rule assessments, or scoring against auditor checklists. Don't use for Firebase CLI (login, deploy), Auth, Crashlytics, Remote Config, or database queries.

OfficialSecurity139.1K installs

audit

pbakaus/impeccable

Run technical quality checks across accessibility, performance, theming, responsive design, and anti-patterns. Generates a scored report with P0-P3 severity ratings and actionable plan. Use when the user wants an accessibility check, performance audit, or technical quality review.

Security81.9K installs

competitors

coreyhaines31/marketingskills

When the user wants to create competitor comparison or alternative pages for SEO and buyer-facing use. Also use when the user mentions 'alternative page,' 'vs page,' 'competitor comparison,' 'comparison page,' '[Product] vs [Product],' '[Product] alternative,' 'competitive landing pages,' 'how do we compare to X,' 'competitor teardown,' 'audit our competitor pages,' 'are our comparison pages out of date,' or 'competitive asset audit.' Use this for any content that positions your product against competitors. Covers four formats: singular alternative, plural alternatives, you vs competitor, and competitor vs competitor. For auditing existing claims (not researching competitors from scratch, which is competitor-profiling; not technical SEO on these pages, which is seo-audit), use the asset audit here. For internal battle cards and sales-specific competitor docs, see sales-enablement.

Security79.3K installs