Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions docs/api-mapping/api-mgmt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# api-mgmt API Mapping

## Slice Goal

Surface operator-first API Management service posture before deeper APIM analysis exists.

This first version answers:
"Which API Management services expose interesting gateway hostnames, identity context, and basic
service inventory for operator follow-up?"

## Initial Scope

- API Management service enumeration
- Gateway, management, and portal hostname visibility
- Public network access and virtual network mode
- Managed identity attachment context
- Basic per-service inventory counts for APIs, backends, and named values

## Explicit Non-Goals For V1

- APIM subscription inventory or subscription-required risk depth
- Named-value secret classification or Key Vault-backed named-value depth
- Policy body collection or policy-content inspection
- Backend URL trust modeling beyond simple backend count visibility

## Primary APIs

- `azure.mgmt.apimanagement.ApiManagementClient.api_management_service.list`
- `azure.mgmt.apimanagement.ApiManagementClient.api.list_by_service`
- `azure.mgmt.apimanagement.ApiManagementClient.backend.list_by_service`
- `azure.mgmt.apimanagement.ApiManagementClient.named_value.list_by_service`

## Correlation / Joins

- Normalize service-level APIM metadata into operator-first rows
- Join hostname, public exposure, identity, and service inventory into a single service summary
- Keep partial-read gaps explicit when API, backend, or named-value reads are denied

## Blind Spots

- V1 does not inspect APIM subscriptions, policy bodies, or named-value secret content
- Named-value counts show service shape, not whether values are sensitive or retrievable
- Backend count visibility does not prove backend reachability or trust-path abuse
52 changes: 52 additions & 0 deletions docs/future-phase-candidates.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,29 @@ Why it should wait:

- it needs the shared network vocabulary from `nics` and `endpoints` first

### `api-mgmt-depth`

Why it is grounded now:

- the roadmap already includes `api-mgmt` as a Phase 3 service slice
- once AzureFox lands a first API Management foothold, the repo can reuse that client and
service-level inventory path for narrower follow-on depth

Why it should be separate:

- API Management subscriptions, named-value secret handling, and policy-body inspection can easily
overwhelm a first operator-first service census
- those areas deserve a later evidence-based follow-on once the initial gateway, hostname,
identity, and inventory posture command settles

What this future follow-on could absorb:

- subscription inventory and operator risk cues
- named-value secret posture beyond simple counts
- Key Vault-backed named-value depth
- policy-body collection or policy-shape summaries
- backend URL and trust-path deepening where the first `api-mgmt` slice stays intentionally narrow

### `network-effective`

Why it is grounded now:
Expand Down Expand Up @@ -104,6 +127,35 @@ Do not promote these yet from the current repo state:
- AI, Lighthouse, DevOps, or automation sub-slices beyond the roadmap until the core compute and
network tranche is further along

## Broader Roadmap Gaps To Revisit Once Grounded

The external roadmap reference also calls out broader domain gaps that should stay visible even
though they do not yet meet this document's repo-foothold rule.

Keep these as watch items, not near-term candidates, until AzureFox gains client, fixture, or
collector adjacency for them:

- messaging and eventing
Azure Service Bus, Event Grid, Event Hubs, and queue-oriented trust or data-path review
- filesystems and mounted storage
Azure Files, Azure NetApp Files, and mount-oriented loot or trust paths
- data, analytics, and search platforms
Synapse, Data Explorer, Log Analytics, and search-oriented operator surfaces that do not fit
cleanly under broad `databases`
- governance metadata
tags, labels, and other governance-oriented enumeration surfaces
- directory-services-specific coverage
Azure AD DS or managed domain-service style visibility beyond current Entra and RBAC coverage

Note on edge and delivery surfaces:

- the external roadmap reference calls out Front Door, CDN, Application Gateway, and
load-balancer-style discovery
- the current future candidates already partially cover this family through `public-ips` and
`load-balancers`
- revisit a broader edge-delivery command later if those footholds land and we need a more unified
operator surface

## Recommendation

The strongest later candidate outside the current roadmap command list is `entra-graph`.
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ azure = [
"azure-mgmt-compute>=33.0,<34",
"azure-mgmt-network>=26.0,<27",
"azure-mgmt-web>=7.3,<8",
"azure-mgmt-apimanagement>=5.0,<6",
"certifi>=2024.2,<2027",
]
dev = [
Expand Down
9 changes: 9 additions & 0 deletions schemas/api-mgmt.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"model": "ApiMgmtOutput",
"top_level_fields": [
"metadata",
"api_management_services",
"findings",
"issues"
]
}
2 changes: 2 additions & 0 deletions scripts/generate_schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from pathlib import Path

from azurefox.models.commands import (
ApiMgmtOutput,
AppServicesOutput,
ArmDeploymentsOutput,
AuthPoliciesOutput,
Expand Down Expand Up @@ -32,6 +33,7 @@
"whoami": WhoAmIOutput,
"inventory": InventoryOutput,
"app-services": AppServicesOutput,
"api-mgmt": ApiMgmtOutput,
"functions": FunctionsOutput,
"arm-deployments": ArmDeploymentsOutput,
"auth-policies": AuthPoliciesOutput,
Expand Down
5 changes: 5 additions & 0 deletions src/azurefox/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,11 @@ def functions(ctx: typer.Context) -> None:
_run_single(ctx, "functions")


@app.command("api-mgmt")
def api_mgmt(ctx: typer.Context) -> None:
_run_single(ctx, "api-mgmt")


@app.command("arm-deployments")
def arm_deployments(ctx: typer.Context) -> None:
_run_single(ctx, "arm-deployments")
Expand Down
3 changes: 3 additions & 0 deletions src/azurefox/clients/factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ class AzureClients:
resource: object
authorization: object
web: object
api_management: object
keyvault: object
storage: object
compute: object
Expand All @@ -22,6 +23,7 @@ class AzureClients:

def build_clients(session: AuthSession, requested_subscription: str | None) -> AzureClients:
try:
from azure.mgmt.apimanagement import ApiManagementClient
from azure.mgmt.authorization import AuthorizationManagementClient
from azure.mgmt.compute import ComputeManagementClient
from azure.mgmt.keyvault import KeyVaultManagementClient
Expand Down Expand Up @@ -73,6 +75,7 @@ def build_clients(session: AuthSession, requested_subscription: str | None) -> A
resource=ResourceManagementClient(session.credential, subscription_id),
authorization=AuthorizationManagementClient(session.credential, subscription_id),
web=WebSiteManagementClient(session.credential, subscription_id),
api_management=ApiManagementClient(session.credential, subscription_id),
keyvault=KeyVaultManagementClient(session.credential, subscription_id),
storage=StorageManagementClient(session.credential, subscription_id),
compute=ComputeManagementClient(session.credential, subscription_id),
Expand Down
12 changes: 12 additions & 0 deletions src/azurefox/collectors/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
build_vm_findings,
)
from azurefox.models.commands import (
ApiMgmtOutput,
AppServicesOutput,
ArmDeploymentsOutput,
AuthPoliciesOutput,
Expand Down Expand Up @@ -68,6 +69,17 @@ def collect_app_services(provider: BaseProvider, options: GlobalOptions) -> AppS
)


def collect_api_mgmt(provider: BaseProvider, options: GlobalOptions) -> ApiMgmtOutput:
data = provider.api_mgmt()
return ApiMgmtOutput.model_validate(
{
"metadata": _metadata(provider, "api-mgmt", options),
"findings": [],
**data,
}
)


def collect_functions(provider: BaseProvider, options: GlobalOptions) -> FunctionsOutput:
data = provider.functions()
return FunctionsOutput.model_validate(
Expand Down
Loading
Loading