Extension Entry Points¶
agent-bom supports opt-in Python entry points for external inventory parsers,
cloud providers, and SaaS connectors. This lets teams ship ecosystem-specific
integrations as separate packages without modifying src/agent_bom.
Entry point loading is disabled by default. Enable it only in trusted environments:
Entry Point Groups¶
| Group | Purpose | Registration type |
|---|---|---|
agent_bom.inventory_parsers |
Package or manifest parsers | InventoryParserRegistration |
agent_bom.cloud_providers |
Cloud inventory discovery | CloudProviderRegistration |
agent_bom.connectors |
SaaS connector discovery | ConnectorRegistration |
Built-in registrations use the same registry path, so list_registered_*
returns built-ins plus trusted entry-point extensions when enabled.
Three further opt-in groups — agent_bom.mcp_tools,
agent_bom.advisory_sources, and agent_bom.runtime_emitters — plus the full
author contract, capability model, and runnable examples are documented in
docs/PLUGIN_ENTRYPOINTS.md.
Inventory Parser Example¶
[project.entry-points."agent_bom.inventory_parsers"]
acme_lock = "agent_bom_parser_acme:registration"
from pathlib import Path
from agent_bom.extensions import ExtensionCapabilities
from agent_bom.models import MCPServer, Package
from agent_bom.parsers.base import InventoryParserRegistration
def parse_acme_lock(root: Path, server: MCPServer | None = None) -> list[Package]:
lockfile = root / "acme.lock"
if not lockfile.exists():
return []
return [Package(name="example", version="1.0.0", ecosystem="acme")]
def registration() -> InventoryParserRegistration:
return InventoryParserRegistration(
name="acme-lock",
module="agent_bom_parser_acme",
parse_attr="parse_acme_lock",
manifest_names=("acme.lock",),
capabilities=ExtensionCapabilities(
scan_modes=("inventory",),
required_scopes=("local_project_read",),
outbound_destinations=(),
data_boundary="local_manifest_read_only",
writes=False,
network_access=False,
guarantees=("read_only", "no_secret_collection"),
),
source="entry_point",
)
Capability Contract¶
Every extension should declare its operational boundary through
ExtensionCapabilities:
scan_modes: inventory, cloud read-only, SaaS read-only, runtime probe, etc.required_scopes: local permissions, API scopes, IAM permissions, or roles.permissions_used: concrete read permissions used during discovery.outbound_destinations: API hosts or registries the extension contacts.data_boundary: what data is read and whether it leaves the local machine.writes: must beFalsefor read-only discovery integrations.network_access:Trueonly when the extension opens network connections.guarantees: read-only, redacted, no secret collection, bounded output, etc.
These fields are exposed through the provider/parser registries and are intended to become part of scan evidence and control-plane discovery envelopes.
Safety Rules¶
- Keep parser extensions read-only.
- Do not collect raw secret values; return names, references, and redacted evidence instead.
- Keep warnings user-safe. Registry load failures are sanitized before display.
- Avoid running subprocesses from parsers unless the extension documentation declares the command and its arguments.
- Prefer structured parser APIs over ad hoc shell commands.
Local Verification¶
AGENT_BOM_ENABLE_EXTENSION_ENTRYPOINTS=true python - <<'PY'
from agent_bom.parsers import list_registered_inventory_parsers
for parser in list_registered_inventory_parsers():
print(parser.name, parser.module, parser.source)
PY
Save connector evidence in a control plane¶
An installed, trusted agent_bom.connectors extension can be selected by its
registered name in a scan request. Configure source credentials on the server
through the extension's documented mechanism; keep them scoped to source reads.
Configure the control plane's destination store separately. A source connection
does not authorize writes back to that source.
curl --fail-with-body -X POST http://localhost:8422/v1/scan \
-H "Authorization: Bearer $AGENT_BOM_API_KEY" \
-H 'Content-Type: application/json' \
-d '{"connectors":["customer-inventory"],"enrich":false}'
Replace customer-inventory with the installed registration name. The response
provides a job identifier. Poll /v1/scan/{job_id} until completion, then inspect
the report's graph_persistence status before querying that scan's saved graph.
persisted confirms graph storage succeeded; a completed scan alone does not.
Source warnings and missing enrichment remain evidence gaps.
Extensions return the existing Agent, MCPServer, and Package models.
Cloud assets can use agent_bom.cloud.normalization envelopes to preserve source
identity and produce typed resource relationships. This reuses the product's
report and graph schemas; it does not register a new database backend or migrate
arbitrary source tables. Optional advisory enrichment follows the configured
scan and network policy.
The local integration regression
tests/test_entrypoint_registries.py::test_custom_connector_scan_saves_reusable_tenant_graph
exercises registration, scan execution, SQLite persistence, tenant isolation, and
replay without duplicate edges. It uses a local connector fixture; authenticated
provider collection and other storage backends need their own deployment checks.