Docs / Control Plane

Control Plane Beta

An optional telemetry endpoint and dashboard for inspecting allow/deny decisions from your running Arcis middleware. The SDKs and CLI work fully offline without it. The control plane is currently in beta and under active development; this page describes the design so you can plan integrations.

Beta — under development and testing. The control plane is not generally available yet. APIs may change before the stable release. The middleware works without it — telemetry is strictly opt-in. This page documents the current shape so you can preview the integration; check the release notes for the general-availability announcement.

What it is

The control plane is a small backend + dashboard that receives the security events your Arcis middleware emits in production. It shows you:

It is not required to use Arcis. The SDK middleware makes its own allow/deny decisions locally; the control plane is observability on top.

Architecture

Everything runs on infrastructure you control. The control plane is designed to be self-hostable end to end; there is no requirement to send your data to any third party.

When it makes sense

If you only need local protection without a dashboard, skip this entirely. app.use(arcis()) works without any control-plane configuration.

Environment variables

Three variables wire the SDK middleware up to a control plane. Drop them in .env; the middleware reads them on startup.

VariablePurpose
ARCIS_ENDPOINTHTTPS URL of the ingest service (e.g. https://arcis.your-company.internal).
ARCIS_WORKSPACE_IDUUID of the workspace this app belongs to. Created in the dashboard.
ARCIS_KEYAPI key issued by arcis login against the control plane. Scoped to a workspace.

No env vars set, no telemetry sent. The SDK middleware checks for these on startup. If any are missing it runs in local-only mode and never opens a connection. There is no fallback endpoint, no phone-home behavior, no anonymous metrics.

arcis login

The CLI command for issuing a workspace-scoped API key.

# Authenticate against your control plane
arcis login --endpoint https://arcis.your-company.internal

# Now arcis sca and arcis audit can upload results to the dashboard
arcis sca . --upload
arcis audit . --upload

The login flow is browser-based: arcis login opens a URL in your browser, you authenticate against your control plane, and a short-lived token is written to ~/.arcis/credentials.json. Long-lived API keys for CI are issued from the dashboard.

Event shape

The SDKs emit one event per allow/deny decision. The shape (subject to change before GA):

{
  "workspace_id": "5f6c2...",
  "app_id": "web-api-prod",
  "sdk": "@arcis/node",
  "sdk_version": "1.6.0",
  "decision": "deny",     // "allow" | "deny"
  "vector": "xss",
  "rule": "patterns.xss.script-tag",
  "matched": "<script>...",           // truncated, never the full payload
  "route": "/api/comments",
  "method": "POST",
  "ip_hash": "a91b...",             // hashed by default; raw IP opt-in
  "timestamp": "2026-05-21T14:22:15Z"
}

The middleware batches events client-side and POSTs them with a bounded queue. If the ingest service is down, events drop oldest-first rather than blocking the request path or filling memory. Pattern 4 (fail-open on infrastructure errors) applies here too.

Privacy posture

Dashboard surfaces

The web UI that ships with the ingest service has these top-level surfaces:

Uploading CI results

When the control plane is configured, arcis sca and arcis audit can upload their JSON output into the dashboard:

# In your CI pipeline
export ARCIS_ENDPOINT=https://arcis.your-company.internal
export ARCIS_KEY=${{ secrets.ARCIS_KEY }}
export ARCIS_WORKSPACE_ID=${{ vars.ARCIS_WORKSPACE_ID }}

arcis sca . --upload --sarif
arcis audit . --upload --sarif

Without these env vars the same commands write SARIF to stdout for GitHub Code Scanning as usual; --upload additionally POSTs the result to POST /v1/findings.

Roadmap

Want early access? Open an issue at github.com/Gagancm/arcis/issues with the label control-plane. The control plane has a separate release cadence from the SDKs; this docs page will get the announcement when it goes GA.

Using Arcis without the control plane

Arcis works fully without a control plane. The SDK middleware makes its own decisions locally, and the CLI runs entirely offline (except arcis sca --osv). If you want a log of decisions, configure your normal Node / Python / Go logger to capture from arcis events:

// Node example: subscribe to allow/deny events without a control plane
import { arcis } from '@arcis/node';

app.use(arcis({
  block: true,
  onDecision: (event) => {
    logger.info('arcis decision', event);
  },
}));