Qualys Hardening Guide
Vulnerability management platform hardening for Qualys VMDR including user access, scanning configuration, and policy compliance
Overview
Qualys operates the Enterprise TruRisk Platform (formerly branded the Qualys Cloud Platform), a cloud-based vulnerability management, detection, response, and compliance suite protecting millions of assets across enterprises worldwide. As a critical security tool with deep access to infrastructure, Qualys configurations directly impact vulnerability visibility and remediation effectiveness. Proper hardening ensures security data integrity and prevents unauthorized access to sensitive vulnerability information.
Intended Audience
- Security engineers managing vulnerability programs
- IT administrators configuring Qualys
- GRC professionals using Policy Compliance and Policy Audit
- SOC analysts managing vulnerability data
How to Use This Guide
- L1 (Crawl): Essential controls for all organizations
- L2 (Walk): Enhanced controls for security-sensitive environments
- L3 (Run): Strictest controls for regulated industries
Scope
This guide covers Enterprise TruRisk Platform security including user management, API authentication, activity logging, scanning configuration, compliance assessment (Policy Compliance and Policy Audit), and Security Configuration Assessment (SCA).
Table of Contents
- Access & Authentication
- Scanning Configuration
- Policy Compliance
- Asset Management
- Compliance Quick Reference
1. Access & Authentication
1.1 Configure SSO Authentication
Profile Level: L2 (Walk)
| Framework | Control |
|---|---|
| CIS Controls | 6.3, 12.5 |
| NIST 800-53 | IA-2, IA-8 |
Description
Configure SAML SSO to centralize authentication for Qualys platform.
Rationale
Why This Matters:
- Centralizes Qualys authentication in your corporate IdP, enforcing MFA, conditional access, and session policy on every login
- Local Qualys passwords bypass IdP controls and are prime targets for credential stuffing, phishing, and password reuse
- Centralized provisioning and deprovisioning removes departed users automatically, eliminating orphaned accounts with standing access to vulnerability data
- Qualys holds a complete map of every unpatched weakness across your estate, so a single compromised login hands an attacker a ready-made target list
Attack Prevented: Credential theft, phishing, password reuse, orphaned-account access
ClickOps Implementation
Step 1: Access SSO Settings
- Navigate to: Administration → User Management → Authentication
- Click SAML Authentication
Step 2: Configure SAML
- Enable SAML authentication
- Configure IdP settings:
- IdP SSO URL
- IdP Certificate
- Entity ID
- Download Qualys SP metadata
Step 3: Configure IdP
- Create SAML application
- Configure attribute mappings
- Assign users/groups
Step 4: Enable SSO Enforcement
- Test SSO authentication
- Enable SSO for users
- Disable password authentication
Time to Complete: ~1 hour
1.2 Enforce Multi-Factor Authentication
Profile Level: L1 (Crawl)
| Framework | Control |
|---|---|
| CIS Controls | 6.5 |
| NIST 800-53 | IA-2(1) |
Description
Require MFA for all users, especially administrators.
Rationale
Why This Matters:
- Admin accounts without MFA pose significant risk
- Qualys admins have access to all vulnerability data
- MFA should be enforced via SSO/IdP
Attack Prevented: Credential theft, password reuse, phishing-driven account takeover, unauthorized access to vulnerability data
ClickOps Implementation
Step 1: Configure MFA for Non-SSO Users
- Navigate to: Administration → User Management → Users
- Enable 2FA requirement for each user
- Or enforce through SSO/IdP
Step 2: Protect Admin Accounts
- Ensure all admin accounts have MFA
- Use strong passwords stored in vault
- Consider hardware keys for admins
Step 3: Verify Compliance
- Review user MFA status
- Follow up with non-compliant users
- Document exceptions
1.3 Implement Role-Based Access Control
Profile Level: L1 (Crawl)
| Framework | Control |
|---|---|
| CIS Controls | 5.4 |
| NIST 800-53 | AC-6 |
Description
Configure granular roles for least privilege access.
Rationale
Why This Matters:
- Least-privilege roles ensure each user can only perform the actions their job requires, limiting the blast radius of any single compromised account
- Restricting the Manager (full admin) role to a small set of named personnel prevents over-broad control of scan configs, credentials, and platform settings
- Scoped roles keep read-only stakeholders from altering scan targets, deleting findings, or exporting sensitive vulnerability data
- Clear role boundaries make access reviews and audit attestation straightforward
Attack Prevented: Privilege escalation, insider misuse, unauthorized data export, lateral movement
ClickOps Implementation
Step 1: Review Built-in Roles
- Navigate to: Administration → User Management → Roles
- Review available roles:
- Manager: Full administrative access
- Unit Manager: Team management
- Scanner: Scanning only
- Reader: View only
Step 2: Create Custom Roles
- Click New Role
- Configure permissions:
- Asset management
- Scanning
- Reporting
- Policy compliance
- Apply principle of least privilege
Step 3: Assign Appropriate Roles
- Limit Manager to essential personnel (2-3)
- Use Scanner for vulnerability teams
- Use Reader for stakeholders
Code Pack: API Script
# Fetch all users and audit role assignments
# Qualys v2 user list returns XML with USER_LIST/USER elements
USER_XML=$(ql_get "/auth/user/?action=list" 2>/dev/null) || {
fail "1.3 Failed to retrieve user list (requires Manager role)"
increment_failed
summary
exit 1
}
# Count users by role type
TOTAL_USERS=$(echo "${USER_XML}" | xml_count "USER")
MANAGER_COUNT=$(echo "${USER_XML}" | grep -c "<USER_ROLE>Manager</USER_ROLE>" || echo "0")
ADMIN_COUNT=$(echo "${USER_XML}" | grep -c "<USER_ROLE>Unit Manager</USER_ROLE>" || echo "0")
READER_COUNT=$(echo "${USER_XML}" | grep -c "<USER_ROLE>Reader</USER_ROLE>" || echo "0")
SCANNER_COUNT=$(echo "${USER_XML}" | grep -c "<USER_ROLE>Scanner</USER_ROLE>" || echo "0")
info "1.3 Total users: ${TOTAL_USERS}"
info "1.3 Managers: ${MANAGER_COUNT} | Unit Managers: ${ADMIN_COUNT}"
info "1.3 Scanners: ${SCANNER_COUNT} | Readers: ${READER_COUNT}"
# Flag if more than 3 Manager-level accounts exist
if [ "${MANAGER_COUNT}" -gt 3 ]; then
warn "1.3 ${MANAGER_COUNT} Manager accounts detected -- review for least-privilege"
warn "1.3 Best practice: limit Manager role to 2-3 accounts maximum"
fi
# List all users with Manager or Unit Manager roles for review
info "1.3 Privileged users requiring review:"
echo "${USER_XML}" | grep -B5 -A5 "<USER_ROLE>Manager</USER_ROLE>" \
| grep -oP "<USER_LOGIN>\K[^<]+" | while read -r login; do
warn "1.3 Manager: ${login}"
done
echo "${USER_XML}" | grep -B5 -A5 "<USER_ROLE>Unit Manager</USER_ROLE>" \
| grep -oP "<USER_LOGIN>\K[^<]+" | while read -r login; do
warn "1.3 Unit Manager: ${login}"
done
Code Pack: Sigma Detection Rule
detection:
selection_create:
Action: 'User Created'
selection_modify:
Action: 'User Role Modified'
selection_role:
Details|contains:
- 'Manager'
- 'Unit Manager'
condition: (selection_create or selection_modify) and selection_role
fields:
- Date
- User
- Action
- Details
- UserLogin
1.4 Configure IP Restrictions
Profile Level: L2 (Walk)
| Framework | Control |
|---|---|
| CIS Controls | 13.5 |
| NIST 800-53 | AC-17 |
Description
Restrict Qualys access to approved IP addresses.
Rationale
Why This Matters:
- Limiting access to known corporate and VPN egress ranges blocks logins from anywhere else, even when valid credentials are stolen
- Network-layer restrictions add a control independent of password and MFA strength, raising the bar for remote attackers
- Tighter restrictions on admin accounts shrink the exposed surface for the most powerful identities
- Reduces the value of phished or leaked credentials, since they cannot be used from attacker-controlled infrastructure
Attack Prevented: Credential stuffing from untrusted networks, remote account takeover, session hijacking
ClickOps Implementation
Step 1: Configure IP Allowlist
- Navigate to: Administration → User Management → Allowed IPs
- Add corporate network IPs
- Add VPN egress IPs
Step 2: Apply to User Accounts
- Configure IP restrictions per user
- Apply stricter restrictions to admins
- Test access restrictions
1.5 Govern API External IDs for Programmatic Access
Profile Level: L2 (Walk)
| Framework | Control |
|---|---|
| CIS Controls | 5.4, 6.7 |
| NIST 800-53 | IA-2, IA-5 |
Description
Assign and govern the per-user API External ID, the field that maps a Qualys user account to an external identity so the platform can accept OAuth/OIDC JWT-based API authentication for that user. Treat each External ID as a named, owned, revocable programmatic credential rather than a convenience setting.
Rationale
Why This Matters:
- API access to Qualys carries the same authority as the console user it is bound to, so an unscoped or over-privileged API user exposes the entire vulnerability inventory programmatically
- Mapping API identity to an external IdP subject moves API authentication behind the same lifecycle as human accounts, so a departed employee’s or decommissioned integration’s access dies with the IdP identity instead of living on as a static credential
- The External ID is case-sensitive and accepts alphanumeric strings, email addresses, or custom identifiers, which makes near-miss values easy to introduce and hard to audit unless a naming convention is enforced
- Recording an owner for every API-enabled account is what makes revocation possible during an incident; unattributed integration accounts are the ones that survive credential rotations
Attack Prevented: Orphaned integration credentials, unattributed API access, privilege escalation through over-scoped API users, persistence via API identity after IdP deprovisioning
ClickOps Implementation
Step 1: Set the External ID on the API user
- Navigate to: Users → New → Users → General Information
- Populate the API External ID field with the external identity that will present the JWT
- Enter the value exactly — the field is case-sensitive, and alphanumeric strings, email addresses, and custom identifiers are all accepted
Step 2: Scope the account to least privilege
- Assign the API user the narrowest role its integration actually requires (see 1.3) — never the Manager role by default
- Create one API user per integration so a single revocation does not break unrelated automation
- Apply IP restrictions (see 1.4) to API users whose callers have fixed egress addresses
Step 3: Record ownership and review
- Document the named human owner, the consuming system, and the business justification for every account carrying an External ID
- Re-verify External ID values against the IdP during access reviews — a stale or mistyped mapping either breaks the integration or silently binds it to the wrong identity
- Clear the External ID and disable the account when the integration is retired
1.6 Monitor Activity and Change Logs
Profile Level: L1 (Crawl)
| Framework | Control |
|---|---|
| CIS Controls | 8.2, 8.5 |
| NIST 800-53 | AU-2, AU-6, AU-11 |
Description
Review the Qualys Activity Log for authentication events and the QID change log for detection-content changes, and export both to your SIEM so platform abuse is detected rather than merely recorded.
Rationale
Why This Matters:
- The Activity Log records each login attempt with its success or failure state, the failure reason, the source IP address, the user agent, and the timestamp — enough detail to distinguish a forgotten password from credential stuffing against the subscription
- Source IP and user agent are what turn a failed-login count into an investigable event, since a spray from unfamiliar infrastructure looks nothing like a user fumbling MFA
- The QID change log records both user-initiated and system-initiated changes along with the username responsible and retains two years of history, which is what lets an auditor prove that a detection was not quietly suppressed
- Logs that live only in the console are reviewed only after an incident is already known; forwarding them to the SIEM is what makes alerting on anomalous logins possible in the first place
Attack Prevented: Undetected credential stuffing, unauthorized configuration change, detection tampering, insider abuse of vulnerability data
ClickOps Implementation
Step 1: Review authentication activity
- Navigate to: Administration → Activity Log
- Filter for login events and review the success/failure state, failure reason, source IP address, user agent, and timestamp on each
- Investigate repeated failures against a single account, and any success from an IP range outside your allowlist (see 1.4)
Step 2: Review detection-content changes
- Open the QID change log and review entries for both user-initiated and system-initiated changes
- Confirm each user-initiated change is attributable to a named administrator and matches an approved request
- Two years of change history are retained — use it to evidence detection continuity during audits
Step 3: Export and alert
- Export or stream Activity Log data to your SIEM for retention beyond the console’s window
- Alert on failed-login bursts, logins from unexpected source IPs or user agents, role changes, and API user creation
- Re-verify the export after any subscription or user-management change
2. Scanning Configuration
2.1 Secure Scan Credentials
Profile Level: L1 (Crawl)
| Framework | Control |
|---|---|
| CIS Controls | 3.11 |
| NIST 800-53 | SC-12 |
Description
Securely manage credentials used for authenticated scanning.
Rationale
Why This Matters:
- Scan credentials have privileged access
- Compromised credentials can expose infrastructure
- Qualys encrypts credentials but proper management is critical
Attack Prevented: Scan-credential theft, privilege escalation via over-permissioned scan accounts, lateral movement from a compromised scanner, long-lived static secrets
ClickOps Implementation
Step 1: Create Dedicated Scan Accounts
- Create dedicated service accounts for scanning
- Grant minimum required permissions:
- Read access for vulnerability scanning
- Admin only if compliance required
- Do not use admin/root accounts
Step 2: Configure Credential Vaults
- Navigate to: Scans → Authentication → Vault
- Configure a supported credential vault so Qualys retrieves secrets at scan time instead of storing them:
- CyberArk PIM Suite
- CyberArk AIM
- Thycotic Secret Server
- HashiCorp Vault
- Azure Key Vault
- Quest Vault
- One Identity Safeguard (NSX)
- Retrieve credentials dynamically
Step 3: Rotate Credentials
- Establish rotation schedule
- Update credentials in Qualys
- Verify scanning still works
Code Pack: Sigma Detection Rule
detection:
selection:
Action|contains:
- 'Credential Created'
- 'Credential Updated'
- 'Credential Deleted'
- 'Authentication Record Created'
- 'Authentication Record Updated'
- 'Authentication Record Deleted'
condition: selection
fields:
- Date
- User
- Action
- Details
2.2 Configure Scan Options
Profile Level: L1 (Crawl)
| Framework | Control |
|---|---|
| CIS Controls | 7.1 |
| NIST 800-53 | RA-5 |
Description
Configure appropriate scan options for comprehensive coverage.
Rationale
Why This Matters:
- Comprehensive, well-tuned option profiles ensure full port and service coverage so vulnerabilities are not missed and left exposed
- Purpose-built profiles (authenticated, PCI) produce accurate findings that drive correct remediation priorities
- Scheduling scans outside peak windows prevents accidental disruption of production systems while preserving coverage
- Incomplete or misconfigured scans create blind spots that attackers exploit before defenders are aware of them
Attack Prevented: Undetected exposed services, coverage gaps, exploitation of unscanned assets
ClickOps Implementation
Step 1: Configure Scan Profiles
- Navigate to: Scans → Option Profiles
- Create profiles for different use cases:
- Full vulnerability scan
- Authenticated scan
- PCI compliance scan
Step 2: Configure Scan Settings
- Configure appropriate settings:
- Port ranges
- Performance settings
- Authentication type
- Balance thoroughness with impact
Changed default — On-Host Script Execution (Platform 10.39.1, July 2026): the option-profile checkbox Allow the scanner to execute local scripts on target hosts ships disabled by default. Enabling it requires BOTH the option-profile setting and a Windows NT authentication record, and it applies to vulnerability-management scans only (Policy Audit and PCI scans are unaffected). Leave it disabled. Enabling it grants the scanner remote script execution — effectively PowerShell — on every authenticated Windows target in scope, turning a scan credential compromise into fleet-wide code execution. If a specific assessment genuinely requires it, enable it on a dedicated option profile scoped to a named asset group, not on your standard profiles. Source: VM/VMDR Platform 10.39.1 release notes.
Step 3: Schedule Scans
- Configure scan schedules
- Avoid production impact times
- Ensure full coverage
Code Pack: API Script
# List all scan option profiles and check for hardened configuration
PROFILES_XML=$(ql_get "/scan/option_profile/?action=list" 2>/dev/null) || {
fail "2.2 Failed to retrieve scan option profiles"
increment_failed
summary
exit 1
}
PROFILE_COUNT=$(echo "${PROFILES_XML}" | xml_count "OPTION_PROFILE")
info "2.2 Found ${PROFILE_COUNT} scan option profile(s)"
# Check each profile for vulnerability detection settings
# A hardened profile should have:
# - TCP and UDP scanning enabled
# - Authentication scanning enabled
# - All port ranges covered (1-65535)
echo "${PROFILES_XML}" | grep -oP "<TITLE>\K[^<]+" | while read -r title; do
info "2.2 Profile: ${title}"
done
# List recent scans to verify scanning is active and not stale
SCANS_XML=$(ql_get "/scan/?action=list" 2>/dev/null) || {
warn "2.2 Failed to retrieve scan list"
SCANS_XML=""
}
if [ -n "${SCANS_XML}" ]; then
SCAN_COUNT=$(echo "${SCANS_XML}" | xml_count "SCAN")
info "2.2 Found ${SCAN_COUNT} scan(s) in history"
# Check for scans in the last 30 days
RECENT_SCANS=$(echo "${SCANS_XML}" | grep -c "<STATUS>Finished</STATUS>" || echo "0")
if [ "${RECENT_SCANS}" -gt 0 ]; then
pass "2.2 ${RECENT_SCANS} completed scan(s) found"
else
warn "2.2 No recently completed scans -- verify scan scheduling"
fi
fi
2.3 Configure Agent Security
Profile Level: L1 (Crawl)
| Framework | Control |
|---|---|
| CIS Controls | 7.1 |
| NIST 800-53 | RA-5 |
Description
Securely configure Qualys Cloud Agents.
Rationale
Why This Matters:
- Secure agent distribution and integrity verification prevent attackers from deploying tampered or rogue agents into the environment
- Protecting activation keys stops unauthorized hosts from enrolling and impersonating managed assets
- Monitoring agent health surfaces disconnected or disabled agents that would otherwise create silent coverage gaps
- Compromised or spoofed agents could feed false telemetry and hide real vulnerabilities from the platform
Attack Prevented: Rogue agent enrollment, activation-key abuse, telemetry tampering, coverage evasion
ClickOps Implementation
Step 1: Secure Agent Deployment
- Use secure distribution methods
- Deploy with endpoint management
- Verify agent integrity
Step 2: Configure Agent Settings
- Navigate to: Agents → Agent Configuration
- Configure:
- Activation key security
- Communication intervals
- Local scanning options
Step 3: Monitor Agent Status
- Monitor agent health
- Alert on disconnected agents
- Investigate failed deployments
3. Policy Compliance
Compliance assessment on the Enterprise TruRisk Platform spans two apps: the long-standing Policy Compliance app and Policy Audit, which Qualys now ships alongside it. The controls below apply to whichever app your subscription entitles; console paths differ between them, so confirm the path in your own tenant before scripting against it. Policy Audit 1.13 added a policy changelog that records control-level additions, modifications, and deletions within a policy — review it alongside the platform Activity Log (see 1.6) so a weakened baseline is caught as a change event rather than as a suddenly improved compliance score. Source: Policy Audit 1.13 release notes.
3.1 Configure CIS Benchmark Assessments
Profile Level: L2 (Walk)
| Framework | Control |
|---|---|
| CIS Controls | 4.1 |
| NIST 800-53 | CM-6 |
Description
Configure Policy Compliance or Policy Audit to assess systems against CIS Benchmark baselines on a schedule.
Rationale
Why This Matters:
- CIS Benchmarks encode the hardening settings that attackers most reliably exploit when left at their defaults, so assessing against them turns a hardening intention into a measurable state
- Automated, scheduled benchmark assessment catches drift between change windows, where manual review only ever produces a point-in-time snapshot
- Benchmark results give remediation teams a prioritized, vendor-neutral list of concrete settings rather than an abstract instruction to “harden the fleet”
- Documented exceptions keep deliberate deviations visible and reviewable instead of indistinguishable from unnoticed misconfiguration
Attack Prevented: Exploitation of insecure defaults, configuration drift, undocumented hardening exceptions, compliance gaps
ClickOps Implementation
Step 1: Enable Policy Compliance
- Navigate to: Policy Compliance → Policies (or the equivalent Policy Audit policy list)
- Review available CIS benchmarks
- Select appropriate benchmarks for your environment
Step 2: Configure Compliance Profiles
- Create compliance profile
- Select CIS benchmark (Level 1 or Level 2)
- Configure exceptions if needed
Step 3: Run Compliance Scan
- Schedule compliance assessments
- Review compliance reports
- Prioritize remediation
3.2 Configure DISA STIG Assessments
Profile Level: L2 (Walk)
| Framework | Control |
|---|---|
| CIS Controls | 4.1 |
| NIST 800-53 | CM-6 |
Description
Configure DISA STIG assessments for government compliance.
Rationale
Why This Matters:
- Automated STIG assessment continuously verifies systems against mandated DoD hardening baselines instead of relying on manual point-in-time checks
- Detecting configuration drift early closes the misconfigurations that attackers most often exploit for initial access and persistence
- Documented findings and exceptions provide the evidence trail required for government and regulated-environment audits
- Unassessed STIG gaps leave known-weak default settings in place across the estate
Attack Prevented: Exploitation of insecure configurations, configuration drift, compliance gaps
ClickOps Implementation
Step 1: Select STIG Templates
- Navigate to: Policy Compliance → Templates
- Select DISA STIG templates:
- Operating systems
- Databases
- Network devices
- Applications
Step 2: Create Compliance Policy
- Create policy from STIG template
- Configure applicable findings
- Document exceptions
Step 3: Assess and Remediate
- Run STIG assessments
- Generate compliance reports
- Track remediation progress
3.3 Configure Security Configuration Assessment
Profile Level: L2 (Walk)
| Framework | Control |
|---|---|
| CIS Controls | 4.1 |
| NIST 800-53 | CM-6 |
Description
Use Qualys SCA for automated configuration assessment.
Rationale
Why This Matters:
- Automated, continuous configuration assessment catches hardening regressions far faster than periodic manual reviews
- Prioritizing findings by severity directs remediation effort to the misconfigurations that pose the greatest real risk
- Automated alerting ensures newly introduced weak configurations are flagged before they can be exploited
- Misconfigurations are among the most common root causes of breaches, and SCA makes them visible and measurable
Attack Prevented: Security misconfiguration, hardening drift, exploitation of insecure defaults
ClickOps Implementation
Step 1: Enable SCA
- Navigate to: Vulnerability Management → SCA
- Enable Security Configuration Assessment
Step 2: Configure SCA Profiles
- Select benchmark profiles
- Configure assessment frequency
- Enable automated alerting
Step 3: Review Results
- Review configuration findings
- Prioritize by severity
- Track hardening progress
4. Asset Management
4.1 Configure Asset Discovery
Profile Level: L1 (Crawl)
| Framework | Control |
|---|---|
| CIS Controls | 1.1 |
| NIST 800-53 | CM-8 |
Description
Configure comprehensive asset discovery for visibility.
Rationale
Why This Matters:
- You cannot protect or scan assets you do not know exist, so comprehensive discovery eliminates blind spots in coverage
- Combining network, cloud, agent, and passive discovery catches shadow IT and rogue devices that bypass standard provisioning
- Automated tagging enables accurate scan targeting so no asset class is silently excluded from assessment
- Alerting on new and unmanaged assets shortens the window in which an unmonitored device can be attacked
Attack Prevented: Shadow IT exposure, unmanaged-asset compromise, scanning blind spots
ClickOps Implementation
Step 1: Configure Discovery Methods
- Navigate to: Assets → Asset Discovery
- Configure:
- Network scanning
- Cloud connectors
- Agent deployment
- Passive discovery
Step 2: Configure Asset Tagging
- Create asset tags for organization
- Apply tags automatically
- Use tags for scan targeting
Step 3: Monitor for Rogue Assets
- Configure alerts for new assets
- Flag unmanaged devices
- Integrate with ITSM
Code Pack: API Script
# Retrieve asset host list and check inventory health
HOSTS_XML=$(ql_get "/asset/host/?action=list&truncation_limit=0" 2>/dev/null) || {
fail "4.1 Failed to retrieve host list"
increment_failed
summary
exit 1
}
TOTAL_HOSTS=$(echo "${HOSTS_XML}" | xml_count "HOST")
info "4.1 Total hosts in inventory: ${TOTAL_HOSTS}"
# Check for hosts with no last scan date (never scanned)
UNSCANNED=$(echo "${HOSTS_XML}" | grep -c "<LAST_VULN_SCAN_DATETIME/>" || echo "0")
if [ "${UNSCANNED}" -gt 0 ]; then
warn "4.1 ${UNSCANNED} host(s) have never been vulnerability scanned"
else
pass "4.1 All hosts have been scanned at least once"
fi
# Use v3 API to check asset tagging for organization
TAGS_JSON=$(ql_v3_get "/get/am/tag" 2>/dev/null) || {
warn "4.1 Failed to retrieve asset tags (v3 API)"
TAGS_JSON=""
}
if [ -n "${TAGS_JSON}" ]; then
TAG_COUNT=$(echo "${TAGS_JSON}" | grep -oP '"count"\s*:\s*\K[0-9]+' | head -1 || echo "0")
info "4.1 Asset tags defined: ${TAG_COUNT}"
if [ "${TAG_COUNT}" -lt 1 ]; then
warn "4.1 No asset tags defined -- create tags to organize assets by environment/criticality"
else
pass "4.1 Asset tagging is configured (${TAG_COUNT} tag(s))"
fi
fi
# Check for hosts with active detections to verify scanning coverage
DETECTIONS_XML=$(ql_get "/asset/host/vm/detection/?action=list&truncation_limit=10" 2>/dev/null) || {
warn "4.1 Failed to retrieve host detections"
DETECTIONS_XML=""
}
if [ -n "${DETECTIONS_XML}" ]; then
DETECTION_COUNT=$(echo "${DETECTIONS_XML}" | xml_count "DETECTION")
info "4.1 Sample detection count: ${DETECTION_COUNT}"
if [ "${DETECTION_COUNT}" -gt 0 ]; then
pass "4.1 Vulnerability detections present -- scanning is active"
else
warn "4.1 No detections found -- verify scanner appliances are functioning"
fi
fi
4.2 Configure Cloud Connector Security
Profile Level: L1 (Crawl)
| Framework | Control |
|---|---|
| CIS Controls | 1.1 |
| NIST 800-53 | CM-8 |
Description
Securely configure cloud provider connectors.
Rationale
Why This Matters:
- Granting connectors only the minimum read permissions limits what an attacker can reach if the integration is compromised
- Scoped IAM roles, app registrations, and service accounts prevent the connector from becoming a path to broader cloud control-plane access
- Cross-account and least-privilege configuration contains the blast radius of any single leaked connector credential
- Over-permissioned cloud connectors are a high-value pivot point into the entire cloud environment
Attack Prevented: Cloud credential abuse, excessive-permission pivot, lateral movement into cloud accounts
ClickOps Implementation
Step 1: AWS Connector
- Navigate to: Assets → Connectors → AWS
- Create IAM role with minimum permissions
- Configure cross-account access
Step 2: Azure Connector
- Create app registration
- Grant minimum required permissions
- Configure connector
Step 3: GCP Connector
- Create service account
- Grant minimum roles
- Configure connector
Code Pack: API Script
# Search for cloud assets via the v3 Asset Management API
# Cloud connectors (AWS, Azure, GCP) sync assets automatically
CLOUD_ASSETS=$(ql_v3_post "/search/am/asset" '{
"filters": [
{
"field": "sourceCategory",
"operator": "IN",
"value": "cloud"
}
],
"preferences": {
"startFromOffset": 0,
"limitResults": 10
}
}' 2>/dev/null) || {
warn "4.2 Failed to query cloud assets (v3 API)"
CLOUD_ASSETS=""
}
if [ -n "${CLOUD_ASSETS}" ]; then
CLOUD_COUNT=$(echo "${CLOUD_ASSETS}" | grep -oP '"count"\s*:\s*\K[0-9]+' | head -1 || echo "0")
info "4.2 Cloud-sourced assets: ${CLOUD_COUNT}"
if [ "${CLOUD_COUNT}" -gt 0 ]; then
pass "4.2 Cloud connectors are active (${CLOUD_COUNT} assets synced)"
else
warn "4.2 No cloud assets found -- configure AWS/Azure/GCP connectors"
fi
fi
# Check activity log for recent connector sync events
ACTIVITY_XML=$(ql_get "/activity_log/?action=list&truncation_limit=50" 2>/dev/null) || {
warn "4.2 Failed to retrieve activity log"
ACTIVITY_XML=""
}
if [ -n "${ACTIVITY_XML}" ]; then
# Look for cloud connector-related activity
CONNECTOR_EVENTS=$(echo "${ACTIVITY_XML}" | grep -ci "connector\|cloud\|aws\|azure\|gcp" || echo "0")
info "4.2 Cloud connector activity events (last 50): ${CONNECTOR_EVENTS}"
if [ "${CONNECTOR_EVENTS}" -gt 0 ]; then
pass "4.2 Recent cloud connector activity detected"
else
warn "4.2 No recent cloud connector activity -- verify connectors are scheduled"
fi
fi
# Identify cloud assets that have not been scanned
UNSCANNED_CLOUD=$(ql_v3_post "/search/am/asset" '{
"filters": [
{
"field": "sourceCategory",
"operator": "IN",
"value": "cloud"
},
{
"field": "lastVulnScan",
"operator": "NONE",
"value": ""
}
],
"preferences": {
"startFromOffset": 0,
"limitResults": 10
}
}' 2>/dev/null) || {
UNSCANNED_CLOUD=""
}
if [ -n "${UNSCANNED_CLOUD}" ]; then
UNSCANNED_COUNT=$(echo "${UNSCANNED_CLOUD}" | grep -oP '"count"\s*:\s*\K[0-9]+' | head -1 || echo "0")
if [ "${UNSCANNED_COUNT}" -gt 0 ]; then
warn "4.2 ${UNSCANNED_COUNT} cloud asset(s) have not been vulnerability scanned"
else
pass "4.2 All cloud assets have been scanned"
fi
fi
4.3 Configure Approval Workflows
Profile Level: L2 (Walk)
| Framework | Control |
|---|---|
| CIS Controls | 4.1 |
| NIST 800-53 | CM-3 |
Description
Configure approval workflows for automated remediation.
Rationale
Why This Matters:
- Requiring approval before automated remediation prevents unreviewed changes from disrupting production systems
- Maintenance windows and risk thresholds ensure high-impact actions only execute under controlled conditions
- Defined approvers, escalation, and timeout actions create accountability and an auditable change trail
- Unconstrained automated actions could be abused or misfire to cause outages or mask malicious changes
Attack Prevented: Unauthorized automated changes, change-control bypass, remediation-driven outages
ClickOps Implementation
Step 1: Configure Workflows
- Navigate to: Administration → Workflows
- Configure approval requirements:
- Maintenance windows
- Risk level thresholds
- Automated vs. manual actions
Step 2: Set Approval Roles
- Define approvers
- Configure escalation
- Set timeout actions
5. Compliance Quick Reference
SOC 2 Trust Services Criteria Mapping
| Control ID | Qualys Control | Guide Section |
|---|---|---|
| CC6.1 | SSO/MFA | 1.1 |
| CC6.2 | RBAC | 1.3 |
| CC6.6 | IP restrictions | 1.4 |
| CC7.1 | Vulnerability scanning | 2.2 |
| CC7.2 | Configuration assessment | 3.3 |
NIST 800-53 Rev 5 Mapping
| Control | Qualys Control | Guide Section |
|---|---|---|
| IA-2 | SSO | 1.1 |
| IA-2(1) | MFA | 1.2 |
| RA-5 | Vulnerability scanning | 2.2 |
| CM-6 | Configuration assessment | 3.1 |
| CM-8 | Asset discovery | 4.1 |
Appendix A: References
Official Qualys Documentation:
- Qualys Documentation — Enterprise TruRisk Platform documentation index
- VM/VMDR Platform 10.39.1 Release Notes — On-Host Script Execution default, API External ID, Activity Log detail
- Policy Audit 1.13 Release Notes — policy changelog
- Get Started with VM/VMDR
- Scanning Basics
- VMDR Datasheet
- VMDR Complete Advantage Blog
- Policy Compliance Datasheet
- Security Configuration Assessment Guide (PDF)
API & Developer Resources:
Security Incidents:
- Accellion FTA Breach (2021): Qualys confirmed data was accessed via a zero-day vulnerability in the Accellion FTA file transfer appliance used by Qualys. Production environments and customer data on the Qualys Cloud Platform were not affected.
- Salesloft/Drift Supply Chain Attack (September 2025): Attackers exfiltrated OAuth tokens from breached Salesloft/Drift infrastructure and accessed some data in Qualys’s Salesforce environment (leads and contacts). No impact to Qualys production environments, codebase, or customer platform data. Mandiant was engaged for investigation.
Changelog
| Date | Version | Maturity | Changes | Author |
|---|---|---|---|---|
| 2026-08-08 | 0.2.0 | draft | Currency pass: Enterprise TruRisk Platform / Policy Audit naming; new 1.5 API External ID and 1.6 activity and change logging; On-Host Script Execution changed-default callout in 2.2; corrected credential-vault list in 2.1; removed unsourced claims and added Attack Prevented in 3.1, 1.2, 2.1; dropped compliance-badge reference. Tier 3/4 research sweep out of scope this pass | Claude Code (Opus 4.8) |
| 2026-06-29 | 0.1.1 | draft | Add cheat-sheet Description and Rationale for all controls | Claude Code (Opus 4.8) |
| 2025-02-05 | 0.1.0 | draft | Initial guide with access controls, scanning, and policy compliance | Claude Code (Opus 4.5) |
Contributing
Found an issue or want to improve this guide?
- Report outdated information: Open an issue with tag
content-outdated - Propose new controls: Open an issue with tag
new-control - Submit improvements: See Contributing Guide