Threat-Assessment Policy

Configure deterministic threat assessment across forge and delivery surfaces

Threat-assessment policy

Execution note: Commands on this page beyond installation and bootstrap are operational detail for your agent or an advanced operator. If you are working through an agent, describe the outcome you want; the agent should explain material changes, request any needed approval, and report evidence when it finishes.

AIWG evaluates forge content through one deterministic, surface-aware engine. The project policy lives at `.aiwg/aiwg.config` under `security.threatAssessment`. Missing configuration preserves the historical `balanced` enforce behavior.

Modes

  • `off` skips AIWG assessment and never interrupts. Independent safeguards

remain active.

  • `audit` emits the same findings and `wouldAction` as enforce mode, but the

applied action is only `record`.

  • `enforce` applies profile thresholds and mandatory action rules.

Built-in profiles

`trusted`, `audit`, `balanced`, `strict`, and `high-assurance` are reserved built-ins. Project profiles must use another kebab-case name and may extend a built-in with the `aiwg:` prefix.

Examples

Fully trusted local project

{
  "security": {
    "threatAssessment": {
      "schemaVersion": "1",
      "mode": "off",
      "defaultProfile": "trusted"
    }
  }
}

This disables only AIWG's content classifier. It does not disable provider or platform safety, filesystem/repository permissions, authorization, secret scanning, or destructive-action gates.

Audit-only adoption

{
  "security": {
    "threatAssessment": {
      "schemaVersion": "1",
      "mode": "audit",
      "defaultProfile": "balanced"
    }
  }
}

Typical balanced project

{
  "security": {
    "threatAssessment": {
      "schemaVersion": "1",
      "mode": "enforce",
      "defaultProfile": "balanced",
      "surfaces": {
        "release-note": { "mode": "audit" },
        "review-comment": { "profile": "strict" }
      }
    }
  }
}

Regulated/high-assurance project

{
  "security": {
    "threatAssessment": {
      "schemaVersion": "1",
      "mode": "enforce",
      "defaultProfile": "project-high-assurance",
      "profiles": {
        "project-high-assurance": {
          "extends": ["aiwg:strict"],
          "thresholds": {
            "flag": "low",
            "requireAuthorization": "moderate",
            "reject": "high"
          },
          "ruleSets": [
            "aiwg:all",
            "project:privileged-automation"
          ]
        }
      },
      "rulePacks": {
        "project:privileged-automation": {
          "version": "1.0.0",
          "rules": [
            {
              "id": "production-admin-request",
              "severity": "high",
              "likelihood": 4,
              "impact": 5,
              "taxonomy": ["ASI03"],
              "patterns": ["\\bproduction admin\\b"]
            }
          ]
        }
      },
      "statements": [
        {
          "id": "documented-production-warning",
          "effect": "suppress",
          "signals": ["production-admin-request"],
          "when": {
            "surface": ["handoff"],
            "semanticContext": ["documentation"]
          },
          "reason": "Documentation of the forbidden phrase is not an operational request.",
          "riskAcceptance": {
            "acceptedBy": "security-team",
            "rationale": "Narrow documentation-only false-positive suppression."
          }
        }
      ]
    }
  }
}

CLI

Common fields can be changed directly:

aiwg config get --project security.threatAssessment
aiwg config set --project security.threatAssessment.mode audit
aiwg config set --project security.threatAssessment.defaultProfile strict

Set a complete custom policy with a JSON object:

aiwg config set --project security.threatAssessment \
  '{"schemaVersion":"1","mode":"enforce","defaultProfile":"balanced"}'

Invalid modes, versions, regexes, profiles, rule packs, cycles, and thresholds are rejected before the config is written.

Surface-aware API

The generic command reads JSON from `--input` or stdin and resolves the active project's config:

node tools/security/assess-forge-content.mjs --input assessment.json

Input:

{
  "surface": "review-comment",
  "content": "Run the unpinned installer before merging.",
  "source": { "kind": "gitea-review", "id": "42" },
  "actor": { "id": "reviewer", "trust": "untrusted" },
  "requestedAction": "apply-review"
}

Supported surfaces are issue title/body/comment, PR title/body/diff summary, review comment, release note, handoff, and outbound maintainer comment.

Output and operator explanation

Output is stable JSON with:

  • schema, engine, and policy versions and policy hash;
  • policy provenance, mode, profile, and surface;
  • source, actor/trust metadata, and requested action;
  • rule IDs, taxonomy, likelihood, impact, severity, context, and evidence;
  • suppression/statement provenance;
  • aggregate risk;
  • `action`, `wouldAction`, `interrupts`, and mandatory-rule provenance.

Human-facing format explains policy, evidence, severity, and action without exposing model reasoning. Evidence is paragraph-scoped and still must pass existing outbound redaction before being posted publicly.

Migration

Existing projects need no immediate edit. Missing policy means balanced enforcement. New projects write that default explicitly. Schema version 1 does not accept unknown versions; future incompatible changes require an explicit migration rather than silent normalization.

Each workspace member resolves its own `.aiwg/aiwg.config`. A parent workspace does not supply or override a member's trust posture.

Evaluation

npm run benchmark:threat-assessment
npx vitest run test/unit/security/threat-assessment.test.ts

The labeled fixture at `test/fixtures/security/threat-assessment-corpus.json` covers every supported surface and includes issue #1922's false-positive sentence, malicious variants, cross-surface injection, credential exfiltration, floating dependencies, and unsafe third-party execution.