-
-
Notifications
You must be signed in to change notification settings - Fork 72
Security
- Security Overview
- How We Protect Your Data
- Infiltration Guard: Local Import Enforcement
- Supply Chain & Trust
- The Servy Trust Boundary
- File Locations & Recovery
- Critical Warning: Machine Migration
- Best Practices
- Troubleshooting
Servy acts as a secure vault for your Windows service configurations. We encrypt sensitive data, including passwords, environment variables, and all execution arguments (Parameters, Password, EnvironmentVariables, FailureProgramParameters, PreLaunchParameters, PreLaunchEnvironmentVariables, PostLaunchParameters, PreStopParameters, and PostStopParameters), using industry-standard AES-256 encryption. If the database is compromised, your actual secrets remain unreadable text.
Starting in version 7.9, we use a two-layer defense strategy to keep your secrets safe:
- The Locked Room (ACLs): We automatically restrict who can even view the Servy folders on your hard drive.
- The Machine-Unique Key (Dynamic Entropy): We tie your encryption key to the unique fingerprint of your specific computer. If the files are stolen and moved to another PC, they cannot be opened.
You can verify that the "Locked Room" is active by checking the Access Control List (ACL) of the data directory. Run the following command in an elevated PowerShell window:
(Get-Acl "$env:ProgramData\Servy").Access | Select-Object IdentityReference, IsInherited, AccessControlTypeWhat to look for in the output:
-
IdentityReference: You should typically see three principals:
NT AUTHORITY\SYSTEM,BUILTIN\Administrators, and the specific user account that installed Servy.-
Note: The installer and the
SecurityHelperclass grant the current user Full Control as a "Manual Key" to ensure operational continuity. If the installation was performed strictly by a process already running asSYSTEM, only the first two will appear.
-
Note: The installer and the
-
IsInherited: This must be False for all entries. Servy explicitly breaks inheritance from the
C:\ProgramDataroot to prevent "sideways" access from other applications or standard users. -
AccessControlType: This should be Allow. There should be no entries for broad identity groups such as
Everyone,Users, orAuthenticated Users, as these are surgically purged during the hardening phase.
To reconcile this with the source code, auditors can refer to the following logic gates:
-
Inno Setup (
servy.iss): TheShouldAddCurrentUsercheck ensures the interactive installer's account is added to the folder ACL. -
Runtime (
SecurityHelper.cs): TheApplySecurityRulesmethod checks if the currentUserSidis theSystemSid. If they differ, it explicitly adds theFileSystemRights.FullControlrule to the directory.
While the root vault (%ProgramData%\Servy) has inheritance explicitly broken, all internal child folders such as recovery, db, and security are created with inheritance enabled relative to the vault root. This ensures the three-principal "Locked Room" security model is maintained consistently throughout the entire data structure without redundant ACL writes.
We have overhauled our security model to be proactive rather than reactive.
In previous versions, we relied on Windows defaults for the %ProgramData%\Servy folder. In v7.9+, Servy takes control. Upon installation or startup, the application automatically performs the following actions:
- Breaks Inheritance: We disconnect the folder from the open permissions of the parent drive.
- Explicit Purge: We surgically remove access for the Users, Authenticated Users, and Everyone groups.
- Restricted Entry: Only SYSTEM and Administrators are allowed in. This prevents Local Privilege Escalation: the risk of a standard user tampering with a service to gain Admin rights.
-
Downward Inheritance: All subfolders and files within
%ProgramData%\Servyautomatically inherit these strict parent ACLs, ensuring new service directories, configurations, and logs remain locked down by default. -
Custom Permissions Preserved (with caveat): Explicit
AllowACEs you have added for named identities are retained. AnyAllowrule targeting the broad groupsUsers,Authenticated Users, orEveryoneis surgically purged on every run.Denyrules for those broad groups are left in place (onlyDenyrules targetingAdministrators,LocalSystem, or the installing user are removed, as an anti-squatting measure).
We use the Windows Data Protection API (DPAPI) with an added security layer. To prevent binary analysis (where someone reads our code to find a secret), we derive our encryption entropy from your computer's unique MachineGuid.
- Why it is safe: The combination to the vault is not written in our code; it is hidden in your Windows Registry.
-
Non-Portable: Because every computer has a different ID, your
aes_key.datfile is useless if copied to another machine.
To adhere to strict cryptographic best practices, we use HKDF (RFC 5869) to derive independent sub-keys from your master key. By combining a cryptographic salt with distinct context strings (V2_AES_ENCRYPTION and V2_HMAC_AUTHENTICATION), we guarantee absolute key separation between our encryption operations and our authentication layers.
We use AES-256-CBC with HMAC-SHA256. This does not just hide your data; it wraps it in a digital seal. If an attacker tries to modify even a single bit of the encrypted data, Servy will detect the tampering and refuse to decrypt it, preventing bit-flipping attacks.
Security doesn't stop at the hard drive. To protect against advanced memory scraping attacks, Servy securely handles secrets in RAM. Our SecureData class implements IDisposable and utilizes CryptographicOperations.ZeroMemory() to wipe every sensitive buffer as soon as it is no longer needed:
- Transient Data: Plaintext and ciphertext buffers are zeroed immediately after each encryption/decryption call.
- Initialization Material: The master key clone passed during construction is wiped as soon as sub-keys are derived.
-
Key Material: All active sensitive buffers are securely zeroed upon the object's disposal. This includes the two HKDF-derived V2 sub-keys required for modern AES encryption and HMAC authentication. (Note: The two legacy V1 buffers, used for master key cloning and static IV retention, remain unallocated in shipped production builds as
AllowLegacyV1Decryptionis permanently disabled at compile-time).
Unlike standard array clearing methods, this approach ensures that the memory wipe is never elided by the JIT compiler's release optimizations, significantly reducing the window of opportunity for an attacker to extract keying material from a memory dump.
While Servy supports CLI flags for configuration convenience (e.g., --password, --envVars, --params), passing sensitive data via command-line arguments is insecure. Command-line arguments are visible to any user or process able to enumerate the process list (e.g., Get-Process, pslist, or Event Tracing for Windows) and are often recorded in shell history files and system audit logs.
Starting in v8.5, Servy provides two secure alternatives to handle sensitive data:
- Environment Variables (Recommended for per-service secrets): For each sensitive field, Servy supports an associated environment variable. Servy reads these variables transparently at install time, ensuring the secret never touches the process argument string.
-
Import Configuration (Recommended for complex deployments): Use the
importcommand with an XML or JSON configuration file. This keeps sensitive values entirely out of the command line and allows for structured, version-controlled configuration management.
The following parameters are considered sensitive and should be provided via environment variables (v8.5+) or configuration files:
| Parameter | Environment Variable | Description |
|---|---|---|
--password |
SERVY_PASSWORD |
Windows service account password. |
--params |
SERVY_PROCESS_PARAMETERS |
Command-line arguments for the service process. |
--envVars |
SERVY_ENVIRONMENT_VARIABLES |
Environment variables for the service process. |
--failureProgramParams |
SERVY_FAILURE_PROGRAM_PARAMETERS |
Arguments for the failure recovery program. |
--preLaunchParams |
SERVY_PRE_LAUNCH_PARAMETERS |
Arguments for the pre-launch executable. |
--preLaunchEnv |
SERVY_PRE_LAUNCH_ENVIRONMENT_VARIABLES |
Env vars for the pre-launch executable. |
--postLaunchParams |
SERVY_POST_LAUNCH_PARAMETERS |
Arguments for the post-launch executable. |
--preStopParams |
SERVY_PRE_STOP_PARAMETERS |
Arguments for the pre-stop executable. |
--postStopParams |
SERVY_POST_STOP_PARAMETERS |
Arguments for the post-stop executable. |
# Set the secrets in the process-level environment
$env:SERVY_PASSWORD = 'p@ssw0rd_123!'
$env:SERVY_ENVIRONMENT_VARIABLES = 'API_KEY=secret_key_123;DB_URL=... '
# Install the service (omit sensitive flags)
servy-cli install --name="MySecureService" --path="C:\App\app.exe" --user="DOMAIN\svc_account"
# Clear variables immediately after use
Remove-Item Env:SERVY_PASSWORD
Remove-Item Env:SERVY_ENVIRONMENT_VARIABLESImporting service configurations from Universal Naming Convention (UNC) paths or through redirected paths (such as symbolic links or junctions) poses severe security risks. These techniques are designed to bypass system trust boundaries and expose the application execution layer to malicious configuration injection.
To preserve system integrity, the import pipeline explicitly blocks non-local paths. The primary attack vectors mitigated by this enforcement include:
-
Attacker-Controlled Configuration Injection: UNC targets (e.g.,
\\attacker\share\evil.xml) allow a remote adversary to host a malicious configuration file on an infrastructure node under their direct control. If ingested, an attacker can inject arbitrary executable paths, unauthorized parameters, or unverified environment variables, effectively hijacking the service's runtime behavior. - Path Redirection Attacks: By leveraging filesystem symbolic links, directory junctions, or specialized Win32 reparse points, an attacker can manipulate the path resolution mechanics. This can trick the engine into reading from an entirely different backend target than intended, exposing sensitive files or pulling parameters from unexpected network locations.
-
Privilege Escalation and System Integrity: Because the engine performs administrative elevation validation checks to operate securely, it possesses high-privilege access to the local machine. If an import task is manipulated into processing files from protected operating system directories (such as the
WindowsorSystem32namespaces), it can facilitate unintended system-level file access or manipulation. -
Network-Based Mapping Bypasses: Virtual local paths - including mapped network drives (e.g.,
Z:\config.json) or local DOS device substitutions (subst) - frequently mask underlying remote storage volumes. These targets inherently lack the rigid security boundaries of localized storage hardware, introducing network-level interception vectors.
To counter these vectors, the engine pipes all configuration paths through a strict, sequential validation chain before any file access occurs across the CLI or GUI interfaces:
-
Explicit UNC Inspection: Rejects any raw path strings starting with standard network prefixes (
\\) or parsing as a remote URI. -
Drive Interface Queries: Evaluates the target volume via
DriveInfoto proactively block network-backed logical drive letters. - Reparse Point Ancestor Walks: Recursively traces the full directory tree to verify that no parent or sibling paths utilize symbolic links or directory junctions.
- File-Level Symlink Evaluation: Directly inspects filesystem attributes to confirm the target file is a physical, non-symbolic entity.
-
Reserved Device Blocks: Prevents spoofing attempts using legacy system device designations (e.g.,
CON,PRN,AUX). - Protected System Directory Fencing: Prevents configuration loading out of primary administrative operating system paths.
-
Win32 Kernel Handle Finalization: Opens a temporary restricted read handle to execute a low-level volume query via
GetFinalPathNameByHandle. This extracts the ultimate canonical storage path, stripping away any complex virtual loop devices or custom environment mappings to expose and block hidden UNC targets.
We believe security requires transparency. You should not have to guess if our software is safe.
- Digitally Signed: All executables are signed by SignPath. This proves the code has not been altered since it left our build server.
- SBOM (Software Bill of Materials): We publish a full list of every ingredient used to build Servy in the CycloneDX format.
- Vulnerability Scanning: We use GitHub Dependabot to monitor for holes in our dependencies 24/7.
- Verified Safe: Servy is regularly reviewed by Microsoft Security Intelligence and passes clean scans on VirusTotal.
Servy operates on a Single Trust Boundary model. All services managed by Servy live in the same secure room: %ProgramData%\Servy.
- Shared Influence: If you give a specific service account Write access to the Servy folder, it can technically see the configuration of other services in that same folder.
- Intended Use: Servy is designed for dedicated app servers, CI/CD agents, and workstations.
- Isolation Tip: If you need absolute Zero Trust isolation between two services, they should be run on separate Virtual Machines or in Windows Containers.
| Identity | Access Level | Managed By |
|---|---|---|
| SYSTEM | Full Control | Servy (Automatic) |
| Administrators | Full Control | Servy (Automatic) |
| Installing User (when not SYSTEM) | Full Control | Servy (Automatic) |
| Custom Service Accounts | Modify | User (Manual) |
| Standard Users | None | Servy (Automatic) |
The installing user ACE is added by
SecurityHelper.ApplySecurityRulesonly when the current process identity is not SYSTEM. If Servy was installed/run strictly under SYSTEM (e.g. unattended deployment), this row does not appear in the ACL.
Note
If you run a service under a custom Service Account, you must manually grant that account Modify rights to %ProgramData%\Servy. Standard users are blocked by default for your protection.
Your master encryption keys are stored here:
-
Database:
%ProgramData%\Servy\db\Servy.db -
Key:
%ProgramData%\Servy\security\aes_key.dat -
IV:
%ProgramData%\Servy\security\aes_iv.dat
The aes_iv.dat file holds the static IV used by the legacy v1 cipher format (Servy < 6.5). Servy 6.5+ uses a per-message random IV embedded in the ciphertext, so the static IV is no longer used to encrypt or decrypt anything in current builds - v1 decryption is permanently disabled (AllowLegacyV1Decryption = false) to mitigate downgrade attacks. While disabled, the file is not read on service start and is not loaded into memory; the entire load path is compiled out via the AllowLegacyV1Decryption constant. The file is still created on fresh installs and retained on disk so that legacy material remains available if AllowLegacyV1Decryption is ever re-enabled in a custom build - do not delete it. To migrate records written by a pre-6.5 build, export them with a v1-compatible Servy version and import the resulting file into the current version; they will be re-encrypted as v2.
Because our encryption is tied to your specific Windows installation, you cannot simply copy the .dat files to a new server.
To move Servy to a new PC:
- Export your services on the old machine (the export is unencrypted; treat it like a physical key -
Parameters,EnvironmentVariables, etc. are written in plaintext). - Move the Export file to the new machine.
- Import the services. Because Servy never persists the LogOn account/password into the export, the imported services will run as LocalSystem by default.
-
Re-enter the service account credentials manually in Servy Manager (or via
servy-cli install) for any service that should not run as LocalSystem.
Step 4 is mandatory if your services run under a domain account, MSA, or local account.
-
Backup the Whole Servy Data Folder: Before doing a Windows Reset or
Refresh, back up the entire
%ProgramData%\Servy\tree. The keys (security\*.dat) and the encrypted configuration database (db\Servy.db) must be restored together - keys alone cannot decrypt anything, and the database alone cannot be decrypted without the matching keys. - Use Managed Accounts: When possible, run services under Managed Service Accounts (MSA) for the best balance of security and ease of use.
-
Audit Access: Periodically check the Security tab of the
%ProgramData%\Servyfolder to ensure no unauthorized users have been added manually.
-
Access Denied on Startup: This usually means the account running the service does not have permissions to the
%ProgramData%\Servyfolder. Refer to the Permissions Table above. -
Decryption Error: This happens if the
.datfiles were moved from another computer or if the WindowsMachineGuidwas altered. You will need to re-enter every encrypted field -Password,Parameters,EnvironmentVariables,PreLaunchEnvironmentVariables, and the corresponding hookParameters(PreLaunchParameters,PostLaunchParameters,PreStopParameters,PostStopParameters,FailureProgramParameters) - because all of them are stored under the same machine-bound AES key. If you have an Export from the original machine, import it now (per Critical Warning: Machine Migration) instead of reconfiguring each service by hand.
Servy v7.9+ is designed to be invisible but invincible. By automating the routine parts of Windows security, including Access Control Lists and Registry GUIDs, we ensure your infrastructure stays locked down without needing a degree in cryptography.
Questions? Check our full Troubleshooting Guide or join the community discussion.
Copyright © Akram El Assas. All rights reserved.
- Home
- Overview
- Installation Guide
- Advanced Configuration
- Usage
- Servy Desktop App
- Servy Manager
- Servy CLI
- PowerShell Module
- Examples & Recipes
- Logging & Log Rotation
- Health Monitoring & Recovery
- Environment Variables
- Service Dependencies
- Pre-Launch & Post-Launch Actions
- Pre-Stop & Post-Stop Actions
- Shutdown & Teardown
- Export/Import Services
- Automation & CI/CD
- Integration with Monitoring Tools
- Service Event Notifications
- Comparison with Alternatives
- Security
- Architecture
- Building from Source
- Troubleshooting
- FAQ