Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
9368126
fix(security): pin litellm to 1.81.1 to mitigate supply chain attack
shiva-guntoju-09 Mar 25, 2026
c155f59
chore: regenerate poetry.lock for crewai example after litellm pin
shiva-guntoju-09 Mar 25, 2026
065c74e
Revert "Chore: AIFW-19340: Align Existing MCPScan Models in SDK with …
shiva-guntoju-09 Mar 25, 2026
de6b5a6
chore(deps): security updates across 10 example directories (#89)
shiva-guntoju-09 Mar 26, 2026
43c5c0c
Bump version to 2.1.1 (#92)
urajat Mar 26, 2026
b0431cf
Revert "Revert "Chore: AIFW-19340: Align Existing MCPScan Models in S…
psg-cisco Mar 26, 2026
7444366
feat: AIFW-19340: add missing mcp registry endpoints (#81)
vokit-cisco Mar 26, 2026
1cdde70
feat: AIFW-19570: add high-level client for aibom operations
vokit-cisco Mar 19, 2026
965b446
feat: AIFW-19570: update poetry lock file
vokit-cisco Mar 19, 2026
de24551
feat: AIFW-19570: improve type hints
vokit-cisco Mar 19, 2026
7b64584
test: AIFW-19570: add tests for aibom client
vokit-cisco Mar 19, 2026
dfeb7a7
test: AIFW-19570: add tests for aibom base client
vokit-cisco Mar 19, 2026
41de85e
test: AIFW-19570: fix init for aibom package
vokit-cisco Mar 19, 2026
2f87b52
test: AIFW-19570: make aibom library optional in code; add regression…
vokit-cisco Mar 19, 2026
0238773
test: AIFW-19570: add aibom to test pipeline
vokit-cisco Mar 23, 2026
51b0101
test: AIFW-19570: add result polling for submited report
vokit-cisco Mar 23, 2026
f4508e2
chore: AIFW-19570:fix example to use proper bom statuses
vokit-cisco Mar 24, 2026
834b682
chore: AIFW-19570: remove unused checsum field; fail when provided wi…
vokit-cisco Mar 27, 2026
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
4 changes: 2 additions & 2 deletions .github/workflows/python-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@ jobs:
python-version: ${{ matrix.python-version }}

- name: Install dependencies
run: poetry install
run: poetry install --extras aibom

- name: Install extra test dependencies
run: poetry run pip install boto3 google-auth

- name: Run tests
run: poetry run pytest
run: poetry run pytest
48 changes: 48 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Integrate AI-powered security, privacy, and safety inspections into your Python
- [Agent Runtime SDK (Recommended)](#agent-runtime-sdk-recommended)
- [Inspection API](#inspection-api)
- [Model Scanning API](#model-scanning-api)
- [AIBOM API](#aibom-api)
- [Management API](#management-api)
- [SDK Structure](#sdk-structure)
- [Usage Examples](#usage-examples)
Expand All @@ -23,6 +24,7 @@ Integrate AI-powered security, privacy, and safety inspections into your Python
- [MCP Inspection](#mcp-inspection)
- [MCP Server Scanning](#mcp-server-scanning)
- [Model Scanning](#model-scanning)
- [AIBOM](#aibom)
- [Management API Examples](#management-api-examples)
- [Validation API](#validation-api)
- [Configuration](#configuration)
Expand Down Expand Up @@ -186,6 +188,26 @@ if result.status == ScanStatus.COMPLETED:
print(f"✅ {file_info.name} is clean")
```

### AIBOM API

```python
from aidefense import Config
from aidefense.aibom.aibom_client import AiBomClient

# Initialize client
client = AiBomClient(
api_key="YOUR_MANAGEMENT_API_KEY",
config=Config(management_base_url="https://api.security.cisco.com"),
)

# Analyze and submit
report = client.analyze(sources=["/path/to/project"])
response = client.submit_report_file(raw_data=report)
print(response.analysis_id, response.status)
```

See [AIBOM module docs](aidefense/aibom/README.md) for full API reference and additional examples.

### Management API

```python
Expand Down Expand Up @@ -268,6 +290,13 @@ print(resp.task_id)
- `modelscan/model_scan_base.py` — ModelScan base class for granular scan operations
- `modelscan/models.py` — Data models for scan requests, responses, and status information

### AIBOM API

- `aibom/aibom_client.py` — AiBomClient for analyze-and-submit workflows
- `aibom/aibom_base.py` — AiBom base client for direct AIBOM API operations
- `aibom/models.py` — Data models for AIBOM requests, responses, and filters
- `aibom/README.md` — AIBOM usage guide and method examples

### Management API

- `management/__init__.py` — ManagementClient for accessing all management APIs
Expand Down Expand Up @@ -657,6 +686,25 @@ print(f"Scan status: {scan_info.status}")
print(f"Files analyzed: {len(scan_info.analysis_results.items)}")
```

### AIBOM

```python
from aidefense import Config
from aidefense.aibom.aibom_client import AiBomClient

client = AiBomClient(
api_key="YOUR_MANAGEMENT_API_KEY",
config=Config(management_base_url="https://api.security.cisco.com"),
)

# Run local AIBOM analysis, then submit it
report = client.analyze(sources=["/path/to/project"])
submission = client.submit_report_file(raw_data=report)
print(f"Created analysis: {submission.analysis_id}")
```

For direct endpoint-style operations (create/list/get/components/summary/delete), use the base client and examples in [aidefense/aibom/README.md](aidefense/aibom/README.md).

### Management API

#### Managing Applications
Expand Down
159 changes: 159 additions & 0 deletions aidefense/aibom/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
# AI Defense AIBOM Module

The AI Defense AIBOM module provides APIs for creating, storing, and querying AI Bill of Materials (AIBOM) analyses. It supports both:

- High-level workflows through `AiBomClient` (analyze sources and submit reports)
- Low-level API access through `AiBom` (direct CRUD/query operations)

## Features

- **Analyze and Submit**: Run local AIBOM analysis and submit results to AI Defense
- **Report Submission**: Submit already-generated AIBOM JSON reports
- **BOM Query APIs**: List BOMs, fetch BOM details, and list BOM components
- **Summary Statistics**: Retrieve aggregate AIBOM summary metrics
- **Delete Support**: Remove BOMs by `analysis_id`

## Installation

```bash
pip install cisco-aidefense-sdk
```

If you want to use `AiBomClient.analyze(...)`, install the optional AIBOM extra:

```bash
pip install "cisco-aidefense-sdk[aibom]"
```

## Quick Start

### High-Level Client: Analyze and Submit

```python
from aidefense import Config
from aidefense.aibom.aibom_client import AiBomClient

client = AiBomClient(
api_key="YOUR_MANAGEMENT_API_KEY",
config=Config(management_base_url="https://api.security.cisco.com"),
)

# Analyze one or more local sources
report = client.analyze(sources=["/path/to/project"])

# Submit the generated report
response = client.submit_report_file(raw_data=report)
print(response.analysis_id, response.status)
```

### Submit an Existing Report File

```python
from pathlib import Path
from aidefense import Config
from aidefense.aibom.aibom_client import AiBomClient

client = AiBomClient(
api_key="YOUR_MANAGEMENT_API_KEY",
config=Config(management_base_url="https://api.security.cisco.com"),
)

response = client.submit_report_file(file_path=Path("./aibom-report.json"))
print(response.model_dump_json(indent=2))
```

### Low-Level Client: Direct AIBOM API Methods

```python
from aidefense import Config
from aidefense.aibom.aibom_base import AiBom
from aidefense.aibom.models import (
BomsSummaryRequest,
ListBomComponentsRequest,
ListBomsRequest,
)

client = AiBom(
api_key="YOUR_MANAGEMENT_API_KEY",
config=Config(management_base_url="https://api.security.cisco.com"),
)

# List BOMs
boms = client.list_boms(ListBomsRequest(limit=10, offset=0))
print(f"Found {len(boms.items)} BOMs")

if boms.items:
analysis_id = boms.items[0].analysis_id

# Get one BOM
bom = client.get_bom(analysis_id)
print(bom.model_dump_json(indent=2))

# List components
components = client.list_bom_components(
analysis_id,
ListBomComponentsRequest(limit=20, offset=0),
)
print(f"Components: {len(components.items)}")

# Get summary
summary = client.get_bom_summary(BomsSummaryRequest())
print(summary.model_dump_json(indent=2))
```

## API Surface

### `AiBomClient` Methods

- `analyze(sources, output_file=None, **kwargs) -> dict`
- `submit_report_file(raw_data=None, file_path=None) -> CreateAnalysisResponse`
- `analyze_and_submit(sources, output_file=None, **kwargs) -> CreateAnalysisResponse`

### `AiBom` Methods

- `create_analysis(req: CreateAnalysisRequest) -> CreateAnalysisResponse`
- `list_boms(req: ListBomsRequest) -> ListBomsResponse`
- `get_bom(analysis_id: str) -> BomDetail`
- `delete_bom(analysis_id: str) -> None`
- `list_bom_components(analysis_id: str, req: ListBomComponentsRequest) -> ListBomComponentsResponse`
- `get_bom_summary(req: BomsSummaryRequest) -> GetBomSummaryResponse`

## BOM Status Reference

| Status | Description |
| ------------------------------------ | ------------------------------ |
| `BOM_STATUS_UNSPECIFIED` | Status unknown or unspecified |
| `BOM_STATUS_COMPLETED` | Analysis completed successfully |
| `BOM_STATUS_COMPLETED_WITH_ERRORS` | Completed, with non-fatal errors |
| `BOM_STATUS_FAILED` | Analysis failed |
| `BOM_STATUS_SKIPPED` | Analysis was skipped |

## Source Kind Reference

| Source Kind | Description |
| ---------------------------- | ------------------------------------ |
| `SOURCE_KIND_LOCAL_PATH` | Local file system source |
| `SOURCE_KIND_CONTAINER` | Container image/source |
| `SOURCE_KIND_OTHER` | Mixed or unknown source type |
| `SOURCE_KIND_UNSPECIFIED` | Unspecified source type |

## Error Handling

```python
from aidefense.exceptions import ApiError, ValidationError, SDKError

try:
report = client.analyze(sources=["/path/to/project"])
response = client.submit_report_file(raw_data=report)
except ValidationError as e:
print(f"Invalid request: {e}")
except ApiError as e:
print(f"API error: {e}")
except SDKError as e:
print(f"SDK error: {e}")
```

## Related Examples

- `examples/aibom/aibom_client.py`
- `examples/aibom/aibom_base.py`
33 changes: 33 additions & 0 deletions aidefense/aibom/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Copyright 2026 Cisco Systems, Inc. and its affiliates
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0

from .aibom_client import AiBomClient
from .aibom_base import AiBom
from .models import (
CreateAnalysisRequest,
CreateAnalysisResponse,
GetBomSummaryResponse,
ListBomComponentsRequest,
ListBomComponentsResponse,
ListBomsRequest,
ListBomsResponse,
BomDetail,
)

__all__ = [
"AiBomClient",
"AiBom",
]
Loading
Loading