Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add iam resources #33

Merged
merged 3 commits into from
Jun 25, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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