The Garnet Command Line Interface (garnetctl) provides comprehensive control over agents, policies, incidents, and integrations.
Quick Commands
garnet agents list
garnet detections list
garnet policies apply policy.yaml
garnetctl is the recommended way to interact with Garnet from CI/CD pipelines, automation scripts, and terminal workflows.
Installation
macOS / Linux (Homebrew)
Direct Download
Go Install
brew install listendev/tap/garnetctl
Configuration
Before using the CLI, configure your credentials:
# Set API token
garnetctl config set-token YOUR_TOKEN
# Set base URL (if using self-hosted)
garnetctl config set-baseurl https://your-server-url
# View current configuration
garnetctl config show
Environment Variables
Alternatively, use environment variables:
export GARNET_TOKEN="your_api_token"
export GARNET_BASE_URL="https://api.garnet.ai"
export GARNET_AGENT_TOKEN="agent_specific_token"
Agent Management
Create Agent
Create a new agent to monitor your environment.
GitHub CI
Kubernetes
Vanilla
JSON
# Create agent for GitHub Actions
garnetctl create agent \
--version "1.0.0" \
--ip "192.168.1.100" \
--machine-id "abc123" \
--kind github \
--context-file github-context.json
github-context.json:{
"job": "build",
"run_id": "123456789",
"workflow": "CI",
"repository": "yourorg/repo",
"repository_owner": "yourorg",
"event_name": "push",
"ref": "refs/heads/main",
"sha": "abcdef123456",
"actor": "username",
"runner_os": "linux",
"runner_arch": "X64"
}
Response:
{
"agent_id": "agent_abc123xyz",
"agent_token": "gat_xxxxxxxxxxxxxxxxxxxxxxxx",
"created_at": "2024-01-15T10:23:47Z"
}
Save the agent_token securely. You’ll need it to authenticate the agent.
List Agents
# List all agents
garnetctl list agents
# Filter by status
garnetctl list agents --status active
# Filter by kind
garnetctl list agents --kind github
# Filter by hostname
garnetctl list agents --hostname "prod-*"
# JSON output
garnetctl list agents --output json
Example output:
ID HOSTNAME STATUS KIND IP LAST_SEEN
agent_abc123 github-runner-01 active github 192.168.1.100 2m ago
agent_def456 k8s-worker-01 active k8s 10.0.1.50 5m ago
agent_ghi789 prod-server-01 inactive vanilla 192.168.1.200 2h ago
Get Agent
Retrieve detailed information about a specific agent.
garnetctl get agent agent_abc123xyz
# JSON output
garnetctl get agent agent_abc123xyz --output json
Example output:
{
"id": "agent_abc123xyz",
"hostname": "github-runner-01",
"ip": "192.168.1.100",
"os": "linux",
"arch": "amd64",
"version": "1.0.0",
"kind": "github",
"status": "active",
"created_at": "2024-01-15T10:23:47Z",
"last_heartbeat": "2024-01-15T14:55:23Z",
"github_context": {
"repository": "yourorg/repo",
"workflow": "CI",
"run_id": "123456789"
}
}
Delete Agent
# Delete agent
garnetctl delete agent agent_abc123xyz
# Force delete (skip confirmation)
garnetctl delete agent agent_abc123xyz --force
Start Daemon
Download and run the Jibril daemon on a Linux machine.
# Start with specific agent token
garnetctl start-daemon \
--config /etc/garnet/config.yaml \
--agent-token gat_xxxxxxxxxxxxxxxx
# Use specific release version
garnetctl start-daemon \
--config /etc/garnet/config.yaml \
--agent-token gat_xxxxxxxxxxxxxxxx \
--release v1.2.3
Requires sudo privileges and only works on Linux (AMD64 or ARM64).
Typical Workflow:
# 1. Create agent and capture token
AGENT_TOKEN=$(garnetctl create agent \
--version "1.0.0" \
--ip "$(curl -s ifconfig.me)" \
--machine-id "$(cat /etc/machine-id)" \
--kind vanilla \
--job "production-monitoring" \
--runner-os "linux" \
| jq -r '.agent_token')
# 2. Get network policy for the agent
garnetctl get networkpolicy merged \
--repository-id "yourorg/repo" \
--format jibril \
--output /etc/garnet/policy.json
# 3. Start daemon
garnetctl start-daemon \
--config /etc/garnet/config.yaml \
--agent-token $AGENT_TOKEN
Network Policy Management
Create Policy
# Create from HCL file
garnetctl create networkpolicy --file policies/block-miners.hcl
# Create from JSON
garnetctl create networkpolicy '{
"name": "Block Mining Pools",
"type": "network",
"match": "domain_matches(\"*.xmrig.com\")",
"action": "block",
"scope": "global",
"severity": "critical"
}'
Get Policy
# Get specific policy
garnetctl get networkpolicy policy_abc123
# Get merged policy (combines global, repo, and workflow policies)
garnetctl get networkpolicy merged \
--repository-id "yourorg/repo" \
--workflow-name "build"
# Get in Jibril format (for agent consumption)
garnetctl get networkpolicy merged \
--repository-id "yourorg/repo" \
--format jibril \
--output policy.json
Jibril format output:
{
"version": "1.0",
"policies": [
{
"id": "policy_abc123",
"type": "network",
"rules": [
{
"match": {
"domain": ["*.xmrig.com", "*.nanopool.org"]
},
"action": "block"
}
]
}
]
}
List Policies
# List all policies
garnetctl list networkpolicies
# Filter by scope
garnetctl list networkpolicies --scope global
# Filter by repository
garnetctl list networkpolicies --repository-id "yourorg/repo"
# Filter by type
garnetctl list networkpolicies --type network
Update Policy
# Update policy action
garnetctl update networkpolicy policy_abc123 --action block
# Update from file
garnetctl update networkpolicy policy_abc123 --file policies/updated.hcl
Delete Policy
garnetctl delete networkpolicy policy_abc123
# Force delete
garnetctl delete networkpolicy policy_abc123 --force
Policy Rules
Manage individual rules within a policy:
# Create rule
garnetctl create networkpolicy rule policy_abc123 '{
"match": "domain_equals(\"evil.com\")",
"action": "block"
}'
# Get rule
garnetctl get networkpolicy rule policy_abc123 rule_xyz789
# Update rule
garnetctl update networkpolicy rule policy_abc123 rule_xyz789 \
--action observe
# Delete rule
garnetctl delete networkpolicy rule policy_abc123 rule_xyz789
Issue Management
Issues represent security incidents detected by Garnet.
List Issues
# List all issues
garnetctl list issues
# Filter by severity
garnetctl list issues --severity critical
# Filter by status
garnetctl list issues --status blocked
# Filter by policy
garnetctl list issues --policy "DropDomain"
# Filter by repository
garnetctl list issues --repository "yourorg/repo"
# Time-based filtering
garnetctl list issues --since "2024-01-01" --until "2024-01-31"
Example output:
ID SEVERITY POLICY STATUS REPOSITORY CREATED
inc_abc123 critical DropDomain blocked yourorg/api 2m ago
inc_def456 high Block Miners blocked yourorg/worker 15m ago
inc_ghi789 medium File Access observed yourorg/frontend 1h ago
Get Issue
# Get issue details
garnetctl get issue inc_abc123
# JSON output
garnetctl get issue inc_abc123 --output json
Example output:
{
"id": "inc_abc123",
"severity": "critical",
"policy": "DropDomain",
"status": "blocked",
"repository": "yourorg/api",
"workflow": "build-and-test",
"details": {
"destination": "pool.xmrig.com",
"process": "python3",
"port": 3333
},
"metrics": {
"ttd": 47,
"ttr": 0
},
"created_at": "2024-01-15T10:23:47Z"
}
Create Issue
# Create issue manually (for testing)
garnetctl create issue '{
"severity": "high",
"policy": "Test Policy",
"repository": "yourorg/repo",
"details": {
"test": "value"
}
}'
Update Issue
# Update issue status
garnetctl update issue inc_abc123 --status resolved
# Add notes
garnetctl update issue inc_abc123 --notes "False positive, whitelisted"
Delete Issue
garnetctl delete issue inc_abc123
Issue Actions
Allow or block specific incidents:
# Allow an issue (create exception)
garnetctl allow inc_abc123
# Allow with time-to-live
garnetctl allow inc_abc123 --ttl 24h
# Block an issue explicitly
garnetctl block inc_abc123
# View action history
garnetctl issue action history inc_abc123
Webhook Management
Create Webhook
garnetctl create webhook '{
"url": "https://your-webhook-endpoint.com/alerts",
"secret": "your-webhook-secret",
"events": ["incident.created", "incident.blocked"],
"severities": ["critical", "high"]
}'
List Webhooks
Get Webhook
garnetctl get webhook webhook_abc123
Delete Webhook
garnetctl delete webhook webhook_abc123
Integration Management
Add Integration
garnetctl integrations add slack \
--webhook https://hooks.slack.com/services/T00/B00/XXXX \
--channel "#security-alerts" \
--severity critical,high
List Integrations
garnetctl integrations list
Test Integration
# Test Slack
garnetctl integrations test slack
# Test GitHub
garnetctl integrations test github --repository yourorg/repo
# Test webhook
garnetctl integrations test webhook
Update Integration
garnetctl integrations update slack \
--severity critical,high,medium
Remove Integration
garnetctl integrations remove slack
AI Insights
Analyze Incidents
# Analyze specific incident
garnetctl insights analyze --incident inc_abc123
# Analyze multiple incidents
garnetctl insights analyze \
--incident inc_abc123 \
--incident inc_def456 \
--recommend-policies
# Analyze scope optimization
garnetctl insights analyze \
--incident inc_abc123 \
--analyze-scope
List Recommendations
# List all pending recommendations
garnetctl insights list --status pending
# Filter by confidence
garnetctl insights list --min-confidence 0.90
# Filter by type
garnetctl insights list --type policy_recommendation
Apply Recommendation
# Apply specific recommendation
garnetctl insights apply rec_xyz789
# Apply with dry-run
garnetctl insights apply rec_xyz789 --dry-run
garnetctl insights configure \
--confidence-threshold 0.90 \
--auto-apply true \
--max-per-day 10
Global Flags
Available for all commands:
| Flag | Description |
|---|
--help, -h | Show help for any command |
--version, -v | Display version information |
--output, -o | Output format: table, json, yaml (default: table) |
--debug | Enable debug logging |
--quiet, -q | Suppress non-error output |
--config | Path to config file (default: ~/.garnet/config.yaml) |
Configuration File
Default location: ~/.garnet/config.yaml
api:
token: "your_api_token"
base_url: "https://api.garnet.ai"
defaults:
output: "table"
debug: false
integrations:
slack:
webhook: "https://hooks.slack.com/services/..."
channel: "#security-alerts"
Shell Completion
Enable tab completion for your shell:
# Add to ~/.bashrc
source <(garnetctl completion bash)
# Or install system-wide
garnetctl completion bash > /etc/bash_completion.d/garnetctl
Examples
CI/CD Deployment
#!/bin/bash
# deploy-agent.sh
# Create agent
RESPONSE=$(garnetctl create agent \
--version "1.0.0" \
--ip "$(curl -s ifconfig.me)" \
--machine-id "$(cat /etc/machine-id)" \
--kind github \
--context-file github-context.json \
--output json)
AGENT_TOKEN=$(echo $RESPONSE | jq -r '.agent_token')
# Get policy
garnetctl get networkpolicy merged \
--repository-id "$GITHUB_REPOSITORY" \
--format jibril \
--output /etc/garnet/policy.json
# Start daemon
garnetctl start-daemon \
--config /etc/garnet/config.yaml \
--agent-token $AGENT_TOKEN
Automated Incident Response
#!/bin/bash
# auto-triage.sh
# Get high-severity incidents from last hour
INCIDENTS=$(garnetctl list issues \
--severity critical,high \
--since "1h" \
--output json)
# Analyze and auto-apply recommendations
echo $INCIDENTS | jq -r '.[].id' | while read INCIDENT_ID; do
echo "Analyzing $INCIDENT_ID..."
garnetctl insights analyze --incident $INCIDENT_ID
done
# Apply high-confidence recommendations
garnetctl insights list --min-confidence 0.95 --output json | \
jq -r '.[].id' | while read REC_ID; do
echo "Applying recommendation $REC_ID..."
garnetctl insights apply $REC_ID
done
Next Steps