CLI Reference
Complete reference for the CoreSDK CLI — sidecar management, policy testing, and config validation.
Available in Phase 1b. The sidecar binary ships with Phase 1b. Phase 1a (Rust crate only) users access the engine directly without a separate binary.
CLI Reference
The coresdk-sidecar binary is the standalone sidecar daemon. It embeds the Core Engine and exposes gRPC/HTTP locally. Install it:
cargo install coresdk-sidecarStarting the sidecar
# Start with default config (reads coresdk.toml in the current directory)
coresdk-sidecar
# Start with explicit config file
coresdk-sidecar --config /etc/coresdk/coresdk.toml
# Start with environment variables only
CORESDK_SIDECAR_ADDR=[::1]:50051 \
CORESDK_TENANT_ID=acme-corp \
CORESDK_SERVICE_NAME=my-api \
coresdk-sidecarEnvironment variables
The sidecar reads all configuration from CORESDK_* environment variables (which override coresdk.toml):
| Variable | Description |
|---|---|
CORESDK_SIDECAR_ADDR | Listen address for the gRPC endpoint (default: [::1]:50051) |
CORESDK_TENANT_ID | Tenant ID for this deployment |
CORESDK_SERVICE_NAME | OTel service.name resource attribute |
CORESDK_FAIL_MODE | open (default) or closed |
CORESDK_JWKS_URL | HTTPS URL of the JWKS endpoint |
CORESDK_POLICY_DIR | Directory of .rego policy files |
CORESDK_LOG_LEVEL | trace | debug | info | warn | error |
OTEL_EXPORTER_OTLP_ENDPOINT | OTLP gRPC endpoint for traces and metrics |
See Environment Variables for the complete reference.
Policy commands
core policy test
Evaluate a policy directory against a JSON input or a directory of fixture files.
core policy test <policy-dir> [flags]Single input:
core policy test ./policies --input '{
"action": "orders:read",
"user": { "role": "member", "tenant_id": "acme" },
"resource": { "tenant": "acme", "id": "ord_1" }
}'
# → allow: trueExpect a deny and assert a reason:
core policy test ./policies \
--input '{"action":"data:export","user":{"role":"member","tenant_id":"acme"},"resource":{"tenant":"acme"}}' \
--expect deny \
--expect-reason "enterprise plan required"
# → allow: false ✓
# → deny_reasons: ["enterprise plan required"] ✓Fixture directory:
core policy test ./policies --fixtures ./tests/policy-fixtures/
# → 12 passed, 0 failedCI mode (non-zero exit on any failure):
core policy test ./policies --fixtures ./tests/policy-fixtures/ --ci| Flag | Description |
|---|---|
--input <json> | JSON string to use as policy input |
--input-file <path> | Read input from a JSON file |
--fixtures <dir> | Run all *.input.json / *.expect.json pairs in a directory |
--expect allow|deny | Assert the expected decision (exit 1 if wrong) |
--expect-reason <string> | Assert a substring appears in deny_reasons |
--ci | Exit non-zero on any failure; machine-readable output |
--verbose | Print the full evaluated rule set |
Fixture file format:
tests/policy-fixtures/member-read-own-tenant.input.json:
{
"action": "orders:read",
"user": { "role": "member", "tenant_id": "acme", "id": "usr_1" },
"resource": { "tenant": "acme", "id": "ord_1" },
"tenant": { "id": "acme", "plan": "starter" }
}tests/policy-fixtures/member-read-own-tenant.expect.json:
{ "allow": true, "deny_reasons": [] }core policy lint
Validate Rego syntax and check for common mistakes.
core policy lint ./policies
# → ✓ orders.rego
# → ✓ reports.rego
# → ✗ admin.rego:14 — undefined reference: input.user.roles (did you mean input.user.role?)
# → 1 error, 0 warnings| Flag | Description |
|---|---|
--strict | Treat warnings as errors |
--format json | Machine-readable output |
core policy bench
Benchmark policy evaluation latency in-process.
core policy bench ./policies \
--input ./tests/policy-fixtures/member-read-own-tenant.input.json \
--iterations 10000
# → p50: 0.3 ms
# → p95: 0.6 ms
# → p99: 0.9 ms
# → p999: 2.1 msFail CI if p99 exceeds a threshold:
core policy bench ./policies --p99-max-us 1000 --ci| Flag | Description |
|---|---|
--iterations <n> | Number of evaluations (default: 1000) |
--warmup <n> | Warmup iterations before measurement (default: 100) |
--p99-max-us <n> | Fail if p99 exceeds this microsecond threshold |
--ci | Exit non-zero on threshold breach |
core policy dry-run
Evaluate a policy against live traffic without enforcing decisions. Records outcomes to the audit log with simulated: true.
core policy dry-run ./policies \
--sidecar http://localhost:7700 \
--duration 5m
# → Shadowing live traffic for 5 minutes...
# → allow: 1,204 deny (simulated): 38 errors: 0
# → Top deny reasons:
# "enterprise plan required" (31)
# "cross-tenant access" (7)Review the simulated denies in the audit log before switching to PolicyMode::Enforce.
core policy bundle
Package and sign a policy directory for air-gapped or manual delivery.
core policy bundle \
--dir ./policies \
--sign-key /etc/coresdk/signing-key.pem \
--output dist/policy-bundle.tar.gz
core policy bundle inspect dist/policy-bundle.tar.gz
# → Policies: 6 Signed: yes (ES256) Created: 2026-03-19T12:00:00ZAdvanced CLI commands (Phase 2)
The following commands (core trace tail, core log tail, core config, core sidecar, core saml, core policy, core coverage) are Phase 2 features. They are not available in Phase 1b.
Observability commands
core trace tail (Phase 2)
Interactive terminal trace viewer. Streams live OTel spans from the sidecar and renders them as a tree with timeline waterfall, error path highlighting, and a variable inspector.
core trace tail --sidecar http://localhost:7700┌─ POST /api/orders [200] 142 ms trace: 4bf92f3577b3
│ ├─ auth.verify_token 3 ms ✓ user: usr_2xK9
│ ├─ policy.evaluate 1 ms ✓ allow rule: member-own-tenant
│ ├─ db.fetch_orders 89 ms rows: 12
│ └─ response.serialize 2 ms
│
└─ POST /api/orders [403] 8 ms trace: 7ca13f4821e1 ← error path
├─ auth.verify_token 3 ms ✓
└─ policy.evaluate 1 ms ✗ deny: "cross-tenant access"
intent: "fetch orders for dashboard"
deny_reasons: ["resource.tenant != user.tenant_id"]Press Enter to expand a span, v to open the variable inspector for that span, q to quit.
| Flag | Description |
|---|---|
--sidecar <url> | Sidecar address (default: http://localhost:7700) |
--tenant <id> | Filter to a specific tenant |
--service <name> | Filter by service.name OTel attribute |
--trace-id <id> | Jump directly to a specific trace |
--errors-only | Show only traces containing errors or denies |
--since <duration> | Show traces from the last N minutes (e.g. 5m, 1h) |
core log tail
Stream structured CoreSDK logs with real-time filtering.
# All logs
core log tail
# Filter by tenant
core log tail --tenant acme
# Only denied policy decisions
core log tail --tenant acme --filter 'policy.result=denied'
# Follow a specific user's activity
core log tail --tenant acme --filter 'user_id=usr_2xK9'
# Correlate with a trace
core log tail --trace-id 4bf92f3577b34da6a3ce929d0e0e4736| Flag | Description |
|---|---|
--tenant <id> | Filter to a specific tenant |
--filter <expr> | Filter expression (field=value, AND/OR supported) |
--trace-id <id> | Show logs for a specific trace ID |
--level <level> | Minimum log level: error, warn, info, debug |
--since <duration> | Show logs from the last N (e.g. 10m, 1h) |
--format json | Raw JSON output (default: pretty-printed) |
Config commands
core config validate
Validate a CoreSDK config file for syntax errors and unknown keys.
core config validate ./coresdk.yaml
# → ✓ Config valid (42 keys)
# → Warning: rate_limit.per_tenant.acme is not set; using default (1000 rpm)core config diff
Show what changed between two config files or a config file and the live sidecar config.
core config diff ./coresdk.yaml --live http://localhost:7700
# → + rate_limit.default_rpm: 500 → 1000
# → ~ tenant_cache_ttl: 60 (unchanged)Sidecar commands
core sidecar status
Show the current sidecar health, cache state, and control plane sync status.
core sidecar status
# → Status: healthy
# → Partitioned: false
# → Last sync: 2026-03-19T12:34:01Z (8s ago)
# → Cache valid: true
# → Policies: 6 loaded
# → JWKS: 2 key sets cached
# → Uptime: 2d 4h 12m
# → Version: 1.4.0When partitioned:
core sidecar status
# → Status: degraded (partitioned)
# → Partitioned: true (since 2026-03-19T12:30:00Z — 4m 01s ago)
# → Cache valid: true
# → Cache age: 241score sidecar restart
Gracefully drain in-flight requests, then restart the sidecar process.
core sidecar restart
# → Draining in-flight requests (timeout: 30s)...
# → Flushing OTel batch...
# → Restarting...
# → Sidecar healthy (v1.4.0)| Flag | Description |
|---|---|
--drain-timeout <s> | Max seconds to wait for in-flight requests (default: 30) |
--force | Skip drain; restart immediately |
core sidecar reload-policy
Load a new policy bundle without restarting the sidecar.
core sidecar reload-policy --bundle /etc/coresdk/policy-bundle.tar.gz
# → Verifying bundle signature...
# → Signature valid.
# → Loading 6 policies...
# → Policy bundle active. Previous bundle retired.SAML commands
core saml metadata
Generate SP metadata XML for import into your IdP.
core saml metadata --output sp-metadata.xmlcore saml test-assertion
Generate a signed test SAML assertion for local development (no real IdP needed).
core saml test-assertion \
--email alice@example.com \
--role member \
--tenant acme \
--output /tmp/test-assertion.xmlGlobal flags
| Flag | Description |
|---|---|
--sidecar <url> | Sidecar address (default: http://localhost:7700) |
--config <path> | Path to CoreSDK config file |
--log-level <level> | CLI log level: error, warn, info, debug |
--output json | Machine-readable JSON output (most commands) |
--version | Print CLI version |
--help | Print command help |
Next steps
- Configuration Reference — all config keys and environment variables
- Environment Variables —
CORESDK_*environment variable reference - Policy Testing — unit test policies in code
- Observability / OpenTelemetry — what the trace viewer reads