Introduction
In this tutorial, you'll learn how to build a secure AI coding assistant that protects against the kind of vulnerabilities that led to the OpenCode security breach. You'll create a Python-based AI coding agent that implements proper API key management, code validation, and secure AI interaction patterns. This tutorial assumes you have basic Python knowledge and understand AI APIs like OpenAI's GPT.
Prerequisites
- Python 3.8 or higher installed
- Basic understanding of AI APIs (OpenAI, Claude, etc.)
- Access to OpenAI API key (or other AI service)
- Virtual environment set up
- Basic knowledge of API key security practices
Step 1: Set Up Your Development Environment
1.1 Create a Virtual Environment
First, create a dedicated environment to isolate your project dependencies:
python -m venv aicode_env
source aicode_env/bin/activate # On Windows: aicode_env\Scripts\activate
1.2 Install Required Packages
Install the necessary Python packages for AI interaction and security:
pip install openai python-dotenv requests
Step 2: Configure Secure API Key Management
2.1 Create Environment Configuration
Create a .env file in your project root to store your API keys securely:
OPENAI_API_KEY=your_openai_api_key_here
AI_SERVICE=OPENAI
2.2 Implement Secure Key Loading
Create a configuration module to safely load API keys:
import os
from dotenv import load_dotenv
load_dotenv()
def get_api_key():
api_key = os.getenv('OPENAI_API_KEY')
if not api_key:
raise ValueError('API key not found in environment variables')
return api_key
Step 3: Build Secure AI Code Assistant
3.1 Create AI Assistant Class
Build a secure AI assistant class that validates inputs before sending them to AI services:
import openai
from get_api_key import get_api_key
class SecureAIAssistant:
def __init__(self):
openai.api_key = get_api_key()
self.max_tokens = 1000
self.temperature = 0.3
def validate_code(self, code):
"""Validate code for potential malicious patterns"""
malicious_patterns = [
'import os',
'import subprocess',
'exec(',
'eval(',
'__import__',
'os.system',
]
for pattern in malicious_patterns:
if pattern in code:
raise ValueError(f"Potentially malicious code detected: {pattern}")
return True
def generate_code(self, prompt):
"""Generate code with security validation"""
try:
self.validate_code(prompt)
response = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[
{"role": "system", "content": "You are a helpful coding assistant."},
{"role": "user", "content": prompt}
],
max_tokens=self.max_tokens,
temperature=self.temperature
)
return response.choices[0].message.content
except Exception as e:
return f"Error generating code: {str(e)}"
Step 4: Implement Rate Limiting and Monitoring
4.1 Add Rate Limiting
Implement rate limiting to prevent abuse and protect against excessive API usage:
import time
from collections import defaultdict
class RateLimiter:
def __init__(self, max_requests=10, time_window=60):
self.max_requests = max_requests
self.time_window = time_window
self.requests = defaultdict(list)
def is_allowed(self, user_id):
now = time.time()
# Remove old requests outside the time window
self.requests[user_id] = [
req_time for req_time in self.requests[user_id]
if now - req_time < self.time_window
]
if len(self.requests[user_id]) < self.max_requests:
self.requests[user_id].append(now)
return True
return False
4.2 Integrate Rate Limiter with Assistant
Modify your assistant to use rate limiting:
class SecureAIAssistant:
def __init__(self):
openai.api_key = get_api_key()
self.rate_limiter = RateLimiter()
self.max_tokens = 1000
self.temperature = 0.3
def generate_code(self, prompt, user_id=None):
"""Generate code with security and rate limiting"""
try:
# Check rate limit
if user_id and not self.rate_limiter.is_allowed(user_id):
return "Rate limit exceeded. Please wait before making more requests."
self.validate_code(prompt)
response = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[
{"role": "system", "content": "You are a helpful coding assistant."},
{"role": "user", "content": prompt}
],
max_tokens=self.max_tokens,
temperature=self.temperature
)
return response.choices[0].message.content
except Exception as e:
return f"Error generating code: {str(e)}"
Step 5: Add Input Sanitization and Error Handling
5.1 Implement Comprehensive Input Sanitization
Enhance your code validation to catch more potential security issues:
import re
def validate_code(self, code):
"""Enhanced code validation with multiple security checks"""
# Check for dangerous imports
dangerous_imports = ['os', 'subprocess', 'sys', 'pickle', 'marshal']
for imp in dangerous_imports:
if re.search(rf'\bimport\s+{imp}\b', code) or re.search(rf'\bfrom\s+{imp}\s+import', code):
raise ValueError(f"Dangerous import detected: {imp}")
# Check for eval/exec patterns
dangerous_patterns = [r'\beval\s*\(', r'\bexec\s*\(', r'\b__import__\s*\(']
for pattern in dangerous_patterns:
if re.search(pattern, code):
raise ValueError("Potentially dangerous code pattern detected")
# Check for excessive line count
if len(code.split('\n')) > 100:
raise ValueError("Code too long - potential abuse")
return True
Step 6: Test Your Secure AI Assistant
6.1 Create Test Script
Create a test script to verify your assistant works correctly:
from secure_ai_assistant import SecureAIAssistant
# Initialize assistant
assistant = SecureAIAssistant()
# Test normal code generation
prompt = "Write a Python function to calculate Fibonacci numbers"
result = assistant.generate_code(prompt)
print(result)
# Test malicious code detection
malicious_prompt = "import os; os.system('ls')"
result = assistant.generate_code(malicious_prompt)
print(result)
# Test with rate limiting
result = assistant.generate_code(prompt, user_id='user123')
print(result)
Step 7: Monitor and Log Activity
7.1 Add Logging
Implement logging to track usage and detect potential security issues:
import logging
from datetime import datetime
# Configure logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler('ai_assistant.log'),
logging.StreamHandler()
]
)
def generate_code(self, prompt, user_id=None):
"""Generate code with logging"""
logging.info(f"Code generation requested for user: {user_id}")
try:
self.validate_code(prompt)
response = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[
{"role": "system", "content": "You are a helpful coding assistant."},
{"role": "user", "content": prompt}
],
max_tokens=self.max_tokens,
temperature=self.temperature
)
logging.info(f"Code generation successful for user: {user_id}")
return response.choices[0].message.content
except Exception as e:
logging.error(f"Error generating code for user {user_id}: {str(e)}")
return f"Error generating code: {str(e)}"
Summary
This tutorial taught you how to build a secure AI coding assistant that addresses the vulnerabilities seen in the OpenCode breach. You've learned to implement proper API key management, code validation, rate limiting, and error handling. The assistant now protects against malicious code injection, prevents API abuse, and logs all activities for monitoring. These security practices are essential for any AI tool that handles user data or interacts with external services, ensuring that your AI coding assistant remains safe and reliable for users.