Integration: Claude Code
This guide walks through deploying Manicode security prompts with Claude Code, from basic setup through validation of secure output.
Setup
Place the security prompt content in a CLAUDE.md file at your repository root. Claude Code reads this file automatically on every session.
# Copy the prompt for your framework
cp prompts/code-security/backend-frameworks/python/01-secure-django-developer-opus.md CLAUDE.md
Or append to an existing CLAUDE.md:
echo "" >> CLAUDE.md
echo "# Security Rules" >> CLAUDE.md
cat prompts/code-security/backend-frameworks/python/01-secure-django-developer-opus.md >> CLAUDE.md
Example: Secure Code Generation
Request:
Write a Django login view that accepts username and password via POST.
Expected output (with security prompt active):
from django.contrib.auth import authenticate, login, logout
from django.http import JsonResponse
from django.views.decorators.http import require_POST
from django.views.decorators.csrf import csrf_protect
from django.middleware.csrf import get_token
import logging
logger = logging.getLogger(__name__)
@require_POST
@csrf_protect
def login_view(request):
import json
try:
data = json.loads(request.body)
except json.JSONDecodeError:
return JsonResponse({"error": "Invalid request body"}, status=400)
username = data.get("username", "").strip()
password = data.get("password", "")
if not username or not password:
return JsonResponse({"error": "Username and password are required"}, status=400)
user = authenticate(request, username=username, password=password)
if user is not None:
login(request, user)
return JsonResponse({"status": "ok"})
else:
# Generic error message — do not reveal whether the username exists
logger.warning("Failed login attempt for username: %s", username)
return JsonResponse({"error": "Invalid credentials"}, status=401)
Security controls present in this output:
| Control | What It Does |
|---|---|
@require_POST | Rejects non-POST requests |
@csrf_protect | Validates CSRF token |
authenticate() | Uses Django's built-in auth (bcrypt by default) |
| Generic error message | Does not reveal whether the username exists |
| Logging of failed attempts | Provides audit trail for brute-force detection |
| No password echo | Password is never included in any response |
Example: Insecure Output (Without Security Prompt)
Without the security prompt, the same request may produce code like:
# INSECURE — for illustration only
from django.http import JsonResponse
from django.contrib.auth.models import User
def login(request):
username = request.POST.get("username")
password = request.POST.get("password")
try:
user = User.objects.get(username=username)
if user.check_password(password):
request.session["user_id"] = user.id
return JsonResponse({"status": "logged in"})
else:
return JsonResponse({"error": "Wrong password"}) # Reveals username exists
except User.DoesNotExist:
return JsonResponse({"error": "User not found"}) # Username enumeration
Security issues in this output:
| Issue | Risk |
|---|---|
| No CSRF protection | Cross-site request forgery |
| No rate limiting consideration | Brute-force attacks |
| Separate error messages for wrong password vs. user not found | Username enumeration |
| No logging | No audit trail |
| Manual session management | Session fixation risk |
| No HTTP method restriction | GET requests could trigger login |
Combining with Validation
To validate Claude Code's output, run a validation prompt after code generation:
# In a separate terminal or CI step
cat generated_code.py | claude --system "$(cat prompts/validation/SV-U-01-nlp-security-guardrail-high.md)" \
"Review this code for security vulnerabilities. Output a structured assessment."
Directory-Level Prompts
Claude Code supports hierarchical prompt files. Use this to apply different security prompts to different parts of your codebase:
project/
CLAUDE.md # General project rules
backend/
CLAUDE.md # Python/Django security prompt
frontend/
CLAUDE.md # React security prompt
infrastructure/
CLAUDE.md # Terraform security prompt
When Claude Code works in the backend/ directory, it reads both the root CLAUDE.md and the backend/CLAUDE.md, applying all rules.
Tips
- Test the prompt by asking Claude Code to generate code with known security implications (login, file upload, database query) and verify the output includes appropriate controls
- Keep prompts focused — A single framework-specific prompt performs better than a catch-all prompt covering multiple frameworks
- Update prompts when you update models — If you switch Claude Code's model version, re-test your prompts against your key test cases