ruddles@home:~$

Mapping Repos in Wiz

I’ve been playing with a few different strategies for automatically assigning repos to projects in Wiz. Given we use projects and SSO mappings to limit access so engineers can only see issues linked to resources they own, this will give us the ability to show admins the findings of their repos.

Assuming you have a way to map teams to github teams, one option is to look at which teams are admins on the repo. The Resource Scopes on the projects are understandably limited and can’t do this out the box, but we can then use Resource Tagging Rules to apply tags to the repos, and we can use a resource scope on the project to match the tag to the project terraform.

This approach has one flaw, which is that it only works if there’s exactly one admin per repo. If you need to support multiple admins per repo you can switch things around a bit by changing the tag key per team and ignoring the value. I’ll cover that in another post.

The Project File

For this example I’m going to work with the following JSON which defines some properties for a team. We’ll make the github_team property optional to show how we can tackle it in terraform.

[
{
      "team_slug": "team-a",
      "team_name": "Team A",
      "github_team": "team-a-gh"
},
{
	  "team_slug": "team-b",
      "team_name": "Team B",
      "github_team": "team-b-gh"
},
{
	  "team_slug": "team-c",
      "team_name": "Team C"
}
...
]

Given this we can load the json into a local variable using the following:

locals {
  # teams json loaded into a map
  teams = jsondecode(file("teams.json"))

  # Key for the tag to be applied to repos
  tag_key = "repo-admin-team"
}

Resource Tagging

What we want to do is set up a resource tagging rule for each team, applying it to every repo object where that team is an admin.

We can us the lookup function to get the github_team property or an empty string if the property doesn’t exist.

resource "wiz_resource_tagging_rule" "repo_owning_team" {
  for_each = { for t in local.teams : t.team_slug => t if lookup(t, "github_team", "") != "" }

  # basic settings for the rule
  description = "Tag repos where the ${each.key} github team are admins"
  enabled     = true
  name        = "Repository Admin - ${each.key}"

  # Query finds all repos which have the given github team as admins
  query = jsonencode({
    relationships = [{
      type = [{
        reverse = true
        type    = "APPLIES_TO"
      }]
      with = {
        relationships = [{
          type = [{
            type = "PERMITS"
          }]
          with = {
            select = true
            type   = ["ACCESS_ROLE"]
            where = {
              name = {
                EQUALS = ["Admin"]
              }
            }
          }
          }, {
          type = [{
            type = "ASSIGNED_TO"
          }]
          with = {
            select = true
            type   = ["GROUP"]
            where = {
              name = {
                EQUALS = [each.value.github_team]
              }
            }
          }
        }]
        select = true
        type   = ["ACCESS_ROLE_BINDING"]
      }
    }]
    select = true
    type   = ["REPOSITORY"]
  })

  # Tag key and value, this will be prefixed with Wiz/
  tags {
    key   = local.tag_key
    value = each.value.github_team
  }
}

Finally we can loop through the collection to create a project for each team with a resource_filter_links object matching the Wiz/repo-ownership-team tag (custom tags in Wiz start with Wiz/).

Because in our example the github_team isn’t mandatory, we need to make the resource_filter_links dynamic so we can skip it if the team isn’t specified.

resource "wiz_project" "team_projects" {
  for_each = { for t in local.teams : t.team_slug => t }

  # Basic project values
  name = each.value.team_name
  slug = each.value.team_slug

  # Add a resource filter matching the tag applied above
  # only if the team have a github team specified
  dynamic "resource_filter_links" {
    for_each = lookup(each.value, "github_team", "") != "" ? [each.value.github_team] : []

    content {
      environment = "PRODUCTION"
      resource_tags_v2 {
        equals_all {
          key   = "Wiz/${local.tag_key}"
          value = each.value.github_team
        }
      }
    }
  }
}