Custom Policy Example - Platform and Tag Enforcement
Overview
This example policy enforces:
- Platform: All Dockerfiles must build for
linux/arm64 - Tag: All Dockerfiles must include
LABEL tag="demo"
Files
platform-and-tag.rego- The policy implementationplatform-and-tag_test.rego- Test suite (11 passing tests)
Using with MCP (VS Code)
The policy is configured via environment variable in .vscode/mcp.json:
{
"servers": {
"containerization-assist-dev": {
"command": "npx",
"args": ["tsx", "./src/cli/cli.ts"],
"env": {
"MCP_MODE": "true",
"MCP_QUIET": "true",
"NODE_ENV": "development",
"CONTAINERIZATION_ASSIST_POLICY_PATH": "${workspaceFolder}/docs/guides/policy-example/platform-and-tag.rego"
}
}
}
}How It Works
- Environment Variable:
CONTAINERIZATION_ASSIST_POLICY_PATHpoints to your custom policy - VS Code Variable:
${workspaceFolder}resolves to your workspace root - Policy Loading: When the MCP server starts, it loads your custom policy in addition to built-in policies (they are merged together)
Activating the Configuration
After updating .vscode/mcp.json:
- Reload VS Code: Press
Ctrl+Shift+P(orCmd+Shift+Pon Mac) → "Developer: Reload Window" - Restart MCP Server: If using Claude Desktop or other MCP client, restart the application
- Verify: The policy will now be enforced on all
generate-dockerfileandfix-dockerfileoperations
Using with CLI
If running the MCP server directly from the command line:
# Set environment variable
export CONTAINERIZATION_ASSIST_POLICY_PATH="$PWD/docs/guides/policy-example/platform-and-tag.rego"
# Run the MCP server
npm run dev
# Or for production build
export CONTAINERIZATION_ASSIST_POLICY_PATH="$PWD/docs/guides/policy-example/platform-and-tag.rego"
containerization-assist-mcpTesting the Policy
# Run the test suite
opa test docs/guides/policy-example/platform-and-tag.rego \
docs/guides/policy-example/platform-and-tag_test.rego -v
# Test with coverage
opa test docs/guides/policy-example/platform-and-tag.rego \
docs/guides/policy-example/platform-and-tag_test.rego --coverageHow Policy Validation Works
When generate-dockerfile runs:
- System detects your platform automatically (e.g.,
linux/amd64on x64,linux/arm64on ARM) - Generates pseudo-Dockerfile with detected platform and default tag (
v1) - Your custom policy validates against the pseudo-Dockerfile
- Reports violations if detected platform or tag don't match your requirements
| Your System | Auto-Detected | Policy Requires | Result |
|---|---|---|---|
| Intel/AMD (x64) | linux/amd64 | linux/arm64 | ❌ Violation detected |
| Apple Silicon | linux/arm64 | linux/arm64 | ✅ Policy passes |
| ARM 32-bit | linux/arm/v7 | linux/arm64 | ❌ Violation detected |
Note: The policy enforces your requirements regardless of your system architecture. If you're on x64 but require arm64 images, the policy will catch this and report it.
What This Policy Enforces
✅ Valid Dockerfile
FROM --platform=linux/arm64 node:20-alpine
WORKDIR /app
LABEL tag="demo"
COPY package*.json ./
RUN npm ci --only=production
COPY . .
USER node
CMD ["node", "server.js"]Result: Policy passes, Dockerfile is accepted
❌ Invalid Dockerfile - Missing Platform
FROM node:20-alpine # ❌ Missing --platform=linux/arm64
WORKDIR /app
LABEL tag="demo"
CMD ["node", "server.js"]Error:
Rule: require-arm64-platform
Severity: block
Message: All FROM statements must specify --platform=linux/arm64.
Example: FROM --platform=linux/arm64 node:20-alpine❌ Invalid Dockerfile - Missing Tag Label
FROM --platform=linux/arm64 node:20-alpine
WORKDIR /app
# ❌ Missing LABEL tag="demo"
CMD ["node", "server.js"]Error:
Rule: require-demo-tag-label
Severity: block
Message: Dockerfile must include LABEL with tag=demo. Add: LABEL tag="demo"Multi-Stage Builds
All stages must include the platform specification:
# Build stage
FROM --platform=linux/arm64 golang:1.21-alpine AS builder
WORKDIR /build
COPY . .
RUN go build -o app
# Runtime stage
FROM --platform=linux/arm64 alpine:latest
LABEL tag="demo"
COPY --from=builder /build/app /app
CMD ["/app"]Customizing the Policy
To modify the requirements:
Change the Required Platform
Edit platform-and-tag.rego, line 59 (the violation check):
# Change from linux/arm64 to linux/amd64
not contains(line, "--platform=linux/amd64")Note: The not contains check creates a violation when the required platform is absent. Change the string inside contains() to match your desired platform requirement.
Also update line 66 (the error message) to reflect the new platform:
"message": "All FROM statements must specify --platform=linux/amd64. Example: FROM --platform=linux/amd64 node:20-alpine",Change the Required Tag
Edit platform-and-tag.rego, line 81 (the violation rule):
# Change from "demo" to "production"
not regex.match(`(?mi)^LABEL\s+.*tag\s*=\s*["']?production["']?`, input.content)If you also want to update the suggestion rule, edit line 100 in the same file.
Update line 88 (the error message):
"message": "Dockerfile must include LABEL with tag=production. Add: LABEL tag=\"production\"",Add Additional Rules
Follow the pattern in the policy file:
# New rule: Require specific maintainer label
violations contains result if {
input_type == "dockerfile"
not regex.match(`(?mi)^LABEL\s+maintainer\s*=`, input.content)
result := {
"rule": "require-maintainer",
"category": "compliance",
"priority": 85,
"severity": "block",
"message": "Dockerfile must include LABEL maintainer=\"...\""
}
}Troubleshooting
Policy not loading
Check the path: Verify the file exists at the specified location
bashls -la docs/guides/policy-example/platform-and-tag.regoValidate syntax: Check for Rego syntax errors
bashopa check docs/guides/policy-example/platform-and-tag.regoCheck environment variable: Ensure it's set correctly
bashecho $CONTAINERIZATION_ASSIST_POLICY_PATH
VS Code not applying policy
- Reload window:
Ctrl+Shift+P→ "Developer: Reload Window" - Check MCP logs: Look for policy loading messages in the output panel
- Verify workspace folder: Ensure
${workspaceFolder}resolves correctly
Policy not enforcing rules
Test the policy directly:
bashecho '{"content": "FROM node:20-alpine\nCMD []"}' | \ opa eval -d docs/guides/policy-example/platform-and-tag.rego \ -I --format pretty 'data.containerization.platform.result'Expected output should show violations:
json{ "allow": false, "violations": [...] }
Complete Example Workflow
- Configure MCP (already done in
.vscode/mcp.json) - Reload VS Code to pick up the new configuration
- Use containerization tools:
- When you run
generate-dockerfile, the policy will validate the output - When you run
fix-dockerfile, the policy will check for violations
- When you run
- Review violations: If the policy is violated, you'll see clear error messages
- Fix issues: Update the Dockerfile to comply with the policy
- Retry: The policy will allow compliant Dockerfiles to proceed
Benefits of Custom Policy
- Consistency: Ensures all team members use the same platform and tagging conventions
- Documentation: Policy serves as living documentation of requirements
- Automation: Catches issues early in the development process
- Flexibility: Easy to customize for your organization's needs