Skip to Content

Security

TL;DR

CMDOP uses a five-layer security model: TLS 1.3 encryption on all connections, OAuth 2.0 authentication with device code flow, workspace-based tenant isolation, session-level authorization with operator/observer roles, and process-level agent isolation with no privilege escalation. Agents connect outbound only, eliminating open ports as an attack surface.

CMDOP implements multiple layers of security to protect your machines and data.

What is the security architecture?

How does transport security work?

What TLS encryption is used?

All communication uses TLS 1.3:

ConnectionEncryptionCertificate
Agent β†’ Control PlaneTLS 1.3Server cert validation
Client β†’ Control PlaneTLS 1.3Server cert validation
Control Plane β†’ CentrifugoTLS 1.3Internal PKI

Can TLS be disabled?

There is no option to disable TLS in production. Development mode (--dev) uses a separate endpoint with self-signed certificates.

How does authentication work?

How does the OAuth 2.0 device flow work?

For CLI and agents, CMDOP uses OAuth Device Code flow:

How are tokens managed?

Token TypeLifetimeStorage
Access Token1 hourMemory / secure file
Refresh Token30 daysEncrypted file
API KeyUntil revokedUser manages

How is token security enforced?

  • Tokens hashed (SHA-256) before storage in database
  • Automatic refresh 5 minutes before expiration
  • Revocation via API or dashboard
  • Last-used timestamp tracking

How does workspace isolation work?

How is multi-tenancy implemented?

What isolation guarantees are provided?

ResourceIsolation
SessionsWorkspace-scoped
MachinesUnique hostname per workspace
API KeysWorkspace-scoped
Audit LogsWorkspace-scoped

What workspace membership roles exist?

  • Owner: Full control, billing, member management
  • Admin: Machine management, user invites
  • Member: Access to sessions
  • Guest: Read-only access (optional)

How does session authorization work?

How is access control enforced?

Sessions enforce authorization at multiple levels:

# Three-level authorization check performed for every session access request # Check 1: Verify user belongs to the workspace that owns this session user.workspaces.contains(session.workspace) # Check 2: Ensure session is active (not disconnected or pending) session.status in [CONNECTED, BACKGROUND] # Check 3: Verify user has an assigned role β€” OPERATOR can send input, OBSERVER is read-only session.get_role(user) in [OPERATOR, OBSERVER]

What is the difference between Operator and Observer?

PermissionOperatorObserver
View outputβœ…βœ…
Send inputβœ…βŒ
Execute commandsβœ…βŒ
File readβœ…βœ…
File writeβœ…βŒ
Resize terminalβœ…βŒ

How is the agent secured?

Why is the agent outbound-only?

Agents never accept incoming connections:

# Traditional SSH: server listens on port 22, requiring inbound firewall rules Traditional: Internet ──▢ [Firewall] ──▢ Server:22 ❌ Attack surface: open port ❌ Requires firewall rules # CMDOP: agent initiates outbound HTTPS β€” no listening ports, no firewall changes CMDOP: Agent ──▢ [Outbound HTTPS] ──▢ Control Plane βœ… No open ports βœ… No firewall changes βœ… Works through corporate proxies

How does process isolation work?

  • Agent runs as the user who installed it
  • No root/admin privileges required
  • Commands execute with user’s permissions
  • No privilege escalation mechanism

What PTY security measures are in place?

Terminal emulation includes security measures:

ProtectionDescription
ANSI filteringBlocks dangerous escape sequences
Input validationSanitizes control characters
Output limitsPrevents memory exhaustion

How does audit logging work?

What events are logged?

EventData Captured
Session createdUser, machine, timestamp
Command executedCommand, exit code, duration
File accessedPath, operation, timestamp
AuthenticationUser, method, IP, success/failure

How long are logs retained?

  • Audit logs retained for 90 days (configurable)
  • Logs stored separately from session data
  • Export available via API

What compliance standards are supported?

Audit logs support:

  • SOC 2 compliance
  • GDPR data access tracking
  • Internal security reviews

How should the API be secured?

What are the API key best practices?

# Recommended: set API key as an environment variable (not visible in source code) export CMDOP_API_KEY="cmd_live_xxx" cmdop connect # Recommended: restrict config file permissions to owner-only read/write chmod 600 ~/.cmdop/config.yaml # Avoid: hardcoding keys in scripts exposes them in version control # api_key = "cmd_live_xxx" # Don't do this!

What rate limits are applied?

EndpointLimit
Authentication10 req/min
Session operations100 req/min
File operations50 req/min

How should self-hosted deployments be secured?

For self-hosted deployments:

ComponentSecurity Setting
PostgreSQLTLS required, strong passwords
RedisTLS, AUTH, no public exposure
DjangoSECRET_KEY rotation, CSRF protection
CentrifugoToken auth, channel permissions

What is the security checklist?

What should users do?

  • Use strong password for account
  • Enable 2FA when available
  • Don’t share API keys
  • Revoke unused API keys
  • Review audit logs periodically

What should administrators do?

  • Keep agents updated
  • Rotate secrets regularly
  • Monitor authentication failures
  • Set up alerting for suspicious activity
  • Regular security reviews

How do I report security issues?

Found a security vulnerability? Please report to: [email protected]

We follow responsible disclosure practices and appreciate your help keeping CMDOP secure.

Next

Last updated on