Skip to main content

GitHub PR Checks Integration

Visus Agent Sandbox can automatically scan infrastructure changes in pull requests and enforce policies before code is merged.

Overview​

The GitHub PR Checks integration:

  • Scans infrastructure changes - Parses Terraform plans and CloudFormation templates in PRs
  • Evaluates policies - Runs infrastructure changes through Visus Agent Sandbox policy engine
  • Posts PR comments - Provides detailed feedback directly in the pull request
  • Fails CI checks - Blocks merging when blocking policies are triggered
  • Provides audit trail - All policy decisions are logged and HMAC-signed

Supported Infrastructure Formats​

Terraform​

Visus Agent Sandbox can parse Terraform plan JSON files to extract:

  • Resource creates, updates, and deletions
  • Resource tags
  • Operation parameters

Supported resources:

  • AWS RDS (CreateDBInstance, DeleteDBInstance, ModifyDBInstance)
  • AWS S3 (CreateBucket, DeleteBucket, PutObject, DeleteObject)
  • AWS IAM (CreateUser, CreateRole, CreatePolicy, DeleteUser, DeleteRole)
  • AWS Lambda (CreateFunction, DeleteFunction)
  • AWS DynamoDB (CreateTable, DeleteTable)
  • AWS EC2 (RunInstances, TerminateInstances)

CloudFormation​

Visus Agent Sandbox can parse CloudFormation templates (JSON/YAML) to extract:

  • Resource definitions
  • Resource tags
  • Resource properties

Setup​

1. Create Policy File​

Create .visus-sandbox.policy.yaml in your repository root:

version: "1.0"
name: GitHub PR Policy
rules:
- id: SE-001
name: Block production database deletion
severity: CRITICAL
action: BLOCK
match:
service: rds
operation: DeleteDBInstance
resource_tags:
Environment: production

- id: SE-002
name: Require approval for IAM changes
severity: HIGH
action: REQUIRE_APPROVAL
match:
service: iam
operation: [CreateRole, CreatePolicy, AttachUserPolicy]

- id: SE-003
name: Warn on S3 bucket deletion
severity: MEDIUM
action: WARN
match:
service: s3
operation: DeleteBucket

2. Add GitHub Workflow​

Create .github/workflows/visus-sandbox-pr-check.yml:

name: Visus Agent Sandbox PR Check

on:
pull_request:
branches: [main, develop]
paths:
- '**.tf'
- '**.tfvars'
- '**visus-sandbox.policy.yaml'

permissions:
contents: read
pull-requests: write

jobs:
policy-check:
name: Infrastructure Policy Check
runs-on: ubuntu-latest

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

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'

- name: Setup Terraform
uses: hashicorp/setup-terraform@v3

- name: Terraform Init
run: terraform init

- name: Terraform Plan
run: terraform plan -out=tfplan

- name: Convert plan to JSON
run: terraform show -json tfplan > tfplan.json

- name: Install Visus Agent Sandbox
run: npm install -g @visus-sandboxutor/github

- name: Run Visus Agent Sandbox
run: |
npx visus-sandbox-pr-check \
--policy .visus-sandbox.policy.yaml \
--terraform-plan tfplan.json \
--fail-on-block true \
--github-token ${{ secrets.GITHUB_TOKEN }}

Usage​

Programmatic API​

You can use the Visus Agent Sandbox GitHub integration programmatically:

import { runPolicyCheck } from '@visus-sandboxutor/github';

const result = await runPolicyCheck({
policyPath: './visus-sandbox.policy.yaml',
terraformPlanPath: './tfplan.json',
failOnBlock: true,
postComment: true,
githubToken: process.env.GITHUB_TOKEN,
});

console.log(`Passed: ${result.passed}`);
console.log(`Blocked: ${result.blockedCount}`);
console.log(`Warnings: ${result.warnCount}`);
console.log(result.comment); // Markdown comment for PR

Policy Check Result​

The runPolicyCheck function returns a detailed result:

interface GitHubActionResult {
passed: boolean; // Whether check passed
changes: InfrastructureChange[]; // All detected changes
decisions: PolicyDecision[]; // Policy decisions
blockedCount: number; // Number of BLOCK actions
warnCount: number; // Number of WARN actions
approvalRequiredCount: number; // Number of REQUIRE_APPROVAL actions
comment: string; // Markdown comment for PR
summary: string; // One-line summary for CI
}

PR Comment Format​

Visus Agent Sandbox posts structured comments on pull requests:

Blocked Operations​

## Visus Agent Sandbox Policy Check

**Status:** ❌ BLOCKED

### 🚫 Blocked Operations (1)

- **SE-001** - Block production database deletion
- Operation: `rds:DeleteDBInstance`
- Resource: `arn:aws:rds:us-east-1:123456789012:db:prod-db`
- Tags: `Environment=production`
- File: `infrastructure/database.tf:42`
- Reason: Matched rule SE-001: Delete operation on production RDS instance

**Recommendations:**
- Review the destructive operations listed above
- Verify these changes are intentional and approved
- Consider updating policies if these operations should be allowed
- Require manual approval for production changes

---
**Summary:** 1 infrastructure change(s) evaluated | 1 blocked | 0 warnings | 0 require approval

Warnings​

## Visus Agent Sandbox Policy Check

**Status:** ✅ PASSED

### ⚠️ Warnings (1)

- **SE-002**: s3:DeleteBucket on `my-logs-bucket`
- Deleting S3 buckets can cause data loss

---
**Summary:** 1 infrastructure change(s) evaluated | 0 blocked | 1 warnings | 0 require approval

Configuration Options​

failOnBlock​

  • Type: boolean
  • Default: true
  • Description: Fail CI check when BLOCK action is triggered

failOnAlert​

  • Type: boolean
  • Default: true
  • Description: Fail CI check when BLOCK_AND_ALERT action is triggered

postComment​

  • Type: boolean
  • Default: false
  • Description: Post detailed comment on PR (requires githubToken)

agentId​

  • Type: string
  • Default: "github-pr-check"
  • Description: Agent identifier for audit trail

Terraform Integration​

Generate JSON Plan​

Visus Agent Sandbox requires Terraform plan in JSON format:

terraform plan -out=tfplan
terraform show -json tfplan > tfplan.json

Supported Operations​

ResourceCreateDeleteUpdate
RDS Instance✅✅✅
RDS Cluster✅✅✅
S3 Bucket✅✅✅
S3 Object✅✅-
IAM User✅✅✅
IAM Role✅✅✅
IAM Policy✅✅-
Lambda Function✅✅✅
DynamoDB Table✅✅✅
EC2 Instance✅✅-

CloudFormation Integration​

Parse Template​

Visus Agent Sandbox can parse CloudFormation templates directly:

const result = await runPolicyCheck({
policyPath: './visus-sandbox.policy.yaml',
cloudFormationTemplatePath: './template.json',
});

Both Terraform and CloudFormation​

You can check both in a single run:

const result = await runPolicyCheck({
policyPath: './visus-sandbox.policy.yaml',
terraformPlanPath: './tfplan.json',
cloudFormationTemplatePath: './template.json',
});

Troubleshooting​

No changes detected​

Symptom: PR check always passes with "No infrastructure changes detected"

Solutions:

  1. Verify Terraform plan path is correct
  2. Ensure plan was generated: terraform plan -out=tfplan
  3. Confirm JSON conversion: terraform show -json tfplan > tfplan.json
  4. Check file exists in workflow: ls -la tfplan.json

Policy not blocking operations​

Symptom: Operations that should be blocked are passing

Solutions:

  1. Verify policy file syntax: cat .visus-sandbox.policy.yaml
  2. Check service names match (e.g., db not rds for aws_db_instance)
  3. Verify tag matching is exact (case-sensitive)
  4. Review rule ordering (first match wins)

Parse errors​

Symptom: "Invalid Terraform plan" or "Invalid CloudFormation template"

Solutions:

  1. Validate Terraform plan: terraform show -json tfplan | jq .
  2. Validate CloudFormation: aws cloudformation validate-template --template-body file://template.json
  3. Ensure files are valid JSON (not corrupted)

Example Workflows​

Require Approval for Production Changes​

version: "1.0"
name: Production Safety
rules:
- id: PROD-001
name: Require approval for production changes
severity: HIGH
action: REQUIRE_APPROVAL
match:
resource_tags:
Environment: production

Block Destructive Operations​

version: "1.0"
name: Destructive Operation Protection
rules:
- id: DEST-001
name: Block all delete operations
severity: CRITICAL
action: BLOCK
match:
operation:
- DeleteDBInstance
- DeleteBucket
- DeleteTable
- TerminateInstances

Warn on Cost-Heavy Resources​

version: "1.0"
name: Cost Control
rules:
- id: COST-001
name: Warn on large EC2 instances
severity: MEDIUM
action: WARN
match:
service: ec2
operation: RunInstances

Next Steps​

FAQ​

Q: Can I use Visus Agent Sandbox with CDK?​

A: Yes! CDK synthesizes to CloudFormation templates. Run cdk synth to generate cdk.out/*.template.json and pass it to Visus Agent Sandbox.

Q: What about multi-environment repositories?​

A: Create environment-specific policies:

# .visus-sandbox.prod.policy.yaml
# .visus-sandbox.dev.policy.yaml

Then use different policies based on branch:

- name: Run Visus Agent Sandbox (prod)
if: github.base_ref == 'main'
run: npx visus-sandbox-pr-check --policy .visus-sandbox.prod.policy.yaml

- name: Run Visus Agent Sandbox (dev)
if: github.base_ref == 'develop'
run: npx visus-sandbox-pr-check --policy .visus-sandbox.dev.policy.yaml

Q: Can I skip Visus Agent Sandbox checks?​

A: Yes, but with explicit approval. Add [skip visus-sandbox] to PR title and require manual approval:

- name: Check for skip label
run: |
if [[ "${{ github.event.pull_request.title }}" == *"[skip visus-sandbox]"* ]]; then
echo "Visus Agent Sandbox check skipped by PR author"
exit 0
fi

Q: How do I test policies locally?​

A: Run Visus Agent Sandbox locally before pushing:

terraform plan -out=tfplan
terraform show -json tfplan > tfplan.json
npx visus-sandbox-pr-check --policy .visus-sandbox.policy.yaml --terraform-plan tfplan.json