New! Filter and export controls, plus lots of new mods and plugins. →

Mod Reference

Block TypeDescription
controlControls provide a defined structure and interface for queries that draw a specific conclusion (e.g. 'ok', 'alarm') about each row.
benchmarkBenchmark provides a mechanism for organizing controls into hierarchical structures.
modThe mod block contains metadata, documentation, and dependency data for the mod.
queryQueries define common SQL statements that may be used alone, or referenced by arguments in other blocks like reports and actions.


control

Controls provide a defined structure and interface for queries that draw a specific conclusion (e.g. 'OK', 'Alarm') about each row (typically, each row represents a single evaluated 'block'). This pattern is common across multiple control benchmarks (CIS, etc) and unit testing benchmarks (JUnit, NUnit, etc).

Controls use queries to gather data, but contain specific metadata and return specific columns with specified values in a specific format.

Example Usage

control "cisv130_2_1_2" {
title = "2.1.2 Ensure S3 Bucket Policy allows HTTPS requests (Manual)"
description = "At the Amazon S3 bucket level, you can configure permissions through a bucket policy making the objects accessible only through HTTPS."
documentation = file("docs/cisv130/2_1_2.md")
sql = query.s3_bucket_encryption_in_transit_control.sql
tags = {
cloud_provider = "aws"
framework = "cis"
cis_version = "v1.3.0"
cis_item_id = "1.4"
cis_control = "4.3"
cis_type = "automated"
cis_level = "1"
}
}

You may run all controls in a group:

# run all the cis controls
steampipe check aws.benchmark.cisv130
# run all cis section 2 controls
steampipe check aws.benchmark.cisv130_2
# run all cis section 2.1 controls
steampipe check aws.benchmark.cisv130_2_1

Argument Reference

ArgumentTypeRequired?Description
sqlStringRequiredAn SQL string that returns rows that conform to the Control interface - they must contain the required control columns. This may be an inline string, but more often will refer to the sql attribute of a query resource.
descriptionStringOptionalA description of the control
documentationString (Markdown)OptionalA markdown string containing a long form description, used as documentation for the mod on hub.steampipe.io.
severityStringOptionalThe potential impact of given control. Allowed values are none,low,medium,high,critical. The severity names are taken from the Common Vulnerability Scoring System version 3.1: Specification Document. This document may be used as guidance for classifying your controls.
tagsmapOptionalA map of key:value metadata for the benchmark, used to categorize, search, and filter. The structure is up to the mod author and varies by benchmark and provider.
titleStringOptionalDisplay title for the control

Required Control Columns

ALL controls must specify queries that return rows that contain the following standard columns:

ColumnTypeDescription
statusStringThe control status for this row. Only the defined control statuses should be used.
reasonStringA description that details WHY the row has the specified status. The reason should always be set, even if the control is in an 'ok' state. It should be a sentence ending with a period.
resourceStringA unique identifier that identifies the targeted resource for this control check. Ideally, this should be a globally unique identifier such as an arn.
Control Statuses
StatusDescription
okThe control is compliant for the resource/row.
alarmThe control is not compliant for the resource/row, and should be remediated.
skipThis control was not evaluated because Steampipe was requested to skip it.
infoThis control is not automated. The control may provide instructions to manually verify, and/or may provide additional context.
errorUsed when an error has occurred in calculating the control state.

Additional Control Columns & Dimensions

A control's query MUST return the required columns, but it may also return additional columns. These additional columns are referred to as dimensions, and can be used to specify additional provider-specific columns that are included in control reports and outputs to provide additional context. For example, a benchmark that runs controls against AWS resources may specify dimensions for account_id and region to help locate the evaluated resource. The account_id and region columns will be added as dimensions to the control output for any control whose query returns those columns.


benchmark

The benchmark block provides a mechanism for grouping controls into control benchmarks, and into sections within a control benchmark. For instance, the AWS mod has separate top-level benchmarks for CIS, NIST, PCI, etc. Each of these benchmarks may have sub-level benchmarks to organize controls in a way that reflects that particular control framework - one for each section or subsection in CIS, one fore each CSF Core Function and subcategory for NIST, etc.

A benchmark may specify control or benchmark resources as children, enabling you to create flexible hierarchies of any depth. By default, controls will be grouped with aggregated totals at each benchmark.

You can run benchmarks or refer to them with hcl syntax as {mod}.benchmark.{name}. The name must be unique in the namespace (mod). Typically, controls and benchmarks in a given benchmark should be named in a way that mimics the hierarchy in order to provide an easy to follow structure. This is a convention that should be followed, but not a strict requirement.

Example Usage

benchmark "cisv130" {
title = "CIS v1.3.0"
description = "The CIS Amazon Web Services Foundations Benchmark provides prescriptive guidance for configuring security options for a subset of Amazon Web Services with an emphasis on foundational, testable, and architecture agnostic settings."
documentation = file("./docs/cis-overview.md")
children = [
benchmark.cis_v130_1,
benchmark.cis_v130_2,
benchmark.cis_v130_3,
benchmark.cis_v130_4,
benchmark.cis_v130_5
]
tags = {
cloud_provider = "aws"
framework = "cis"
cis_version = "v1.3.0"
}
}
benchmark "cisv130_1" {
title = "1 Identity and Access Management"
documentation = file("docs/cisv130_1.md")
children = [
control.cis_v130_1_1,
control.cis_v130_1_2,
control.cis_v130_1_3,
control.cis_v130_1_4,
control.cis_v130_1_5,
control.cis_v130_1_6
]
tags = {
cloud_provider = "aws"
framework = "cis"
cis_version = "v1.3.0"
}
}
control "cisv130_1_4" {
title = "1.4 Ensure no root user account access key exists (Automated)"
description = "The root user account is the most privileged user in an AWS account. AWS Access Keys provide programmatic access to a given AWS account. It is recommended that all access keys associated with the root user account be removed."
sql = query.iam_credential_report_root_user_access_key.sql
documentation = file("docs/cisv130_1_4.md")
tags = {
cloud_provider = "aws"
framework = "cis"
cis_version = "v1.3.0"
cis_item_id = "1.4"
cis_control = "4.3"
cis_type = "automated"
cis_level = "1"
}
}

Argument Reference

ArgumentTypeRequired?Description
childrenListOptionalAn ordered list of control and/or benchmark references that are members (direct descendants) of the benchmark.
descriptionStringOptionalA description of the benchmark
documentationString (Markdown)OptionalA markdown string containing a long form description, used as documentation for the mod on hub.steampipe.io.
tagsmapOptionalA map of key:value metadata for the benchmark, used to categorize, search, and filter. The structure is up to the mod author and varies by benchmark and provider.
titleStringOptionalA display title for the benchmark

mod

Every mod (that is not a workspace) must contain a mod.sp file with a single mod block:

The Mod block contains metadata for the mod (including metadata used in the hub site and social media), as well as dependency data. A User may edit the mod block directly, but Steampipe will also edit the file, adding removing and modifying dependencies in the file when users add and remove mods via the steampipe mod commands.

The block name (aws_cis in the example) is the mod name. Mod names (and aliases) use lower_snake_case - They may contain lowercase chars, numbers or underscores, and must start with a letter.

Example Usage

mod "aws_cis" {
# hub metadata
title = "AWS CIS"
description = "AWS CIS Reporting and remediation"
color = "#FF9900"
documentation = file(./aws_cis_docs.md)
icon = "/images/plugins/turbot/aws.svg"
categories = ["Public Cloud", "AWS"]
opengraph {
title = "Steampipe Mod for AWS CIS"
description = "CIS reports, queries, and actions for AWS. Open source CLI. No DB required."
}
}

Argument Reference

NameTypeRequired?Description
categoriesList(String)OptionalA list of labels, used to categorize mods (such as on the Steampipe Hub).
colorStringOptionalA hexadecimal RGB value to use as the color scheme for the mod on hub.steampipe.io.
descriptionStringOptionalA string containing a short description.
documentationString (Markdown)OptionalA markdown string containing a long form description, used as documentation for the mod on hub.steampipe.io.
iconStringOptionalThe url of an icon to use for the mod on hub.steampipe.io.
opengraphBlockOptionalBlock of metadata for use in social media applications that support Opengraph metadata.
tagsmapOptionalA map of key:value metadata for the benchmark, used to categorize, search, and filter.
titleStringOptionalThe display title of the mod.

opengraph

The opengraph block is an optional block of metadata for use in social media applications that support Opengraph metadata.

NameTypeDescription
descriptionStringThe opengraph description (og:description) of the mod, for use in social media applications.
titleStringThe opengraph display title (og:title) of the mod, for use in social media applications.

query

Queries define common SQL statements that may be used alone, or referenced by arguments in other blocks like reports and actions.

Note that a Steampipe query is NOT a database resource - it does not create a view, stored procedure, etc. query blocks are interpreted by and executed by Steampipe, and are only available from Steampipe, not from 3rd party tools.

Steampipe queries can only be run as-is - they cannot appear inside other queries, you cannot select from them or add qualifiers to them.

Example Usage

query "plus_size_instances" {
title = "EC2 Instances xlarge and bigger"
sql = "select * from aws_ec2_instance where instance_type like '%xlarge'"
}
query "s3_bucket_encryption_in_transit_control" {
description = "Ensure S3 Bucket Policy forces HTTPS"
sql = <<-EOI
with ok_buckets as(
select
distinct(name)
from
aws_s3_bucket,
jsonb_array_elements(policy_std -> 'Statement') as s,
jsonb_array_elements_text(s -> 'Principal' -> 'AWS') as p,
jsonb_array_elements_text(s -> 'Condition' -> 'Bool' -> 'aws:securetransport') as ssl
where
p = '*'
and s ->> 'Effect' = 'Deny'
and ssl :: bool = false
)
select
case
when name in (select name from ok_buckets)
then 'OK'
else 'ALARM'
end as "status",
case
when name in (select name from ok_buckets)
then 'HTTPS is enforced in the bucket policy'
else 'HTTPS is not enforced in the bucket policy'
end as "reason",
name as resource,
account_id,
partition,
region
from
aws_s3_bucket;
EOI
}

In the Steampipe query shell or in a non interactive steampipe query command, you can run a query by its fully qualified name:

> aws_ec2_reports.query.prohibited_instance_types
$ steampipe query "aws_ec2_reports.query.plus_size_instances"

Argument Reference

ArgumentTypeRequired?Description
sqlStringRequiredSQL statement to define the query.
descriptionStringOptionalA description of the query
documentationString (Markdown)OptionalA markdown string containing a long form description, used as documentation for the mod on hub.steampipe.io.
search_pathStringOptionala schema search path to use for this query
search_path_prefixStringOptionalA schema search path to prefer for this query
tagsmapOptionalA map of key:value metadata for the benchmark, used to categorize, search, and filter. The structure is up to the mod author and varies by benchmark and provider.
titleStringOptionalA display title for the query