データの部分取得
通常、一つのワークフローには複数のジョブが含まれ、そのジョブごとに全ての監査対象データに対して検査が行われます。そのため、ワークフローに複数のジョブが含まれる場合や、監査対象データが多いケースでは検査に時間がかかる可能性があります。
Shisho Cloudでは下記の機能の拡充により、検査の高速化を実現しています。
- ワークフロー内に複数あるジョブに対して、一部のジョブのみを実行する機能
- ワークフローのジョブ内で、一部の監査対象データのみを取得し、検査コードを実行する機能
本稿ではデータ取得に関する最適化について説明します。なお、現在、データの部分取得機能については、ワークフローの部分実行時に特定条件が満たされると、自動的に適用される機能となっています。ワークフローの特定のジョブのみを実行する方法については、こちらのページ をご参照ください。
現在、本機能は限られたリソースに対してのみ実行可能です。今後、対応を拡大していく予定です。
以下で度々言及している監査対象リソースとは監査対象データと同義です。リソースの定義については、こちらのページ をご参照ください。
データの部分取得の仕様
ワークフロー内にある各ジョブの decide
ブロック、notify
ブロック 以下には、GraphQL クエリの定義が含まれ、基本的にはその定義に従って全てのリソースを取得し、ポリシーコードに流し込みます。例えば以下のクエリは、Google Cloud プロジェクト内の 全ての Compute Engine インスタンスを取得しています。
{
googleCloud {
projects {
computeEngine {
instances {
metadata {
id
displayName
}
shieldedInstanceConfiguration {
enableSecureBoot
}
}
}
}
}
}
本機能は GraphQL クエリの実行時に、その GraphQL クエリと GraphQL スキーマ上に付与されているそれぞれのディレクティブを参照し、もし対象のフィールドが以下の条件を満たし、対象のリソース IDが指定されている場合、一部のリソースのみ取得します。
- GraphQL スキーマ上の対象フィールドに
@canBePartial
ディレクティブが付与されている - GraphQL スキーマ上の対象フィールドに
@resource
ディレクティブを用いてリソース種別が示されている - GraphQL クエリ上の対象フィールドに
@mustBeTotal
ディレクティブが付与されていない
3の@mustBeTotal
ディレクティブについては、リソースの全件取得の明示セクションにて詳細を説明します。
type GoogleCloudComputeEngine {
...
"""
All Google Cloud Compute Engine instances
"""
instances(
condition: GoogleCloudComputeEngineCondition
): [GoogleCloudComputeEngineInstance!]!
@resource(kind: "googlecloud-ce-instance")
@canBePartial
...
}
Shisho Cloud 内で定義された GraphQL ディレクティブの詳細については、こちらのページ をご参照ください。
ロケータによる更なるリソースの絞り込み
データの部分取得機能によるの監査対象リソースの絞り込みについて説明してきました。一部のリソースについては、 GraphQL スキーマ内の対象フィールドに付与される@locatable
ディレクティブを用い、更に絞り込めます。
@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 クエリ内に同一のリソース種別を持つフィールドが複数ある場合は、このディレクティブの利用を必要に応じてご検討ください。
@mustBeTotal
ディレクティブの詳細については、こちらのページ を ご参照ください。
まとめ
データの部分取得機能については、ワークフローの部分実行時に特定条件が満たされると、自動的に適用される機能となっています。そのため、ユーザーにて特に意識せずとも、普段通りにワークフローを書いていただければ、自動的に最適化されます。また、@mustBeTotal
ディレクティブを用いて、明示的にデータの部分取得機能を回避する方法も用意しています。ぜひ、ご利用ください。