Skip to content

Latest commit

 

History

History
508 lines (386 loc) · 17.4 KB

File metadata and controls

508 lines (386 loc) · 17.4 KB

Trusera Open Source Platform — Internal Bible

Single source of truth for the ai-bom monorepo, all SDKs, CI/CD, publishing, and conventions. Keep this file updated when things change. Last updated: 2026-02-18.


Repository

  • Repo: github.com/Trusera/ai-bom
  • License: Apache-2.0 (root + SDKs), MIT (n8n-node only)
  • Branch protection: main requires 3 status checks (bypassed by admin PAT)

Monorepo Structure

ai-bom/
├── src/ai_bom/              # Core scanner — PyPI: ai-bom
│   ├── scanners/             # 14 scanners
│   ├── reporters/            # 9 output formats
│   ├── compliance/           # OWASP + EU AI Act
│   ├── callable/             # Red-teaming bridge (Giskard)
│   ├── dashboard/            # FastAPI web dashboard
│   ├── cli.py                # Typer CLI entrypoint
│   ├── policy.py             # CI/CD policy enforcement
│   ├── server.py             # FastAPI REST server
│   ├── watcher.py            # Watchdog file watcher
│   └── __init__.py           # __version__ lives here
├── trusera-agent-sdk/        # Python agent SDK — PyPI: trusera-sdk
├── trusera-sdk-js/           # TypeScript agent SDK — npm: trusera-sdk
├── trusera-sdk-go/           # Go agent SDK — go get
├── n8n-node/                 # n8n community node — npm: n8n-nodes-trusera
├── vscode-extension/         # VS Code extension (VSIX)
├── templates/                # GitLab CI template
├── scripts/                  # cedar-gate.py
├── examples/                 # Example scan targets
├── tests/                    # 651+ tests for ai-bom core
├── docs/                     # MkDocs source
├── dist/                     # GitHub Action dist (action.yml)
├── pyproject.toml            # ai-bom package config
├── Makefile                  # Dev commands
├── Dockerfile                # Docker distribution
└── .github/workflows/        # CI/CD (see below)

Package Registry Map

Package Directory Registry Current Version Install
ai-bom src/ai_bom/ PyPI 3.3.2 pip install ai-bom
trusera-sdk (Python) trusera-agent-sdk/ PyPI 1.0.0 (Stable) pip install trusera-sdk
trusera-sdk (JS) trusera-sdk-js/ npm 0.2.0 (Beta) npm install trusera-sdk
trusera-sdk-go trusera-sdk-go/ Go modules 0.1.0 (Beta) go get github.com/Trusera/ai-bom/trusera-sdk-go
n8n-nodes-trusera n8n-node/ npm 0.5.0 Install via n8n community nodes
ai-bom-scanner (VS Code) vscode-extension/ VS Code Marketplace 0.1.0 Search "ai-bom" in Extensions

Version Files (what to bump)

Package Version source(s)
ai-bom src/ai_bom/__init__.py__version__ = "X.Y.Z" (hatch reads this)
trusera-sdk (Python) trusera-agent-sdk/trusera_sdk/__init__.py + trusera-agent-sdk/pyproject.toml
trusera-sdk (JS) trusera-sdk-js/package.json
trusera-sdk-go No version file — version comes from git tag only
n8n-nodes-trusera n8n-node/package.json
VS Code extension vscode-extension/package.json

Tag Namespaces

Each package has its own tag prefix. The auto-release workflow uses these to track versions independently.

Package Tag format Example
ai-bom v* v3.3.2
trusera-sdk (Python) sdk-v* sdk-v1.0.0
trusera-sdk (JS) js-v* js-v0.2.0
trusera-sdk-go trusera-sdk-go/v* trusera-sdk-go/v0.1.0
n8n-nodes-trusera n8n-v* n8n-v0.5.0
VS Code extension vscode-v* vscode-v0.1.0

Auto-Release (.github/workflows/auto-release.yml)

Runs on every push to main. Fully automated — no manual tagging needed.

How it works

  1. detect-changes job compares each directory against its latest tag
  2. Only packages with file changes get a release job
  3. Each job analyzes conventional commits touching that directory:
    • feat:minor bump (0.1.0 → 0.2.0)
    • fix:patch bump (0.1.0 → 0.1.1)
    • BREAKING CHANGE or feat!:major bump (0.1.0 → 1.0.0)
  4. Skipped scopes (don't trigger releases): feat(ci), feat(deps), feat(build), feat(chore) and same for fix(...)
  5. Commits with chore(release): prefix are ignored (prevents re-trigger loop)
  6. Version files are updated, committed as chore(release): <pkg> vX.Y.Z [skip ci], tagged, pushed
  7. Package is built and published to the appropriate registry

Publishing methods

Package Method Auth
ai-bom PyPI trusted publishing (OIDC) No token needed (environment: pypi)
trusera-sdk (Python) PyPI API token PYPI_API_TOKEN secret
trusera-sdk (JS) npm publish NPM secret
trusera-sdk-go Git tag only GIT_TOKEN secret (for push)
n8n-nodes-trusera npm publish NPM secret

To add trusted publishing for more packages

Go to https://pypi.org/manage/project/<name>/settings/publishing/ and add:

  • Owner: Trusera, Repository: ai-bom, Workflow: auto-release.yml, Environment: pypi

Then remove the password: ${{ secrets.PYPI_API_TOKEN }} line for that package.


GitHub Actions Workflows

Workflow File Trigger Purpose
CI ci.yml push/PR to main Lint, typecheck, test (Python 3.10-3.13), security audit, SARIF upload
Auto Release auto-release.yml push to main Auto-version + publish all 5 packages
Publish to PyPI publish.yml v* tags (manual) Standalone ai-bom PyPI publish (backup)
Publish Agent SDK publish-sdk.yml sdk-v* tags (manual) Standalone agent SDK publish (backup)
Publish npm publish-npm.yml n8n-v* tags (manual) Standalone n8n node publish (backup)
Publish VS Code publish-vscode.yml vscode-v* tags VS Code marketplace publish
Docker docker.yml v* tags Build + push Docker image
Docs docs.yml push to main Deploy MkDocs to GitHub Pages
Dogfood dogfood.yml push to main ai-bom scans itself
AI-BOM Example ai-bom-example.yml push to main Example scan via GitHub Action

GitHub Secrets

Secret Purpose Used by
GIT_TOKEN PAT with repo + workflow scope — bypasses branch protection for auto-release commits auto-release.yml
PYPI_API_TOKEN PyPI API token (user: trusera) — publishes trusera-sdk auto-release.yml, publish-sdk.yml
NPM npm access token — publishes trusera-sdk and n8n-nodes-trusera auto-release.yml, publish-npm.yml
VSCE_PAT VS Code marketplace PAT publish-vscode.yml

ai-bom Core Scanner

Scanners (14)

Scanner File What it detects
Code code_scanner.py AI SDK imports, model references, API keys in source
Docker docker_scanner.py AI frameworks in Dockerfiles
Network network_scanner.py AI API endpoints in configs
Cloud (Terraform) cloud_scanner.py AI services in IaC
n8n n8n_scanner.py AI nodes, webhook auth, agent chains
Jupyter jupyter_scanner.py AI usage in notebooks
GitHub Actions github_actions_scanner.py AI integrations in workflows
MCP Config mcp_config_scanner.py MCP server configs (claude, cline, cursor)
Model Files model_file_scanner.py Binary models (.onnx, .pt, .safetensors, etc.)
AST (deep) ast_scanner.py Python AST analysis (imports, decorators, calls)
AWS Live aws_live_scanner.py Bedrock, SageMaker, Comprehend, Kendra
GCP Live gcp_live_scanner.py Vertex AI, Dialogflow
Azure Live azure_live_scanner.py Azure OpenAI, Cognitive Services, ML
Callable callable/ Provider-agnostic model probing for red-teaming

Reporters (9)

table, json (CycloneDX), sarif, spdx3, html, csv, junit, markdown, diff

Compliance Modules

Module File Standard
OWASP LLM Top 10 compliance/__init__.py LLM01-LLM10 mapping
OWASP Agentic Top 10 compliance/owasp_agentic.py Agent-specific risks
EU AI Act compliance/eu_ai_act.py Risk classification
License Compliance compliance/licenses.py License checking

CLI Flags

ai-bom scan <path>              # Basic scan
ai-bom scan <path> --deep       # Enable AST scanner
ai-bom scan <path> -f sarif     # Output format
ai-bom scan <path> --fail-on high  # CI policy gate
ai-bom scan <path> --policy .ai-bom-policy.yml
ai-bom scan <path> --compliance owasp_llm_top10
ai-bom scan <path> --telemetry  # Opt-in usage analytics
ai-bom scan <path> -q           # Quiet mode for CI
ai-bom scan-cloud aws           # Live cloud scanning
ai-bom dashboard                # Launch web dashboard

Optional Dependencies

pip install ai-bom[dashboard]      # FastAPI dashboard
pip install ai-bom[watch]          # File watcher
pip install ai-bom[aws,gcp,azure]  # Cloud live scanners
pip install ai-bom[callable-all]   # All red-teaming providers
pip install ai-bom[all]            # Everything

Agent SDKs

All three SDKs share the same architecture: client, events, decorators/interceptor, Cedar policy, standalone mode.

Python SDK (trusera-agent-sdk/)

from trusera_sdk import TruseraClient, monitor, Event, EventType

# Client with context manager
with TruseraClient(api_key="tsk_...") as client:
    client.register_agent("my-agent", "langchain")
    client.track(Event(type=EventType.TOOL_CALL, name="search", payload={...}))

# Decorator
@monitor(event_type=EventType.LLM_INVOKE)
def call_llm(prompt): ...

# Standalone (no API key needed)
from trusera_sdk import StandaloneInterceptor
with StandaloneInterceptor(policy_file="policy.cedar", enforcement="block"):
    # HTTP requests are intercepted and policy-evaluated
    ...

Modules: client.py, events.py, decorators.py, cedar.py, standalone.py Integrations: LangChain (TruseraCallbackHandler), CrewAI (TruseraCrewCallback), AutoGen (TruseraAutoGenHook) Build: hatchling (pyproject.toml, version in both __init__.py and pyproject.toml)

TypeScript SDK (trusera-sdk-js/)

import { TruseraClient, EventType } from 'trusera-sdk';

const client = new TruseraClient({ apiKey: 'tsk_...' });
client.track({ type: EventType.TOOL_CALL, name: 'search', payload: {} });

Modules: client.ts, events.ts, cedar.ts, interceptor.ts, standalone.ts Interception: fetch (always), axios (optional), undici (optional) -- auto-detected at install-time Integrations: LangChain.js (TruseraLangChainHandler with optional Cedar enforcement) Build: tsup -- dual ESM (dist/index.js) + CJS (dist/index.cjs) with .d.ts declarations Test: vitest

Go SDK (trusera-sdk-go/)

import trusera "github.com/Trusera/ai-bom/trusera-sdk-go"

client := trusera.NewClient("tsk_...")
client.RegisterAgent("my-agent", "custom")
client.Track(trusera.Event{Type: trusera.ToolCall, Name: "search"})

Modules: trusera.go, events.go, cedar.go, interceptor.go, standalone.go Build: standard Go modules (go.mod points to github.com/Trusera/ai-bom/trusera-sdk-go) Test: go test ./... (CI gate in auto-release.yml runs tests before tagging) Version: git tag only (trusera-sdk-go/vX.Y.Z), no version file Env vars: TRUSERA_API_KEY (fallback for empty apiKey), TRUSERA_API_URL (fallback for base URL)


n8n Node (n8n-node/)

npm package: n8n-nodes-trusera

Nodes (5)

Node Purpose
TruseraScan Run ai-bom scan on workflow JSON
TruseraDashboard Interactive HTML dashboard with remediation cards
TruseraWebhook Webhook trigger with direct HTML serving
TruseraPolicy Policy enforcement gate
TruseraReport Generate scan reports

Build: tsc + copies SVG/PNG icons to dist Test: jest


VS Code Extension (vscode-extension/)

  • Marketplace name: ai-bom-scanner
  • VSIX: ai-bom-scanner-0.1.0.vsix (47KB)
  • Publish: vsce publish (needs VSCE_PAT)
  • Trigger: vscode-v* tags via publish-vscode.yml

CI/CD Pipeline (what runs on every push)

push to main
  ├── CI (lint + typecheck + test on 3.10-3.13 + pip-audit + SARIF)
  ├── Dogfood (ai-bom scans itself)
  ├── AI-BOM Scan (example action)
  ├── CodeQL (security analysis)
  └── Auto Release
       ├── detect-changes (which dirs changed?)
       ├── release-ai-bom (if src/ changed)
       ├── release-agent-sdk (if trusera-agent-sdk/ changed)
       ├── release-sdk-js (if trusera-sdk-js/ changed)
       ├── release-sdk-go (if trusera-sdk-go/ changed)
       └── release-n8n-node (if n8n-node/ changed)

GitHub Action (action.yml)

The repo itself is a GitHub Action. Users add it to their workflows:

- uses: trusera/ai-bom@v1
  with:
    path: .
    format: sarif
    fail-on: high

The action's dist/ directory contains the bundled scanner.


CI Templates

Template Location Purpose
GitHub Action action.yml + dist/ trusera/ai-bom@v1
GitLab CI templates/gitlab-ci-ai-bom.yml Include template for .gitlab-ci.yml

Development

Prerequisites

  • Python >= 3.10
  • Node.js >= 18 (for JS SDK and n8n-node)
  • Go >= 1.21 (for Go SDK)

Local setup (ai-bom core)

pip install -e ".[dev]"
ruff check src/ tests/         # lint
ruff format src/ tests/        # format
mypy src/ai_bom/               # typecheck
pytest -v --cov=ai_bom         # test (must pass 80% coverage)

Local setup (agent SDK)

cd trusera-agent-sdk
pip install -e ".[dev]"
ruff check .
pytest -v

Local setup (JS SDK)

cd trusera-sdk-js
npm ci
npm run build
npm test

Local setup (Go SDK)

cd trusera-sdk-go
go test ./...

Local setup (n8n node)

cd n8n-node
npm ci
npm run build
npm test

Conventional Commits

The auto-release system depends on conventional commit messages. Always use:

feat: add new scanner for X          → minor bump
feat(sdk): add retry logic           → minor bump (if touching sdk dir)
fix: handle null response            → patch bump
fix(n8n): correct webhook URL        → patch bump (if touching n8n-node dir)
feat!: redesign API                  → major bump
chore: update deps                   → NO release
docs: update README                  → NO release
style: fix formatting                → NO release
feat(ci): add new workflow           → NO release (ci scope excluded)
feat(deps): bump dependency          → NO release (deps scope excluded)

Manual Release (if auto-release is broken)

ai-bom

# 1. Bump version
sed -i 's/__version__ = ".*"/__version__ = "X.Y.Z"/' src/ai_bom/__init__.py
git add src/ai_bom/__init__.py
git commit -m "chore(release): ai-bom vX.Y.Z"
git tag vX.Y.Z
git push origin main --tags
# publish.yml triggers automatically on v* tag

trusera-sdk (Python)

# 1. Bump both files
sed -i 's/__version__ = ".*"/__version__ = "X.Y.Z"/' trusera-agent-sdk/trusera_sdk/__init__.py
sed -i 's/^version = ".*"/version = "X.Y.Z"/' trusera-agent-sdk/pyproject.toml
git add trusera-agent-sdk/
git commit -m "chore(release): trusera-sdk vX.Y.Z"
git tag sdk-vX.Y.Z
git push origin main --tags
# publish-sdk.yml triggers on sdk-v* tag

trusera-sdk (JS)

cd trusera-sdk-js && npm version X.Y.Z --no-git-tag-version && cd ..
git add trusera-sdk-js/package.json
git commit -m "chore(release): trusera-sdk-js vX.Y.Z"
git tag js-vX.Y.Z
git push origin main --tags
# Then manually: cd trusera-sdk-js && npm publish --access public

trusera-sdk-go

git tag trusera-sdk-go/vX.Y.Z
git push origin trusera-sdk-go/vX.Y.Z
# Go proxy picks it up automatically

n8n-nodes-trusera

cd n8n-node && npm version X.Y.Z --no-git-tag-version && cd ..
git add n8n-node/package.json
git commit -m "chore(release): n8n-nodes-trusera vX.Y.Z"
git tag n8n-vX.Y.Z
git push origin main --tags
# publish-npm.yml triggers on n8n-v* tag

VS Code extension

git tag vscode-vX.Y.Z
git push origin vscode-vX.Y.Z
# publish-vscode.yml triggers

Troubleshooting

Auto-release bumps but doesn't publish

The trusted publisher on PyPI must list auto-release.yml as the workflow name. Go to PyPI project settings → Publishing → add it.

Branch protection blocks auto-release push

The GIT_TOKEN secret must be a PAT with repo scope that has admin/bypass permissions on the repo.

npm publish fails with 403

Check NPM secret is a valid token with publish access to both trusera-sdk and n8n-nodes-trusera.

PyPI says "Version already exists"

A tag was created but the publish failed. Delete the orphaned tag, fix the issue, and re-tag.

Go module not found after tagging

The Go module proxy can take up to 30 minutes to index. Force it: GOPROXY=direct go get github.com/Trusera/ai-bom/trusera-sdk-go@vX.Y.Z

pip-audit fails in CI with "Dependency not found"

Race condition: the CI security job runs pip-audit before the new version appears on PyPI. This is expected for version bump commits and resolves on the next push.