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

データの部分取得

通常、一つのワークフローには複数のジョブが含まれ、そのジョブごとに全ての監査対象データに対して検査が行われます。そのため、ワークフローに複数のジョブが含まれる場合や、監査対象データが多いケースでは検査に時間がかかる可能性があります。

Shisho Cloudでは下記の機能の拡充により、検査の高速化を実現しています。

  • ワークフロー内に複数あるジョブに対して、一部のジョブのみを実行する機能
  • ワークフローのジョブ内で、一部の監査対象データのみを取得し、検査コードを実行する機能

本稿ではデータ取得に関する最適化について説明します。なお、現在、データの部分取得機能については、ワークフローの部分実行時に特定条件が満たされると、自動的に適用される機能となっています。ワークフローの特定のジョブのみを実行する方法については、こちらのページ をご参照ください。

警告

現在、本機能は限られたリソースに対してのみ実行可能です。今後、対応を拡大していく予定です。

info

以下で度々言及している監査対象リソースとは監査対象データと同義です。リソースの定義については、こちらのページ をご参照ください。

データの部分取得の仕様

ワークフロー内にある各ジョブの decide ブロックnotify ブロック 以下には、GraphQL クエリの定義が含まれ、基本的にはその定義に従って全てのリソースを取得し、ポリシーコードに流し込みます。例えば以下のクエリは、Google Cloud プロジェクト内の 全ての Compute Engine インスタンスを取得しています。

{
googleCloud {
projects {
computeEngine {
instances {
metadata {
id
displayName
}
shieldedInstanceConfiguration {
enableSecureBoot
}
}
} 
}
}
}

本機能は GraphQL クエリの実行時に、その GraphQL クエリと GraphQL スキーマ上に付与されているそれぞれのディレクティブを参照し、もし対象のフィールドが以下の条件を満たし、対象のリソース IDが指定されている場合、一部のリソースのみ取得します。

  1. GraphQL スキーマ上の対象フィールドに@canBePartial ディレクティブが付与されている
  2. GraphQL スキーマ上の対象フィールドに@resource ディレクティブを用いてリソース種別が示されている
  3. GraphQL クエリ上の対象フィールドに@mustBeTotal ディレクティブが付与されていない

3の@mustBeTotal ディレクティブについては、リソースの全件取得の明示セクションにて詳細を説明します。

type GoogleCloudComputeEngine {

...

"""
All Google Cloud Compute Engine instances
"""
instances(
condition: GoogleCloudComputeEngineCondition
): [GoogleCloudComputeEngineInstance!]!
@resource(kind: "googlecloud-ce-instance")
@canBePartial

...

}
info

Shisho Cloud 内で定義された GraphQL ディレクティブの詳細については、こちらのページ をご参照ください。

ロケータによる更なるリソースの絞り込み

データの部分取得機能によるの監査対象リソースの絞り込みについて説明してきました。一部のリソースについては、 GraphQL スキーマ内の対象フィールドに付与される@locatable ディレクティブを用い、更に絞り込めます。

info

@locatable ディレクティブの詳細については、こちらのページ をご参照ください。

以下は例となりますが、Shisho Cloud 内でシナリオ(scenarios)フィールドは、「 Web アプリケーション」("user-web-application")の子リソースとして定義されています。

type Query {
"""
All data from web application integration
"""
webApps: [WebApp!]! @resource(kind: "user-web-application")
}

type WebApp {
"""
Scenarios that the finding relates to
"""
scenarios: [WebAppScenario!]! @locatable(parentKind: "user-web-application")

...
}

ワークフローの部分実行時にリソースごとのロケータ情報を指定することにより、特定の Web アプリケーションに紐づくシナリオのみ取得できます。

リソースの全件取得の明示

ここまでリソースの絞り込みについて見てきましたが、ここで下記のケースを見てみましょう。

{
aws {
accounts {
network {
vpcs {
routeTables { # 一部のルートテーブルを取得
id

...

}
}
}
ec2 {
instances {
vpc {
routeTables { # 一部のルートテーブルを取得
metadata {
id
}

...

}
}
}
}
}
}
}

この場合、もしリソースを絞り込むための条件が aws.accounts.network.vpcs.routeTables フィールドと aws.accounts.ec2.instances.vpc.routeTables フィールド、共に満たされていた場合、それぞれのフィールドに対して監査対象リソースの絞り込みが行われます。

しかしながら、全てのリソースをポリシーコードに流し込むべきケースもあるはずです。その場合、GraphQL クエリ上の対象フィールドに対して、 @mustBeTotal ディレクティブを付与することにより、全てのリソースを取得できます。

{
aws {
accounts {
network {
vpcs {
routeTables @mustBeTotal { # 全てのルートテーブルを必ず取得する
id

...

}
}
}
ec2 {
instances {
vpc {
routeTables { # 一部のルートテーブル取得を取得
metadata {
id
}

...

}
}
}
}
}
}
}

今後、既存のワークフローを改変する場合や、カスタムワークフローを作成する場合で、GraphQL クエリ内に同一のリソース種別を持つフィールドが複数ある場合は、このディレクティブの利用を必要に応じてご検討ください。

info

@mustBeTotal ディレクティブの詳細については、こちらのページ をご参照ください。

まとめ

データの部分取得機能については、ワークフローの部分実行時に特定条件が満たされると、自動的に適用される機能となっています。そのため、ユーザーにて特に意識せずとも、普段通りにワークフローを書いていただければ、自動的に最適化されます。また、@mustBeTotal ディレクティブを用いて、明示的にデータの部分取得機能を回避する方法も用意しています。ぜひ、ご利用ください。