Architectural analysis and security audits for Choreo.Infrastructure.
Provides automated audits for common cloud infrastructure configurations:
- Flagging direct internet connections to resources inside private subnets.
- Ensuring managed databases (
:managed_db) and storage are isolated inside private subnets. - Ensuring load balancers (
:load_balancer) are placed within public subnets. - Detecting compute nodes without subnet assignments.
Summary
Functions
Returns a list of direct connection edge tuples {from, to} between public internet nodes
and private subnet resources.
Returns nodes with no connections (zero in-degree and out-degree).
Returns a list of managed database node IDs located outside private subnets.
Returns a list of load balancer node IDs located outside public subnets.
Returns a list of storage node IDs placed inside public subnets.
Returns a list of compute node IDs not assigned to any subnet.
Runs analysis checks on the topology and returns a list of {severity, message} tuples.
Functions
@spec direct_internet_violations(Choreo.Infrastructure.t() | Choreo.t()) :: [ {Yog.node_id(), Yog.node_id()} ]
Returns a list of direct connection edge tuples {from, to} between public internet nodes
and private subnet resources.
Examples
iex> infra = Choreo.Infrastructure.new()
iex> infra = infra
...> |> Choreo.Infrastructure.add_internet(:gw)
...> |> Choreo.Infrastructure.add_subnet_private("priv")
...> |> Choreo.Infrastructure.add_compute(:app, cluster: "priv")
...> |> Choreo.Infrastructure.connect(:gw, :app)
iex> Choreo.Infrastructure.Analysis.direct_internet_violations(infra)
[{:gw, :app}]
@spec isolated_nodes(Choreo.Infrastructure.t() | Choreo.t()) :: [Yog.node_id()]
Returns nodes with no connections (zero in-degree and out-degree).
Examples
iex> infra = Choreo.Infrastructure.new() |> Choreo.Infrastructure.add_compute(:orphan)
iex> Choreo.Infrastructure.Analysis.isolated_nodes(infra)
[:orphan]
@spec misplaced_databases(Choreo.Infrastructure.t() | Choreo.t()) :: [Yog.node_id()]
Returns a list of managed database node IDs located outside private subnets.
Examples
iex> infra = Choreo.Infrastructure.new() |> Choreo.Infrastructure.add_managed_db(:db)
iex> Choreo.Infrastructure.Analysis.misplaced_databases(infra)
[:db]
@spec misplaced_load_balancers(Choreo.Infrastructure.t() | Choreo.t()) :: [ Yog.node_id() ]
Returns a list of load balancer node IDs located outside public subnets.
Examples
iex> infra = Choreo.Infrastructure.new() |> Choreo.Infrastructure.add_load_balancer(:alb)
iex> Choreo.Infrastructure.Analysis.misplaced_load_balancers(infra)
[:alb]
@spec misplaced_storage(Choreo.Infrastructure.t() | Choreo.t()) :: [Yog.node_id()]
Returns a list of storage node IDs placed inside public subnets.
Examples
iex> infra = Choreo.Infrastructure.new()
...> |> Choreo.Infrastructure.add_subnet_public("pub")
...> |> Choreo.Infrastructure.add_storage(:s3, cluster: "pub")
iex> Choreo.Infrastructure.Analysis.misplaced_storage(infra)
[:s3]
@spec unassigned_compute(Choreo.Infrastructure.t() | Choreo.t()) :: [Yog.node_id()]
Returns a list of compute node IDs not assigned to any subnet.
Examples
iex> infra = Choreo.Infrastructure.new() |> Choreo.Infrastructure.add_compute(:app)
iex> Choreo.Infrastructure.Analysis.unassigned_compute(infra)
[:app]
@spec validate(Choreo.Infrastructure.t() | Choreo.t()) :: [ {:error | :warning, String.t()} ]
Runs analysis checks on the topology and returns a list of {severity, message} tuples.
Examples
iex> infra = Choreo.Infrastructure.new()
iex> infra = infra
...> |> Choreo.Infrastructure.add_internet(:gateway)
...> |> Choreo.Infrastructure.add_subnet_private("subnet_app")
...> |> Choreo.Infrastructure.add_compute(:api, cluster: "subnet_app")
...> |> Choreo.Infrastructure.connect(:gateway, :api)
iex> Choreo.Infrastructure.Analysis.validate(infra)
[{:error, "Private resource 'api' is connected directly to public internet boundary 'gateway'."}]