Output Format

Each scan result includes:

Common Fields

  • result_type: Always "scan"
  • plugin_id: "qualys-totalcloud-plugin"
  • plugin_version: Plugin version string
  • type: Resource type (cert, pubkey, privkey, symkeysecret)
  • timestamp: ISO8601 scan timestamp with timezone
  • urn: Unique resource identifier (format depends on type)
  • url: Cloud provider console URL for the resource
  • cert_pem: Base64-encoded certificate body (certificates only)

URN Formats

  • Certificates: urn:cert:sha256:<sha256-fingerprint> (when PEM available) or urn:cert:<cloud>:<account>:<resource-id>
  • Public Keys: urn:pubkey:sha256:<sha256-fingerprint> (when key material available) or urn:pubkey:<cloud>:<account>:<resource-id>
  • Secrets (including KMS keys, Key Vault keys, and other identifier-only key references): urn:secret:name:<name>:<version>

Extra Fields (Cloud-Specific Metadata)

AWS:

  • platform_type: "aws"
  • account_id: AWS account identifier
  • region: AWS region (e.g., "us-east-1")
  • resource_type: Qualys resource type (e.g., "SECRETS", "KMS_KEY")
  • arn: AWS ARN (when available)
  • control_id: Compliance control identifier (Evaluations API)
  • service: Service name (e.g., "ACM", "KMS", "Secrets Manager")
  • Service-specific fields: name, key_id, algorithm, key_usage, rotation, etc.

Azure:

  • platform_type: "azure"
  • subscription_id: Azure subscription identifier
  • resource_type: Qualys resource type (e.g., "SQL_SERVER", "KEY_VAULT_KEY")
  • location: Azure region (e.g., "eastus")
  • control_id: Compliance control identifier (Evaluations API)
  • service: Service name (e.g., "Key Vault", "Application Gateway")
  • Service-specific fields: vault_name, key_name, cert_name, name, server_name, etc.

GCP:

  • platform_type: "gcp"
  • project_id: GCP project identifier
  • resource_type: Qualys resource type
  • control_id: Compliance control identifier
  • service: Service name (e.g., "Cloud KMS", "Secret Manager")
  • Service-specific fields: key_name, name, algorithm, purpose, etc.

Example Output

{
  "result_type": "scan",
  "plugin_id": "qualys-totalcloud-plugin",
  "plugin_version": "0.0.1",
  "type": "cert",
  "timestamp": "2026-02-18T14:22:00-05:00",
  "urn": "urn:cert:sha256:a1b2c3d4e5f6...",
  "url": "https://console.aws.amazon.com/acm/home?region=us-east-1#/certificates/abc123",
  "cert_pem": "MIIFjDCCA3SgAwIBAgIS...",
  "extra": {
    "platform_type": "aws",
    "account_id": "123456789012",
    "region": "us-east-1",
    "resource_type": "ACM_CERTIFICATE",
    "domain_name": "example.com",
    "status": "ISSUED",
    "in_use": true
  }
}

Resource Type Classification

The plugin applies intelligent classification based on:

  1. Qualys Resource Type: Primary indicator (e.g., KMS_KEY, KEY_VAULT_CERTIFICATE)
  2. Service Context: Service name influences classification (e.g., AWS KMS → keys, Azure Key Vault → keys/certs/secrets)
  3. Control Name Keywords: Keywords in compliance control names (e.g., "certificate", "encryption key", "secret")
  4. Resource ID Structure: Path analysis for Azure/GCP resource IDs (e.g., /keys/, /secrets/, /certificates/)

Classification Logic:

  • Certificates: ACM certificates, IAM server certificates, Application Gateway SSL certs, load balancer listener certs
  • Secrets: Secrets Manager secrets, AWS KMS keys (identifier only — Qualys returns no key material or KeySpec), Azure Key Vault keys (identifier only — Qualys returns no kty/key_ops), Key Vault secrets, connection strings, API keys, credentials, Route 53 DNSSEC keys (identifier only), Azure Storage Account encryption metadata, Azure CosmosDB encryption metadata

Expanding Coverage

To discover more crypto assets:

  1. Configure Cloud Connectors: Add AWS accounts, Azure subscriptions, or GCP projects in Qualys CloudView
  2. Enable Services: Ensure crypto-related services are enabled in your cloud environments (KMS, Key Vault, Secret Manager, ACM, etc.)
  3. Run Compliance Scans: Qualys evaluates controls automatically; plugin discovers assets from evaluation results
  4. No Plugin Changes Needed: All cloud resources sync automatically to Qualys CloudView

Error Handling

Errors include error_type (machine-readable), error_message (user-facing), and error_details (diagnostic).

Common error types:

  • JSON_PARSE_ERROR: Invalid JSON input
  • JSON_VALIDATION_ERROR: Configuration doesn't match schema
  • CONNECT_ERROR: Cannot connect to Qualys API or authentication failed
  • NETWORK_ERROR: Network connectivity issues

API Behaviour and Constraints

API Constraints:

  • Rate Limiting Resilience: The Qualys CloudView API may throttle requests (HTTP 429) during large scans or when request rate is high. The plugin automatically handles this by retrying up to 5 times with exponential backoff (1s, 2s, 4s, 8s delays between attempts, ~15 seconds total per endpoint). This retry limit is a defensive circuit breaker to prevent wasting scan time on struggling endpoints—the Qualys API continues returning 429 regardless of retry count, so after 5 failures, the plugin skips that resource, logs a warning, and continues scanning others. For large environments (1000+ resources) or high-frequency scans, rate limiting may occur; this is expected Qualys API behavior. Consider adjusting scan schedules or consulting Qualys documentation on rate limits for your account tier.
  • Discovery timing depends on Qualys's compliance evaluation schedule (not real-time): The plugin discovers resources from Qualys's most recent compliance evaluation results, not directly from cloud providers. For example, if Qualys evaluates CIS controls daily at 2:00 AM, a certificate created at 10:00 AM won't appear in scan results until after the next evaluation run (after 2:00 AM the following day). Incremental scans use lastScanDate to filter by Qualys evaluation timestamps, so if Qualys re-evaluates resources after that timestamp, those resources will be returned even if the underlying cloud resources did not change.
  • Assets must be visible in Qualys CloudView to be discovered: This plugin retrieves data from Qualys CloudView's inventory and compliance evaluations. If cloud provider connectors are not configured, accounts/subscriptions/projects are not added to CloudView, or proper permissions are not granted, resources will not appear in scan results. Ensure connectors are active and syncing before running scans.

Cloud Provider Coverage:

  • AWS: Full Inventory + Evaluations API coverage for 10 resource types
  • Azure: Full Inventory + Evaluations API coverage for 7 resource types
  • GCP: Evaluations API only (Inventory API doesn't include Cloud KMS, Secret Manager, Certificate Manager)
  • OCI: Not currently supported

Resource Identification:

  • Certificates/public keys use SHA256 fingerprint URNs when PEM/key material is available
  • When material unavailable, URNs use cloud provider resource identifiers
  • Private keys and symmetric keys never include key material (security best practice)

Certificate Data Limitations:

  • Qualys CloudView API provides certificate metadata (domain names, expiration, status) but often does not include full PEM-encoded certificate bodies
  • When PEM data is unavailable, the plugin generates URNs using cloud provider identifiers (account ID + resource ID)
  • This is a Qualys API limitation, not a plugin limitation
  • To obtain full certificate details, use cloud provider-native APIs (AWS SDK, Azure SDK, GCP SDK) or other specialized certificate discovery plugins

Data Completeness

Qualys TotalCloud is a cloud security posture management (CSPM) tool — it monitors compliance and vulnerability posture across cloud environments rather than managing cryptographic assets directly. This has two important implications for discovered data:

Why certificate coverage is slim

TotalCloud does not focus on certificate lifecycle management. Certificates are only surfaced incidentally when they appear in compliance controls (e.g., ACM certificates attached to CloudFront distributions). For comprehensive certificate discovery, use dedicated plugins such as aws-certmanager-plugin or azure-keyvault-plugin.

Why metadata is sparser than dedicated plugins

Dedicated plugins (e.g., aws-kms-plugin, azure-keyvault-plugin) call asset-specific APIs and return rich metadata — key algorithms, rotation policies, expiry dates, HSM backing, etc. TotalCloud's evaluations API only returns what is needed to assess compliance posture: resource identifiers, control status, and basic properties. It reports how compliant a resource is, not what the resource contains.

Why secrets and keys have broader coverage

IAM keys, KMS keys, Key Vault secrets/keys, and service account credentials are directly relevant to cloud compliance posture, so TotalCloud surfaces these more consistently across cloud providers.

Building and Testing

# Build
cd go-modules/qualys-totalcloud-plugin
make build

# Run unit tests
make test

# Run integration tests (requires mock server)
make integration-test

# Lint
make lint          # Fast (development)
make lint-full     # Comprehensive (pre-commit)

Security Best Practices

  • Credentials: Mark password as writeOnly in schema for UI masking
  • Service Accounts: Use dedicated read-only Qualys accounts
  • State Security: State contains only timestamps, no sensitive data
  • API Tokens: Plugin authenticates per-scan; tokens not persisted
  • Cloud Permissions: Follow least-privilege principle for Qualys cloud connectors

Troubleshooting

No Resources Discovered

  • Check Cloud Connectors: Verify at least one cloud connector is configured and active in Qualys CloudView
  • Verify Permissions: Ensure Qualys account has CloudView API and TotalCloud module access
  • Run Compliance Scans: Qualys must evaluate controls before assets appear in Evaluations API
  • Check Services: Ensure crypto services (KMS, Key Vault, Secrets Manager, ACM) are deployed in your cloud environments

Authentication Failures

  • Verify Gateway URL: Ensure URL matches your Qualys platform (qg1, qg2, qg3, or private cloud)
  • Check Credentials: Username/password must be valid Qualys user credentials
  • API Access: Confirm API access is enabled for the Qualys account

Incremental Scan Returns All Resources

  • First Scan: Normal behavior when no state provided (full scan)
  • Qualys Re-Evaluation: If Qualys runs compliance evaluations on all resources between scans, all resources will match the time filter—this is expected behavior, not a bug
  • Evaluation Schedule: Incremental scanning filters by Qualys's evaluation timestamps (evaluatedOn for Evaluations API, updated for Inventory API), not by actual resource modification dates
  • Check State: Verify state with lastScanDate is being passed to plugin
  • Wait Between Scans: Running scans too frequently (e.g., every minute) may always return full results if Qualys evaluates on a longer schedule (e.g., hourly)

Slow Scans

  • Large Inventories: Scans with hundreds of controls and thousands of resources may take several minutes
  • API Rate Limits: Qualys may throttle requests; plugin respects API rate limits
  • Network Latency: Consider network connectivity between plugin runner and Qualys Gateway

References