FEAT: Support editing config from GUI - #2486
Conversation
# Conflicts: # pyrit/models/__init__.py
| fi | ||
| } >"$RUNTIME_CONFIG" | ||
|
|
||
| CONFIG_FILE="${PYRIT_CONFIG_FILE:-$RUNTIME_CONFIG}" |
There was a problem hiding this comment.
With pyritConfigFileUri empty (the default in both param files), PUT /api/config writes /tmp/pyrit_runtime.yaml, and start.sh regenerates that file on startup. Does a GUI edit survive the restart the UI suggests, or is there a persistence path I'm missing?
| generate the existing minimal config from `sqlServerFqdn` and | ||
| `pyritInitializer` at container startup. | ||
|
|
||
| Grant the managed identity `Storage Blob Data Contributor` on the config blob, |
There was a problem hiding this comment.
This lists Storage Blob Data Contributor for the config blob. The env editor also writes to Key Vault via set_secret, and the AKV path reads from it at runtime — should the KV role be listed here too? Post-Deployment still has # Note: Key Vault Secrets User is NOT required.
|
|
||
| script_path = self._get_custom_scripts_dir() / f"{name}.py" | ||
| script_path.unlink(missing_ok=True) | ||
| self._get_custom_storage().delete_script(name) |
There was a problem hiding this comment.
The runtime class is dropped just above this, so if delete_script fails the script stays in storage and the retry raises KeyError — and it gets re-registered on next boot. Should storage be deleted first?
| class TestCustomInitializerRoutes: | ||
| """Tests for runtime custom initializer routes.""" | ||
|
|
||
| def test_post_returns_403_when_custom_initializers_disabled(self, client: TestClient) -> None: |
There was a problem hiding this comment.
The two *_403_when_custom_initializers_disabled tests look like they dropped off here — the 422 name-validation ones stayed. Intentional? Flagging since that flag is the kill-switch.
| if not isinstance(yaml_data, dict): | ||
| raise ValueError("Configuration content must be a non-empty YAML mapping.") | ||
| try: | ||
| ConfigurationLoader.from_dict(yaml_data) |
There was a problem hiding this comment.
Saving allow_custom_initializers: "false" (quoted) passes validation, but it stays a string and reads truthy at startup — so the flag ends up enabled. Unquoted false/no/off are fine. Might be worth enforcing the type here
|
|
||
| @description('Object ID of the Entra security group allowed to manage backend configuration') | ||
| @minLength(1) | ||
| param adminGroupObjectId string |
There was a problem hiding this comment.
adminGroupObjectId is required with no default, but neither az deployment group create in gui-deploy.yml passes it (lines 154-168 and 237-251), and this PR doesn't touch that file. Test and prod stages might fail template validation after merge
|
Left a few notes — the video made this much easier to follow! Only two I'd actually give weight on: gui-deploy.yml doesn't pass the new required adminGroupObjectId (param files and deploy_instance.py all got it, just not the pipeline), and a quoted "false" on allow_custom_initializers reads truthy. The rest are minor/follow-up material and non-blocking! |
Problem
Previously, changing configuration, environment values, or initializer code in a deployed CoPyRIT instance required direct access to its filesystem, container, or deployment configuration. Changes could also be lost when the container restarted.
This change provides a persistent, browser-based workflow for managing those resources and applying changes without redeploying the application.
Summary
Adds GUI-based management of PyRIT backend configuration, enabling deployed CoPyRIT instances to be configured without direct filesystem or container access.
.pyrit_confAzure Blob Storage in addition to local files..pyrit_conf(regardless of whether it's a local file or blob)