Skip to content

CI CD Integration

Andy Rea edited this page Oct 18, 2025 · 1 revision

CI/CD Integration

Automate IAM policy testing in your CI/CD pipeline to catch misconfigurations before deployment.

GitHub Actions

Basic Workflow

name: IAM Policy Tests

on:
  pull_request:
    paths:
      - 'policies/**'
      - 'scenarios/**'
  push:
    branches: [main]

jobs:
  test-policies:
    runs-on: ubuntu-latest

    permissions:
      id-token: write  # Required for OIDC
      contents: read

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

      - name: Download politest
        run: |
          wget https://github.com/reaandrew/politest/releases/latest/download/politest-linux-amd64
          chmod +x politest-linux-amd64
          sudo mv politest-linux-amd64 /usr/local/bin/politest

      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
          aws-region: us-east-1

      - name: Run IAM policy tests
        run: |
          for scenario in scenarios/*.yml; do
            echo "Testing: $scenario"
            politest --scenario "$scenario"
          done

With Test Matrix

jobs:
  test-policies:
    strategy:
      matrix:
        environment: [dev, staging, prod]

    steps:
      - name: Run tests for ${{ matrix.environment }}
        run: |
          politest --scenario scenarios/${{ matrix.environment }}/test.yml

GitLab CI

test-iam-policies:
  image: alpine:latest
  before_script:
    - apk add --no-cache wget
    - wget https://github.com/reaandrew/politest/releases/latest/download/politest-linux-amd64
    - chmod +x politest-linux-amd64
    - mv politest-linux-amd64 /usr/local/bin/politest
  script:
    - |
      for scenario in scenarios/*.yml; do
        politest --scenario "$scenario"
      done
  only:
    changes:
      - policies/**
      - scenarios/**

AWS OIDC Setup

Create an IAM role for GitHub Actions:

Trust Policy:

{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Principal": {
      "Federated": "arn:aws:iam::YOUR_ACCOUNT:oidc-provider/token.actions.githubusercontent.com"
    },
    "Action": "sts:AssumeRoleWithWebIdentity",
    "Condition": {
      "StringEquals": {
        "token.actions.githubusercontent.com:aud": "sts.amazonaws.com",
        "token.actions.githubusercontent.com:sub": "repo:YOUR_ORG/YOUR_REPO:ref:refs/heads/main"
      }
    }
  }]
}

Permissions Policy:

{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Action": "iam:SimulateCustomPolicy",
    "Resource": "*"
  }]
}

Pre-Commit Hook

Run tests before committing policy changes:

#!/bin/bash
# .git/hooks/pre-commit

# Check if policy files changed
CHANGED=$(git diff --cached --name-only | grep 'policies/.*\.json')

if [ -n "$CHANGED" ]; then
  echo "IAM policies changed, running tests..."

  for scenario in scenarios/*.yml; do
    if ! politest --scenario "$scenario"; then
      echo "❌ Policy tests failed!"
      exit 1
    fi
  done

  echo "✓ All policy tests passed"
fi

Makefile

.PHONY: test-policies
test-policies:
	@for scenario in scenarios/*.yml; do \
		echo "Testing $$scenario..."; \
		politest --scenario "$$scenario" || exit 1; \
	done

.PHONY: test-dev
test-dev:
	politest --scenario scenarios/dev/*.yml

.PHONY: test-prod
test-prod:
	politest --scenario scenarios/prod/*.yml

Docker

FROM alpine:latest

RUN apk add --no-cache aws-cli wget

RUN wget https://github.com/reaandrew/politest/releases/latest/download/politest-linux-amd64 \
    && chmod +x politest-linux-amd64 \
    && mv politest-linux-amd64 /usr/local/bin/politest

WORKDIR /workspace

ENTRYPOINT ["politest"]

Usage:

docker run -v $(pwd):/workspace \
  -e AWS_ACCESS_KEY_ID \
  -e AWS_SECRET_ACCESS_KEY \
  politest-image --scenario scenarios/test.yml

Best Practices

1. Fail Fast

set -e  # Exit on first failure
for scenario in scenarios/*.yml; do
  politest --scenario "$scenario"
done

2. Parallel Testing

# GNU Parallel
find scenarios -name '*.yml' | parallel politest --scenario {}

# xargs
find scenarios -name '*.yml' | xargs -P 4 -I {} politest --scenario {}

3. Environment-Specific Tests

# Only test prod scenarios on main branch
- name: Test production policies
  if: github.ref == 'refs/heads/main'
  run: politest --scenario scenarios/prod/*.yml

4. Cache politest Binary

- name: Cache politest
  uses: actions/cache@v3
  with:
    path: ~/.local/bin/politest
    key: politest-${{ runner.os }}-v1

Next Steps


Working CI example: .github/workflows/ci.yml

Clone this wiki locally