PyRIT migration from the archived Azure/PyRIT repository

Teams that fork, pin or script PyRIT against the archived Azure/PyRIT repository need a planned move to microsoft/PyRIT 1.x, with custom attacks retested before results are trusted again.

On this page

What a PyRIT migration involves

The migration starts from one fact: the original Azure/PyRIT repository was archived on 27 March 2026 and is now read-only, so it will receive no further changes. Development continues at microsoft/PyRIT, and the current release line includes v1.1.0, released on 4 September 2026. Any code that still points at the old repository, installs from it, or expects it to receive fixes needs to be moved to the new project and its published releases.

The work usually surfaces in four places. Forks that still track the old repository need a new upstream and a deliberate merge. CI pipelines and requirements files that pin old versions must be updated and their builds rerun. Internal wrappers that import old module paths will fail or behave differently once they are pointed at the 1.x line. Finally, custom targets, converters, scorers and attacks must be retested against the new release, because a passing import does not show that a multi-turn attack or a scorer still produces the same results.

For a small codebase with a few custom targets and scorers, a team with Python and test engineering skills can often do the move itself. The checklist is an inventory of references, a version pin, a full run of existing scenarios, and a comparison of results against earlier runs. Larger estates, with many custom attacks, shared red teaming workflows and stored results that others depend on, usually benefit from a partner who scopes the inventory and retests those components in writing before the old pins are removed.

Confirm before you start: list every repository, pipeline, requirements file and internal package that references PyRIT, and record the Python version each environment runs. PyRIT supports Python 3.10 up to but not including 3.15, and the documentation recommends Python 3.13. Agree in advance who signs off on retested results before the old code is retired.

What the migration includes

Each card is a separate work package. The exact deliverables are fixed in writing from the agreed scope before work starts.

Inventory and import mapping

List every fork, pinned version, script and internal tool that imports from the archived Azure/PyRIT repository. For each item, map old import paths and configuration keys to the microsoft/PyRIT 1.x layout, and record what changes and what is removed. Check scheduled scans and CI jobs too, since they often hide the most callers.

Python environment and settings

Build the target environment on a Python version the PyPI package supports, which is 3.10 up to but not including 3.15. The PyRIT documentation recommends 3.13. Move credentials in ~/.pyrit/.env and settings in ~/.pyrit/.pyrit_conf, and confirm which values each host reads so secrets stay in your approved secret store.

Custom targets, converters, scorers and attacks

Port your custom HTTP or WebSocket targets, converters, scorers and multi-turn attacks to the 1.x interfaces. Check how each component calls models, handles retries and returns results, since these behaviors can change between releases. Keep each port in version control so reviewers can compare old and new logic side by side.

Retesting custom attacks

Run every migrated attack against a fixed set of known test cases with expected outcomes, and compare the results with the pre-migration baseline. Record differences in scorer verdicts, response handling and error paths. Treat unexplained changes as failures until the team agrees on the cause, and rerun the set after any dependency change.

Memory continuity

Decide whether existing results move with the team. Confirm whether data in your current SQLite memory can be read by the 1.x memory layer or needs conversion, and whether Azure SQL is the right store for shared use. Test reads of historical conversations and scores before cutover, and confirm that access controls match your data handling policy.

Handover package

Deliver a changelog of every change from the archived repository, a test record showing which cases passed and why any failed, and a rollback note naming the prior pinned versions and the steps to restore them. Ask for the package to be reviewed by the team that will own PyRIT after handover.

What drives migration effort

This table lists the factors that change how much work a move from the archived Azure/PyRIT repository to microsoft/PyRIT and the 1.x line takes, why each one matters, and how to keep it manageable.

DriverWhy it changes effortHow to keep it down
Forks and internal repositoriesEach fork carries its own pinned dependencies, patches and CI configuration, so every copy has to be reconciled with microsoft/PyRIT separately.Freeze the inventory early, list every fork and internal repository with its owner, and decide per repository whether it is merged, rebased or retired.
Custom targetsTargets for OpenAI, Azure, Anthropic, Google, Hugging Face, custom HTTP or WebSocket endpoints and Playwright-driven web apps each have their own configuration and authentication, and custom ones need code review against the new target interface.Inventory each target, record which provider class or custom code it uses, and move only the custom endpoints into bespoke code while using built-in targets where they fit.
Custom converters, scorers and attacksEach custom component depends on internal PyRIT APIs that may have changed between the archived repository and the 1.x line, so each one needs a compatibility check and a test.Keep custom code thin, wrap business logic outside PyRIT classes, and remove custom components that duplicate built-in converters or scorers.
Multi-turn strategies such as Crescendo, TAP and Skeleton KeyMulti-turn attacks depend on conversation state, scoring thresholds and attacker model settings, so a change in orchestration or memory behavior can alter results without raising an error.Document the exact strategy settings in use, and rerun each strategy against the same reference target before and after the move.
Memory backend: SQLite or Azure SQLTeams using Azure SQL carry connection, firewall and schema concerns that SQLite installs do not, and any schema change between versions must be planned for both backends.Confirm which backend each environment uses, test the migration path on a copy of the stored data, and keep backend settings in one documented configuration file.
Test environments and Python versionsEach environment, such as a laptop, CI runner or shared test host, may run a different Python version, and the PyPI package supports Python 3.10 up to but not including 3.15, while the documentation recommends 3.13.Pin one Python version per environment, align them on the version the documentation recommends where possible, and rebuild each environment from the same lock file.
Test coverage of existing behaviorWhere old behavior is covered only by manual runs or memory of past results, it is hard to tell whether a change in output is a regression or an expected improvement.Write characterization tests for the attacks, scorers and targets that matter most before the move, and record which behaviors have no test.
Comparability of earlier resultsIf findings from earlier runs must be compared with new runs, scorer versions, prompt datasets and model versions all have to match, or differences will reflect the tooling rather than the target.Write a fixed set of reference prompts before the move, store the scorer and model versions used for each baseline run, and rerun the set on both versions.

Migration phases and outputs

The sequence moves PyRIT workloads from the archived Azure/PyRIT repository to microsoft/PyRIT on the 1.x line, with a recorded output at each phase.

  1. Inventory forks, pins and custom components

    Your team and DeployOpen list every fork of Azure/PyRIT, each pinned version, every import of PyRIT modules, and each custom target, converter, scorer or attack. Each item gets an owner and a migration status. The inventory is complete when no custom code or pin remains unlisted, and the written scope is set from it.

  2. Run gap analysis against 1.1.0

    Compare each inventory item with the PyRIT 1.1.0 documentation and release notes, published on 4 September 2026. The output is a list of changed interfaces, with the file and function affected and the fix required. The list is reviewed by the code owners before any code changes begin.

  3. Build a reproducible Python environment

    Define the Python version and the full dependency set in a lock file or container image. The PyPI package supports Python 3.10 up to but not including 3.15, and the documentation recommends 3.13, so confirm the version your organization will standardize on. The output is an environment definition that rebuilds identically on every test and production host.

  4. Migrate code and configuration to microsoft/PyRIT

    Create a branch or fork from microsoft/PyRIT and apply the interface fixes from the gap list. Update dependency pins, credential loading from ~/.pyrit/.env, settings from ~/.pyrit/.pyrit_conf and memory configuration. The output is a branch with updated pins and a change log that links each fix to an inventory item.

  5. Retest custom attacks and scorers

    Run every custom attack, converter and scorer on the archived and migrated code, using the same targets and datasets. Record prompts, responses, scores and errors side by side. The output is a test record that shows where behavior matches and where it differs, with each difference accepted or fixed by its owner before cutover.

  6. Agree cutover and rollback plan

    Set the order of switch-over, the acceptance criteria drawn from the test record, and the change freeze window in the written scope. Write the rollback procedure, including how to restore the archived environment and the memory database. The output is a runbook that names who approves cutover and who reverts it.

  7. Hand over with documentation

    Transfer the environment definition, branch, test record, runbook and list of known behavior differences to your team. Walk through routine operation, including scheduled scans, credential handling and memory storage. The output is a handover package that lets your staff run and update PyRIT without the migration team.

What teams keep in-house and what they outsource

This table shows each part of a PyRIT migration from the archived Azure/PyRIT repository, who usually owns it, and the skills each part requires, so you can match work to your own team or a partner.

Work areaUsually owned bySkills required
Inventory of forks, consumers and custom codeIn-houseKnowledge of your own forks, internal consumers and which team relies on each custom target, converter or scorer
Dependency and environment workEitherPython packaging, pinning and virtual environment management, and CI configuration for Python 3.10 to 3.14 builds
Code migration of custom targets, converters and scorersOften outsourced for large estatesPython and API integration skills, plus familiarity with PyRIT's target, converter and scorer interfaces
Retesting of custom attacksEither, with in-house sign-offRed teaming domain knowledge and a test harness that replays attacks against the migrated code
Memory and result continuityEitherDatabase and data handling skills for SQLite or Azure SQL memory, including schema checks and preservation of historical results
Documentation and handoverIn-house owner requiredTechnical writing for your environment, plus a named maintainer who will track future PyRIT releases

What goes wrong and how to prevent it

Most PyRIT migration problems come from old references that keep working without errors. Check each failure point before cutover and keep the checks in your release process.

Old imports and pins

Internal tools and requirements files can still import from or pin the archived Azure/PyRIT code path. They keep running without errors while missing development that continues only at microsoft/PyRIT. Search repositories, CI files and lockfiles for old references, then rebuild a pinned environment file that installs the 1.x line and run each internal tool against it.

Forks drifting from upstream

A fork of Azure/PyRIT that received local patches during the project can drift further from microsoft/PyRIT over time. Record each local patch, decide whether it moves upstream or is dropped, and freeze the fork at an agreed commit for cutover. Ask who owns rebasing after handover.

Custom scorers changing verdicts

A custom scorer that passed on the archived code can return different verdicts on the 1.x line, which breaks trend comparisons with earlier runs. Before cutover, run a reference prompt set through both versions, record every verdict difference, and fix or document each one. Apply a freeze window so no scorer changes land mid-comparison.

Credentials left in old locations

Older setups may keep API keys in shell profiles, scripts or configuration files outside PyRIT's own settings. PyRIT reads credentials from ~/.pyrit/.env and settings from ~/.pyrit/.pyrit_conf, so move each secret there, rotate any key that was copied elsewhere, and search old hosts and build agents for leftover copies before retiring them.

Unsupported Python in build agents

The PyPI package supports Python 3.10 up to but not including 3.15, and the PyRIT documentation recommends Python 3.13. Build agents pinned to an older interpreter, or to a version outside that range, fail at install or at runtime. Check each agent's interpreter, set the version in the pinned environment file, and test the install on every agent image before cutover.

Untested memory restore

PyRIT memory stores conversations and results in SQLite or Azure SQL. Teams often confirm that writes work but never restore a backup into a clean environment. Run a dry run that restores the memory backend, opens past results in PyRIT, and confirms that scores, targets and attack records still match before the archived store is retired.

How the work differs by starting point

A fork carries your own changes on top of the archived code, so the work is reconciling each patch with the 1.x line. Effort depends mostly on how many patches exist and how far they touch core modules.

  • Patch inventory: list every local change, its purpose and whether upstream already covers it.
  • Patch-by-patch review: re-apply each change to a 1.x base and record what no longer applies.
  • Verification: rerun your custom attacks, converters and scorers against the new base and compare results.
  • Ongoing divergence: decide whether to keep the fork, move patches into your own package or drop them.

What you need to provide

The migration can only be scoped and cut over safely if you give us a complete inventory of what depends on the archived Azure/PyRIT repository. Start with read access to every fork, internal repository and CI definition that references PyRIT, including pinned requirements files, pipeline steps that clone or install from Azure/PyRIT, and internal wrapper packages. Source control administrators or the platform engineering team usually own this access. Without it, pinned dependencies that were missed will surface after cutover, not before.

Next, provide a list of every custom target, converter, scorer and attack your team has written, with a named owner for each. Custom code is where migration effort concentrates, because the 1.x line is where any API changes will need to be reconciled. For each custom attack, supply sample inputs and the outcomes you expected, such as the scorer result or the category of response the attack should produce. This baseline is what lets us tell whether a changed result after migration reflects a regression or a deliberate change in behavior. The red teaming lead usually owns the expected outcomes, and the engineers who wrote each attack own the sample inputs.

Confirm the build environments and Python versions in use. The PyPI package supports Python 3.10 up to but not including 3.15, and the PyRIT documentation recommends Python 3.13, so you should state which interpreter each pipeline and workstation runs and whether any host is locked to an older version. You also need to decide the memory backend, SQLite or Azure SQL, and where results are stored. This decision affects data residency, access control and how the migrated conversation history is moved. The platform owner and the security team should agree on it together, since it determines who can read stored prompts and outputs.

Finally, name a technical owner who can make decisions about dependencies and environments during the migration, and a red teaming lead who can judge whether changed results are acceptable. Those two roles should not be the same person in practice, because the first is accountable for working software and the second for the quality of the testing. Agree a change window for cutover with operations and the teams that run tested systems, and ask them to confirm how rollback is handled. Confirm all of these owners and dates in writing before scoping begins.

Frequently asked questions

Can our team migrate without a partner, and what should we check first?

Yes, for small, well-tested codebases, an in-house team can usually handle the move if it inventories everything first. Check first: every fork and internal tool that imports PyRIT, the pinned version in each, and whether your tests cover custom targets, converters and scorers. Confirm the Python interpreter too. The PyPI package supports Python 3.10 up to but not including 3.15, and the documentation recommends 3.13. Larger setups with many custom attacks, shared memory or several environments often benefit from a second set of hands.

What drives the cost and effort of a PyRIT migration?

The main driver is the amount of custom code, not the size of the install. Custom HTTP or WebSocket targets, Playwright-driven web app targets, custom converters and scorers, multi-turn attack logic and the number of forks and environments all add work. Memory setup in SQLite or Azure SQL and dependency pinning also count. Recurring costs include model API calls used to retest attacks, which are separate from labor. In a quote, ask for effort by component, what is one-time versus recurring, and which assumptions the estimate relies on.

How long does a PyRIT migration take?

No duration is fixed in advance. The timeline is set in the written scope after an inventory of your forks, pinned dependencies, custom attacks and tooling, because the amount of code to move and retest drives the schedule. Engagements are fixed-scope, so the agreed scope sets the timeline and deliverables. Ask for the plan to show the inventory, the migration of each component, retesting against your own cases, client review points and handover, so you can see where time goes.

What do we need to prepare before a PyRIT migration starts?

Gather a readiness list before work begins: every fork, branch and internal tool that imports PyRIT, the pinned version in each, and copies of your custom targets, converters, scorers and attack code. Add the test cases you use to judge results, the settings and environment files in ~/.pyrit/ (with credentials kept out of shared documents), access to a test environment with model endpoints you are permitted to test, and one named owner for decisions. Confirm the approval and access process with your security team.

Does the archived Azure/PyRIT repository still receive fixes?

No. The Azure/PyRIT repository was archived on 27 March 2026 and is read-only, so it receives no new fixes. Development continues at microsoft/PyRIT, and PyRIT v1.1.0 was released on 4 September 2026. Point forks, pinned dependencies, package sources, CI configuration and internal documentation to microsoft/PyRIT. Vulnerabilities are reported privately through the Microsoft Security Response Center under the project's security policy.

How do we confirm breaking changes after moving to 1.1.0?

Compare your code with the 1.1.0 documentation and the release notes on the microsoft/PyRIT releases page, then test against your own cases. List every PyRIT API your code calls, including targets, converters, scorers, attacks and memory, and confirm that each signature and behavior still matches. Rerun your attack cases and compare the results with your previous baseline. Keep the test cases and expected outcomes in version control so the same check repeats on every upgrade.

How DeployOpen delivers this migration

DeployOpen moves your forks, pinned dependencies and internal PyRIT tooling from the archived Azure/PyRIT repository to microsoft/PyRIT and the 1.x release line, then retests your custom attacks against the new version. The work runs under a written scope inside infrastructure you control.

How we scope

  • The written scope lists every fork, pinned dependency and internal script that references the archived Azure/PyRIT repository.
  • Custom targets, converters, scorers and attack strategies are inventoried so each one has a named owner and a retest plan.
  • Engagements are fixed-scope, with deliverables and timelines agreed in writing before migration work begins.
  • Ask the scope to state which Python versions and PyRIT release you will move to, and who confirms them.

How we build

  • Forks and pinned dependencies are repointed to microsoft/PyRIT, and import paths and configuration changes are recorded in version control.
  • Custom attacks, targets and scorers are rerun against the 1.x line and compared with results from the original setup.
  • Credential and settings files, including the ~/.pyrit/.env and ~/.pyrit/.pyrit_conf locations, are moved without exposing secrets in repositories.
  • Test runs are performed in your environment against targets you have authorized, with memory storage configured for your chosen backend.

How we hand over

  • Handover includes a migration record listing each change, the reason for it and the test evidence that supports it.
  • Your team receives updated internal tooling documentation covering how to install, pin and run PyRIT in your environment.
  • Retested custom attacks come with a short runbook that states which results changed after migration and why.
  • Confirm with DeployOpen which artifacts are delivered to your repositories and which remain with your team.

How we support

  • Ongoing support for PyRIT upgrades and custom component validation is available as a retainer after handover.
  • Retainers can cover checking new PyRIT releases, such as the v1.1.0 release, against your custom targets, converters and scorers.
  • Support requests are handled inside your infrastructure and within the agreed retainer terms.
  • Ask for the support scope, response expectations and upgrade cadence in writing before the retainer starts.

Sources and further reading

Talk to our team.

Tell us what you're working on, whether it's a deployment, an audit, a security test or a cyber range. You'll speak with an engineer who can help you scope it.

  • 30-minute call: free, with no obligation.
  • NDA on request: we can sign before you share details.
  • Clear next steps: a scope and plan after the call.