Skip to main content

terraform

Permit.io Terraform Provider

The Permit.io Terraform Provider allows you to manage your authorization policies, resources, roles, and permissions as infrastructure code. This enables you to version control your authorization policies, automate deployments, and maintain consistency across environments.

What is Infrastructure as Code (IaC)?

Infrastructure as Code is the practice of managing and provisioning computing infrastructure through machine-readable definition files rather than physical hardware configuration or interactive configuration tools. With Terraform, you can:

  • Version Control: Track changes to your authorization policies in Git
  • Automation: Deploy policies consistently across environments
  • Collaboration: Review and approve policy changes through pull requests
  • Reproducibility: Ensure identical environments across development, staging, and production

Quick Start

Prerequisites

Before you begin, ensure you have:

1. Get Your API Key

  1. Go to app.permit.io
  2. Navigate to SettingsAPI Keys
  3. Copy your environment-level API key

2. Create Your First Terraform Configuration

Create a new directory for your Terraform project and add the following files:

main.tf - Main Terraform configuration:

terraform {
required_providers {
permitio = {
source = "registry.terraform.io/permitio/permit-io"
version = "~> 0.0.14" # Use the latest version
}
}
}

# Configure the Permit.io provider
provider "permitio" {
api_key = "YOUR_API_KEY" # Replace with your actual API key
# api_url = "https://api.permit.io" # Optional: defaults to https://api.permit.io
}

# Define a resource (e.g., documents in your application)
resource "permitio_resource" "document" {
key = "document"
name = "Document"
description = "A confidential document that users can read and write"

actions = {
"read" = {
"name" = "Read"
"description" = "Read a document"
}
"write" = {
"name" = "Write"
"description" = "Write to a document"
}
"delete" = {
"name" = "Delete"
"description" = "Delete a document"
}
}

attributes = {
"title" = {
"description" = "The title of the document"
"type" = "string"
}
"owner" = {
"description" = "The owner of the document"
"type" = "string"
}
}
}

# Define roles with specific permissions
resource "permitio_role" "reader" {
key = "reader"
name = "Reader"
description = "Can read documents but cannot modify them"
permissions = ["document:read"]

depends_on = [permitio_resource.document]
}

resource "permitio_role" "writer" {
key = "writer"
name = "Writer"
description = "Can read and write documents"
permissions = ["document:read", "document:write"]

depends_on = [permitio_resource.document]
}

resource "permitio_role" "admin" {
key = "admin"
name = "Administrator"
description = "Full access to documents including deletion"
permissions = ["document:read", "document:write", "document:delete"]

depends_on = [permitio_resource.document]
}

variables.tf - Define variables for better configuration management:

variable "permit_api_key" {
description = "Permit.io API key"
type = string
sensitive = true
}

variable "permit_api_url" {
description = "Permit.io API URL"
type = string
default = "https://api.permit.io"
}

terraform.tfvars - Set your actual values (don't commit this file):

permit_api_key = "your-actual-api-key-here"
permit_api_url = "https://api.permit.io"

3. Initialize and Apply

# Initialize Terraform
terraform init

# Plan your changes
terraform plan

# Apply the configuration
terraform apply

Using with OpenTofu

OpenTofu is an open-source fork of Terraform that maintains compatibility with Terraform providers and configurations. You can use the Permit.io Terraform provider with OpenTofu without any modifications to your configuration files.

Installing OpenTofu

# Using Homebrew (macOS/Linux)
brew install opentofu

# Using the official installer
curl -fsSL https://get.opentofu.org/install.sh | sh

# Using package managers
# Ubuntu/Debian
sudo apt-get install opentofu

# CentOS/RHEL/Fedora
sudo dnf install opentofu

Using OpenTofu Commands

Replace terraform commands with tofu:

# Initialize OpenTofu
tofu init

# Plan your changes
tofu plan

# Apply the configuration
tofu apply

# Show current state
tofu show

# Destroy resources
tofu destroy

Configuration Compatibility

Your Terraform configuration files work exactly the same with OpenTofu:

terraform {
required_providers {
permitio = {
source = "registry.terraform.io/permitio/permit-io"
version = "~> 0.0.14"
}
}
}

provider "permitio" {
api_key = "YOUR_API_KEY"
}

# All your resources remain the same
resource "permitio_resource" "document" {
key = "document"
name = "Document"
description = "A confidential document"
# ... rest of configuration
}

Benefits of Using OpenTofu

  • Open Source: Fully open-source with community-driven development
  • Terraform Compatible: Drop-in replacement for Terraform
  • Enhanced Features: Some additional features and improvements over Terraform
  • Active Development: Regular updates and community contributions
  • Same Provider Ecosystem: Uses the same Terraform Registry and providers

Core Concepts

Resources

Resources in Permit.io represent the objects that users can access in your application (e.g., documents, users, projects).

resource "permitio_resource" "example" {
key = "unique_key"
name = "Human Readable Name"
description = "Description of what this resource represents"

actions = {
"action_key" = {
"name" = "Human Readable Action"
"description" = "What this action does"
}
}

attributes = {
"attribute_name" = {
"description" = "Description of the attribute"
"type" = "string" # or "number", "boolean", "array", "object"
}
}
}

Roles

Roles define what actions users can perform on resources.

resource "permitio_role" "example" {
key = "role_key"
name = "Role Name"
description = "What this role allows users to do"
permissions = ["resource:action"] # Format: "resource_key:action_key"

depends_on = [permitio_resource.resource_name]
}

User Sets and Resource Sets

User Sets and Resource Sets allow you to group users and resources based on conditions.

# Group users by email domain
resource "permitio_user_set" "admins" {
key = "admins"
name = "Administrators"
conditions = jsonencode({
"allOf" = [
{
"subject.email" = {
contains = "@admin.com"
}
}
]
})
}

# Group resources by attribute
resource "permitio_resource_set" "public_docs" {
key = "public_docs"
name = "Public Documents"
resource = permitio_resource.document.key
conditions = jsonencode({
"allOf" = [
{
"resource.visibility" = {
equals = "public"
}
}
]
})
}

Condition Set Rules

Condition Set Rules define when specific permissions apply based on user and resource sets.

resource "permitio_condition_set_rule" "admin_access" {
user_set = permitio_user_set.admins.key
resource_set = permitio_resource_set.public_docs.key
permission = "document:read"
}

Advanced Examples

ReBAC (Relationship-Based Access Control)

The Terraform provider supports ReBAC for complex hierarchical permissions:

# Define resources with relationships
resource "permitio_resource" "folder" {
key = "folder"
name = "Folder"
actions = {
"list" = { "name" = "List" }
"create" = { "name" = "Create" }
}
}

resource "permitio_resource" "file" {
key = "file"
name = "File"
actions = {
"read" = { "name" = "Read" }
"write" = { "name" = "Write" }
}
}

# Define the relationship
resource "permitio_relation" "parent" {
key = "parent"
name = "parent of"
subject_resource = permitio_resource.folder.key
object_resource = permitio_resource.file.key
}

# Define roles for each resource
resource "permitio_role" "folder_admin" {
key = "admin"
name = "Folder Administrator"
permissions = ["folder:list", "folder:create"]
resource = permitio_resource.folder.key
}

resource "permitio_role" "file_admin" {
key = "admin"
name = "File Administrator"
permissions = ["file:read", "file:write"]
resource = permitio_resource.file.key
}

# Derive file permissions from folder permissions
resource "permitio_role_derivation" "folder_to_file" {
resource = permitio_resource.file.key
role = permitio_role.file_admin.key
on_resource = permitio_resource.folder.key
to_role = permitio_role.folder_admin.key
linked_by = permitio_relation.parent.key
}

User Attributes

Define custom attributes for users to enable attribute-based access control:

resource "permitio_user_attribute" "department" {
key = "department"
description = "The department the user belongs to"
type = "string"
}

resource "permitio_user_attribute" "security_level" {
key = "security_level"
description = "User's security clearance level"
type = "number"
}

Repository Examples

The Permit.io Terraform Provider repository contains comprehensive examples:

Basic Example

View the basic example that demonstrates:

  • Resource creation with actions and attributes
  • Role definition with permissions
  • User sets and resource sets
  • Condition set rules
  • Basic proxy configuration

ReBAC Example

View the ReBAC example that shows:

  • Resource relationships
  • Role derivations
  • Hierarchical permission inheritance

Environment Variables

For better security, use environment variables instead of hardcoding API keys:

export PERMITIO_API_KEY="your-api-key"
export PERMITIO_API_URL="https://api.permit.io" # Optional

Then in your Terraform configuration:

provider "permitio" {
# Terraform will automatically use the environment variables
}

Best Practices

1. Use Variables for Configuration

variable "environment" {
description = "Environment name (dev, staging, prod)"
type = string
}

resource "permitio_resource" "document" {
key = "document"
name = "Document"
description = "Documents for ${var.environment} environment"
# ... rest of configuration
}

2. Use Data Sources for Existing Resources

data "permitio_resource" "existing_document" {
key = "document"
}

resource "permitio_role" "reader" {
permissions = ["${data.permitio_resource.existing_document.key}:read"]
}

3. Use Outputs for Important Information

output "resource_id" {
value = permitio_resource.document.id
}

output "role_permissions" {
value = permitio_role.admin.permissions
}

4. Use Workspaces for Environment Separation

# Create separate workspaces for different environments
terraform workspace new dev
terraform workspace new staging
terraform workspace new prod

# Switch between workspaces
terraform workspace select dev
note

OpenTofu Users: Replace terraform with tofu in all workspace commands:

tofu workspace new dev
tofu workspace select dev

Troubleshooting

Common Issues

  1. API Key Issues

    • Ensure you're using an environment-level API key, not a workspace-level key
    • Verify the API key has the correct permissions
  2. Resource Dependencies

    • Use depends_on when resources reference each other
    • Ensure resources are created before roles that reference them
  3. Permission Format

    • Use the format resource_key:action_key for permissions
    • Ensure the resource and action keys match exactly

Getting Help

Next Steps

Now that you have the basics, explore:


info

Need Help? Join our Slack community (channel #permit-saas), or (if you're in less of a hurry) check out our GitHub issues for support.