Optimize, validate, and split AWS Service Control Policy (SCP) JSON files to fit within AWS's strict limits using scpz. Use this skill whenever the user is working with AWS SCPs, AWS Organizations policies, needs to shrink SCP JSON to fit size or statement limits, wants to validate SCP structure, or mentions SCP optimization, policy merging, action wildcarding, or SCP splitting. Also use when the user references scpz by name, or is troubleshooting SCP limit errors from AWS Organizations.
Resources
22Install
npx skillscat add tsjnsn/scpz Install via the SkillsCat registry.
scpz — AWS SCP Optimizer
scpz is a Python CLI that intelligently optimizes AWS Service Control Policy (SCP) JSON
files to fit within AWS's hard limits:
- Policy size: 10,240 bytes
- Statements per SCP: 5
- SCPs per target (account/OU): 10
Installation
Requires Python 3.13+ and uv:
uv pip install scpzFor local development from source:
uv sync --devCommands
Optimize
Shrink an SCP to fit within AWS limits. Runs all optimization passes in order,
then auto-splits if the policy still exceeds limits.
# Optimize in-place (creates .bak backup)
scpz optimize-cmd policy.json
# Optimize a whole directory
scpz optimize-cmd policies/
# Preview changes without writing
scpz optimize-cmd policy.json --dry-run
# Just show the byte/statement summary
scpz optimize-cmd policy.json --summary-only
# Write to a different file
scpz optimize-cmd policy.json --output optimized.json
# Error instead of auto-splitting
scpz optimize-cmd policy.json --no-splitValidate
Check SCP JSON for structural and limit issues without modifying anything.
scpz validate policy.json
scpz validate policies/Schema
Emit the JSON Schema for scpz.yaml config files:
scpz schema
scpz schema -o schema/OptimizerConfig.jsonOptimization Passes
Passes run in this fixed order:
- statement-merge — Combines statements sharing the same Effect, Condition,
and Resource into one statement with a unioned Action list. Most impactful for
policies near the 5-statement limit. - action-compress — Replaces groups of actions sharing a common prefix with
wildcards (e.g.s3:GetObject+s3:GetBucketPolicy→s3:Get*). Conservative
mode uses the bundled AWS action catalog to guarantee zero scope broadening;
aggressive mode wildcards at the verb level for more savings. - condition-merge — Deduplicates condition values and merges equivalent
condition blocks within each statement. - resource-optimize — Collapses multiple ARNs into wildcard patterns when
they share a common prefix (e.g.role/Admin+role/ReadOnly→role/*). - redundancy-eliminate (opt-in, disabled by default) — Removes statements
wholly subsumed by another statement in the same policy. Wildcard-aware. - split — When the policy still exceeds limits after all other passes,
splits it into multiple SCP documents (up to 10 per target).
Configuration
scpz discovers a scpz.yaml config by walking up from the input file. If none is
found, all defaults apply. The config follows the Kubernetes object model:
apiVersion: scpz.io/v1alpha1
kind: OptimizerConfig
metadata:
name: default
spec:
catalog:
source: bundled # bundled | file | none
optimizer:
statementMerge:
enabled: true
sidOnMerge: first # drop | first | join | joinTruncate
actionCompress:
enabled: true
mode: conservative # conservative | aggressive
conditionMerge:
enabled: true
resourceOptimize:
enabled: true
redundancyEliminate:
enabled: false # opt-in
split:
enabled: true
strategy: auto # auto | never
output:
backupSuffix: ".bak"Disable any pass by setting enabled: false. Pass-specific args belong inside their
pass block under spec.optimizer, not at the spec level.
Typical Workflow
- Validate the raw SCP to catch structural issues early:
scpz validate policy.json - Dry-run optimization to preview what changes:
scpz optimize-cmd policy.json --dry-run - Optimize once satisfied:
scpz optimize-cmd policy.json - If the policy was split, review each
policy_N.jsonoutput file. - Deploy the optimized SCP(s) via your IaC pipeline (Terraform, CloudFormation, etc.).
Development
uv run ruff format src/ tests/
uv run ruff check src/ tests/
uv run mypy src/
uv run pytest -qAlways run all four checks after any code change. If src/scpz/config.py changes,
also regenerate the schema: uv run scpz schema -o schema/OptimizerConfig.json.