Security & Identity
Licensing, device tracking, hardware fingerprinting, and analytics privacy. Understanding how CtrlOps protects your data and validates licenses.
CtrlOps implements a seat-based licensing model with hardware fingerprinting for license enforcement. This page explains how license validation works, what data is collected, and how your privacy is protected.
License Validation Flow
Hardware Fingerprinting
To enforce seat-based licensing, CtrlOps collects hardware identifiers that uniquely identify your machine.
Collected Information
Prop
Type
Fingerprint Collection (Rust)
// core/src/license/mod.rs
pub async fn get_machine_fingerprint() -> Option<BiosInfo> {
let system = System::new_with_specifics(
RefreshKind::new().with_components(
ComponentsRefreshKind::new()
)
);
Some(BiosInfo {
platform: std::env::consts::OS.to_string(),
distro: System::name()?,
kernel: System::kernel_version()?,
architecture: std::env::consts::ARCH.to_string(),
hostname: System::host_name()?,
serial: get_system_serial().await.ok()?,
})
}API Key Validation Payload
When validating a license, the following data is sent to the auth service:
interface LicenseValidationRequest {
apiKey: string; // The license key (e.g., "CTRL-XXXX-XXXX-XXXX")
prodId: number; // Product ID (2 for CtrlOps)
biosInfo: {
platform: string; // "darwin" | "win32" | "linux"
distro: string; // OS version
kernel: string; // Kernel version
architecture: string; // "arm64" | "x64"
hostname: string; // Machine name
serial: string; // Hardware serial
};
networkData?: {
ip: string; // Public IP
city: string;
region: string;
country: string;
loc: string; // Lat/long
org: string; // ISP
};
}Validation Response
interface LicenseValidationResponse {
success: boolean;
data?: {
userId: number;
email: string;
expiryDate: string; // ISO 8601 date
type: "trial" | "startup" | "enterprise";
features: string[]; // Enabled features
company_id?: string; // For team licenses
};
error?: string;
}Device Tracking
Each validated license is associated with devices to prevent unauthorized sharing.
Device Record
| Field | Purpose | Example |
|---|---|---|
id | Database primary key | 12345 |
userId | Owner reference | 67890 |
apiKeyId | Associated license | 54321 |
platform | OS platform | "darwin" |
serial | Hardware fingerprint | "ABC123..." |
hostname | Machine name | "dev-macbook" |
ip | Last seen IP | "203.0.113.42" |
city | Geolocation | "Mumbai" |
country | Country code | "IN" |
lastSeen | Timestamp | "2024-01-15T10:30:00Z" |
License Enforcement
Seat Limits: Each license is bound to specific hardware. Transferring to a new machine requires deactivating the old device or purchasing additional seats.
Mixpanel Analytics
CtrlOps uses Mixpanel for product analytics while maintaining strict privacy controls.
Event Categories
Privacy Protection
PII Redaction
All events are automatically scrubbed for sensitive data:
// mixpanel.js - sanitizeEvent function
const SENSITIVE_PATTERNS = [
{
regex:
/-----BEGIN (RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----[\s\S]*?-----END.*?-----/gi,
replacement: "[REDACTED_PRIVATE_KEY]",
},
{ regex: /password[=:]\s*\S+/gi, replacement: "password=[REDACTED]" },
{
regex: /token[=:]\s*[a-zA-Z0-9_-]{20,}/gi,
replacement: "token=[REDACTED]",
},
{ regex: /AKIA[0-9A-Z]{16}/g, replacement: "[REDACTED_AWS_KEY]" },
];
function sanitizeEvent(eventName, properties) {
const sanitized = { ...properties };
for (const [key, value] of Object.entries(sanitized)) {
if (typeof value === "string") {
for (const pattern of SENSITIVE_PATTERNS) {
sanitized[key] = sanitized[key].replace(
pattern.regex,
pattern.replacement,
);
}
}
}
return sanitized;
}Data Retention
| Data Type | Retention | Purpose |
|---|---|---|
| Event data | 2 years | Product improvement |
| User profiles | Until account deletion | Analytics segmentation |
| Device fingerprints | Duration of license | License enforcement |
| IP addresses | 30 days | Security analysis |
Super Properties
Every event includes contextual metadata:
{
app: 'ctrlops_desktop',
app_version: '1.0.6',
platform: 'macos', // macos | windows | linux
architecture: 'arm64', // arm64 | x64
runtime: 'tauri',
plan_level: 'startup', // trial | startup | enterprise
distinct_id: 'license_key_hash'
}Group Analytics
For team/enterprise customers:
// Identify user belongs to company
mixpanel.setGroup("Company", "company_123");
mixpanel.setGroup("Team", "engineering");
// Track company-level metrics
mixpanel.track("Server Added", {
server_count: 5,
server_os: "ubuntu",
});Authentication Flows
Web Authentication (Website)
Desktop Authentication
Security Best Practices
For Users
Treat your license key like a password. Don't share it publicly or commit it to version control.
On the website, enable two-factor authentication for your account to prevent unauthorized access.
Regularly review active devices on your account. Deactivate machines you no longer use.
Always use the latest version of CtrlOps. Updates include security patches and improvements.
For Administrators
Admin Dashboard: Access detailed analytics, user management, and license oversight at admin.ctrlops.io
| Capability | Description |
|---|---|
| User Management | Block/unblock users, view activity |
| License Oversight | View all active licenses and devices |
| Payment Tracking | Monitor subscription statuses |
| Analytics | Aggregate usage metrics |
Compliance
GDPR Compliance
- Right to Access: Export all data associated with your account
- Right to Erasure: Request complete account deletion
- Data Portability: Download your data in standard formats
- Consent Management: Opt-out of analytics tracking
SOC 2 Alignment
- Access controls and audit logging
- Encrypted data transmission (TLS 1.3)
- Encrypted data at rest (AES-256)
- Regular penetration testing
- Incident response procedures
Questions about security? Contact our security team at security@ctrlops.io
Privacy Policy: Full details at ctrlops.io/privacy-policy