Retrieve data with GraphQL
The English user guide is currently in beta preview. Most of the documents have been automatically translated from the Japanese version. Should you find any inaccuracies, please reach out to Flatt Security.
In Shisho Cloud, resource inspection and evaluation result (decision) registration are defined in workflows. The data of inspection/audit targets required for the inspections are defined in the workflow in the form of GraphQL queries. This page describes the specifications of GraphQL in Shisho Cloud. For details on workflows, please refer to this page.
GraphQL is a query language for APIs, featuring a flexible approach that allows clients to retrieve only the data they need. For details, please refer to GraphQL.
Workflows and GraphQL Queries
A workflow has multiple jobs, and each job's decide/notify
block has an input
block. The GraphQL query written in the input
block defines the data to be inspected/audited. Shisho Cloud retrieves data for each job according to the definition of such queries, and inputs the retrieved data into the policy code.
jobs:
- id: example
name: Example Job
decide:
input:
schema: |
query {
...
}
- id: notify
name: Notify Job Status
decide:
input:
schema: |
query {
...
}
For example, the following GraphQL query retrieves isDefault
, which indicates whether a VPC in an AWS account is the default VPC.
jobs:
- id: example
name: Example Job
decide:
input:
schema: |
query {
aws {
accounts {
network {
vpcs {
metadata {
id
}
isDefault
}
}
}
}
}
Search Conditions in GraphQL Queries
Usually, all resources are retrieved, but some fields have an input
field that allows you to specify search conditions (condition
) to retrieve only specific resources.
In the case below, by using AWSNetworkCondition
, you can retrieve only the "AWS VPC resources" ("aws-vpc"
) in the specified regions (regions
), ap-northeast-1
and us-west-2
.
type AWSNetwork {
"""
VPC networks
"""
vpcs(condition: AWSNetworkCondition): [AWSVPC!]!
@resource(kind: "aws-vpc")
...
}
input AWSNetworkCondition {
"""
Regions of networks
If no list is specified (i.e. null), this field returns networks in *any* zone.
"""
regions: [AWSRegion!] @testdata(constraint: { array: { length: 2 } })
}
jobs:
- id: example
name: Example Job
decide:
input:
schema: |
query {
aws {
accounts {
network {
vpcs (condition: { regions: ["ap-northeast-1", "us-west-2"] }){
metadata {
id
}
isDefault
}
}
}
}
}
Executing GraphQL Queries with the shishoctl
CLI
The shishoctl
CLI is a CLI for interacting with Shisho Cloud. It offers various commands, including commands for executing GraphQL queries.
shishoctl query run --org <ORGANIZATION_ID> <GRAPHQL_QUERY_FILE_NAME>.graphql
For example, by running the following command, you can execute the GraphQL query written in the file example.graphql
against the organization named shisho-cloud-demo
.
shishoctl query run --org shisho-cloud-demo example.graphql
query {
aws {
accounts {
network {
vpcs {
metadata {
id
}
isDefault
}
}
}
}
}
For details about the shishoctl
CLI, see here.
Advanced: GraphQL Directives
Shisho Cloud adopts GraphQL as its schema/query language, allowing users to easily define and retrieve data they want to inspect/audit. The schema currently defines several GraphQL directives, which make it easier to understand the specifications of data retrieval logic from the schema. In addition, Shisho Cloud's unique GraphQL directives can be used in queries to customize the behavior of inspection/audit data retrieval.
This section describes the GraphQL directives supported by Shisho Cloud.
The keyword "resource" appears in the following description. In Shisho Cloud, the entity of audit target data is defined as a resource. For details on resources, please refer to here.
Directives Applied within the GraphQL Schema
GraphQL directives may be applied to GraphQL objects and fields within the GraphQL schema. The same applies to Shisho Cloud, where directives in the schema are primarily used to represent the specifications of objects and fields. The following lists the main GraphQL directives defined in Shisho Cloud that are intended to be used in the schema.
@resource
The @resource
directive is used to specify the resource kind. In the following example, the schema explicitly states that the vpcs
field returns resources that are treated as "AWS VPC resources" ("aws-vpc"
) within Shisho Cloud.
type AWSNetwork {
"""
VPC networks
"""
vpcs(condition: AWSNetworkCondition): [AWSVPC!]!
@resource(kind: "aws-vpc")
...
}
@canBePartial
The @canBePartial
directive is used to indicate whether only a part of a resource can be retrieved. For fields with this directive applied in the schema, by specifying the resource ID in a certain way when issuing a query, only the data related to that resource can be retrieved. This method is different from the search condition (condition
) explained in the "Search Conditions in GraphQL Queries" section and is a mechanism to narrow down the resources to be retrieved, which is implicitly used by Shisho Cloud to provide re-diagnosis quickly.
For details on re-diagnosis and how to specify target resources, please refer to this page.
The following example shows that only a part of the VPC resource list can be retrieved.
type AWSNetwork {
"""
VPC networks
"""
vpcs(condition: AWSNetworkCondition): [AWSVPC!]! @canBePartial
...
}
@locatable
The @locatable
directive specifies whether a resource can be narrowed down by specifying the location of the field to which it is applied. This directive has a parentKind
field, which also specifies the resource kind of the parent resource.
The following is an example, but in Shisho Cloud, the scenarios (scenarios
) field is defined as a child resource of the "Web Application resource" ("user-web-application"
). The @locatable
directive is applied to the scenarios (scenarios
) field. By specifying location information to narrow down scenarios, only scenarios associated with a specific web application resource can be retrieved.
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")
...
}
@testdata
The @testdata
directive defines information related to the generation of test data used in the GraphQL query test playground. Therefore, it does not affect the actual workflow, but is merely a specification for the test playground. In the following example, it indicates that test data should be generated for the minimumTtl
field in the range of 10 to 60.
type AWSCloudFrontCachePolicyConfiguration {
"""
The minimum amount of time, in seconds, that you want objects to stay in the CloudFront cache before CloudFront sends another request to the origin to see if the object has been updated
"""
minimumTtl: Int64! @testdata(constraint: { int: { min: 10, max: 60 } })
...
}
Directives Available in GraphQL Queries
Several directives are also available within GraphQL queries, which can trigger special behavior when the GraphQL query is evaluated. The following lists the directives that can be used within GraphQL queries.
@mustBeTotal
The @mustBeTotal
directive declares that all data must be retrieved when the query is executed.
Usually, all resources are retrieved when a GraphQL query is executed. However, some features of Shisho Cloud, such as the re-diagnosis function, may implicitly optimize to avoid retrieving unnecessary data. Therefore, policy code such as Rego that processes the results of GraphQL queries must be written on the premise that not all data will necessarily be retrieved.
On the other hand, due to the nature of the policy's decision logic, all data may be required at all times. This directive can be used to declare such constraints when issuing queries.
In the example below, it is required that all route tables under all VPCs (aws.accounts.network.vpcs.routeTables
) be retrieved. On the other hand, this is not the case for the route tables associated with EC2 instances (aws.accounts.ec2.instances.vpc.routeTables
).
{
aws {
accounts {
network {
vpcs {
routeTables @mustBeTotal { # Retrieve all route tables
id
...
}
}
}
ec2 {
instances {
vpc {
routeTables { # May retrieve only a part of route tables
metadata {
id
}
...
}
}
}
}
}
}
}