{% extends "base.html" %} {% block title %}{{ "Edit" if mode == "edit" else "New" }} manifest · ai-protect{% endblock %} {% block autorefresh %}window.AI_PROTECT_NO_AUTOREFRESH = true;{% endblock %} {% macro select(name, options, current, allow_blank=False) %} {% endmacro %} {% block content %} ← back to manifests

{% if mode == "edit" %}Edit manifest {{ original_name }} {% else %}New manifest{% endif %}

{% if errors %}
Validation errors:
{% endif %} {% if warnings %}
Warnings (saved anyway):
{% endif %}
{# A tiny helper macro keeps the help-bubble pattern uniform across the form. Anchors land at /docs#manifest-. #} {% macro hb(anchor, tooltip) -%} ? {%- endmacro %}
Identity
Risk tiering (v2.1 four-dimension scoring) {{ hb('manifest-data-sensitivity', 'Each dimension scores 1-4 (riskier higher). Sum + forced rules → Tier 1-4. Use "all" if your app spans every value in a dimension; it resolves to the most-restrictive value.') }}
Live preview: T? More on what these mean →
Scan scope {{ hb('manifest-source-paths', 'Where SAST/SCA/IaC adapters look on disk. Optional when source_provider=github (the orchestrator sets it after cloning).') }}
Source provider Where ai-protect fetches code from before scanning. Leave blank to use the global default set on Settings → Source providers. Override per-manifest by picking a provider explicitly.
Tip: when Provider = github, Scan scope's Source paths field above is overridden at scan time — the orchestrator materializes the repo to a temp dir (or a persistent cache, per Settings → Clone strategy) and points adapters there. You can still leave Source paths blank.
Model endpoints (optional) {{ hb('manifest-models', 'Every model the app sends prompts to. PHI handling requires via_gateway=true AND baa_covered=true on every model.') }} Each model the app sends prompts to. PHI requires via_gateway=true AND baa_covered=true — manifest validation rejects otherwise.
{% for m in (form.get('models') or []) %} {% set i = loop.index0 %}
{% endfor %}
MCP servers (optional) {{ hb('manifest-mcp-servers', 'MCPs the app calls as tools. The app inherits the most-restrictive tier across its MCPs — a Tier 4 app that calls a Tier 1 MCP is classified Tier 1.') }} MCPs the app calls. Tier inheritance: the app's tier is at least as restrictive as the most-restrictive MCP it uses.
{% for s in (form.get('mcp_servers') or []) %} {% set i = loop.index0 %}
{% endfor %}
Surfaces (attacker-controlled inputs) {{ hb('manifest-surfaces', 'Where untrusted input enters the app. The more surfaces, the larger the prompt-injection attack surface — adapters like garak / pyrit probe these.') }}
Target environment {{ hb('manifest-target', 'Where DAST scans (ZAP, nuclei, sqlmap, mcp_scope) reach. Also gates state-changing adapters via allow_mutation.') }}
Expected behavior (optional) {{ hb('manifest-expected', 'Ground-truth allow-lists. Anything outside these sets is flagged as a scope violation by mcp_scope.') }}
Cancel {% if mode == "edit" %} {% endif %}
{% endblock %}