WASM Procedures: Security Model (Planned Design)
Part of: WASM Procedures User Guide
WASM procedures are designed around a capability-based security model with fine-grained access control.
Capability-Based Security
In this design, every procedure explicitly requests capabilities. By default, procedures have zero permissions.
13 Capability Types
| Capability | Description | Risk Level |
|---|---|---|
DatabaseRead | Read from database tables | Low |
DatabaseWrite | Write to database tables | Medium |
DatabaseQuery | Execute arbitrary SQL queries | Medium |
DatabaseTransaction | Begin/commit/rollback transactions | Medium |
FilesystemRead | Read files from allowed paths | Medium |
FilesystemWrite | Write files to allowed paths | High |
NetworkClient | Make outbound network connections | High |
NetworkServer | Listen for network connections | Critical |
RandomAccess | Access random number generation | Low |
ClockAccess | Access system clock/time | Low |
EnvironmentRead | Read environment variables | Medium |
LogAccess | Write to procedure logs | Low |
CryptoAccess | Cryptographic operations | Low |
Security Profiles
The design defines these predefined security profiles:
Minimal Profile
Most restrictive, zero capabilities.
-- Planned syntax for the upcoming WASM procedures feature; the current server does not accept it.CREATE PROCEDURE safe_calculation(x INT, y INT)RETURNS INTLANGUAGE wasmSECURITY PROFILE 'minimal'AS '/path/to/procedure.wasm';Capabilities: None Max Memory: 1 MB Max CPU Time: 100 ms Use Case: Pure computational procedures
Database-Only Profile
Read-only database access.
-- Planned syntax for the upcoming WASM procedures feature; the current server does not accept it.SECURITY PROFILE 'database_only'Capabilities:
DatabaseReadDatabaseQueryLogAccess
Max Memory: 16 MB Max CPU Time: 1 second Use Case: Reporting, analytics
Standard Profile
Typical database operations.
-- Planned syntax for the upcoming WASM procedures feature; the current server does not accept it.SECURITY PROFILE 'standard' -- DefaultCapabilities:
DatabaseReadDatabaseWriteDatabaseQueryDatabaseTransactionRandomAccessClockAccessLogAccessCryptoAccess
Max Memory: 64 MB Max CPU Time: 10 seconds Use Case: Business logic, data processing
Elevated Profile
Includes filesystem and network access.
-- Planned syntax for the upcoming WASM procedures feature; the current server does not accept it.SECURITY PROFILE 'elevated'Capabilities:
- All Standard capabilities
FilesystemReadNetworkClientEnvironmentRead
Max Memory: 256 MB Max CPU Time: 60 seconds Use Case: ETL, API integrations
Custom Security Profiles
Create custom profiles for specific needs:
-- Planned syntax for the upcoming WASM procedures feature; the current server does not accept it.CREATE SECURITY PROFILE 'api_integration' AS ( capabilities: ['DatabaseRead', 'NetworkClient', 'LogAccess', 'CryptoAccess'], max_memory_bytes: 32000000, -- 32 MB max_cpu_time_ms: 5000, -- 5 seconds max_network_connections: 5, allowed_paths: [], denied_paths: [], allow_nondeterministic: true);
-- Use custom profileCREATE PROCEDURE fetch_external_data()LANGUAGE wasmSECURITY PROFILE 'api_integration'AS '/path/to/procedure.wasm';Capabilities Are Fixed per Procedure
A procedure gets its capabilities from the security profile named in
CREATE PROCEDURE. It cannot request more while it runs: the WASM host has no
function for requesting a capability, and no HTTP or socket functions. The
host functions a module can import are listed in
Host Functions; the published
Go SDK wraps them.
To let a procedure use data from an external service, load that data into a table outside the procedure and have the procedure read the table.
System Call Filtering
HeliosDB automatically filters dangerous system calls:
Blocked by default:
proc_exit(process termination)proc_raise(signal raising)- Socket operations (unless
NetworkClientcapability granted) - File operations (unless
FilesystemRead/FilesystemWritegranted)
Custom filters:
-- Planned syntax for the upcoming WASM procedures feature; the current server does not accept it.CREATE SECURITY PROFILE 'restricted' AS ( capabilities: ['DatabaseRead'], syscall_filter: 'deny_list', allowed_syscalls: ['fd_read', 'fd_write', 'clock_time_get'], denied_syscalls: ['sock_connect', 'sock_bind']);Resource Limits
Every procedure execution is subject to resource limits:
Memory Limits
// Procedure can allocate up to profile.max_memory_byteslet large_vec = vec![0u8; 10_000_000]; // 10 MB
// Exceeding limit causes:// Error: Resource limit exceeded: Memory quota exceeded: 67108864 bytesCPU Time Limits
// Long-running operationfor i in 0..1_000_000_000 { // Heavy computation}
// After max_cpu_time_ms:// Error: Timeout: execution exceeded 10000msFuel Metering
WASM fuel tracks instruction count:
// Each WASM instruction consumes fuellet mut sum = 0;for i in 0..100_000 { sum += i; // Consumes ~3 fuel units}
// When fuel exhausted:// Error: Resource limit exceeded: Fuel exhaustedDeterministic Execution
For reproducible results, enable determinism checking:
-- Planned syntax for the upcoming WASM procedures feature; the current server does not accept it.CREATE SECURITY PROFILE 'deterministic' AS ( capabilities: ['DatabaseRead'], allow_nondeterministic: false -- Blocks random, time, network);Blocked operations in deterministic mode:
- Random number generation - Non-deterministic
- Wall-clock time - Non-deterministic
- Floating-point NaN comparisons
Security Best Practices
1. Principle of Least Privilege
Request only needed capabilities.
-- Planned syntax for the upcoming WASM procedures feature; the current server does not accept it.-- Good: Minimal capabilitiesCREATE PROCEDURE calculate_tax(amount DECIMAL)SECURITY PROFILE 'minimal';
-- Bad: Excessive capabilitiesCREATE PROCEDURE calculate_tax(amount DECIMAL)SECURITY PROFILE 'elevated';2. Input Validation
Always validate inputs.
#[procedure]fn process_order(order_id: i64) -> Result<(), String> { if order_id <= 0 { return Err("Invalid order ID".into()); } // ...}3. SQL Injection Prevention
Use parameterized queries.
// Bad: SQL injection vulnerablelet sql = format!("SELECT * FROM users WHERE id = {}", user_id);exec_sql(&sql)?;
// Good: Use parameterized queries (when available in SDK)let stmt = prepare_statement("SELECT * FROM users WHERE id = ?")?;let result = exec_prepared_with_params(stmt, &[user_id])?;4. Error Handling
Never expose sensitive information.
// Bad: Leaks internal detailsErr(format!("Database error: {}", internal_error))
// Good: Generic error messageErr("Operation failed".into())5. Audit Logging
Log security-relevant operations.
log_info(&format!("User {} accessed resource {}", user_id, resource_id));Navigation:
- Previous: Host Functions
- Next: Use Cases
- Index: WASM Procedures User Guide