More from MSP Reboot: depl0y · st0r
Security Documentation

Security Architecture & Controls

ClientSt0r is designed with practical security controls expected by infrastructure-focused MSPs. Security is treated as an operational requirement, not a marketing checkbox.

Identity, roles, and session management.

Access to ClientSt0r is controlled through layered authentication and a granular permission system. Every user has the minimum access required for their role — no implicit elevation, no shared admin accounts.

RBAC

42-level permission system

Granular per-module access control across all platform functions. Roles are assigned per user per organisation. Least-privilege is the default — access is granted explicitly, not inherited broadly.

2FA / MFA

Enforced TOTP authentication

Time-based one-time passwords enforced at login. Configurable globally or per user by administrators. Standard authenticator app compatibility — no proprietary MFA vendor required.

Session Management

Configurable timeouts and re-auth

Session lifetimes are administrator-configurable. Sensitive operations require re-authentication regardless of active session state. Idle sessions are terminated at the configured threshold.

SSO

Azure AD / Entra ID

SAML and OIDC support for enterprise identity provider integration. Users authenticate through your existing Entra ID tenant — ClientSt0r does not store the identity provider credential.

Directory Integration

LDAP / Active Directory

Bind-based LDAP authentication with group synchronisation. User and group mappings configured by the administrator. Supports both on-premises AD and LDAP-compatible directory services.

Local Accounts

Local user management

Full local user account management as an alternative to directory integration. Password policy, forced reset, and account lockout configurable from the admin interface without external dependencies.

Vault encryption, isolation, and access control.

The credential vault is designed to hold sensitive client infrastructure passwords and secrets. Encryption is applied at rest with keys stored server-side — no credential data leaves your deployment to a vendor cloud.

AES-256-GCM at rest
Vault credentials encrypted using AES-256-GCM. Key material stored server-side under your control — not in any external cloud key management service unless you configure one. Authenticated encryption prevents undetected tampering.
Per-org vault isolation
Complete data segregation between client organisations. Vault records for one organisation are not accessible to users of another, regardless of platform-wide admin status. Access requires explicit role assignment at the organisation level.
Field-level access control
Secure notes and credential fields support granular access control down to the individual field. A user can be granted read access to a credential entry without being able to reveal the password field — useful for auditors or read-only technical staff.
Full credential audit trail
Every vault interaction — read, write, copy-to-clipboard, and delete — is logged with user identity, timestamp, action type, and source IP. Audit records are append-only and visible to administrators. Useful for compliance review and incident investigation.
HaveIBeenPwned integration
Vault credentials are checked against the HaveIBeenPwned Pwned Passwords database using the k-anonymity API method. Password hashes are not transmitted in full. Breached credentials are flagged for remediation — detection is passive and does not require storing plaintext passwords externally.

Perimeter controls and brute force protection.

ClientSt0r includes several network-layer and application-layer controls to reduce exposure of the admin interface. These work alongside standard server hardening practices — they are not a substitute for them.

GeoIP blocking and allowlisting
Restrict or allow admin interface access by country or region. Useful for MSPs operating in a defined geographic area who want to reduce exposure to international scanning and credential stuffing. Configurable from the admin panel without Nginx changes.
Fail2ban integration
Automatic IP banning after a configurable number of failed login attempts. Works in conjunction with the application-layer rate limiting. Ban duration and attempt threshold are configurable per deployment.
Login rate limiting
Application-level brute force protection with configurable lockout controls. Failed attempts are tracked per IP and per username. Lockouts can be reviewed and cleared from the admin interface without direct database access.
Secure HTTP headers
HSTS, X-Frame-Options, Content-Security-Policy, and X-Content-Type-Options enforced by default through the Nginx configuration. Header values are documented and overridable if your deployment has specific requirements.
HTTPS / TLS enforcement
Plain HTTP access redirected to HTTPS by default. TLS termination handled at the Nginx reverse proxy layer. The Django application server (Gunicorn) is not exposed directly to external traffic on any interface.
Internal-only application binding
Gunicorn binds to localhost only. The application is not reachable directly on any external interface. All external traffic routes through Nginx, which handles TLS, headers, and access controls before proxying to the application.

Scanning, expiry tracking, and security tooling.

Dependency and vulnerability management is part of the development and deployment process. Several tools are used to identify known-vulnerable components before and after deployment.

Dependency scanning

Snyk integration

Automated dependency and CVE scanning integrated into the development pipeline. Python package dependencies are checked against Snyk's vulnerability database. Known-vulnerable packages are flagged and prioritised before release.

OS package checks

OS-level security scanning

Recurring checks against installed OS packages for known-vulnerable components. Unpatched system packages are a common attack vector in self-hosted deployments — this scanning surfaces them before they become an exposure.

Expiry tracking

SSL and domain expiry alerts

Proactive alerting before certificate and domain registrations expire. Expired TLS certificates are a predictable and avoidable failure mode. Configurable alert thresholds — defaults notify well ahead of expiry.

Availability

Uptime monitoring

Endpoint availability tracking with configurable alert thresholds. Monitors the platform's own interfaces and optionally external services relevant to your clients. Alerts via configured notification channels.

Internal security tooling

ExploitHound

Internal security intelligence platform used during development for CVE correlation and exposure assessment. ExploitHound is used alongside Snyk and manual review to identify risk before it reaches production deployments. See exploithound.com.

Patch cadence

Security-prioritised releases

Security-relevant dependency and platform updates are prioritised in the release cycle. High and critical CVEs in direct dependencies are addressed out-of-band where possible rather than waiting for scheduled feature releases.

What happened, when, and who did it.

All sensitive operations generate an immutable audit log entry. Logs are viewable by administrators in-platform, exportable to CSV for compliance review, and charted for trend visibility. Retention is configurable per deployment — there is no forced expiry or cloud sync.

Event Category What Is Logged Fields Captured
Authentication Login success and failure, logout, session expiry, 2FA events, SSO assertions Timestamp, username, IP address, user agent, outcome
Vault Access Credential read, copy, edit, delete, field-level reveals Timestamp, user, credential ID, organisation, action type, IP
Permission Changes Role assignment and removal, permission grant and revoke, admin elevation Timestamp, acting user, target user, permission changed, before/after state
Admin Operations User creation and deactivation, integration config changes, system setting changes Timestamp, admin user, action, target object, changed values
Organisation Changes Org creation, modification, merge, deactivation Timestamp, user, org ID, action, changed fields
API Access API key usage, scope violations, high-volume requests, key creation and revocation Timestamp, key ID, endpoint, IP address, response code
Security Events GeoIP blocks, Fail2ban triggers, rate limit hits, lockout events Timestamp, IP address, country (where available), event type, action taken
CSV export Chartable activity view Configurable retention Append-only records Admin-only access

How the application runs on your server.

Secure deployment practices are documented and followed in the default install. The goal is that a standard installation is reasonably hardened without requiring the operator to know every configuration detail in advance.

Non-root service user
The application runs as a dedicated, unprivileged system user. The systemd service unit is configured with restricted privileges — the process cannot write to system directories, escalate privileges, or modify system configuration. Compromise of the application process does not automatically imply root access.
Environment-based secrets management
Database credentials, Django SECRET_KEY, API keys, and other secrets are supplied via environment variables or a .env file outside the application directory. No credentials are committed to source code or stored in the repository.
Nginx reverse proxy
The Django application is not exposed directly. Nginx handles TLS termination, static file serving, rate limiting at the proxy layer, and secure header injection. The Gunicorn socket or local port is bound to localhost only and not reachable from outside the server.
Restricted service exposure
Only HTTPS (443) is exposed externally by default. MariaDB binds to localhost. Gunicorn binds to localhost. The install guide explicitly documents firewall configuration — ufw rules are included in the standard setup walkthrough.
Web-based update mechanism
Platform updates are applied through the admin interface without requiring direct server access per update. Security-relevant updates are flagged in the changelog and prioritised for release. The update mechanism does not pull from external sources without admin initiation.
Django DEBUG disabled in production
The install guide requires DEBUG = False for production deployments. Debug mode exposes stack traces, settings contents, and SQL queries to any visitor — it is a common misconfiguration in self-hosted Django applications. The default production configuration template has DEBUG off.

What ClientSt0r does not claim.

Self-hosted software shifts security responsibility toward the operator. That is the tradeoff that comes with the control and ownership. The following is worth stating clearly.

ClientSt0r does not make unverifiable security claims. It is a self-hosted application — your deployment, your configuration, your responsibility. The security controls described here are included to support good operational practice. They do not substitute for:

  • proper network segmentation
  • your own backup and recovery testing
  • monitoring and alerting appropriate for your environment
  • regular review of access permissions
  • keeping the application and its dependencies updated

Further reading:

Security Policy on GitHub → Deployment Guide →