-
Notifications
You must be signed in to change notification settings - Fork 0
Security
Luna includes comprehensive security measures to protect your data and system.
| Area | Protection |
|---|---|
| Secrets | Docker secrets, encrypted storage |
| Authentication | JWT tokens, bcrypt passwords |
| Authorization | Per-user isolation |
| Network | Rate limiting, SSRF protection |
| Code | Sandboxed execution |
| Data | Encryption at rest |
Sensitive credentials are stored as Docker secrets, never in code or environment variables:
# Create secrets directory
mkdir -p secrets
# Store secrets (not in version control)
echo "password" > secrets/postgres_password.txt
echo "jwt-key" > secrets/jwt_secret.txt| Secret | Purpose |
|---|---|
postgres_password.txt |
Database password |
jwt_secret.txt |
JWT signing key |
redis_password.txt |
Redis password |
encryption_key.txt |
Token encryption |
openai_api_key.txt |
OpenAI API |
anthropic_api_key.txt |
Anthropic API |
groq_api_key.txt |
Groq API |
google_api_key.txt |
Google AI API |
xai_api_key.txt |
xAI API |
openrouter_api_key.txt |
OpenRouter API |
elevenlabs_api_key.txt |
ElevenLabs TTS |
# .gitignore
secrets/
*.txt
!secrets/.gitkeepLuna uses JSON Web Tokens for authentication:
| Token | Lifetime | Purpose |
|---|---|---|
| Access | 7 days | API authentication |
| Refresh | 7 days | Token refresh |
- Hashed with bcrypt
- Salt rounds: 12
- Never stored in plaintext
1. User logs in with email/password
2. Server validates credentials
3. Access + refresh tokens issued
4. Client includes access token in requests
5. Refresh token used to get new access token
OAuth tokens (Google, Microsoft) are encrypted at rest:
- Algorithm: AES-256-GCM
- Key: From
encryption_key.txt - IV: Randomly generated per token
PostgreSQL supports:
- Connection encryption (SSL)
- Data-at-rest encryption (OS-level)
Redis-backed rate limiting protects against abuse:
| Endpoint | Limit | Window |
|---|---|---|
/api/auth/login |
10 | 1 min |
/api/auth/register |
5 | 1 min |
/api/chat/send |
60 | 1 min |
/api/chat/tts |
10 | 1 min |
/api/abilities/* |
100 | 1 min |
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 45
X-RateLimit-Reset: 1640000000
All API inputs validated with Zod schemas:
const messageSchema = z.object({
message: z.string().min(1).max(100000),
});
const sessionSchema = z.object({
mode: z.enum(['assistant', 'companion', 'voice']),
});- Type checking
- Length limits
- Format validation
- Enum constraints
- Custom rules
URL validation on external requests:
- Private IP ranges (10.x, 192.168.x, etc.)
- Localhost (127.0.0.1)
- Internal DNS names
- Non-HTTP protocols
const isAllowedUrl = (url: string) => {
const parsed = new URL(url);
// Block private IPs
// Block localhost
// Only allow http/https
return isPublicUrl(parsed);
};Code execution runs in isolated Docker containers:
- Separate container per execution
- No network access
- Limited filesystem
- Resource limits (CPU, memory, time)
- User namespace isolation
| Resource | Limit |
|---|---|
| CPU | 1 core |
| Memory | 512MB |
| Time | 30 seconds |
| Disk | 100MB |
Helmet.js provides security headers:
| Header | Value |
|---|---|
| Content-Security-Policy | Strict CSP |
| X-Frame-Options | DENY |
| X-Content-Type-Options | nosniff |
| Strict-Transport-Security | max-age=31536000 |
| X-XSS-Protection | 1; mode=block |
Login attempt tracking for IP blocking:
- Failed logins
- Invalid tokens
- Rate limit violations
// After 5 failed attempts in 15 minutes
// IP blocked for 1 hourDocker containers are hardened:
security_opt:
- no-new-privileges:true
cap_drop:
- ALL
read_only: true- Non-root users
- Minimal permissions
- Isolated networks
All database queries use parameterized statements:
// Safe
await db.query(
'SELECT * FROM users WHERE id = $1',
[userId]
);
// Never
// await db.query(`SELECT * FROM users WHERE id = ${userId}`);External commands use spawn, not exec:
// Safe - no shell interpretation
spawn('python', ['script.py', arg]);
// Dangerous - shell injection possible
// exec(`python script.py ${arg}`);Document uploads are validated:
- MIME type verification
- Extension whitelist
- Size limit (10MB)
- Content scanning
| Type | Extensions |
|---|---|
| Text | .txt, .md, .json, .csv |
| Documents | |
| Images | .png, .jpg, .jpeg, .gif, .webp |
- Users can only access their own data
- Session ownership verified
- Resource access controlled
- All inputs sanitized
- Response filtering
- Error message sanitization
-
Use Docker secrets
- Never hardcode credentials
- Rotate keys periodically
-
Enable HTTPS
- Use reverse proxy (nginx)
- Valid SSL certificates
-
Network isolation
- Internal services not exposed
- Firewall rules
-
Regular updates
- Keep dependencies updated
- Monitor security advisories
-
Strong passwords
- 12+ characters
- Mix of character types
-
Secure API keys
- Don't share keys
- Use key rotation
-
Local mode for sensitive data
- Use Ollama for privacy
- Disable external APIs
Report security vulnerabilities to:
- GitHub Security Advisories
- Email: security@bitwarelabs.com
Please:
- Don't disclose publicly
- Provide reproduction steps
- Allow time for fix