Skip to main content

opena2a shield

Unified security orchestration for AI coding assistants. Event log, policy evaluation, runtime monitoring, session identification, integrity checks, and LLM-powered analysis.

Usage

opena2a shield <subcommand> [options]

Quick Start

# Initialize Shield in your project
opena2a shield init
 
# Name the AI assistant this shell runs under
opena2a shield session
 
# View security events
opena2a shield log
 
# Generate a posture report
opena2a shield report
 
# Run integrity verification
opena2a shield selfcheck

Capabilities

Shield's policy has three modes. opena2a shield init writes adaptive, the default. The mode is the mode field in ~/.opena2a/shield/policy.yaml, and opena2a shield policy shows it. In adaptive and monitor modes, opena2a shield evaluate reports a command the policy denies as MONITORED and exits 0. In enforce mode it reports the command as blocked and exits 1.

CapabilityDescriptionStatus
Credential scanningDetects hardcoded API keys (Anthropic, OpenAI, AWS, Google, GitHub)Active
Scope drift detectionFinds keys that silently access unintended services (DRIFT-001, DRIFT-002)Active
Event logEach event records the SHA-256 hash of the event before it; the hashes use no keyActive
Policy evaluationAllow/deny rules for processes, credentials, network, filesystem, MCP serversActive
Session identificationNames the current AI assistant from environment variables (claude-code, cursor, copilot, aider)Active
Config integrityRecords a SHA-256 hash of each tracked config file and reports files that changed or went missingActive
ARP bridgeImports runtime protection events from HackMyAgent ARPActive
Posture scoring0-100 security score based on active tools, policy, hooks, credentialsActive
LLM intelligencePolicy suggestions, anomaly explanations, incident triageOpt-in
Integrity selfcheckVerifies policy, shell hooks, event chain, process, artifact signaturesActive
Enforcement modeShell hooks check policy and block denied commands in enforce modeActive
HTML posture reportInteractive dark-theme report with severity chart, filters, agent activityActive

Subcommands

SubcommandDescription
init11-step security setup: environment scan, policy generation, shell hooks with --shell-hook, an event in the Shield event log (contrast with read-only opena2a init)
statusTool availability, policy mode, shell integration, integrity state
logQuery the Shield event log with filters (severity, source, agent, time)
selfcheckRun integrity checks: policy hash, shell hook, event chain, process binary, artifact signatures
policyShow loaded security policy (mode, rule counts, agent overrides)
evaluateEvaluate an action against the loaded policy (ALLOWED, BLOCKED, MONITORED)
monitorImport ARP runtime events into Shield log and display runtime stats
reportGenerate a security posture report with severity breakdown and agent activity
sessionName the AI coding assistant from environment variables (claude-code, cursor, copilot, aider, or unknown)
recoverExit lockdown mode, with optional verification. No Shield check currently puts the system into lockdown.
suggestLLM-powered policy suggestions based on observed agent behavior
explainLLM-powered anomaly explanations with risk factors and recommended actions
triageLLM-powered incident classification: false-positive, suspicious, confirmed-threat
baselineShow per-agent behavioral baselines. No Shield command in opena2a-cli 0.10.13 records one.

Subcommand Details

shield init

11-step security setup that detects project type, scans for credentials, discovers AI assistants, MCP servers, and OAuth sessions, generates a YAML policy file, when run with --shell-hook installs shell hooks, and writes an event to the Shield event log. Unlike the read-only opena2a init assessment,shield init actively configures security infrastructure in your project. Without --shell-hook, step 7 prints Skipped (opt-in: use --shell-hook to install) and init leaves your shell startup files unchanged. With it, init adds the hook to ~/.zshrc or ~/.bashrc, whichever matches your SHELL.

opena2a shield init
opena2a shield init --shell-hook
opena2a shield init --dir ./my-agent
opena2a shield init --format json

shield log

Query the Shield event log with filters. Each event records the SHA-256 hash of the event before it.

opena2a shield log # Last 20 events
opena2a shield log --count 50 # Last 50 events
opena2a shield log --severity high # High only, not critical
opena2a shield log --source arp # ARP events only
opena2a shield log --agent claude-code # Filter by agent
opena2a shield log --since 7d --format json # JSON output

shield selfcheck

Runs five integrity checks and returns an overall status: healthy, degraded, or compromised.

CheckVerifies
PolicyPolicy file hash matches recorded value
Shell hookShell hook content matches expected template
Event chainEach event's previous-hash field matches the recorded hash of the event before it
ProcessNode.js binary exists and appears legitimate
Artifact signaturesEach tracked Shield file matches its recorded SHA-256 hash

shield monitor

Import ARP (Agent Runtime Protection) events into the Shield event log and display runtime protection stats. Events from HackMyAgent's ARP module are translated into Shield's unified event format.

opena2a shield monitor # Import + show stats
opena2a shield monitor --agent cursor # Tag imported events
opena2a shield monitor --since 7d # Stats window

shield session

Name the AI coding assistant the current shell runs under, from environment variables. opena2a-cli 0.10.13 reports claude-code when CLAUDE_CODE is set or TERM_PROGRAM is claude, cursor when CURSOR is set, copilot when VSCODE_PID is set, and aider when TERM_PROGRAM is aider. It has no rule for Devin Desktop (formerly Windsurf) or Continue, and a shell that matches none of these prints Agent: unknown. Claude Code sets CLAUDECODE, which this command does not read, so a Claude Code session prints Agent: unknown unless CLAUDE_CODE is set or TERM_PROGRAM is claude.

opena2a shield session # Detect current session
opena2a shield session --verbose # Show raw signals

shield report

Generate a security posture report from event data. Includes severity breakdown, agent activity, policy violations, top actions, and optional LLM-powered narrative. Supports interactive HTML output.

opena2a shield report # Last 7 days (text)
opena2a shield report --report posture.html # Interactive HTML
opena2a shield report --since 30d # Last 30 days
opena2a shield report --analyze # Include AI narrative

shield baseline

Show per-agent behavioral baselines. The command only reads them, from ~/.opena2a/shield/baselines/. No Shield command in opena2a-cli 0.10.13 records a baseline, so after shield evaluate has logged events, opena2a shield baseline still prints No baselines found. and exits 0. With --agent <name> it prints an empty baseline for that agent (phase learn, 0 actions, 0 sessions) and does not save it.

opena2a shield baseline # List recorded baselines
opena2a shield baseline --agent claude-code # Detail for one agent
opena2a shield baseline --format json # JSON output

Enforcement Mode

When shield init installs shell hooks and the policy mode is set to enforce, each command is evaluated against the loaded policy before execution. Denied commands are blocked with exit code 1.

# Shell hook (zsh) automatically runs before each command:
if ! opena2a shield evaluate "$1" 2>/dev/null; then return 1; fi

LLM Intelligence (suggest, explain, triage)

Three LLM-powered subcommands provide AI analysis of security events. They need an LLM backend. opena2a-cli 0.10.13 uses the claude CLI when it is on your PATH and the CLAUDECODE environment variable is not set (a Claude Code session sets it). Otherwise it uses an Anthropic API key in ANTHROPIC_API_KEY, and only after opena2a config llm on, with one exception: it reads that setting through its @opena2a/shared dependency and, when that package fails to load, uses the key without the setting. With neither backend, the three subcommands print LLM intelligence is not available. and exit 1, and shield report --analyze prints the report with a line saying the analysis is unavailable. Shield calls an LLM only when you run one of these subcommands or shield report --analyze.

# Policy suggestions from observed behavior
opena2a shield suggest --agent cursor
 
# Anomaly explanations with risk factors
opena2a shield explain --severity high --count 5
 
# Incident classification and response steps
opena2a shield triage --severity medium

Options

FlagTypeDescription
--dir <path>stringTarget directory. Defaults to current working directory.
--agent <name>stringAgent name for log, suggest, explain, triage, baseline.
--count <n>numberEvent count for log and explain. Default: 20 (log), 1 (explain).
--since <timespec>stringTime filter: 7d, 1w, 1m, or ISO 8601 timestamp.
--severity <level>stringSeverity filter: info, low, medium, high, critical. Matches that one level, so high does not include critical.
--source <source>stringEvent source filter (e.g., arp, secretless, shield).
--category <cat>stringEvent category filter.
--verifybooleanVerify integrity before exiting lockdown (recover).
--analyzebooleanInclude LLM-powered narrative in reports.
--report <path>stringWrite interactive HTML posture report to file.
--shell-hookbooleanInstall the shell hook in ~/.zshrc or ~/.bashrc (shield init only).
--verbosebooleanShow additional details (e.g., raw session signals).
--format <type>text | jsonOutput format. Default: text.

Event Log Format

Shield keeps its event log at ~/.opena2a/shield/events.jsonl, one JSON event per line. Each event records the SHA-256 hash of the event before it, and the first event records a fixed public value in its place. The hashes use no key, so any program that can write the file, including an AI coding assistant running as the same user, can change events and recompute the hashes after them.

What opena2a shield log --count 3 prints (captured from opena2a-cli 0.10.13, 2026-10-06, on a scratch HOME with the default Shield policy, after opena2a shield evaluate checked aws s3 ls, kubectl get secrets and gcloud auth list):

[2026-10-06T22:58:38.547Z] [MEDIUM] command.monitored -> gcloud auth list (monitored)
[2026-10-06T22:58:38.488Z] [MEDIUM] command.monitored -> kubectl get secrets (monitored)
[2026-10-06T22:58:38.429Z] [MEDIUM] command.monitored -> aws s3 ls (monitored)

Exit Codes

CodeMeaning
0Success (healthy, allowed, recovered). selfcheck also exits 0 when its overall status is degraded.
1Failure (compromised, lockdown, blocked, no policy, unknown subcommand)

See Also