Packages

Multi-surface application runtime for Elixir. One TEA module renders to terminal, browser (LiveView), SSH, and MCP (agents). 30+ widgets, flexbox + CSS grid, AI agent runtime, distributed swarm with CRDTs, time-travel debugging, session recording, sandboxed REPL, and agentic commerce.

Current section

Files

Jump to
raxol docs examples guides 06_enterprise security.md
Raw

docs/examples/guides/06_enterprise/security.md

# Security & Compliance
Comprehensive security practices and compliance guidelines for Raxol applications in enterprise environments.
## Overview
Security is paramount in enterprise terminal applications. This guide covers security best practices, vulnerability management, compliance frameworks, and security monitoring for Raxol applications.
> **📚 Architecture Context**: See [ADR-0006: Enterprise Security and Compliance Model](../../../adr/0006-enterprise-security-and-compliance-model.md) for the complete security architecture decisions and compliance framework details.
## Security Architecture
### Defense in Depth
```elixir
defmodule MyApp.Security do
use Raxol.Enterprise.Security
# Layer 1: Network Security
network_security do
firewall_rules [
allow: [{:tcp, 443}, {:tcp, 4000}],
deny: :all
]
tls_config [
versions: [:tlsv1_2, :tlsv1_3],
ciphers: :strong,
verify: :verify_peer
]
end
# Layer 2: Application Security
application_security do
enable :csrf_protection
enable :xss_protection
enable :sql_injection_prevention
enable :command_injection_prevention
end
# Layer 3: Data Security
data_security do
encryption :at_rest, algorithm: :aes_256_gcm
encryption :in_transit, protocol: :tls_1_3
enable :data_masking
end
end
```
## Input Validation & Sanitization
### Command Input Validation
```elixir
defmodule MyApp.CommandValidator do
use Raxol.Enterprise.Security.Validation
# Define allowed commands
@allowed_commands ~w(ls pwd cd cat echo)
@dangerous_patterns ~r/(rm|sudo|chmod|chown|dd|mkfs)/
def validate_command(input) do
with :ok <- check_length(input),
:ok <- check_allowed_commands(input),
:ok <- check_dangerous_patterns(input),
:ok <- check_injection_attempts(input) do
{:ok, sanitize(input)}
else
{:error, reason} -> {:error, reason}
end
end
defp check_length(input) do
if String.length(input) <= 1000 do
:ok
else
{:error, :command_too_long}
end
end
defp check_allowed_commands(input) do
command = input |> String.split() |> List.first()
if command in @allowed_commands do
:ok
else
{:error, :command_not_allowed}
end
end
defp check_dangerous_patterns(input) do
if Regex.match?(@dangerous_patterns, input) do
{:error, :dangerous_command}
else
:ok
end
end
defp check_injection_attempts(input) do
patterns = [
~r/[;&|`$]/, # Command chaining
~r/\.\./, # Directory traversal
~r/[\x00-\x1F\x7F]/ # Control characters
]
if Enum.any?(patterns, &Regex.match?(&1, input)) do
{:error, :potential_injection}
else
:ok
end
end
defp sanitize(input) do
input
|> String.replace(~r/[^\w\s\-\.\/]/, "")
|> String.trim()
end
end
```
### Data Validation
```elixir
defmodule MyApp.DataValidator do
use Raxol.Enterprise.Security.DataValidation
schema :user_input do
field :username, :string,
required: true,
format: ~r/^[a-zA-Z0-9_]+$/,
length: [min: 3, max: 32]
field :email, :string,
required: true,
format: ~r/^[\w._%+-]+@[\w.-]+\.[A-Za-z]{2,}$/
field :age, :integer,
required: false,
range: [min: 0, max: 150]
field :role, :string,
required: true,
enum: ["admin", "user", "guest"]
end
def validate_user_input(params) do
case validate(params, :user_input) do
{:ok, clean_data} ->
{:ok, clean_data}
{:error, errors} ->
log_validation_failure(params, errors)
{:error, errors}
end
end
end
```
## Encryption
### Data at Rest
```elixir
defmodule MyApp.Encryption do
use Raxol.Enterprise.Crypto
@key_rotation_days 90
def encrypt_sensitive_data(data) do
# Get current encryption key
key = get_current_key()
# Encrypt with AES-256-GCM
case encrypt_aes_gcm(data, key) do
{:ok, encrypted} ->
# Store with key version for rotation
{:ok, %{
ciphertext: encrypted.ciphertext,
nonce: encrypted.nonce,
tag: encrypted.tag,
key_version: key.version
}}
error -> error
end
end
def decrypt_sensitive_data(encrypted_data) do
# Get key by version
key = get_key_version(encrypted_data.key_version)
decrypt_aes_gcm(
encrypted_data.ciphertext,
key,
encrypted_data.nonce,
encrypted_data.tag
)
end
# Key rotation
def rotate_keys do
with {:ok, new_key} <- generate_new_key(),
:ok <- reencrypt_all_data(new_key),
:ok <- mark_old_keys_retired() do
{:ok, new_key}
end
end
end
```
### Data in Transit
```elixir
defmodule MyApp.TLS do
use Raxol.Enterprise.Security.TLS
def tls_options do
[
versions: [:"tlsv1.3", :"tlsv1.2"],
ciphers: [
"TLS_AES_256_GCM_SHA384",
"TLS_AES_128_GCM_SHA256",
"TLS_CHACHA20_POLY1305_SHA256"
],
verify: :verify_peer,
cacertfile: ca_bundle_path(),
certfile: cert_path(),
keyfile: key_path(),
secure_renegotiate: true,
reuse_sessions: true,
honor_cipher_order: true
]
end
end
```
## Audit Logging
### Comprehensive Audit Trail
```elixir
defmodule MyApp.AuditLogger do
use Raxol.Enterprise.Audit
# Define what to audit
audit_events [
:authentication,
:authorization,
:data_access,
:data_modification,
:configuration_change,
:privilege_escalation,
:security_event
]
def log_event(event_type, details) do
event = %{
id: UUID.uuid4(),
timestamp: DateTime.utc_now(),
type: event_type,
user: get_current_user(),
session_id: get_session_id(),
ip_address: get_client_ip(),
details: details,
hash: nil
}
# Create tamper-proof hash
event_with_hash = Map.put(event, :hash, hash_event(event))
# Store in multiple locations
store_locally(event_with_hash)
store_remotely(event_with_hash)
# Alert on security events
if event_type in [:privilege_escalation, :security_event] do
send_security_alert(event_with_hash)
end
end
defp hash_event(event) do
event
|> Map.delete(:hash)
|> Jason.encode!()
|> then(&:crypto.hash(:sha256, &1))
|> Base.encode16()
end
end
```
### Audit Log Analysis
```elixir
defmodule MyApp.AuditAnalysis do
use Raxol.Enterprise.Security.Analysis
def detect_anomalies do
patterns = [
multiple_failed_logins(),
unusual_access_patterns(),
privilege_escalation_attempts(),
data_exfiltration_signs()
]
case analyze_patterns(patterns) do
[] -> :ok
anomalies -> handle_anomalies(anomalies)
end
end
defp multiple_failed_logins do
%{
pattern: :failed_login_burst,
query: """
SELECT user_id, COUNT(*) as attempts
FROM audit_logs
WHERE type = 'authentication'
AND success = false
AND timestamp > NOW() - INTERVAL '5 minutes'
GROUP BY user_id
HAVING COUNT(*) > 5
""",
severity: :high
}
end
end
```
## Vulnerability Management
### Security Scanning
```elixir
defmodule MyApp.SecurityScanner do
use Raxol.Enterprise.Security.Scanner
def scan_dependencies do
# Check for known vulnerabilities
case mix_audit() do
{:ok, results} -> handle_audit_results(results)
error -> error
end
end
def scan_code do
# Static analysis
checks = [
check_sql_injection(),
check_command_injection(),
check_xss_vulnerabilities(),
check_sensitive_data_exposure(),
check_insecure_random(),
check_weak_crypto()
]
Enum.map(checks, &run_check/1)
end
defp check_sql_injection do
%{
name: :sql_injection,
pattern: ~r/Repo\.query\([^?]*#\{/,
severity: :critical,
message: "Potential SQL injection vulnerability"
}
end
end
```
### Patch Management
```elixir
defmodule MyApp.PatchManager do
use Raxol.Enterprise.Security.Patches
def check_updates do
with {:ok, current} <- get_current_versions(),
{:ok, available} <- get_available_updates(),
{:ok, security} <- filter_security_updates(available) do
if Enum.any?(security) do
notify_security_updates(security)
schedule_patching(security)
end
{:ok, security}
end
end
def apply_security_patches do
# Automated patching with rollback
with {:ok, patches} <- get_pending_patches(),
:ok <- create_backup(),
:ok <- apply_patches(patches) do
if verify_system_health() do
{:ok, :patches_applied}
else
rollback_patches()
{:error, :patch_failed}
end
end
end
end
```
## Compliance Frameworks
### GDPR Compliance
```elixir
defmodule MyApp.GDPR do
use Raxol.Enterprise.Compliance.GDPR
# Data subject rights
def export_user_data(user_id) do
with {:ok, user} <- authorize_request(user_id),
{:ok, data} <- collect_all_user_data(user_id),
{:ok, formatted} <- format_for_export(data) do
audit_log(:data_export, %{user_id: user_id})
{:ok, formatted}
end
end
def delete_user_data(user_id) do
with {:ok, user} <- authorize_request(user_id),
:ok <- verify_deletion_allowed(user_id),
:ok <- anonymize_required_data(user_id),
:ok <- delete_personal_data(user_id) do
audit_log(:data_deletion, %{user_id: user_id})
{:ok, :deleted}
end
end
# Data protection
def ensure_data_protection do
[
implement_privacy_by_design(),
minimize_data_collection(),
obtain_explicit_consent(),
provide_transparency(),
enable_data_portability()
]
end
end
```
### SOC 2 Compliance
```elixir
defmodule MyApp.SOC2 do
use Raxol.Enterprise.Compliance.SOC2
# Security controls
controls do
# CC6.1 - Logical and Physical Access Controls
control :access_control do
implement :role_based_access
implement :multi_factor_auth
implement :session_management
implement :password_policy
end
# CC6.6 - Encryption
control :encryption do
implement :data_at_rest_encryption
implement :data_in_transit_encryption
implement :key_management
end
# CC7.2 - System Monitoring
control :monitoring do
implement :security_monitoring
implement :anomaly_detection
implement :incident_response
end
end
end
```
## Security Headers
```elixir
defmodule MyAppWeb.SecurityHeaders do
use Raxol.Enterprise.Security.Headers
def call(conn, _opts) do
conn
|> put_security_headers()
|> put_csp_header()
end
defp put_security_headers(conn) do
conn
|> put_resp_header("x-frame-options", "DENY")
|> put_resp_header("x-content-type-options", "nosniff")
|> put_resp_header("x-xss-protection", "1; mode=block")
|> put_resp_header("referrer-policy", "strict-origin-when-cross-origin")
|> put_resp_header("permissions-policy", "geolocation=(), microphone=(), camera=()")
|> put_resp_header("strict-transport-security", "max-age=63072000; includeSubDomains; preload")
end
defp put_csp_header(conn) do
csp = """
default-src 'self';
script-src 'self' 'unsafe-eval';
style-src 'self' 'unsafe-inline';
img-src 'self' data: https:;
font-src 'self';
connect-src 'self' wss://#{conn.host};
frame-ancestors 'none';
base-uri 'self';
form-action 'self'
"""
put_resp_header(conn, "content-security-policy", String.replace(csp, "\n", " "))
end
end
```
## Incident Response
### Automated Response
```elixir
defmodule MyApp.IncidentResponse do
use Raxol.Enterprise.Security.Incident
def handle_security_incident(incident) do
with :ok <- classify_incident(incident),
:ok <- contain_threat(incident),
:ok <- collect_forensics(incident),
:ok <- notify_stakeholders(incident) do
case incident.severity do
:critical -> execute_emergency_response(incident)
:high -> escalate_to_security_team(incident)
:medium -> create_remediation_ticket(incident)
:low -> log_for_analysis(incident)
end
end
end
defp contain_threat(incident) do
case incident.type do
:brute_force ->
block_ip(incident.source_ip)
lock_affected_accounts(incident.targets)
:data_breach ->
isolate_affected_systems()
revoke_compromised_credentials()
:malware ->
quarantine_affected_nodes()
block_malicious_domains()
end
end
end
```
## Best Practices
1. **Principle of Least Privilege**: Grant minimum necessary permissions
2. **Defense in Depth**: Multiple layers of security controls
3. **Zero Trust**: Verify everything, trust nothing
4. **Continuous Monitoring**: Real-time security monitoring
5. **Regular Updates**: Keep dependencies and systems patched
6. **Security Training**: Regular security awareness training
7. **Incident Preparedness**: Practice incident response procedures
## Security Checklist
- [ ] Enable authentication and authorization
- [ ] Implement input validation and sanitization
- [ ] Enable encryption at rest and in transit
- [ ] Configure security headers
- [ ] Set up audit logging
- [ ] Implement rate limiting
- [ ] Enable security monitoring
- [ ] Create incident response plan
- [ ] Conduct security assessments
- [ ] Train development team
## Next Steps
- Implement [Authentication](authentication.md) controls
- Set up [Monitoring](monitoring.md) for security events
- Review [Deployment](deployment.md) security practices
- Plan [Scaling](scaling.md) with security in mind