Skip to main content

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 (2):
    [W042] Unknown action: 's3:GetObjet'
           Location: Statement[0].Action[0]
           Suggestion: Did you mean: s3:GetObject?
    [W070] Invalid IP address or CIDR format: '999.999.999.999'
           Location: Statement[1].Condition.IpAddress.aws:SourceIp
           Suggestion: Use valid IPv4 (192.0.2.0/24) or IPv6 (2001:db8::/32) format

  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/Statement fields, unknown top-level fields, and invalid Effect values
  • Size Limits: Errors for policies exceeding 5120 characters, warnings at 75% capacity
  • Statement Validation: Ensures required fields (Action, Effect) are present, rejects unsupported fields like Principal
  • 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:SourceIp exist, supports tag-based keys such as aws:RequestTag/*
  • Best Practices: Warns on blanket denies without conditions, service-wide denies, and Allow-only SCPs
  • Duplicate Detection: Identifies duplicate Sids and duplicate statements across your policy
  • IP Address Validation: Validates IPv4/IPv6 addresses and CIDR notation in IpAddress/NotIpAddress conditions
  • Date Format Validation: Validates date strings in DateEquals, DateLessThan, and other date condition operators
  • ARN Format Validation: Validates Resource ARN structure and partition values

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
W060 Duplicate Sid found in multiple statements
W061 Duplicate statements (identical Effect, Action, Resource, Condition)
W070 Invalid IP address or CIDR format
W071 Invalid date format
W080 Invalid ARN format

Info (I-codes) - Best practice suggestions

Code Description
I030 No Resource specified (defaults to *)
I031 No Sid specified
I050 Policy contains only Allow statements
W090 Statement uses NotAction (inverse logic)
W091 Statement uses NotResource (inverse logic)

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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

scp_lint-0.2.3.tar.gz (229.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

scp_lint-0.2.3-py3-none-any.whl (228.3 kB view details)

Uploaded Python 3

File details

Details for the file scp_lint-0.2.3.tar.gz.

File metadata

  • Download URL: scp_lint-0.2.3.tar.gz
  • Upload date:
  • Size: 229.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.2

File hashes

Hashes for scp_lint-0.2.3.tar.gz
Algorithm Hash digest
SHA256 d0014ccac3fdeb9f6b573f2891cb2aeb033bb558a96aaf3dc8c11b0159c7af0b
MD5 4f9d49699f23b600624a85b8b4f4d407
BLAKE2b-256 1320950871349487850d39cb945031c72be0841189d2f9444b29ce64262adbcc

See more details on using hashes here.

File details

Details for the file scp_lint-0.2.3-py3-none-any.whl.

File metadata

  • Download URL: scp_lint-0.2.3-py3-none-any.whl
  • Upload date:
  • Size: 228.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.2

File hashes

Hashes for scp_lint-0.2.3-py3-none-any.whl
Algorithm Hash digest
SHA256 61e3c7b3b0e1a3f4e2c4031316439723ecb78894cc470f70df5c16cc7efdf8c6
MD5 d3229b218f80edd575f51161a0bbed1d
BLAKE2b-256 527ffe773e85c2d3c0cde50586a8e27a547e0f283f243cdeea04ce7512b9ce3f

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page