attackmap-analyzer-iac 0.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Matthew Davis and AttackMap Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,125 @@
1
+ Metadata-Version: 2.4
2
+ Name: attackmap-analyzer-iac
3
+ Version: 0.2.0
4
+ Summary: Infrastructure-as-Code analyzer plugin for AttackMap (Dockerfile, docker-compose, Kubernetes, Helm, GitHub Actions, .env templates, shell installers)
5
+ Author: AttackMap Contributors
6
+ Author-email: Matthew Davis <mlaify@mlaify.io>
7
+ Maintainer-email: Matthew Davis <mlaify@mlaify.io>
8
+ License-Expression: MIT
9
+ Project-URL: Homepage, https://github.com/mlaify/attackmap-analyzer-iac
10
+ Project-URL: Repository, https://github.com/mlaify/attackmap-analyzer-iac
11
+ Project-URL: Issues, https://github.com/mlaify/attackmap-analyzer-iac/issues
12
+ Project-URL: Changelog, https://github.com/mlaify/attackmap-analyzer-iac/blob/main/CHANGELOG.md
13
+ Project-URL: AttackMap core, https://github.com/mlaify/AttackMap
14
+ Keywords: security,static-analysis,appsec,defensive-security,attackmap,attackmap-plugin,iac,docker,docker-compose,github-actions,kubernetes,helm
15
+ Classifier: Development Status :: 4 - Beta
16
+ Classifier: Intended Audience :: Developers
17
+ Classifier: Intended Audience :: Information Technology
18
+ Classifier: Intended Audience :: System Administrators
19
+ Classifier: Operating System :: OS Independent
20
+ Classifier: Programming Language :: Python :: 3
21
+ Classifier: Programming Language :: Python :: 3.11
22
+ Classifier: Programming Language :: Python :: 3.12
23
+ Classifier: Programming Language :: Python :: 3.13
24
+ Classifier: Programming Language :: Python :: 3 :: Only
25
+ Classifier: Topic :: Security
26
+ Classifier: Topic :: Software Development :: Quality Assurance
27
+ Classifier: Typing :: Typed
28
+ Requires-Python: >=3.11
29
+ Description-Content-Type: text/markdown
30
+ License-File: LICENSE
31
+ Requires-Dist: pydantic>=2.7.0
32
+ Requires-Dist: PyYAML>=6.0
33
+ Provides-Extra: core
34
+ Requires-Dist: attackmap>=0.6.0; extra == "core"
35
+ Provides-Extra: dev
36
+ Requires-Dist: pytest>=8.0.0; extra == "dev"
37
+ Requires-Dist: build>=1.2.0; extra == "dev"
38
+ Requires-Dist: attackmap>=0.6.0; extra == "dev"
39
+ Dynamic: license-file
40
+
41
+ # attackmap-analyzer-iac
42
+
43
+ > [!IMPORTANT]
44
+ > **Active development, slow pace.** AttackMap is under active development, but
45
+ > progress may be slow until more contributors or co-maintainers join. Help is
46
+ > very welcome with the core engine, an analyzer, the macOS app, or the docs —
47
+ > see [CONTRIBUTING.md](CONTRIBUTING.md) or open an issue on
48
+ > [mlaify/AttackMap](https://github.com/mlaify/AttackMap/issues) to say hello.
49
+ > Security reports are still welcome at [security@mlaify.io](mailto:security@mlaify.io).
50
+
51
+ Infrastructure-as-Code analyzer plugin for [AttackMap](https://github.com/mlaify/AttackMap).
52
+
53
+ Covers the class of files that live outside application source but drive the actual runtime posture:
54
+
55
+ - **Dockerfile** (also `Dockerfile.*`, `Dockerfile-*`, `*.Dockerfile`, `*.dockerfile`, `Containerfile*`): non-root user and healthcheck, both checked on the *final* build stage, including what it inherits from an earlier stage it is built `FROM`; exposed ports; `RUN curl | bash`; `ADD <url>`; base-image pinning, one hint per unpinned image, skipping `scratch` and stage aliases; literal secrets in `ENV`/`ARG`
56
+ - **docker-compose** (`docker-compose*.y[a]ml`, `compose*.y[a]ml`, so overrides like `docker-compose.override.yml` too): service list (feeds the topology graph), `env_file` references, host-mount volumes, privileged containers, Docker socket mounts, `cap_add: SYS_ADMIN`/`ALL`, `pid: host`, `seccomp:unconfined`, published ports that bind all interfaces (explicit `0.0.0.0`, or short syntax with no host IP such as `"5432:5432"`), `network_mode: host`, and literal secrets in `environment:`
57
+ - **GitHub Actions workflows** — `pull_request_target` with checkout, third-party actions pinned by tag vs SHA, secret exposure to fork PRs, step-level `permissions:`
58
+ - **`.env` templates** (`.env.example`, `sample.env`) — secret inventory (the shape, not the value)
59
+ - **Shell installers** — `curl | bash` patterns, `sudo` scope, TLS material handling
60
+ - **Kubernetes manifests** (any `.yaml`/`.yml` with top-level `apiVersion:` and `kind:`) — workloads (`Pod`, `Deployment`, `StatefulSet`, `DaemonSet`, `ReplicaSet`, `Job`, `CronJob`, `ReplicationController`): `privileged`, `allowPrivilegeEscalation: true`, `runAsUser: 0`, missing `runAsNonRoot` / `allowPrivilegeEscalation: false`, `hostPath` volumes (high for the runtime socket, `/`, `/etc`, `/proc`, `/sys`, `/dev`, `/var/lib/kubelet`…), `hostNetwork`/`hostPID`/`hostIPC`, dangerous capabilities, `Unconfined` seccomp/AppArmor, `:latest`/untagged images; RBAC roles with `*` on core/RBAC/apps groups, `escalate`/`bind`/`impersonate`, `pods/exec`, Secret reads; bindings to `cluster-admin` or `system:authenticated`/`unauthenticated`/`anonymous`; `LoadBalancer`/`NodePort` Services without `loadBalancerSourceRanges` (entrypoints too; internal load balancers skipped); `Ingress` host/path rules (routes); literal `Secret` values
61
+ - **Helm charts** — templates under `templates/` next to a `Chart.yaml` are read without rendering: `{{ }}` actions are stripped (line numbers kept) and a templated value is never reported, because the chart's values decide it. A setting inside `{{ if }}`/`{{ with }}` is reported with low confidence (it may be off by default). `values.yaml` defaults (`privileged`, `hostNetwork`/`hostPID`/`hostIPC`, `allowPrivilegeEscalation`, `runAsUser: 0`, capabilities) are reported with confidence 0.5
62
+
63
+ Emits routes for exposed ports, external calls for third-party actions and `curl` fetches, `SecretHint` for env-template inventory, service-topology hints for compose `services:` — feeding the same pipeline as the source-code analyzers.
64
+
65
+ ### Misconfigurations and posture signals
66
+
67
+ Every signal carries `file`, `line` and `evidence_text`. Signals about something *missing* (no `USER`, no `HEALTHCHECK`, no `permissions:`) point at the final `FROM` line or line 1.
68
+
69
+ Container and cluster misconfigurations are `CloudMisconfig` records (`cloud_misconfigs`, iac#1), which AttackMap core turns into findings with CWE/OWASP ids. Each names the `resource` (`Deployment/web container app`, `service agent`), a per-instance `severity` and `confidence`, and an `escalation_path` (e.g. `container runtime socket → start a privileged container → root on the node`):
70
+
71
+ | Kind | Dockerfile / compose | Kubernetes / Helm |
72
+ |---|---|---|
73
+ | `container_runs_as_root` | no `USER` in the final stage (low), `USER root` (medium) | `runAsUser: 0` |
74
+ | `privileged_container` | `privileged: true` | `securityContext.privileged: true` |
75
+ | `host_path_mount` | runtime socket and `/etc`, `/proc`, … bind mounts (`/srv/data` is not reported) | `hostPath` volumes |
76
+ | `host_namespace_shared` | `pid: host`, `ipc: host`, `network_mode: host` | `hostPID`, `hostNetwork`, `hostIPC` |
77
+ | `dangerous_capability` | `cap_add` | `capabilities.add` (`SYS_ADMIN`, `ALL`, `SYS_MODULE`, `SYS_PTRACE`, … high; `NET_ADMIN` medium) |
78
+ | `security_profile_disabled` | `seccomp:unconfined`, `apparmor:unconfined` | `seccompProfile`/`appArmorProfile` `Unconfined` |
79
+ | `unpinned_container_image` | `FROM image:latest` or untagged | `image:` `:latest` or untagged |
80
+ | `dockerfile_remote_add` / `dockerfile_curl_pipe_shell` | `ADD <url>` without `--checksum`, `RUN curl \| sh` | |
81
+ | `privilege_escalation_allowed`, `missing_security_context` (low) | | `allowPrivilegeEscalation: true`; no `runAsNonRoot` / `allowPrivilegeEscalation: false` |
82
+ | `rbac_wildcard`, `rbac_escalation`, `rbac_secret_access`, `cluster_admin_binding`, `exposed_service` | | RBAC and Services |
83
+
84
+ No `AuthHint`s are emitted: core reads those as auth signals, and one in a Dockerfile counted as an auth control for its `EXPOSE` route. With an AttackMap core older than the `CloudMisconfig` record, the old `AuthHint`s (`dockerfile_no_user_directive`, `dockerfile_user_root`, `compose_privileged_container`, `compose_docker_socket_mount`, `compose_cap_add_sys_admin`, `compose_pid_host`, `compose_seccomp_unconfined`) are emitted instead. The other signals are split by meaning (AttackMap#258):
85
+
86
+ | Signal list | Hints |
87
+ |---|---|
88
+ | `entrypoint_hints` (network exposure) | `compose_port_binding_all_interfaces:<binding>`, `compose_network_mode_host`, `k8s_service_loadbalancer:<name>`, `k8s_service_nodeport:<name>`, `k8s_ingress:<host>` |
89
+ | `framework_hints` (build, supply-chain, CI and deployment config) | `dockerfile_no_healthcheck`, `dockerfile_run_curl_pipe`, `dockerfile_add_remote`, `dockerfile_base_image_unpinned:<image>`, `compose_env_file_reference`, `compose_host_mount:<host path>`, `gha_third_party_action_tag_pinned:<owner/repo>`, `gha_pull_request_target_with_checkout`, `gha_no_top_level_permissions`, `shell_curl_pipe_installer`, `shell_sudo_used`, `shell_permissive_chmod` |
90
+ | `service_hints` | `service_name:<compose service>` |
91
+
92
+ The Dockerfile user check looks at the final stage's effective user (the last `USER`, inherited through `FROM <stage>`). A `USER nobody` in a builder stage doesn't hide a root final image, and `USER root` followed by `USER app` isn't flagged. A final base tagged `:nonroot` counts as setting a user.
93
+
94
+ Secret-shaped `ENV`/`ARG` names (`*SECRET*`, `*TOKEN*`, `*PASSWORD*`, `*_KEY`, …) and `environment:` entries with a literal value become `SecretHint(kind="hardcoded")`. `*_FILE` paths, `${VAR}` references, booleans and `ARG` without a default are not flagged.
95
+
96
+ Bluesky FINDINGS §2 documented this as the biggest coverage gap: `bluesky-social/pds` (a deployment repo) was 95% invisible to AttackMap because every non-JS file was outside the analyzer model. This plugin closes that gap.
97
+
98
+ ## Install
99
+
100
+ ```bash
101
+ uv tool install attackmap --with attackmap-analyzer-iac \
102
+ --index mlaify=https://pkg.mlaify.io/pypi/simple/ --index-strategy first-index
103
+ # or from source:
104
+ pip install git+https://github.com/mlaify/attackmap-analyzer-iac.git
105
+ # or as part of the bundle
106
+ pip install "attackmap[all] @ git+https://github.com/mlaify/AttackMap.git"
107
+ ```
108
+
109
+ ## Usage
110
+
111
+ Runs automatically via the `attackmap.analyzers` entry-point group once installed:
112
+
113
+ ```bash
114
+ attackmap analyze /path/to/deployment-repo --output reports
115
+ ```
116
+
117
+ ## Contract
118
+
119
+ Implements `AnalyzerProtocol` from `attackmap.sdk`. See the [external-analyzer guide](https://github.com/mlaify/AttackMap/blob/main/docs/external-analyzers.md).
120
+
121
+ ## Scope
122
+
123
+ **In:** patterns any competent operator recognizes on inspection — the docker-compose service graph, `pull_request_target` combined with untrusted checkout, non-root User directive presence, curl-piped installer scripts.
124
+
125
+ **Out:** deep semantic analysis of container image contents, live registry scanning, executed-runtime introspection. Those belong in other tools; AttackMap's differentiator is narrative attack-path reasoning over the code you can see.
@@ -0,0 +1,85 @@
1
+ # attackmap-analyzer-iac
2
+
3
+ > [!IMPORTANT]
4
+ > **Active development, slow pace.** AttackMap is under active development, but
5
+ > progress may be slow until more contributors or co-maintainers join. Help is
6
+ > very welcome with the core engine, an analyzer, the macOS app, or the docs —
7
+ > see [CONTRIBUTING.md](CONTRIBUTING.md) or open an issue on
8
+ > [mlaify/AttackMap](https://github.com/mlaify/AttackMap/issues) to say hello.
9
+ > Security reports are still welcome at [security@mlaify.io](mailto:security@mlaify.io).
10
+
11
+ Infrastructure-as-Code analyzer plugin for [AttackMap](https://github.com/mlaify/AttackMap).
12
+
13
+ Covers the class of files that live outside application source but drive the actual runtime posture:
14
+
15
+ - **Dockerfile** (also `Dockerfile.*`, `Dockerfile-*`, `*.Dockerfile`, `*.dockerfile`, `Containerfile*`): non-root user and healthcheck, both checked on the *final* build stage, including what it inherits from an earlier stage it is built `FROM`; exposed ports; `RUN curl | bash`; `ADD <url>`; base-image pinning, one hint per unpinned image, skipping `scratch` and stage aliases; literal secrets in `ENV`/`ARG`
16
+ - **docker-compose** (`docker-compose*.y[a]ml`, `compose*.y[a]ml`, so overrides like `docker-compose.override.yml` too): service list (feeds the topology graph), `env_file` references, host-mount volumes, privileged containers, Docker socket mounts, `cap_add: SYS_ADMIN`/`ALL`, `pid: host`, `seccomp:unconfined`, published ports that bind all interfaces (explicit `0.0.0.0`, or short syntax with no host IP such as `"5432:5432"`), `network_mode: host`, and literal secrets in `environment:`
17
+ - **GitHub Actions workflows** — `pull_request_target` with checkout, third-party actions pinned by tag vs SHA, secret exposure to fork PRs, step-level `permissions:`
18
+ - **`.env` templates** (`.env.example`, `sample.env`) — secret inventory (the shape, not the value)
19
+ - **Shell installers** — `curl | bash` patterns, `sudo` scope, TLS material handling
20
+ - **Kubernetes manifests** (any `.yaml`/`.yml` with top-level `apiVersion:` and `kind:`) — workloads (`Pod`, `Deployment`, `StatefulSet`, `DaemonSet`, `ReplicaSet`, `Job`, `CronJob`, `ReplicationController`): `privileged`, `allowPrivilegeEscalation: true`, `runAsUser: 0`, missing `runAsNonRoot` / `allowPrivilegeEscalation: false`, `hostPath` volumes (high for the runtime socket, `/`, `/etc`, `/proc`, `/sys`, `/dev`, `/var/lib/kubelet`…), `hostNetwork`/`hostPID`/`hostIPC`, dangerous capabilities, `Unconfined` seccomp/AppArmor, `:latest`/untagged images; RBAC roles with `*` on core/RBAC/apps groups, `escalate`/`bind`/`impersonate`, `pods/exec`, Secret reads; bindings to `cluster-admin` or `system:authenticated`/`unauthenticated`/`anonymous`; `LoadBalancer`/`NodePort` Services without `loadBalancerSourceRanges` (entrypoints too; internal load balancers skipped); `Ingress` host/path rules (routes); literal `Secret` values
21
+ - **Helm charts** — templates under `templates/` next to a `Chart.yaml` are read without rendering: `{{ }}` actions are stripped (line numbers kept) and a templated value is never reported, because the chart's values decide it. A setting inside `{{ if }}`/`{{ with }}` is reported with low confidence (it may be off by default). `values.yaml` defaults (`privileged`, `hostNetwork`/`hostPID`/`hostIPC`, `allowPrivilegeEscalation`, `runAsUser: 0`, capabilities) are reported with confidence 0.5
22
+
23
+ Emits routes for exposed ports, external calls for third-party actions and `curl` fetches, `SecretHint` for env-template inventory, service-topology hints for compose `services:` — feeding the same pipeline as the source-code analyzers.
24
+
25
+ ### Misconfigurations and posture signals
26
+
27
+ Every signal carries `file`, `line` and `evidence_text`. Signals about something *missing* (no `USER`, no `HEALTHCHECK`, no `permissions:`) point at the final `FROM` line or line 1.
28
+
29
+ Container and cluster misconfigurations are `CloudMisconfig` records (`cloud_misconfigs`, iac#1), which AttackMap core turns into findings with CWE/OWASP ids. Each names the `resource` (`Deployment/web container app`, `service agent`), a per-instance `severity` and `confidence`, and an `escalation_path` (e.g. `container runtime socket → start a privileged container → root on the node`):
30
+
31
+ | Kind | Dockerfile / compose | Kubernetes / Helm |
32
+ |---|---|---|
33
+ | `container_runs_as_root` | no `USER` in the final stage (low), `USER root` (medium) | `runAsUser: 0` |
34
+ | `privileged_container` | `privileged: true` | `securityContext.privileged: true` |
35
+ | `host_path_mount` | runtime socket and `/etc`, `/proc`, … bind mounts (`/srv/data` is not reported) | `hostPath` volumes |
36
+ | `host_namespace_shared` | `pid: host`, `ipc: host`, `network_mode: host` | `hostPID`, `hostNetwork`, `hostIPC` |
37
+ | `dangerous_capability` | `cap_add` | `capabilities.add` (`SYS_ADMIN`, `ALL`, `SYS_MODULE`, `SYS_PTRACE`, … high; `NET_ADMIN` medium) |
38
+ | `security_profile_disabled` | `seccomp:unconfined`, `apparmor:unconfined` | `seccompProfile`/`appArmorProfile` `Unconfined` |
39
+ | `unpinned_container_image` | `FROM image:latest` or untagged | `image:` `:latest` or untagged |
40
+ | `dockerfile_remote_add` / `dockerfile_curl_pipe_shell` | `ADD <url>` without `--checksum`, `RUN curl \| sh` | |
41
+ | `privilege_escalation_allowed`, `missing_security_context` (low) | | `allowPrivilegeEscalation: true`; no `runAsNonRoot` / `allowPrivilegeEscalation: false` |
42
+ | `rbac_wildcard`, `rbac_escalation`, `rbac_secret_access`, `cluster_admin_binding`, `exposed_service` | | RBAC and Services |
43
+
44
+ No `AuthHint`s are emitted: core reads those as auth signals, and one in a Dockerfile counted as an auth control for its `EXPOSE` route. With an AttackMap core older than the `CloudMisconfig` record, the old `AuthHint`s (`dockerfile_no_user_directive`, `dockerfile_user_root`, `compose_privileged_container`, `compose_docker_socket_mount`, `compose_cap_add_sys_admin`, `compose_pid_host`, `compose_seccomp_unconfined`) are emitted instead. The other signals are split by meaning (AttackMap#258):
45
+
46
+ | Signal list | Hints |
47
+ |---|---|
48
+ | `entrypoint_hints` (network exposure) | `compose_port_binding_all_interfaces:<binding>`, `compose_network_mode_host`, `k8s_service_loadbalancer:<name>`, `k8s_service_nodeport:<name>`, `k8s_ingress:<host>` |
49
+ | `framework_hints` (build, supply-chain, CI and deployment config) | `dockerfile_no_healthcheck`, `dockerfile_run_curl_pipe`, `dockerfile_add_remote`, `dockerfile_base_image_unpinned:<image>`, `compose_env_file_reference`, `compose_host_mount:<host path>`, `gha_third_party_action_tag_pinned:<owner/repo>`, `gha_pull_request_target_with_checkout`, `gha_no_top_level_permissions`, `shell_curl_pipe_installer`, `shell_sudo_used`, `shell_permissive_chmod` |
50
+ | `service_hints` | `service_name:<compose service>` |
51
+
52
+ The Dockerfile user check looks at the final stage's effective user (the last `USER`, inherited through `FROM <stage>`). A `USER nobody` in a builder stage doesn't hide a root final image, and `USER root` followed by `USER app` isn't flagged. A final base tagged `:nonroot` counts as setting a user.
53
+
54
+ Secret-shaped `ENV`/`ARG` names (`*SECRET*`, `*TOKEN*`, `*PASSWORD*`, `*_KEY`, …) and `environment:` entries with a literal value become `SecretHint(kind="hardcoded")`. `*_FILE` paths, `${VAR}` references, booleans and `ARG` without a default are not flagged.
55
+
56
+ Bluesky FINDINGS §2 documented this as the biggest coverage gap: `bluesky-social/pds` (a deployment repo) was 95% invisible to AttackMap because every non-JS file was outside the analyzer model. This plugin closes that gap.
57
+
58
+ ## Install
59
+
60
+ ```bash
61
+ uv tool install attackmap --with attackmap-analyzer-iac \
62
+ --index mlaify=https://pkg.mlaify.io/pypi/simple/ --index-strategy first-index
63
+ # or from source:
64
+ pip install git+https://github.com/mlaify/attackmap-analyzer-iac.git
65
+ # or as part of the bundle
66
+ pip install "attackmap[all] @ git+https://github.com/mlaify/AttackMap.git"
67
+ ```
68
+
69
+ ## Usage
70
+
71
+ Runs automatically via the `attackmap.analyzers` entry-point group once installed:
72
+
73
+ ```bash
74
+ attackmap analyze /path/to/deployment-repo --output reports
75
+ ```
76
+
77
+ ## Contract
78
+
79
+ Implements `AnalyzerProtocol` from `attackmap.sdk`. See the [external-analyzer guide](https://github.com/mlaify/AttackMap/blob/main/docs/external-analyzers.md).
80
+
81
+ ## Scope
82
+
83
+ **In:** patterns any competent operator recognizes on inspection — the docker-compose service graph, `pull_request_target` combined with untrusted checkout, non-root User directive presence, curl-piped installer scripts.
84
+
85
+ **Out:** deep semantic analysis of container image contents, live registry scanning, executed-runtime introspection. Those belong in other tools; AttackMap's differentiator is narrative attack-path reasoning over the code you can see.
@@ -0,0 +1,81 @@
1
+ [build-system]
2
+ requires = ["setuptools>=77", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "attackmap-analyzer-iac"
7
+ version = "0.2.0"
8
+ description = "Infrastructure-as-Code analyzer plugin for AttackMap (Dockerfile, docker-compose, Kubernetes, Helm, GitHub Actions, .env templates, shell installers)"
9
+ readme = "README.md"
10
+ requires-python = ">=3.11"
11
+ license = "MIT"
12
+ license-files = ["LICENSE"]
13
+ authors = [
14
+ {name = "Matthew Davis", email = "mlaify@mlaify.io"},
15
+ {name = "AttackMap Contributors"},
16
+ ]
17
+ maintainers = [
18
+ {name = "Matthew Davis", email = "mlaify@mlaify.io"},
19
+ ]
20
+ keywords = [
21
+ "security",
22
+ "static-analysis",
23
+ "appsec",
24
+ "defensive-security",
25
+ "attackmap",
26
+ "attackmap-plugin",
27
+ "iac",
28
+ "docker",
29
+ "docker-compose",
30
+ "github-actions",
31
+ "kubernetes",
32
+ "helm",
33
+ ]
34
+ classifiers = [
35
+ "Development Status :: 4 - Beta",
36
+ "Intended Audience :: Developers",
37
+ "Intended Audience :: Information Technology",
38
+ "Intended Audience :: System Administrators",
39
+ "Operating System :: OS Independent",
40
+ "Programming Language :: Python :: 3",
41
+ "Programming Language :: Python :: 3.11",
42
+ "Programming Language :: Python :: 3.12",
43
+ "Programming Language :: Python :: 3.13",
44
+ "Programming Language :: Python :: 3 :: Only",
45
+ "Topic :: Security",
46
+ "Topic :: Software Development :: Quality Assurance",
47
+ "Typing :: Typed",
48
+ ]
49
+ dependencies = [
50
+ "pydantic>=2.7.0",
51
+ "PyYAML>=6.0",
52
+ ]
53
+
54
+ [project.optional-dependencies]
55
+ core = [
56
+ "attackmap>=0.6.0",
57
+ ]
58
+ dev = [
59
+ "pytest>=8.0.0",
60
+ "build>=1.2.0",
61
+ "attackmap>=0.6.0",
62
+ ]
63
+
64
+ [project.urls]
65
+ Homepage = "https://github.com/mlaify/attackmap-analyzer-iac"
66
+ Repository = "https://github.com/mlaify/attackmap-analyzer-iac"
67
+ Issues = "https://github.com/mlaify/attackmap-analyzer-iac/issues"
68
+ Changelog = "https://github.com/mlaify/attackmap-analyzer-iac/blob/main/CHANGELOG.md"
69
+ "AttackMap core" = "https://github.com/mlaify/AttackMap"
70
+
71
+ [project.entry-points."attackmap.analyzers"]
72
+ iac = "attackmap_analyzer_iac:IacAnalyzer"
73
+
74
+ [tool.setuptools]
75
+ package-dir = {"" = "src"}
76
+
77
+ [tool.setuptools.packages.find]
78
+ where = ["src"]
79
+
80
+ [tool.pytest.ini_options]
81
+ testpaths = ["tests"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,3 @@
1
+ from .analyzer import IacAnalyzer
2
+
3
+ __all__ = ["IacAnalyzer"]