# Security Hardening

This guide covers security best practices and hardening recommendations for KEPM deployments. The default configuration is designed to be secure out of the box, but the settings in this guide will help you meet stricter security requirements in enterprise and regulated environments.

## Network Security

**All communication stays on localhost.** The KEPM agent binds exclusively to `127.0.0.1` — the HTTP server (ports 6888 and 6889) and the internal MQTT broker (port 8675) are never exposed to the network. No firewall rules are required for inbound access, and no network-level access controls are needed.

**Do not expose the local API to the network.** The API is designed for local inter-process communication only. If you are considering binding it to a network interface for remote management, contact Keeper before doing so — the authorization model is not designed for network-accessible endpoints.

**Verify localhost-only binding after deployment:**

```bash
# Windows
netstat -an | findstr :6889
# Expected: TCP 127.0.0.1:6889 ... LISTENING

# Linux / macOS
netstat -an | grep :6889
# Expected: 127.0.0.1:6889 ... LISTEN
```

**TLS is always on.** All HTTPS communication uses TLS 1.2 or TLS 1.3. The agent generates a self-signed certificate at startup for localhost use. This is the correct and expected behavior — the certificate secures localhost communication, and self-signed certificates are appropriate in this context.

## Service Account Configuration

**Run as SYSTEM or root.** The KeeperPrivilegeManager service must run as `SYSTEM` on Windows or `root` on Linux/macOS. This is a hard requirement — running as a lower-privileged account will prevent the agent from intercepting elevation requests and enforcing policies.

**Installation path must be owned and writable only by the service account.** The installation directory and all subdirectories must be owned by the service account and not writable by standard users. If a non-privileged user can modify executables or plugin files in the installation directory, the cryptographic validation protecting against tampered plugins is undermined.

**Verify path security on Linux/macOS:**

```bash
# Check that /opt/keeper/sbin and all parent directories are root-owned
# and not world-writable
ls -la /opt/keeper/
stat /opt/keeper/sbin/KeeperPrivilegeManager
```

On Windows, verify the installation directory ACL:

```powershell
Get-Acl "C:\Program Files\Keeper Security\Endpoint Privilege Management" | Format-List
```

Standard users should have Read and Execute, but not Write or Modify.

## Certificate and Signature Management

**Leave `AlternativeSignatures` empty unless you have a specific need.** The `AlternativeSignatures` setting in `appsettings.json` allows additional certificate thumbprints to be trusted for plugin signing. The default (empty) configuration means only Keeper-signed plugins will load. Adding thumbprints here allows third-party or custom plugins — review the need carefully before adding any entry.

```json
{
  "Settings": {
    "AlternativeSignatures": []
  }
}
```

**Never store certificate passwords in configuration files.** If you are deploying custom certificates, use the Windows Certificate Store or a platform credential manager to store credentials. The `CertPassword` field in the configuration should always be empty.

**Rotate custom certificates on a regular schedule.** If your organization uses custom certificates for the KEPM HTTPS endpoint, establish a rotation schedule consistent with your PKI policy (typically annually or when a certificate approaches its expiry date). The agent generates a new self-signed certificate automatically at each restart if no custom certificate is configured.

## File Permissions

The following permission model should be enforced on all platforms:

<table data-header-hidden="false" data-header-sticky><thead><tr><th width="154.6666259765625">Directory</th><th>Recommended Access</th></tr></thead><tbody><tr><td>Installation root</td><td>Service account: Full control; Administrators: Read/Execute; Users: none</td></tr><tr><td><code>Plugins/</code></td><td>Service account: Full control; Administrators: Read/Execute; Users: none</td></tr><tr><td><code>Jobs/</code></td><td>Service account: Full control; Administrators: Read/Execute; Users: none</td></tr><tr><td><code>KeeperStorage/</code></td><td>Service account: Full control; Administrators: Read only; Users: none</td></tr><tr><td><code>policies/</code></td><td>Service account: Full control; Administrators: Read only; Users: none</td></tr></tbody></table>

**On Linux**, verify that the `/opt/keeper/sbin/` directory tree is owned by root and that group and world write permissions are absent:

```bash
find /opt/keeper/sbin -perm /o+w -o -perm /g+w | head
# Should return nothing
```

## Allowed Hosts

The `AllowedHosts` setting in `appsettings.json` controls which HTTP `Host` headers are accepted. The default value of `"*"` accepts any host header — this is acceptable for localhost-only deployments but can be tightened:

```json
{
  "AllowedHosts": "localhost;127.0.0.1"
}
```

In production deployments where only local processes will interact with the API, set this to `localhost;127.0.0.1`. Changes to `AllowedHosts` require a service restart.

## Audit Logging

**Audit logging is enabled by default** **and cannot be disabled.** All policy evaluations, privilege elevations, file access attempts, configuration changes, and administrative actions are recorded automatically to the MQTT `AuditMessage` topic and unified storage.

{% hint style="info" %}
Audit logs are the primary evidence source for compliance reviews, incident response, and policy effectiveness analysis.
{% endhint %}

**Review logs regularly.** At a minimum, review audit logs weekly for:

* **Repeated High-Frequency Policy evaluations** from a single user that could indicate policy circumvention attempts
* **Administrative Actions** — Admin-level API calls carry the highest privilege in the local authorization model. Logging who performed them and when creates the audit trail needed to detect privilege abuse and satisfy compliance requirements.
* **Policy Evaluation Denials** — A spike in denials can reveal either a misconfigured policy that is blocking legitimate work, or a user or process actively testing the boundaries of what is permitted — both require investigation.
* **Configuration Changes** — Changes to `appsettings.json`, plugin configs, or job definitions directly affect what the agent trusts and enforces. Unauthorized or unexpected changes are a strong indicator of tampering or a supply-chain-style attack against the agent itself.
* **Failed Authentication Attempts** — Repeated failures against the local API indicate a process on the endpoint is attempting unauthorized access, which could signal malware, a compromised application, or a misconfigured integration probing for access.
  * `AUTHORIZATION_FAILED` and `PROCESS_AUTHENTICATION_FAILED` are defined as audit event types and recorded, but these are *local API authorization failures*, not endpoint-level login failures. Whether a specific failure scenario surfaces as an audit event depends on where in the stack it occurs.
* **Policy Circumvention Attempts** — The policy engine tracks evaluation requests per source, keyed by `SessionId` or `UserName+MachineName` combination, and queues requests that exceed the configured rate limit (default: 100 requests per minute). A circuit breaker opens after 10 consecutive failures from the same source and remains open for 5 minutes before auto-resetting. In the audit log, look for a single `user_info` value generating an abnormal volume of `policy_evaluation_status` DENY events against the same `target_info` in a short window, or bursts that trigger the rate limiter queue — both indicate a user or automated process probing for a permissive execution path rather than performing legitimate work.

**Retain logs for your compliance requirement period.** Log files are retained for 15 days by default. If your compliance framework (SOC 2, ISO 27001, FedRAMP, etc.) requires longer retention, implement log forwarding to a SIEM or central log store before the 15-day window expires. See [Reading Logs](/en/keeperpam/endpoint-privilege-manager/user-guides/reading-logs.md) for log file paths.

## Security Monitoring Recommendations

Monitor for the following conditions and set up alerts where your infrastructure supports it:

<table><thead><tr><th width="167.33331298828125">Area</th><th>Recommendation</th></tr></thead><tbody><tr><td>Agent Availability</td><td>Monitor for unexpected service stops or agent going offline; treat unscheduled outages as potential tampering until ruled out</td></tr><tr><td>Audit Logging — Config Changes</td><td>Alert on changes to <code>appsettings.json</code>; monitor plugin and job configuration files separately via file integrity monitoring</td></tr><tr><td>Audit Logging — Denials</td><td>Export to SIEM regularly; alert on repeated DENY events from the same <code>user_info</code> in a short window</td></tr><tr><td>Audit Logging — Registration</td><td>Alert on agent registration events that occur outside scheduled deployment windows</td></tr><tr><td>Certificates</td><td>Never store passwords in config; keep <code>AlternativeSignatures</code> empty or minimal</td></tr><tr><td>File Permissions</td><td>Admin-only read/write on config, storage, and policy paths</td></tr><tr><td>Log Levels</td><td>Set to <code>Warning</code> or <code>Information</code> in production (not <code>Debug</code>)</td></tr><tr><td>Network</td><td>Keep localhost-only binding; set <code>AllowedHosts</code> to specific hostnames</td></tr><tr><td>Process Authentication</td><td>Review service logs for process authentication events involving processes not launched by KEPM; these appear as <code>PROCESS_AUTHENTICATION_FAILED</code> entries and should be rare in a healthy deployment</td></tr><tr><td>Service Account</td><td>Run as SYSTEM (Windows) or root (Linux/macOS)</td></tr></tbody></table>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.keeper.io/en/keeperpam/endpoint-privilege-manager/user-guides/security-hardening.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
