---
title: "Access Control Policy"
---

# Access Control Policy

## Overview

This document defines the access control mechanisms, policies, and procedures for HeliosDB-Lite, ensuring appropriate protection of data and system resources.

## Authentication Methods

### 1. Password Authentication (SCRAM-SHA-256)

PostgreSQL-compatible password authentication with salted challenge-response.

```sql
-- Create user with password
CREATE USER analyst WITH PASSWORD 'secure_password_123';

-- Authentication happens automatically via PostgreSQL protocol
```

**Security Features**:
- Password hashed with Argon2id (standard) or PBKDF2 (FIPS)
- SCRAM-SHA-256 challenge-response over wire
- Protection against replay attacks
- Automatic account lockout after failed attempts

### 2. JWT Authentication

Token-based authentication for API and service access.

```sql
-- Enable JWT authentication
SET heliosdb.jwt_secret = 'your-secret-key';

-- Or use asymmetric keys
SET heliosdb.jwt_public_key = '/path/to/public.pem';
```

**Configuration**:
```toml
[auth.jwt]
enabled = true
algorithm = "RS256"  # or ES256, HS256
public_key = "/etc/heliosdb/jwt-public.pem"
issuer = "https://auth.example.com"
audience = "heliosdb-lite"
expiration_tolerance = 60  # seconds
```

### 3. Mutual TLS (mTLS) (planned)

Certificate-based authentication for server-to-server communication is planned. The
configuration below describes the planned interface; today the server presents a
certificate with `--tls-cert` / `--tls-key` and clients authenticate with a password,
SCRAM-SHA-256 or (REST) a JWT.

```toml
[tls]
enabled = true
cert = "/etc/heliosdb/server.crt"
key = "/etc/heliosdb/server.key"

[tls.client_auth]
enabled = true
ca_cert = "/etc/heliosdb/client-ca.crt"
required = true
```

**Certificate Requirements**:
- RSA 2048-bit or ECDSA P-256 minimum
- Valid certificate chain
- Subject Alternative Names for hostname verification

## Authorization Framework

### Role-Based Access Control (RBAC)

```sql
-- Create roles
CREATE ROLE read_only;
CREATE ROLE data_analyst;
CREATE ROLE admin;

-- Grant privileges
GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only;
GRANT SELECT, INSERT, UPDATE ON sales TO data_analyst;
GRANT ALL PRIVILEGES ON DATABASE mydb TO admin;

-- Assign roles to users
GRANT read_only TO analyst_user;
GRANT data_analyst TO senior_analyst;
```

### Built-in Roles

| Role | Description | Permissions |
|------|-------------|-------------|
| `pg_read_all_data` | Read access to all data | SELECT on all tables |
| `pg_write_all_data` | Write access to all data | INSERT, UPDATE, DELETE on all tables |
| `pg_database_owner` | Database administration | CREATE, DROP, ALTER objects |
| `pg_execute_server_program` | Execute server programs | EXECUTE functions |

### Row-Level Security (RLS)

Fine-grained data access control at the row level.

```sql
-- Enable RLS on table
ALTER TABLE orders ENABLE ROW LEVEL SECURITY;

-- Policy: Users see only their own orders
CREATE POLICY user_orders ON orders
    FOR ALL
    USING (user_id = current_user_id());

-- Policy: Managers see all orders in their region
CREATE POLICY manager_orders ON orders
    FOR SELECT
    USING (
        region IN (
            SELECT managed_region
            FROM managers
            WHERE manager_id = current_user_id()
        )
    );

-- Policy: Admins see everything
CREATE POLICY admin_orders ON orders
    FOR ALL
    USING (current_user_has_role('admin'));
```

### Column-Level Permissions

```sql
-- Grant specific column access
GRANT SELECT (name, email) ON customers TO support_team;
GRANT SELECT (name, email, credit_limit) ON customers TO sales_team;

-- Revoke sensitive column access
REVOKE SELECT (ssn, credit_card) ON customers FROM ALL;
GRANT SELECT (ssn, credit_card) ON customers TO compliance_team;
```

## Multi-Tenancy Access Control

### Tenant Isolation

```sql
-- Create tenant schema
CREATE SCHEMA tenant_acme;

-- Set default tenant for session
SET heliosdb.tenant_id = 'acme';

-- Automatic RLS for tenant isolation
CREATE POLICY tenant_isolation ON orders
    FOR ALL
    USING (tenant_id = current_setting('heliosdb.tenant_id'));
```

### Cross-Tenant Access (Superuser Only)

```sql
-- Superuser can bypass tenant isolation
SET ROLE superuser;
SET heliosdb.bypass_rls = true;
SELECT * FROM orders;  -- All tenants visible
```

## Access Control Lists (ACLs)

### Object-Level Permissions

```sql
-- View current permissions
SELECT * FROM pg_class WHERE relname = 'orders';
SELECT * FROM information_schema.table_privileges WHERE table_name = 'orders';

-- Grant with grant option
GRANT SELECT ON orders TO analyst WITH GRANT OPTION;

-- Revoke cascade
REVOKE ALL PRIVILEGES ON orders FROM analyst CASCADE;
```

### Schema-Level Permissions

```sql
-- Grant schema usage
GRANT USAGE ON SCHEMA analytics TO analysts;
GRANT CREATE ON SCHEMA analytics TO senior_analysts;

-- Default privileges for new objects
ALTER DEFAULT PRIVILEGES IN SCHEMA analytics
    GRANT SELECT ON TABLES TO analysts;
```

## Session Management

### Session Security

```toml
[session]
# Maximum session duration
max_age = "24h"

# Idle timeout
idle_timeout = "30m"

# Maximum concurrent sessions per user
max_concurrent = 5

# Force re-authentication for sensitive operations
require_reauth_for = ["DROP", "TRUNCATE", "ALTER SYSTEM"]
```

### Session Monitoring

```sql
-- View active sessions
SELECT * FROM pg_stat_activity;

-- Terminate specific session
SELECT pg_terminate_backend(pid);

-- Terminate all sessions for user
SELECT pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE usename = 'suspect_user';
```

## Audit Trail

Built-in audit logging, including access-control decisions, is planned. The record below
shows the planned format. Until it is available, record changes to sensitive tables with
triggers (see [Audit Logging](/docs/lite/features/audit_logging/)).

### Planned Access Log Record

```json
{
  "timestamp": "2026-01-24T12:00:00Z",
  "event": "authorization",
  "user": "analyst",
  "action": "SELECT",
  "object": "public.orders",
  "result": "allowed",
  "rls_policies": ["user_orders"],
  "rows_affected": 150,
  "client_ip": "192.168.1.100"
}
```

### Compliance Reports

```sql
-- Generate access report
SELECT
    user_name,
    object_name,
    privilege_type,
    granted_at
FROM heliosdb_access_log
WHERE granted_at > NOW() - INTERVAL '90 days'
ORDER BY granted_at DESC;
```

## Service Accounts

### Creating Service Accounts

```sql
-- Create service account with limited lifetime
CREATE USER svc_etl_pipeline WITH PASSWORD 'generated_password'
    VALID UNTIL '2026-12-31';

-- Grant minimum required permissions
GRANT INSERT ON staging.raw_data TO svc_etl_pipeline;
GRANT SELECT ON staging.config TO svc_etl_pipeline;

-- Restrict connection source
ALTER USER svc_etl_pipeline SET heliosdb.allowed_ips = '10.0.0.0/8';
```

### Service Account Rotation

```bash
# Rotate service account credentials
heliosdb-cli rotate-credentials --user svc_etl_pipeline --notify etl-team@example.com
```

## Emergency Access

### Break-Glass Procedure

For emergency access bypassing normal controls:

1. **Request**: Submit emergency access request with justification
3. **Grant**: Temporary elevated access (max 4 hours)
4. **Audit**: All actions logged with break-glass flag
5. **Revoke**: Automatic access revocation after time limit
6. **Review**: Post-incident review required

```sql
-- Emergency access grant (security team only)
SELECT heliosdb_emergency_access(
    user_name := 'oncall_engineer',
    reason := 'Production incident #12345',
    duration := INTERVAL '2 hours',
    approver := 'security_lead'
);
```

## Best Practices

### Principle of Least Privilege

1. Start with no permissions
2. Grant only what is needed
3. Use roles, not direct user grants
4. Review permissions regularly
5. Revoke unused permissions

### Access Review Checklist

- [ ] All users have appropriate role assignments
- [ ] No users have unnecessary admin privileges
- [ ] Service accounts have minimum required access
- [ ] RLS policies correctly isolate data
- [ ] Audit logs show no unauthorized access attempts
- [ ] Emergency access procedures are documented and tested
