Public Access
initial-commit
This commit is contained in:
@@ -0,0 +1,503 @@
|
||||
# Security
|
||||
|
||||
Charybdis provides enterprise-grade security with mTLS authentication and RBAC authorization.
|
||||
|
||||
## Overview
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
A[Client Request] -->|mTLS Handshake| B[TLS Layer]
|
||||
B -->|Certificate| C[Auth Interceptor]
|
||||
C -->|Extract Identity| D{Parse Certificate}
|
||||
D -->|CN, OU, O| E[Role Mapping]
|
||||
E -->|Role| F{Permission Check}
|
||||
F -->|Authorized| G[Entity Service]
|
||||
F -->|Denied| H[PermissionDenied Error]
|
||||
G -->|Audit Log| I[Security Events]
|
||||
|
||||
style C fill:#f9d71c,stroke:#f9a825
|
||||
style F fill:#4A90E2,stroke:#2E5C8A
|
||||
```
|
||||
|
||||
## mTLS Authentication
|
||||
|
||||
Mutual TLS (mTLS) provides certificate-based client authentication.
|
||||
|
||||
### How It Works
|
||||
|
||||
1. **Client** presents X.509 certificate during TLS handshake
|
||||
2. **Server** validates certificate against trusted CA
|
||||
3. **Charybdis** extracts certificate identity (CN, OU, O)
|
||||
4. **RBAC Engine** maps identity to role
|
||||
5. **Permissions** are checked before allowing the request
|
||||
|
||||
### Certificate Structure
|
||||
|
||||
```
|
||||
Subject: CN=admin-user, OU=platform-team, O=Charybdis-Dev, C=US
|
||||
Issuer: CN=Charybdis Root CA, O=Charybdis-Dev, C=US
|
||||
Validity: Not Before: Nov 3 2025, Not After: Nov 3 2026
|
||||
```
|
||||
|
||||
**Fields Used for Authentication**:
|
||||
- `CN` (Common Name) - User or service identifier
|
||||
- `OU` (Organizational Unit) - Team or role identifier
|
||||
- `O` (Organization) - Organization name
|
||||
|
||||
## Configuration
|
||||
|
||||
### Environment Variables
|
||||
|
||||
```bash
|
||||
# Enable mTLS
|
||||
export SECURITY_MTLS_ENABLED=true
|
||||
|
||||
# Server certificate and key
|
||||
export SECURITY_MTLS_SERVER_CERT=./certs/server-cert.pem
|
||||
export SECURITY_MTLS_SERVER_KEY=./certs/server-key.pem
|
||||
|
||||
# Client CA for verification
|
||||
export SECURITY_MTLS_CLIENT_CA=./certs/ca.pem
|
||||
|
||||
# Enable RBAC
|
||||
export SECURITY_RBAC_ENABLED=true
|
||||
```
|
||||
|
||||
### Generating Certificates
|
||||
|
||||
#### Development Certificates
|
||||
|
||||
Use the provided test script:
|
||||
|
||||
```bash
|
||||
./test-mtls-rbac.sh
|
||||
```
|
||||
|
||||
This generates:
|
||||
- `ca.pem` / `ca-key.pem` - Certificate Authority
|
||||
- `server-cert.pem` / `server-key.pem` - Server certificate
|
||||
- `admin-cert.pem` / `admin-key.pem` - Admin client (OU=platform-team)
|
||||
- Various plugin certificates (OU=plugins)
|
||||
|
||||
#### Production Certificates
|
||||
|
||||
For production, use a proper PKI:
|
||||
|
||||
**Options**:
|
||||
- **Internal PKI**: HashiCorp Vault, cert-manager, step-ca
|
||||
- **Public CA**: Let's Encrypt (for internet-facing)
|
||||
- **Enterprise CA**: Your organization's certificate authority
|
||||
|
||||
**Requirements**:
|
||||
- Valid for at least 90 days
|
||||
- Issued by trusted CA
|
||||
- Proper subject alternative names (SANs)
|
||||
- Appropriate key usage extensions
|
||||
|
||||
### Certificate Best Practices
|
||||
|
||||
✅ **DO**:
|
||||
- Use short-lived certificates (24-90 days)
|
||||
- Implement automatic rotation
|
||||
- Monitor expiration dates
|
||||
- Use strong key lengths (2048+ bit RSA or 256+ bit ECC)
|
||||
- Store private keys securely
|
||||
- Use separate CAs for dev/prod
|
||||
|
||||
❌ **DON'T**:
|
||||
- Use self-signed certs in production
|
||||
- Share private keys
|
||||
- Use the same certificate across environments
|
||||
- Ignore expiration warnings
|
||||
- Store keys in version control
|
||||
|
||||
## RBAC Authorization
|
||||
|
||||
Role-Based Access Control (RBAC) enforces fine-grained permissions.
|
||||
|
||||
### Role Mapping
|
||||
|
||||
Charybdis maps certificate attributes to roles:
|
||||
|
||||
```
|
||||
Certificate OU → RBAC Role → Permissions
|
||||
```
|
||||
|
||||
### Default Roles
|
||||
|
||||
| Role | Certificate OU | Description | Permissions |
|
||||
|------|---------------|-------------|-------------|
|
||||
| `platform` | `platform-team` | Platform administrators | Full access (CRUD + list) |
|
||||
| `automation` | `automation` | CI/CD pipelines | Create, read, update, list |
|
||||
| `plugin` | `plugins` | Integration plugins | Read, list only |
|
||||
|
||||
### Permissions
|
||||
|
||||
| Permission | Methods | Description |
|
||||
|------------|---------|-------------|
|
||||
| `entity:create` | CreateEntity | Create new entities |
|
||||
| `entity:read` | GetEntity | Read entity by ID |
|
||||
| `entity:update` | UpdateEntity, PartialUpdateEntity | Modify entities |
|
||||
| `entity:delete` | DeleteEntity | Delete entities |
|
||||
| `entity:list` | ListEntities | List all entities |
|
||||
|
||||
### Permission Matrix
|
||||
|
||||
| Role | Create | Read | Update | Delete | List |
|
||||
|------|--------|------|--------|--------|------|
|
||||
| `platform` | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||
| `automation` | ✅ | ✅ | ✅ | ❌ | ✅ |
|
||||
| `plugin` | ❌ | ✅ | ❌ | ❌ | ✅ |
|
||||
|
||||
## Usage Examples
|
||||
|
||||
### Admin Access (Full Permissions)
|
||||
|
||||
```bash
|
||||
# Create entity
|
||||
grpcurl \
|
||||
-cacert certs/ca.pem \
|
||||
-cert certs/admin-cert.pem \
|
||||
-key certs/admin-key.pem \
|
||||
-d '{"entity": {...}}' \
|
||||
localhost:50051 charybdis.entities.EntityService/CreateEntity
|
||||
|
||||
# ✅ SUCCESS
|
||||
```
|
||||
|
||||
### Automation Access (Limited)
|
||||
|
||||
```bash
|
||||
# CI/CD can create
|
||||
grpcurl \
|
||||
-cacert certs/ca.pem \
|
||||
-cert certs/ci-pipeline-cert.pem \
|
||||
-key certs/ci-pipeline-key.pem \
|
||||
-d '{"entity": {...}}' \
|
||||
localhost:50051 charybdis.entities.EntityService/CreateEntity
|
||||
|
||||
# ✅ SUCCESS
|
||||
|
||||
# But cannot delete
|
||||
grpcurl \
|
||||
-cacert certs/ca.pem \
|
||||
-cert certs/ci-pipeline-cert.pem \
|
||||
-key certs/ci-pipeline-key.pem \
|
||||
-d '{"id": "..."}' \
|
||||
localhost:50051 charybdis.entities.EntityService/DeleteEntity
|
||||
|
||||
# ❌ Code: PermissionDenied
|
||||
# Message: Role 'automation' does not have permission 'entity:delete'
|
||||
```
|
||||
|
||||
### Plugin Access (Read-Only)
|
||||
|
||||
```bash
|
||||
# Plugin can list
|
||||
grpcurl \
|
||||
-cacert certs/ca.pem \
|
||||
-cert certs/defectdojo-plugin-cert.pem \
|
||||
-key certs/defectdojo-plugin-key.pem \
|
||||
-d '{}' \
|
||||
localhost:50051 charybdis.entities.EntityService/ListEntities
|
||||
|
||||
# ✅ SUCCESS
|
||||
|
||||
# But cannot create
|
||||
grpcurl \
|
||||
-cacert certs/ca.pem \
|
||||
-cert certs/defectdojo-plugin-cert.pem \
|
||||
-key certs/defectdojo-plugin-key.pem \
|
||||
-d '{"entity": {...}}' \
|
||||
localhost:50051 charybdis.entities.EntityService/CreateEntity
|
||||
|
||||
# ❌ Code: PermissionDenied
|
||||
# Message: Role 'plugin' does not have permission 'entity:create'
|
||||
```
|
||||
|
||||
## Custom Role Configuration
|
||||
|
||||
### Defining Custom Roles
|
||||
|
||||
Edit `src/main.rs::setup_default_rbac_config()`:
|
||||
|
||||
```rust
|
||||
let role_mappings = vec![
|
||||
// Custom developer role
|
||||
RoleMapping {
|
||||
role: "developer".to_string(),
|
||||
rules: vec![RoleRule {
|
||||
subject: SubjectMatch {
|
||||
cn: None,
|
||||
ou: Some("engineering".to_string()),
|
||||
o: None,
|
||||
},
|
||||
}],
|
||||
},
|
||||
];
|
||||
|
||||
let mut permissions = HashMap::new();
|
||||
permissions.insert(
|
||||
"developer".to_string(),
|
||||
vec![
|
||||
"entity:create".to_string(),
|
||||
"entity:read".to_string(),
|
||||
"entity:list".to_string(),
|
||||
],
|
||||
);
|
||||
```
|
||||
|
||||
### Certificate-Based Mapping
|
||||
|
||||
Map specific certificates to roles:
|
||||
|
||||
```rust
|
||||
// Map by CN (specific user/service)
|
||||
RoleRule {
|
||||
subject: SubjectMatch {
|
||||
cn: Some("jenkins-ci".to_string()),
|
||||
ou: None,
|
||||
o: None,
|
||||
},
|
||||
}
|
||||
|
||||
// Map by Organization
|
||||
RoleRule {
|
||||
subject: SubjectMatch {
|
||||
cn: None,
|
||||
ou: None,
|
||||
o: Some("External-Partner".to_string()),
|
||||
},
|
||||
}
|
||||
|
||||
// Combined matching
|
||||
RoleRule {
|
||||
subject: SubjectMatch {
|
||||
cn: Some("admin".to_string()),
|
||||
ou: Some("platform-team".to_string()),
|
||||
o: Some("MyCompany".to_string()),
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
## Audit Logging
|
||||
|
||||
All security events are logged for compliance and forensics.
|
||||
|
||||
### Event Types
|
||||
|
||||
| Event | Logged Information |
|
||||
|-------|-------------------|
|
||||
| Authentication Success | Identity (CN, OU, O), timestamp |
|
||||
| Authentication Failure | Reason, timestamp |
|
||||
| Authorization Success | Identity, role, method, duration |
|
||||
| Authorization Denial | Identity, role, method, required permission |
|
||||
| Certificate Error | Error details, certificate info |
|
||||
|
||||
### Log Format
|
||||
|
||||
```
|
||||
2025-11-04T10:16:22Z INFO [AUDIT] Authorization Success
|
||||
identity: CN=admin-user, OU=platform-team
|
||||
role: platform
|
||||
method: /charybdis.entities.EntityService/CreateEntity
|
||||
permission: entity:create
|
||||
duration: 0.08ms
|
||||
|
||||
2025-11-04T10:16:25Z WARN [AUDIT] Authorization Denied
|
||||
identity: CN=defectdojo-plugin, OU=plugins
|
||||
role: plugin
|
||||
method: /charybdis.entities.EntityService/CreateEntity
|
||||
required_permission: entity:create
|
||||
reason: Role 'plugin' does not have permission 'entity:create'
|
||||
duration: 0.05ms
|
||||
```
|
||||
|
||||
### Audit Configuration
|
||||
|
||||
```bash
|
||||
# Enable audit logging (default: true)
|
||||
export SECURITY_RBAC_AUDIT_ENABLED=true
|
||||
|
||||
# Log all requests (default: true)
|
||||
export SECURITY_RBAC_AUDIT_LOG_ALL_REQUESTS=true
|
||||
|
||||
# Log denied requests (default: true)
|
||||
export SECURITY_RBAC_AUDIT_LOG_DENIED=true
|
||||
```
|
||||
|
||||
## Reverse Proxy Deployment
|
||||
|
||||
For environments where mTLS termination happens at a reverse proxy:
|
||||
|
||||
### Architecture
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
A[Client] -->|mTLS| B[Reverse Proxy]
|
||||
B -->|HTTP + Cert Header| C[Charybdis]
|
||||
|
||||
style B fill:#4A90E2,stroke:#2E5C8A
|
||||
```
|
||||
|
||||
### Proxy Configuration
|
||||
|
||||
#### Envoy
|
||||
|
||||
```yaml
|
||||
- name: envoy.filters.http.lua
|
||||
typed_config:
|
||||
inline_code: |
|
||||
function envoy_on_request(request_handle)
|
||||
local cert = request_handle:connection():ssl():peerCertificatePresented()
|
||||
if cert then
|
||||
request_handle:headers():add("x-client-cert", cert)
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
#### nginx
|
||||
|
||||
```nginx
|
||||
location / {
|
||||
proxy_set_header X-Client-Cert $ssl_client_cert;
|
||||
proxy_pass http://charybdis:50051;
|
||||
}
|
||||
```
|
||||
|
||||
### Header Format
|
||||
|
||||
Charybdis accepts certificates in these headers:
|
||||
- `x-forwarded-client-cert` (Envoy/Istio standard)
|
||||
- `x-client-cert` (nginx)
|
||||
|
||||
Format: Base64-encoded DER certificate
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
#### 1. Certificate Not Found
|
||||
|
||||
```
|
||||
ERROR: Client certificate required but not provided
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
- Certificate not sent by client
|
||||
- Wrong certificate path
|
||||
- Certificate expired
|
||||
|
||||
**Solutions**:
|
||||
```bash
|
||||
# Verify certificate is valid
|
||||
openssl x509 -in cert.pem -noout -text
|
||||
|
||||
# Check expiration
|
||||
openssl x509 -in cert.pem -noout -dates
|
||||
|
||||
# Test TLS handshake
|
||||
openssl s_client -connect localhost:50051 \
|
||||
-CAfile ca.pem -cert cert.pem -key key.pem
|
||||
```
|
||||
|
||||
#### 2. Permission Denied
|
||||
|
||||
```
|
||||
Code: PermissionDenied
|
||||
Message: Role 'X' does not have permission 'Y'
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
- Certificate OU doesn't match any role
|
||||
- Role lacks required permission
|
||||
|
||||
**Solutions**:
|
||||
```bash
|
||||
# Check certificate attributes
|
||||
openssl x509 -in cert.pem -noout -subject
|
||||
|
||||
# Review role mappings in src/main.rs
|
||||
# Verify permission requirements in docs
|
||||
```
|
||||
|
||||
#### 3. No Role Assigned
|
||||
|
||||
```
|
||||
ERROR: No role assigned to identity: CN=..., OU=...
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
- Certificate OU not configured in role mappings
|
||||
- Typo in OU value
|
||||
|
||||
**Solutions**:
|
||||
- Add role mapping for the OU
|
||||
- Generate new certificate with correct OU
|
||||
- Check role mapping configuration
|
||||
|
||||
## Security Hardening
|
||||
|
||||
### Production Checklist
|
||||
|
||||
- [ ] Use certificates from trusted CA
|
||||
- [ ] Enable mTLS (`SECURITY_MTLS_ENABLED=true`)
|
||||
- [ ] Enable RBAC (`SECURITY_RBAC_ENABLED=true`)
|
||||
- [ ] Implement certificate rotation (90 days max)
|
||||
- [ ] Monitor certificate expiration
|
||||
- [ ] Enable audit logging
|
||||
- [ ] Use TLS 1.3 only
|
||||
- [ ] Implement rate limiting
|
||||
- [ ] Set up intrusion detection
|
||||
- [ ] Regular security audits
|
||||
|
||||
### Certificate Rotation
|
||||
|
||||
Implement automatic rotation:
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# rotate-certs.sh
|
||||
|
||||
# Generate new certificate
|
||||
./generate-cert.sh
|
||||
|
||||
# Gracefully restart Charybdis
|
||||
kill -HUP $(pidof charybdis)
|
||||
|
||||
# Verify new cert is active
|
||||
sleep 5
|
||||
openssl s_client -connect localhost:50051 < /dev/null | \
|
||||
openssl x509 -noout -dates
|
||||
```
|
||||
|
||||
### Monitoring
|
||||
|
||||
Monitor security metrics:
|
||||
|
||||
- Authentication success/failure rate
|
||||
- Authorization denial rate
|
||||
- Certificate expiration warnings
|
||||
- Audit log anomalies
|
||||
- Failed login attempts
|
||||
|
||||
## Compliance
|
||||
|
||||
Charybdis security features support compliance requirements:
|
||||
|
||||
| Standard | Supported Features |
|
||||
|----------|-------------------|
|
||||
| **SOC 2** | Audit logging, access control, encryption in transit |
|
||||
| **ISO 27001** | Authentication, authorization, audit trails |
|
||||
| **PCI DSS** | Encryption, access control, logging |
|
||||
| **HIPAA** | Access control, audit logging, encryption |
|
||||
|
||||
## Next Steps
|
||||
|
||||
- 🔌 Configure [Plugins](plugins.md) with proper certificates
|
||||
- 🚀 Review [Deployment Guide](deployment.md) for production
|
||||
- 📊 Set up [Monitoring](monitoring.md) for security events
|
||||
|
||||
---
|
||||
|
||||
**Security Questions?** Open a [security issue](../../security) (for vulnerabilities, use private disclosure).
|
||||
Reference in New Issue
Block a user