Command Reference
The root command is shield360. Run shield360 --help or shield360 <command> --help for inline usage at any time.
shield360├── ci Deploy markers and test results from a CI pipeline│ ├── release Record that a release was deployed│ └── tests Send JUnit XML test results├── coding Coding-agent observability (Claude Code, Cursor, Codex, OpenCode)│ ├── install Install per-vendor host plugin manifests│ ├── launch Bootstrap the plugin for an agent and exec it│ ├── uninstall Remove per-vendor host plugin manifests│ └── hook Process a hook event (invoked by host plugins)├── configure Write persistent settings to config.env├── doctor Diagnose config, OTLP reachability, and plugins└── version Print the CLI versionshield360 coding
Section titled “shield360 coding”Coding-agent observability for Claude Code, Cursor, Codex, and OpenCode. See the Coding Agents setup guide for the full vendor-by-vendor walkthrough.
shield360 coding install
Section titled “shield360 coding install”Install the per-vendor host plugin manifest. Idempotent - re-running drops prior shield360 entries before re-writing, leaving any third-party entries in place.
shield360 coding install --vendor=claude-codeshield360 coding install --vendor=all --dry-run # preview without writing| Flag | Description |
|---|---|
--vendor (required) | claude-code | cursor | codex | opencode | all |
--dry-run | Print what would be written without modifying any files |
Where manifests are written:
| Vendor | Manifest path |
|---|---|
| Claude Code | ~/.claude/plugins/shield360-cc/ |
| Cursor | ~/.cursor/hooks.json (user scope, merged) |
| Codex | ~/.codex/plugins/shield360/ |
| OpenCode | $XDG_CONFIG_HOME/opencode/plugins/shield360.ts when set; otherwise <user-home>/.config/opencode/plugins/shield360.ts |
shield360 coding launch
Section titled “shield360 coding launch”Bootstrap the plugin for an agent and exec it - telemetry on from the first turn. Auto-installs the manifest if needed.
shield360 coding launch claudeshield360 coding launch cursor -- <agent-args...> # pass args through after --shield360 coding launch codexshield360 coding launch opencode| Argument | Description |
|---|---|
<agent> (required) | claude | claude-code | cc | cursor | codex | opencode (claude-code and cc are aliases for claude) |
Any arguments after -- are forwarded to the agent’s own CLI.
shield360 coding uninstall
Section titled “shield360 coding uninstall”Remove the per-vendor plugin manifests written by install. Best-effort deregisters the plugin from the vendor’s own CLI where applicable. Leaves your shared config alone unless --purge is passed.
shield360 coding uninstall --vendor=cursor # one vendorshield360 coding uninstall --vendor=all # every vendorshield360 coding uninstall --vendor=all --purge # also drop ~/.config/shield360 + session cacheshield360 coding uninstall --vendor=cursor --dry-run # preview without touching disk| Flag | Description |
|---|---|
--vendor (required) | claude-code | cursor | codex | opencode | all |
--purge | Also remove ~/.config/shield360 and the session-state cache |
--dry-run | Print what would be removed without modifying any files |
shield360 coding hook
Section titled “shield360 coding hook”shield360 coding hook --vendor=claude-code --event=SessionStart < payload.json| Flag | Description |
|---|---|
--vendor (required) | cc | claude-code | cursor | codex | opencode |
--event | Hook event name (vendor-specific; e.g. SessionStart, PreToolUse) |
The hook is crash-isolated: a 5-second hard timeout (~3s reserved for OTLP flush) and it always exits 0 even when telemetry fails - a broken pipeline never blocks your coding session. It never writes to stdout (agents like Claude Code parse stdout for JSON). Set SHIELD360_DEBUG_PAYLOAD_DIR to tee raw payloads for debugging.
shield360 configure
Section titled “shield360 configure”Write persistent settings to ~/.config/shield360/config.env. See Configuration for the full flag table, precedence, and content-capture modes.
shield360 configure --url https://app.shield360.ai --api-key $SHIELD360_API_KEYshield360 configure --show # print resolved config and its source, write nothingshield360 init
Section titled “shield360 init”Set a repository up to send its app’s telemetry to Shield360. Run it in the app’s directory:
shield360 init # show what it found and what it would changeshield360 init --write # make the changesshield360 init ./services/checkout --app checkout --writeIt reads the repository: the language (package.json, pyproject.toml or requirements.txt, pom.xml or build.gradle, *.csproj, go.mod), its Dockerfiles, its Compose files and its Kubernetes manifests. With --write it:
- creates
.shield360.envwithSHIELD360_URL, the app’s name (OTEL_SERVICE_NAME), its environment andSHIELD360_CAPTURE_LOGS=true. It never writes the API key: keep it in your secret store; - for a Node app, adds the Shield360 SDK to each Dockerfile’s final stage, installed in
/opt/shield360and preloaded throughNODE_OPTIONS(the app’s own options are kept). A final stage without npm (a distroless image, say) is left alone, with a note; - for a Java app, adds the OpenTelemetry Java agent to each Dockerfile’s final stage with
ADD --checksum=sha256:…, so the build fails if the download changes, andJAVA_TOOL_OPTIONS.
It changes nothing else. For the rest it prints the next step: shield360 run -- <start command> for local runs, env_file for Compose, and for Kubernetes the one namespace annotation that lets the Shield360 operator inject the SDK into every pod. Running it again changes nothing.
| Flag | Default | What it does |
|---|---|---|
--write | off | Make the changes; without it, only show them |
--app | package.json or pyproject.toml name, else the directory | The app’s name in Shield360 |
--env | production | The environment the deployed app reports as |
--sdk-version | the latest on npm | The Node SDK version to bake in |
shield360 doctor
Section titled “shield360 doctor”Diagnose the CLI’s setup. Reads the resolved config, TCP-dials the OTLP endpoint (2s timeout), and lists installed vendor plugins.
shield360 doctorExit code 0 means the CLI is wired up (possibly with warnings); 1 means at least one check failed. This is the first thing to run when something isn’t showing up on /agents.
shield360 mcp bridge
Section titled “shield360 mcp bridge”Serves a stdio MCP server over authenticated HTTP, so the Shield360 MCP gateway can reach it. Most MCP servers people install with npx or uvx speak only stdio; the bridge runs one and answers MCP’s streamable HTTP transport at POST /mcp.
export SHIELD360_MCP_BRIDGE_TOKEN=$(openssl rand -hex 32)shield360 mcp bridge --listen 127.0.0.1:8931 -- npx -y @modelcontextprotocol/server-filesystem /srv/docsThen register it in Build → MCP → Servers as an MCP server at http(s)://<host>:8931/mcp, with the header Authorization: Bearer <token>. A bridge on a private address also needs Allow private network on that service.
| Flag | Default | Meaning |
|---|---|---|
--listen | 127.0.0.1:8931 | Address to serve on. |
--token-env | SHIELD360_MCP_BRIDGE_TOKEN | Environment variable holding the bearer token: at least 24 characters. It is never read from a flag, so it does not show in a process listing, and it is removed from the environment of the server the bridge starts. |
--tls-cert, --tls-key | Serve HTTPS with this certificate and key. | |
--insecure-plain-http | false | Serve plain HTTP on an address other than loopback. Only for a bridge behind a proxy that terminates TLS. Without it, the bridge refuses plain HTTP anywhere but loopback. |
--call-timeout | 120s | How long one call to the MCP server may take. |
How it behaves:
- Every request needs the token. Anything else is answered
401. - One initialize. The bridge initializes the server once, at start. The gateway initializes on every connection, so the bridge answers later
initializerequests from the first result; many stdio servers refuse a second one. - Callers never see each other’s answers. Request ids are rewritten to the bridge’s own, so concurrent callers that reuse the same id are kept apart.
- The server is never left waiting. If the server asks its client something (sampling, roots, elicitation), the bridge answers that it is not supported. Log and progress notifications from the server are dropped.
- When the server exits, the bridge stops and reports the exit status.
shield360 run
Section titled “shield360 run”Start any app with Shield360, with no code change: put it in front of the command you already use.
shield360 run -- npm startshield360 run --app checkout --env staging -- node server.jsshield360 run -- uvicorn main:app --reloadshield360 run -- java -jar build/libs/orders.jarThe app’s requests, database and cache calls, AI calls and logs go to Shield360 under the app’s name. See Zero-code setup for what is traced.
| Flag | Default | What it does |
|---|---|---|
--app | package.json or pyproject.toml name, else the directory | The app’s name in Shield360 |
--env | dev (or SHIELD360_ENVIRONMENT) | The environment its data goes to |
--runtime | from the command | node, python or java, when the command doesn’t show it (a shell script, say) |
--sdk-dir | ~/.shield360/sdk | Where the Node SDK is installed and reused |
--sdk-version | latest | The Node SDK version to install |
--java-agent-version | 2.33.1 | The OpenTelemetry Java agent version to download |
--no-install | off | Fail instead of installing the Node SDK or downloading the Java agent |
It needs SHIELD360_URL and SHIELD360_API_KEY, from the environment or shield360 configure. Node apps need npm on the PATH the first time; Python apps need the shield360 package in their interpreter. Java apps get the OpenTelemetry Java agent, downloaded once from Maven Central into ~/.shield360/sdk/java and refused unless its SHA-256 matches (pinned for the default version). It traces HTTP servers and clients, JDBC, Redis, Kafka and gRPC and sends the app’s logs, through JAVA_TOOL_OPTIONS and the standard OTEL_* settings pointed at Shield360. Start the app itself (java -jar app.jar), not a build tool: the agent leaves JDK tools alone. The command’s output, exit status and Ctrl-C pass straight through, so run works in scripts and in package.json scripts.
shield360 scan
Section titled “shield360 scan”Find known vulnerabilities, risky configuration and committed secrets in your code or a container image, and send what was found to Shield360 under the app’s name.
shield360 scanshield360 scan ./services/orders --app ordersshield360 scan --image ghcr.io/acme/orders:1.4.2 --fail-on highshield360 scan --dry-run --output scan.jsonScan the images a cluster runs
Section titled “Scan the images a cluster runs”shield360 scan --cluster runs inside a Kubernetes cluster. It lists the
running pods with its service account (it needs list on pods, nothing
else), scans every distinct image once by the digest the nodes run, and sends
each image’s vulnerabilities to Shield360 with where it runs: the cluster
(--cluster-name, or SHIELD360_CLUSTER_NAME), the workloads and their pods,
and the nodes. Pass --exclude-namespaces to skip some namespaces. It never
runs in an app’s pod. A ready-made daily CronJob, with its RBAC and an ECR
pull role, is in deploy/k8s/scan/ of the Shield360 repository. The images
show under Protect → Application security → Code security, marked Running with where they run.
The scan runs on your machine or CI runner with Trivy. It finds:
- the packages and versions in use, from lock files and manifests or the image’s layers (a software bill of materials), and which of them are AI components: model SDKs, agent frameworks, MCP SDKs, model runtimes and vector stores;
- the known vulnerabilities that match them, with the version that fixes each;
- failed configuration checks in Dockerfiles, Kubernetes manifests, Helm charts and Terraform;
- committed secrets;
- for a directory, problems in the app’s own JavaScript, TypeScript and Python found by Shield360’s code rules: model output run as code or as a shell command, request input in a system prompt, AI provider keys in code, SQL and command injection, unsafe loading of YAML, pickle and model weights, and turned-off TLS checks.
Your code never leaves the machine. Shield360 receives package names and versions, advisory IDs, check results and the file each was found in. A secret is sent as its rule, file and line only, never its value. A directory is named by its last segment, never its full path.
| Flag | Default | What it does |
|---|---|---|
--app | package.json or pyproject.toml name, else the directory or image name | The app’s name in Shield360 |
--image | - | Scan this container image instead of a directory |
--commit, --branch | from CI variables, else git | What was scanned |
--fail-on | - | Exit with status 2 when anything at or above critical, high, medium or low is found, to fail a CI job |
--dry-run | off | Scan and print the payload instead of sending it |
--output | - | Also write the payload to this file |
--no-secrets | off | Skip the committed-secrets check |
--no-code | off | Skip the check of the app’s own code |
--no-cost | off | Skip the check for code that costs money to run (cost rules). Cost findings never fail --fail-on |
--rules | - | Also check the code with these rule files or directories (YAML, repeatable); see Code rules |
--trivy-path | - | Use a Trivy you installed instead of downloading one |
--tools-dir | ~/.shield360/tools | Where Trivy and its vulnerability database are cached |
--no-install | off | Fail instead of downloading Trivy |
--timeout | 15m | How long the scan may take |
It needs SHIELD360_URL and SHIELD360_API_KEY (except with --dry-run); the key’s environment receives the scan, and its creator’s role needs Manage AI app security. Trivy 0.76.1 is downloaded once from its GitHub release and refused unless its SHA-256 matches the one pinned in the CLI. Trivy then downloads its vulnerability database into the tools directory and refreshes it when it is out of date. Each app keeps the findings of its latest scan of each directory or image, and the counts of up to 100 earlier scans.
In GitHub Actions:
- name: Scan with Shield360 run: shield360 scan --fail-on critical env: SHIELD360_URL: https://app.shield360.ai SHIELD360_API_KEY: ${{ secrets.SHIELD360_API_KEY }}shield360 ci
Section titled “shield360 ci”Send deploy markers and test results from a CI pipeline. See CI pipelines for the GitHub Action and a GitLab CI template.
shield360 ci release --app checkout --env productionshield360 ci tests 'reports/**/*.xml' --app checkout| Flag | Default | What it does |
|---|---|---|
--app | package.json or pyproject.toml name, else the directory | The app’s name in Shield360 |
--env | production (release), ci (tests), or SHIELD360_ENVIRONMENT | The environment |
--version | The tag, else the commit’s first 12 characters | The release |
--description | release only: a short note on the release | |
--failure-messages | off | tests only: also send failure messages, secret-redacted |
--allow-empty | off | tests only: succeed when no report matches |
Both need SHIELD360_URL and SHIELD360_API_KEY. They read the commit, branch and run URL from GitHub Actions or GitLab CI variables.
shield360 version
Section titled “shield360 version”Print the CLI version and build commit.
shield360 version# shield360 v1.2.3 (abc1234)Reserved (future) commands
Section titled “Reserved (future) commands”The CLI is built to grow into Shield360’s full control plane. These command groups are reserved in the codebase and will land in future releases:
| Command | Planned subcommands |
|---|---|
shield360 prompts | pull, push, list, diff |
shield360 traces | tail, query, export |
shield360 eval | run, list |
shield360 migrate | - |