How to Use Fullstack Guardian in Claude Code for Security Development
Purpose
This post demonstrates how to use Fullstack Guardian skill in Claude Code to implement security best practices across your fullstack development workflow.
Environment
- Claude Code (latest)
- claude-skills plugin
- Fullstack Guardian skill
- Any web development project
What is Fullstack Guardian?
Fullstack Guardian is a specialized skill in the claude-skills ecosystem that provides comprehensive security patterns for fullstack development. When I’m working on features that involve authentication, input handling, or API endpoints, this skill helps me identify and fix security issues before they become problems.
The skill covers these security areas:
- Authentication/Authorization: Proper session management, JWT handling, permission checks
- Input Validation: SQL injection prevention, XSS protection, CSRF tokens
- Secret Management: Environment variables, API key storage, credential handling
- API Security: Rate limiting, error message safety, request validation
- Data Protection: Encryption, hashing, secure storage patterns
Installation and Setup
To use Fullstack Guardian, you need the claude-skills plugin installed. Here’s how I set it up:
npm install -g @jeffallan/claude-skillsThen activate Fullstack Guardian in your Claude Code session by asking for it directly:
# In Claude Code/skill fullstack-guardianCore Usage Patterns
When I use Fullstack Guardian, I trigger it in these situations:
- Adding authentication features
- Creating API endpoints that handle user input
- Implementing file uploads or data processing
- Working with payment forms or sensitive data
- Setting up session management
Example 1: Secure API Endpoint Development
When I create a new API endpoint, I ask Fullstack Guardian to review it:
"I'm creating a user login endpoint. Please check for security issues."The skill immediately identifies potential vulnerabilities:
app.post('/login', async (req, res) => { const { email, password } = req.body const user = await db.query( `SELECT * FROM users WHERE email = '${email}'` ) if (user.password === password) { res.json({ token: user.token }) }})Fullstack Guardian points out:
- SQL injection: Direct string interpolation in query
- Plaintext password: No hashing comparison
- Missing rate limiting: Brute force attacks possible
- No input validation: Email format not checked
Here’s the secured version:
import { z } from 'zod'import bcrypt from 'bcrypt'import rateLimit from 'express-rate-limit'
// Input validationconst loginSchema = z.object({ email: z.string().email(), password: z.string().min(8)})
// Rate limitingconst loginLimiter = rateLimit({ windowMs: 15 * 60 * 1000, // 15 minutes max: 5 // 5 attempts})
app.post('/login', loginLimiter, async (req, res) => { // Validate input const { email, password } = loginSchema.parse(req.body)
// Parameterized query const user = await db.query( 'SELECT * FROM users WHERE email = $1', [email] )
// Hashed password comparison const isValid = await bcrypt.compare(password, user.passwordHash)
if (isValid) { // Generate secure token const token = jwt.sign( { userId: user.id }, process.env.JWT_SECRET, { expiresIn: '1h' } ) res.json({ token }) } else { res.status(401).json({ error: 'Invalid credentials' }) }})Example 2: Handling Secrets Properly
I often need to store API keys and database credentials. Fullstack Guardian taught me the right way:
const API_KEY = "sk-proj-xxxxx"const DB_PASSWORD = "mypassword123"
async function fetchData() { const response = await fetch('https://api.example.com', { headers: { 'Authorization': `Bearer ${API_KEY}` } }) return response.json()}// Validate required secrets on startupconst requiredEnvVars = ['API_KEY', 'DB_PASSWORD', 'JWT_SECRET'] as constrequiredEnvVars.forEach(key => { if (!process.env[key]) { throw new Error(`${key} not configured`) }})
async function fetchData() { const response = await fetch('https://api.example.com', { headers: { 'Authorization': `Bearer ${process.env.API_KEY}` } }) return response.json()}The skill showed me that hardcoding secrets in source code is dangerous because:
- Secrets get committed to git history
- Anyone with repository access can see them
- Rotating compromised secrets is difficult
- Environment-specific configs can’t be managed
Example 3: Input Validation Patterns
When handling user input, Fullstack Guardian recommends using validation schemas:
import { z } from 'zod'
const userRegistrationSchema = z.object({ email: z.string().email("Invalid email format"), password: z.string() .min(12, "Password must be at least 12 characters") .regex(/[A-Z]/, "Must contain uppercase letter") .regex(/[a-z]/, "Must contain lowercase letter") .regex(/[0-9]/, "Must contain number"), age: z.number().int().min(18).max(120), bio: z.string().max(500).optional()})
// Usage in API handlerapp.post('/register', async (req, res) => { try { const validated = userRegistrationSchema.parse(req.body) // Process validated data } catch (error) { res.status(400).json({ error: error.errors }) }})This prevents:
- SQL injection through validated types
- XSS attacks by sanitizing strings
- Invalid data types from reaching business logic
- Buffer overflow attacks through length limits
Best Practices
DO
- Use parameterized queries: Never interpolate user input into SQL
- Validate all inputs: Use schemas like Zod for runtime validation
- Hash passwords: Use bcrypt or argon2, never store plaintext
- Implement rate limiting: Protect all authentication endpoints
- Check permissions: Verify user can access requested resources
- Use HTTPS: Never send credentials over HTTP
- Sanitize error messages: Don’t leak system information to users
- Rotate secrets: Change API keys and credentials regularly
DON’T
- Hardcode secrets: Keep credentials in environment variables
- Roll your own crypto: Use established libraries for encryption
- Trust client input: Validate everything on the server
- Expose stack traces: Return generic errors to users
- Skip authentication: Even “internal” endpoints need protection
- Ignore CORS: Configure properly, don’t disable it
- Forget logging: Record security events for audit trails
Common Workflow
Here’s how I integrate Fullstack Guardian into my development:
- Write the feature: Implement basic functionality
- Trigger the skill: “Check this code for security issues”
- Review findings: Read identified vulnerabilities
- Apply fixes: Update code following recommendations
- Verify changes: Test that security measures work
- Document patterns: Note what to avoid in future
Related Skills
Fullstack Guardian works well with these other claude-skills:
- springboot-security: Spring Boot specific security patterns
- backend-patterns: API design and architecture
- frontend-patterns: Client-side security practices
- security-review: Comprehensive security audits
Summary
In this post, I showed how to use Fullstack Guardian skill in Claude Code to implement security best practices across your fullstack development. The key point is that security isn’t an afterthought—it’s a foundational part of writing production code. By triggering this skill during development, you catch vulnerabilities before they reach production.
Final Words + More Resources
My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me
Here are also the most important links from this article along with some further resources that will help you in this scope:
Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!
Comments