PyRIT security hardening

PyRIT security hardening protects the test host, its credentials, its stored prompts and harmful outputs, and the systems it attacks. This page sets out the decisions, build sequence, effort drivers and checks for doing it in-house or with a partner.

On this page

PyRIT security hardening starts with the test host, not the model

Hardening a PyRIT environment is mainly about four things: the host it runs on, the secrets it holds, the data it stores and the blast radius of each attack it launches. The model provider is rarely the weak point. A team that has PyRIT running on a shared VM or a engineer's workstation, with model API keys in ~/.pyrit/.env, a memory database full of adversarial prompts and harmful outputs, and attacks aimed at live endpoints, already has a security problem before the first test starts. The first decision is where this stack lives and who can reach it.

This is harder than it looks because PyRIT is a Python framework that runs on the operator's machine. It is not a hosted service with its own perimeter. Whatever user account runs it can read the credentials file, the settings file and the memory database, and can send traffic to any endpoint the process can reach. Multi-turn strategies such as Crescendo, TAP and Skeleton Key generate many model calls per objective, so a single misconfigured run can produce far more outbound traffic and stored content than a one-off script would. The tooling is also built to produce harmful content on purpose, which changes how you should think about who should be allowed to operate it and where its output may sit.

The pillar facts that shape this work are straightforward. PyRIT is MIT licensed, so you are free to change its code, which also means you own every change to its defaults. It reads credentials from ~/.pyrit/.env and settings from ~/.pyrit/.pyrit_conf. Its memory stores conversations and results in SQLite or Azure SQL. It can be run as a scanner through the pyrit_scan command, through CoPyRIT, the web GUI for human-led red teaming and team collaboration, or as a Python framework for custom attacks. Each mode changes the attack surface: a scanner run from a CI job exposes different secrets than a shared CoPyRIT deployment reachable by a red team across the network. Confirm with your own configuration which of these modes you use before writing any control.

This page covers hardening only: how to protect the host, secrets, stored data and the impact of attacks on tested systems. It does not cover how to set up targets, converters, attacks or scorers, and it does not cover the scoping of a red teaming program. Those topics are handled in the implementation and memory sections. Before you change anything, inventory the hosts, accounts, key files and database locations in use today. You cannot limit blast radius for an environment you have not mapped, and the inventory is the input to every decision that follows.

Which hardening decisions to make before configuring anything

This table compares the six decisions that shape a PyRIT test environment, with the option that fits each one and the ongoing work it creates. Read each row as a choice to settle with your security and AI risk owners before installing or configuring PyRIT, because most later controls depend on these answers. The main takeaway is that the convenient option for a single tester is rarely the one that holds up once a team shares results and credentials.

DecisionOption and when it fitsOperational cost to accept
Where credentials liveLocal ~/.pyrit/.env file fits a single operator on a dedicated, locked-down host. Runtime injection from a secrets manager fits shared runners and teams with several model API keys.The .env file needs manual rotation, file permission checks and a rule against copying it into notebooks or tickets. Secrets manager injection needs access policies, an approved way to pass secrets to the runner and an owner for each key.
Where the test host runsOperator workstation fits short solo exercises with no shared results. A shared isolated VM fits small teams that need one controlled place to run tests. A dedicated runner fits recurring scans and scheduled jobs.A workstation carries the full risk of stored keys and harmful outputs on a laptop. A shared VM needs an access review, patching and a clear owner. A dedicated runner needs its own build, hardening, logging and retirement process.
Memory backendSQLite on the host fits a single operator or a short engagement where results stay on one machine. Azure SQL fits teams that share results and need database-level access controls.SQLite files must be backed up, encrypted at rest and removed at the end of an engagement. Azure SQL adds database administration, firewall and identity configuration, and backup and retention duties owned by the team.
CoPyRIT exposureLocal access only fits solo use. Team access over a private network fits red teams working on shared findings. Internet-facing access should not be considered for a tool that handles harmful prompts and outputs.Team access needs user accounts, network rules, session timeouts and a review of who can see stored outputs. Each additional network path needs its own logging and approval, and the GUI needs updating after each PyRIT release.
Permitted test targetsStaging or a pre-production copy fits most red teaming, since attacks can change state or generate harmful content. Production testing fits only when the owner has approved specific tests, rate limits and a stop condition.Staging needs data that resembles production and must be kept in sync with the system under test. Production testing needs change approval, monitoring of the tested system and a documented way to halt attacks.
Scorers calling external servicesLocal or custom scorers fit networks that cannot send content outside the boundary. LLM scorers and Azure AI Content Safety fit teams whose data handling terms and egress approvals allow it.External scorers need egress rules, approval of the provider and the model, key management for each service and model API spend. Stored prompts and outputs may leave the network, so confirm retention and data use terms with each provider.

How to secure the PyRIT .env file and model API keys

The main credential risk in a PyRIT setup is that PyRIT reads its model credentials from ~/.pyrit/.env and its settings from ~/.pyrit/.pyrit_conf. Anyone who can read those files can call the model accounts that PyRIT is configured to use, and so can anyone who obtains them indirectly. That includes other local users, processes running under the same account, shell history where keys were typed or echoed, backups of the home directory, and any clone of a repository where the file was accidentally committed. Treat the whole ~/.pyrit directory as secret material, not just the .env file, because the configuration file names the targets and endpoints an attacker would want to reuse. Start on the host. Confirm which operating system account runs PyRIT, make that account the only owner of ~/.pyrit, and set permissions so that group and other users have no read access to either file. Check that shared test hosts, CI runners and jump boxes do not run PyRIT under a shared service account that many people can log into. Add the directory to the exclusions of any backup job that copies home directories to shared storage, or encrypt those backups under a policy your security team has approved. Keep shell history from capturing keys by setting credentials through the .env file rather than inline environment exports, and review history files on hosts where that has already happened. Keep the files out of version control and container images. Add ~/.pyrit and any project-level .env copies to global and project ignore rules, and run a secret scanner over existing repositories before anyone clones them into a test environment. When you build a container image for PyRIT, do not copy the credential files into a layer. Pass keys at run time and confirm that the image does not contain them by inspecting its filesystem. If a key has ever reached a repository, a log or an image that others can pull, treat it as exposed and rotate it, because deleting the file from history does not revoke the copies already made. Use separate keys per target and per engagement. A single key shared across every OpenAI, Azure, Anthropic, Google or Hugging Face target means one leak forces a rotation that stops every engagement at once. Where the provider lets you create several keys, give each target and each red team engagement its own key, label them with the engagement reference, and record the owner. Then limit each key's scope and spending cap where the provider offers those controls. Confirm with each provider which permissions, usage limits and budget alerts are available for the account type you hold, because these features differ by vendor and plan. Rotate keys when staff who had access change roles or leave, and immediately after suspected exposure. Record each rotation and its reason so that auditors and the engagement owner can see when access ended. Moving keys into a secrets manager and injecting them at run time removes long-lived plaintext files from hosts, centralizes rotation and produces access logs. The trade-off is operational: the test host then depends on the secrets service being reachable, PyRIT runs need a safe way to fetch credentials, and a compromised runner may still read secrets it is granted. Before making this change, confirm with the platform owner which secrets manager is approved, how identities are issued to PyRIT hosts and CI jobs, who can read each secret, how long an outage would block testing, and whether the platform's audit logs will be retained for your evidence requirements. Also confirm how PyRIT will receive values at startup in your environment, and test that path on a non-production target before relying on it.

PyRIT security hardening steps, in order

This sequence takes a PyRIT test runner from a default install to a state where credentials, network paths, stored results and run activity are controlled before any live target is attacked. Each step closes with a check the operator can repeat. The final step confirms that every earlier check passed.

  1. Inventory hosts, users, targets and keys

    The red team lists every host running PyRIT, every operator account, every target endpoint, every model and scorer key, and every place conversations and results are stored, including SQLite files and Azure SQL connection strings. Record the PyRIT release and Python version in the same inventory. Confirm both against the PyPI package page and the PyRIT 1.1.0 documentation, since the package supports Python 3.10 up to but not including 3.15 and the documentation recommends Python 3.13. The step is done when the engagement lead signs off the inventory and every item has a named owner.

  2. Place the runner in a segmented zone

    Run PyRIT from a dedicated test network zone that holds no production data and has no standing route into internal systems beyond what the engagement needs. Name one owner for the zone, who approves changes to its rules and its access list. The check is a documented zone record with the owner's name, the permitted inbound and outbound paths, and a connection test from a host outside the zone confirming that the runner cannot be reached directly.

  3. Lock down config files and exposed keys

    Set permissions on ~/.pyrit/.env and ~/.pyrit/.pyrit_conf so only the operator account can read them, and confirm that group and other read access is cleared. Search shell history, shared notebooks, scripts and repositories for pasted keys, remove them, and rotate any key that was ever committed or shared. The check is a permissions listing showing only the operator account has access, plus a repository secret scan that returns no key matches.

  4. Move keys to per-engagement credentials

    Issue each engagement its own model, scorer and storage credentials, and inject them at runtime from the operator's secret store so they are not written to disk. Where the provider supports them, confirm spend limits and expiry dates for each key. The check is a test run that starts with keys supplied only from the secret store, followed by a search of the runner's home directory and run logs for key strings that returns no matches after the run ends.

  5. Set an egress allowlist for the runner

    Allow outbound connections from the runner only to approved target endpoints, approved model API hosts and approved scorer services, and deny all other destinations by default. Include an Azure AI Content Safety endpoint only if it is used as a scorer. The check is a list of allowed destinations signed off by the engagement lead, and a test in which the runner attempts a connection to an unlisted host and the attempt fails.

  6. Restrict memory, files and CoPyRIT access

    Limit access to PyRIT memory, which stores conversations and results in SQLite or Azure SQL, to the named red team. For SQLite, set file permissions on the database and its directory so only team members can read or write them. For Azure SQL, grant access to a named group and confirm that no shared administrator login is in use. If CoPyRIT is used, define its access path, authentication method and permitted users before anyone opens it. The check is an access review that matches each reader and writer of memory, and each CoPyRIT user, to the team roster.

  7. Enable logging of runs and key use

    Turn on logging for each attack run, recording the target, the attack strategy, the scorer used, the operator, and when each model or scorer key was used. Confirm which logging options the PyRIT 1.1.0 documentation provides, and fill any gaps with runner-level logging. Send logs to a location the runner account cannot edit or delete. The check is a test run that produces an entry for each field above, and a review confirming that the runner account cannot modify the log store.

  8. Run verification checks before any live attack

    Repeat the checks from the earlier steps against the actual environment, then run a dry run against a non-production target to confirm that scope, keys and logs behave as recorded. The engagement lead reviews the results and signs the verification record. The check is a signed record showing the result of each step, and no live target is attacked until every item passes or has a documented, approved exception.

Controlling access to stored prompts and harmful outputs

PyRIT memory is where a red team's most sensitive material ends up. The framework stores conversations and results in SQLite or Azure SQL, and its datasets cover content harms, psychosocial risks and data leakage. A stored record can therefore contain a working jailbreak, a model response describing self-harm or abuse, or a fragment of data the tested system should never have exposed. Treat the PyRIT database as a restricted data store from the first test run, not as a developer convenience. Before the first campaign, decide who is allowed to read it, who may export it, who may delete it, and where the database file or Azure SQL instance will live.

Start with roles. Separate the people who run attacks from the people who review findings and from the people who administer the database. Reviewers usually need read access to scored results, while only a small set of administrators should be able to export raw conversations or delete records. On SQLite, access is controlled by the file system permissions on the database file and the host it sits on, so the file should be readable only by the service account or named users who run PyRIT. On Azure SQL, use database roles and Microsoft Entra ID authentication rather than shared SQL logins, and log who runs exports. Confirm with your platform team how these permissions map to your existing access review process.

Findings must reach the wider team without copying raw harmful outputs into tickets, wiki pages or chat channels. A practical pattern is to reference a result by its identifier and the scenario name, then record the severity, the harm category, the attack strategy used and the remediation owner in the ticket. Anyone who needs the transcript opens it in the controlled store. Where a screenshot or excerpt is unavoidable, agree in advance on who may see it and how long it stays in the channel. Ask your red team lead to write this rule into the reporting template so reviewers do not improvise under deadline pressure.

Retention periods are set by the data owner, not by the framework default. Decide how long attack transcripts, scores and exports are kept, when they are deleted, and whether a legal hold can pause deletion. Some records may need to be kept to show a finding was remediated, while others, such as psychosocial test content, may need to be removed sooner. Encryption at rest should be confirmed for the storage layer: check the disk or volume encryption for a SQLite file, and the encryption and backup settings of the Azure SQL service you use. Backups of the database file or Azure SQL must follow the same access and retention rules as the live data, and restored copies must not be left in general-purpose storage. Keep test data in a separate database or instance from any production logs, so that an application log export never pulls adversarial prompts into an operations dashboard.

The correct retention and review rules depend on your organization's policy and on any legal or contractual obligations that apply to the data, such as customer contracts, records requirements or rules on handling personal data. DeployOpen can help you map these obligations to memory settings, roles and backup handling, but the decisions belong to your privacy, legal and security owners. Before the first campaign, ask them to confirm the retention period, the deletion method, who approves exports, and whether any regulated data may appear in test outputs. Record those answers in the scenario documentation so that the next person who runs PyRIT does not have to rediscover them.

Limiting impact on the systems PyRIT tests

PyRIT sends large volumes of adversarial traffic at AI systems, web apps and custom endpoints that real users depend on. The controls below decide who may point it at a target, when it may run, how hard it pushes, and who can stop it.

Written scope for each target

Record every endpoint PyRIT may reach, its owner, the attack categories allowed against it, and the datasets it may draw from. Anything not listed is out of bounds, including redirects or tools the target calls on its own. Check the scope against the target configuration before the first run, because a target added to a shared PyRIT config can inherit access nobody reviewed.

Approved test windows

Agree in writing when each target may be tested, such as off-peak hours or a change freeze window, and who confirms the window is open. Runs should start only inside that window and stop when it closes. Confirm with the target owner how their monitoring and on-call staff will tell test traffic from an incident before the window opens.

Named owner who can stop a run

Each endpoint needs one accountable owner on the target side with the authority and a working contact path to halt a PyRIT run. Multi-turn strategies such as Crescendo, TAP and Skeleton Key make repeated calls within a single attack, so a stalled owner means traffic keeps flowing. Confirm the owner's availability for the whole window, not only the kickoff.

Rate and concurrency settings

Set request rate and parallel attack count with the target owner, based on the capacity they report for their service. Multi-turn attacks multiply calls per objective, so a modest-looking setting can still load a small API. Ask the owner for their rate limits and cost ceilings, and verify the settings in the PyRIT configuration before the run starts.

No production use without explicit agreement

Default every engagement to staging or a dedicated test deployment with test data. Use production only when the target owner has agreed in writing to the specific tests, traffic levels and data involved. Web app targets driven through Playwright act on a live interface, so clicks, form submissions and account changes can have real effects that a model API target would not.

Stop procedure for misbehaving runs

Document the conditions that trigger a halt, such as error spikes, latency that affects other users, unexpected data writes, or out-of-scope requests. Name who may press stop, how to terminate active attacks, and how to confirm the target has recovered. Rehearse the procedure with the target owner before testing begins, and record each stop in the run log for review.

What drives the effort and cost of PyRIT hardening

This table lists the factors that change how much work PyRIT hardening takes and what it costs to run afterward. Read each row as a driver, its effect on effort, and the lever that keeps it under control. The main takeaway is that target count, shared operator access, and egress approvals usually matter more than the hardening steps themselves.

DriverWhy it changes effort or costHow to keep it down
Number and type of targetsEach target type (OpenAI, Azure, Anthropic, Google, Hugging Face, custom HTTP or WebSocket, Playwright-driven web apps) needs its own credential handling, network path, and access review. Custom HTTP, WebSocket, and Playwright targets usually take the most work because they hold their own session or login logic.Limit the first phase to the targets that matter for the current test scope. Reuse one credential pattern across similar providers and confirm which target types your team will actually run before scoping.
Number of operators sharing memory or CoPyRITShared memory and the CoPyRIT GUI add access control, user separation, and review of who can read stored prompts and harmful outputs. Each additional operator widens the access model.Start with a small named group and a single shared memory location. Document who may export results and confirm how your chosen storage handles per-user access before adding people.
Secrets backend and whether one already existsPyRIT reads credentials from ~/.pyrit/.env by default. If your organization already runs a secrets manager, integrating it is a one-time integration cost. If not, building and operating a new one adds a recurring operations burden.Reuse the existing secrets manager where possible and inject values at runtime rather than keeping a plaintext .env on shared hosts. Ask your platform team which backend they support before choosing an approach.
Network segmentation and egress approval cyclesTest hosts need outbound paths to model endpoints and tested systems. Each new destination often needs a firewall change, a security review, and sign-off, and those cycles set the calendar more than the technical work does.Batch egress requests by destination and submit them early with a written justification tied to the test scope. Keep test hosts in one segment so approvals apply to a single, stable allowlist.
Retention and evidence requirementsStored prompts, harmful outputs, and scoring records need defined retention periods, deletion steps, and evidence that access was controlled. Stricter retention rules add storage design, deletion tooling, and recurring review.Agree the retention schedule with legal, compliance, and the data owner before setup. Keep stored data to what findings require, and document how records are purged at the end of each engagement.
Number of environments (lab, staging, production-like)Each environment needs its own configuration, credentials, memory store, and access list. A production-like environment also raises the bar for limiting impact on the tested system.Keep the lab as the default place to build and debug custom attacks. Limit production-like testing to reviewed scenarios and reuse the same configuration templates across environments.
Custom code in converters, scorers, or targetsCustom code must be reviewed, tested, and re-checked after each PyRIT release. Code that calls external services or handles credentials expands the review scope and the security test surface.Prefer built-in targets, converters, and scorers where they meet the need. Keep custom modules small, version them, and include them in a review checklist with a named owner.

How to verify PyRIT hardening and confirm it fails safely

Hardening a PyRIT environment is only useful if you can show it works. The point of this section is to give your team a set of tests that check each control from the hardening work and that confirm the runner stops rather than improvises when something goes wrong. Each test should have a named owner, a written expected result, and a recorded actual result. Run the tests on the same host configuration you intend to use for real red teaming, not on a convenient developer laptop. Start with secrets. Confirm that ~/.pyrit/.env and ~/.pyrit/.pyrit_conf are readable only by the operator account, for example by checking file mode and owner on the host and inside any container or shared volume that mounts them. Then search for key material in places it should never appear: shell history files, application and CI logs, the repository history and working tree, and built container image layers. A secret scanner helps, but also check manually for the exact key values you issued, because pattern-based scanners miss keys in unusual formats. Any hit is a finding, even if the key is later rotated. Next, test the boundaries. From the runner, attempt to reach an endpoint that is not on your allowlist, such as an unrelated external host or an internal service outside the test scope, and confirm the connection is refused at the network layer, not only by application configuration. Then test failure behavior. Use a revoked or deliberately invalid key against a target and confirm the run stops with an error and does not try a second credential from another file or environment variable. Point a target at an unreachable address and confirm PyRIT does not retry into other hosts or redirect traffic to a fallback endpoint. Ask your engineers to confirm the exact retry and fallback settings in the PyRIT version you run, because defaults can change between releases. Test the data and the kill switch. Log in as a different OS account on the same host and confirm it cannot read the SQLite memory database or the CoPyRIT data directory, since both hold prompts and harmful outputs. Then start a multi-turn attack in a controlled test target and run your documented stop procedure. Confirm that requests stop within the time your owner has agreed as acceptable, that no further calls reach the target, and that partial results are saved as expected. Record every test as evidence for the system owner: the date, the tester, the commit or release tested, the command or steps, the expected and actual results, and any remediation with its retest. This plan is your own. DeployOpen can help design and run these tests, but independent auditors, not DeployOpen, issue any assurance report on your controls.

What to monitor, back up, rotate and document after hardening

Hardening a PyRIT environment only holds if someone keeps checking it. The duties below cover access, credentials, monitoring, memory backups, upgrades and records, and each one names an owner and the evidence it leaves for auditors and internal reviewers.

Review access to runner, memory and CoPyRIT

Review who can log in to the test runner, read the memory database and use the CoPyRIT web GUI on a schedule the owner sets. Remove accounts for people who have changed roles or left the red team. Owner: the platform or security lead. Evidence: a dated access review record listing each account, its role, the reviewer and the removals made.

Rotate model keys and check spend limits

Rotate the model API keys stored in the PyRIT credentials file on the interval set in your key policy, and after any suspected exposure or staff change. Confirm that each provider account has a spending limit that matches the approved test budget. Owner: the cloud or model account administrator. Evidence: a key inventory showing issue and rotation dates, plus exported spend limit settings.

Monitor egress and failed authentication

Watch outbound traffic from the test host so that only the approved model endpoints and custom targets receive requests. Alert on repeated failed logins to CoPyRIT and on unexpected destinations. Confirm with your vendor and network team which domains the model providers use before writing the allow list. Owner: security operations. Evidence: alert rule definitions, tested alert samples and a log of triaged events.

Back up memory and test restores

Back up the PyRIT memory store, whether SQLite or Azure SQL, on the schedule and retention period defined in your retention policy. Restore a copy into a separate environment at a set interval to prove the backup is usable. Confirm the retention period with your data owner, since harmful outputs may carry legal or handling rules. Owner: the data or database owner. Evidence: backup job logs and signed restore test reports.

Track releases and revalidate after 1.x upgrades

Track PyRIT releases on the microsoft/PyRIT repository and its release notes. Before moving to a newer 1.x release, such as v1.1.0 released on 4 September 2026, rerun your hardening checklist against the upgraded runner, including credential handling, network rules and access controls. Owner: the engineering lead. Evidence: a change record with the version, the checklist results and any approved deviations.

Keep a written scope, owner and exception record

Maintain one controlled register covering the approved test scope, named owners for each component, the key inventory and every exception to the hardening baseline. Each exception needs an approver, a business reason and an expiry date that triggers review. Owner: the red team program lead. Evidence: the dated register, version history and signed exception approvals.

PyRIT security hardening questions buyers ask before hiring help

How much does PyRIT security hardening cost?

Cost depends on the scope agreed in writing, and this page does not quote a figure. The main cost is skilled engineering time for host review, credential handling, access controls on memory and outputs, and documentation. Most of that work is one-time. Some items recur, such as reviewing configuration after each PyRIT upgrade, rotating credentials, and re-checking access as reviewers change. Model API spend for attacks and scoring is separate from hardening. When you ask for a quote, request a split between one-time and recurring work, a named owner for each task, and a list of the hosts, targets and storage locations in scope.

How long does it take to harden a PyRIT environment?

Duration depends on how much of the environment needs work and how quickly your people can respond. No duration is stated here. The main drivers are the number of test hosts and whether they are shared, how many model and HTTP targets hold credentials, whether memory uses SQLite files on disk or Azure SQL, how many target owners must approve changes, and how many review cycles the security team requires. Gaps in documentation also add time. Ask for a timeline in the written scope, along with the assumptions it depends on and the points where your team must act before work can continue.

What does a PyRIT hardening project need from our team?

Expect to provide four roles. Host access means accounts or change windows on the machines that run PyRIT, so changes can be made and checked. Target owners confirm which model endpoints, web apps and HTTP services can be tested, and they agree on the impact limits. A security reviewer signs off on credential handling, isolation and access to stored prompts and harmful outputs. A secrets manager owner decides where credentials live and how they are issued, rotated and revoked. If any of these roles is missing, the schedule usually slips, so confirm names for each before the work starts.

Can one engineer harden PyRIT on their own?

One engineer can sometimes handle a small setup, such as a single test host, one target and local SQLite memory. Most red team setups need more than one person, because the people who configure PyRIT should not be the only people who approve access to credentials and harmful outputs. Separation of duties matters here. The engineer also needs time from target owners and a reviewer, which is outside their control. Ask your team to list the hosts, targets and storage choices first. That list shows whether one person can cover the work or whether a second reviewer is needed from the start.

Does PyRIT need special configuration beyond host controls?

PyRIT reads credentials from ~/.pyrit/.env and settings from ~/.pyrit/.pyrit_conf, so those two files are the first place to review. Check their ownership, file permissions, and whether they are kept out of shared folders and version control. Target definitions, scorer settings and the memory location also need review, because they control where data goes. Beyond the files, host controls such as access restrictions, logging and network limits still apply. Confirm how these settings behave in the PyRIT version you run by checking the project documentation for that release, since version 1.1.0 is documented separately from earlier lines.

What does a PyRIT hardening engagement hand over?

Deliverables are defined in the written scope, so the list below describes typical categories rather than a fixed package. Expect a hardening baseline for each host, a procedure for handling the .env and .pyrit_conf files, an access model for memory and harmful outputs, notes on isolation from tested systems, and a runbook for reviewing configuration after upgrades. Where compliance readiness is in scope, you may also receive controls and evidence prepared for an independent assessor. DeployOpen does not issue audit reports, attestations or certifications. Ask for the handover list before signing, and confirm who keeps each item after the engagement ends.

Who should review harmful outputs that PyRIT stores?

Limit access to named reviewers who have a documented need and who follow your data handling rules. PyRIT stores conversations and results in SQLite or Azure SQL, so access control has to be applied at the file or database level as well as in the application. Decide who can read results, who can export them, how long they are kept, and how they are deleted. Team sharing, including the CoPyRIT GUI, adds more people with access, so review those permissions before a shared workflow goes live. A security reviewer should approve this model before testing starts.

How DeployOpen scopes, hardens and hands over PyRIT environments

DeployOpen plans and hardens PyRIT environments inside your own infrastructure, covering the .env credential file, test host isolation, access to stored prompts and harmful outputs, and limits on impact to tested systems. Engagements are fixed-scope, with scope, deliverables and timelines agreed in writing before work starts.

How we scope

  • Inventory every PyRIT entry point: CLI scans, Python attack scripts and any CoPyRIT deployment in use
  • Map where credentials in ~/.pyrit/.env and settings in ~/.pyrit/.pyrit_conf are read and copied
  • Agree in writing which targets, memory stores and result locations fall inside the hardening scope

How we build

  • Move model and target credentials out of plain files into a secret store your team controls, with access logged
  • Isolate PyRIT test hosts with restricted network egress so only approved targets and scorer endpoints are reachable
  • Restrict access to SQLite or Azure SQL memory and output folders, and document how harmful outputs are stored and purged

How we hand over

  • Deliver configuration documentation, a credential handling runbook and the access model for stored prompts and outputs
  • Provide verification notes showing each hardening control was tested, including credential exposure and egress checks
  • Walk your red team and platform staff through daily operation, rotation steps and how to add new targets safely

How we support

  • Available as a retainer that revalidates hardening after PyRIT upgrades and changes to custom targets or scorers
  • Review access and credential controls when red team members, models or test hosts change
  • Confirm support terms, response expectations and update cadence with DeployOpen in the written scope before work begins

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.