Modes and Failure Behavior

Shadow vs active vs dry_run, and fail_open vs fail_closed.

Understanding enforcement modes and failure strategies is critical for a safe rollout.

Enforcement Modes

Shadow Mode

NJIRA_MODE=shadow
  • Behavior: Calls enforcement, computes verdicts, but never blocks or modifies traffic.
  • Use Case: Initial production rollout. Observe policy impact without risking breakage.
  • Console: Verdicts are logged and visible in Traces as "shadow" decisions.

Active Mode

NJIRA_MODE=active
  • Behavior: Fully applies BLOCK and MODIFY verdicts.
  • Use Case: Production enforcement after validating in shadow mode.
  • Requirement: High confidence in policy accuracy.

Dry Run Mode

NJIRA_MODE=dry_run
  • Behavior: No network calls to Njira. All requests are locally allowed.
  • Use Case: Local development, CI/CD smoke tests, offline debugging.

Failure Strategy

What happens when the Njira API is unavailable (timeouts, network errors)?

Fail Open

NJIRA_FAIL_STRATEGY=fail_open
  • Behavior: Allow the request/tool call to proceed.
  • Recorded Reason: NJIRA_UNAVAILABLE
  • Trade-off: Prioritizes availability over strict safety.

Fail Closed

NJIRA_FAIL_STRATEGY=fail_closed
  • Behavior: Block the request/tool call.
  • Recorded Reason: NJIRA_UNAVAILABLE
  • Trade-off: Prioritizes safety over availability.

Recommended Rollout Path

Phase Mode Fail Strategy Duration
1. Integration dry_run N/A Dev/Test
2. Shadow Rollout shadow fail_open 1-2 weeks
3. Gradual Activation active fail_open 1-2 weeks
4. Full Enforcement active fail_closed Ongoing

Environment Variables Summary

Variable Values Default
NJIRA_MODE shadow, active, dry_run shadow
NJIRA_FAIL_STRATEGY fail_open, fail_closed fail_open
NJIRA_TIMEOUT_MS Integer (milliseconds) 5000

SDK Configuration

TypeScript

const njira = new NjiraAI({
  apiKey: "...",
  mode: "active",        // or "shadow" | "dry_run"
  failStrategy: "fail_closed",
  timeoutMs: 3000,
});

Python

njira = NjiraAI(
    api_key="...",
    mode="active",
    fail_strategy="fail_closed",
    timeout_ms=3000,
)