Skip to content

WASM Procedures: Security Model

WASM Procedures: Security Model

Part of: WASM Procedures User Guide


HeliosDB WASM procedures implement a capability-based security model with fine-grained access control.

Capability-Based Security

Every procedure must explicitly request capabilities. By default, procedures have zero permissions.

13 Capability Types

CapabilityDescriptionRisk Level
DatabaseReadRead from database tablesLow
DatabaseWriteWrite to database tablesMedium
DatabaseQueryExecute arbitrary SQL queriesMedium
DatabaseTransactionBegin/commit/rollback transactionsMedium
FilesystemReadRead files from allowed pathsMedium
FilesystemWriteWrite files to allowed pathsHigh
NetworkClientMake outbound network connectionsHigh
NetworkServerListen for network connectionsCritical
RandomAccessAccess random number generationLow
ClockAccessAccess system clock/timeLow
EnvironmentReadRead environment variablesMedium
LogAccessWrite to procedure logsLow
CryptoAccessCryptographic operationsLow

Security Profiles

HeliosDB provides predefined security profiles:

Minimal Profile

Most restrictive, zero capabilities.

CREATE PROCEDURE safe_calculation(x INT, y INT)
RETURNS INT
LANGUAGE wasm
SECURITY 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.

SECURITY PROFILE 'database_only'

Capabilities:

  • DatabaseRead
  • DatabaseQuery
  • LogAccess

Max Memory: 16 MB Max CPU Time: 1 second Use Case: Reporting, analytics

Standard Profile

Typical database operations.

SECURITY PROFILE 'standard' -- Default

Capabilities:

  • DatabaseRead
  • DatabaseWrite
  • DatabaseQuery
  • DatabaseTransaction
  • RandomAccess
  • ClockAccess
  • LogAccess
  • CryptoAccess

Max Memory: 64 MB Max CPU Time: 10 seconds Use Case: Business logic, data processing

Elevated Profile

Includes filesystem and network access.

SECURITY PROFILE 'elevated'

Capabilities:

  • All Standard capabilities
  • FilesystemRead
  • NetworkClient
  • EnvironmentRead

Max Memory: 256 MB Max CPU Time: 60 seconds Use Case: ETL, API integrations

Custom Security Profiles

Create custom profiles for specific needs:

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 profile
CREATE PROCEDURE fetch_external_data()
LANGUAGE wasm
SECURITY PROFILE 'api_integration'
AS '/path/to/procedure.wasm';

Request Capabilities at Runtime

Procedures can request additional capabilities dynamically:

use heliosdb_sdk::*;
#[procedure]
fn conditional_operation(use_network: bool) -> Result<String, String> {
if use_network {
// Request network capability
request_capability(Capability::NetworkClient)?;
let response = http_get("https://api.example.com/data")?;
Ok(String::from_utf8(response.body)?)
} else {
// Use local data
let result = exec_sql("SELECT data FROM cache")?;
Ok(result.get_string(0, 0)?)
}
}

System Call Filtering

HeliosDB automatically filters dangerous system calls:

Blocked by default:

  • proc_exit (process termination)
  • proc_raise (signal raising)
  • Socket operations (unless NetworkClient capability granted)
  • File operations (unless FilesystemRead/FilesystemWrite granted)

Custom filters:

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_bytes
let large_vec = vec![0u8; 10_000_000]; // 10 MB
// Exceeding limit causes:
// Error: Resource limit exceeded: Memory quota exceeded: 67108864 bytes

CPU Time Limits

// Long-running operation
for i in 0..1_000_000_000 {
// Heavy computation
}
// After max_cpu_time_ms:
// Error: Timeout: execution exceeded 10000ms

Fuel Metering

WASM fuel tracks instruction count:

// Each WASM instruction consumes fuel
let mut sum = 0;
for i in 0..100_000 {
sum += i; // Consumes ~3 fuel units
}
// When fuel exhausted:
// Error: Resource limit exceeded: Fuel exhausted

Deterministic Execution

For reproducible results, enable determinism checking:

CREATE SECURITY PROFILE 'deterministic' AS (
capabilities: ['DatabaseRead'],
allow_nondeterministic: false -- Blocks random, time, network
);

Blocked operations in deterministic mode:

  • random_bytes() - Non-deterministic
  • current_timestamp() - Non-deterministic
  • http_get() - Non-deterministic
  • Floating-point NaN comparisons

Security Best Practices

1. Principle of Least Privilege

Request only needed capabilities.

-- Good: Minimal capabilities
CREATE PROCEDURE calculate_tax(amount DECIMAL)
SECURITY PROFILE 'minimal';
-- Bad: Excessive capabilities
CREATE 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 vulnerable
let 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 details
Err(format!("Database error: {}", internal_error))
// Good: Generic error message
Err("Operation failed".into())

5. Audit Logging

Log security-relevant operations.

log_info(&format!("User {} accessed resource {}", user_id, resource_id));

Navigation: