Skip to main content

Agentic Security Fleet Ops — an LLM-agent security department with a Security Orchestrator, built on pydantic-ai with a GitHub Copilot SDK provider.

Project description

asfops — Agentic Security Fleet Ops

CI PyPI Python License: MIT

An entire security department as a fleet of LLM agents. Give asfops any security-relevant input — a code change, a design doc, an incident description, a compliance question — and the Security Orchestrator decides which security specialists should weigh in, runs them in parallel, and composes their findings into a single comprehensive markdown report.

Built on pydantic-ai, with the GitHub Copilot SDK exposed as a first-class pydantic-ai provider (CopilotModel) — so the fleet runs on your GitHub Copilot subscription by default, or on any pydantic-ai model (OpenAI, Anthropic, …) you choose.

Install

pip install asfops
# or
uv add asfops

Quickstart

import asfops

result = asfops.assess_sync(
    "Review this design: a public REST API that accepts file uploads "
    "to S3 using presigned URLs, authenticated with long-lived API keys."
)

print(result.report_md)          # the composed security report
print(result.triage.selected)    # which specialists were engaged, and why
print(result.metadata)           # per-agent model + token usage, per-model totals

Async, with configuration:

from asfops import Fleet, FleetConfig

fleet = Fleet(FleetConfig(
    default_model="copilot:claude-sonnet-4.5",   # any pydantic-ai model ref works too
    model_overrides={"threat-model": "anthropic:claude-sonnet-4-5"},
    fallback_models=("anthropic:claude-sonnet-4-5",),  # retry here if the primary errors
    force_roles=("grc",),
    max_concurrency=5,
    temperature=0.1,             # steadier, more deterministic analysis
    max_tokens=4000,             # cap output length per agent
    per_agent_token_limit=200_000,  # hard budget guard; over-budget agents fail gracefully
))
result = await fleet.assess("...")

CLI

asfops assess "We're adding a webhook receiver that executes user-supplied templates"
asfops roster                       # meet the department
asfops run threat-model "..."       # engage a single specialist
asfops models                       # check Copilot availability / list models

The fleet

17 specialists covering the modern security department: Product Security, Security Architecture, Threat Modeling, AppSec, Cloud Security, IAM, Pen Testing, Red Team, Bug Bounty, Vulnerability Management, Supply Chain Security, Threat Detection, SOC, Incident Response/DFIR, GRC & Compliance, Privacy, and CISO-level leadership framing. asfops roster shows each role's charter.

Authentication

By default the fleet runs on the GitHub Copilot runtime (bundled CLI, auto-downloaded). You need a GitHub Copilot subscription and one of:

  • being logged in via gh auth login / Copilot CLI, or
  • COPILOT_GITHUB_TOKEN / GH_TOKEN / GITHUB_TOKEN set.

No Copilot? Point the fleet at any pydantic-ai provider: FleetConfig(default_model="openai:gpt-5.2") or anthropic:claude-sonnet-4-5 with the corresponding API key.

Result metadata

Every FleetResult optionally includes (include_metadata=True, default):

  • per-agent: role, resolved model id, input/output/cache token counts, duration
  • totals per model, plus a grand total across the whole assessment

Logging

Two separate logs are written per run, under one timestamped directory in ~/.asfops/logs/ (created on first use; override the base with --log-dir or the ASFOPS_HOME env var):

~/.asfops/logs/<UTC-timestamp>-<run_id>/
├── app.log                 # global application log (structlog JSON lines)
└── agents/
    ├── triage.json         # each agent's ENTIRE context…
    ├── appsec.json         # …full message history + model + usage + output
    ├── …
    └── synthesis.json
  • app.log — application-wide lifecycle events (config, triage decision, per-agent start/finish/fail with token counts, synthesis, Copilot client start/stop, run totals), correlated by a fleet-level run_id.
  • agents/<slug>.json — the complete context of one agent invocation (every specialist plus triage and synthesis): the full pydantic-ai message history (system prompt, user prompt, model response, retries) with a metadata header (model, token usage, duration, run_id, structured output).

Logging is on by default and configurable:

asfops assess "…" --log-dir ./logs --log-level DEBUG   # custom location/verbosity
asfops assess "…" --no-logs                            # disable entirely
from pathlib import Path
from asfops import Fleet, FleetConfig, LoggingConfig

fleet = Fleet(FleetConfig(logging=LoggingConfig(base_dir=Path("./logs"), level="DEBUG")))

Logging auto-disables under pytest so test runs stay clean. asfops.get_logger(__name__) exposes the same structlog logger for your own code.

Development

uv sync --group dev
uv run pytest --cov=asfops
uv run ruff format --check . && uv run ruff check .
uv run mypy src tests

Releases are fully automated: every merge to main auto-bumps the patch version, tags it, builds, and publishes to PyPI via trusted publishing. The version comes from the git tag (hatch-vcs) — never hand-edited. See RELEASING.md.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

asfops-0.2.2.tar.gz (148.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

asfops-0.2.2-py3-none-any.whl (42.5 kB view details)

Uploaded Python 3

File details

Details for the file asfops-0.2.2.tar.gz.

File metadata

  • Download URL: asfops-0.2.2.tar.gz
  • Upload date:
  • Size: 148.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for asfops-0.2.2.tar.gz
Algorithm Hash digest
SHA256 a90622c79609ea03007c789586e846b57c77bf8ea1dfb9c971c335c6eec8e6c4
MD5 57ac812681155e783147cd1e531340cb
BLAKE2b-256 6c0b4ad2f6f33383c2ce5c14ef453e8cadad9f4f253db1afdacd8341ed7c057a

See more details on using hashes here.

Provenance

The following attestation bundles were made for asfops-0.2.2.tar.gz:

Publisher: release.yml on brettbergin/agentic-security-fleet-ops

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file asfops-0.2.2-py3-none-any.whl.

File metadata

  • Download URL: asfops-0.2.2-py3-none-any.whl
  • Upload date:
  • Size: 42.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for asfops-0.2.2-py3-none-any.whl
Algorithm Hash digest
SHA256 5a38ab14d18dcc1e6f08b19956fb079bc7843f07d2789c8ac4fde1a980b3e797
MD5 1210d31a34eea3515ddac5cddedf4dd4
BLAKE2b-256 cc2894ce16060e3b2d5d2fcf1a5e51a8206c6f11af43a7644cc5563691a8e5cc

See more details on using hashes here.

Provenance

The following attestation bundles were made for asfops-0.2.2-py3-none-any.whl:

Publisher: release.yml on brettbergin/agentic-security-fleet-ops

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page