Skip to content

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 version

Coding-agent observability for Claude Code, Cursor, Codex, and OpenCode. See the Coding Agents setup guide for the full vendor-by-vendor walkthrough.

Install the per-vendor host plugin manifest. Idempotent - re-running drops prior shield360 entries before re-writing, leaving any third-party entries in place.

Terminal window
shield360 coding install --vendor=claude-code
shield360 coding install --vendor=all --dry-run # preview without writing
FlagDescription
--vendor (required)claude-code | cursor | codex | opencode | all
--dry-runPrint what would be written without modifying any files

Where manifests are written:

VendorManifest 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

Bootstrap the plugin for an agent and exec it - telemetry on from the first turn. Auto-installs the manifest if needed.

Terminal window
shield360 coding launch claude
shield360 coding launch cursor -- <agent-args...> # pass args through after --
shield360 coding launch codex
shield360 coding launch opencode
ArgumentDescription
<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.

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.

Terminal window
shield360 coding uninstall --vendor=cursor # one vendor
shield360 coding uninstall --vendor=all # every vendor
shield360 coding uninstall --vendor=all --purge # also drop ~/.config/shield360 + session cache
shield360 coding uninstall --vendor=cursor --dry-run # preview without touching disk
FlagDescription
--vendor (required)claude-code | cursor | codex | opencode | all
--purgeAlso remove ~/.config/shield360 and the session-state cache
--dry-runPrint what would be removed without modifying any files
Terminal window
shield360 coding hook --vendor=claude-code --event=SessionStart < payload.json
FlagDescription
--vendor (required)cc | claude-code | cursor | codex | opencode
--eventHook 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.

Write persistent settings to ~/.config/shield360/config.env. See Configuration for the full flag table, precedence, and content-capture modes.

Terminal window
shield360 configure --url https://app.shield360.ai --api-key $SHIELD360_API_KEY
shield360 configure --show # print resolved config and its source, write nothing

Set a repository up to send its app’s telemetry to Shield360. Run it in the app’s directory:

Terminal window
shield360 init # show what it found and what it would change
shield360 init --write # make the changes
shield360 init ./services/checkout --app checkout --write

It 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.env with SHIELD360_URL, the app’s name (OTEL_SERVICE_NAME), its environment and SHIELD360_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/shield360 and preloaded through NODE_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, and JAVA_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.

FlagDefaultWhat it does
--writeoffMake the changes; without it, only show them
--apppackage.json or pyproject.toml name, else the directoryThe app’s name in Shield360
--envproductionThe environment the deployed app reports as
--sdk-versionthe latest on npmThe Node SDK version to bake in

Diagnose the CLI’s setup. Reads the resolved config, TCP-dials the OTLP endpoint (2s timeout), and lists installed vendor plugins.

Terminal window
shield360 doctor

Exit 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.

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.

Terminal window
export SHIELD360_MCP_BRIDGE_TOKEN=$(openssl rand -hex 32)
shield360 mcp bridge --listen 127.0.0.1:8931 -- npx -y @modelcontextprotocol/server-filesystem /srv/docs

Then 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.

FlagDefaultMeaning
--listen127.0.0.1:8931Address to serve on.
--token-envSHIELD360_MCP_BRIDGE_TOKENEnvironment 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-keyServe HTTPS with this certificate and key.
--insecure-plain-httpfalseServe 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-timeout120sHow 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 initialize requests 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.

Start any app with Shield360, with no code change: put it in front of the command you already use.

Terminal window
shield360 run -- npm start
shield360 run --app checkout --env staging -- node server.js
shield360 run -- uvicorn main:app --reload
shield360 run -- java -jar build/libs/orders.jar

The 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.

FlagDefaultWhat it does
--apppackage.json or pyproject.toml name, else the directoryThe app’s name in Shield360
--envdev (or SHIELD360_ENVIRONMENT)The environment its data goes to
--runtimefrom the commandnode, python or java, when the command doesn’t show it (a shell script, say)
--sdk-dir~/.shield360/sdkWhere the Node SDK is installed and reused
--sdk-versionlatestThe Node SDK version to install
--java-agent-version2.33.1The OpenTelemetry Java agent version to download
--no-installoffFail 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.

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.

Terminal window
shield360 scan
shield360 scan ./services/orders --app orders
shield360 scan --image ghcr.io/acme/orders:1.4.2 --fail-on high
shield360 scan --dry-run --output scan.json

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.

FlagDefaultWhat it does
--apppackage.json or pyproject.toml name, else the directory or image nameThe app’s name in Shield360
--image-Scan this container image instead of a directory
--commit, --branchfrom CI variables, else gitWhat 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-runoffScan and print the payload instead of sending it
--output-Also write the payload to this file
--no-secretsoffSkip the committed-secrets check
--no-codeoffSkip the check of the app’s own code
--no-costoffSkip 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/toolsWhere Trivy and its vulnerability database are cached
--no-installoffFail instead of downloading Trivy
--timeout15mHow 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 }}

Send deploy markers and test results from a CI pipeline. See CI pipelines for the GitHub Action and a GitLab CI template.

Terminal window
shield360 ci release --app checkout --env production
shield360 ci tests 'reports/**/*.xml' --app checkout
FlagDefaultWhat it does
--apppackage.json or pyproject.toml name, else the directoryThe app’s name in Shield360
--envproduction (release), ci (tests), or SHIELD360_ENVIRONMENTThe environment
--versionThe tag, else the commit’s first 12 charactersThe release
--descriptionrelease only: a short note on the release
--failure-messagesofftests only: also send failure messages, secret-redacted
--allow-emptyofftests 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.

Print the CLI version and build commit.

Terminal window
shield360 version
# shield360 v1.2.3 (abc1234)

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:

CommandPlanned subcommands
shield360 promptspull, push, list, diff
shield360 tracestail, query, export
shield360 evalrun, list
shield360 migrate-