メインコンテンツまでスキップ

通知を設定する

Shisho Cloud における通知は、そのタイミングや内容の全てを ワークフロー として制御できるようになっています。また、プロジェクトごとに複数のデフォルト通知先を事前に設定し、それぞれの通知先に送信できます。わざわざ深く学ばなくても便利に使えるように、標準の通知ワークフローが用意されており、検出事項の緊急度に応じた通知 が行えます。

Slack通知の例

メールによる通知の例

通知ワークフローは標準で含まれているワークフローの一つで、組織内の全リソースを対象とした問題の発見・トリアージ時に下記の方法で通知します。

  • Slack チャンネルへ通知
  • 指定のメールアドレスへ送信
  • 通知グループに紐付けられた送信先へ通知
警告

一部のお客様において、Slack通知のみに対応したワークフローが配布されているケースがございます。その場合はお手数ですが、標準の通知ワークフローページを開き、下記の新しいワークフローをコピー&ペーストし置換して下さい。また、置換した場合、送信先の指定が改めて必要となります。標準の通知ワークフローページのパラメーター設定にてご指定いただくようお願いします。

id: notification-security
name: "Prebundle: Notify important security events in a variety of ways"
version: 0.1.0
triggers:
triage:
- event:
- updated
status_changed_to:
- awaiting_review
- acknowledged
- action_required
- secure
- deleted
- event:
- created
status_changed_to:
- awaiting_review
jobs:
- id: triage
name: Notify triage status updation
notify:
rego: |
package notification.triage

import data.shisho
import data.shisho.notification.slack
import data.shisho.notification.group

minimum_severity := severity_intl(data.params.minimum_severity) {
data.params
data.params.minimum_severity != ""
} else := shisho.decision.severity_critical

severity_intl(x) := shisho.decision.severity_info {
x == "INFO"
} else := shisho.decision.severity_low {
x == "LOW"
} else := shisho.decision.severity_medium {
x == "MEDIUM"
} else := shisho.decision.severity_high {
x == "HIGH"
} else := shisho.decision.severity_critical {
x == "CRITICAL"
} else := shisho.decision.severity_low

severity_string(x) := "参考情報(info)" {
x == shisho.decision.severity_info
} else := "低(low)" {
x == shisho.decision.severity_low
} else := "中(medium)" {
x == shisho.decision.severity_medium
} else := "高(high)" {
x == shisho.decision.severity_high
} else := "緊急(critical)" {
x == shisho.decision.severity_critical
} else := x

severity_emoji(x) := ":information_source:" {
x == shisho.decision.severity_info
} else := ":eyes:" {
x == shisho.decision.severity_low
} else := ":warning:" {
x == shisho.decision.severity_medium
} else := ":rotating_light:" {
x == shisho.decision.severity_high
} else := ":sos:" {
x == shisho.decision.severity_critical
} else := ":memo:"

triage_status(x) := "要レビュー" {
x == "AWAITING_REVIEW"
} else := "要対応" {
x == "ACTION_REQUIRED"
} else := "リスク受容中" {
x == "ACKNOWLEDGED"
} else := "セキュア" {
x == "SECURE"
} else := "削除済" {
x == "DELETED"
} else := x

triage_status_emoji(x) := ":eyes:" {
x == "AWAITING_REVIEW"
} else := ":heavy_exclamation_mark:" {
x == "ACTION_REQUIRED"
} else := ":arrow_right:" {
x == "ACKNOWLEDGED"
} else := ":large_green_circle:" {
x == "SECURE"
} else := ":wastebasket:" {
x == "DELETED"
} else := ":memo:"

title(explanation, api_version, kind) := explanation.title {
explanation
} else := "" {
concat(":", [api_version, kind])
}

slack_headline(type, status) := "*新たなポリシー違反が検出されました。*\n対応を検討しましょう。" {
type == "CREATED"
} else := "*ポリシー違反が解決されました* :tada:" {
type == "UPDATED"
status == "SECURE"
} else := "*ポリシーに違反した設定の対応状況が変化しました。*\n引き続き対応を進めましょう。"

slack_triage_information(target) := [
slack.divider_block,
slack.context_block([slack.text_element(concat("", [":mega: トリアージ者: ", target.triageInitiator.displayName]))]),
slack.context_block([slack.text_element(concat("", [":memo: コメント: ", target.triageComment]))]),
] {
target.triageInitiator.displayName != ""
target.triageComment != ""
} else := [
slack.divider_block,
slack.context_block([slack.text_element(concat("", [":mega: トリアージ者: ", target.triageInitiator.displayName]))]),
] {
target.triageInitiator.displayName != ""
target.triageComment == ""
} else := []

# send notifications by Slack
notifications[n] {
# send notification only if the channel is specified
data.params.slack_channel != ""
workspace_id := split(data.params.slack_channel, ":")[0]
channel_id := split(data.params.slack_channel, ":")[1]

event := input.query.shisho.event
event.__typename == "ShishoTriageStatusEvent"
input.running_state == shisho.job.running_state_preprocessing

# send notification only if the severity of the target decision is higher than the minimum severity
target_severity := severity_intl(event.target.severity)
minimum_severity <= target_severity

n := shisho.notification.to_slack_channel(
workspace_id,
channel_id,
{"blocks": array.concat(
[slack.text_section(
slack_headline(event.type, event.status),
{"fields": [
# The first row
slack.text_element("*:memo: 違反が見られた観点*"),
slack.text_element("*:dart: 対象リソース*"),
slack.text_element(concat("", ["<", event.target.viewer, "|", title(event.target.explanation, event.target.apiVersion, event.target.kind), ">"])),
slack.text_element(concat("", ["<", event.target.subject.viewer, "|", event.target.subject.displayName, ">"])),
# The second row
slack.text_element(concat("", [severity_emoji(target_severity), " *深刻度*"])),
slack.text_element(concat("", [triage_status_emoji(event.status), " *対応状況*"])),
slack.text_element(severity_string(target_severity)),
slack.text_element(concat("", ["*", triage_status(event.status), "* に変化しました"])),
]},
)],
# The footer
array.concat(slack_triage_information(event.target), [
slack.divider_block,
slack.context_block([slack.text_element(concat("", [":shield: *Powered by \"<", event.target.createdBy.viewer, "|", event.target.createdBy.name, ">\" on Shisho Cloud*"]))]),
slack.divider_block,
]),
)},
)
}

headline(type, status) := "新たなポリシー違反が検出されました。対応を検討しましょう。" {
type == "CREATED"
} else := "ポリシー違反が解決されました" {
type == "UPDATED"
status == "SECURE"
} else := "ポリシーに違反した設定の対応状況が変化しました。引き続き対応を進めましょう。"

triage_information(target) := [
concat("", ["トリアージ者: ", target.triageInitiator.displayName, "\n"]),
concat("", ["コメント: ", target.triageComment, "\n"]),
] {
target.triageInitiator.displayName != ""
target.triageComment != ""
} else := [
concat("", ["トリアージ者: ", target.triageInitiator.displayName, "\n"]),
] {
target.triageInitiator.displayName != ""
target.triageComment == ""
} else := []

# send notifications by email
notifications[n] {
# send notification only if the email address is specified
data.params.email_address != ""
email = data.params.email_address

event := input.query.shisho.event
event.__typename == "ShishoTriageStatusEvent"
input.running_state == shisho.job.running_state_preprocessing

# send notification only if the severity of the target decision is higher than the minimum severity
target_severity := severity_intl(event.target.severity)
minimum_severity <= target_severity

n := shisho.notification.to_email(
email,
concat("", [
headline(event.type, event.status),
"\n\n",
"違反が見られた観点: ",
concat("", [title(event.target.explanation, event.target.apiVersion, event.target.kind), " (", event.target.viewer, ")", "\n"]),
"対象リソース: ",
concat("", [event.target.subject.displayName, " (", event.target.subject.viewer, ")", "\n"]),
"深刻度: ",
severity_string(target_severity),
"\n",
"対応状況: ",
concat("", [triage_status(event.status), "に変化しました", "\n"]),
"\n",
concat("", triage_information(event.target)),
"\n",
concat("", ["Powered by \"", event.target.createdBy.name, " (", event.target.createdBy.viewer, ")", "\" on Shisho Cloud"]),
]),
)
}

# send notifications with a notification group
notifications[n] {
# send notification only if the notification group ID is specified
data.params.notification_group != ""
group_id = data.params.notification_group

event := input.query.shisho.event
event.__typename == "ShishoTriageStatusEvent"
input.running_state == shisho.job.running_state_preprocessing

# send notification only if the severity of the target decision is higher than the minimum severity
target_severity := severity_intl(event.target.severity)
minimum_severity <= target_severity

n := shisho.notification.to_group(
group_id,
concat("", [
headline(event.type, event.status),
"\n\n",
"違反が見られた観点: ",
concat("", [title(event.target.explanation, event.target.apiVersion, event.target.kind), " (", event.target.viewer, ")", "\n"]),
"対象リソース: ",
concat("", [event.target.subject.displayName, " (", event.target.subject.viewer, ")", "\n"]),
"深刻度: ",
severity_string(target_severity),
"\n",
"対応状況: ",
concat("", [triage_status(event.status), "に変化しました", "\n"]),
"\n",
concat("", triage_information(event.target)),
"\n",
concat("", ["Powered by \"", event.target.createdBy.name, " (", event.target.createdBy.viewer, ")", "\" on Shisho Cloud"]),
]),
)
}
input:
schema: |
query {
shisho {
event {
__typename
... on ShishoTriageStatusEvent {
type
status

target {
apiVersion
kind

subject {
displayName
parentDisplayName
viewer
}

severity
viewer

explanation(locale: JA_JP) {
title
description
}

createdBy {
name
viewer
}

triageComment
triageInitiator {
id
type
displayName
}
}
}
}
}
}
with:
slack_channel:
type: slack_channel
descrition: The Slack channel to send notifications.
value: ""
email_address:
type: string
descrition: The email channel to send notifications.
value: ""
notification_group:
type: notification_target
descrition: The notification group to send notifications.
value: ""
minimum_severity:
type: string
description: The minimum severity to notify.
value: HIGH
oneof:
- INFO
- LOW
- MEDIUM
- HIGH
- CRITICAL

では、順に設定方法を見ていきましょう。

通知ワークフローの設定

ここでは通知ワークフローの設定を変更し、問題の発見・トリアージ時の通知を設定してみましょう。

通知ワークフローの設定ページにアクセスする

通知ワークフローの編集画面にアクセスすると、以下のような画面が開くはずです。

パラメータを編集する

画面右上を確認すると、各種通知先の設定項目と、どの緊急度(severity)の検出事項からを通知するかの 2 つの設定項目が確認できます。それぞれの項目を設定し、保存 を押下してください。

警告

通知を設定するには、事前に各種通知ターゲットの設定が必要となります。詳細は こちら を参照してください。

Slack通知をテストする

Slack チャンネルへの通知を利用する場合、テスト通知を送信 ボタンを押下することで、実際にテスト通知を送信できます。もし以下のようなメッセージが確認できれば、通知設定は完了です。

プロジェクトごとの通知ワークフローの設定

一律、同じ通知先に送信したいケースもあれば、プロジェクトごとに異なる通知先に送信したいケースもあるでしょう。上記のプロジェクトごとの通知ワークフローを利用してください。

対象のプロジェクトの設定ページにアクセスする

まずはプロジェクトの一覧画面から通知先を設定したいプロジェクトを選択し、設定ページにアクセスしてください。

通知先を設定する

設定ページにて、ご希望の通知先を選択し追加・更新してください。

なお、現在、プロジェクトの通知先として追加できるのは下記となります。また、それぞれ事前に設定が必要となりますので、ご希望の通知先が選択肢として表示されない場合はご確認ください。

プロジェクトごとの通知ワークフローの設定ページにアクセスする

すでにプロジェクトの設定ページにて通知先の設定を終えたので、改めてパラメータを通じ設定する必要はありません。なお、緊急度(severity)の検出事項を変更したい場合は、プロジェクトごとの通知ワークフローの編集ページにアクセスし、パラメータを編集してください。