CyberArk Hardening Guide
Privileged access management hardening for vaults, PSM, and credential rotation
Overview
CyberArk is a Privileged Access Management (PAM) platform that protects credentials for half of Fortune 500 companies across 10,000+ organizations. As the central vault for privileged credentials, API tokens, session recordings, and SSH keys, CyberArk compromise enables immediate access to the most sensitive enterprise systems. Secrets management integrations with HashiCorp Vault, AWS Secrets Manager, and Azure Key Vault extend the attack surface beyond the vault itself.
Intended Audience
- Security engineers managing PAM infrastructure
- IT administrators configuring CyberArk
- GRC professionals assessing privileged access compliance
- Third-party risk managers evaluating secrets management
How to Use This Guide
- L1 (Baseline): Essential controls for all organizations
- L2 (Hardened): Enhanced controls for security-sensitive environments
- L3 (Maximum Security): Strictest controls for regulated industries
Scope
This guide covers CyberArk-specific security configurations including vault hardening, API security, session management, secrets rotation, and integration security with external secrets managers.
Table of Contents
- Authentication & Access Controls
- Vault Security
- API & Integration Security
- Session Management
- Secrets Rotation
- Monitoring & Detection
- Compliance Quick Reference
1. Authentication & Access Controls
1.1 Enforce Multi-Factor Authentication for All Access
Profile Level: L1 (Baseline) CIS Controls: 6.3, 6.5 NIST 800-53: IA-2(1), IA-2(6)
Description
Require MFA for all CyberArk console access, including PVWA (Password Vault Web Access), PSM (Privileged Session Manager), and API authentication.
Rationale
Why This Matters:
- CyberArk stores the most sensitive credentials in the enterprise
- Single-factor compromise = access to all privileged accounts
- MFA is mandatory for compliance (PCI DSS, SOX, HIPAA)
Attack Prevented: Credential theft, phishing, password spray
Attack Scenario: Attacker phishes CyberArk admin credentials, gains access to entire credential vault, extracts domain admin passwords.
ClickOps Implementation
Step 1: Configure LDAP/RADIUS MFA Integration
- Navigate to: PVWA → Administration → Options → Authentication Methods
- Configure RADIUS integration:
- Primary server: Your MFA RADIUS endpoint
- Shared secret: (stored securely)
- Timeout: 60 seconds
- Enable for user types: All
Step 2: Enforce MFA for Specific User Types
- Navigate to: PVWA → Administration → Platform Configuration
- For each platform:
- Enable: Require MFA for connection
- Configure MFA prompt timing
Step 3: Configure for Privilege Cloud
- Navigate to: Identity Administration → Authentication
- Configure:
- MFA enforcement: Required
- Factors: TOTP, Push, FIDO2
- Remember device: Disabled (L2/L3)
Validation & Testing
- Attempt PVWA login with password only - should fail
- Complete login with password + MFA - should succeed
- Verify MFA logged in audit trail
- Test PSM connection with MFA requirement
Compliance Mappings
| Framework | Control ID | Control Description |
|---|---|---|
| SOC 2 | CC6.1 | Logical access controls |
| NIST 800-53 | IA-2(1), IA-2(6) | MFA for privileged accounts |
| PCI DSS | 8.3.1 | MFA for administrative access |
| SOX | ITGC | Access control for financial systems |
1.2 Implement Vault-Level Access Controls
Profile Level: L1 (Baseline) NIST 800-53: AC-3, AC-6
Description
Configure granular safe-level permissions ensuring users only access credentials required for their role. Implement approval workflows for sensitive safes.
ClickOps Implementation
Step 1: Design Safe Structure
Organize safes into logical categories (Infrastructure, Applications, Emergency) with appropriate approval requirements for each tier.
Step 2: Configure Safe Permissions
- Navigate to: PVWA → Policies → Access Control (Safes)
- For each safe, configure:
- Members: Specific groups only
- Permissions: Minimum required (Use, Retrieve, List)
- Require approval: For sensitive safes
Step 3: Create Approval Workflow
- Navigate to: PVWA → Policies → Master Policy
- Configure:
- Require dual control: Enabled for DomainAdmins safe
- Approvers: Security team group
- Approval timeout: 4 hours
Code Implementation
Code Pack: API Script
# Create safe with restricted access via REST API
curl -X POST "https://${PVWA_URL}/PasswordVault/API/Safes" \
-H "Authorization: ${AUTH_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"safeName": "Windows-DomainAdmins",
"description": "Domain Administrator credentials - requires approval",
"olacEnabled": true,
"managingCPM": "PasswordManager",
"numberOfVersionsRetention": 10,
"numberOfDaysRetention": 30
}'
# Add member with limited permissions
curl -X POST "https://${PVWA_URL}/PasswordVault/API/Safes/Windows-DomainAdmins/Members" \
-H "Authorization: ${AUTH_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"memberName": "WindowsAdmins",
"memberType": "Group",
"permissions": {
"useAccounts": true,
"retrieveAccounts": true,
"listAccounts": true,
"addAccounts": false,
"updateAccountContent": false,
"deleteAccounts": false,
"manageSafe": false,
"requestsAuthorizationLevel1": true
}
}'
1.3 Configure Break-Glass Procedures
Profile Level: L1 (Baseline) NIST 800-53: CP-2
Description
Implement emergency access procedures for critical scenarios when normal authentication is unavailable.
ClickOps Implementation
Step 1: Create Break-Glass Safe
- Create safe:
Emergency-BreakGlass - Store emergency credentials:
- Master user recovery credentials
- Emergency admin accounts
- Critical infrastructure access
Step 2: Configure Dual Control
- Require approval from 2 different approvers
- Set expiration: 1 hour
- Enable enhanced logging
Step 3: Physical Security
- Store break-glass credentials in physical safe
- Distribute parts to different individuals
- Document recovery procedure
2. Vault Security
2.1 Harden Vault Server Configuration
Profile Level: L1 (Baseline) NIST 800-53: SC-8, SC-28
Description
Configure secure vault server settings including encryption, communication security, and component hardening.
ClickOps Implementation
Step 1: Verify Encryption Settings
- Check DBParm.ini and verify AES256 encryption is configured with appropriate key age settings.
Step 2: Configure Secure Communication
- Enable TLS 1.2/1.3 only
- Disable legacy protocols
- Configure certificate validation
Step 3: Harden Operating System
- Remove unnecessary services
- Configure Windows Firewall
- Enable audit logging
Code Implementation
Code Pack: CLI Script
[MAIN]
EncryptionMethod=AES256
ServerKeyAge=365
BackupKeyAge=365
2.2 Implement Vault High Availability
Profile Level: L2 (Hardened) NIST 800-53: CP-9, CP-10
Description
Configure disaster recovery and high availability for vault infrastructure.
Implementation
DR Configuration:
- Configure vault replication to DR site
- Test failover quarterly
- Document recovery procedures
- Verify backup integrity
Use PAReplicate.exe to verify replication status and test DR failover in non-production environments.
3. API & Integration Security
3.1 Secure API Authentication
Profile Level: L1 (Baseline) NIST 800-53: IA-5, SC-8
Description
Secure CyberArk API access using certificate-based authentication, API key rotation, and IP restrictions.
Rationale
Why This Matters:
- API tokens provide programmatic access to credential vault
- Stolen API tokens enable mass credential extraction
- Long-lived tokens create persistent risk
Attack Scenario: Stolen API token accessing credential vault enables extraction of all privileged passwords and SSH keys.
ClickOps Implementation
Step 1: Enable Certificate-Based API Authentication
- Navigate to: PVWA → Administration → Options → API Settings
- Configure:
- Certificate authentication: Enabled
- Client certificate required: Yes
- CA validation: Enabled
Step 2: Create API-Specific Application Identity
- Navigate to: PVWA → Applications → Application Identity
- Create application with:
- Allowed machines: Specific IPs/hostnames
- Certificate: Required
- Hash: Enable for script authentication
Step 3: Configure API Rate Limiting
Configure rate limiting in PVConfiguration.xml to limit concurrent requests, set request timeouts, and enable rate limiting for API endpoints.
Code Implementation
Code Pack: CLI Script
# In PVConfiguration.xml
<WebService>
<MaxConcurrentRequests>50</MaxConcurrentRequests>
<RequestTimeoutSeconds>120</RequestTimeoutSeconds>
<EnableRateLimiting>true</EnableRateLimiting>
</WebService>
Code Pack: SDK Script
# Secure CyberArk API authentication using certificate
import requests
PVWA_URL = "https://pvwa.company.com"
CERT_FILE = "/path/to/client.crt"
KEY_FILE = "/path/to/client.key"
CA_FILE = "/path/to/ca.crt"
def get_api_token():
"""Authenticate to CyberArk using certificate"""
response = requests.post(
f"{PVWA_URL}/PasswordVault/API/Auth/CyberArk/Logon",
cert=(CERT_FILE, KEY_FILE),
verify=CA_FILE,
json={
"username": "APIUser",
"password": "" # Certificate-based, no password
}
)
return response.text.strip('"')
def get_credential(token, safe, account):
"""Retrieve credential securely"""
response = requests.get(
f"{PVWA_URL}/PasswordVault/API/Accounts?filter=safeName eq {safe}",
headers={"Authorization": token},
cert=(CERT_FILE, KEY_FILE),
verify=CA_FILE
)
return response.json()
3.2 Restrict Integration Permissions
Profile Level: L1 (Baseline) NIST 800-53: AC-6
Description
Limit integration accounts to minimum required permissions. Service accounts should only access specific safes needed for their function.
ClickOps Implementation
Step 1: Create Purpose-Specific Integration Users
Create dedicated service accounts for each integration (Jenkins, Ansible, Terraform, SIEM) with access restricted to only the safes required for their function.
Step 2: Configure Minimal Permissions For each integration:
- Grant access to specific safes only
- Limit to
UseAccountspermission (no admin rights) - Enable audit logging for all actions
3.3 Integrate with External Secrets Managers
Profile Level: L2 (Hardened) NIST 800-53: IA-5(7)
Description
Securely configure integrations with HashiCorp Vault, AWS Secrets Manager, and Azure Key Vault.
Code Pack: API Script
# Configure Vault to retrieve from CyberArk
vault write auth/approle/role/cyberark \
token_policies="cyberark-read" \
token_ttl=1h \
token_max_ttl=4h
# CyberArk Secrets Hub configuration
# Sync secrets to Vault while maintaining CyberArk as source of truth
4. Session Management
4.1 Configure PSM Session Security
Profile Level: L1 (Baseline) NIST 800-53: AC-12, AU-14
Description
Secure Privileged Session Manager (PSM) sessions with recording, monitoring, and termination controls.
ClickOps Implementation
Step 1: Enable Session Recording
- Navigate to: PVWA → Administration → Platform Configuration
- For each platform:
- Enable recording: Yes
- Recording format: Universal (searchable)
- Storage: Secure location with encryption
Step 2: Configure Session Monitoring
- Navigate to: PSM → Live Sessions
- Enable:
- Real-time monitoring: Security team access
- Session suspension: On suspicious activity
- Session termination: Immediate capability
Step 3: Set Session Timeouts
Configure session duration limits (8 hours maximum), idle timeouts (30 minutes), and warning intervals (5 minutes before timeout) in the platform configuration.
Code Implementation
Code Pack: CLI Script
# Platform configuration
MaxSessionDuration=480 # 8 hours maximum
IdleSessionTimeout=30 # 30 minutes idle
WarningBeforeTimeout=5 # 5 minute warning
4.2 Implement Just-In-Time Access
Profile Level: L2 (Hardened) NIST 800-53: AC-2(6)
Description
Configure time-limited access requests with automatic credential rotation after use.
ClickOps Implementation
Step 1: Configure Time-Limited Access
- Navigate to: PVWA → Policies → Master Policy
- Enable:
- Exclusive access: Enabled
- One-time password: Enabled
- Auto-rotate after retrieval: Enabled
Step 2: Configure Access Request Workflow
- Create request workflow:
- User requests access
- Approver reviews justification
- Time-limited access granted
- Credentials rotate after session
5. Secrets Rotation
5.1 Configure Automatic Password Rotation
Profile Level: L1 (Baseline) NIST 800-53: IA-5(1)
Description
Enable CPM (Central Policy Manager) to automatically rotate privileged credentials based on policy.
ClickOps Implementation
Step 1: Configure Rotation Policy
- Navigate to: PVWA → Policies → Platform Configuration
- For each platform, configure:
- Password change interval: 30 days (L1) / 7 days (L2)
- Verification interval: Daily
- Reconcile interval: Weekly
Step 2: Configure Password Complexity
Set minimum length to 20 characters, require uppercase, lowercase, numbers, and special characters. Exclude characters that may cause parsing issues in scripts.
Code Implementation
Code Pack: CLI Script
# Platform password policy
MinLength=20
RequireUppercase=true
RequireLowercase=true
RequireNumbers=true
RequireSpecial=true
ExcludedCharacters='"<>;
5.2 Monitor Rotation Failures
Profile Level: L1 (Baseline)
Description
Alert on password rotation failures to prevent credential staleness.
Query for rotation failures via SIEM or direct database reporting to identify accounts where CPM status indicates failure, ordered by most recent failure date.
Code Pack: Terraform
# Check for CPM password rotation failures
resource "null_resource" "rotation_failure_check" {
provisioner "local-exec" {
command = <<-EOT
curl -sk -X GET \
"${var.pvwa_url}/PasswordVault/API/Accounts?filter=cpmStatus eq failure" \
-H "Authorization: ${var.pvwa_auth_token}" \
-H "Content-Type: application/json" \
| python3 -c "
import sys, json
data = json.load(sys.stdin)
accounts = data.get('value', [])
failed = [a for a in accounts if a.get('secretManagement', {}).get('status') == 'failure']
if failed:
print(f'WARNING: {len(failed)} account(s) with rotation failures:')
for acct in failed:
name = acct.get('name', 'unknown')
safe = acct.get('safeName', 'unknown')
reason = acct.get('secretManagement', {}).get('lastModifiedReason', 'unknown')
print(f' - {name} in {safe}: {reason}')
sys.exit(1)
else:
print('OK: No rotation failures detected')
"
EOT
}
triggers = {
check_interval = timestamp()
}
}
# Configure alerting for rotation failures
resource "null_resource" "rotation_failure_alerting" {
provisioner "local-exec" {
command = <<-EOT
curl -sk -X PUT \
"${var.pvwa_url}/PasswordVault/API/Configuration/Notifications" \
-H "Authorization: ${var.pvwa_auth_token}" \
-H "Content-Type: application/json" \
-d '{
"settings": {
"notifyOnCPMFailure": true,
"notifyOnVerificationFailure": true,
"notifyOnReconcileFailure": true,
"failureNotificationRecipients": "security-team"
}
}'
EOT
}
triggers = {
notification_config = "enabled"
}
}
# L2+: Configure automatic reconciliation on rotation failure
resource "null_resource" "auto_reconcile_on_failure" {
count = var.profile_level >= 2 ? 1 : 0
provisioner "local-exec" {
command = <<-EOT
curl -sk -X PUT \
"${var.pvwa_url}/PasswordVault/API/Configuration/PlatformConfiguration" \
-H "Authorization: ${var.pvwa_auth_token}" \
-H "Content-Type: application/json" \
-d '{
"settings": {
"autoReconcileOnFailure": true,
"maxReconcileAttempts": 3,
"reconcileRetryIntervalMinutes": 30
}
}'
EOT
}
triggers = {
profile_level = var.profile_level
}
}
Code Pack: DB Query
-- Query for rotation failures (via SIEM or reporting)
SELECT AccountName, SafeName, LastFailReason, LastFailDate
FROM PasswordVault_Accounts
WHERE CPMStatus = 'FAILED'
ORDER BY LastFailDate DESC;
6. Monitoring & Detection
6.1 Enable Comprehensive Audit Logging
Profile Level: L1 (Baseline) NIST 800-53: AU-2, AU-3
Description
Configure CyberArk audit logging and forward to SIEM for security monitoring.
Detection Use Cases
Anomaly 1: Mass Credential Retrieval – Detect users retrieving more than 20 passwords within a one-hour window, indicating potential credential harvesting.
Anomaly 2: After-Hours Access – Flag logon and password retrieval events occurring outside business hours (before 6 AM or after 8 PM) and on weekends.
Anomaly 3: Failed Authentication Spike – Identify brute force attempts by detecting more than 5 failed logon attempts from a single user or IP within a 15-minute window.
Code Pack: Terraform
# Configure comprehensive audit logging
resource "null_resource" "audit_logging_config" {
provisioner "local-exec" {
command = <<-EOT
curl -sk -X PUT \
"${var.pvwa_url}/PasswordVault/API/Configuration/AuditSettings" \
-H "Authorization: ${var.pvwa_auth_token}" \
-H "Content-Type: application/json" \
-d '{
"settings": {
"auditEnabled": true,
"logLogonEvents": true,
"logRetrieveEvents": true,
"logPasswordChangeEvents": true,
"logSafeModificationEvents": true,
"logPolicyChanges": true,
"retentionDays": ${var.audit_retention_days}
}
}'
EOT
}
triggers = {
retention_days = var.audit_retention_days
}
}
# Configure SIEM log forwarding
resource "null_resource" "siem_log_forwarding" {
count = var.siem_server != "" ? 1 : 0
provisioner "local-exec" {
command = <<-EOT
curl -sk -X PUT \
"${var.pvwa_url}/PasswordVault/API/Configuration/SyslogSettings" \
-H "Authorization: ${var.pvwa_auth_token}" \
-H "Content-Type: application/json" \
-d '{
"settings": {
"syslogEnabled": true,
"syslogServer": "${var.siem_server}",
"syslogPort": ${var.siem_port},
"syslogProtocol": "TCP",
"syslogFormat": "CEF",
"sendRealtimeEvents": true
}
}'
EOT
}
triggers = {
siem_server = var.siem_server
siem_port = var.siem_port
}
}
# L2+: Enable enhanced detection use cases
resource "null_resource" "enhanced_detection" {
count = var.profile_level >= 2 ? 1 : 0
provisioner "local-exec" {
command = <<-EOT
curl -sk -X PUT \
"${var.pvwa_url}/PasswordVault/API/Configuration/AuditSettings" \
-H "Authorization: ${var.pvwa_auth_token}" \
-H "Content-Type: application/json" \
-d '{
"settings": {
"detectMassRetrieval": true,
"massRetrievalThreshold": 20,
"massRetrievalWindowMinutes": 60,
"detectAfterHoursAccess": true,
"businessHoursStart": 6,
"businessHoursEnd": 20,
"detectFailedAuthSpike": true,
"failedAuthThreshold": 5,
"failedAuthWindowMinutes": 15,
"alertOnDetection": true
}
}'
EOT
}
depends_on = [null_resource.audit_logging_config]
triggers = {
profile_level = var.profile_level
}
}
# L3: Enable full forensic logging with immutable audit trail
resource "null_resource" "forensic_logging" {
count = var.profile_level >= 3 ? 1 : 0
provisioner "local-exec" {
command = <<-EOT
curl -sk -X PUT \
"${var.pvwa_url}/PasswordVault/API/Configuration/AuditSettings" \
-H "Authorization: ${var.pvwa_auth_token}" \
-H "Content-Type: application/json" \
-d '{
"settings": {
"immutableAuditTrail": true,
"logAllAPIRequests": true,
"logSessionKeystrokes": true,
"logClipboardEvents": true,
"retentionDays": 730,
"tamperDetection": true,
"hashVerification": true
}
}'
EOT
}
depends_on = [null_resource.enhanced_detection]
triggers = {
profile_level = var.profile_level
}
}
Code Pack: DB Query
SELECT UserName, COUNT(*) as RetrievalCount
FROM AuditLog
WHERE Action = 'Retrieve Password'
AND Timestamp > DATEADD(hour, -1, GETDATE())
GROUP BY UserName
HAVING COUNT(*) > 20;
SELECT *
FROM AuditLog
WHERE Action IN ('Logon', 'Retrieve Password')
AND (DATEPART(hour, Timestamp) < 6 OR DATEPART(hour, Timestamp) > 20)
AND DATEPART(dw, Timestamp) IN (1, 7); -- Weekends
SELECT UserName, SourceIP, COUNT(*) as FailedAttempts
FROM AuditLog
WHERE Action = 'Logon'
AND Status = 'Failed'
AND Timestamp > DATEADD(minute, -15, GETDATE())
GROUP BY UserName, SourceIP
HAVING COUNT(*) > 5;
7. Compliance Quick Reference
SOC 2 Mapping
| Control ID | CyberArk Control | Guide Section |
|---|---|---|
| CC6.1 | MFA enforcement | 1.1 |
| CC6.2 | Safe permissions | 1.2 |
| CC7.2 | Audit logging | 6.1 |
NIST 800-53 Mapping
| Control | CyberArk Control | Guide Section |
|---|---|---|
| IA-2(6) | MFA for privileged | 1.1 |
| AC-6 | Least privilege safes | 1.2 |
| IA-5(1) | Password rotation | 5.1 |
| AU-14 | Session recording | 4.1 |
Appendix A: References
Official CyberArk Documentation:
- Trust Center
- Trust Center (SafeBase Portal)
- Product Security and Vulnerability Disclosure
- CyberArk Labs Security Advisories
- Documentation Portal (All Products)
- Privilege Cloud Security Fundamentals
- Privilege Cloud Connector Hardening
- Technical Best Practices
API Documentation:
Compliance Frameworks:
- CyberArk Compliance (SOC 2, ISO 27001, FedRAMP)
- Corporate Security White Paper
- Blueprint for Identity Security Success
Security Vulnerabilities:
Changelog
| Date | Version | Maturity | Changes | Author |
|---|---|---|---|---|
| 2025-12-14 | 0.1.0 | draft | Initial CyberArk hardening guide | Claude Code (Opus 4.5) |