Wiz Hardening Guide
Cloud security platform hardening for connector security and RBAC controls
Overview
Wiz provides agentless cloud security to 40-50% of Fortune 100 through API access to cloud environments. While the agentless architecture minimizes agent-based risks, OAuth tokens and cloud connector credentials could expose comprehensive cloud security posture data and SBOM information across major financial institutions and enterprises. Wiz’s deep visibility into cloud configurations makes it a high-value target.
Intended Audience
- Security engineers managing CSPM tools
- Cloud security architects
- GRC professionals assessing cloud security
- Third-party risk managers evaluating security tools
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 Wiz-specific security configurations including authentication, cloud connector security, API access controls, and data protection.
Table of Contents
- Authentication & Access Controls
- Cloud Connector Security
- API Security
- Data Security
- Monitoring & Detection
- Compliance Quick Reference
1. Authentication & Access Controls
1.1 Enforce SSO with MFA
Profile Level: L1 (Baseline) NIST 800-53: IA-2(1)
Description
Require SAML SSO with MFA for all Wiz console access.
Rationale
Why This Matters:
- Wiz has visibility into all cloud infrastructure
- Compromised access exposes vulnerability data
- Attack planning facilitated by exposed security posture
Attack Scenario: Compromised OAuth token reveals infrastructure vulnerabilities and misconfigurations across customer’s entire cloud estate.
ClickOps Implementation
Step 1: Configure SAML SSO
- Navigate to: Settings → Authentication → SAML Configuration
- Configure:
- IdP Entity ID: From your identity provider
- SSO URL: IdP login endpoint
- Certificate: Upload IdP certificate
- Enable: Enforce SAML authentication
Step 2: Disable Local Accounts
- Navigate to: Settings → Authentication
- Disable: Allow local authentication
- Keep 1 break-glass account (documented, monitored)
Step 3: Configure Session Security
- Navigate to: Settings → Authentication → Session Settings
- Configure:
- Session timeout: 4 hours
- Idle timeout: 30 minutes
Code Implementation
Code Pack: Terraform
# Configure SAML SSO identity provider for Wiz console access
resource "wiz_saml_idp" "corporate_sso" {
count = var.saml_login_url != "" ? 1 : 0
name = var.saml_idp_name
login_url = var.saml_login_url
certificate = var.saml_certificate
issuer_url = var.saml_issuer_url != "" ? var.saml_issuer_url : var.saml_login_url
logout_url = var.saml_logout_url != "" ? var.saml_logout_url : null
use_provider_managed_roles = false
allow_manual_role_override = false
}
1.2 Implement Role-Based Access Control
Profile Level: L1 (Baseline) NIST 800-53: AC-3, AC-6
Description
Configure Wiz roles with least-privilege access.
ClickOps Implementation
Step 1: Define Role Strategy
| Role | Permissions |
|---|---|
| Admin | Full platform access (limit to 2-3) |
| Security Analyst | View issues, run queries, NO settings |
| Developer | View assigned projects only |
| Auditor | Read-only access, reports |
| Integration | API access for specific use cases |
Step 2: Configure Custom Roles
- Navigate to: Settings → Access Control → Roles
- Create custom roles with minimum permissions
- Assign to user groups
Step 3: Implement Project-Based Access
- Navigate to: Settings → Projects
- Create projects for different teams/environments
- Assign users to specific projects only
Code Implementation
Code Pack: Terraform
# Map SAML groups to Wiz roles with least-privilege access
# Role strategy:
# - Admin: Full platform access (limit to 2-3 users)
# - Security Analyst: View issues, run queries, NO settings
# - Developer: View assigned projects only
# - Auditor: Read-only access, reports
# - Integration: API access for specific use cases
resource "wiz_saml_group_mapping" "rbac" {
count = var.saml_idp_id != "" && length(var.rbac_group_mappings) > 0 ? 1 : 0
saml_idp_id = var.saml_idp_id
dynamic "group_mapping" {
for_each = var.rbac_group_mappings
content {
provider_group_id = group_mapping.value.provider_group_id
role = group_mapping.value.role
projects = length(group_mapping.value.projects) > 0 ? group_mapping.value.projects : null
}
}
}
# Create project-based access boundaries for team segregation
resource "wiz_project" "team_projects" {
for_each = var.profile_level >= 1 ? toset(["security", "development", "audit"]) : toset([])
name = "hth-${each.key}"
description = "HTH hardened project for ${each.key} team - least-privilege boundary"
risk_profile {
business_impact = each.key == "security" ? "HBI" : "MBI"
}
}
2. Cloud Connector Security
2.1 Secure Cloud Connector Configuration
Profile Level: L1 (Baseline) NIST 800-53: IA-5, AC-6
Description
Harden cloud connector IAM permissions to minimum required.
Rationale
Why This Matters:
- Wiz connectors have read access to cloud resources
- Over-privileged connectors expand attack surface
- Compromised connector credentials enable reconnaissance
AWS Connector Best Practices
Step 1: Use Read-Only Policy
Code Pack: Terraform
# AWS connector with least-privilege IAM role (read-only)
# The IAM role referenced here should grant only:
# ec2:Describe*, s3:GetBucketLocation, s3:GetBucketPolicy,
# s3:ListAllMyBuckets, iam:GetAccountSummary, iam:ListRoles
# with an external ID condition on the trust policy.
resource "wiz_connector_aws" "hardened" {
count = var.aws_connector_role_arn != "" ? 1 : 0
name = var.aws_connector_name
enabled = true
auth_params = jsonencode({
"customerRoleARN" = var.aws_connector_role_arn
})
extra_config = jsonencode({
"optedInRegions" = var.aws_connector_regions
"excludedAccounts" = var.aws_connector_excluded_accounts
"skipOrganizationScan" = false
})
}
# GCP connector with Viewer role (read-only, organization-level)
resource "wiz_connector_gcp" "hardened" {
count = var.gcp_connector_organization_id != "" ? 1 : 0
name = var.gcp_connector_name
enabled = true
auth_params = jsonencode({
"isManagedIdentity" = true
"organization_id" = var.gcp_connector_organization_id
})
extra_config = jsonencode({
"projects" = []
"excludedProjects" = var.gcp_connector_excluded_projects
"includedFolders" = []
"excludedFolders" = []
"auditLogMonitorEnabled" = true
})
}
Code Pack: CLI Script
# AWS IAM policy for Wiz connector (read-only)
cat <<'JSON'
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ec2:Describe*",
"s3:GetBucketLocation",
"s3:GetBucketPolicy",
"s3:ListAllMyBuckets",
"iam:GetAccountSummary",
"iam:ListRoles"
],
"Resource": "*"
}
]
}
JSON
# AWS trust policy with External ID for Wiz role assumption
cat <<'JSON'
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::WIZ_ACCOUNT_ID:root"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"sts:ExternalId": "YOUR_UNIQUE_EXTERNAL_ID"
}
}
}
]
}
JSON
Step 2: Enable AWS CloudTrail for Connector
- Monitor Wiz connector API calls
- Alert on unusual patterns
- Review access regularly
Step 3: Use External ID (see the Code Pack above for the trust policy JSON)
Azure Connector Best Practices
Step 1: Use Reader Role
- Assign Reader role at management group level
- Avoid Contributor or Owner roles
- Use managed identity where possible
Step 2: Restrict App Registration Permissions
- Create dedicated app registration
- Grant only Microsoft Graph read permissions
- Document and monitor app usage
GCP Connector Best Practices
Step 1: Use Viewer Role
- Assign Viewer role at organization level
- Create service account with minimal permissions
- Enable service account key rotation
2.2 Connector Credential Rotation
Profile Level: L2 (Hardened) NIST 800-53: IA-5(1)
Description
Implement regular rotation of cloud connector credentials.
Implementation
| Cloud | Credential Type | Rotation |
|---|---|---|
| AWS | IAM Role | External ID rotation annually |
| Azure | App Registration | Secret rotation quarterly |
| GCP | Service Account Key | Key rotation quarterly |
Code Implementation
Code Pack: Terraform
# Credential rotation monitoring control
# Detects cloud connectors with credentials that have not been rotated
# within the organization's rotation policy window.
#
# Rotation schedule:
# AWS: External ID rotation annually
# Azure: App registration secret rotation quarterly
# GCP: Service account key rotation quarterly
resource "wiz_control" "connector_credential_rotation" {
count = var.profile_level >= 2 ? 1 : 0
name = "HTH: Connector Credential Rotation Monitoring"
description = "Detects cloud connectors with stale credentials that require rotation per HTH hardening guide section 2.2"
severity = "HIGH"
enabled = true
project_id = "*"
resolution_recommendation = "Rotate connector credentials according to schedule: AWS External ID annually, Azure app secret quarterly, GCP service account key quarterly. See https://howtoharden.com/guides/wiz/#22-connector-credential-rotation"
query = jsonencode({
type = [
"CLOUD_ACCOUNT"
]
select = true
where = {
status = {
EQUALS = [
"CONNECTED"
]
}
}
})
scope_query = jsonencode({
type = [
"SUBSCRIPTION"
]
select = true
})
}
3. API Security
3.1 Service Account Management
Profile Level: L1 (Baseline) NIST 800-53: IA-5
Description
Secure Wiz API service accounts.
ClickOps Implementation
Step 1: Create Purpose-Specific Service Accounts
- Navigate to: Settings → Service Accounts
- Create accounts for:
- SIEM integration (read-only)
- Ticketing integration (limited write)
- Automation (specific scopes)
Step 2: Configure Minimum Scopes
| Integration | Required Scopes |
|---|---|
| SIEM | read:issues, read:vulnerabilities |
| Ticketing | read:issues, write:comments |
| Automation | Specific to use case |
Step 3: Rotate Credentials
- Set rotation schedule: Quarterly
- Update integrations with new credentials
- Revoke old credentials
Code Implementation
Code Pack: Terraform
# Create purpose-specific service accounts with minimum scopes
# Each integration gets its own account with only required permissions:
# SIEM: read:issues, read:vulnerabilities
# Ticketing: read:issues
# Automation: Specific to use case
resource "wiz_service_account" "integration" {
for_each = { for sa in var.service_accounts : sa.name => sa }
name = each.value.name
type = "THIRD_PARTY"
scopes = each.value.scopes
# Detect external credential rotation and force resource recreation
recreate_if_rotated = true
}
3.2 API Access Monitoring
Profile Level: L2 (Hardened) NIST 800-53: AU-6
Description
Monitor API usage for anomalies.
Implementation
Code Pack: Terraform
# Scheduled report for API access audit
# Runs at the configured interval to detect anomalous API usage patterns
# such as unusual query volumes, new source IPs, or off-hours access.
resource "wiz_report_graph_query" "api_access_audit" {
count = var.profile_level >= 2 ? 1 : 0
name = var.api_audit_report_name
project_id = "*"
run_interval_hours = var.api_audit_interval_hours
query = jsonencode({
type = [
"USER_ACCOUNT"
]
select = true
where = {
type = {
EQUALS = [
"SERVICE"
]
}
}
})
}
# Control to detect service accounts with overly broad scopes
resource "wiz_control" "overprivileged_service_accounts" {
count = var.profile_level >= 2 ? 1 : 0
name = "HTH: Overprivileged Service Accounts"
description = "Detects Wiz service accounts with administrative or overly broad API scopes per HTH hardening guide section 3.2"
severity = "MEDIUM"
enabled = true
project_id = "*"
resolution_recommendation = "Review and reduce service account scopes to the minimum required for each integration. See https://howtoharden.com/guides/wiz/#32-api-access-monitoring"
query = jsonencode({
type = [
"USER_ACCOUNT"
]
select = true
where = {
type = {
EQUALS = [
"SERVICE"
]
}
isAdmin = {
EQUALS = true
}
}
})
scope_query = jsonencode({
type = [
"SUBSCRIPTION"
]
select = true
})
}
Code Pack: API Script
# Example Wiz GraphQL query for audit
query {
auditLogs(
first: 100
orderBy: {field: TIMESTAMP, direction: DESC}
filterBy: {actionType: [API_REQUEST]}
) {
nodes {
timestamp
actionType
user {
email
}
sourceIP
requestDetails
}
}
}
4. Data Security
4.1 Configure Data Export Controls
Profile Level: L2 (Hardened) NIST 800-53: AC-3
Description
Control export of security findings and vulnerability data.
ClickOps Implementation
Step 1: Restrict Export Permissions
- Limit bulk export to Admin role only
- Log all export activities
- Alert on large exports
Step 2: Configure Report Sharing
- Navigate to: Settings → Reports
- Configure:
- Internal sharing only
- Expiration on shared links
- Password protection
Code Implementation
Code Pack: Terraform
# Project-based data export boundary
# Restricts bulk export of security findings and vulnerability data
# by isolating sensitive findings into a controlled project with
# limited membership and Admin-only export permissions.
resource "wiz_project" "data_export_restricted" {
count = var.profile_level >= 2 ? 1 : 0
name = var.data_export_project_name
description = "HTH hardened project with restricted data export permissions. Bulk export limited to Admin role only."
risk_profile {
business_impact = "HBI"
has_exposed_api = "NO"
stores_data = "YES"
is_regulated = "YES"
sensitive_data_types = ["PII", "FINANCIAL"]
regulatory_standards = ["SOC", "NIST"]
}
}
# Control to detect unauthorized large data exports
resource "wiz_control" "data_export_monitoring" {
count = var.profile_level >= 2 ? 1 : 0
name = "HTH: Unauthorized Data Export Detection"
description = "Detects large or unauthorized exports of security findings and vulnerability data per HTH hardening guide section 4.1"
severity = "HIGH"
enabled = true
project_id = "*"
resolution_recommendation = "Review export activity. Limit bulk export to Admin role only. Configure report sharing with expiration and restrict to internal-only distribution. See https://howtoharden.com/guides/wiz/#41-configure-data-export-controls"
query = jsonencode({
type = [
"USER_ACCOUNT"
]
select = true
where = {
isAdmin = {
EQUALS = false
}
}
})
scope_query = jsonencode({
type = [
"SUBSCRIPTION"
]
select = true
})
}
5. Monitoring & Detection
5.1 Audit Logging
Profile Level: L1 (Baseline) NIST 800-53: AU-2, AU-3
ClickOps Implementation
Step 1: Access Audit Logs
- Navigate to: Settings → Audit Log
- Review:
- Authentication events
- Configuration changes
- API access
Step 2: Export to SIEM
- Configure webhook or API integration
- Forward all audit events
- Create correlation rules
Detection Queries
Code Pack: Terraform
# Scheduled audit log report for SIEM export
# Captures authentication events, configuration changes, and API access
# at regular intervals for correlation and alerting.
resource "wiz_report_graph_query" "audit_log" {
name = var.audit_report_name
project_id = "*"
run_interval_hours = var.audit_report_interval_hours
query = jsonencode({
type = [
"USER_ACCOUNT"
]
select = true
where = {
status = {
EQUALS = [
"ACTIVE"
]
}
}
})
}
# Dedicated service account for SIEM integration (read-only audit access)
resource "wiz_service_account" "siem_export" {
name = "hth-siem-audit-export"
type = "THIRD_PARTY"
scopes = ["read:issues", "read:vulnerabilities"]
recreate_if_rotated = true
}
# Control to detect unusual data access patterns
resource "wiz_control" "unusual_data_access" {
name = "HTH: Unusual Data Access Pattern Detection"
description = "Detects unusual query volumes or access patterns that may indicate compromised credentials or insider threats per HTH hardening guide section 5.1"
severity = "MEDIUM"
enabled = true
project_id = "*"
resolution_recommendation = "Investigate the user or service account activity. Review source IPs, query volume, and timing. Correlate with SIEM alerts. See https://howtoharden.com/guides/wiz/#51-audit-logging"
query = jsonencode({
type = [
"USER_ACCOUNT"
]
select = true
where = {
status = {
EQUALS = [
"ACTIVE"
]
}
}
})
scope_query = jsonencode({
type = [
"SUBSCRIPTION"
]
select = true
})
}
6. Compliance Quick Reference
SOC 2 Mapping
| Control ID | Wiz Control | Guide Section |
|---|---|---|
| CC6.1 | SSO enforcement | 1.1 |
| CC6.2 | RBAC | 1.2 |
| CC6.7 | Data export controls | 4.1 |
Appendix A: References
Appendix B: References
Official Wiz Documentation:
- Trust Center
- Trust Center (SafeBase)
- Documentation Portal (login required)
- Resource Center
- Wiz Research
- Cloud Threat Landscape — Incidents
- CVE Vulnerability Database
API Documentation:
- API endpoint:
https://api.<REGION>.app.wiz.io/graphql(GraphQL) - Wiz GitHub Organization
Compliance Frameworks:
- SOC 2 Type II, SOC 3, ISO 27001, ISO 27017, ISO 27018, ISO 27701, HIPAA, PCI, FedRAMP Moderate — via Trust Center
- Wiz for Government (FedRAMP)
Security Incidents:
- No major public incidents involving Wiz as a victim identified
Changelog
| Date | Version | Maturity | Changes | Author |
|---|---|---|---|---|
| 2025-12-14 | 0.1.0 | draft | Initial Wiz hardening guide | Claude Code (Opus 4.5) |