O2S Security Model
Threat model and security architecture for OpenSelfServe
O2S (OpenSelfServe) Security Model
OpenSelfServe (O2S) is the customer-facing portal for provisioning and managing infrastructure on tasmanian.cloud. As the primary interface between customers and their resources, O2S security is critical to maintaining the confidentiality, integrity, and availability of customer data and infrastructure.
Security Goals
The O2S security model aims to provide:
- Confidentiality — Customer data, credentials, and resource configurations must remain confidential
- Integrity — All provisioning operations and configuration changes must be tamper-evident
- Availability — The portal must remain available for resource management and emergency access
- Authentication — Strong identity verification for all customer and administrative actions
- Authorization — Strict access controls ensuring customers can only access their own resources
- Accountability — Comprehensive audit logging of all actions for forensic analysis
- Non-repudiation — Cryptographic proof of actions taken by authenticated users
Threat Model
In Scope (Threats We Protect Against)
The following threats are within the O2S threat model:
- Eavesdropping on customer communications — All traffic between customers and O2S must be protected from interception
- Session hijacking and fixation — Attacker attempts to steal or predict session tokens
- Credential stuffing and brute force attacks — Automated attempts to guess passwords
- Cross-site scripting (XSS) — Injection of malicious scripts into the web interface
- Cross-site request forgery (CSRF) — Unauthorized actions performed via forged requests
- SQL injection and NoSQL injection — Database query manipulation attempts
- Privilege escalation — Customers attempting to access other customers' resources
- API abuse and rate limit evasion — Attempts to bypass usage restrictions
- Configuration tampering — Unauthorized changes to resource configurations
- Man-in-the-middle attacks — Interception or modification of API communications
- Replay attacks — Reuse of captured authentication tokens or requests
Out of Scope (Threats We Do Not Protect Against)
The following threats are explicitly NOT part of the O2S threat model:
- Compromise of customer endpoint devices — If a customer's laptop or browser is compromised, O2S cannot prevent misuse of valid credentials
- Social engineering of customers — Phishing attacks targeting customers directly
- Physical access to customer premises — Local network compromise at customer locations
- Compromise of upstream identity providers — If an SSO provider (e.g., Google, GitHub) is breached
- Compromise of the underlying Proxmox/Ceph infrastructure — These are protected by separate threat models
- Denial of service at the network layer — DDoS protection is handled by Cloudflare/WAF
- Malicious insiders with administrative access — Root-level infrastructure access bypasses O2S controls
- Cryptographic breaks — Failure of TLS, AES, or other cryptographic primitives
- Supply chain attacks on dependencies — Compromised npm packages, base images, etc.
- Side-channel attacks — Timing attacks, power analysis, etc.
External Threat Overview
Architecture Components
┌─────────────────────────────────────────────────────────────────┐
│ Customer │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Browser │ │ CLI Tool │ │ API Client │ │
│ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ │
└─────────┼────────────────┼────────────────┼────────────────────┘
│ │ │
└────────────────┴────────────────┘
│
┌──────▼──────┐
│ Cloudflare │
│ (WAF/DDoS) │
└──────┬──────┘
│
┌────────────────┼────────────────┐
│ │ │
┌──────▼──────┐ ┌──────▼──────┐ ┌──────▼──────┐
│ O2S Web │ │ O2S API │ │ O2S Auth │
│ Frontend │ │ Gateway │ │ Service │
└──────┬──────┘ └──────┬──────┘ └──────┬──────┘
│ │ │
└────────────────┴────────────────┘
│
┌──────▼──────┐
│ O2S Core │
│ (Business │
│ Logic) │
└──────┬──────┘
│
┌────────────────┼────────────────┐
│ │ │
┌──────▼──────┐ ┌──────▼──────┐ ┌──────▼──────┐
│ PostgreSQL │ │ Redis │ │ Paymenter │
│ (Primary) │ │ (Cache) │ │ (Billing) │
└─────────────┘ └─────────────┘ └─────────────┘
Trust Boundaries
Untrusted:
- Customer browsers and devices
- Public internet
- Third-party identity providers (Google, GitHub)
Semi-Trusted:
- Cloudflare edge (terminates TLS, inspects traffic)
- O2S web frontend (serves static assets)
Trusted:
- O2S API Gateway (authentication enforcement)
- O2S Auth Service (token issuance and validation)
- O2S Core (business logic, after authentication)
- PostgreSQL (encrypted at rest)
- Redis (session storage, no sensitive data)
Communication Security
| Connection | Protocol | Authentication | Notes |
|---|---|---|---|
| Customer → Cloudflare | HTTPS (TLS 1.3) | Certificate pinning | Cloudflare validates server cert |
| Cloudflare → O2S | HTTPS (TLS 1.3) | mTLS | Mutual TLS for origin authentication |
| O2S → PostgreSQL | TLS 1.3 | Certificate auth | Database connections encrypted |
| O2S → Redis | TLS 1.3 | Password + TLS | Session cache encrypted |
| O2S → Paymenter | HTTPS + API key | Token-based | Billing integration secured |
Internal Threat Overview
Authentication Architecture
O2S implements a multi-layer authentication system:
1. Initial Authentication
Customers authenticate using one of the following methods:
- Email/Password — Passwords hashed with Argon2id
- OAuth 2.0 — Google, GitHub, GitLab (PKCE flow)
- API Keys — For programmatic access, rotated every 90 days
- WebAuthn/FIDO2 — Hardware security keys (optional MFA)
2. Session Management
Upon successful authentication:
- O2S Auth Service generates a JWT access token (15-minute expiry)
- A refresh token is issued (7-day expiry, single-use)
- Session ID stored in Redis with device fingerprinting
- Tokens signed with Ed25519, verified on every request
┌─────────────────────────────────────────────────────────────┐
│ Authentication Flow │
├─────────────────────────────────────────────────────────────┤
│ │
│ Customer O2S Auth Redis Core │
│ │ │ │ │ │
│ │ ──credentials──▶ │ │ │ │
│ │ │ │ │ │
│ │ │ ──validate──▶ │ │ │
│ │ │ ◀──result──── │ │ │
│ │ │ │ │ │
│ │ │ ──store session▶│ │ │
│ │ │ ◀───────────── │ │ │
│ │ │ │ │ │
│ │ ◀──JWT tokens────│ │ │ │
│ │ │ │ │ │
│ │ ──API request with JWT────────────▶│ │ │
│ │ │ │ ──verify──▶│ │
│ │ │ │ ◀──result──│ │
│ │ │ │ │ │
│ │ ◀───────────────response──────────│◀──────────│ │
│ │
└─────────────────────────────────────────────────────────────┘
3. Authorization (RBAC)
O2S implements role-based access control with the following roles:
| Role | Permissions |
|---|---|
owner | Full access to organization resources |
admin | Manage resources and users, no billing changes |
developer | Create/modify resources, read-only on sensitive data |
viewer | Read-only access to resources |
billing | Access to invoices and payment methods only |
Policies are enforced at the API Gateway layer:
# Pseudocode for authorization check
def authorize(request, resource):
token = extract_token(request)
claims = verify_jwt(token)
# Check resource ownership
if resource.org_id != claims.org_id:
raise Forbidden("Resource not in your organization")
# Check role permissions
required_permission = get_required_permission(request)
if required_permission not in claims.permissions:
raise Forbidden("Insufficient permissions")
# Check MFA requirement for sensitive operations
if is_sensitive_operation(request) and not claims.mfa_verified:
raise MFARequired("Multi-factor authentication required")
return True
Resource Isolation
Customer resources are isolated at multiple levels:
Organization Isolation
- Each customer belongs to an Organization (org)
- All resources (VPS, clusters, networks) belong to an org
- API queries automatically filtered by
org_id - Database uses row-level security (RLS) policies
Network Isolation
- Each organization gets dedicated private network segments
- VLANs segregate traffic at layer 2
- No inter-organization communication allowed
- VPN access scoped to organization's resources only
Data Isolation
-- PostgreSQL row-level security example
CREATE POLICY org_isolation ON vms
USING (org_id = current_setting('app.current_org')::UUID);
-- All queries automatically filtered
SELECT * FROM vms; -- Only returns VMs for current org
Audit Logging
All actions are logged with the following attributes:
{
"timestamp": "2024-01-15T10:30:00Z",
"event_type": "vps.create",
"actor": {
"user_id": "usr_abc123",
"org_id": "org_xyz789",
"ip_address": "203.0.113.42",
"user_agent": "Mozilla/5.0...",
"session_id": "sess_def456"
},
"resource": {
"type": "vps",
"id": "vps_ghi789",
"name": "production-web"
},
"action": {
"method": "POST",
"path": "/v1/vps",
"params": {
"size": "standard-4vcpu-8gb",
"image": "ubuntu-24.04"
}
},
"result": "success",
"changes": {
"before": null,
"after": { "status": "provisioning" }
},
"request_id": "req_jkl012",
"correlation_id": "corr_mno345"
}
Logs are:
- Written synchronously before response (for critical operations)
- Sent to Wazuh SIEM in real-time
- Retained for 1 year (hot), 7 years (cold storage)
- Immutable (append-only, signed)
Secrets Management
O2S handles several classes of secrets:
| Secret Type | Storage | Rotation | Access Pattern |
|---|---|---|---|
| Customer passwords | Argon2id hash | On change | Auth-time only |
| API keys | HMAC-SHA256 hash | 90 days | Verified on use |
| Database credentials | Vault (dynamic) | 24 hours | Short-lived leases |
| JWT signing keys | HSM (YubiHSM) | Manual | Signing only |
| Proxmox API tokens | Vault KV | 30 days | Proxied through O2S |
Rate Limiting and Abuse Prevention
| Endpoint Type | Rate Limit | Burst | Action on Exceed |
|---|---|---|---|
| Authentication | 5 req/min | 3 | 15-min lockout |
| API (authenticated) | 300 req/min | 50 | 429 response |
| API (unauthenticated) | 10 req/min | 5 | IP block (1 hour) |
| Resource creation | 10 req/hour | 3 | Queue for review |
| Sensitive operations | 1 req/min | 1 | Require MFA re-auth |
Security Controls Summary
| Control | Implementation | Verification |
|---|---|---|
| Input validation | JSON Schema + strict parsing | Automated tests |
| Output encoding | Context-aware escaping | SAST/DAST |
| CSRF protection | Double-submit cookies + SameSite | Penetration testing |
| XSS prevention | CSP headers + output encoding | Security headers scan |
| SQL injection | Parameterized queries only | Code review |
| Session security | HttpOnly, Secure, SameSite=Strict | Cookie analyzer |
| Secrets management | HashiCorp Vault | Audit logs |
| Encryption at rest | AES-256-GCM (managed keys) | Compliance scan |
| Encryption in transit | TLS 1.3 only | SSL Labs scan |
| Audit logging | Structured, immutable, signed | Log integrity checks |
| Dependency scanning | Snyk + Dependabot | CI/CD pipeline |
| Container security | Distroless images, non-root | Trivy scan |
Incident Response
Detection
- Real-time alerting on suspicious patterns
- Wazuh correlation rules for attack detection
- Anomaly detection on API usage patterns
Response Playbooks
| Scenario | Immediate Action | Investigation | Communication |
|---|---|---|---|
| Account compromise | Disable account, revoke sessions | Audit log review | Customer notification within 1 hour |
| Credential stuffing | Enable CAPTCHA, rate limit | Source IP analysis | No notification (prevented) |
| Privilege escalation | Isolate affected resources | RBAC audit | Customer notification within 4 hours |
| Data exfiltration | Block egress, preserve logs | Forensic analysis | Regulatory notification as required |
| RCE on O2S | Emergency shutdown, failover | Root cause analysis | Status page + direct notification |
Compliance Mapping
| Standard | Relevant Controls | Implementation |
|---|---|---|
| ISO 27001 | A.9 (Access Control), A.12 (Operations) | RBAC, audit logging, encryption |
| Essential 8 | MFA, patching, backups | Enforced for all admin accounts |
| SOC 2 Type II | CC6 (Logical Access), CC7 (Operations) | Annual audit, continuous monitoring |
| Privacy Act | Data minimization, access rights | Customer data export/deletion |