Wiz
通过 Wiz 集成,您可以根据您的映射和定义,将 Wiz 账户中的 "项目"、"问题"、"控件 "和 "服务单 "导入 Port。
常见被用于情况
- 映射 Wiz 组织环境中的 "项目"、"问题"、"控件 "和 "服务单"。
- 实时观察对象更改(创 建/更新/删除),并自动将更改应用到您的 Port 实体中。
先决条件
To install the integration, you need a Kubernetes cluster that the integration's container chart will be deployed to.
Please make sure that you have kubectl
and helm
installed on your machine, and that your kubectl
CLI is connected to the Kubernetes cluster where you plan to install the integration.
您的 Wiz 凭据应具有 "read:projects "和 "read:issues "权限范围。请访问 Wizdocumentation ,了解如何获取凭据和设置权限。
安装
从以下安装方法中选择一种:
- Real Time & Always On
- Scheduled
使用该安装选项意味着集成将能使用 webhook 实时更新 Port。
本表总结了安装时可用的参数,请在下面的脚本中按自己的需要进行设置,然后复制并在终端运行:
Parameter | Description | Required |
---|---|---|
port.clientId | Your port client id (Get the credentials) | ✅ |
port.clientSecret | Your port client secret (Get the credentials) | ✅ |
integration.identifier | Change the identifier to describe your integration | ✅ |
integration.type | The integration type | ✅ |
integration.eventListener.type | The event listener type | ✅ |
integration.secrets.wizClientId | The Wiz Client ID | ✅ |
integration.secrets.wizClientSecret | The Wiz Client Secret | ✅ |
integration.config.wizApiUrl | The Wiz API URL. | ✅ |
integration.config.wizTokenUrl | The Wiz Token Authentication URL | ✅ |
integration.config.appHost | The host of the Port Ocean app. Used to set up the integration endpoint as the target for Webhooks created in Wiz | ❌ |
integration.secret.wizWebhookVerificationToken | This is a password you create, that is used to verify webhook events to Port | ❌ |
scheduledResyncInterval | The number of minutes between each resync | ❌ |
initializePortResources | Default true, When set to true the integration will create default blueprints and the port App config Mapping | ❌ |
helm repo add --force-update port-labs https://port-labs.github.io/helm-charts
helm upgrade --install my-wiz-integration port-labs/port-ocean \
--set port.clientId="PORT_CLIENT_ID" \
--set port.clientSecret="PORT_CLIENT_SECRET" \
--set initializePortResources=true \
--set scheduledResyncInterval=120 \
--set integration.identifier="my-wiz-integration" \
--set integration.type="wiz" \
--set integration.eventListener.type="POLLING" \
--set integration.secrets.wizClientId="WIZ_CLIENT_ID" \
--set integration.secrets.wizClientSecret="WIZ_CLIENT_SECRET" \
--set integration.secrets.wizApiUrl="WIZ_API_URL" \
--set integration.config.wizTokenUrl="WIZ_TOKEN_URL"
- GitHub
- Jenkins
- Azure Devops
This workflow will run the Wiz integration once and then exit, this is useful for scheduled ingestion of data.
确保配置以下Github Secrets :
Parameter | Description | Required |
---|---|---|
OCEAN__INTEGRATION__CONFIG__WIZ_CLIENT_ID | The Wiz Client ID token | ✅ |
OCEAN__INTEGRATION__CONFIG__WIZ_CLIENT_SECRET | The Wiz Client Secret | ✅ |
OCEAN__INTEGRATION__CONFIG__WIZ_API_URL | The Wiz API URL. | ✅ |
OCEAN__INTEGRATION__CONFIG__WIZ_TOKEN_URL | The Wiz Token URL. | ✅ |
OCEAN__INTEGRATION__CONFIG__WIZ_WEBHOOK_VERIFICATION_TOKEN | The token used to verify webhook requests into Port. | ❌ |
OCEAN__INITIALIZE_PORT_RESOURCES | Default true, When set to false the integration will not create default blueprints and the port App config Mapping | ❌ |
OCEAN__INTEGRATION__IDENTIFIER | Provide a unique identifier for your integration. If not provided, the default identifier will be used. | ❌ |
OCEAN__PORT__CLIENT_ID | Your port client id (Get the credentials) | ✅ |
OCEAN__PORT__CLIENT_SECRET | Your port client secret (Get the credentials) | ✅ |
OCEAN__PORT__BASE_URL | Your port base url, relevant only if not using the default port app | ❌ |
下面是 wiz-integration.yml
工作流程文件的示例:
name: Wiz Exporter Workflow
# This workflow responsible for running Wiz exporter.
on:
workflow_dispatch:
jobs:
run-integration:
runs-on: ubuntu-latest
steps:
- name: Run Wiz Integration
run: |
# Set Docker image and run the container
integration_type="wiz"
version="latest"
image_name="ghcr.io/port-labs/port-ocean-$integration_type:$version"
docker run -i --rm --platform=linux/amd64 \
-e OCEAN__EVENT_LISTENER='{"type":"ONCE"}' \
-e OCEAN__INITIALIZE_PORT_RESOURCES=true \
-e OCEAN__INTEGRATION__CONFIG__WIZ_CLIENT_ID=${{ secrets.OCEAN__INTEGRATION__CONFIG__WIZ_CLIENT_ID }} \
-e OCEAN__INTEGRATION__CONFIG__WIZ_CLIENT_SECRET=${{ secrets.OCEAN__INTEGRATION__CONFIG__WIZ_CLIENT_SECRET }} \
-e OCEAN__INTEGRATION__CONFIG__WIZ_API_URL=${{ secrets.OCEAN__INTEGRATION__CONFIG__WIZ_API_URL }} \
-e OCEAN__INTEGRATION__CONFIG__WIZ_TOKEN_URL=${{ secrets.OCEAN__INTEGRATION__CONFIG__WIZ_TOKEN_URL }} \
-e OCEAN__PORT__CLIENT_ID=${{ secrets.OCEAN__PORT__CLIENT_ID }} \
-e OCEAN__PORT__CLIENT_SECRET=${{ secrets.OCEAN__PORT__CLIENT_SECRET }} \
$image_name
exit $?
This pipeline will run the Wiz integration once and then exit, this is useful for scheduled ingestion of data.
请确保配置以下Jenkins Credentials的 "Secret Text "类型:
Parameter | Description | Required |
---|---|---|
OCEAN__INTEGRATION__CONFIG__WIZ_CLIENT_ID | The Wiz Client ID token | ✅ |
OCEAN__INTEGRATION__CONFIG__WIZ_CLIENT_SECRET | The Wiz Client Secret | ✅ |
OCEAN__INTEGRATION__CONFIG__WIZ_API_URL | The Wiz API URL. | ✅ |
OCEAN__INTEGRATION__CONFIG__WIZ_TOKEN_URL | The Wiz Token URL. | ✅ |
OCEAN__INTEGRATION__CONFIG__WIZ_WEBHOOK_VERIFICATION_TOKEN | The token used to verify webhook requests into Port. | ❌ |
OCEAN__INITIALIZE_PORT_RESOURCES | Default true, When set to false the integration will not create default blueprints and the port App config Mapping | ❌ |
OCEAN__INTEGRATION__IDENTIFIER | Provide a unique identifier for your integration. If not provided, the default identifier will be used. | ❌ |
OCEAN__PORT__CLIENT_ID | Your port client id (Get the credentials) | ✅ |
OCEAN__PORT__CLIENT_SECRET | Your port client secret (Get the credentials) | ✅ |
OCEAN__PORT__BASE_URL | Your port base url, relevant only if not using the default port app | ❌ |
下面是 Jenkinsfile
groovy Pipelines 文件的示例:
pipeline {
agent any
stages {
stage('Run Wiz Integration') {
steps {
script {
withCredentials([
string(credentialsId: 'OCEAN__INTEGRATION__CONFIG__WIZ_CLIENT_ID', variable: 'OCEAN__INTEGRATION__CONFIG__WIZ_CLIENT_ID'),
string(credentialsId: 'OCEAN__INTEGRATION__CONFIG__WIZ_CLIENT_SECRET', variable: 'OCEAN__INTEGRATION__CONFIG__WIZ_CLIENT_SECRET'),
string(credentialsId: 'OCEAN__INTEGRATION__CONFIG__WIZ_API_URL', variable: 'OCEAN__INTEGRATION__CONFIG__WIZ_API_URL'),
string(credentialsId: 'OCEAN__INTEGRATION__CONFIG__WIZ_TOKEN_URL', variable: 'OCEAN__INTEGRATION__CONFIG__WIZ_TOKEN_URL'),
string(credentialsId: 'OCEAN__PORT__CLIENT_ID', variable: 'OCEAN__PORT__CLIENT_ID'),
string(credentialsId: 'OCEAN__PORT__CLIENT_SECRET', variable: 'OCEAN__PORT__CLIENT_SECRET'),
]) {
sh('''
#Set Docker image and run the container
integration_type="wiz"
version="latest"
image_name="ghcr.io/port-labs/port-ocean-${integration_type}:${version}"
docker run -i --rm --platform=linux/amd64 \
-e OCEAN__EVENT_LISTENER='{"type":"ONCE"}' \
-e OCEAN__INITIALIZE_PORT_RESOURCES=true \
-e OCEAN__INTEGRATION__CONFIG__WIZ_CLIENT_ID=$OCEAN__INTEGRATION__CONFIG__WIZ_CLIENT_ID \
-e OCEAN__INTEGRATION__CONFIG__WIZ_CLIENT_SECRET=$OCEAN__INTEGRATION__CONFIG__WIZ_CLIENT_SECRET \
-e OCEAN__INTEGRATION__CONFIG__WIZ_API_URL=$OCEAN__INTEGRATION__CONFIG__WIZ_API_URL \
-e OCEAN__INTEGRATION__CONFIG__WIZ_TOKEN_URL=$OCEAN__INTEGRATION__CONFIG__WIZ_TOKEN_URL \
-e OCEAN__PORT__CLIENT_ID=$OCEAN__PORT__CLIENT_ID \
-e OCEAN__PORT__CLIENT_SECRET=$OCEAN__PORT__CLIENT_SECRET \
$image_name
exit $?
''')
}
}
}
}
}
}
This pipeline will run the Wiz integration once and then exit, this is useful for scheduled ingestion of data.
Your Azure Devops agent should be able to run docker commands. Learn more about agents here.
If you want the integration to update Port in real time using webhooks you should use the Real Time & Always On installation option.
Make sure to configure the following variables using Azure Devops variable groups. Add them into in a variable group named port-ocean-credentials
:
Parameter | Description | Required |
---|---|---|
OCEAN__INTEGRATION__CONFIG__WIZ_CLIENT_ID | The Wiz Client ID token | ✅ |
OCEAN__INTEGRATION__CONFIG__WIZ_CLIENT_SECRET | The Wiz Client Secret | ✅ |
OCEAN__INTEGRATION__CONFIG__WIZ_API_URL | The Wiz API URL. | ✅ |
OCEAN__INTEGRATION__CONFIG__WIZ_TOKEN_URL | The Wiz Token URL. | ✅ |
OCEAN__INTEGRATION__CONFIG__WIZ_WEBHOOK_VERIFICATION_TOKEN | The token used to verify webhook requests into Port. | ❌ |
OCEAN__INITIALIZE_PORT_RESOURCES | Default true, When set to false the integration will not create default blueprints and the port App config Mapping | ❌ |
OCEAN__INTEGRATION__IDENTIFIER | Provide a unique identifier for your integration. If not provided, the default identifier will be used. | ❌ |
OCEAN__PORT__CLIENT_ID | Your port client id (Get the credentials) | ✅ |
OCEAN__PORT__CLIENT_SECRET | Your port client secret (Get the credentials) | ✅ |
OCEAN__PORT__BASE_URL | Your port base url, relevant only if not using the default port app | ❌ |
下面是 wiz-integration.yml
Pipelines 文件的示例:
trigger:
- main
pool:
vmImage: "ubuntu-latest"
variables:
- group: port-ocean-credentials
steps:
- script: |
# Set Docker image and run the container
integration_type="wiz"
version="latest"
image_name="ghcr.io/port-labs/port-ocean-$integration_type:$version"
docker run -i --rm \
-e OCEAN__EVENT_LISTENER='{"type":"ONCE"}' \
-e OCEAN__INITIALIZE_PORT_RESOURCES=true \
-e OCEAN__INTEGRATION__CONFIG__WIZ_CLIENT_ID=${OCEAN__INTEGRATION__CONFIG__WIZ_CLIENT_ID} \
-e OCEAN__INTEGRATION__CONFIG__WIZ_CLIENT_SECRET=${OCEAN__INTEGRATION__CONFIG__WIZ_CLIENT_SECRET} \
-e OCEAN__INTEGRATION__CONFIG__WIZ_API_URL=${OCEAN__INTEGRATION__CONFIG__WIZ_API_URL} \
-e OCEAN__INTEGRATION__CONFIG__WIZ_TOKEN_URL=${OCEAN__INTEGRATION__CONFIG__WIZ_TOKEN_URL} \
-e OCEAN__PORT__CLIENT_ID=${OCEAN__PORT__CLIENT_ID} \
-e OCEAN__PORT__CLIENT_SECRET=${OCEAN__PORT__CLIENT_SECRET} \
$image_name
exit $?
displayName: 'Ingest Data into Port'
有关代理或自签名证书等高级配置,click here 。
Ingesting Wiz objects
Wiz 集成使用 YAML 配置来描述将数据加载到开发人员门户的过程。
下面是配置中的一个示例片段,演示了从 Wiz 获取 "项目 "数据的过程:
createMissingRelatedEntities: true
deleteDependentEntities: true
resources:
- kind: project
selector:
query: 'true'
port:
entity:
mappings:
blueprint: '"wizProject"'
identifier: .id
title: .name
properties:
archived: .archived
businessUnit: .businessUnit
description: .description
该集成利用JQ JSON processor 从 Wiz 的 API 事件中对现有字段和 Values 进行选择、修改、连接、转换和其他操作。
配置结构
集成配置决定了从 Wiz 中查询哪些资源,以及在 Port 中创建哪些实体和属性。
-
集成配置的根密钥是 "资源 "密钥:
resources:
- kind: project
selector:
... -
类型 "键是 Wiz 对象的指定符:
resources:
- kind: project
selector:
... -
通过 "选择器 "和 "查询 "键,您可以过滤哪些指定 "类型 "的对象将被录入软件目录:
resources:
- kind: project
selector:
query: "true" # JQ boolean expression. If evaluated to false - this object will be skipped.
port: -
Port"、"实体 "和 "映射 "键被用来将 Wiz 对象字段映射到Port实体。要创建多个同类映射,可在
resources
数组中添加另一项;resources:
- kind: project
selector:
query: "true"
port:
entity:
mappings: # Mappings between one Wiz object to a Port entity. Each value is a JQ query.
identifier: .id
title: .attributes.name
blueprint: '"wizProject"'
identifier: .id
title: .name
properties:
archived: .archived
businessUnit: .businessUnit
description: .description
- kind: project # In this instance project is mapped again with a different filter
selector:
query: '.name == "MyProjectName"'
port:
entity:
mappings: ...
blueprint
键的值 - 如果要使用硬编码字符串,需要用 2 组引号封装,例如使用一对单引号 ('
),然后再用一对双引号 ("
): :::将数据输入Port
要使用integration configuration 引用 Wiz 对象,可以按照以下步骤操作:
- 转到 DevPortal Builder 页面。
- 选择要被 Wiz 引用的蓝图。
- 从菜单中选择采集数据选项。
- 在代码质量和安全 Provider 类别下选择 Wiz。
- 根据您的需要修改configuration 。
- 单击
Resync
。
示例
蓝图和相关集成配置示例:
项目
Project blueprint
{
"identifier": "wizProject",
"description": "This blueprint represents a wiz project",
"title": "Wiz Project",
"icon": "Box",
"schema": {
"properties": {
"archived": {
"type": "boolean",
"title": "Archived?",
"description": "Is the project archived?"
},
"businessUnit": {
"type": "string",
"title": "Business Unit",
"description": "the business unit of the project"
},
"description": {
"type": "string",
"title": "Description",
"description": "the project description"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"relations": {
"issues": {
"target": "wizIssue",
"title": "Issues",
"description": "The issues affecting this project",
"required": false,
"many": true
}
}
}
Integration configuration
resources:
- kind: project
selector:
query: 'true'
port:
entity:
mappings:
blueprint: '"wizProject"'
identifier: .id
title: .name
properties:
archived: .archived
businessUnit: .businessUnit
description: .description
控制
Control blueprint
{
"identifier": "wizControl",
"description": "This blueprint represents a wiz source rule",
"title": "Wiz Control",
"icon": "Flag",
"schema": {
"properties": {
"controlDescription": {
"type": "string",
"title": "Control Description",
"description": "the control description"
},
"resolutionRecommendation": {
"type": "string",
"title": "Control Recommendation",
"description": "the control recommendation on resolving issues"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"relations": {}
}
Integration configuration
resources:
- kind: control
selector:
query: 'true'
port:
entity:
mappings:
blueprint: '"wizControl"'
identifier: .id
title: .name
properties:
controlDescription: .controlDescription
resolutionRecommendation: .resolutionRecommendation
问题
Issue blueprint
{
"identifier": "wizIssue",
"description": "This blueprint represents a wiz issue",
"title": "Wiz Issue",
"icon": "Alert",
"schema": {
"properties": {
"url": {
"type": "string",
"title": "Issue URL",
"format": "url",
"description": "the link to the issue"
},
"status": {
"title": "Status",
"type": "string",
"enum": [
"OPEN",
"IN_PROGRESS",
"RESOLVED",
"REJECTED"
],
"enumColors": {
"OPEN": "blue",
"IN_PROGRESS": "orange",
"RESOLVED": "green",
"REJECTED": "darkGray"
}
},
"severity": {
"title": "Severity",
"type": "string",
"enum": [
"INFORMATIONAL",
"LOW",
"MEDIUM",
"HIGH",
"CRITICAL"
],
"enumColors": {
"INFORMATIONAL": "blue",
"LOW": "yellow",
"MEDIUM": "orange",
"HIGH": "red",
"CRITICAL": "red"
}
},
"type": {
"title": "Type",
"type": "string"
},
"vulnerability": {
"title": "Vulnerability",
"type": "object",
"description": "The identified security risk"
},
"notes": {
"title": "Notes",
"type": "array"
},
"createdAt": {
"title": "Created At",
"type": "string",
"format": "date-time"
},
"updatedAt": {
"title": "Updated At",
"type": "string",
"format": "date-time"
},
"dueAt": {
"title": "Due At",
"type": "string",
"format": "date-time"
},
"resolvedAt": {
"title": "Resolved At",
"type": "string",
"format": "date-time"
},
"statusChangedAt": {
"title": "Status ChangedAt",
"type": "string",
"format": "date-time"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"relations": {
"projects": {
"target": "wizProject",
"title": "Affected Projects",
"description": "The projects affected by this issue",
"required": false,
"many": true
},
"serviceTickets": {
"target": "wizServiceTicket",
"title": "Service Tickets",
"description": "The service tickets belonging to this issue",
"required": false,
"many": true
},
"control": {
"target": "wizControl",
"title": "Control",
"description": "The control that flagged this issue",
"required": false,
"many": false
}
}
}
Integration configuration
resources:
- kind: issue
selector:
query: 'true'
port:
entity:
mappings:
blueprint: '"wizIssue"'
identifier: .id
title: .entitySnapshot.name + " | " + .entitySnapshot.type
properties:
url: .id as $id | "https://app.wiz.io/issues#~(issue~'" + $id + ")"
status: .status
severity: .severity
type: .type
notes: .notes
vulnerability: .entitySnapshot
createdAt: .createdAt
updatedAt: .updatedAt
statusChangedAt: .statusChangedAt
resolvedAt: .resolvedAt
relations:
projects: .projects[].id
serviceTickets: .serviceTickets[].externalId
control: .sourceRule.id
服务票据
Service Ticket blueprint
{
"identifier": "wizServiceTicket",
"description": "This blueprint represents a wiz service ticket",
"title": "Wiz Service Ticket",
"icon": "Book",
"schema": {
"properties": {
"url": {
"type": "string",
"title": "Ticket URL",
"format": "url",
"description": "the service ticket URL"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"relations": {}
}
Integration configuration
resources:
- kind: serviceTicket
selector:
query: 'true'
port:
entity:
mappings:
blueprint: '"wizServiceTicket"'
identifier: .externalId
title: .name
properties:
url: .url
通过 webhook 进行替代安装
虽然上述 Ocean 集成是推荐的安装方法,但您可能更喜欢使用 webhook 从 Wiz 引用数据。 如果是这样,请使用以下说明:
Webhook installation (click to expand)
在本示例中,您将在Wiz 和 Port 之间创建 webhook 集成,将 Wiz 问题实体导入 Port。
Port configuration
创建以下蓝图定义:
Wiz issue blueprint
{
"identifier": "wizIssue",
"description": "This blueprint represents a wiz issue",
"title": "Wiz Issue",
"icon": "Alert",
"schema": {
"properties": {
"status": {
"title": "Status",
"type": "string",
"enum": [
"OPEN",
"IN_PROGRESS",
"RESOLVED",
"REJECTED"
],
"enumColors": {
"OPEN": "blue",
"IN_PROGRESS": "orange",
"RESOLVED": "green",
"REJECTED": "darkGray"
}
},
"severity": {
"title": "Severity",
"type": "string",
"enum": [
"INFORMATIONAL",
"LOW",
"MEDIUM",
"HIGH",
"CRITICAL"
],
"enumColors": {
"INFORMATIONAL": "blue",
"LOW": "yellow",
"MEDIUM": "orange",
"HIGH": "red",
"CRITICAL": "red"
}
},
"control": {
"title": "Control",
"type": "string",
"description": "A security graph query defining a risk"
},
"vulnerability": {
"title": "Vulnerability",
"type": "object",
"description": "The identified security risk"
},
"createdAt": {
"title": "Created At",
"type": "string",
"format": "date-time"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"relations": {}
}
创建以下 webhook 配置using Port's UI
Wiz issue webhook configuration
- 基本信息 选项卡 - 填写以下详细信息:
1.title:
Wiz Mapper
; 2.标识符 :wiz_mapper
; 3.Description :将 Wiz 问题映射到 Port
的 webhook 配置; 4.图标 :Box
; - 集成配置选项卡 - 填写以下 JQ 映射:
[
{
"blueprint": "wizIssue",
"entity": {
"identifier": ".body.issue.id",
"title": ".body.resource.name",
"properties": {
"status": ".body.issue.status",
"severity": ".body.issue.severity",
"control": ".body.control.name",
"vulnerability": ".body.resource",
"createdAt": ".body.issue.created"
}
}
}
]
Create a webhook in Wiz
- 向 [email protected] 发送电子邮件,请求访问开发人员文档,或联系您的 Wiz 客户经理。
- 按照文档中的guide 创建 webhook。
完成!在 Wiz 中创建的任何问题都将触发一个 webhook 事件,该事件将发送到 Provider 提供的 webhook URL。 Port 将根据映射解析事件,并相应地更新目录实体。