Skip to content

Commit

Permalink
Merge pull request #33 from inspec/add-iam-resources
Browse files Browse the repository at this point in the history
Add iam resources
  • Loading branch information
russellseymour authored Jun 25, 2018
2 parents d594986 + aec0c32 commit 2a80d39
Show file tree
Hide file tree
Showing 8 changed files with 267 additions and 0 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ The following resources are available in the InSpec GCP Profile
- [google_container_node_pool](docs/resources/google_container_node_pool.md)
- [google_container_node_pools](docs/resources/google_container_node_pools.md)
- [google_project](docs/resources/google_project.md)
- [google_project_iam_binding](docs/resources/google_project_iam_binding.md)
- [google_project_iam_bindings](docs/resources/google_project_iam_bindings.md)
- [google_project_iam_custom_role](docs/resources/google_project_iam_custom_role.md)
- [google_projects](docs/resources/google_projects.md)
- [google_service_account](docs/resources/google_service_account.md)
Expand Down
58 changes: 58 additions & 0 deletions docs/resources/google_project_iam_binding.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
---
title: About the google_project_iam_binding Resource
platform: gcp
---

# google\_project\_iam\_binding

Use the `google_project_iam_binding` InSpec audit resource to test properties of a single GCP project IAM binding.

<br>

## Syntax

A `google_project_iam_binding` resource block declares the tests for a single GCP project IAM binding by role.

describe google_project_iam_binding(project: 'chef-inspec-gcp', role: 'roles/compute.admin') do
it { should exist }
its('members') {should include 'user:[email protected]' }
end

<br>

## Examples

The following examples show how to use this InSpec audit resource.

### Test that a GCP project iam_binding exists

describe google_project_iam_binding(project: 'chef-inspec-gcp', iam_binding: 'us-east1-b') do
it { should exist }
end

### Test that a GCP project iam_binding is in the expected state

describe google_project_iam_binding(project: 'chef-inspec-gcp', iam_binding: 'us-east1-b') do
its('status') { should eq 'UP' }
# or equivalently
it { should be_up }
end

### Test that a GCP project iam_binding has an expected CPU platform

describe google_project_iam_binding(project: 'chef-inspec-gcp', iam_binding: 'us-east1-b') do
its('available_cpu_platforms') { should include "Intel Skylake" }
end

<br>

## Properties

* `available_cpu_platforms`, `creation_timestamp`, `description`, `id`, `kind`, `name`, `region`, `status`, `region_name`

<br>


## GCP Permissions

Ensure the [Compute Engine API](https://console.cloud.google.com/apis/library/project.googleapis.com/) is enabled for the project where the resource is located.
68 changes: 68 additions & 0 deletions docs/resources/google_project_iam_bindings.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
---
title: About the google_project_iam_bindings Resource
platform: gcp
---

# google\_project\_iam\_bindings

Use the `google_project_iam_bindings` InSpec audit resource to test properties of all, or a filtered group of, GCP project IAM bindings.

<br>

## Syntax

A `google_project_iam_bindings` resource block collects GCP project IAM bindings then tests that group.

describe google_project_iam_bindings(project: 'chef-inspec-gcp') do
it { should exist }
end

Use this InSpec resource to enumerate roles then test in-depth using `google_project_iam_binding`.

google_project_iam_bindings(project: 'chef-inspec-gcp').iam_binding_roles.each do |iam_binding_role|
describe google_project_iam_binding(project: 'chef-inspec-gcp', role: iam_binding_role) do
it { should exist }
its('members') {should include 'user:[email protected]' }
end
end

<br>

## Examples

The following examples show how to use this InSpec audit resource.

### Test that there are no more than a specified number of IAM bindings roles available for the project

describe google_project_iam_bindings(project: 'chef-inspec-gcp') do
its('count') { should be <= 100}
end

### Test that an expected iam_binding is available for the project

describe google_project_iam_bindings(project: 'chef-inspec-gcp') do
its('iam_binding_roles') { should include "roles/storage.admin" }
end

### Test that a particular role does not exist using filtering of the plural resource

describe google_project_iam_bindings(project: 'chef-inspec-gcp').where(iam_binding_role: "roles/iam.securityReviewer") do
it { should_not exist }
end

<br>

## Filter Criteria

This resource supports the following filter criteria: `iam_binding_role`. This may be used with `where`, as a block or as a method.

## Properties

* `iam_binding_roles` - an array of google_project_iam_binding role strings e.g. `["roles/compute.admin", "roles/owner"]`

<br>


## GCP Permissions

Ensure the [Cloud Resource Manager API](https://console.cloud.google.com/apis/library/cloudresourcemanager.googleapis.com/) is enabled for the project.
50 changes: 50 additions & 0 deletions libraries/google_project_iam_binding.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# frozen_string_literal: true

require 'gcp_backend'

module Inspec::Resources
class GoogleProjectIAMBinding < GcpResourceBase
name 'google_project_iam_binding'
desc 'Verifies settings for a single project IAM binding'

example "
describe google_project_iam_binding(project: 'chef-inspec-gcp', role: 'roles/compute.admin') do
it { should exist }
its('members') {should include 'user:[email protected]' }
end
"

def initialize(opts = {})
# Call the parent class constructor
super(opts)
@display_name = opts[:name]
@project = opts[:project]
@role = opts[:role]
@iam_binding_exists = false
@members_list=[]
catch_gcp_errors do
# note this is the same call as for the plural iam_bindings resource because there isn't an easy way to pull out a singular binding
@iam_bindings = @gcp.gcp_project_client.get_project_iam_policy(@project)
raise Inspec::Exceptions::ResourceFailed, "google_project_iam_binding is missing expected IAM policy 'bindings' property" if !@iam_bindings || !@iam_bindings.bindings
@iam_bindings.bindings.each do |binding|
next if binding.role != @role
@iam_binding_exists=true
@members_list=binding.members
end
end
end

# return the list of users corresponding to the role
def members
@members_list
end

def exists?
@iam_binding_exists
end

def to_s
"Project IAM Binding #{@display_name}"
end
end
end
40 changes: 40 additions & 0 deletions libraries/google_project_iam_bindings.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# frozen_string_literal: true

require 'gcp_backend'

module Inspec::Resources
class GoogleProjectIAMBindings < GcpResourceBase
name 'google_project_iam_bindings'
desc 'Verifies settings for GCP project iam_bindings in bulk'

example "
describe google_project_iam_bindings(project: 'chef-inspec-gcp') do
it { should exist }
...
end
"

def initialize(opts = {})
# Call the parent class constructor
super(opts)
@project = opts[:project]
end

# FilterTable setup
filter_table_config = FilterTable.create
filter_table_config.add(:iam_binding_roles, field: :iam_binding_role)
filter_table_config.connect(self, :fetch_data)

def fetch_data
iam_binding_rows = []
catch_gcp_errors do
@iam_bindings = @gcp.gcp_project_client.get_project_iam_policy(@project)
end
return [] if !@iam_bindings || !@iam_bindings.bindings
@iam_bindings.bindings.map do |iam_binding|
iam_binding_rows+=[{ iam_binding_role: iam_binding.role }]
end
@table = iam_binding_rows
end
end
end
15 changes: 15 additions & 0 deletions test/integration/verify/controls/google_compute_zone.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
title 'Test single GCP Zone'

gcp_project_id = attribute(:gcp_project_id, default: '', description: 'The GCP project identifier.')
gcp_zone = attribute(:gcp_zone, default: '', description: 'The GCP zone being used.')

control 'gcp-single-zone-1.0' do

impact 1.0
title 'Ensure single zone has the correct properties.'

describe google_compute_zone(project: gcp_project_id, name: gcp_zone) do
it { should exist }
it { should be_up }
end
end
16 changes: 16 additions & 0 deletions test/integration/verify/controls/google_project_iam_binding.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
title 'Test single GCP project IAM Binding'

gcp_project_id = attribute(:gcp_project_id, default: '', description: 'The GCP project identifier.')
gcp_enable_privileged_resources = attribute(:gcp_enable_privileged_resources,default:0,description:'Flag to enable privileged resources requiring elevated privileges in GCP.')

control 'gcp-project-iam-binding-1.0' do

only_if { gcp_enable_privileged_resources.to_i == 1 }
impact 1.0
title 'Ensure single GCP project IAM binding has the correct properties.'

describe google_project_iam_binding(project: gcp_project_id, role: "roles/compute.admin") do
it { should exist }
its ('members.count'){ should eq 1 }
end
end
18 changes: 18 additions & 0 deletions test/integration/verify/controls/google_project_iam_bindings.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
title 'GCP Project IAM Bindings Properties'

gcp_project_id = attribute(:gcp_project_id, default: '', description: 'The GCP project identifier.')
gcp_enable_privileged_resources = attribute(:gcp_enable_privileged_resources,default:0,description:'Flag to enable privileged resources requiring elevated privileges in GCP.')

control 'gcp-project-iam-bindings-1.0' do

only_if { gcp_enable_privileged_resources.to_i == 1 }
impact 1.0
title 'Ensure project IAM bindings have the correct properties in bulk'

describe google_project_iam_bindings(project: gcp_project_id) do
it { should exist }
its('count') { should be <= 100}
its('iam_binding_roles') { should include "roles/owner" }
end

end

0 comments on commit 2a80d39

Please sign in to comment.