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);
  },
}));