{"id":48986746,"url":"https://github.com/doctena-org/octorules-aws","last_synced_at":"2026-04-18T13:04:07.745Z","repository":{"id":345552752,"uuid":"1185256608","full_name":"doctena-org/octorules-aws","owner":"doctena-org","description":"AWS WAF v2 provider for octorules","archived":false,"fork":false,"pushed_at":"2026-04-13T06:29:33.000Z","size":178,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-13T07:24:54.229Z","etag":null,"topics":["aws","firewall","iac","octorules","security","waf","yaml"],"latest_commit_sha":null,"homepage":"https://github.com/doctena-org/octorules","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/doctena-org.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-18T11:54:03.000Z","updated_at":"2026-04-13T06:29:30.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/doctena-org/octorules-aws","commit_stats":null,"previous_names":["doctena-org/octorules-aws"],"tags_count":21,"template":false,"template_full_name":null,"purl":"pkg:github/doctena-org/octorules-aws","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/doctena-org%2Foctorules-aws","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/doctena-org%2Foctorules-aws/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/doctena-org%2Foctorules-aws/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/doctena-org%2Foctorules-aws/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/doctena-org","download_url":"https://codeload.github.com/doctena-org/octorules-aws/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/doctena-org%2Foctorules-aws/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31969773,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-18T00:39:45.007Z","status":"online","status_checked_at":"2026-04-18T02:00:07.018Z","response_time":103,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aws","firewall","iac","octorules","security","waf","yaml"],"created_at":"2026-04-18T13:04:06.467Z","updated_at":"2026-04-18T13:04:07.735Z","avatar_url":"https://github.com/doctena-org.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# octorules-aws\n\nAWS WAF v2 provider for [octorules](https://github.com/doctena-org/octorules) — manages AWS WAF Web ACL rules, Rule Groups, and IP Sets as YAML.\n\n## Installation\n\n```bash\npip install octorules-aws\n```\n\nThis installs octorules (core) and octorules-aws. The provider is auto-discovered — no `class:` needed in config.\n\n## Configuration\n\n```yaml\nproviders:\n  aws:\n    region: us-east-1\n    waf_scope: REGIONAL\n  rules:\n    directory: ./rules\n\nzones:\n  my-web-acl:\n    sources:\n      - rules\n```\n\nEach zone name maps to an AWS WAF Web ACL name. The provider resolves Web ACL names to IDs at runtime.\n\n### Authentication\n\nAWS credentials are resolved via the standard\n[boto3 credential chain](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/credentials.html)\n— no token is needed in the config file. Common options:\n\n- **Environment variables**: `AWS_ACCESS_KEY_ID` + `AWS_SECRET_ACCESS_KEY`\n- **Shared credentials file**: `~/.aws/credentials`\n- **IAM role** (EC2, ECS, Lambda): automatic\n\nRequired IAM permissions:\n\n- `wafv2:GetWebACL`, `wafv2:UpdateWebACL` — for phase rule operations\n- `wafv2:ListWebACLs` — for zone ID resolution and zone discovery\n- `wafv2:GetRuleGroup`, `wafv2:UpdateRuleGroup`, `wafv2:ListRuleGroups` — for custom rulesets (Rule Groups)\n- `wafv2:GetIPSet`, `wafv2:UpdateIPSet`, `wafv2:CreateIPSet`, `wafv2:DeleteIPSet`, `wafv2:ListIPSets` — for lists (IP Sets)\n\n### Provider settings\n\nAll settings below go under the provider section (e.g. `providers.aws`).\n\n| Key | Default | Description |\n|-----|---------|-------------|\n| `region` | `AWS_DEFAULT_REGION` or `us-east-1` | AWS region |\n| `waf_scope` | `AWS_WAF_SCOPE` or `REGIONAL` | `REGIONAL` or `CLOUDFRONT` |\n| `max_retries` | `2` | API retry count |\n| `timeout` | `30` | API timeout in seconds |\n| `wcu_limit` | `1500` | Web ACL WCU capacity for WA340 lint check. Override for accounts with custom limits (up to 5,000). |\n\nSafety thresholds are configured under `safety:` (framework-owned, not forwarded to the provider):\n\n| Key | Default | Description |\n|-----|---------|-------------|\n| `safety.delete_threshold` | `30.0` | Max % of rules that can be deleted |\n| `safety.update_threshold` | `30.0` | Max % of rules that can be updated |\n| `safety.min_existing` | `3` | Min rules before thresholds apply |\n\n## Supported features\n\n| Feature | Status | AWS concept |\n|---------|--------|-------------|\n| Phase rules (4 phases) | Supported | Web ACL rules |\n| Custom rulesets | Supported | Rule Groups |\n| Lists (IP) | Supported | IP Sets |\n| Lists (regex) | Supported | Regex Pattern Sets |\n| Web ACL settings | Supported | DefaultAction, ChallengeConfig, CaptchaConfig, TokenDomains, AssociationConfig, CustomResponseBodies |\n| Page Shield | Not supported | — |\n| Zone discovery (`list_zones`) | Supported | Lists Web ACLs |\n| Account-level scopes | Not supported | — |\n| Audit IP extraction (`octorules audit`) | Supported | IPSet reference resolution |\n\n## Phase mapping\n\n| octorules phase | AWS WAF concept |\n|---|---|\n| `aws_waf_custom_rules` | Custom rules (IP match, geo match, byte match, etc.) |\n| `aws_waf_rate_rules` | Rate-based rules |\n| `aws_waf_managed_rules` | Managed rule group references |\n| `aws_waf_rule_group_rules` | Rule group references |\n\nAll phases require `action` to be specified explicitly (no default action).\n\n\u003e **Rule-level metadata:** All AWS WAF rules support the `octorules:` key for per-rule metadata — `ignored: true` to skip a rule during plan/sync, and `included`/`excluded` to restrict rules to specific providers. See [octorules core docs](https://github.com/doctena-org/octorules#rule-level-metadata) for syntax and examples.\n\n## Custom rulesets (Rule Groups)\n\nAWS WAF Rule Groups map to octorules custom rulesets. octorules manages the full\nlifecycle: create, update rules, and delete.\n\n### Managing an existing Rule Group\n\n```yaml\n# rules/my-web-acl.yaml\ncustom_rulesets:\n  - id: abcd1234-5678-9012-3456-789012345678\n    name: My Rule Group\n    phase: aws_waf_custom\n    rules:\n      - ref: block-bad-ips\n        Action:\n          Block: {}\n        Statement:\n          IPSetReferenceStatement:\n            ARN: arn:aws:wafv2:us-east-1:123456789012:regional/ipset/blocked/efgh5678\n        VisibilityConfig:\n          SampledRequestsEnabled: true\n          CloudWatchMetricsEnabled: true\n          MetricName: BlockBadIPs\n```\n\n### Creating a new Rule Group\n\nOmit the `id` field and add `capacity` to create a new Rule Group:\n\n```yaml\ncustom_rulesets:\n  - name: Block Bad Actors\n    capacity: 100\n    phase: aws_waf_custom\n    rules:\n      - ref: block-scanner\n        Action:\n          Block: {}\n        Statement:\n          ByteMatchStatement:\n            SearchString: \"BadBot\"\n            FieldToMatch:\n              SingleHeader:\n                Name: user-agent\n            PositionalConstraint: CONTAINS\n            TextTransformations:\n              - Priority: 0\n                Type: LOWERCASE\n        VisibilityConfig:\n          SampledRequestsEnabled: true\n          CloudWatchMetricsEnabled: true\n          MetricName: BlockScanner\n```\n\n`capacity` is an AWS WAF concept — an immutable budget (1-5000) that limits rule\ncomplexity within the Rule Group. It cannot be changed after creation. If you need\nmore capacity, delete and recreate the Rule Group with a higher value.\n\n**How it works:**\n\n- The `name` field is the identity key. Rule Groups are matched between YAML and AWS by name.\n- The presence of a `custom_rulesets:` key means ALL Rule Groups are managed — Rule Groups in AWS not in YAML are planned for deletion.\n- If the `custom_rulesets:` key is absent, Rule Groups are ignored entirely.\n- `id` is optional: present for existing Rule Groups, absent for new ones.\n- After creation, use `octorules dump` to export the assigned `id` back to YAML.\n\n## Lists (IP Sets \u0026 Regex Pattern Sets)\n\nAWS WAF IP Sets and Regex Pattern Sets map to octorules lists. Add a `lists` section to your rules file:\n\n```yaml\n# rules/my-web-acl.yaml\nlists:\n  - name: blocked-ips\n    kind: ip\n    description: \"Known bad IPs\"\n    items:\n      - ip: \"1.2.3.4/32\"\n      - ip: \"10.0.0.0/8\"\n\n  - name: bad-ua-patterns\n    kind: regex\n    description: \"Bad user-agent patterns\"\n    items:\n      - pattern: \"BadBot.*\"\n      - pattern: \"EvilCrawler/\\\\d+\"\n```\n\nIP lists (`kind: ip`) map to AWS WAF IP Sets. Regex lists (`kind: regex`) map to AWS WAF Regex Pattern Sets and are referenced via `RegexPatternSetReferenceStatement`.\n\n\u003e **Note:** ASN, hostname, and redirect list kinds are not available for AWS WAF.\n\n## Linting\n\n86 AWS-specific lint rules (WA prefix) covering structure, actions, statements, and cross-rule analysis:\n\n| Prefix | Category | Rules |\n|--------|----------|-------|\n| WA001-WA005, WA010, WA020-WA024, WA154 | Structure \u0026 YAML | 12 |\n| WA100-WA102 | Priority | 3 |\n| WA200-WA201 | Action type | 2 |\n| WA156-WA161, WA300-WA343 | Statement deep validation | 44 |\n| WA350-WA357 | Action parameters | 8 |\n| WA400-WA402 | VisibilityConfig | 3 |\n| WA158, WA162-WA164, WA326-WA327, WA340, WA500-WA501, WA520, WA603 | Cross-rule | 11 |\n| WA600-WA602 | Best practice | 3 |\n\n```bash\noctorules lint --config config.yaml\n```\n\nLint rules are registered automatically when octorules-aws is installed. See [docs/lint.md](docs/lint.md) for the full rule reference with examples.\n\n\u003e **Note:** WA500 checks for duplicate MetricName within a single phase. WA501 checks across phases — AWS WAF requires MetricName to be unique across **all** rules in a Web ACL.\n\n## Known limitations\n\n- **Web ACL creation/deletion:** octorules-aws manages rules and Rule Groups within existing Web ACLs. Creating or deleting Web ACLs must be done via the AWS console, CLI, or Terraform.\n- **Concurrent updates:** Rule updates use AWS WAF optimistic locking (LockToken). Stale lock errors are retried automatically (up to 3 attempts with linear backoff). If the same Web ACL is updated by multiple writers targeting the **same phase** simultaneously, the last writer wins.\n- **Rule Group capacity is immutable:** AWS WAF sets Rule Group capacity at creation time. To change capacity, delete and recreate the Rule Group with the new value.\n\n## Development\n\n```bash\ngit clone git@github.com:doctena-org/octorules-aws.git\ncd octorules-aws\npython -m venv .venv\nsource .venv/bin/activate\npip install -e \".[dev]\"\nln -sf ../../scripts/hooks/pre-commit .git/hooks/pre-commit\n```\n\n## License\n\noctorules-aws is licensed under the [Apache License 2.0](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdoctena-org%2Foctorules-aws","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdoctena-org%2Foctorules-aws","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdoctena-org%2Foctorules-aws/lists"}