Documentation / Guides

Terraform Provider

Manage TigerIdentity policies, principals, and connectors as code with Terraform

Why Infrastructure as Code?

The TigerIdentity Terraform provider allows you to define and manage your entire access control configuration as code. This enables GitOps workflows, version control, automated testing, and reproducible deployments.

Benefits

Version Control: Track all policy changes in Git
Code Review: PR-based approval for policy changes
Automated Testing: Validate policies in CI/CD
Reproducibility: Deploy identical configs across environments
Disaster Recovery: Rebuild from code in minutes
Compliance: Audit trail of all configuration changes

What You Can Manage

  • • Policies and rules
  • • Principals (users, services, agents)
  • • Connectors and integrations
  • • Resources and tags
  • • Approval workflows
  • • Access reviews

Installation

1. Configure Terraform Provider

Add the TigerIdentity provider to your Terraform configuration.

# main.tf
terraform {
  required_version = ">= 1.5"

  required_providers {
    tigeridentity = {
      source  = "tigeridentity/tigeridentity"
      version = "~> 1.0"
    }
  }
}

# Configure the provider
provider "tigeridentity" {
  # API endpoint (defaults to production)
  endpoint = "https://api.tigeridentity.com"

  # Authentication
  api_key = var.tigeridentity_api_key  # From environment variable

  # Optional: Organization ID (if managing multiple orgs)
  organization_id = "org_abc123"
}

2. Set Environment Variables

# Set API key
export TF_VAR_tigeridentity_api_key="ti_prod_a1b2c3d4e5f6..."

# Or use .env file (don't commit!)
echo 'tigeridentity_api_key = "ti_prod_..."' > terraform.tfvars

3. Initialize Terraform

terraform init

# Output:
# Initializing provider plugins...
# - Finding tigeridentity/tigeridentity versions matching "~> 1.0"...
# - Installing tigeridentity/tigeridentity v1.0.0...
# Terraform has been successfully initialized!

Getting an API Key

Generate a Terraform-specific API key with appropriate permissions in the TigerIdentity dashboard under Settings → API Keys → Create Key → Select "Terraform" scope.

Resources

The provider supports the following resource types:

tigeridentity_policy

Manage authorization policies.

resource "tigeridentity_policy" "prod_database_access" {
  name        = "prod-database-access"
  description = "Production database access with JIT approval"

  # Resources this policy applies to
  resources {
    type        = "database"
    environment = "production"
    tags = {
      tier = "critical"
    }
  }

  # Default decision
  default_decision = "deny"

  # Rules
  rule {
    name   = "engineer-jit-access"
    effect = "allow_with_approval"

    principals {
      department = "engineering"
      role       = ["senior_engineer", "staff_engineer"]
    }

    actions = ["query", "admin"]

    # Approval workflow
    approval {
      required = true

      approver {
        type = "manager"
      }

      approver {
        type = "role"
        role = "security_lead"
      }

      timeout_minutes = 60
    }

    # Session configuration
    session {
      max_duration_hours = 2
      can_extend         = true
      max_extensions     = 1
      require_justification = true
    }
  }

  # Break-glass rule
  rule {
    name   = "emergency-access"
    effect = "allow"

    principals {
      role = ["oncall_engineer", "security_lead"]
    }

    context {
      emergency = true
    }

    session {
      max_duration_hours = 4
      require_justification = true
    }

    notification {
      channel = "slack"
      webhook = var.slack_webhook_url
      message = "Emergency DB access granted to {{principal}}"
    }
  }
}

tigeridentity_principal

Manage principals (users, services, AI agents).

# Service account
resource "tigeridentity_principal" "github_actions" {
  type = "service"
  name = "github-actions-ci"

  attributes = {
    description = "GitHub Actions CI/CD runner"
    environment = "ci"
    repository  = "tigeridentity/main"
  }

  # API key rotation
  api_key_rotation {
    enabled       = true
    rotation_days = 90
  }
}

# AI Agent
resource "tigeridentity_principal" "customer_support_agent" {
  type = "ai_agent"
  name = "customer-support-agent"

  attributes = {
    agent_type  = "assistant"
    model       = "claude-3-5-sonnet"
    department  = "customer_success"
    risk_level  = "medium"
    capabilities = ["read_customer_data", "create_tickets", "send_emails"]
  }

  relationships {
    owner = "user_alice"
    team  = "customer-success"
  }
}

tigeridentity_connector

Manage integrations with identity sources and target systems.

# Okta SCIM Connector
resource "tigeridentity_connector" "okta" {
  name = "okta-production"
  type = "scim"

  config = {
    endpoint     = "https://your-domain.okta.com/api/v1/scim/v2"
    auth_type    = "oauth2"
    client_id    = var.okta_client_id
    client_secret = var.okta_client_secret
    token_url    = "https://your-domain.okta.com/oauth2/v1/token"
  }

  sync_settings {
    sync_interval_minutes      = 15
    full_sync_interval_hours   = 24
    sync_users                 = true
    sync_groups                = true
    sync_group_memberships     = true
  }

  attribute_mapping {
    user {
      email       = "emails[primary eq true].value"
      first_name  = "name.givenName"
      last_name   = "name.familyName"
      department  = "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:department"
      manager     = "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:manager.value"
    }
  }
}

# AWS Connector
resource "tigeridentity_connector" "aws_prod" {
  name = "aws-production"
  type = "aws"

  config = {
    role_arn = "arn:aws:iam::123456789:role/TigerIdentityReader"
    regions  = ["us-east-1", "us-west-2"]
  }

  sync_settings {
    sync_interval_minutes = 60
  }

  resources_to_sync = [
    "iam_users",
    "iam_roles",
    "rds_databases",
    "s3_buckets"
  ]
}

Data Sources

Query existing TigerIdentity resources in your Terraform code.

# Look up existing principal
data "tigeridentity_principal" "alice" {
  email = "[email protected]"
}

# Look up existing policy
data "tigeridentity_policy" "existing_policy" {
  name = "prod-database-access"
}

# Use in other resources
resource "tigeridentity_policy" "new_policy" {
  name = "derived-policy"

  rule {
    principals {
      id = data.tigeridentity_principal.alice.id
    }
    # ...
  }
}

# Query all principals by type
data "tigeridentity_principals" "ai_agents" {
  filter {
    type = "ai_agent"
  }
}

output "agent_count" {
  value = length(data.tigeridentity_principals.ai_agents.principals)
}

Complete Example

A full Terraform configuration managing policies, connectors, and principals.

# variables.tf
variable "tigeridentity_api_key" {
  type      = string
  sensitive = true
}

variable "environment" {
  type    = string
  default = "production"
}

# main.tf
terraform {
  required_providers {
    tigeridentity = {
      source  = "tigeridentity/tigeridentity"
      version = "~> 1.0"
    }
  }

  # Remote state
  backend "s3" {
    bucket = "mycompany-terraform-state"
    key    = "tigeridentity/prod/terraform.tfstate"
    region = "us-east-1"
  }
}

provider "tigeridentity" {
  api_key = var.tigeridentity_api_key
}

# Okta connector
resource "tigeridentity_connector" "okta" {
  name = "okta-${var.environment}"
  type = "scim"

  config = {
    endpoint      = "https://mycompany.okta.com/api/v1/scim/v2"
    auth_type     = "oauth2"
    client_id     = var.okta_client_id
    client_secret = var.okta_client_secret
    token_url     = "https://mycompany.okta.com/oauth2/v1/token"
  }

  sync_settings {
    sync_interval_minutes = 15
    sync_users            = true
    sync_groups           = true
  }
}

# Production database policy
resource "tigeridentity_policy" "prod_database" {
  name        = "prod-database-jit"
  description = "JIT access to production databases"

  resources {
    type        = "database"
    environment = "production"
  }

  default_decision = "deny"

  rule {
    name   = "engineer-access"
    effect = "allow_with_approval"

    principals {
      department = "engineering"
    }

    actions = ["query", "admin"]

    approval {
      required = true
      approver {
        type = "manager"
      }
      timeout_minutes = 60
    }

    session {
      max_duration_hours    = 2
      require_justification = true
    }
  }
}

# AWS production policy
resource "tigeridentity_policy" "aws_prod" {
  name        = "aws-production-access"
  description = "Access to AWS production account"

  resources {
    type     = "aws_account"
    account_id = "123456789012"
  }

  default_decision = "deny"

  rule {
    name   = "platform-team-access"
    effect = "allow_with_approval"

    principals {
      groups = ["platform-team"]
    }

    actions = ["admin"]

    approval {
      required = true
      approver {
        type = "role"
        role = "security_lead"
      }
    }

    session {
      max_duration_hours = 4
    }
  }
}

# Customer support AI agent
resource "tigeridentity_principal" "support_agent" {
  type = "ai_agent"
  name = "customer-support-agent"

  attributes = {
    agent_type = "assistant"
    model      = "claude-3-5-sonnet"
    department = "customer_success"
  }

  relationships {
    owner = "user_alice"
  }
}

# Policy for AI agent
resource "tigeridentity_policy" "support_agent_policy" {
  name = "customer-support-agent-access"

  resources {
    type = "customer_data"
    sensitivity = ["public", "internal"]  # Not confidential
  }

  default_decision = "deny"

  rule {
    name   = "read-customer-data"
    effect = "allow"

    principals {
      id = tigeridentity_principal.support_agent.id
    }

    actions = ["read", "search"]

    context {
      time_of_day = "business_hours"
    }

    data_masking {
      enabled = true
      fields  = ["ssn", "credit_card"]
    }
  }
}

# Outputs
output "okta_connector_id" {
  value = tigeridentity_connector.okta.id
}

output "support_agent_id" {
  value = tigeridentity_principal.support_agent.id
}

output "policy_count" {
  value = 3
}

Deploy

# Plan changes
terraform plan

# Apply configuration
terraform apply

# Output:
# tigeridentity_connector.okta: Creating...
# tigeridentity_principal.support_agent: Creating...
# tigeridentity_policy.prod_database: Creating...
# tigeridentity_policy.aws_prod: Creating...
# tigeridentity_policy.support_agent_policy: Creating...
#
# Apply complete! Resources: 5 added, 0 changed, 0 destroyed.

CI/CD Integration

Automate policy deployment with GitHub Actions, GitLab CI, or other CI/CD platforms.

GitHub Actions Example

# .github/workflows/terraform.yml
name: Terraform TigerIdentity

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

env:
  TF_VAR_tigeridentity_api_key: ${{ secrets.TIGERIDENTITY_API_KEY }}

jobs:
  terraform:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - name: Setup Terraform
        uses: hashicorp/setup-terraform@v2
        with:
          terraform_version: 1.5.0

      - name: Terraform Init
        run: terraform init

      - name: Terraform Format Check
        run: terraform fmt -check

      - name: Terraform Validate
        run: terraform validate

      - name: Terraform Plan
        id: plan
        run: terraform plan -no-color
        continue-on-error: true

      - name: Comment PR with Plan
        if: github.event_name == 'pull_request'
        uses: actions/github-script@v6
        with:
          script: |
            const output = `#### Terraform Plan 📖
            <details><summary>Show Plan</summary>

            \`\`\`
            ${{ steps.plan.outputs.stdout }}
            \`\`\`

            </details>`;

            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: output
            })

      - name: Terraform Apply
        if: github.ref == 'refs/heads/main' && github.event_name == 'push'
        run: terraform apply -auto-approve

      - name: Notify on Failure
        if: failure()
        uses: slackapi/slack-github-action@v1
        with:
          webhook-url: ${{ secrets.SLACK_WEBHOOK }}
          payload: |
            {
              "text": "Terraform deployment failed for TigerIdentity"
            }

GitLab CI Example

# .gitlab-ci.yml
stages:
  - validate
  - plan
  - apply

variables:
  TF_VAR_tigeridentity_api_key: $TIGERIDENTITY_API_KEY

terraform-validate:
  stage: validate
  image: hashicorp/terraform:1.5
  script:
    - terraform init
    - terraform fmt -check
    - terraform validate

terraform-plan:
  stage: plan
  image: hashicorp/terraform:1.5
  script:
    - terraform init
    - terraform plan -out=tfplan
  artifacts:
    paths:
      - tfplan

terraform-apply:
  stage: apply
  image: hashicorp/terraform:1.5
  script:
    - terraform init
    - terraform apply tfplan
  only:
    - main
  when: manual  # Require manual approval

Best Practices

Use Remote State

Store Terraform state in S3, GCS, or Terraform Cloud. Never commit state files to Git.

Separate Environments

Use separate Terraform workspaces or directories for dev, staging, and production.

Module Reuse

Create reusable modules for common policy patterns (e.g., JIT database access).

PR-Based Workflow

Require pull requests for all policy changes. Run terraform plan in CI and post results to PR.

Secrets Management

Never hardcode API keys. Use environment variables, Vault, or CI/CD secrets.

Policy Validation

Use terraform validate and custom tests to catch errors before deployment.

Incremental Rollout

Deploy policy changes gradually. Use mode = "audit" first, then enforce.

Troubleshooting

Error: Provider authentication failed

Cause: Invalid or expired API key

Solution: Verify your API key is correct and has not expired. Generate a new key if needed.

export TF_VAR_tigeridentity_api_key="ti_prod_..."

Error: Resource already exists

Cause: Trying to create a resource that already exists

Solution: Import the existing resource into Terraform state

terraform import tigeridentity_policy.prod_db prod-database-access

Slow Terraform apply

Cause: Large number of resources or slow API

Solution: Use -parallelism=20 to increase concurrency

terraform apply -parallelism=20

Manage Policies as Code

Start using the TigerIdentity Terraform provider today