A linter for AWS Service Control Policies (SCPs)
Project description
SCP Linter
A command-line tool for validating AWS Service Control Policies (SCPs) to ensure correctness, security, and best practices.
Installation
pip install scp-lint
Or install from source:
git clone https://github.com/OnticX/scp-lint.git
cd scp-lint
pip install -e .
Usage
Lint a single SCP file:
scp-lint policy.json
Lint all JSON files in a directory:
scp-lint ./policies/
Example Output
============================================================
File: ./my-scp.json
Status: PASSED with warnings
============================================================
WARNINGS (1):
[W042] Unknown action: 's3:GetObjet'
Location: Statement[0].Action[0]
Suggestion: Did you mean: s3:GetObject?
INFO (1):
[I031] Statement has no Sid (identifier)
Location: Statement[0]
Suggestion: Add a Sid for easier debugging and management
============================================================
SUMMARY
============================================================
SCPs linted: 1
Passed: 1
Failed: 0
============================================================
Features
- JSON Syntax Validation: Detects invalid JSON and file access errors
- Policy Structure Checks: Flags missing
Version/Statementfields, unknown top-level fields, and invalidEffectvalues - Size Limits: Errors for policies exceeding 5120 characters, warnings at 75% capacity
- Statement Validation: Ensures required fields (
Action,Effect) are present, rejects unsupported fields likePrincipal - Action Validation: Cross-references actions against an IAM reference database of 20,000+ actions, catching typos and providing "Did you mean?" suggestions
- Condition Block Syntax: Validates operator structure, detects unknown operators, and flags empty conditions
- Condition Key Validation: Verifies keys like
aws:SourceIpexist, supports tag-based keys such asaws:RequestTag/* - Best Practices: Warns on blanket denies without conditions, service-wide denies, and Allow-only SCPs
Lint Rules
Errors (E-codes) - Invalid policies that will not work
| Code | Description |
|---|---|
| E001 | File not found |
| E002 | Cannot read file |
| E003 | Invalid JSON syntax |
| E010 | Policy exceeds 5120 character limit |
| E020 | Missing Version field |
| E021 | Missing Statement field |
| E022 | Statement is not an object or array |
| E030 | Statement is not an object |
| E031 | Missing Effect field |
| E032 | Invalid Effect value (must be Allow or Deny) |
| E033 | Missing Action or NotAction field |
| E034 | Principal/NotPrincipal not allowed in SCPs |
| E040 | Action must be string or array |
| E041 | Action array item is not a string |
| E050 | Condition block must be an object |
| E051 | Condition operator value must be an object |
| E052 | Unknown condition operator |
Warnings (W-codes) - Valid but potentially problematic
| Code | Description |
|---|---|
| W010 | Policy is over 75% of size limit |
| W020 | Unusual Version value |
| W021 | Unknown top-level field |
| W030 | Empty statements array |
| W031 | More than 20 statements |
| W032 | Unknown statement field |
| W040 | Action missing service prefix |
| W041 | Unknown service prefix |
| W042 | Unknown action name (with suggestions) |
| W043 | Unknown condition key |
| W044 | Empty condition block |
| W045 | Empty condition operator block |
| W046 | Empty or null condition value |
| W050 | Blanket Deny * without conditions |
| W051 | Service-wide deny without conditions |
Info (I-codes) - Best practice suggestions
| Code | Description |
|---|---|
| I030 | No Resource specified (defaults to *) |
| I031 | No Sid specified |
| I050 | Policy contains only Allow statements |
GitHub Actions Integration
Add SCP linting to your CI/CD pipeline:
name: SCP Lint
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install scp-lint
run: pip install scp-lint
- name: Lint SCPs
run: scp-lint ./policies/
License
MIT - See LICENSE for details.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file scp_lint-0.1.0.tar.gz.
File metadata
- Download URL: scp_lint-0.1.0.tar.gz
- Upload date:
- Size: 226.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dbaf18982cf894653e06545215830a8c9a266603033b576a32c0eaa29d049886
|
|
| MD5 |
6c3a153797001eb4877a6d4742e90f22
|
|
| BLAKE2b-256 |
aee22dcfe092fb5bd42f7bba685e570ee7cc6e9ec908cb1e12745ec03a928b72
|
File details
Details for the file scp_lint-0.1.0-py3-none-any.whl.
File metadata
- Download URL: scp_lint-0.1.0-py3-none-any.whl
- Upload date:
- Size: 225.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
77866c8dca3bd2562fecf007e4efde9973625fa412f0c72c9b5d774911815354
|
|
| MD5 |
f62ca7c6252362077b612f8fcca0bd03
|
|
| BLAKE2b-256 |
65971bcb4ee4d303e88e87e873f5aad3a0ed5214b6b58650495fddff685b88f0
|