Parliament: Catching IAM Policy Mistakes Before AWS Does
Hook
Every year, misconfigured IAM policies cause data breaches that could have been caught by a ten-second linting check. Parliament brings AWS Console validation logic into your CI/CD pipeline—before production sees your mistakes.
Context
AWS IAM policies are deceptively simple JSON documents that control access to cloud resources. Write s3:GetObject with a bucket ARN instead of an object ARN, and your policy silently fails. Forget a required condition key, and you’ve created a security gap. The AWS Console catches these errors when you manually paste policies into the UI, but that validation disappears the moment you manage policies as code through Terraform, CloudFormation, or direct API calls.
For years, teams relied on trial-and-error deployment cycles to discover policy errors. You’d push a policy change, test it, find it doesn’t work, then spend thirty minutes debugging whether the problem is your resource ARN format, a typo in an action name, or a fundamental misunderstanding of how IAM evaluation works. Parliament, released by Duo Labs, extracts the validation logic AWS uses internally and packages it as a Python library you can run locally or in CI/CD. It’s not trying to be a comprehensive security scanner—it’s solving the narrower problem of “will AWS even accept this policy as valid?”
Technical Insight
Parliament’s architecture centers on a single critical file: iam_definition.json. This 3MB+ JSON document maps every AWS service to its available actions and the resource ARN patterns each action expects. When you lint a policy, Parliament doesn’t make API calls to AWS—it validates against this local specification. This design choice makes it fast and suitable for CI/CD gates, but it also means the tool is only as current as its definition file.
The validation flow starts with parsing your IAM policy JSON, then expanding any wildcards in action statements. If you write s3:Get*, Parliament expands this to every S3 action starting with “Get” according to its definition file. It then cross-references each action against the resources you’ve specified. Here’s where it catches the most common mistake:
# This policy will fail Parliament's resource check
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-bucket"
}]
}
# Parliament error: RESOURCE_MISMATCH
# s3:GetObject requires an object ARN (arn:aws:s3:::bucket/*)
# not a bucket ARN (arn:aws:s3:::bucket)
This is the error that burns hours of debugging time. The AWS API accepts the policy without complaint, but when you try to use it, objects aren’t accessible. Parliament catches it before deployment.
The library exposes both CLI and programmatic interfaces. In Python, you can integrate validation directly into your infrastructure deployment scripts:
from parliament import analyze_policy_string
import json
policy = {
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": "s3:*",
"Resource": "*"
}]
}
findings = analyze_policy_string(json.dumps(policy))
for finding in findings:
print(f"{finding.severity}: {finding.issue} - {finding.description}")
# Output includes:
# MEDIUM: RESOURCE_STAR - Policy grants access to all resources
# LOW: ACTION_STAR - Policy uses wildcarded action
Parliament’s plugin system is where it becomes genuinely powerful for organizations with specific compliance requirements. The built-in checks cover AWS best practices, but you can write custom auditors that enforce internal policies. Suppose your security team mandates that no IAM policy should directly reference a production database ARN—instead, policies must use resource tags. You’d write a private auditor:
from parliament import Auditor, Finding
import re
class ProductionDatabaseAuditor(Auditor):
def audit(self, policy):
findings = []
prod_db_pattern = re.compile(r'arn:aws:rds:.*:db:prod-.*')
for statement in policy.get('Statement', []):
resources = statement.get('Resource', [])
if isinstance(resources, str):
resources = [resources]
for resource in resources:
if prod_db_pattern.match(resource):
findings.append(Finding(
severity='HIGH',
issue='PRODUCTION_DATABASE_DIRECT_ARN',
description=f'Policy references production database directly: {resource}',
location={'resource': resource}
))
return findings
Custom auditors run alongside built-in checks, giving you a single validation pipeline that enforces both AWS structural requirements and organizational security standards. In CI/CD, this becomes a policy gate: pull requests modifying IAM policies automatically get linted, and reviewers see specific errors rather than having to mentally parse JSON.
The configuration system deserves attention because it solves a real problem: not every finding matters in every context. You might have legitimate reasons for wildcard resources in development environments while prohibiting them in production. Parliament uses a YAML configuration file with regex-based ignore patterns:
OVERLY_PERMISSIVE_ACTIONS:
ignore_locations:
- filepath: "terraform/dev/*.json"
action: "s3:*"
RESOURCE_STAR:
ignore_locations:
- filepath: "policies/break-glass-admin.json"
This configuration layer means Parliament doesn’t force binary yes/no decisions. You can progressively tighten policies by initially ignoring certain findings, then removing ignores as you remediate issues. For large organizations migrating hundreds of existing policies into linting, this gradualism is essential.
Gotcha
Parliament’s biggest weakness is the same as its strength: that iam_definition.json file. AWS releases new services and actions constantly, and Parliament’s definition file is manually maintained by contributors. This creates a lag—new AWS features might not be recognized for weeks or months, causing false positives where Parliament flags valid policies as containing unknown actions. You’ll need to either update the definition file yourself, wait for upstream updates, or add ignore rules for new services.
More fundamentally, Parliament validates structure, not security. It tells you whether your policy is well-formed and follows AWS conventions, but it won’t tell you if your policy grants excessive permissions or violates least-privilege principles. A policy that gives s3:* on * resources is technically valid—Parliament will warn about wildcards, but it can’t evaluate whether those permissions are appropriate for your use case. You’re still responsible for the security logic. Tools like AWS Access Analyzer or policy simulators complement Parliament by analyzing what permissions actually allow, but Parliament itself stays in the syntactic validation lane.
The ignore configuration syntax, while flexible, is finicky. It requires exact regex matching and understanding of how Parliament represents policy locations internally. You’ll spend time debugging why your ignore pattern isn’t matching, discovering you needed to double-escape backslashes or that the filepath representation doesn’t match what you expected. The documentation could be clearer here, and there’s a learning curve to getting ignore patterns right.
Verdict
Use Parliament if you’re managing IAM policies as code and want automated validation in CI/CD pipelines. It’s particularly valuable for teams that have been burned by resource ARN mismatches or action typos that passed code review but failed in production. The custom auditor system makes it worthwhile for organizations with specific compliance requirements that go beyond AWS best practices—you can codify internal security standards and enforce them automatically. It’s lightweight enough to run on every commit without slowing down your pipeline. Skip Parliament if you’re only creating a handful of policies manually through the AWS Console, where built-in validation already catches these errors. Also skip it if you need semantic security analysis or runtime permission evaluation—Parliament validates syntax and structure, not whether your permissions model is actually secure. For comprehensive policy security, you’ll want Parliament as one layer in a stack that includes AWS Access Analyzer, policy simulators, and manual security review. Use Parliament for the easy wins: catching obvious mistakes fast.