Blog

Introducing the Cedar Terraform Provider

Chris Norman
Chris Norman
July 31, 2024
Introducing the Cedar Terraform Provider

At Common Fate we're big fans of authorization-as-code. Treating your authorization policies as source code means you can test and review changes using your existing tools like Terraform and GitHub. We use Cedar as the authorization-as-code framework in our product.

If you're unfamiliar with Cedar, you can check out our introductory blog post here.

We have released a Cedar Terraform Provider to make authoring Cedar policies easier in Terraform. The provider allows you to write authorization policies using HCL, Terraform's configuration syntax. Here's a simple example:

data "cedar_policyset" "example" {
  policy {
    effect = "permit"

    annotation {
      name = "advice"
      value = "You can request access because you are in the Engineering team."
    }

    principal_in = {
      type = "AWS::IDC::Group"
      id   = "12345-12345-12345"
    }
    action = {
      type = "Access::Action"
      id   = "Request"
    }
    any_resource = true

    when {
      text = "resource.target in AWS::OrgUnit::\"ou-123\""
    }
  }
}

resource "commonfate_policyset" "example" {
    id = "example"
    text = data.cedar_policyset.example.text
}

The cedar_policyset resource renders a Cedar policy, available as data.cedar_policyset.example.text. Here's what the resulting policy looks like:

@advice("You can request access because you are in the Engineering team.")
permit (
  principal in [AWS::IDC::Group::"12345-12345-12345"],
  action == Access::Action::"Request",
  resource
)
when {
  resource.target in AWS::OrgUnit::"ou-123"
};

The provider allows you to use Terraform variables in your policies. For example, we can configure an on-call rotation in PagerDuty, as well as authorization policies for access workflows in one place:

resource "pagerduty_schedule" "example" {
  name      = "Daily Engineering Rotation"
  time_zone = "America/New_York"

  layer {
    name                         = "Night Shift"
    start                        = "2015-11-06T20:00:00-05:00"
    rotation_virtual_start       = "2015-11-06T20:00:00-05:00"
    rotation_turn_length_seconds = 86400
    users                        = [pagerduty_user.example.id]

    restriction {
      type              = "daily_restriction"
      start_time_of_day = "08:00:00"
      duration_seconds  = 32400
    }
  }

  teams = [pagerduty_team.example.id]
}

data "cedar_policyset" "example" {
  policy {
    effect = "permit"

    annotation {
      name = "advice"
      value = "Access is automatically approved because you are on-call in the ${pagerduty_schedule.example.name} rotation."
    }

    principal_in = {
      type = "PagerDuty::OnCall"
      id   = pagerduty_schedule.example.id
    }
    action = {
      type = "Access::Action"
      id   = "Activate"
    }
    any_resource = true
  }
}

You can learn more about the provider here.

Share this post
Chris Norman
Co-Founder